BsPhysics.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsPhysics.h"
  4. #include "BsRigidbody.h"
  5. #include "BsRay.h"
  6. #include "BsCCollider.h"
  7. namespace BansheeEngine
  8. {
  9. Physics::Physics(const PHYSICS_INIT_DESC& init)
  10. {
  11. memset(mCollisionMap, 1, CollisionMapSize * CollisionMapSize * sizeof(bool));
  12. }
  13. void Physics::toggleCollision(UINT64 groupA, UINT64 groupB, bool enabled)
  14. {
  15. assert(groupA < CollisionMapSize && groupB < CollisionMapSize);
  16. mMutex.lock();
  17. mCollisionMap[groupA][groupB] = enabled;
  18. }
  19. bool Physics::isCollisionEnabled(UINT64 groupA, UINT64 groupB) const
  20. {
  21. assert(groupA < CollisionMapSize && groupB < CollisionMapSize);
  22. mMutex.lock();
  23. return mCollisionMap[groupA][groupB];
  24. }
  25. bool Physics::rayCast(const Ray& ray, PhysicsQueryHit& hit, UINT64 layer, float max) const
  26. {
  27. return rayCast(ray.getOrigin(), ray.getDirection(), hit, layer, max);
  28. }
  29. Vector<PhysicsQueryHit> Physics::rayCastAll(const Ray& ray, UINT64 layer, float max) const
  30. {
  31. return rayCastAll(ray.getOrigin(), ray.getDirection(), layer, max);
  32. }
  33. bool Physics::rayCastAny(const Ray& ray, UINT64 layer, float max) const
  34. {
  35. return rayCastAny(ray.getOrigin(), ray.getDirection(), layer, max);
  36. }
  37. Vector<HCollider> rawToComponent(const Vector<Collider*>& raw)
  38. {
  39. if (raw.empty())
  40. return Vector<HCollider>(0);
  41. Vector<HCollider> output;
  42. for (auto& entry : raw)
  43. {
  44. if (entry == nullptr)
  45. continue;
  46. CCollider* component = (CCollider*)entry->_getOwner(PhysicsOwnerType::Component);
  47. if (component == nullptr)
  48. continue;
  49. output.push_back(component->getHandle());
  50. }
  51. return output;
  52. }
  53. Vector<HCollider> Physics::boxOverlap(const AABox& box, const Quaternion& rotation, UINT64 layer) const
  54. {
  55. return rawToComponent(_boxOverlap(box, rotation, layer));
  56. }
  57. Vector<HCollider> Physics::sphereOverlap(const Sphere& sphere, UINT64 layer) const
  58. {
  59. return rawToComponent(_sphereOverlap(sphere, layer));
  60. }
  61. Vector<HCollider> Physics::capsuleOverlap(const Capsule& capsule, const Quaternion& rotation, UINT64 layer) const
  62. {
  63. return rawToComponent(_capsuleOverlap(capsule, rotation, layer));
  64. }
  65. Vector<HCollider> Physics::convexOverlap(const HPhysicsMesh& mesh, const Vector3& position,
  66. const Quaternion& rotation, UINT64 layer) const
  67. {
  68. return rawToComponent(_convexOverlap(mesh, position, rotation, layer));
  69. }
  70. void Physics::registerRigidbody(Rigidbody* body, UINT32 priority)
  71. {
  72. assert(priority <= MAX_PRIORITY && "Priority value too high");
  73. if (mRigidbodies.size() <= priority)
  74. mRigidbodies.resize(priority + 1);
  75. UINT32 nextId = (UINT32)mRigidbodies[priority].size();
  76. mRigidbodies[priority].push_back(body);
  77. body->_setPhysicsId(nextId);
  78. }
  79. void Physics::unregisterRigidbody(UINT32 id, UINT32 priority)
  80. {
  81. assert(mRigidbodies.size() >= priority);
  82. auto& rigidbodies = mRigidbodies[priority];
  83. UINT32 lastId = (UINT32)rigidbodies.size();
  84. if (id != lastId)
  85. {
  86. rigidbodies[id] = rigidbodies[lastId];
  87. rigidbodies[id]->_setPhysicsId(id);
  88. }
  89. rigidbodies.erase(rigidbodies.begin() + lastId);
  90. }
  91. void Physics::updatePriority(UINT32 id, UINT32 oldPriority, UINT32 newPriority)
  92. {
  93. assert(newPriority <= MAX_PRIORITY && "Priority value too high");
  94. if (oldPriority == newPriority)
  95. return;
  96. assert(mRigidbodies.size() >= oldPriority);
  97. auto& rigidbodies = mRigidbodies[oldPriority];
  98. Rigidbody* rigidbody = rigidbodies[id];
  99. unregisterRigidbody(id, oldPriority);
  100. registerRigidbody(rigidbody, newPriority);
  101. }
  102. Physics& gPhysics()
  103. {
  104. return Physics::instance();
  105. }
  106. }