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
00028
00029
00030
00031
00032
00033
00034 #ifndef __VCG_GLADDONS
00035 #define __VCG_GLADDONS
00036
00037 #include <wrap/gl/math.h>
00038 #include <wrap/gl/space.h>
00039 #include <vcg/space/point3.h>
00040 #include <map>
00041
00042 namespace vcg
00043 {
00044 #include "gl_geometry.h"
00048 class Add_Ons
00049 {
00050 public:
00051 enum DrawMode {DMUser,DMWire,DMSolid,DMFlat} ;
00052 private:
00053
00055 static void XAxis(vcg::Point3f zero, vcg::Point3f uno, Matrix44f & tr)
00056 {
00057 #ifndef VCG_USE_EIGEN
00058 tr.SetZero();
00059 *((vcg::Point3f*)&tr[0][0]) = uno-zero;
00060 GetUV(*((vcg::Point3f*)tr[0]),*((vcg::Point3f*)tr[1]),*((vcg::Point3f*)tr[2]));
00061 tr[3][3] = 1.0;
00062 *((vcg::Point3f*)&tr[3][0]) = zero;
00063 #else
00064 tr.col(0).start<3>().setZero();
00065 tr.row(0).start<3>() = (uno-zero).normalized();
00066 tr.row(1).start<3>() = tr.row(0).start<3>().unitOrthogonal();
00067 tr.row(2).start<3>() = tr.row(0).start<3>().cross(tr.row(1).start<3>()).normalized();
00068 tr.row(3) << zero.transpose(), 1.;
00069 #endif
00070 }
00071
00072
00073 static void SetGLParameters(DrawMode DM)
00074 {
00075 switch(DM)
00076 {
00077 case DMUser :
00078 break;
00079 case DMFlat :
00080 glEnable(GL_CULL_FACE);
00081 glEnable(GL_LIGHTING);
00082 glEnable(GL_NORMALIZE);
00083 break;
00084 case DMWire :
00085 glDisable(GL_CULL_FACE);
00086 glDisable(GL_LIGHTING);
00087 glDisable(GL_NORMALIZE);
00088 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
00089 break;
00090 case DMSolid :
00091 glDisable(GL_CULL_FACE);
00092 glPolygonMode(GL_FRONT,GL_FILL);
00093 break;
00094 default :
00095 break;
00096 }
00097 }
00098
00100 static void Cylinder(int slices,float lenght,float width,bool useDisplList)
00101 {
00102 static std::map<int,GLint> Disp_listMap;
00103 GLint cyl_List=-1;
00104 std::map<int,GLint>::const_iterator it=Disp_listMap.find(slices);
00106 bool to_insert=false;
00107 if (useDisplList)
00108 {
00109 if (it!=Disp_listMap.end())
00110 cyl_List=it->second;
00111 else to_insert=true;
00112 }
00113
00114 glScaled(lenght,width,width);
00115
00116 if (((!glIsList(cyl_List))&&(useDisplList))||(!useDisplList))
00117 {
00118 if (useDisplList)
00119 {
00120 cyl_List = glGenLists(1);
00121 glNewList(cyl_List, GL_COMPILE);
00122 }
00123 int b;
00124 vcg::Point3f p0;
00125 vcg::Point3f p1;
00126
00127 float step=6.28f/(float)slices;
00128 float angle=0;
00129 glBegin(GL_TRIANGLE_STRIP);
00130 for(b = 0; b <= slices-1; ++b){
00131 p0 = vcg::Point3f( 0, sin(angle),cos(angle));
00132 p1 = p0; p1[0] = 1.f;
00133 glNormal3f(p0[0],p0[1],p0[2]);
00134 glVertex3d(p0[0],p0[1],p0[2]);
00135 glVertex3d(p1[0],p1[1],p1[2]);
00136 angle+=step;
00137 }
00139 glNormal3f(0,0,1);
00140 glVertex3d(0,0,1);
00141 glVertex3d(1,0,1);
00142
00143 glEnd();
00144
00146 angle=0;
00147 p0=vcg::Point3f(0,0,0);
00148 glBegin(GL_TRIANGLE_FAN);
00149 glNormal3f(-1,0,0);
00150 glVertex3d(p0[0],p0[1],p0[2]);
00151 for(b = 0; b <= slices-1; ++b){
00152 glNormal3f(-1,0,0);
00153 p1 = Point3f( 0, sin(angle),cos(angle));
00154 glVertex3d(p1[0],p1[1],p1[2]);
00155 angle+=step;
00156 }
00157 glNormal3f(-1,0,0);
00158 glVertex3d(0,0,1);
00159 glEnd();
00160
00161 angle=0;
00162 p0=vcg::Point3f(1,0,0);
00163 glBegin(GL_TRIANGLE_FAN);
00164 glNormal3f(1,0,0);
00165 glVertex3d(p0[0],p0[1],p0[2]);
00166 for(b = 0; b <= slices-1; ++b){
00167 glNormal3f(1,0,0);
00168 p1 = Point3f( 1, sin(angle),cos(angle));
00169 glVertex3d(p1[0],p1[1],p1[2]);
00170 angle+=step;
00171 }
00172 glNormal3f(1,0,0);
00173 glVertex3d(1,0,1);
00174 glEnd();
00175
00176
00177 if (useDisplList)
00178 glEndList();
00179 }
00180 if (useDisplList)
00181 {
00182 glCallList(cyl_List);
00184 if (to_insert)
00185 Disp_listMap.insert(std::pair<int,GLint>(slices,cyl_List));
00186 }
00187 }
00188 public:
00189 static void Diamond (float radius,bool useDisplList)
00190 {
00191 static GLint diam_List=-1;
00192
00193 glScaled(radius,radius,radius);
00194 if (((!glIsList(diam_List))&&(useDisplList))||(!useDisplList))
00195 {
00196 if (useDisplList)
00197 {
00198 diam_List = glGenLists(1);
00199 glNewList(diam_List, GL_COMPILE);
00200 }
00201
00202 glBegin(GL_TRIANGLE_FAN);
00203 glNormal3f( 0.0, 1, 0.0);
00204 glVertex3f(0.0,1,0.0);
00205
00206 glNormal3f( 1, 0.0, 0.0);
00207 glVertex3f( 1, 0.0, 0.0);
00208
00209 glNormal3f( 0.0, 0.0, -1);
00210 glVertex3f( 0.0, 0.0,-1);
00211
00212 glNormal3f(-1, 0.0 , 0.0);
00213 glVertex3f(-1, 0.0, 0.0);
00214
00215 glNormal3f( 0.0, 0.0, 1);
00216 glVertex3f( 0.0, 0.0, 1);
00217
00218 glNormal3f( 1, 0.0, 0.0);
00219 glVertex3f( 1, 0.0, 0.0);
00220
00221 glEnd();
00222
00223 glBegin(GL_TRIANGLE_FAN);
00224 glNormal3f( 0.0, 1, 0.0);
00225 glVertex3f( 0.0,-1, 0.0);
00226
00227 glNormal3f( 1, 0.0, 0.0);
00228 glVertex3f( 1, 0.0, 0.0);
00229
00230 glNormal3f( 0.0, 0.0, 1);
00231 glVertex3f( 0.0, 0.0, 1);
00232
00233 glNormal3f(-1,0.0 , 0.0);
00234 glVertex3f(-1, 0.0, 0.0);
00235
00236 glNormal3f( 0.0,0.0, -1);
00237 glVertex3f( 0.0, 0.0,-1);
00238
00239 glNormal3f( 1, 0.0, 0.0);
00240 glVertex3f( 1, 0.0, 0.0);
00241 glEnd();
00242 if (useDisplList)
00243 glEndList();
00244 }
00245 if (useDisplList)
00246 glCallList(diam_List);
00247 }
00248
00250 static void Cone(int slices,float lenght,float width,bool useDisplList)
00251 {
00252 static std::map<int,GLint> Disp_listMap;
00253 GLint cone_List=-1;
00254 std::map<int,GLint>::const_iterator it=Disp_listMap.find(slices);
00256 bool to_insert=false;
00257
00258 if (useDisplList)
00259 {
00260 if (it!=Disp_listMap.end())
00261 cone_List=it->second;
00262 else to_insert=true;
00263 }
00264
00265 glScaled(lenght,width,width);
00266 if (((!glIsList(cone_List))&&(useDisplList))||(!useDisplList))
00267 {
00268 int h=1;
00269 vcg::Point3f p0;
00270 vcg::Point3f P[2];
00271 vcg::Point3f N[2];
00272 glScaled(lenght,width,width);
00273 if (useDisplList)
00274 {
00275 cone_List = glGenLists(1);
00276 glNewList(cone_List, GL_COMPILE);
00277 }
00278 for(h=0; h < 2; ++h)
00279 {
00280
00281
00282 p0 = Point3f(0,0,0);
00283 if(h==0) p0[0]+=1.f;
00284
00285
00286 N[0]= Point3f( 1.f,sinf(0),cosf(0) );
00287 P[0]= Point3f( 0,sinf(0),cosf(0));
00288 int b;
00289 for(b = 1; b <= slices; ++b)
00290 {
00291 float angle = -6.28f*(float)b/(float)slices;
00292 if (b==slices) angle=0;
00293 N[1] = Point3f( 1.f, sinf(angle), cosf(angle) );
00294 P[1] = Point3f( 0, sinf(angle), cosf(angle));
00295 glBegin(GL_TRIANGLES);
00296 Point3f n = ( (P[0]-p0) ^ (P[1]-p0) ).Normalize();
00297
00298 glNormal(n);
00299 glVertex(p0);
00300 glNormal3f(N[0][0],N[0][1],N[0][2]);
00301 glVertex3f(P[0][0],P[0][1],P[0][2]);
00302 glNormal3f(N[1][0],N[1][1],N[1][2]);
00303 glVertex3f(P[1][0],P[1][1],P[1][2]);
00304 glEnd();
00305
00306 N[0] = N[1];
00307 P[0] = P[1];
00308 }
00309
00310 }
00311 if (useDisplList)
00312 glEndList();
00313 }
00314 if (useDisplList)
00315 {
00316 glCallList(cone_List);
00318 if (to_insert)
00319 Disp_listMap.insert(std::pair<int,GLint>(slices,cone_List));
00320 }
00321 }
00322
00323 public:
00324
00331 template <DrawMode dm>
00332 static void glArrow(Point3f tail, Point3f head,float body_width,float head_lenght,
00333 float head_width,int body_slice=10,int head_slice=10,bool useDisplList=true)
00334 {
00335 if (tail!=head)
00336 {
00337
00338 Matrix44f tr;
00339 XAxis(tail,head,tr);
00340 glPushAttrib(GL_ALL_ATTRIB_BITS);
00341 SetGLParameters(dm);
00342 glPushMatrix();
00343 glMultMatrixf(&tr[0][0]);
00344 vcg::Point3f Direct=(head-tail);
00345 if(body_width == 0) body_width = Direct.Norm()/40.0f;
00346 if(head_lenght == 0) head_lenght = Direct.Norm()/5.0f;
00347 if(head_width == 0) head_width = Direct.Norm()/15.0f;
00348 float l_body=Direct.Norm()-head_lenght;
00349 glPushMatrix();
00350
00351 Cylinder(body_slice,l_body,body_width,useDisplList);
00352 glPopMatrix();
00353 glTranslate(vcg::Point3f(l_body,0,0));
00354 Cone(head_slice,head_lenght,head_width,useDisplList);
00355 glPopMatrix();
00356
00357 glPopAttrib();
00358
00359 }
00360 }
00361
00365 template <DrawMode dm>
00366 static void glCone(Point3f tail, Point3f head,float width,int slice=10,bool useDisplList=true)
00367 {
00368 if (tail!=head)
00369 {
00370 Matrix44f tr;
00371 XAxis(tail,head,tr);
00372 glPushAttrib(GL_ALL_ATTRIB_BITS);
00373 SetGLParameters(dm);
00374 glPushMatrix();
00375 glMultMatrixf(&tr[0][0]);
00376 vcg::Point3f Direct=(head-tail);
00377 float l_body=Direct.Norm();
00378
00379 Cone(slice,l_body,width,useDisplList);
00380 glPopMatrix();
00381 glPopAttrib();
00382 }
00383 }
00384
00388 template <DrawMode dm>
00389 static void glCylinder(Point3f tail, Point3f head,float width,int slice=10,bool useDisplList=true)
00390 {
00391 if (tail!=head)
00392 {
00393 Matrix44f tr;
00394 XAxis(tail,head,tr);
00395 glPushAttrib(GL_ALL_ATTRIB_BITS);
00396 SetGLParameters(dm);
00397 glPushMatrix();
00398 glMultMatrixf(&tr[0][0]);
00399 vcg::Point3f Direct=(head-tail);
00400 float l_body=Direct.Norm();
00401
00402 Cylinder(slice,l_body,width,useDisplList);
00403 glPopMatrix();
00404 glPopAttrib();
00405 }
00406
00407 }
00408
00413 template <DrawMode dm>
00414 static void glPoint(vcg::Point3f Center,float size,int slices =16,int stacks =16)
00415 {
00416 if (size!=0){
00417 glPushMatrix();
00418 glTranslate(Center);
00419 if (dm==DMWire)
00420 glutWireSphere(size,slices,stacks);
00421 else
00422 if (dm==DMSolid)
00423 glutSolidSphere(size,slices,stacks);
00424 else
00425 glutSolidSphere(size,slices,stacks);
00426 glPopMatrix();
00427 }
00428 }
00429
00434 template <DrawMode dm>
00435 static void glDiamond (Point3f Center, float size,bool useDisplList=true)
00436 {
00437 if (size!=0){
00438 glPushAttrib(GL_ALL_ATTRIB_BITS);
00439 SetGLParameters(dm);
00440 glPushMatrix();
00441 glTranslated(Center[0],Center[1],Center[2]);
00442 Diamond(size,useDisplList);
00443 glPopMatrix();
00444 glPopAttrib();
00445 }
00446 }
00447 };
00448 }
00449 #endif