Leviathan  0.8.0.0
Leviathan game engine
PhysicalWorld.h
Go to the documentation of this file.
1 // Leviathan Game Engine
2 // Copyright (c) 2012-2019 Henri Hyyryläinen
3 #pragma once
4 #include "Define.h"
5 // ------------------------------------ //
6 #include "Common/ThreadSafe.h"
7 #include "Common/Types.h"
8 #include "PhysicsBody.h"
9 #include "PhysicsConstraint.h"
10 #include "PhysicsShape.h"
11 
12 #include <functional>
13 
14 // Bullet forward declarations
15 class btCollisionShape;
16 class btRigidBody;
17 class btDefaultCollisionConfiguration;
18 class btCollisionDispatcher;
19 class btBroadphaseInterface;
20 class btSequentialImpulseConstraintSolver;
21 class btDiscreteDynamicsWorld;
22 class btDynamicsWorld;
23 class btPersistentManifold;
24 class btManifoldPoint;
25 class btCollisionObject;
26 
27 #ifdef BT_USE_DOUBLE_PRECISION
28 using btScalar = double;
29 #else
30 using btScalar = float;
31 #endif
32 
33 
34 namespace Leviathan {
35 
36 class PhysicsDebugDrawer;
37 class LeviathanPhysicsOverlapFilter;
38 struct PhysMaterialDataPair;
39 
40 constexpr auto PHYSICS_BASE_GRAVITY = -9.81f;
41 
42 // //! \brief Base class for custom joint types defined for use by this class
43 // //! \note If these should be able to be accessed from elsewhere, move this to a new file
44 // class BaseCustomJoint {
45 // public:
46 // //! This helps with allowing all custom types to be destroyed with a single callback
47 // DLLEXPORT virtual ~BaseCustomJoint() {}
48 
49 // DLLEXPORT static void JointDestructorCallback(const NewtonJoint* joint);
50 // };
51 
52 // TODO: need to find some way to fake this with bullet
53 // int SingleBodyUpdate(
54 // const NewtonWorld* const newtonWorld, const void* islandHandle, int bodyCount);
55 
57  // friend int SingleBodyUpdate(
58  // const NewtonWorld* const newtonWorld, const void* islandHandle, int bodyCount);
59 public:
60  DLLEXPORT PhysicalWorld(GameWorld* owner, PhysicsMaterialManager* physicscallbacks);
62 
65  DLLEXPORT void SimulateWorld(float secondspassed, int maxsubsteps = 8);
66 
67  // ------------------------------------ //
68  // Physics collision creation
69  // NOTE: all created collisions HAVE to be destroyed after all bodies using them are
70  // destroyed
71  DLLEXPORT PhysicsShape::pointer CreateCompound();
72 
73  DLLEXPORT PhysicsShape::pointer CreateSphere(float radius);
74 
76  DLLEXPORT PhysicsShape::pointer CreateBox(
77  float xdimension, float ydimension, float zdimension);
78 
79  DLLEXPORT PhysicsShape::pointer CreateCone(float radius, float height);
80 
81  // ------------------------------------ //
82  // Physics constraint creation
83  DLLEXPORT PhysicsConstraint::pointer CreateFixedConstraint(const PhysicsBody::pointer& a,
84  const PhysicsBody::pointer& b, const Float3& aoffset, const Quaternion& aorientation,
85  const Float3& boffset, const Quaternion& borientation);
86 
91 
93  // DLLEXPORT NewtonJoint* Create2DJoint(NewtonBody* body, const Float3& planenormal);
94 
95  // ------------------------------------ //
96 
99  DLLEXPORT PhysicsBody::pointer CreateBodyFromCollision(const PhysicsShape::pointer& shape,
100  float mass, PhysicsPositionProvider* positionsynchronization,
101  int physicsmaterialid = -1);
102 
107  const PhysicsBody::pointer& body, const PhysicsShape::pointer& shape);
108 
112  DLLEXPORT bool DestroyBody(PhysicsBody* body);
113 
114 
116  const PhysMaterialDataPair* GetMaterialPair(int id1, int id2) const;
117 
119  DLLEXPORT void SetDebugDrawer(const std::shared_ptr<PhysicsDebugDrawer>& drawer);
120 
122  {
123  return OwningWorld;
124  }
125 
126  //
127  // Script wrappers
128  //
129  inline PhysicsShape* CreateSphereWrapper(float radius)
130  {
131  return CreateSphere(radius).detach();
132  }
133 
134  inline PhysicsShape* CreateConeWrapper(float radius, float height)
135  {
136  return CreateCone(radius, height).detach();
137  }
138 
140  {
141  return CreateCompound().detach();
142  }
143 
145  const Float3& aoffset, const Quaternion& aorientation, const Float3& boffset,
146  const Quaternion& borientation)
147  {
149  aorientation, boffset, borientation)
150  .detach();
151  }
152 
154  {
155  const auto result = DestroyConstraint(constraint);
156  if(constraint)
157  constraint->Release();
158  return result;
159  }
160 
161 protected:
162  static void OnPhysicsSubStep(btDynamicsWorld* world, btScalar timeStep);
163 
166  void OnManifoldWithContact(btPersistentManifold* contactManifold,
167  const btManifoldPoint& contactPoint, const PhysMaterialDataPair& pair,
168  PhysicsBody* body1, PhysicsBody* body2);
169 
170 protected:
172  float PassedTimeTotal = 0;
173 
176 
179 
180  // Bullet resources
181  std::unique_ptr<btDefaultCollisionConfiguration> CollisionConfiguration;
182 
183  std::unique_ptr<btCollisionDispatcher> Dispatcher;
184 
185  std::unique_ptr<btBroadphaseInterface> OverlappingPairCache;
186 
187  std::unique_ptr<btSequentialImpulseConstraintSolver> Solver;
188 
189  std::unique_ptr<btDiscreteDynamicsWorld> DynamicsWorld;
190 
191  std::unique_ptr<LeviathanPhysicsOverlapFilter> OverlapFilter;
192 
194  std::vector<PhysicsBody::pointer> PhysicsBodies;
195 
197  std::vector<PhysicsConstraint::pointer> PhysicsConstraints;
198 
199  std::shared_ptr<PhysicsDebugDrawer> DebugDrawer;
200 
201  // //! Used for resimulation
202  // //! \todo Potentially allow this to be a vector
203  // NewtonBody* ResimulatedBody = nullptr;
204 };
205 
206 } // namespace Leviathan
constexpr auto PHYSICS_BASE_GRAVITY
Definition: PhysicalWorld.h:40
void OnManifoldWithContact(btPersistentManifold *contactManifold, const btManifoldPoint &contactPoint, const PhysMaterialDataPair &pair, PhysicsBody *body1, PhysicsBody *body2)
Calls appropriate material callbacks. This is called once per contact manifold that has penetrating p...
PhysicsShape * CreateCompoundWrapper()
DLLEXPORT void SimulateWorld(float secondspassed, int maxsubsteps=8)
Advances the simulation the specified amount of time.
std::unique_ptr< btDefaultCollisionConfiguration > CollisionConfiguration
std::unique_ptr< btBroadphaseInterface > OverlappingPairCache
std::vector< PhysicsBody::pointer > PhysicsBodies
We need to keep the physic bodies alive (guaranteed) until they are destroyed.
bool PhysicsUpdateInProgress
This is a small sanity check for preventing destroying physics bodies during a tick.
DLLEXPORT PhysicsShape::pointer CreateCompound()
DLLEXPORT bool ChangeBodyShape(const PhysicsBody::pointer &body, const PhysicsShape::pointer &shape)
Applies a changed shape to a body.
This acts as a bridge between Leviathan positions and physics engine positions.
Definition: PhysicsBody.h:27
std::unique_ptr< btCollisionDispatcher > Dispatcher
This is an instance of a collision body.
A physical shape that can be used to create PhysicsBody objects.
Definition: PhysicsShape.h:18
DLLEXPORT PhysicsShape::pointer CreateBox(float xdimension, float ydimension, float zdimension)
The dimensions are halfwidths of the box along each axis.
Defines properties between two materials.
DLLEXPORT PhysicsBody::pointer CreateBodyFromCollision(const PhysicsShape::pointer &shape, float mass, PhysicsPositionProvider *positionsynchronization, int physicsmaterialid=-1)
Constraints body to a 2d plane of movement specified by its normal.
FORCE_INLINE void Release() const
removes a reference and deletes the object if reference count reaches zero
DLLEXPORT PhysicsShape::pointer CreateCone(float radius, float height)
float btScalar
Definition: PhysicalWorld.h:30
DLLEXPORT bool DestroyConstraint(PhysicsConstraint *constraint)
Destroys a physics constraint.
std::vector< PhysicsConstraint::pointer > PhysicsConstraints
We need to keep constraints alive until they are destroyed.
static void OnPhysicsSubStep(btDynamicsWorld *world, btScalar timeStep)
This is an instance of a collision body.
Definition: PhysicsBody.h:77
float PassedTimeTotal
Total amount of seconds required to be simulated.
DLLEXPORT bool DestroyBody(PhysicsBody *body)
Destroys a physics body.
const PhysMaterialDataPair * GetMaterialPair(int id1, int id2) const
Finds the information for contact between objects with two materials.
std::shared_ptr< PhysicsDebugDrawer > DebugDrawer
DLLEXPORT PhysicsConstraint::pointer CreateFixedConstraint(const PhysicsBody::pointer &a, const PhysicsBody::pointer &b, const Float3 &aoffset, const Quaternion &aorientation, const Float3 &boffset, const Quaternion &borientation)
PhysicsShape * CreateConeWrapper(float radius, float height)
PhysicsMaterialManager * PhysicsMaterials
std::unique_ptr< LeviathanPhysicsOverlapFilter > OverlapFilter
DLLEXPORT void SetDebugDrawer(const std::shared_ptr< PhysicsDebugDrawer > &drawer)
Sets or clears the debug drawer used by this world.
DLLEXPORT PhysicsShape::pointer CreateSphere(float radius)
Contains a material list for applying automatic properties to PhysicsBody and collision callbacks.
A Quaternion type to make quaternion specific operations easier to access.
Definition: Quaternion.h:14
#define DLLEXPORT
Definition: Include.h:84
std::unique_ptr< btDiscreteDynamicsWorld > DynamicsWorld
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
static boost::intrusive_ptr< ActualType > WrapPtr(ActualType *ptr)
Creates an intrusive_ptr from raw pointer.
DLLEXPORT PhysicalWorld(GameWorld *owner, PhysicsMaterialManager *physicscallbacks)
bool DestroyConstraintWrapper(PhysicsConstraint *constraint)
PhysicsShape * CreateSphereWrapper(float radius)
PhysicsConstraint * CreateFixedConstraintWrapper(PhysicsBody *a, PhysicsBody *b, const Float3 &aoffset, const Quaternion &aorientation, const Float3 &boffset, const Quaternion &borientation)
DLLEXPORT GameWorld * GetGameWorld()
Represents a world that contains entities.
Definition: GameWorld.h:57
std::unique_ptr< btSequentialImpulseConstraintSolver > Solver