PhysicsBody.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Physics2/PhysicsBody.h>
  6. #include <AnKi/Physics2/PhysicsWorld.h>
  7. namespace anki {
  8. namespace v2 {
  9. void PhysicsBody::init(const PhysicsBodyInitInfo& init)
  10. {
  11. PhysicsWorld& world = PhysicsWorld::getSingleton();
  12. const Vec3 pos = init.m_transform.getOrigin().xyz();
  13. const Quat rot = Quat(init.m_transform.getRotation());
  14. // Create a scale shape
  15. const Bool hasScale = (init.m_transform.getScale().xyz() - 1.0).getLengthSquared() > kEpsilonf * 10.0;
  16. PhysicsCollisionShapePtr scaledShape;
  17. if(hasScale)
  18. {
  19. scaledShape = world.newScaleCollisionObject(init.m_transform.getScale().xyz(), init.m_shape);
  20. }
  21. // Create JPH body
  22. JPH::EMotionType motionType;
  23. if(init.m_isTrigger)
  24. {
  25. motionType = JPH::EMotionType::Kinematic;
  26. }
  27. else if(init.m_mass == 0.0f)
  28. {
  29. motionType = JPH::EMotionType::Static;
  30. }
  31. else
  32. {
  33. motionType = JPH::EMotionType::Dynamic;
  34. }
  35. JPH::BodyCreationSettings settings((scaledShape) ? &scaledShape->m_scaled : &init.m_shape->m_shapeBase, toJPH(pos), toJPH(rot), motionType,
  36. JPH::ObjectLayer(init.m_layer));
  37. if(init.m_mass)
  38. {
  39. ANKI_ASSERT(!init.m_isTrigger && "Triggers can't have mass");
  40. settings.mOverrideMassProperties = JPH::EOverrideMassProperties::CalculateInertia;
  41. settings.mMassPropertiesOverride.mMass = init.m_mass;
  42. }
  43. settings.mFriction = init.m_friction;
  44. settings.mUserData = ptrToNumber(static_cast<PhysicsObjectBase*>(this));
  45. settings.mIsSensor = init.m_isTrigger;
  46. // Call the thread-safe version because many threads may try to create bodies
  47. JPH::Body* jphBody = world.m_jphPhysicsSystem->GetBodyInterface().CreateBody(settings);
  48. world.m_jphPhysicsSystem->GetBodyInterface().AddBody(jphBody->GetID(), JPH::EActivation::Activate);
  49. // Misc
  50. m_jphBody = jphBody;
  51. m_primaryShape.reset(init.m_shape);
  52. m_scaledShape = scaledShape;
  53. m_worldTrf = init.m_transform;
  54. m_isTrigger = init.m_isTrigger;
  55. m_mass = init.m_mass;
  56. setUserData(init.m_userData);
  57. }
  58. void PhysicsBody::setTransform(const Transform& trf)
  59. {
  60. ANKI_ASSERT(trf.getScale() == m_worldTrf.getScale() && "Can't handle dynamic scaling for now");
  61. const JPH::RVec3 pos = toJPH(trf.getOrigin().xyz());
  62. const JPH::Quat rot = toJPH(Quat(trf.getRotation()));
  63. PhysicsWorld::getSingleton().m_jphPhysicsSystem->GetBodyInterfaceNoLock().SetPositionAndRotation(m_jphBody->GetID(), pos, rot,
  64. JPH::EActivation::Activate);
  65. m_worldTrf = trf;
  66. ++m_worldTrfVersion;
  67. }
  68. void PhysicsBody::applyForce(const Vec3& force, const Vec3& relPos)
  69. {
  70. const Vec3 worldForcePos = m_worldTrf.transform(relPos);
  71. PhysicsWorld::getSingleton().m_jphPhysicsSystem->GetBodyInterfaceNoLock().AddForce(m_jphBody->GetID(), toJPH(force), toJPH(worldForcePos));
  72. }
  73. void PhysicsBody::applyForce(const Vec3& force)
  74. {
  75. PhysicsWorld::getSingleton().m_jphPhysicsSystem->GetBodyInterfaceNoLock().AddForce(m_jphBody->GetID(), toJPH(force));
  76. }
  77. void PhysicsBody::activate(Bool activate)
  78. {
  79. if(activate)
  80. {
  81. PhysicsWorld::getSingleton().m_jphPhysicsSystem->GetBodyInterfaceNoLock().ActivateBody(m_jphBody->GetID());
  82. }
  83. else
  84. {
  85. PhysicsWorld::getSingleton().m_jphPhysicsSystem->GetBodyInterfaceNoLock().DeactivateBody(m_jphBody->GetID());
  86. }
  87. }
  88. void PhysicsBody::setGravityFactor(F32 factor)
  89. {
  90. PhysicsWorld::getSingleton().m_jphPhysicsSystem->GetBodyInterfaceNoLock().SetGravityFactor(m_jphBody->GetID(), factor);
  91. }
  92. void PhysicsBody::postPhysicsUpdate()
  93. {
  94. if(m_activated)
  95. {
  96. const Transform newTrf =
  97. toAnKi(PhysicsWorld::getSingleton().m_jphPhysicsSystem->GetBodyInterfaceNoLock().GetWorldTransform(m_jphBody->GetID()));
  98. if(newTrf != m_worldTrf)
  99. {
  100. m_worldTrf = newTrf;
  101. ++m_worldTrfVersion;
  102. }
  103. }
  104. }
  105. } // namespace v2
  106. } // namespace anki