BodyComponent.cpp 2.4 KB

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