00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <sofa/helper/gl/Axis.h>
00028
00029 #include <sofa/helper/system/gl.h>
00030
00031 #include <assert.h>
00032 #include <algorithm>
00033 #include <iostream>
00034 using std::cout;
00035 using std::cerr;
00036 using std::endl;
00037
00038
00039 namespace sofa
00040 {
00041
00042 namespace helper
00043 {
00044
00045 namespace gl
00046 {
00047
00048 static const int quadricDiscretisation = 16;
00049
00050
00051 std::map < std::pair<std::pair<float,float>,float>, Axis* > Axis::axisMap;
00052
00053 void Axis::initDraw()
00054 {
00055 if (quadratic!=NULL) return;
00056
00057 Vector3 L= length;
00058 SReal Lmin = L[0];
00059 if (L[1]<Lmin) Lmin = L[1];
00060 if (L[2]<Lmin) Lmin = L[2];
00061 SReal Lmax = L[0];
00062 if (L[1]>Lmax) Lmax = L[1];
00063 if (L[2]>Lmax) Lmax = L[2];
00064 if (Lmax > Lmin*2 && Lmin > 0.0)
00065 Lmax = Lmin*2;
00066 if (Lmax > Lmin*2)
00067 Lmin = Lmax/(SReal)1.414;
00068 Vector3 l(Lmin / (SReal)10, Lmin / (SReal)10, Lmin / (SReal)10);
00069 Vector3 lc(Lmax / (SReal)5, Lmax / (SReal)5, Lmax / (SReal)5);
00070 Vector3 Lc = lc;
00071
00072 quadratic=gluNewQuadric();
00073 gluQuadricNormals(quadratic, GLU_SMOOTH);
00074 gluQuadricTexture(quadratic, GL_TRUE);
00075
00076 displayList=glGenLists(1);
00077
00078 glNewList(displayList, GL_COMPILE);
00079
00080
00081 glColor3f(1,1,1);
00082 gluSphere(quadratic,l[0],quadricDiscretisation,quadricDiscretisation/2);
00083
00084 if (L[0] > 0.0)
00085 {
00086
00087 glColor3f(1,0,0);
00088 glRotatef(90,0,1,0);
00089 gluCylinder(quadratic,l[0],l[0],L[0],quadricDiscretisation,quadricDiscretisation);
00090 glRotatef(-90,0,1,0);
00091
00092 glTranslated(L[0],0,0);
00093 glRotatef(90,0,1,0);
00094 gluDisk(quadratic,0,lc[0],quadricDiscretisation,quadricDiscretisation);
00095 gluCylinder(quadratic,lc[0],0,Lc[0],quadricDiscretisation,quadricDiscretisation);
00096 glRotatef(-90,0,1,0);
00097 glTranslated(-L[0],0,0);
00098 }
00099 if (L[1] > 0.0)
00100 {
00101
00102 glColor3f(0,1,0);
00103 glRotatef(-90,1,0,0);
00104 gluCylinder(quadratic,l[1],l[1],L[1],quadricDiscretisation,quadricDiscretisation);
00105 glRotatef(90,1,0,0);
00106
00107 glTranslated(0,L[1],0);
00108 glRotatef(-90,1,0,0);
00109 gluDisk(quadratic,0,lc[1],quadricDiscretisation,quadricDiscretisation);
00110 gluCylinder(quadratic,lc[1],0,Lc[1],quadricDiscretisation,quadricDiscretisation);
00111 glRotatef(90,1,0,0);
00112 glTranslated(0,-L[1],0);
00113 }
00114 if (L[2] > 0.0)
00115 {
00116
00117 glColor3f(0,0,1);
00118 gluCylinder(quadratic,l[2],l[2],L[2],quadricDiscretisation,quadricDiscretisation);
00119
00120 glTranslated(0,0,L[2]);
00121 gluDisk(quadratic,0,lc[2],quadricDiscretisation,quadricDiscretisation);
00122 gluCylinder(quadratic,lc[2],0,Lc[2],quadricDiscretisation,quadricDiscretisation);
00123 glTranslated(0,0,-L[2]);
00124 }
00125 glEndList();
00126 }
00127
00128 void Axis::draw()
00129 {
00130 initDraw();
00131
00132 glPushMatrix();
00133 glPushAttrib(GL_ENABLE_BIT);
00134
00135 glEnable(GL_LIGHTING);
00136 glEnable(GL_COLOR_MATERIAL);
00137 glMultMatrixd(matTransOpenGL);
00138 glCallList(displayList);
00139
00140 glPopAttrib();
00141 glPopMatrix();
00142 }
00143
00144 void Axis::update(const double *mat)
00145 {
00146 std::copy(mat,mat+16, matTransOpenGL);
00147 }
00148
00149 void Axis::update(const Vector3& center, const double orient[4][4])
00150 {
00151 matTransOpenGL[0] = orient[0][0];
00152 matTransOpenGL[1] = orient[0][1];
00153 matTransOpenGL[2] = orient[0][2];
00154 matTransOpenGL[3] = 0;
00155
00156 matTransOpenGL[4] = orient[1][0];
00157 matTransOpenGL[5] = orient[1][1];
00158 matTransOpenGL[6] = orient[1][2];
00159 matTransOpenGL[7] = 0;
00160
00161 matTransOpenGL[8] = orient[2][0];
00162 matTransOpenGL[9] = orient[2][1];
00163 matTransOpenGL[10]= orient[2][2];
00164 matTransOpenGL[11] = 0;
00165
00166 matTransOpenGL[12] = center[0];
00167 matTransOpenGL[13] = center[1];
00168 matTransOpenGL[14] = center[2];
00169 matTransOpenGL[15] = 1;
00170 }
00171
00172 void Axis::update(const Vector3& center, const Quaternion& orient)
00173 {
00174 orient.writeOpenGlMatrix(matTransOpenGL);
00175 matTransOpenGL[12] = center[0];
00176 matTransOpenGL[13] = center[1];
00177 matTransOpenGL[14] = center[2];
00178 }
00179
00180 Axis::Axis(SReal len)
00181 {
00182 quadratic = NULL;
00183 length = Vector3(len,len,len);
00184 update(Vector3(0,0,0), Quaternion(1,0,0,0));
00185 }
00186
00187 Axis::Axis(const Vector3& len)
00188 {
00189 quadratic = NULL;
00190 length = len;
00191 update(Vector3(0,0,0), Quaternion(1,0,0,0));
00192 }
00193
00194 Axis::Axis(const Vector3& center, const Quaternion& orient, const Vector3& len)
00195 {
00196 quadratic = NULL;
00197 length = len;
00198 update(center, orient);
00199 }
00200
00201 Axis::Axis(const Vector3& center, const double orient[4][4], const Vector3& len)
00202 {
00203 quadratic = NULL;
00204 length = len;
00205 update(center, orient);
00206 }
00207
00208 Axis::Axis(const double *mat, const Vector3& len)
00209 {
00210 quadratic = NULL;
00211 length = len;
00212 update(mat);
00213 }
00214
00215 Axis::Axis(const Vector3& center, const Quaternion& orient, SReal len)
00216 {
00217 quadratic = NULL;
00218 length = Vector3(len,len,len);
00219 update(center, orient);
00220 }
00221 Axis::Axis(const Vector3& center, const double orient[4][4], SReal len)
00222 {
00223 quadratic = NULL;
00224 length = Vector3(len,len,len);
00225 update(center, orient);
00226 }
00227
00228 Axis::Axis(const double *mat, SReal len)
00229 {
00230 quadratic = NULL;
00231 length = Vector3(len,len,len);
00232 update(mat);
00233 }
00234
00235 Axis::~Axis()
00236 {
00237 if (quadratic != NULL)
00238 gluDeleteQuadric(quadratic);
00239 }
00240
00241 Axis* Axis::get(const Vector3& len)
00242 {
00243 Axis*& a = axisMap[std::make_pair(std::make_pair((float)len[0],(float)len[1]),(float)len[2])];
00244 if (a==NULL)
00245 a = new Axis(len);
00246 return a;
00247 }
00248
00249 void Axis::draw(const Vector3& center, const Quaternion& orient, const Vector3& len)
00250 {
00251 Axis* a = get(len);
00252 a->update(center, orient);
00253 a->draw();
00254 }
00255
00256 void Axis::draw(const Vector3& center, const double orient[4][4], const Vector3& len)
00257 {
00258 Axis* a = get(len);
00259 a->update(center, orient);
00260 a->draw();
00261 }
00262
00263 void Axis::draw(const double *mat, const Vector3& len)
00264 {
00265 Axis* a = get(len);
00266 a->update(mat);
00267 a->draw();
00268 }
00269
00270 void Axis::draw(const Vector3& center, const Quaternion& orient, SReal len)
00271 {
00272 Axis* a = get(Vector3(len,len,len));
00273 a->update(center, orient);
00274 a->draw();
00275 }
00276
00277 void Axis::draw(const Vector3& center, const double orient[4][4], SReal len)
00278 {
00279 Axis* a = get(Vector3(len,len,len));
00280 a->update(center, orient);
00281 a->draw();
00282 }
00283
00284 void Axis::draw(const double *mat, SReal len)
00285 {
00286 Axis* a = get(Vector3(len,len,len));
00287 a->update(mat);
00288 a->draw();
00289 }
00290
00291 void Axis::draw(const Vector3& p1, const Vector3& p2, const double& r)
00292 {
00293 Vector3 v = p2-p1;
00294 Axis::draw(p1, p1+v*0.9, r,r);
00295 Axis::draw(p1+v*0.9,p2, 2.0*r,0.0);
00296 }
00297
00298 void Axis::draw(const Vector3& p1, const Vector3& p2, const double& r1, const double& r2 )
00299 {
00300 int i;
00301 double theta;
00302 Vec3d n,p,q,perp;
00303
00304 double theta2 = 2*3.141592653;
00305 double m = 16;
00306
00307
00308 n = p1-p2;
00309
00310
00311
00312
00313
00314
00315 if (n[1] != 0 || n[2] != 0) perp = Vec3d(1,0,0);
00316 else perp = Vec3d(0,1,0);
00317
00318
00319 q = perp.cross(n);
00320 perp = n.cross(q);
00321 perp.normalize();
00322 q.normalize();
00323
00324 glBegin(GL_QUAD_STRIP);
00325 for (i=0;i<=m;i++) {
00326 theta = i * (theta2) / m;
00327
00328 n = perp*cos(theta) + q*sin(theta);
00329 n.normalize();
00330
00331 p = p1 + n*r1;
00332 glNormal3d(n[0],n[1],n[2]); glTexCoord2d(i/(double)m,0.0);
00333 glVertex3d(p[0],p[1],p[2]);
00334
00335 p = p2 + n*r2;
00336 glNormal3d(n[0],n[1],n[2]); glTexCoord2d(i/(double)m,1.0);
00337 glVertex3d(p[0],p[1],p[2]);
00338
00339 }
00340 glEnd();
00341
00342 glBegin(GL_TRIANGLE_FAN);
00343 glVertex3d(p1[0],p1[1],p1[2]);
00344 for (i=0;i<=m && r1 != 0;i++) {
00345 theta = i * (theta2) / m;
00346
00347 n = perp*cos(theta) + q*sin(theta);
00348 n.normalize();
00349
00350 p = p1 + n*r1;
00351 glNormal3d(n[0],n[1],n[2]); glTexCoord2d(i/(double)m,0.0);
00352 glVertex3d(p[0],p[1],p[2]);
00353 }
00354 glEnd();
00355
00356 glBegin(GL_TRIANGLE_FAN);
00357 glVertex3d(p2[0],p2[1],p2[2]);
00358 for (i=0;i<=m && r2 != 0;i++) {
00359 theta = i * (theta2) / m;
00360
00361 n = perp*cos(theta) + q*sin(theta);
00362 n.normalize();
00363
00364 p = p2 + n*r2;
00365 glNormal3d(n[0],n[1],n[2]); glTexCoord2d(i/(double)m,1.0);
00366 glVertex3d(p[0],p[1],p[2]);
00367 }
00368 glEnd();
00369
00370 }
00371
00372 }
00373
00374 }
00375
00376 }
00377