00001 00002 /*************************************************************************** 00003 * Copyright (C) 2005 by Robot Group Leipzig * 00004 * martius@informatik.uni-leipzig.de * 00005 * fhesse@informatik.uni-leipzig.de * 00006 * der@informatik.uni-leipzig.de * 00007 * frankguettler@gmx.de * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the * 00021 * Free Software Foundation, Inc., * 00022 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00023 * * 00024 *************************************************************************** 00025 * * 00026 * This file provides basic primitives for ODE and openscenegraph * 00027 * * 00028 * * 00029 * $Log: primitive.h,v $ 00030 * Revision 1.19 2009/10/23 12:47:13 guettler 00031 * hack for tasked simulations: 00032 * there are some problems if running in parallel mode, 00033 * if you do not destroy the geom, everything is fine 00034 * (should be no problem because world is destroying geoms too) 00035 * 00036 * Revision 1.18 2009/08/10 07:46:36 guettler 00037 * removed typedef to avoid compiler warnings 00038 * 00039 * Revision 1.17 2009/08/03 14:09:48 jhoffmann 00040 * Remove some compiling warnings, memory leaks; Add some code cleanups 00041 * 00042 * Revision 1.16 2009/03/13 09:19:53 martius 00043 * changed texture handling in osgprimitive 00044 * new OsgBoxTex that supports custom texture repeats and so on 00045 * Box uses osgBoxTex now. We also need osgSphereTex and so on. 00046 * setTexture has to be called before init() of the primitive 00047 * 00048 * Revision 1.15 2008/09/11 15:24:01 martius 00049 * motioncallback resurrected 00050 * noContact substance 00051 * use slider center of the connecting objects for slider drawing 00052 * 00053 * Revision 1.14 2008/05/07 16:45:51 martius 00054 * code cosmetics and documentation 00055 * 00056 * Revision 1.13 2008/05/01 22:03:54 martius 00057 * build system expanded to allow system wide installation 00058 * that implies <ode_robots/> for headers in simulations 00059 * 00060 * Revision 1.12 2007/11/07 13:19:01 martius 00061 * toLocal: coordinate transformation 00062 * 00063 * Revision 1.11 2007/08/23 14:51:28 martius 00064 * Ray 00065 * 00066 * Revision 1.10 2007/07/31 08:21:34 martius 00067 * OSGMesh does not need GlobalData 00068 * drawBoundings moved to OsgHandle 00069 * 00070 * Revision 1.9 2007/07/17 07:20:04 martius 00071 * setMass added 00072 * 00073 * Revision 1.8 2007/07/03 13:12:52 martius 00074 * limitLinearVel 00075 * 00076 * Revision 1.7 2007/03/16 10:51:36 martius 00077 * each primitive has a substance 00078 * geom userdata is set to primitive itself 00079 * 00080 * Revision 1.6 2007/02/23 15:13:24 martius 00081 * setColor 00082 * 00083 * Revision 1.5 2007/01/26 12:05:36 martius 00084 * joint support forces in uniform manner 00085 * 00086 * Revision 1.4 2006/12/13 09:09:56 martius 00087 * transform objects delete child 00088 * 00089 * Revision 1.3 2006/08/30 08:58:56 martius 00090 * categories and collision mask used for static geoms to reduce number of collision checks 00091 * 00092 * Revision 1.2 2006/07/14 12:23:35 martius 00093 * selforg becomes HEAD 00094 * 00095 * Revision 1.1.2.18 2006/07/14 11:23:38 martius 00096 * revert to older revision of robot3 00097 * 00098 * Revision 1.1.2.16 2006/06/29 16:35:32 robot3 00099 * -Mesh code optimized 00100 * -includes cleared up, more using forward declarations 00101 * (sometimes additionally #include "osgprimitive.h" is needed) 00102 * 00103 * Revision 1.1.2.15 2006/06/27 14:14:29 robot3 00104 * -optimized mesh and boundingshape code 00105 * -other changes 00106 * 00107 * Revision 1.1.2.14 2006/06/23 08:53:56 robot3 00108 * made some changes on primitive Mesh 00109 * 00110 * Revision 1.1.2.13 2006/05/29 22:03:26 martius 00111 * cylinder 00112 * 00113 * Revision 1.1.2.12 2006/05/29 21:27:02 robot3 00114 * made some preparations for the boundingshape of the Mesh 00115 * 00116 * Revision 1.1.2.11 2006/05/28 22:14:57 martius 00117 * heightfield included 00118 * 00119 * Revision 1.1.2.10 2006/05/24 12:23:10 robot3 00120 * -passive_mesh works now (simple bound_version) 00121 * -Primitive Mesh now exists (simple bound_version) 00122 * 00123 * Revision 1.1.2.9 2006/04/04 14:13:24 fhesse 00124 * documentation improved 00125 * 00126 * Revision 1.1.2.8 2006/03/29 15:07:17 martius 00127 * Dummy Primitive 00128 * 00129 * Revision 1.1.2.7 2006/01/31 15:45:35 martius 00130 * proper destruction 00131 * 00132 * Revision 1.1.2.6 2006/01/12 14:21:00 martius 00133 * drawmode, material 00134 * 00135 * Revision 1.1.2.5 2005/12/29 12:58:42 martius 00136 * *** empty log message *** 00137 * 00138 * Revision 1.1.2.4 2005/12/15 17:03:43 martius 00139 * cameramanupulator setPose is working 00140 * joints have setter and getter parameters 00141 * Primitives are not longer inherited from OSGPrimitive, moreover 00142 * they aggregate them 00143 * 00144 * Revision 1.1.2.3 2005/12/14 15:36:45 martius 00145 * joints are visible now 00146 * 00147 * Revision 1.1.2.2 2005/12/13 18:11:14 martius 00148 * transform primitive added, some joints stuff done, forward declaration 00149 * 00150 * Revision 1.1.2.1 2005/12/06 10:13:25 martius 00151 * openscenegraph integration started 00152 * 00153 * * 00154 * * 00155 ***************************************************************************/ 00156 #ifndef __PRIMITIVE_H 00157 #define __PRIMITIVE_H 00158 00159 #include <osg/Matrix> 00160 #include <ode/common.h> 00161 00162 #include "substance.h" 00163 // another forward declaration "block" 00164 #include "osgforwarddecl.h" 00165 00166 namespace lpzrobots { 00167 00168 /***** begin of forward declaration block *****/ 00169 class BoundingShape; 00170 class OSGPrimitive; 00171 class OSGPlane; 00172 class OSGBox; 00173 class OSGBoxTex; 00174 class OSGSphere; 00175 class OSGCapsule; 00176 class OSGCylinder; 00177 class OSGDummy; 00178 class OSGMesh; 00179 00180 /* typedef */ struct GlobalData; 00181 00182 class OdeHandle; 00183 class OsgHandle; 00184 class Color; 00185 /***** end of forward declaration block *****/ 00186 00187 00188 /// returns the osg (4x4) pose matrix of the ode geom 00189 osg::Matrix osgPose( dGeomID geom ); 00190 /// returns the osg (4x4) pose matrix of the ode body 00191 osg::Matrix osgPose( dBodyID body ); 00192 /// converts a position vector and a rotation matrix from ode to osg 4x4 matrix 00193 osg::Matrix osgPose( const double * position , const double * rotation ); 00194 /// converts the rotation component of pose into an ode rotation matrix 00195 void odeRotation( const osg::Matrix& pose , dMatrix3& odematrix); 00196 00197 /** 00198 Interface class for primitives represented in the physical and graphical world. 00199 This is intended to bring OSG and ODE together and hide most implementation details. 00200 */ 00201 class Primitive { 00202 public: 00203 /** Body means that it is a dynamic object with a body. 00204 Geom means it has a geometrical represenation used for collision detection. 00205 Draw means the primitive is drawn 00206 Child is only used internally and is used for transformed geoms. 00207 */ 00208 00209 /* typedef */ enum Modes {Body=1, Geom=2, Draw=4, Child=8}; 00210 /* typedef */ enum Category { Dyn=1, Stat=2}; 00211 00212 00213 Primitive (); 00214 virtual ~Primitive (); 00215 /** registers primitive in ODE and OSG. 00216 @param osgHandle scruct with ODE variables inside (to specify space, world...) 00217 @param mass Mass of the object in ODE (if withBody = true) 00218 @param osgHandle scruct with OSG variables inside (scene node, color ...) 00219 @param mode is a conjuction of Modes. 00220 */ 00221 virtual void init(const OdeHandle& odeHandle, double mass, 00222 const OsgHandle& osgHandle, 00223 char mode = Body | Geom | Draw) = 0 ; 00224 00225 /** Updates the OSG nodes with ODE coordinates. 00226 This function must be overloaded (usually calls setMatrix of OsgPrimitives) 00227 */ 00228 virtual void update() =0 ; 00229 00230 /// returns the assoziated osg primitive if there or 0 00231 virtual OSGPrimitive* getOSGPrimitive() = 0; 00232 00233 /// sets the color for the underlaying osgprimitive 00234 virtual void setColor(const Color& color); 00235 00236 /// assigns a texture to the primitive 00237 virtual void setTexture(const std::string& filename); 00238 /// assigns a texture to the primitive, you can choose if the texture should be repeated 00239 virtual void setTexture(const std::string& filename, double repeatOnX, double repeatOnY); 00240 /** assigns a texture to the x-th surface of the primitive, you can choose how often to repeat 00241 negative values of repeat correspond to length units. 00242 E.g. assume a rectangle of size 5 in x direction: with repeatOnX = 2 the texture would be two times 00243 rereated. With repeatOnX = -1 the texture would be 5 times repeated because the texture is 00244 made to have the size 1 00245 */ 00246 virtual void setTexture(int surface, const std::string& filename, double repeatOnX, double repeatOnY); 00247 00248 00249 /// set the position of the primitive (orientation is preserved) 00250 void setPosition(const osg::Vec3& pos); 00251 /// set the pose of the primitive 00252 void setPose(const osg::Matrix& pose); 00253 /// returns the position 00254 osg::Vec3 getPosition() const; 00255 /// returns the pose 00256 osg::Matrix getPose() const; 00257 00258 /// sets the mass of the body (uniform) 00259 virtual void setMass(double mass) = 0; 00260 /** sets full mass specification 00261 \param cg center of gravity vector 00262 \param I 3x3 interia tensor 00263 */ 00264 void setMass(double mass, double cgx, double cgy, double cgz, 00265 double I11, double I22, double I33, 00266 double I12, double I13, double I23); 00267 00268 /// returns ODE geomID if there 00269 dGeomID getGeom() const; 00270 /// returns ODE bodyID if there 00271 dBodyID getBody() const; 00272 00273 /// checks whether the object has higher velocity than maxVel and limits it in case 00274 bool limitLinearVel(double maxVel); 00275 00276 /// return the given point transformed to local coordinates of the primitive 00277 osg::Vec3 toLocal(const osg::Vec3& pos) const; 00278 /** return the given vector or axis transformed to local coordinates 00279 of the primitive (translation depends on the 4th coordinate) 00280 */ 00281 osg::Vec4 toLocal(const osg::Vec4& axis) const; 00282 00283 /** 00284 * 20091023; guettler: 00285 * hack for tasked simulations; there are some problems if running in parallel mode, 00286 * if you do not destroy the geom, everything is fine (should be no problem because world is destroying geoms too) 00287 * @param _destroyGeom set this to false if geoms must not be destroyed if the primitive is destroyed 00288 */ 00289 static void setDestroyGeomFlag(bool _destroyGeom) { 00290 destroyGeom = _destroyGeom; 00291 } 00292 00293 protected: 00294 /** attaches geom to body (if any) and sets the category bits and collision bitfields. 00295 assumes: mode & Geom != 0 00296 */ 00297 virtual void attachGeomAndSetColliderFlags(); 00298 00299 public: 00300 Substance substance; // substance description 00301 protected: 00302 dGeomID geom; 00303 dBodyID body; 00304 char mode; 00305 00306 // 20091023; guettler: 00307 // hack for tasked simulations; there are some problems if running in parallel mode, 00308 // if you do not destroy the geom, everything is fine (should be no problem because world is destroying geoms too) 00309 static bool destroyGeom; 00310 }; 00311 00312 00313 /** Plane primitive */ 00314 class Plane : public Primitive { 00315 public: 00316 Plane(); 00317 virtual ~Plane(); 00318 virtual void init(const OdeHandle& odeHandle, double mass, 00319 const OsgHandle& osgHandle, 00320 char mode = Body | Geom | Draw) ; 00321 00322 virtual void update(); 00323 virtual OSGPrimitive* getOSGPrimitive(); 00324 00325 virtual void setMass(double mass); 00326 00327 protected: 00328 OSGPlane* osgplane; 00329 }; 00330 00331 00332 /** Box primitive */ 00333 class Box : public Primitive { 00334 public: 00335 00336 Box(float lengthX, float lengthY, float lengthZ); 00337 virtual ~Box(); 00338 00339 virtual void init(const OdeHandle& odeHandle, double mass, 00340 const OsgHandle& osgHandle, 00341 char mode = Body | Geom | Draw) ; 00342 00343 virtual void update(); 00344 virtual OSGPrimitive* getOSGPrimitive(); 00345 00346 virtual void setMass(double mass); 00347 protected: 00348 OSGBoxTex* osgbox; 00349 }; 00350 00351 00352 /** Sphere primitive */ 00353 class Sphere : public Primitive { 00354 public: 00355 Sphere(float radius); 00356 virtual ~Sphere(); 00357 00358 virtual void init(const OdeHandle& odeHandle, double mass, 00359 const OsgHandle& osgHandle, 00360 char mode = Body | Geom | Draw) ; 00361 00362 virtual void update(); 00363 virtual OSGPrimitive* getOSGPrimitive(); 00364 00365 virtual void setMass(double mass); 00366 00367 protected: 00368 OSGSphere* osgsphere; 00369 }; 00370 00371 /** Capsule primitive */ 00372 class Capsule : public Primitive { 00373 public: 00374 Capsule(float radius, float height); 00375 virtual ~Capsule(); 00376 virtual void init(const OdeHandle& odeHandle, double mass, 00377 const OsgHandle& osgHandle, 00378 char mode = Body | Geom | Draw) ; 00379 00380 virtual void update(); 00381 virtual OSGPrimitive* getOSGPrimitive(); 00382 00383 virtual void setMass(double mass); 00384 00385 protected: 00386 OSGCapsule* osgcapsule; 00387 }; 00388 00389 /** Cylinder primitive */ 00390 class Cylinder : public Primitive { 00391 public: 00392 Cylinder(float radius, float height); 00393 virtual ~Cylinder(); 00394 virtual void init(const OdeHandle& odeHandle, double mass, 00395 const OsgHandle& osgHandle, 00396 char mode = Body | Geom | Draw) ; 00397 00398 virtual void update(); 00399 virtual OSGPrimitive* getOSGPrimitive(); 00400 00401 virtual void setMass(double mass); 00402 protected: 00403 OSGCylinder* osgcylinder; 00404 }; 00405 00406 /** Ray primitive 00407 The actual visual representation can have different length than the 00408 ray object. This is specified by length. 00409 SetLength is an efficient way to change the length at runtime. 00410 */ 00411 class Ray : public Primitive { 00412 public: 00413 Ray(double range, float thickness, float length); 00414 virtual ~Ray(); 00415 virtual void init(const OdeHandle& odeHandle, double mass, 00416 const OsgHandle& osgHandle, 00417 char mode = Geom | Draw) ; 00418 00419 void setLength(float len); 00420 virtual void update(); 00421 virtual OSGPrimitive* getOSGPrimitive(); 00422 00423 virtual void setMass(double mass); 00424 protected: 00425 double range; 00426 float thickness; 00427 float length; 00428 OSGBox* osgbox; 00429 }; 00430 00431 00432 00433 00434 /** Mesh primitive */ 00435 class Mesh : public Primitive { 00436 public: 00437 Mesh(const std::string& filename,float scale); 00438 virtual ~Mesh(); 00439 virtual void init(const OdeHandle& odeHandle, double mass, 00440 const OsgHandle& osgHandle, 00441 char mode = Body | Geom | Draw) ; 00442 virtual void update(); 00443 virtual OSGPrimitive* getOSGPrimitive(); 00444 virtual float getRadius(); 00445 00446 virtual void setMass(double mass); 00447 protected: 00448 OSGMesh* osgmesh; 00449 const std::string filename; 00450 float scale; 00451 BoundingShape* boundshape; 00452 }; 00453 00454 00455 /** 00456 Primitive for transforming a geom (primitive without body) 00457 in respect to a body (primitive with body). 00458 Hides complexity of ODE TransformGeoms. 00459 */ 00460 class Transform : public Primitive { 00461 public: 00462 /** 00463 @param parent primitive should have a body and should be initialised 00464 @param child is transformed by pose in respect to parent. 00465 This Primitive must NOT have a body and should not be initialised 00466 */ 00467 Transform(Primitive* parent, Primitive* child, const osg::Matrix& pose); 00468 00469 /// destructor deletes child object 00470 ~Transform(); 00471 00472 /** initialised the transform object. This automatically 00473 initialises the child geom. 00474 @param mass mass of the child 00475 @param mode is the mode for the child, except that Body bit is ignored (child can't have a body) 00476 */ 00477 virtual void init(const OdeHandle& odeHandle, double mass, 00478 const OsgHandle& osgHandle, 00479 char mode = Body | Geom | Draw); 00480 00481 virtual void update(); 00482 virtual OSGPrimitive* getOSGPrimitive(); 00483 00484 virtual void setMass(double mass); 00485 protected: 00486 Primitive* parent; 00487 Primitive* child; 00488 osg::Matrix pose; 00489 }; 00490 00491 /** 00492 Dummy Primitive which returns 0 for geom and body. 00493 Only useful for representing the static world in terms of primitives. 00494 */ 00495 class DummyPrimitive : public Primitive { 00496 public: 00497 00498 DummyPrimitive() { 00499 body=0; 00500 geom=0; 00501 } 00502 virtual void init(const OdeHandle& odeHandle, double mass, 00503 const OsgHandle& osgHandle, char mode = Body | Geom | Draw) { 00504 } 00505 virtual void update() {} 00506 virtual OSGPrimitive* getOSGPrimitive() { return 0; } 00507 00508 virtual void setMass(double mass) {} 00509 00510 }; 00511 00512 00513 } 00514 #endif 00515