2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
7 #ifndef CAFU_PHYSICS_WORLD_HPP_INCLUDED
8 #define CAFU_PHYSICS_WORLD_HPP_INCLUDED
10 #include "Math3D/BoundingBox.hpp" // Temporary for PhysicsWorldT::TraceBoundingBox().
11 #include "Math3D/Quaternion.hpp"
12 #include "Math3D/Vector3.hpp"
13 #include "btBulletDynamicsCommon.h"
15 #undef min // See http://stackoverflow.com/questions/5004858/stdmin-gives-error
19 namespace cf
{ namespace ClipSys
{ class CollisionModelT
; } }
20 namespace cf
{ namespace GameSys
{ class ComponentPhysicsT
; } }
21 typedef cf::GameSys::ComponentPhysicsT TraceUserEntityT
;
24 // Auxiliary functions for making the conversion between Bullet and Cafu vectors easier.
25 inline btVector3
conv(const Vector3T
<float>& v
) { return btVector3(v
.x
, v
.y
, v
.z
); }
26 inline btVector3
conv(const Vector3T
<double>& v
) { return btVector3(float(v
.x
), float(v
.y
), float(v
.z
)); }
27 inline Vector3fT
conv(const btVector3
& v
) { return Vector3fT(v
.x(), v
.y(), v
.z()); }
28 inline Vector3dT
convd(const btVector3
& v
) { return Vector3dT(v
.x(), v
.y(), v
.z()); }
30 inline cf::math::QuaternionfT
conv(const btQuaternion
& v
) { return cf::math::QuaternionfT(v
.x(), v
.y(), v
.z(), v
.w()); }
31 inline btQuaternion
conv(const cf::math::QuaternionfT
& v
) { return btQuaternion(v
.x
, v
.y
, v
.z
, v
.w
); }
33 inline float UnitsToPhys(float v
) { return v
* 0.0254f
; }
34 inline double UnitsToPhys(double v
) { return v
* 0.0254; }
35 inline Vector3fT
UnitsToPhys(const Vector3fT
& v
) { return v
* 0.0254f
; }
36 inline Vector3dT
UnitsToPhys(const Vector3dT
& v
) { return v
* 0.0254; }
38 inline float PhysToUnits(float v
) { return v
/ 0.0254f
; }
39 inline double PhysToUnits(double v
) { return v
/ 0.0254; }
40 inline Vector3fT
PhysToUnits(const Vector3fT
& v
) { return v
/ 0.0254f
; }
41 inline Vector3dT
PhysToUnits(const Vector3dT
& v
) { return v
/ 0.0254; }
44 /// This class handles the results of tracing a ray through the world.
45 /// As such, it is called back for intermediate results and thus can "configure" or "parametrize" the trace,
46 /// and it keeps the final trace result for inspection by the caller as well.
47 class RayResultT
: public btCollisionWorld::ClosestRayResultCallback
52 /// @param IgnoreObject A collision object to ignore for this trace. This is usually the object from which the trace emanates.
53 RayResultT(const btCollisionObject
* IgnoreObject
)
54 : btCollisionWorld::ClosestRayResultCallback(btVector3(), btVector3()),
55 m_IgnoreObject(IgnoreObject
)
60 /// If something was hit (hasHit() returns true), this method returns a pointer to the
61 /// Physics component that the hit collision object belongs to.
62 /// The returned pointer is NULL if the collision object belongs to the world.
63 /// If nothing was hit (hasHit() returns false), NULL is always returned.
64 TraceUserEntityT
* GetHitPhysicsComp() const
66 if (m_collisionObject
==NULL
) return NULL
;
68 return static_cast<TraceUserEntityT
*>(m_collisionObject
->getUserPointer());
72 virtual btScalar
addSingleResult(btCollisionWorld::LocalRayResult
& RayResult
, bool NormalIsInWorldSpace
)
74 if (RayResult
.m_collisionObject
==m_IgnoreObject
) return 1.0;
76 return ClosestRayResultCallback::addSingleResult(RayResult
, NormalIsInWorldSpace
);
82 const btCollisionObject
* m_IgnoreObject
;
86 /// This class handles the results of tracing a convex shape through the world.
87 /// As such, it is called back for intermediate results and thus can "configure" or "parametrize" the trace,
88 /// and it keeps the final trace result for inspection by the caller as well.
89 class ShapeResultT
: public btCollisionWorld::ClosestConvexResultCallback
95 : btCollisionWorld::ClosestConvexResultCallback(btVector3(), btVector3()),
102 /// Adds the given collision object to the objects to be ignored for this trace.
103 /// @param Obj A collision object to ignore for this trace. This is often the object from which the trace emanates.
104 void Ignore(const btCollisionObject
* Obj
)
106 assert(m_IgnoreObjCount
<2);
107 if (m_IgnoreObjCount
>=2) return;
109 m_IgnoreObjects
[m_IgnoreObjCount
++]=Obj
;
113 /// Adds the given entity to the entities to be ignored for this trace.
114 /// @param Ent An entity to ignore for this trace. This is often the entity from which the trace emanates, or e.g. NULL (the world).
115 void Ignore(const TraceUserEntityT
* Ent
)
117 assert(m_IgnoreEntCount
<2);
118 if (m_IgnoreEntCount
>=2) return;
120 m_IgnoreEntities
[m_IgnoreEntCount
++]=Ent
;
124 /// If something was hit (hasHit() returns true), this method returns a pointer to the
125 /// Physics component that the hit collision object belongs to.
126 /// The returned pointer is NULL if the collision object belongs to the world.
127 /// If nothing was hit (hasHit() returns false), NULL is always returned.
128 TraceUserEntityT
* GetHitPhysicsComp() const
130 if (m_hitCollisionObject
==NULL
) return NULL
;
132 return static_cast<TraceUserEntityT
*>(m_hitCollisionObject
->getUserPointer());
136 virtual btScalar
addSingleResult(btCollisionWorld::LocalConvexResult
& ConvexResult
, bool NormalIsInWorldSpace
)
138 for (unsigned short Count
=0; Count
<m_IgnoreObjCount
; Count
++)
139 if (ConvexResult
.m_hitCollisionObject
==m_IgnoreObjects
[Count
]) return 1.0;
141 for (unsigned short Count
=0; Count
<m_IgnoreEntCount
; Count
++)
142 if (ConvexResult
.m_hitCollisionObject
->getUserPointer()==m_IgnoreEntities
[Count
]) return 1.0;
144 return ClosestConvexResultCallback::addSingleResult(ConvexResult
, NormalIsInWorldSpace
);
150 unsigned short m_IgnoreObjCount
;
151 unsigned short m_IgnoreEntCount
;
153 const btCollisionObject
* m_IgnoreObjects
[2];
154 const TraceUserEntityT
* m_IgnoreEntities
[2];
162 PhysicsWorldT(const cf::ClipSys::CollisionModelT
* WorldCollMdl
);
165 void AddRigidBody(btRigidBody
* RigidBody
);
166 void RemoveRigidBody(btRigidBody
* RigidBody
);
168 void TraceRay(const Vector3dT
& Origin
, const Vector3dT
& Ray
, RayResultT
& RayResult
) const;
169 void TraceBoundingBox(const BoundingBox3T
<double>& BB
, const Vector3dT
& Origin
, const Vector3dT
& Dir
, ShapeResultT
& ShapeResult
) const;
170 void TraceShape() const;
172 void Think(float FrameTime
);
177 btDefaultCollisionConfiguration
* m_CollisionConfiguration
;
178 btCollisionDispatcher
* m_Dispatcher
;
179 btBroadphaseInterface
* m_Broadphase
;
180 btConstraintSolver
* m_Solver
;
181 btDiscreteDynamicsWorld
* m_PhysicsWorld
;