1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #pragma once
24 
25 #include "../Container/HashSet.h"
26 #include "../IO/VectorBuffer.h"
27 #include "../Math/BoundingBox.h"
28 #include "../Math/Sphere.h"
29 #include "../Math/Vector3.h"
30 #include "../Scene/Component.h"
31 
32 #include <Bullet/LinearMath/btIDebugDraw.h>
33 
34 class btCollisionConfiguration;
35 class btCollisionShape;
36 class btBroadphaseInterface;
37 class btConstraintSolver;
38 class btDiscreteDynamicsWorld;
39 class btDispatcher;
40 class btDynamicsWorld;
41 class btPersistentManifold;
42 
43 namespace Urho3D
44 {
45 
46 class CollisionShape;
47 class Deserializer;
48 class Constraint;
49 class Model;
50 class Node;
51 class Ray;
52 class RigidBody;
53 class Scene;
54 class Serializer;
55 class XMLElement;
56 
57 struct CollisionGeometryData;
58 
59 /// Physics raycast hit.
60 struct URHO3D_API PhysicsRaycastResult
61 {
62     /// Construct with defaults.
PhysicsRaycastResultPhysicsRaycastResult63     PhysicsRaycastResult() :
64         body_(0)
65     {
66     }
67 
68     /// Test for inequality, added to prevent GCC from complaining.
69     bool operator !=(const PhysicsRaycastResult& rhs) const
70     {
71         return position_ != rhs.position_ || normal_ != rhs.normal_ || distance_ != rhs.distance_ || body_ != rhs.body_;
72     }
73 
74     /// Hit worldspace position.
75     Vector3 position_;
76     /// Hit worldspace normal.
77     Vector3 normal_;
78     /// Hit distance from ray origin.
79     float distance_;
80     /// Hit fraction.
81     float hitFraction_;
82     /// Rigid body that was hit.
83     RigidBody* body_;
84 };
85 
86 /// Delayed world transform assignment for parented rigidbodies.
87 struct DelayedWorldTransform
88 {
89     /// Rigid body.
90     RigidBody* rigidBody_;
91     /// Parent rigid body.
92     RigidBody* parentRigidBody_;
93     /// New world position.
94     Vector3 worldPosition_;
95     /// New world rotation.
96     Quaternion worldRotation_;
97 };
98 
99 /// Manifold pointers stored during collision processing.
100 struct ManifoldPair
101 {
102     /// Construct with defaults.
ManifoldPairManifoldPair103     ManifoldPair() :
104         manifold_(0),
105         flippedManifold_(0)
106     {
107     }
108 
109     /// Manifold without the body pointers flipped.
110     btPersistentManifold* manifold_;
111     /// Manifold with the body pointers flipped.
112     btPersistentManifold* flippedManifold_;
113 };
114 
115 /// Custom overrides of physics internals. To use overrides, must be set before the physics component is created.
116 struct PhysicsWorldConfig
117 {
PhysicsWorldConfigPhysicsWorldConfig118     PhysicsWorldConfig() :
119         collisionConfig_(0)
120     {
121     }
122 
123     /// Override for the collision configuration (default btDefaultCollisionConfiguration).
124     btCollisionConfiguration* collisionConfig_;
125 };
126 
127 static const float DEFAULT_MAX_NETWORK_ANGULAR_VELOCITY = 100.0f;
128 
129 /// Physics simulation world component. Should be added only to the root scene node.
130 class URHO3D_API PhysicsWorld : public Component, public btIDebugDraw
131 {
132     URHO3D_OBJECT(PhysicsWorld, Component);
133 
134     friend void InternalPreTickCallback(btDynamicsWorld* world, btScalar timeStep);
135     friend void InternalTickCallback(btDynamicsWorld* world, btScalar timeStep);
136 
137 public:
138     /// Construct.
139     PhysicsWorld(Context* scontext);
140     /// Destruct.
141     virtual ~PhysicsWorld();
142     /// Register object factory.
143     static void RegisterObject(Context* context);
144 
145     /// Check if an AABB is visible for debug drawing.
146     virtual bool isVisible(const btVector3& aabbMin, const btVector3& aabbMax);
147     /// Draw a physics debug line.
148     virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color);
149     /// Log warning from the physics engine.
150     virtual void reportErrorWarning(const char* warningString);
151     /// Draw a physics debug contact point. Not implemented.
152     virtual void drawContactPoint
153         (const btVector3& pointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color);
154     /// Draw physics debug 3D text. Not implemented.
155     virtual void draw3dText(const btVector3& location, const char* textString);
156 
157     /// Set debug draw flags.
setDebugMode(int debugMode)158     virtual void setDebugMode(int debugMode) { debugMode_ = debugMode; }
159 
160     /// Return debug draw flags.
getDebugMode()161     virtual int getDebugMode() const { return debugMode_; }
162 
163     /// Visualize the component as debug geometry.
164     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
165 
166     /// Step the simulation forward.
167     void Update(float timeStep);
168     /// Refresh collisions only without updating dynamics.
169     void UpdateCollisions();
170     /// Set simulation substeps per second.
171     void SetFps(int fps);
172     /// Set gravity.
173     void SetGravity(const Vector3& gravity);
174     /// Set maximum number of physics substeps per frame. 0 (default) is unlimited. Positive values cap the amount. Use a negative value to enable an adaptive timestep. This may cause inconsistent physics behavior.
175     void SetMaxSubSteps(int num);
176     /// Set number of constraint solver iterations.
177     void SetNumIterations(int num);
178     /// Enable or disable automatic physics simulation during scene update. Enabled by default.
179     void SetUpdateEnabled(bool enable);
180     /// Set whether to interpolate between simulation steps.
181     void SetInterpolation(bool enable);
182     /// Set whether to use Bullet's internal edge utility for trimesh collisions. Disabled by default.
183     void SetInternalEdge(bool enable);
184     /// Set split impulse collision mode. This is more accurate, but slower. Disabled by default.
185     void SetSplitImpulse(bool enable);
186     /// Set maximum angular velocity for network replication.
187     void SetMaxNetworkAngularVelocity(float velocity);
188     /// Perform a physics world raycast and return all hits.
189     void Raycast
190         (PODVector<PhysicsRaycastResult>& result, const Ray& ray, float maxDistance, unsigned collisionMask = M_MAX_UNSIGNED);
191     /// Perform a physics world raycast and return the closest hit.
192     void RaycastSingle(PhysicsRaycastResult& result, const Ray& ray, float maxDistance, unsigned collisionMask = M_MAX_UNSIGNED);
193     /// Perform a physics world segmented raycast and return the closest hit. Useful for big scenes with many bodies.
194     void RaycastSingleSegmented(PhysicsRaycastResult& result, const Ray& ray, float maxDistance, float segmentDistance, unsigned collisionMask = M_MAX_UNSIGNED);
195     /// Perform a physics world swept sphere test and return the closest hit.
196     void SphereCast
197         (PhysicsRaycastResult& result, const Ray& ray, float radius, float maxDistance, unsigned collisionMask = M_MAX_UNSIGNED);
198     /// Perform a physics world swept convex test using a user-supplied collision shape and return the first hit.
199     void ConvexCast(PhysicsRaycastResult& result, CollisionShape* shape, const Vector3& startPos, const Quaternion& startRot,
200         const Vector3& endPos, const Quaternion& endRot, unsigned collisionMask = M_MAX_UNSIGNED);
201     /// Perform a physics world swept convex test using a user-supplied Bullet collision shape and return the first hit.
202     void ConvexCast(PhysicsRaycastResult& result, btCollisionShape* shape, const Vector3& startPos, const Quaternion& startRot,
203         const Vector3& endPos, const Quaternion& endRot, unsigned collisionMask = M_MAX_UNSIGNED);
204     /// Invalidate cached collision geometry for a model.
205     void RemoveCachedGeometry(Model* model);
206     /// Return rigid bodies by a sphere query.
207     void GetRigidBodies(PODVector<RigidBody*>& result, const Sphere& sphere, unsigned collisionMask = M_MAX_UNSIGNED);
208     /// Return rigid bodies by a box query.
209     void GetRigidBodies(PODVector<RigidBody*>& result, const BoundingBox& box, unsigned collisionMask = M_MAX_UNSIGNED);
210     /// Return rigid bodies by contact test with the specified body. It needs to be active to return all contacts reliably.
211     void GetRigidBodies(PODVector<RigidBody*>& result, const RigidBody* body);
212     /// Return rigid bodies that have been in collision with the specified body on the last simulation step. Only returns collisions that were sent as events (depends on collision event mode) and excludes e.g. static-static collisions.
213     void GetCollidingBodies(PODVector<RigidBody*>& result, const RigidBody* body);
214 
215     /// Return gravity.
216     Vector3 GetGravity() const;
217 
218     /// Return maximum number of physics substeps per frame.
GetMaxSubSteps()219     int GetMaxSubSteps() const { return maxSubSteps_; }
220 
221     /// Return number of constraint solver iterations.
222     int GetNumIterations() const;
223 
224     /// Return whether physics world will automatically simulate during scene update.
IsUpdateEnabled()225     bool IsUpdateEnabled() const { return updateEnabled_; }
226 
227     /// Return whether interpolation between simulation steps is enabled.
GetInterpolation()228     bool GetInterpolation() const { return interpolation_; }
229 
230     /// Return whether Bullet's internal edge utility for trimesh collisions is enabled.
GetInternalEdge()231     bool GetInternalEdge() const { return internalEdge_; }
232 
233     /// Return whether split impulse collision mode is enabled.
234     bool GetSplitImpulse() const;
235 
236     /// Return simulation steps per second.
GetFps()237     int GetFps() const { return fps_; }
238 
239     /// Return maximum angular velocity for network replication.
GetMaxNetworkAngularVelocity()240     float GetMaxNetworkAngularVelocity() const { return maxNetworkAngularVelocity_; }
241 
242     /// Add a rigid body to keep track of. Called by RigidBody.
243     void AddRigidBody(RigidBody* body);
244     /// Remove a rigid body. Called by RigidBody.
245     void RemoveRigidBody(RigidBody* body);
246     /// Add a collision shape to keep track of. Called by CollisionShape.
247     void AddCollisionShape(CollisionShape* shape);
248     /// Remove a collision shape. Called by CollisionShape.
249     void RemoveCollisionShape(CollisionShape* shape);
250     /// Add a constraint to keep track of. Called by Constraint.
251     void AddConstraint(Constraint* joint);
252     /// Remove a constraint. Called by Constraint.
253     void RemoveConstraint(Constraint* joint);
254     /// Add a delayed world transform assignment. Called by RigidBody.
255     void AddDelayedWorldTransform(const DelayedWorldTransform& transform);
256     /// Add debug geometry to the debug renderer.
257     void DrawDebugGeometry(bool depthTest);
258     /// Set debug renderer to use. Called both by PhysicsWorld itself and physics components.
259     void SetDebugRenderer(DebugRenderer* debug);
260     /// Set debug geometry depth test mode. Called both by PhysicsWorld itself and physics components.
261     void SetDebugDepthTest(bool enable);
262 
263     /// Return the Bullet physics world.
GetWorld()264     btDiscreteDynamicsWorld* GetWorld() { return world_.Get(); }
265 
266     /// Clean up the geometry cache.
267     void CleanupGeometryCache();
268 
269     /// Return trimesh collision geometry cache.
GetTriMeshCache()270     HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> >& GetTriMeshCache() { return triMeshCache_; }
271 
272     /// Return convex collision geometry cache.
GetConvexCache()273     HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> >& GetConvexCache() { return convexCache_; }
274 
275     /// Set node dirtying to be disregarded.
SetApplyingTransforms(bool enable)276     void SetApplyingTransforms(bool enable) { applyingTransforms_ = enable; }
277 
278     /// Return whether node dirtying should be disregarded.
IsApplyingTransforms()279     bool IsApplyingTransforms() const { return applyingTransforms_; }
280 
281     /// Return whether is currently inside the Bullet substep loop.
IsSimulating()282     bool IsSimulating() const { return simulating_; }
283 
284     /// Overrides of the internal configuration.
285     static struct PhysicsWorldConfig config;
286 
287 protected:
288     /// Handle scene being assigned.
289     virtual void OnSceneSet(Scene* scene);
290 
291 private:
292     /// Handle the scene subsystem update event, step simulation here.
293     void HandleSceneSubsystemUpdate(StringHash eventType, VariantMap& eventData);
294     /// Trigger update before each physics simulation step.
295     void PreStep(float timeStep);
296     /// Trigger update after each physics simulation step.
297     void PostStep(float timeStep);
298     /// Send accumulated collision events.
299     void SendCollisionEvents();
300 
301     /// Bullet collision configuration.
302     btCollisionConfiguration* collisionConfiguration_;
303     /// Bullet collision dispatcher.
304     UniquePtr<btDispatcher> collisionDispatcher_;
305     /// Bullet collision broadphase.
306     UniquePtr<btBroadphaseInterface> broadphase_;
307     /// Bullet constraint solver.
308     UniquePtr<btConstraintSolver> solver_;
309     /// Bullet physics world.
310     UniquePtr<btDiscreteDynamicsWorld> world_;
311     /// Extra weak pointer to scene to allow for cleanup in case the world is destroyed before other components.
312     WeakPtr<Scene> scene_;
313     /// Rigid bodies in the world.
314     PODVector<RigidBody*> rigidBodies_;
315     /// Collision shapes in the world.
316     PODVector<CollisionShape*> collisionShapes_;
317     /// Constraints in the world.
318     PODVector<Constraint*> constraints_;
319     /// Collision pairs on this frame.
320     HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, ManifoldPair> currentCollisions_;
321     /// Collision pairs on the previous frame. Used to check if a collision is "new." Manifolds are not guaranteed to exist anymore.
322     HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, ManifoldPair> previousCollisions_;
323     /// Delayed (parented) world transform assignments.
324     HashMap<RigidBody*, DelayedWorldTransform> delayedWorldTransforms_;
325     /// Cache for trimesh geometry data by model and LOD level.
326     HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> > triMeshCache_;
327     /// Cache for convex geometry data by model and LOD level.
328     HashMap<Pair<Model*, unsigned>, SharedPtr<CollisionGeometryData> > convexCache_;
329     /// Preallocated event data map for physics collision events.
330     VariantMap physicsCollisionData_;
331     /// Preallocated event data map for node collision events.
332     VariantMap nodeCollisionData_;
333     /// Preallocated buffer for physics collision contact data.
334     VectorBuffer contacts_;
335     /// Simulation substeps per second.
336     unsigned fps_;
337     /// Maximum number of simulation substeps per frame. 0 (default) unlimited, or negative values for adaptive timestep.
338     int maxSubSteps_;
339     /// Time accumulator for non-interpolated mode.
340     float timeAcc_;
341     /// Maximum angular velocity for network replication.
342     float maxNetworkAngularVelocity_;
343     /// Automatic simulation update enabled flag.
344     bool updateEnabled_;
345     /// Interpolation flag.
346     bool interpolation_;
347     /// Use internal edge utility flag.
348     bool internalEdge_;
349     /// Applying transforms flag.
350     bool applyingTransforms_;
351     /// Simulating flag.
352     bool simulating_;
353     /// Debug draw depth test mode.
354     bool debugDepthTest_;
355     /// Debug renderer.
356     DebugRenderer* debugRenderer_;
357     /// Debug draw flags.
358     int debugMode_;
359 };
360 
361 /// Register Physics library objects.
362 void URHO3D_API RegisterPhysicsLibrary(Context* context);
363 
364 }
365