void NAMESPACE::Trackball::updateRotation(uint x, uint y) { float speed = 3.0f; // *m_Elapsed; float dx = (float(x) - float(m_PrevX)) * speed / float(m_Width); float dy = (float(y) - float(m_PrevY)) * speed / float(m_Height); m_PrevX = x; m_PrevY = y; quatf dr = deltaRotation(dx, dy); m_Rotation = dr * m_Rotation; if (m_Walkthrough) { // remove 'roll' int d = -1; if (m_Up == X_neg || m_Up == Y_neg || m_Up == Z_neg) { d = 1; } quatf rinv = m_Rotation.inverse(); v3f up = dir2v3f(m_Up); v3f realleft = rinv * V3F(1, 0, 0); v3f frwd = rinv * V3F(0, 0, 1); v3f flat = normalize_safe(realleft - dot(realleft, up)*up); float cs = dot(realleft, flat); if (cs > -1.0f && cs < 1.0f) { float sign = dot(up, realleft) > 0 ? -1.0f : 1.0f; float target_agl = sign * acos(cs); float agl = target_agl; m_Rotation = quatf(V3F(0, 0, 1), agl) * m_Rotation; } } }
void draw_segment_color (int ncp, /* number of contour points */ gleDouble front_contour[][3], gleDouble back_contour[][3], float color_last[3], float color_next[3], int inext, double len) { int j; /* draw the tube segment */ BGNTMESH (inext, len); for (j=0; j<ncp; j++) { C3F (color_last); V3F (front_contour[j], j, FRONT); C3F (color_next); V3F (back_contour[j], j, BACK); } if (__TUBE_CLOSE_CONTOUR) { /* connect back up to first point of contour */ C3F (color_last); V3F (front_contour[0], 0, FRONT); C3F (color_next); V3F (back_contour[0], 0, BACK); } ENDTMESH (); }
void NAMESPACE::Trackball::init(uint w, uint h) { m_Width = w; m_Height = h; m_Translation = V3F(0, 0, -m_Radius); m_Rotation = quatf(V3F(0, 0, 1), 0.0f); m_Center = V3F(0, 0, 0); }
void draw_segment_facet_n (int ncp, /* number of contour points */ gleDouble front_contour[][3], gleDouble back_contour[][3], double norm_cont[][3], int inext, double len) { int j; /* draw the tube segment */ BGNTMESH (inext, len); for (j=0; j<ncp-1; j++) { N3F_D (norm_cont[j]); V3F (front_contour[j], j, FRONT); V3F (back_contour[j], j, BACK); V3F (front_contour[j+1], j+1, FRONT); V3F (back_contour[j+1], j+1, BACK); } if (__TUBE_CLOSE_CONTOUR) { /* connect back up to first point of contour */ N3F_D (norm_cont[ncp-1]); V3F (front_contour[ncp-1], ncp-1, FRONT); V3F (back_contour[ncp-1], ncp-1, BACK); V3F (front_contour[0], 0, FRONT); V3F (back_contour[0], 0, BACK); } ENDTMESH (); }
void NAMESPACE::Trackball::updateTranslation(uint x, uint y) { if (!m_Walkthrough) { float speed = m_BallSpeed * m_Radius * (1.0f + length(m_Translation) / m_Radius); float dx = (float(x) - float(m_PrevX)) * speed / float(m_Width); float dy = -(float(y) - float(m_PrevY)) * speed / float(m_Height); //std::cerr << abs(dx) << std::endl; //std::cerr << abs(dy) << std::endl; const float limit = 100.0f; dx = min(abs(dx), limit)*sign(dx); dy = min(abs(dy), limit)*sign(dy); m_PrevX = x; m_PrevY = y; v3f tx = dx * V3F(1, 0, 0); v3f ty = dy * V3F(0, 1, 0); m_Translation = m_Translation + tx + ty; } }
void NAMESPACE::Trackball::setWalkthrough(bool b) { if (m_Walkthrough && !b) { m_Translation = -(m_Rotation * m_Translation) - m_Center + (m_Rotation * m_Center); } else if (b && !m_Walkthrough) { m_Translation = matrix().inverse().mulPoint(V3F(0, 0, 0)); } m_Walkthrough = b; }
void NAMESPACE::Trackball::animate(float elapsed) { m_Elapsed = elapsed; if (m_Walkthrough) { float speed = m_WalkSpeed * m_Radius * elapsed / 1000.0f; // v3f up = dir2v3f(m_Up); // v3f left = normalize_safe(cross(up,forward)); m_Translation = m_Translation + m_Rotation.inverse() * (speed * ((V3F(0, 0, -1)*m_WalkDir) + (V3F(1, 0, 0)*m_WalkSide))); } }
/* * This little routine draws the little idd-biddy fillet triangle with * the right color, normal, etc. * * HACK ALERT -- there are two aspects to this routine/interface that * are "unfinished". * 1) the third point of the triangle should get a color thats * interpolated beween the front and back color. The interpolant * is not currently being computed. The error introduced by not * doing this should be tiny and/or non-exitant in almost all * expected uses of this code. * * 2) additional normal vectors should be supplied, and these should * be interpolated to fit. Currently, this is not being done. As * above, the expected error of not doing this should be tiny and/or * non-existant in almost all expected uses of this code. */ static void draw_fillet_triangle_n_norms (gleDouble va[3], gleDouble vb[3], gleDouble vc[3], int face, float front_color[3], float back_color[3], double na[3], double nb[3]) { if (front_color != NULL) C3F (front_color); BGNTMESH (-5, 0.0); if (__TUBE_DRAW_FACET_NORMALS) { N3F_D (na); if (face) { V3F (va, -1, FILLET); V3F (vb, -1, FILLET); } else { V3F (vb, -1, FILLET); V3F (va, -1, FILLET); } V3F (vc, -1, FILLET); } else { if (face) { N3F_D (na); V3F (va, -1, FILLET); N3F_D (nb); V3F (vb, -1, FILLET); } else { N3F_D (nb); V3F (vb, -1, FILLET); N3F_D (na); V3F (va, -1, FILLET); N3F_D (nb); } V3F (vc, -1, FILLET); } ENDTMESH (); }
/* ARGSUSED6 */ static void draw_fillet_triangle_plain (gleDouble va[3], gleDouble vb[3], gleDouble vc[3], int face, float front_color[3], float back_color[3]) { if (front_color != NULL) C3F (front_color); BGNTMESH (-5, 0.0); if (face) { V3F (va, -1, FILLET); V3F (vb, -1, FILLET); } else { V3F (vb, -1, FILLET); V3F (va, -1, FILLET); } V3F (vc, -1, FILLET); ENDTMESH (); }
quatf NAMESPACE::Trackball::deltaRotation(float dx, float dy) { //quatf qx=quatf(V3F(1,0,0),dy); //quatf qy=quatf(qx.inverse()*V3F(0,1,0),dx); if (dx*dx + dy*dy > 1e-10f) { quatf qd = quatf(V3F(dy, dx, 0), sqrt(dx*dx + dy*dy)); return (qd); } else { return quatf(); } }
void NAMESPACE::Trackball::updateZoom(uint x, uint y) { float speed = m_BallSpeed * m_Radius * (1.0f + length(m_Translation) / m_Radius); float d = -(float(y) - float(m_PrevY)) * speed / float(m_Width); const float limit = 100.0f; d = min(abs(d), limit)*sign(d); m_PrevX = x; m_PrevY = y; v3f tz; if (!m_Walkthrough) { tz = d * V3F(0, 0, 1); } else { tz = d * dir2v3f(m_Up); } m_Translation = m_Translation + tz; }
static v3f dir2v3f(NAMESPACE::Trackball::e_Direction dir) { switch (dir) { case NAMESPACE::Trackball::X_pos: return V3F(1, 0, 0); break; case NAMESPACE::Trackball::X_neg: return V3F(-1, 0, 0); break; case NAMESPACE::Trackball::Y_pos: return V3F(0, 1, 0); break; case NAMESPACE::Trackball::Y_neg: return V3F(0, -1, 0); break; case NAMESPACE::Trackball::Z_pos: return V3F(0, 0, 1); break; case NAMESPACE::Trackball::Z_neg: return V3F(0, 0, -1); break; }; sl_assert(false); return v3f(0); }
void draw_angle_style_front_cap (int ncp, /* number of contour points */ gleDouble bi[3], /* biscetor */ gleDouble point_array[][3]) /* polyline */ { int j; #ifdef OPENGL_10 GLUtriangulatorObj *tobj; #endif /* OPENGL_10 */ if (bi[2] < 0.0) { VEC_SCALE (bi, -1.0, bi); } #ifdef GL_32 /* old-style gl handles concave polygons no problem, so the code is * simple. New-style gl is a lot more tricky. */ /* draw the end cap */ BGNPOLYGON (); N3F (bi); for (j=0; j<ncp; j++) { V3F (point_array[j], j, FRONT_CAP); } ENDPOLYGON (); #endif /* GL_32 */ #ifdef OPENGL_10 N3F(bi); tobj = gluNewTess (); gluTessCallback (tobj, GLU_BEGIN, glBegin); gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); gluTessCallback (tobj, GLU_END, glEnd); gluBeginPolygon (tobj); for (j=0; j<ncp; j++) { gluTessVertex (tobj, point_array[j], point_array[j]); } gluEndPolygon (tobj); gluDeleteTess (tobj); #endif /* OPENGL_10 */ }
void NAMESPACE::Trackball::reset() { m_Translation = V3F(0, 0, -m_Radius); m_Rotation = quatf(V3F(0, 0, 1), 0.0f); }
v3f NAMESPACE::Trackball::forward() const { v3f front = V3F(0, 0, -1); return matrix().inverse().mulVector(front); }
void draw_segment_c_and_facet_n (int ncp, /* number of contour points */ gleDouble front_contour[][3], gleDouble back_contour[][3], double norm_cont[][3], float color_last[3], float color_next[3], int inext, double len) { int j; /* Note about this code: * At first, when looking at this code, it appears to be really dumb: * the N3F() call appears to be repeated multiple times, for no * apparent purpose. It would seem that a performance improvement * would be gained by stripping it out. !DONT DO IT! * When there are no local lights or viewers, the V3F() subroutine * does not trigger a recalculation of the lighting equations. * However, we MUST trigger lighting, since otherwise colors come out * wrong. Trigger lighting by doing an N3F call. */ /* draw the tube segment */ BGNTMESH (inext, len); for (j=0; j<ncp-1; j++) { C3F (color_last); N3F_D (norm_cont[j]); V3F (front_contour[j], j, FRONT); C3F (color_next); N3F_D (norm_cont[j]); V3F (back_contour[j], j, BACK); C3F (color_last); N3F_D (norm_cont[j]); V3F (front_contour[j+1], j+1, FRONT); C3F (color_next); N3F_D (norm_cont[j]); V3F (back_contour[j+1], j+1, BACK); } if (__TUBE_CLOSE_CONTOUR) { /* connect back up to first point of contour */ C3F (color_last); N3F_D (norm_cont[ncp-1]); V3F (front_contour[ncp-1], ncp-1, FRONT); C3F (color_next); N3F_D (norm_cont[ncp-1]); V3F (back_contour[ncp-1], ncp-1, BACK); C3F (color_last); N3F_D (norm_cont[ncp-1]); V3F (front_contour[0], 0, FRONT); C3F (color_next); N3F_D (norm_cont[ncp-1]); V3F (back_contour[0], 0, BACK); } ENDTMESH (); }