BodyComponent.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright (C) 2009-2021, 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/Scene/Components/BodyComponent.h>
  6. #include <AnKi/Scene/SceneNode.h>
  7. #include <AnKi/Scene/SceneGraph.h>
  8. #include <AnKi/Resource/CpuMeshResource.h>
  9. #include <AnKi/Resource/ResourceManager.h>
  10. #include <AnKi/Physics/PhysicsWorld.h>
  11. namespace anki
  12. {
  13. ANKI_SCENE_COMPONENT_STATICS(BodyComponent)
  14. BodyComponent::BodyComponent(SceneNode* node)
  15. : SceneComponent(node, getStaticClassId())
  16. , m_node(node)
  17. {
  18. }
  19. BodyComponent::~BodyComponent()
  20. {
  21. }
  22. Error BodyComponent::loadMeshResource(CString meshFilename)
  23. {
  24. m_body.reset(nullptr);
  25. ANKI_CHECK(m_node->getSceneGraph().getResourceManager().loadResource(meshFilename, m_mesh));
  26. const Transform prevTransform = (m_body) ? m_body->getTransform() : m_trf;
  27. const F32 prevMass = (m_body) ? m_body->getMass() : 0.0f;
  28. PhysicsBodyInitInfo init;
  29. init.m_mass = prevMass;
  30. init.m_transform = prevTransform;
  31. init.m_shape = m_mesh->getCollisionShape();
  32. m_body = m_node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsBody>(init);
  33. m_body->setUserData(this);
  34. m_markedForUpdate = true;
  35. return Error::NONE;
  36. }
  37. CString BodyComponent::getMeshResourceFilename() const
  38. {
  39. return (m_mesh.isCreated()) ? m_mesh->getFilename() : CString();
  40. }
  41. void BodyComponent::setMass(F32 mass)
  42. {
  43. if(mass < 0.0f)
  44. {
  45. ANKI_SCENE_LOGW("Attempting to set a negative mass");
  46. mass = 0.0f;
  47. }
  48. if(m_body.isCreated())
  49. {
  50. if((m_body->getMass() == 0.0f && mass != 0.0f) || (m_body->getMass() != 0.0f && mass == 0.0f))
  51. {
  52. // Will become from static to dynamic or the opposite, re-create the body
  53. const Transform prevTransform = getWorldTransform();
  54. PhysicsBodyInitInfo init;
  55. init.m_transform = prevTransform;
  56. init.m_mass = mass;
  57. init.m_shape = m_mesh->getCollisionShape();
  58. m_body = m_node->getSceneGraph().getPhysicsWorld().newInstance<PhysicsBody>(init);
  59. m_body->setUserData(this);
  60. m_markedForUpdate = true;
  61. }
  62. else
  63. {
  64. m_body->setMass(mass);
  65. }
  66. }
  67. else
  68. {
  69. ANKI_SCENE_LOGW("BodyComponent is not initialized. Ignoring setting of mass");
  70. }
  71. }
  72. Error BodyComponent::update(SceneNode& node, Second, Second, Bool& updated)
  73. {
  74. updated = m_markedForUpdate;
  75. m_markedForUpdate = false;
  76. if(m_body && m_body->getTransform() != m_trf)
  77. {
  78. updated = true;
  79. m_trf = m_body->getTransform();
  80. }
  81. return Error::NONE;
  82. }
  83. } // end namespace anki