PhysicsWorld.hpp
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
5 */
6
7 #ifndef CAFU_PHYSICS_WORLD_HPP_INCLUDED
8 #define CAFU_PHYSICS_WORLD_HPP_INCLUDED
9
10 #include "Math3D/BoundingBox.hpp" // Temporary for PhysicsWorldT::TraceBoundingBox().
11 #include "Math3D/Quaternion.hpp"
12 #include "Math3D/Vector3.hpp"
13 #include "btBulletDynamicsCommon.h"
14
15 #undef min // See http://stackoverflow.com/questions/5004858/stdmin-gives-error
16 #undef max
17
18
19 namespace cf { namespace ClipSys { class CollisionModelT; } }
20 namespace cf { namespace GameSys { class ComponentPhysicsT; } }
22
23
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()); }
29
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); }
32
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; }
37
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; }
42
43
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
48 {
49  public:
50
51  /// The constructor.
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)
56  {
57  }
58
59
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.
65  {
66  if (m_collisionObject==NULL) return NULL;
67
68  return static_cast<TraceUserEntityT*>(m_collisionObject->getUserPointer());
69  }
70
71
72  virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& RayResult, bool NormalIsInWorldSpace)
73  {
74  if (RayResult.m_collisionObject==m_IgnoreObject) return 1.0;
75
77  }
78
79
80  protected:
81
82  const btCollisionObject* m_IgnoreObject;
83 };
84
85
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
90 {
91  public:
92
93  /// The constructor.
95  : btCollisionWorld::ClosestConvexResultCallback(btVector3(), btVector3()),
96  m_IgnoreObjCount(0),
97  m_IgnoreEntCount(0)
98  {
99  }
100
101
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)
105  {
106  assert(m_IgnoreObjCount<2);
107  if (m_IgnoreObjCount>=2) return;
108
109  m_IgnoreObjects[m_IgnoreObjCount++]=Obj;
110  }
111
112
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)
116  {
117  assert(m_IgnoreEntCount<2);
118  if (m_IgnoreEntCount>=2) return;
119
120  m_IgnoreEntities[m_IgnoreEntCount++]=Ent;
121  }
122
123
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.
129  {
130  if (m_hitCollisionObject==NULL) return NULL;
131
132  return static_cast<TraceUserEntityT*>(m_hitCollisionObject->getUserPointer());
133  }
134
135
136  virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& ConvexResult, bool NormalIsInWorldSpace)
137  {
138  for (unsigned short Count=0; Count<m_IgnoreObjCount; Count++)
139  if (ConvexResult.m_hitCollisionObject==m_IgnoreObjects[Count]) return 1.0;
140
141  for (unsigned short Count=0; Count<m_IgnoreEntCount; Count++)
142  if (ConvexResult.m_hitCollisionObject->getUserPointer()==m_IgnoreEntities[Count]) return 1.0;
143
145  }
146
147
148  protected:
149
150  unsigned short m_IgnoreObjCount;
151  unsigned short m_IgnoreEntCount;
152
153  const btCollisionObject* m_IgnoreObjects[2];
154  const TraceUserEntityT* m_IgnoreEntities[2];
155 };
156
157
159 {
160  public:
161
162  PhysicsWorldT(const cf::ClipSys::CollisionModelT* WorldCollMdl);
163  ~PhysicsWorldT();
164
166  void RemoveRigidBody(btRigidBody* RigidBody);
167
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;
171
172  void Think(float FrameTime);
173
174
175  private:
176
177  btDefaultCollisionConfiguration* m_CollisionConfiguration;
178  btCollisionDispatcher* m_Dispatcher;
180  btConstraintSolver* m_Solver;
181  btDiscreteDynamicsWorld* m_PhysicsWorld;
182 };
183
184 #endif
Definition: PhysicsWorld.hpp:158
ShapeResultT()
The constructor.
Definition: PhysicsWorld.hpp:94
TraceUserEntityT * GetHitPhysicsComp() const
If something was hit (hasHit() returns true), this method returns a pointer to the Physics component ...
Definition: PhysicsWorld.hpp:64
RayResultT(const btCollisionObject *IgnoreObject)
The constructor.
Definition: PhysicsWorld.hpp:53
void Ignore(const TraceUserEntityT *Ent)
Adds the given entity to the entities to be ignored for this trace.
Definition: PhysicsWorld.hpp:115
T y
The y-component of this vector.
Definition: Vector3.hpp:41
TraceUserEntityT * GetHitPhysicsComp() const
If something was hit (hasHit() returns true), this method returns a pointer to the Physics component ...
Definition: PhysicsWorld.hpp:128
void Ignore(const btCollisionObject *Obj)
Adds the given collision object to the objects to be ignored for this trace.
Definition: PhysicsWorld.hpp:104
This component includes the body of this entity in the dynamic simulation of physics.
Definition: CompPhysics.hpp:26
This is the base class for collision models, defining their common interface.
Definition: CollisionModel_base.hpp:29
This class handles the results of tracing a convex shape through the world.
Definition: PhysicsWorld.hpp:89
T z
The z-component of this vector.
Definition: Vector3.hpp:42
T x
The x-component of this vector.
Definition: Vector3.hpp:40
This class handles the results of tracing a ray through the world.
Definition: PhysicsWorld.hpp:47