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