BsPhysX.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsPhysXPrerequisites.h"
  5. #include "BsPhysics.h"
  6. #include "BsPhysicsCommon.h"
  7. #include "PxPhysics.h"
  8. #include "foundation/Px.h"
  9. #include "characterkinematic\PxControllerManager.h"
  10. #include "cooking/PxCooking.h"
  11. namespace BansheeEngine
  12. {
  13. /** @addtogroup PhysX
  14. * @{
  15. */
  16. /** NVIDIA PhysX implementation of Physics. */
  17. class PhysX : public Physics
  18. {
  19. /** Type of contacts reported by PhysX simulation. */
  20. enum class ContactEventType
  21. {
  22. ContactBegin,
  23. ContactStay,
  24. ContactEnd
  25. };
  26. /** Event reported when a physics object interacts with a collider. */
  27. struct TriggerEvent
  28. {
  29. Collider* trigger; /** Trigger that was interacted with. */
  30. Collider* other; /** Collider that was interacted with. */
  31. ContactEventType type; /** Exact type of the event. */
  32. };
  33. /** Event reported when two colliders interact. */
  34. struct ContactEvent
  35. {
  36. Collider* colliderA; /** First collider. */
  37. Collider* colliderB; /** Second collider. */
  38. ContactEventType type; /** Exact type of the event. */
  39. // Note: Not too happy this is heap allocated, use static allocator?
  40. Vector<ContactPoint> points; /** Information about all contact points between the colliders. */
  41. };
  42. /** Event reported when a joint breaks. */
  43. struct JointBreakEvent
  44. {
  45. Joint* joint; /** Broken joint. */
  46. };
  47. public:
  48. PhysX(const PHYSICS_INIT_DESC& input);
  49. ~PhysX();
  50. /** @copydoc Physics::update */
  51. void update() override;
  52. /** @copydoc Physics::createMaterial */
  53. SPtr<PhysicsMaterial> createMaterial(float staticFriction, float dynamicFriction, float restitution) override;
  54. /** @copydoc Physics::createMesh */
  55. SPtr<PhysicsMesh> createMesh(const SPtr<MeshData>& meshData, PhysicsMeshType type) override;
  56. /** @copydoc Physics::createRigidbody */
  57. SPtr<Rigidbody> createRigidbody(const HSceneObject& linkedSO) override;
  58. /** @copydoc Physics::createBoxCollider */
  59. SPtr<BoxCollider> createBoxCollider(const Vector3& extents, const Vector3& position,
  60. const Quaternion& rotation) override;
  61. /** @copydoc Physics::createSphereCollider */
  62. SPtr<SphereCollider> createSphereCollider(float radius, const Vector3& position, const Quaternion& rotation) override;
  63. /** @copydoc Physics::createPlaneCollider */
  64. SPtr<PlaneCollider> createPlaneCollider(const Vector3& position, const Quaternion& rotation) override;
  65. /** @copydoc Physics::createCapsuleCollider */
  66. SPtr<CapsuleCollider> createCapsuleCollider(float radius, float halfHeight, const Vector3& position,
  67. const Quaternion& rotation) override;
  68. /** @copydoc Physics::createMeshCollider */
  69. SPtr<MeshCollider> createMeshCollider(const Vector3& position, const Quaternion& rotation) override;
  70. /** @copydoc Physics::createFixedJoint */
  71. SPtr<FixedJoint> createFixedJoint(const FIXED_JOINT_DESC& desc) override;
  72. /** @copydoc Physics::createDistanceJoint */
  73. SPtr<DistanceJoint> createDistanceJoint(const DISTANCE_JOINT_DESC& desc) override;
  74. /** @copydoc Physics::createHingeJoint */
  75. SPtr<HingeJoint> createHingeJoint(const HINGE_JOINT_DESC& desc) override;
  76. /** @copydoc Physics::createSphericalJoint */
  77. SPtr<SphericalJoint> createSphericalJoint(const SPHERICAL_JOINT_DESC& desc) override;
  78. /** @copydoc Physics::createSliderJoint */
  79. SPtr<SliderJoint> createSliderJoint(const SLIDER_JOINT_DESC& desc) override;
  80. /** @copydoc Physics::createD6Joint */
  81. SPtr<D6Joint> createD6Joint(const D6_JOINT_DESC& desc) override;
  82. /** @copydoc Physics::createCharacterController*/
  83. SPtr<CharacterController> createCharacterController(const CHAR_CONTROLLER_DESC& desc) override;
  84. /** @copydoc Physics::rayCast(const Vector3&, const Vector3&, PhysicsQueryHit&, UINT64, float) const */
  85. bool rayCast(const Vector3& origin, const Vector3& unitDir, PhysicsQueryHit& hit,
  86. UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  87. /** @copydoc Physics::boxCast */
  88. bool boxCast(const AABox& box, const Quaternion& rotation, const Vector3& unitDir, PhysicsQueryHit& hit,
  89. UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  90. /** @copydoc Physics::sphereCast */
  91. bool sphereCast(const Sphere& sphere, const Vector3& unitDir, PhysicsQueryHit& hit,
  92. UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  93. /** @copydoc Physics::capsuleCast */
  94. bool capsuleCast(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
  95. PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  96. /** @copydoc Physics::convexCast */
  97. bool convexCast(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
  98. const Vector3& unitDir, PhysicsQueryHit& hit, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  99. /** @copydoc Physics::rayCastAll(const Vector3&, const Vector3&, UINT64, float) const */
  100. Vector<PhysicsQueryHit> rayCastAll(const Vector3& origin, const Vector3& unitDir,
  101. UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  102. /** @copydoc Physics::boxCastAll */
  103. Vector<PhysicsQueryHit> boxCastAll(const AABox& box, const Quaternion& rotation,
  104. const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  105. /** @copydoc Physics::sphereCastAll */
  106. Vector<PhysicsQueryHit> sphereCastAll(const Sphere& sphere, const Vector3& unitDir,
  107. UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  108. /** @copydoc Physics::capsuleCastAll */
  109. Vector<PhysicsQueryHit> capsuleCastAll(const Capsule& capsule, const Quaternion& rotation,
  110. const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  111. /** @copydoc Physics::convexCastAll */
  112. Vector<PhysicsQueryHit> convexCastAll(const HPhysicsMesh& mesh, const Vector3& position,
  113. const Quaternion& rotation, const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS,
  114. float max = FLT_MAX) const override;
  115. /** @copydoc Physics::rayCastAny(const Vector3&, const Vector3&, UINT64, float) const */
  116. bool rayCastAny(const Vector3& origin, const Vector3& unitDir,
  117. UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  118. /** @copydoc Physics::boxCastAny */
  119. bool boxCastAny(const AABox& box, const Quaternion& rotation, const Vector3& unitDir,
  120. UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  121. /** @copydoc Physics::sphereCastAny */
  122. bool sphereCastAny(const Sphere& sphere, const Vector3& unitDir,
  123. UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  124. /** @copydoc Physics::capsuleCastAny */
  125. bool capsuleCastAny(const Capsule& capsule, const Quaternion& rotation, const Vector3& unitDir,
  126. UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  127. /** @copydoc Physics::convexCastAny */
  128. bool convexCastAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
  129. const Vector3& unitDir, UINT64 layer = BS_ALL_LAYERS, float max = FLT_MAX) const override;
  130. /** @copydoc Physics::boxOverlapAny */
  131. bool boxOverlapAny(const AABox& box, const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) const override;
  132. /** @copydoc Physics::sphereOverlapAny */
  133. bool sphereOverlapAny(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) const override;
  134. /** @copydoc Physics::capsuleOverlapAny */
  135. bool capsuleOverlapAny(const Capsule& capsule, const Quaternion& rotation,
  136. UINT64 layer = BS_ALL_LAYERS) const override;
  137. /** @copydoc Physics::convexOverlapAny */
  138. bool convexOverlapAny(const HPhysicsMesh& mesh, const Vector3& position, const Quaternion& rotation,
  139. UINT64 layer = BS_ALL_LAYERS) const override;
  140. /** @copydoc Physics::setFlag */
  141. void setFlag(PhysicsFlags flags, bool enabled) override;
  142. /** @copydoc Physics::setPaused */
  143. void setPaused(bool paused) override;
  144. /** @copydoc Physics::getGravity */
  145. Vector3 getGravity() const override;
  146. /** @copydoc Physics::setGravity */
  147. void setGravity(const Vector3& gravity) override;
  148. /** @copydoc Physics::getMaxTesselationEdgeLength */
  149. float getMaxTesselationEdgeLength() const override { return mTesselationLength; }
  150. /** @copydoc Physics::setMaxTesselationEdgeLength */
  151. void setMaxTesselationEdgeLength(float length) override;
  152. /** @copydoc Physics::addBroadPhaseRegion */
  153. UINT32 addBroadPhaseRegion(const AABox& region) override;
  154. /** @copydoc Physics::removeBroadPhaseRegion */
  155. void removeBroadPhaseRegion(UINT32 regionId) override;
  156. /** @copydoc Physics::clearBroadPhaseRegions */
  157. void clearBroadPhaseRegions() override;
  158. /** @copydoc Physics::_boxOverlap */
  159. Vector<Collider*> _boxOverlap(const AABox& box, const Quaternion& rotation,
  160. UINT64 layer = BS_ALL_LAYERS) const override;
  161. /** @copydoc Physics::_sphereOverlap */
  162. Vector<Collider*> _sphereOverlap(const Sphere& sphere, UINT64 layer = BS_ALL_LAYERS) const override;
  163. /** @copydoc Physics::_capsuleOverlap */
  164. Vector<Collider*> _capsuleOverlap(const Capsule& capsule, const Quaternion& rotation,
  165. UINT64 layer = BS_ALL_LAYERS) const override;
  166. /** @copydoc Physics::_convexOverlap */
  167. Vector<Collider*> _convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
  168. const Quaternion& rotation, UINT64 layer = BS_ALL_LAYERS) const override;
  169. /** @copydoc Physics::_rayCast */
  170. bool _rayCast(const Vector3& origin, const Vector3& unitDir, const Collider& collider, PhysicsQueryHit& hit,
  171. float maxDist = FLT_MAX) const override;
  172. /** Triggered by the PhysX simulation when an interaction between two colliders is found. */
  173. void _reportContactEvent(const ContactEvent& event);
  174. /** Triggered by the PhysX simulation when an interaction between two trigger and a collider is found. */
  175. void _reportTriggerEvent(const TriggerEvent& event);
  176. /** Triggered by the PhysX simulation when a joint breaks. */
  177. void _reportJointBreakEvent(const JointBreakEvent& event);
  178. /** Returns the default PhysX material. */
  179. physx::PxMaterial* getDefaultMaterial() const { return mDefaultMaterial; }
  180. /** Returns the main PhysX object. */
  181. physx::PxPhysics* getPhysX() const { return mPhysics; }
  182. /** Returns the main PhysX scene. */
  183. physx::PxScene* getScene() const { return mScene; }
  184. /** Returns the PhysX object used for mesh cooking. */
  185. physx::PxCooking* getCooking() const { return mCooking; }
  186. /** Returns default scale used in the PhysX scene. */
  187. physx::PxTolerancesScale getScale() const { return mScale; }
  188. private:
  189. friend class PhysXEventCallback;
  190. /** Sends out all events recorded during simulation to the necessary physics objects. */
  191. void triggerEvents();
  192. /**
  193. * Helper method that performs a sweep query by checking if the provided geometry hits any physics objects
  194. * when moved along the specified direction. Returns information about the first hit.
  195. */
  196. inline bool sweep(const physx::PxGeometry& geometry, const physx::PxTransform& tfrm, const Vector3& unitDir,
  197. PhysicsQueryHit& hit, UINT64 layer, float maxDist) const;
  198. /**
  199. * Helper method that performs a sweep query by checking if the provided geometry hits any physics objects
  200. * when moved along the specified direction. Returns information about all hit.
  201. */
  202. inline Vector<PhysicsQueryHit> sweepAll(const physx::PxGeometry& geometry, const physx::PxTransform& tfrm,
  203. const Vector3& unitDir, UINT64 layer, float maxDist) const;
  204. /**
  205. * Helper method that performs a sweep query by checking if the provided geometry hits any physics objects
  206. * when moved along the specified direction. Returns no information about the hit, but rather just if it happened or
  207. * not.
  208. */
  209. inline bool sweepAny(const physx::PxGeometry& geometry, const physx::PxTransform& tfrm, const Vector3& unitDir,
  210. UINT64 layer, float maxDist) const;
  211. /** Helper method that returns all colliders that are overlapping the provided geometry. */
  212. inline Vector<Collider*> overlap(const physx::PxGeometry& geometry, const physx::PxTransform& tfrm,
  213. UINT64 layer) const;
  214. /** Helper method that checks if the provided geometry overlaps any physics object. */
  215. inline bool overlapAny(const physx::PxGeometry& geometry, const physx::PxTransform& tfrm, UINT64 layer) const;
  216. float mSimulationStep = 1.0f/60.0f;
  217. float mSimulationTime = 0.0f;
  218. float mFrameTime = 0.0f;
  219. float mTesselationLength = 3.0f;
  220. UINT32 mNextRegionIdx = 1;
  221. bool mPaused = false;
  222. Vector<TriggerEvent> mTriggerEvents;
  223. Vector<ContactEvent> mContactEvents;
  224. Vector<JointBreakEvent> mJointBreakEvents;
  225. UnorderedMap<UINT32, UINT32> mBroadPhaseRegionHandles;
  226. physx::PxFoundation* mFoundation = nullptr;
  227. physx::PxPhysics* mPhysics = nullptr;
  228. physx::PxCooking* mCooking = nullptr;
  229. physx::PxScene* mScene = nullptr;
  230. physx::PxControllerManager* mCharManager = nullptr;
  231. physx::PxMaterial* mDefaultMaterial = nullptr;
  232. physx::PxTolerancesScale mScale;
  233. static const UINT32 SCRATCH_BUFFER_SIZE;
  234. /** Determines how many physics updates per frame are allowed. Only relevant when framerate is low. */
  235. static const UINT32 MAX_ITERATIONS_PER_FRAME;
  236. };
  237. /** Provides easier access to PhysX. */
  238. PhysX& gPhysX();
  239. /** @} */
  240. }