BodyComponent.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // Copyright (C) 2009-2022, 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/Components/ModelComponent.h>
  7. #include <AnKi/Scene/SceneNode.h>
  8. #include <AnKi/Scene/SceneGraph.h>
  9. #include <AnKi/Resource/CpuMeshResource.h>
  10. #include <AnKi/Resource/ResourceManager.h>
  11. #include <AnKi/Physics/PhysicsWorld.h>
  12. #include <AnKi/Resource/ModelResource.h>
  13. namespace anki {
  14. BodyComponent::BodyComponent(SceneNode* node)
  15. : SceneComponent(node, getStaticClassId())
  16. , m_node(node)
  17. {
  18. node->setIgnoreParentTransform(true);
  19. }
  20. BodyComponent::~BodyComponent()
  21. {
  22. }
  23. void BodyComponent::loadMeshResource(CString meshFilename)
  24. {
  25. CpuMeshResourcePtr rsrc;
  26. const Error err = getExternalSubsystems(*m_node).m_resourceManager->loadResource(meshFilename, rsrc);
  27. if(err)
  28. {
  29. ANKI_SCENE_LOGE("Failed to load mesh");
  30. return;
  31. }
  32. m_mesh = std::move(rsrc);
  33. const Transform prevTransform = m_node->getWorldTransform();
  34. const F32 prevMass = (m_body) ? m_body->getMass() : 0.0f;
  35. PhysicsBodyInitInfo init;
  36. init.m_mass = prevMass;
  37. init.m_transform = prevTransform;
  38. init.m_shape = m_mesh->getCollisionShape();
  39. m_body = getExternalSubsystems(*m_node).m_physicsWorld->newInstance<PhysicsBody>(init);
  40. m_body->setUserData(this);
  41. m_body->setTransform(m_node->getWorldTransform());
  42. m_dirty = true;
  43. }
  44. void BodyComponent::setMeshFromModelComponent(U32 patchIndex)
  45. {
  46. if(!ANKI_SCENE_ASSERT(m_modelc))
  47. {
  48. return;
  49. }
  50. if(!ANKI_SCENE_ASSERT(patchIndex < m_modelc->getModelResource()->getModelPatches().getSize()))
  51. {
  52. return;
  53. }
  54. loadMeshResource(m_modelc->getModelResource()->getModelPatches()[patchIndex].getMesh()->getFilename());
  55. }
  56. CString BodyComponent::getMeshResourceFilename() const
  57. {
  58. return (m_mesh.isCreated()) ? m_mesh->getFilename() : CString();
  59. }
  60. void BodyComponent::setMass(F32 mass)
  61. {
  62. if(!ANKI_SCENE_ASSERT(mass >= 0.0f && m_body.isCreated()))
  63. {
  64. return;
  65. }
  66. if((m_body->getMass() == 0.0f && mass != 0.0f) || (m_body->getMass() != 0.0f && mass == 0.0f))
  67. {
  68. // Will become from static to dynamic or the opposite, re-create the body
  69. const Transform& prevTransform = m_body->getTransform();
  70. PhysicsBodyInitInfo init;
  71. init.m_transform = prevTransform;
  72. init.m_mass = mass;
  73. init.m_shape = m_mesh->getCollisionShape();
  74. m_body = getExternalSubsystems(*m_node).m_physicsWorld->newInstance<PhysicsBody>(init);
  75. m_body->setUserData(this);
  76. m_dirty = true;
  77. }
  78. else
  79. {
  80. m_body->setMass(mass);
  81. }
  82. }
  83. void BodyComponent::teleportTo(const Transform& trf)
  84. {
  85. if(ANKI_SCENE_ASSERT(m_body.isCreated()))
  86. {
  87. m_body->setTransform(trf);
  88. m_node->setLocalTransform(trf); // Set that just to be sure
  89. }
  90. }
  91. Error BodyComponent::update(SceneComponentUpdateInfo& info, Bool& updated)
  92. {
  93. updated = m_dirty;
  94. m_dirty = false;
  95. if(m_body && m_body->getTransform() != info.m_node->getWorldTransform())
  96. {
  97. updated = true;
  98. info.m_node->setLocalTransform(m_body->getTransform());
  99. }
  100. return Error::kNone;
  101. }
  102. void BodyComponent::onOtherComponentRemovedOrAdded(SceneComponent* other, Bool added)
  103. {
  104. if(other->getClassId() != ModelComponent::getStaticClassId())
  105. {
  106. return;
  107. }
  108. if(added && m_modelc == nullptr)
  109. {
  110. m_modelc = static_cast<ModelComponent*>(other);
  111. }
  112. else if(!added && m_modelc == other)
  113. {
  114. m_modelc = nullptr;
  115. }
  116. }
  117. } // end namespace anki