From: <Awa...@ao...> - 2004-08-10 14:41:34
|
included in this email is a modifed routine to plot thick curves without twisting ... (This code can replace the same routine in curve.cpp) The only modification is to the code which calculates the orthogonal vectors which span the plane at the intersection of line segments. The modification constructs orthogonal vectors which span the first plane (perpendicular to the first line segment) and then parallel transports these vectors along the curve. regards Andrew Wadsley ### start of code void curve::thickline( rView& view) { // double* v, double* color, double radius, int count const int MAX_SEGMENTS = 1024; const int curve_around = 4; static vertex projected[MAX_SEGMENTS * curve_around ]; static float light[MAX_SEGMENTS * curve_around * 3]; int step = (count + MAX_SEGMENTS-1) / MAX_SEGMENTS; vertex *pr = projected; float *lt = light; float *cost = curve_sc; float *sint = cost + curve_around; //Vector lastx(0,1,0), lasty(0,0,1); vector x, y, lastx, lasty; vector lastB, B; float tmp; int npoints = 0; // pos and color iterators const double* v_i = (double*)( data(pos)); const double* c_i = (double*)( data(color)); for(size_t corner=0; corner < count/step; ++corner, v_i += step*3, c_i += step*3) { // The vector to which v_i currently points towards. vector current( v_i[0], v_i[1], v_i[2] ); view.ext_point( current); /* To construct the circle of vertices around a point on the curve, * I need an orthonormal basis of the plane of the circle. A and B, * normalized vectors pointing toward the next and from the previous * points on the curve, are vectors in the plane of the *curve* at * this point. The cross product and the difference of these vectors * are orthogonal and lie in the appropriate plane. * Then parallel transport the last frame to this plane */ if (corner && (corner+1 < count/step)) { // Any point except the first and last. vector next( v_i[3], v_i[4], v_i[5]); // The next vector in pos vector prev( v_i[-3], v_i[-2], v_i[-1]); // The previous vector in pos vector A = next - current; B = current - prev; if ( !B ) B = lastB; x = A-B; y = A.cross(B); if (!x || !y) { x = lastx; y = lasty; B = lastB; } else { vector pz = x.cross(y); pz = pz.norm(); tmp = pz.dot(lastx)/pz.dot(B); x = lastx - B * tmp; tmp = pz.dot(lasty)/pz.dot(B); y = lasty - B * tmp; } } else if (corner) { // The last point vector prev( v_i[-3], v_i[-2], v_i[-1]); B = current - prev; if ( !B ) B = lastB; x = B.cross(vector(0,1,0)); if (!x) x = B.cross(vector(1,0,0)); y = B.cross(x); if (!x || !y) { x = lastx; y = lasty; B = lastB; } else { vector pz = x.cross(y); pz = pz.norm(); tmp = pz.dot(lastx)/pz.dot(B); x = lastx - B * tmp; tmp = pz.dot(lasty)/pz.dot(B); y = lasty - B * tmp; } } else { // The first point vector next( v_i[3], v_i[4], v_i[5]); B = next - current; x = B.cross(vector(0,1,0)); if (!x) x = B.cross(vector(1,0,0)); y = B.cross(x); if (!x || !y ) { x = vector(1,0,0); y = vector(0,0,1); B = vector(0,1,0); } } x = x.norm(); y = y.norm(); lastx = x; lasty = y; lastB = B; float lx[2], ly[2]; for(int li=0; li < view.lights.n_lights; li++) { lx[li] = view.lights.L[li].dot( x ); ly[li] = view.lights.L[li].dot( y ); } x = x * radius; y = y * radius; // Manipulate colors when we are in stereo mode. rgb rendered_color( static_cast<float>(c_i[0]), static_cast<float>(c_i[1]), static_cast<float>(c_i[2])); if (view.anaglyph) { if (view.coloranaglyph) { rendered_color = rendered_color.unsaturate(); } else { rendered_color.r = rendered_color.g = rendered_color.b = rendered_color.grayscale(); } } npoints++; for (int a=0; a < curve_around; a++) { float c = cost[a]; float s = sint[a]; float illum = view.lights.ambient; for(int li=0; li < view.lights.n_lights; li++) { float dot = c*lx[li] + s*ly[li]; if (dot > 0.0) illum += dot; } view.wct.project(current + x*c + y*s, *pr++); *(lt++) = illum * rendered_color.r; *(lt++) = illum * rendered_color.g; *(lt++) = illum * rendered_color.b; } } glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glShadeModel(GL_SMOOTH); int *ind = curve_slice; for(int a=0; a<curve_around; a++) { int ai = a; if (a == curve_around-1) { ind += 256; ai = 0; } for(int i=0; i<npoints; i+=127) { glVertexPointer(4, GL_DOUBLE, sizeof(vertex), & projected[i*curve_around + ai].x); glColorPointer (3, GL_FLOAT, sizeof(float)*3, & light[(i*curve_around + ai)*3] ); if (npoints-i < 128) glDrawElements(GL_TRIANGLE_STRIP, 2*(npoints-i), GL_UNSIGNED_INT, ind); else glDrawElements(GL_TRIANGLE_STRIP, 256, GL_UNSIGNED_INT, ind); } } } ### end of code |
From: Jonathan B. <jbr...@ea...> - 2004-08-10 15:30:59
|
On Tue, 2004-08-10 at 10:41, Awa...@ao... wrote: > included in this email is a modifed routine to plot thick curves > without twisting ... > > (This code can replace the same routine in curve.cpp) > > The only modification is to the code which calculates the orthogonal > vectors which span the plane at the intersection of line segments. > The modification constructs orthogonal vectors which span the first > plane (perpendicular to the first line segment) and then parallel > transports these vectors along the curve. > > regards > > Andrew Wadsley Well, I see that it fixes the twist, but it introduces another problem. If you run the drape demo in slow motion (change line 39 to rate(10), or so), you will see that in some places the line becomes flat as it falls on the spheres. tictac.py also shows this behavior: The flat faces are parallel to +y. You may have to rotate the scene such that the camera is under the grid to see it clearly. FYI, the next major revision to VPython will probably use GLE (http://linas.org/gle/) for much higher-quality thick line rendering code. I can't say when that release will be available. I have some concerns about its speed, although the results look great. If you manage to fix the current thickline rendering code, that would give me something suitable to compare against. Thanks, -Jonathan P.S. Please send the update as either a unified diff (created with diff -u), or as an attachment. When sent inline, the formatting was totally butchered. Also, please use tabs rather than spaces. |