262 |
struct FilletSpan2 { |
struct FilletSpan2 { |
263 |
enum { NTrans = 3 }; |
enum { NTrans = 3 }; |
264 |
|
|
265 |
|
float border; |
266 |
int ndice; |
int ndice; |
267 |
int flags; |
int flags; |
268 |
|
|
269 |
|
template<class F> void params(F &f) { |
270 |
|
f(border, ndice, flags); |
271 |
|
} |
272 |
|
|
273 |
template<class T> float crad(const T &t) const { |
template<class T> float crad(const T &t) const { |
274 |
return t.getSqSize().x; |
return t.getSqSize().x; |
275 |
} |
} |
282 |
float dr = (d - (rmax-rmin)) / (r0 + r1); |
float dr = (d - (rmax-rmin)) / (r0 + r1); |
283 |
return .96 * rmin * 1 / (1 + dr); |
return .96 * rmin * 1 / (1 + dr); |
284 |
} |
} |
|
|
|
|
template<class F> void params(F &f) { |
|
|
f(ndice, flags); |
|
|
} |
|
285 |
|
|
286 |
void v(ZVec p) const { |
void v(ZVec p) const { |
287 |
if(flags & 4) { |
if(flags & 4) { |
319 |
glEnd(); |
glEnd(); |
320 |
} |
} |
321 |
|
|
322 |
template<class G> void renderSpan(const G &g) const { |
void pointInternNormal(ZVec p, ZVec intern, ZVec normal) const { |
323 |
if(flags & 1) |
if(flags & 1) { |
324 |
renderSpanSolid(g); |
// solid |
325 |
if(flags & 2) |
v(p - border/2 * normal); |
326 |
renderSpanLine(g); |
v(intern); |
327 |
|
} else { |
328 |
|
// Line |
329 |
|
vl(p + border/2 * normal); |
330 |
|
vl(p - border/2 * normal); |
331 |
|
} |
332 |
} |
} |
333 |
|
|
334 |
|
template<class G> void renderSpanPolyedged(const G &g, int sign) const { |
335 |
|
glBegin(GL_QUAD_STRIP); |
336 |
|
ZVec intern0; |
337 |
|
ZVec p0 = g.point(0, &intern0); |
338 |
|
|
339 |
|
ZVec intern1; |
340 |
|
ZVec p1 = g.point(1 / (ndice-1.0), &intern1); |
341 |
|
|
342 |
|
ZVec normal0 = sign * Vec(p1-p0).cw90().normalized(); |
343 |
|
|
344 |
|
pointInternNormal(p0, intern0, normal0); |
345 |
|
|
346 |
|
ZVec prevpt = p0; |
347 |
|
ZVec curpt = p1; ZVec curintern = intern1; |
348 |
|
ZVec nextpt, nextintern; |
349 |
|
|
350 |
|
for(int i=1; i<ndice-1; i++) { |
351 |
|
float fract = (i+1) / (ndice-1.0); |
352 |
|
nextpt = g.point(fract, &nextintern); |
353 |
|
|
354 |
|
ZVec normal = sign * Vec(nextpt - prevpt).cw90().normalized(); |
355 |
|
pointInternNormal(curpt, curintern, normal); |
356 |
|
prevpt = curpt; |
357 |
|
curpt = nextpt; |
358 |
|
curintern = nextintern; |
359 |
|
} |
360 |
|
|
361 |
|
ZVec normalLast = sign * Vec(curpt - prevpt).cw90().normalized(); |
362 |
|
pointInternNormal(curpt, curintern, normalLast); |
363 |
|
|
364 |
|
glEnd(); |
365 |
|
} |
366 |
|
|
367 |
|
template<class G> void renderSpan(const G &g, int sign) const { |
368 |
|
if(flags & 8) { |
369 |
|
renderSpanPolyedged(g, -sign); |
370 |
|
} else { |
371 |
|
if(flags & 1) |
372 |
|
renderSpanSolid(g); |
373 |
|
if(flags & 2) |
374 |
|
renderSpanLine(g); |
375 |
|
} |
376 |
|
} |
377 |
|
|
378 |
|
|
379 |
|
|
380 |
float normAngle(float a) const { |
float normAngle(float a) const { |
381 |
while(a < 0) a += 2*M_PI; |
while(a < 0) a += 2*M_PI; |
450 |
makeLerpFilletSpan( |
makeLerpFilletSpan( |
451 |
FilletBlend(f1, vf2), |
FilletBlend(f1, vf2), |
452 |
f1, |
f1, |
453 |
fract) |
fract), 1 |
454 |
); |
); |
455 |
|
|
456 |
renderSpan( |
renderSpan( |
457 |
makeLerpFilletSpan( |
makeLerpFilletSpan( |
458 |
FilletBlend(f2, vf1), |
FilletBlend(f2, vf1), |
459 |
f2, |
f2, |
460 |
fract) |
fract), -1 |
461 |
); |
); |
462 |
} else if(f1.overlaps(f2)) { |
} else if(f1.overlaps(f2)) { |
463 |
renderSpan(FilletBlend(f1, f2)); |
renderSpan(FilletBlend(f1, f2), 1); |
464 |
renderSpan(FilletBlend(f2, f1)); |
renderSpan(FilletBlend(f2, f1), -1); |
465 |
} else { |
} else { |
466 |
renderSpan(f1); |
renderSpan(f1, 1); |
467 |
float ta1 = f1.dirtang.atan(); |
float ta1 = f1.dirtang.atan(); |
468 |
float ta2 = f2.dirtang.atan(); |
float ta2 = f2.dirtang.atan(); |
469 |
if(ta2 < ta1) ta2 += 2*M_PI; |
if(ta2 < ta1) ta2 += 2*M_PI; |
470 |
renderSpan(CircularNodeSpan(node, ta1, ta2)); |
renderSpan(CircularNodeSpan(node, ta1, ta2), 1); |
471 |
renderSpan(f2); |
renderSpan(f2, -1); |
472 |
} |
} |
473 |
|
|
474 |
} |
} |