Axis.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                              SOFA :: Framework                              *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
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 //GLuint Axis::displayList;
00050 //GLUquadricObj *Axis::quadratic = NULL;
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); // = L / 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     // Center
00081     glColor3f(1,1,1);
00082     gluSphere(quadratic,l[0],quadricDiscretisation,quadricDiscretisation/2);
00083 
00084     if (L[0] > 0.0)
00085     {
00086         // X Axis
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         // Y Axis
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         // Z Axis
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; //precision
00306   
00307   /* Normal pointing from p1 to p2 */
00308   n = p1-p2;
00309   
00310    /*
00311   Create two perpendicular vectors perp and q
00312   on the plane of the disk:  
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 } // namespace gl
00373 
00374 } // namespace helper
00375 
00376 } // namespace sofa
00377 

Generated on Sun Nov 23 02:29:29 2008 for Sofa by  doxygen 1.5.7.1