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 #ifndef PHY_GEOMETRY_HANDLERS_H
00028 #define PHY_GEOMETRY_HANDLERS_H
00029
00030 #include <ode/ode.h>
00031 #include <osg/Referenced>
00032 #include <osg/ref_ptr>
00033 #include <PVLE/Physics/Converters.h>
00034 #include <PVLE/Export.h>
00035 #include <PVLE/Util/Util.h>
00036 #include <PVLE/Util/Singleton.h>
00037 #include <PVLE/Util/Callback.h>
00038
00039 #include <osg/Array>
00040
00041
00042 #include <boost/filesystem/path.hpp>
00043 #include <osg/Geometry>
00044
00045
00046 namespace osg {
00047 class Heightfield;
00048 }
00049
00050
00051 namespace Physics {
00052
00053 class GeometryHandler;
00054
00057 class GHChangeCallback : public Util::Callback<GHChangeCallback> {
00058 public:
00059 virtual void operator()(GeometryHandler * pGH) {
00060
00061 traverse(pGH);
00062 }
00063
00064 void traverse(GeometryHandler * pGH) { if (_nestedCallback.valid()) _nestedCallback->operator()(pGH); }
00065 };
00066
00067
00073 class PVLE_EXPORT GeometryHandler : public osg::Referenced {
00074 public:
00077 enum EGeomType { SPHERE=dSphereClass, BOX=dBoxClass, CAPSULE=dCapsuleClass, CYLINDER=dCylinderClass, PLANE=dPlaneClass, RAY=dRayClass, CONVEX=dConvexClass, TRANSFORM=dGeomTransformClass, MESH=dTriMeshClass, HEIGHT_FIELD=dHeightfieldClass, USER1=dFirstUserClass };
00078
00080 enum EBodyADOverride {
00081 AD_NO_OVERRIDE = 0,
00082 AD_FLAG = 0x01,
00083 AD_LINEAR = 0x02,
00084 AD_ANGULAR = 0x04,
00085 AD_STEPS = 0x08,
00086 AD_TIME = 0x10,
00087 AD_SAMPLES_COUNT = 0x20
00088 };
00089
00090 GeometryHandler() : id(0) {}
00091 virtual EGeomType type() const =0;
00092
00096
00098 virtual UINT getADOverrideFlag() { return AD_NO_OVERRIDE; }
00099 virtual bool getADFlag() { return true; }
00100 virtual dReal getADLinearThreshold() { return 0.01f; }
00101 virtual dReal getADAngularThreshold() { return 0.01f; }
00102 virtual UINT getADSteps() { return 10; }
00103 virtual dReal getADTime() { return 0; }
00104 virtual UINT getADSamplesCount() { return 1; }
00106
00107 virtual GeometryHandler * clone() const =0;
00108
00112 osg::ref_ptr<GHChangeCallback> pChangeCallback;
00113 inline void addOrSetChangeCallback(GHChangeCallback * callback) { if (pChangeCallback.valid()) pChangeCallback->addNestedCallback(callback); else pChangeCallback = callback; }
00115
00116
00117 protected:
00118 friend class Geom;
00119 virtual dGeomID create(dSpaceID spaceId) =0;
00120 mutable dGeomID id;
00121
00124 virtual ~GeometryHandler() {}
00125 };
00126
00127
00129 class PVLE_EXPORT UserGeomsInitializer : public Util::Singleton<UserGeomsInitializer> {
00130 public:
00131 UserGeomsInitializer();
00132 dGeomID createUserGeom(GeometryHandler::EGeomType type) { return dCreateGeom(type); }
00133 };
00134
00135
00136
00137
00138
00140 class PVLE_EXPORT SphereHandler : public GeometryHandler {
00141 public:
00142 SphereHandler(dReal radius = 1) : radius(radius) {}
00143 virtual EGeomType type() const { return SPHERE; }
00144
00145 void setRadius(dReal radius) {
00146 if (this->radius == radius) return;
00147 if(!id) this->radius = radius; else dGeomSphereSetRadius(id, radius);
00148 if (pChangeCallback.valid()) pChangeCallback->operator()(this);
00149 }
00150 dReal getRadius() const { if(!id) return radius; return dGeomSphereGetRadius(id); }
00151
00152 dReal getPointDepth(graphVec3 point) { ASSERT(id); return dGeomSpherePointDepth(id, point.x(), point.y(), point.z()); }
00153
00154
00155 virtual UINT getADOverrideFlag() { return AD_STEPS; }
00156 virtual UINT getADSteps() { return 2; }
00157
00158 virtual GeometryHandler * clone() const { return new SphereHandler(radius); }
00159 protected:
00160 virtual dGeomID create(dSpaceID spaceId) { id = dCreateSphere(spaceId, radius); return id; }
00161 dReal radius;
00162 };
00163
00164
00166 class PVLE_EXPORT BoxHandler : public GeometryHandler {
00167 public:
00168 BoxHandler(dReal x =1, dReal y =1, dReal z =1) : x(x), y(y), z(z) {}
00169 BoxHandler(graphVec3 v) { setSize(v); }
00170 virtual EGeomType type() const { return BOX; }
00171
00172 void setSize(graphVec3 v) { setSize(v.x(), v.y(), v.z()); }
00173 void setSize(dReal x, dReal y, dReal z) {
00174 if (this->x == x && this->y == y && this->z == z) return;
00175 this->x = x; this->y = y; this->z = z;
00176 if (id) dGeomBoxSetLengths(id, x, y, z);
00177 if (pChangeCallback.valid()) pChangeCallback->operator()(this);
00178 }
00179
00180 graphVec3 getSize() const { if(!id) return graphVec3(x,y,z); dVector3 v; dGeomBoxGetLengths(id, v); return toGraphVec3(v); }
00181 dReal getPointDepth(graphVec3 point) { ASSERT(id); return dGeomBoxPointDepth(id, point.x(), point.y(), point.z()); }
00182
00183 virtual GeometryHandler * clone() const { return new BoxHandler(x,y,z); }
00184
00185 protected:
00186 virtual dGeomID create(dSpaceID spaceId) { id = dCreateBox(spaceId, x, y, z); return id; }
00187 dReal x,y,z;
00188 };
00189
00190
00192 class PVLE_EXPORT PlaneHandler : public GeometryHandler {
00193 public:
00194 PlaneHandler(graphVec4 plane = graphVec4(0,0,1,0)) : x(plane.x()), y(plane.y()), z(plane.z()), t(plane.w()) {}
00195 PlaneHandler(dReal x, dReal y =0, dReal z =1, dReal t =0) : x(x), y(y), z(z), t(t) {}
00196
00197 virtual EGeomType type() const { return PLANE; }
00198
00199 void setParams(graphVec4 plane) { setParams(plane.x(), plane.y(), plane.z(), plane.w()); }
00200 void setParams(dReal x, dReal y, dReal z, dReal t) {
00201 if (this->x == x && this->y == y && this->z == z && this->t == t) return;
00202 this->x = x; this->y = y; this->z = z; this->t = t;
00203 if (id) dGeomPlaneSetParams(id, x, y, z, t);
00204 if (pChangeCallback.valid()) pChangeCallback->operator()(this);
00205 }
00206
00207 graphVec4 getParams() const {
00208 if(!id) return graphVec4(x,y,z,t);
00209 dVector4 v;
00210 dGeomPlaneGetParams(id, v);
00211 return toGraphVec4(v);
00212 }
00213
00214 dReal getPointDepth(graphVec3 point) { ASSERT(id); return dGeomPlanePointDepth(id, point.x(), point.y(), point.z()); }
00215
00216 virtual GeometryHandler * clone() const { return new PlaneHandler(x,y,z,t); }
00217
00218 protected:
00219 virtual dGeomID create(dSpaceID spaceId) { id = dCreatePlane(spaceId, x, y, z, t); return id; }
00220 dReal x,y,z,t;
00221 };
00222
00223
00225 class PVLE_EXPORT CylinderHandler : public GeometryHandler {
00226 public:
00227 CylinderHandler(dReal radius = 1, dReal length = 1) : radius(radius), length(length) {}
00228 virtual EGeomType type() const { return CYLINDER; }
00229
00230 void setParams(dReal radius, dReal length) {
00231 if (this->radius == radius && this->length == length) return;
00232 this->radius = radius; this->length = length;
00233 if (id) dGeomCylinderSetParams(id, radius, length);
00234 if (pChangeCallback.valid()) pChangeCallback->operator()(this);
00235 }
00236
00238 std::pair<dReal, dReal> getParams() const {
00239 if(!id) return std::make_pair(radius, length);
00240 dReal r, l;
00241 dGeomCylinderGetParams(id, &r, &l);
00242 return std::make_pair(r,l);
00243 }
00244
00245
00246
00247 virtual GeometryHandler * clone() const { return new CylinderHandler(radius, length); }
00248 protected:
00249 virtual dGeomID create(dSpaceID spaceId) { id = dCreateCylinder(spaceId, radius, length); return id; }
00250 dReal radius, length;
00251 };
00252
00253
00255 class PVLE_EXPORT CapsuleHandler : public GeometryHandler {
00256 public:
00257 CapsuleHandler(dReal radius = 1, dReal length = 1) : radius(radius), length(length) {}
00258 virtual EGeomType type() const { return CAPSULE; }
00259
00260 void setParams(dReal radius, dReal length) {
00261 if (this->radius == radius && this->length == length) return;
00262 this->radius = radius; this->length = length;
00263 if (id) dGeomCapsuleSetParams(id, radius, length);
00264 if (pChangeCallback.valid()) pChangeCallback->operator()(this);
00265 }
00266
00268 std::pair<dReal, dReal> getParams() const {
00269 if(!id) return std::make_pair(radius, length);
00270 dReal r, l;
00271 dGeomCapsuleGetParams(id, &r, &l);
00272 return std::make_pair(r,l);
00273 }
00274
00275 dReal getPointDepth(graphVec3 point) { ASSERT(id); return dGeomCapsulePointDepth(id, point.x(), point.y(), point.z()); }
00276
00277 virtual GeometryHandler * clone() const { return new CapsuleHandler(radius, length); }
00278
00279 protected:
00280 virtual dGeomID create(dSpaceID spaceId) { id = dCreateCapsule(spaceId, radius, length); return id; }
00281 dReal radius, length;
00282 };
00283
00284
00287 class PVLE_EXPORT RayHandler : public GeometryHandler {
00288 public:
00289 RayHandler(dReal length) : length(length), startPoint(osg::Vec3(0,0,0)), dir(osg::Vec3(0,0,1)) {}
00290 RayHandler(dReal length, graphVec3 startPoint, graphVec3 dir) : length(length), startPoint(startPoint), dir(dir) {}
00291 virtual EGeomType type() const { return RAY; }
00292
00293 void setLength(dReal length) {
00294 if (this->length == length) return;
00295 this->length = length;
00296 if (id) dGeomRaySetLength(id, length);
00297 if (pChangeCallback.valid()) pChangeCallback->operator()(this);
00298 }
00299 dReal getLength() const { if(!id) return length; return dGeomRayGetLength(id); }
00300
00302 void setRay(graphVec3 startPoint, graphVec3 dir) {
00303 if (this->startPoint == startPoint && this->dir == dir) return;
00304 this->startPoint = startPoint; this->dir = dir;
00305 if (id) dGeomRaySet(id, startPoint.x(), startPoint.y(), startPoint.z(), dir.x(), dir.y(), dir.z());
00306 if (pChangeCallback.valid()) pChangeCallback->operator()(this);
00307 }
00308
00309 graphVec3 getStartPoint() {
00310 if(!id) return startPoint;
00311 dVector3 s, d;
00312 dGeomRayGet(id, s, d);
00313 return toGraphVec3(s);
00314 }
00315 graphVec3 getDir() {
00316 if(!id) return dir;
00317 dVector3 s, d;
00318 dGeomRayGet(id, s, d);
00319 return toGraphVec3(d);
00320 }
00321
00322 virtual GeometryHandler * clone() const { return new RayHandler(length, startPoint, dir); }
00323
00324 protected:
00325 virtual dGeomID create(dSpaceID spaceId) {
00326 id = dCreateRay(spaceId, length);
00327 dGeomRaySet(id, startPoint.x(), startPoint.y(), startPoint.z(), dir.x(), dir.y(), dir.z());
00328 dGeomRaySetLength(id, length);
00329 return id;
00330 }
00331 dReal length;
00332 graphVec3 startPoint, dir;
00333 };
00334
00335
00340 class PVLE_EXPORT HeightFieldHandler : public GeometryHandler {
00341 public:
00347 HeightFieldHandler(const osg::HeightField * pGfxHeightField, float thickness = 1, const graphVec3 & offset_from_graph = graphVec3(0,0,0), bool bWarp = false);
00348
00350 HeightFieldHandler(const HeightFieldHandler & hf);
00351
00352
00353
00354
00355 virtual EGeomType type() const { return HEIGHT_FIELD; }
00356
00357
00358
00359
00360
00361
00362
00363
00364 virtual GeometryHandler * clone() const { return new HeightFieldHandler(*this); }
00365
00366 protected:
00367 virtual dGeomID create(dSpaceID spaceId);
00368
00369 float * pData;
00370 float width, depth;
00371 UINT widthSamples, depthSamples;
00372 float scale, offset, thickness;
00373 bool bPlaceable, bWarp;
00374 dVector3 pos;
00375 dQuaternion rot;
00376 dHeightfieldDataID idHFData;
00377 dGeomID idHF;
00378
00379 virtual ~HeightFieldHandler() {
00380 if (idHFData) dGeomHeightfieldDataDestroy(idHFData);
00381 delete[] pData;
00382 }
00383 };
00384
00385
00389 class PVLE_EXPORT MeshHandler : public GeometryHandler {
00390 public:
00392 MeshHandler(const osg::Geometry * pGfxGeometry) : pGeo(pGfxGeometry), pLocalIndexArray(NULL) { meshDataId = dGeomTriMeshDataCreate(); }
00395 MeshHandler(osg::Node * pModel);
00398 MeshHandler(const osg::HeightField * pGfxHeightField);
00399
00400 virtual EGeomType type() const { return MESH; }
00401
00402 const osg::Geometry * getGeometry() const { ASSERT(pGeo); return pGeo; }
00403
00404
00405 osg::Geometry * DEBUG_getOwnGeometry() { return pOwnGeo.get(); }
00406
00408
00409
00410 void clearCache() { dGeomTriMeshClearTCCache(id);}
00411
00412
00413
00414
00415
00416
00417
00419
00420
00421
00422
00423
00424 virtual UINT getADOverrideFlag();
00425 virtual UINT getADSteps();
00426 virtual UINT getADSamplesCount();
00427 virtual dReal getADLinearThreshold();
00428 virtual dReal getADAngularThreshold();
00429
00430 virtual GeometryHandler * clone() const {
00431 THROW_TRACED_EXCEPTION("Not implemented");
00432
00433 }
00434 protected:
00435 virtual dGeomID create(dSpaceID spaceId);
00436 const osg::Geometry * pGeo;
00437 dTriMeshDataID meshDataId;
00438
00439 typedef osg::TemplateIndexArray< GLuint, osg::Array::UIntArrayType, sizeof(GLuint), GL_UNSIGNED_INT > TIndexArray;
00440 osg::ref_ptr<TIndexArray> pLocalIndexArray;
00441
00442 template<class TDrawElements>
00443 void indexAdd(const osg::PrimitiveSet * pPrimitive);
00444
00445
00446 void indexTriangles(UINT lengthPrimitive, UINT offset);
00447 void indexTriangleStrip(UINT lengthPrimitive, UINT offset);
00448 void indexTriangleFan(UINT lengthPrimitive, UINT offset);
00449 void indexQuads(UINT lengthPrimitive, UINT offset);
00450 void indexQuadStrip(UINT lengthPrimitive, UINT offset);
00451
00452
00453 template<class TDrawElements>
00454 void indexTriangles(const TDrawElements * pPrimitive);
00455 template<class TDrawElements>
00456 void indexTriangleStrip(const TDrawElements * pPrimitive);
00457 template<class TDrawElements>
00458 void indexTriangleFan(const TDrawElements * pPrimitive);
00459 template<class TDrawElements>
00460 void indexQuads(const TDrawElements * pPrimitive);
00461 template<class TDrawElements>
00462 void indexQuadStrip(const TDrawElements * pPrimitive);
00463
00465 template <class TDrawElements>
00466 void indexByType(const osg::PrimitiveSet * pPrimitive);
00467
00468 virtual ~MeshHandler() { dGeomTriMeshDataDestroy(meshDataId); }
00469
00470 private:
00471 osg::ref_ptr<osg::Geometry> pOwnGeo;
00472 };
00473
00474
00475
00480
00481
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 }
00525
00526
00527 #endif // PHY_GEOMETRY_HANDLERS_H