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} ;
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 DMWire :
00080 glDisable(GL_CULL_FACE);
00081 glDisable(GL_LIGHTING);
00082 glDisable(GL_NORMALIZE);
00083 glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
00084 break;
00085 case DMSolid :
00086 glDisable(GL_CULL_FACE);
00087 glPolygonMode(GL_FRONT,GL_FILL);
00088 break;
00089 default :
00090 break;
00091 }
00092 }
00093
00095 static void Cylinder(int slices,float lenght,float width,bool useDisplList)
00096 {
00097 static std::map<int,GLint> Disp_listMap;
00098 GLint cyl_List=-1;
00099 std::map<int,GLint>::const_iterator it=Disp_listMap.find(slices);
00101 bool to_insert=false;
00102 if (useDisplList)
00103 {
00104 if (it!=Disp_listMap.end())
00105 cyl_List=it->second;
00106 else to_insert=true;
00107 }
00108
00109 glScaled(lenght,width,width);
00110
00111 if (((!glIsList(cyl_List))&&(useDisplList))||(!useDisplList))
00112 {
00113 if (useDisplList)
00114 {
00115 cyl_List = glGenLists(1);
00116 glNewList(cyl_List, GL_COMPILE);
00117 }
00118 int b;
00119 vcg::Point3f p0;
00120 vcg::Point3f p1;
00121
00122 float step=6.28f/(float)slices;
00123 float angle=0;
00124 glBegin(GL_TRIANGLE_STRIP);
00125 for(b = 0; b <= slices-1; ++b){
00126 p0 = vcg::Point3f( 0, sin(angle),cos(angle));
00127 p1 = p0; p1[0] = 1.f;
00128 glNormal3f(p0[0],p0[1],p0[2]);
00129 glVertex3d(p0[0],p0[1],p0[2]);
00130 glVertex3d(p1[0],p1[1],p1[2]);
00131 angle+=step;
00132 }
00134 glNormal3f(0,0,1);
00135 glVertex3d(0,0,1);
00136 glVertex3d(1,0,1);
00137
00138 glEnd();
00139
00141 angle=0;
00142 p0=vcg::Point3f(0,0,0);
00143 glBegin(GL_TRIANGLE_FAN);
00144 glNormal3f(-1,0,0);
00145 glVertex3d(p0[0],p0[1],p0[2]);
00146 for(b = 0; b <= slices-1; ++b){
00147 glNormal3f(-1,0,0);
00148 p1 = Point3f( 0, sin(angle),cos(angle));
00149 glVertex3d(p1[0],p1[1],p1[2]);
00150 angle+=step;
00151 }
00152 glNormal3f(-1,0,0);
00153 glVertex3d(0,0,1);
00154 glEnd();
00155
00156 angle=0;
00157 p0=vcg::Point3f(1,0,0);
00158 glBegin(GL_TRIANGLE_FAN);
00159 glNormal3f(1,0,0);
00160 glVertex3d(p0[0],p0[1],p0[2]);
00161 for(b = 0; b <= slices-1; ++b){
00162 glNormal3f(1,0,0);
00163 p1 = Point3f( 1, sin(angle),cos(angle));
00164 glVertex3d(p1[0],p1[1],p1[2]);
00165 angle+=step;
00166 }
00167 glNormal3f(1,0,0);
00168 glVertex3d(1,0,1);
00169 glEnd();
00170
00171
00172 if (useDisplList)
00173 glEndList();
00174 }
00175 if (useDisplList)
00176 {
00177 glCallList(cyl_List);
00179 if (to_insert)
00180 Disp_listMap.insert(std::pair<int,GLint>(slices,cyl_List));
00181 }
00182 }
00183 public:
00184 static void Diamond (float radius,bool useDisplList)
00185 {
00186 static GLint diam_List=-1;
00187
00188 glScaled(radius,radius,radius);
00189 if (((!glIsList(diam_List))&&(useDisplList))||(!useDisplList))
00190 {
00191 if (useDisplList)
00192 {
00193 diam_List = glGenLists(1);
00194 glNewList(diam_List, GL_COMPILE);
00195 }
00196
00197 glBegin(GL_TRIANGLE_FAN);
00198 glNormal3f( 0.0, 1, 0.0);
00199 glVertex3f(0.0,1,0.0);
00200
00201 glNormal3f( 1, 0.0, 0.0);
00202 glVertex3f( 1, 0.0, 0.0);
00203
00204 glNormal3f( 0.0, 0.0, -1);
00205 glVertex3f( 0.0, 0.0,-1);
00206
00207 glNormal3f(-1, 0.0 , 0.0);
00208 glVertex3f(-1, 0.0, 0.0);
00209
00210 glNormal3f( 0.0, 0.0, 1);
00211 glVertex3f( 0.0, 0.0, 1);
00212
00213 glNormal3f( 1, 0.0, 0.0);
00214 glVertex3f( 1, 0.0, 0.0);
00215
00216 glEnd();
00217
00218 glBegin(GL_TRIANGLE_FAN);
00219 glNormal3f( 0.0, 1, 0.0);
00220 glVertex3f( 0.0,-1, 0.0);
00221
00222 glNormal3f( 1, 0.0, 0.0);
00223 glVertex3f( 1, 0.0, 0.0);
00224
00225 glNormal3f( 0.0, 0.0, 1);
00226 glVertex3f( 0.0, 0.0, 1);
00227
00228 glNormal3f(-1,0.0 , 0.0);
00229 glVertex3f(-1, 0.0, 0.0);
00230
00231 glNormal3f( 0.0,0.0, -1);
00232 glVertex3f( 0.0, 0.0,-1);
00233
00234 glNormal3f( 1, 0.0, 0.0);
00235 glVertex3f( 1, 0.0, 0.0);
00236 glEnd();
00237 if (useDisplList)
00238 glEndList();
00239 }
00240 if (useDisplList)
00241 glCallList(diam_List);
00242 }
00243
00245 static void Cone(int slices,float lenght,float width,bool useDisplList)
00246 {
00247 assert(!glGetError());
00248 static std::map<int,GLint> Disp_listMap;
00249 GLint cone_List=-1;
00250 std::map<int,GLint>::const_iterator it=Disp_listMap.find(slices);
00252 bool to_insert=false;
00253
00254 if (useDisplList)
00255 {
00256 if (it!=Disp_listMap.end())
00257 cone_List=it->second;
00258 else to_insert=true;
00259 }
00260
00261 glScaled(lenght,width,width);
00262 assert(!glGetError());
00263 if (((!glIsList(cone_List))&&(useDisplList))||(!useDisplList))
00264 {
00265 int h=1;
00266 vcg::Point3f p0;
00267 vcg::Point3f P[2];
00268 vcg::Point3f N[2];
00269 assert(!glGetError());
00270 glScaled(lenght,width,width);
00271 if (useDisplList)
00272 {
00273 cone_List = glGenLists(1);
00274 glNewList(cone_List, GL_COMPILE);
00275 }
00276 for(h=0; h < 2; ++h)
00277 {
00278 assert(!glGetError());
00279
00280 p0 = Point3f(0,0,0);
00281 if(h==0) p0[0]+=1.f;
00282
00283
00284 N[0]= Point3f( 1.f,sinf(0),cosf(0) );
00285 P[0]= Point3f( 0,sinf(0),cosf(0));
00286 int b;
00287 for(b = 1; b <= slices; ++b)
00288 {
00289 float angle = -6.28f*(float)b/(float)slices;
00290 if (b==slices) angle=0;
00291 N[1] = Point3f( 1.f, sinf(angle), cosf(angle) );
00292 P[1] = Point3f( 0, sinf(angle), cosf(angle));
00293 assert(!glGetError());
00294 glBegin(GL_TRIANGLES);
00295 Point3f n = ( (P[0]-p0) ^ (P[2]-p0) ).Normalize();
00296 glNormal3f(n[0],n[1],n[2]);
00297 glVertex3f(p0[0],p0[1],p0[2]);
00298 glNormal3f(N[0][0],N[0][1],N[0][2]);
00299 glVertex3f(P[0][0],P[0][1],P[0][2]);
00300 glNormal3f(N[1][0],N[1][1],N[1][2]);
00301 glVertex3f(P[1][0],P[1][1],P[1][2]);
00302 glEnd();
00303 assert(!glGetError());
00304 N[0] = N[1];
00305 P[0] = P[1];
00306 }
00307
00308 }
00309 if (useDisplList)
00310 glEndList();
00311 }
00312 if (useDisplList)
00313 {
00314 glCallList(cone_List);
00316 if (to_insert)
00317 Disp_listMap.insert(std::pair<int,GLint>(slices,cone_List));
00318 }
00319 }
00320
00321 public:
00322
00329 template <DrawMode dm>
00330 static void glArrow(Point3f tail, Point3f head,float body_width,float head_lenght,
00331 float head_width,int body_slice=10,int head_slice=10,bool useDisplList=true)
00332 {
00333 if (tail!=head)
00334 {
00335
00336 Matrix44f tr;
00337 XAxis(tail,head,tr);
00338 glPushAttrib(GL_ALL_ATTRIB_BITS);
00339 SetGLParameters(dm);
00340 glPushMatrix();
00341 glMultMatrixf(&tr[0][0]);
00342 vcg::Point3f Direct=(head-tail);
00343 float l_body=Direct.Norm()-head_lenght;
00344 glPushMatrix();
00345
00346 Cylinder(body_slice,l_body,body_width,useDisplList);
00347 glPopMatrix();
00348 glTranslate(vcg::Point3f(l_body,0,0));
00349 Cone(head_slice,head_lenght,head_width,useDisplList);
00350 glPopMatrix();
00351
00352 glPopAttrib();
00353
00354 }
00355 }
00356
00360 template <DrawMode dm>
00361 static void glCone(Point3f tail, Point3f head,float width,int slice=10,bool useDisplList=true)
00362 {
00363 if (tail!=head)
00364 {
00365 Matrix44f tr;
00366 XAxis(tail,head,tr);
00367 glPushAttrib(GL_ALL_ATTRIB_BITS);
00368 SetGLParameters(dm);
00369 glPushMatrix();
00370 glMultMatrixf(&tr[0][0]);
00371 vcg::Point3f Direct=(head-tail);
00372 float l_body=Direct.Norm();
00373
00374 Cone(slice,l_body,width,useDisplList);
00375 glPopMatrix();
00376 glPopAttrib();
00377 }
00378 }
00379
00383 template <DrawMode dm>
00384 static void glCylinder(Point3f tail, Point3f head,float width,int slice=10,bool useDisplList=true)
00385 {
00386 if (tail!=head)
00387 {
00388 Matrix44f tr;
00389 XAxis(tail,head,tr);
00390 glPushAttrib(GL_ALL_ATTRIB_BITS);
00391 SetGLParameters(dm);
00392 glPushMatrix();
00393 glMultMatrixf(&tr[0][0]);
00394 vcg::Point3f Direct=(head-tail);
00395 float l_body=Direct.Norm();
00396
00397 Cylinder(slice,l_body,width,useDisplList);
00398 glPopMatrix();
00399 glPopAttrib();
00400 }
00401
00402 }
00403
00408 template <DrawMode dm>
00409 static void glPoint(vcg::Point3f Center,float size,int slices =16,int stacks =16)
00410 {
00411 if (size!=0){
00412 glPushMatrix();
00413 glTranslate(Center);
00414 if (dm==DMWire)
00415 glutWireSphere(size,slices,stacks);
00416 else
00417 if (dm==DMSolid)
00418 glutSolidSphere(size,slices,stacks);
00419 else
00420 glutSolidSphere(size,slices,stacks);
00421 glPopMatrix();
00422 }
00423 }
00424
00429 template <DrawMode dm>
00430 static void glDiamond (Point3f Center, float size,bool useDisplList=true)
00431 {
00432 if (size!=0){
00433 glPushAttrib(GL_ALL_ATTRIB_BITS);
00434 SetGLParameters(dm);
00435 glPushMatrix();
00436 glTranslated(Center[0],Center[1],Center[2]);
00437 Diamond(size,useDisplList);
00438 glPopMatrix();
00439 glPopAttrib();
00440 }
00441 }
00442 };
00443 }
00444 #endif