ActorHelper.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <ActorHelper.h>
  9. #include <AzCore/std/smart_ptr/make_shared.h>
  10. #include <AzCore/std/algorithm.h>
  11. #include <EMotionFX/Source/Mesh.h>
  12. #include <EMotionFX/Source/Node.h>
  13. #include <EMotionFX/Source/SkinningInfoVertexAttributeLayer.h>
  14. #include <EMotionFX/Source/SubMesh.h>
  15. #include <EMotionFX/Source/VertexAttributeLayerAbstractData.h>
  16. #include <Integration/Assets/ActorAsset.h>
  17. #include <Tests/TestAssetCode/MeshFactory.h>
  18. #include <NvCloth/ITangentSpaceHelper.h>
  19. namespace UnitTest
  20. {
  21. ActorHelper::ActorHelper(const char* name)
  22. : EMotionFX::Actor(name)
  23. {
  24. }
  25. size_t ActorHelper::AddJoint(
  26. const AZStd::string& name,
  27. const AZ::Transform& localTransform,
  28. const AZStd::string& parentName)
  29. {
  30. EMotionFX::Node* parentNode = GetSkeleton()->FindNodeByNameNoCase(parentName.c_str());
  31. auto node = AddNode(
  32. GetNumNodes(),
  33. name.c_str(),
  34. (parentNode) ? parentNode->GetNodeIndex() : InvalidIndex);
  35. GetBindPose()->SetLocalSpaceTransform(node->GetNodeIndex(), localTransform);
  36. return node->GetNodeIndex();
  37. }
  38. void ActorHelper::AddClothCollider(const Physics::CharacterColliderNodeConfiguration& colliderNode)
  39. {
  40. GetPhysicsSetup()->GetConfig().m_clothConfig.m_nodes.push_back(colliderNode);
  41. }
  42. void ActorHelper::FinishSetup()
  43. {
  44. SetID(0);
  45. GetSkeleton()->UpdateNodeIndexValues(0);
  46. ResizeTransformData();
  47. PostCreateInit();
  48. }
  49. AZ::Data::Asset<AZ::Data::AssetData> CreateAssetFromActor(
  50. AZStd::unique_ptr<EMotionFX::Actor> actor)
  51. {
  52. AZ::Data::AssetId assetId(AZ::Uuid::CreateRandom());
  53. AZ::Data::Asset<EMotionFX::Integration::ActorAsset> actorAsset = AZ::Data::AssetManager::Instance().CreateAsset<EMotionFX::Integration::ActorAsset>(assetId);
  54. actorAsset.GetAs<EMotionFX::Integration::ActorAsset>()->SetData(AZStd::move(actor));
  55. return actorAsset;
  56. }
  57. Physics::CharacterColliderNodeConfiguration CreateSphereCollider(
  58. const AZStd::string& jointName,
  59. float radius,
  60. const AZ::Transform& offset)
  61. {
  62. auto colliderConf = AZStd::make_shared<Physics::ColliderConfiguration>();
  63. colliderConf->m_position = offset.GetTranslation();
  64. colliderConf->m_rotation = offset.GetRotation();
  65. auto shapeConf = AZStd::make_shared<Physics::SphereShapeConfiguration>(radius);
  66. Physics::CharacterColliderNodeConfiguration collider;
  67. collider.m_name = jointName;
  68. collider.m_shapes.emplace_back(colliderConf, shapeConf);
  69. return collider;
  70. }
  71. Physics::CharacterColliderNodeConfiguration CreateCapsuleCollider(
  72. const AZStd::string& jointName,
  73. float height, float radius,
  74. const AZ::Transform& offset)
  75. {
  76. auto colliderConf = AZStd::make_shared<Physics::ColliderConfiguration>();
  77. colliderConf->m_position = offset.GetTranslation();
  78. colliderConf->m_rotation = offset.GetRotation();
  79. auto shapeConf = AZStd::make_shared<Physics::CapsuleShapeConfiguration>(height, radius);
  80. Physics::CharacterColliderNodeConfiguration collider;
  81. collider.m_name = jointName;
  82. collider.m_shapes.emplace_back(colliderConf, shapeConf);
  83. return collider;
  84. }
  85. Physics::CharacterColliderNodeConfiguration CreateBoxCollider(
  86. const AZStd::string& jointName,
  87. const AZ::Vector3& dimensions,
  88. const AZ::Transform& offset)
  89. {
  90. auto colliderConf = AZStd::make_shared<Physics::ColliderConfiguration>();
  91. colliderConf->m_position = offset.GetTranslation();
  92. colliderConf->m_rotation = offset.GetRotation();
  93. auto shapeConf = AZStd::make_shared<Physics::BoxShapeConfiguration>(dimensions);
  94. Physics::CharacterColliderNodeConfiguration collider;
  95. collider.m_name = jointName;
  96. collider.m_shapes.emplace_back(colliderConf, shapeConf);
  97. return collider;
  98. }
  99. EMotionFX::Mesh* CreateEMotionFXMesh(
  100. const AZStd::vector<AZ::Vector3>& vertices,
  101. const AZStd::vector<AZ::u32>& indices,
  102. const AZStd::vector<VertexSkinInfluences>& skinningInfo,
  103. const AZStd::vector<AZ::Vector2>& uvs)
  104. {
  105. // Generate the normals for this mesh
  106. AZStd::vector<AZ::Vector4> particles(vertices.size());
  107. AZStd::transform(vertices.begin(), vertices.end(), particles.begin(), [](const AZ::Vector3& vertex) { return AZ::Vector4::CreateFromVector3(vertex); } );
  108. AZStd::vector<AZ::Vector3> normals;
  109. AZ::Interface<NvCloth::ITangentSpaceHelper>::Get()->CalculateNormals(
  110. particles, indices,
  111. normals);
  112. return EMotionFX::MeshFactory::Create(
  113. indices,
  114. vertices,
  115. normals,
  116. uvs,
  117. skinningInfo
  118. );
  119. }
  120. } // namespace UnitTest