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