SkeletalLODTests.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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 <Tests/ActorFixture.h>
  9. #include <EMotionFX/Source/Actor.h>
  10. #include <EMotionFX/Source/ActorInstance.h>
  11. #include <EMotionFX/Source/Node.h>
  12. #include <EMotionFX/Source/Skeleton.h>
  13. namespace EMotionFX
  14. {
  15. class SkeletalLODFixture
  16. : public ActorFixture
  17. {
  18. public:
  19. void SetUp()
  20. {
  21. ActorFixture::SetUp();
  22. GetActor()->AddLODLevel();
  23. DisableJointsForLOD(m_disabledJointNames, 1);
  24. }
  25. void DisableJointsForLOD(const std::vector<std::string>& jointNames, size_t lodLevel)
  26. {
  27. const Skeleton* skeleton = GetActor()->GetSkeleton();
  28. for (const std::string& jointName : jointNames)
  29. {
  30. Node* joint = skeleton->FindNodeByName(jointName.c_str());
  31. ASSERT_NE(joint, nullptr);
  32. joint->SetSkeletalLODStatus(lodLevel, false);
  33. }
  34. }
  35. static void VerifySkeletalLODFlags(const ActorInstance* actorInstance, const std::vector<std::string>& disabledJointNames, size_t lodLevel)
  36. {
  37. EXPECT_EQ(actorInstance->GetLODLevel(), lodLevel)
  38. << "Please note that setting the LOD level is delayed and happend with the next UpdateTransforms().";
  39. const Actor* actor = actorInstance->GetActor();
  40. const Skeleton* skeleton = actor->GetSkeleton();
  41. const AZStd::vector<AZ::u16>& enabledJoints = actorInstance->GetEnabledNodes();
  42. const size_t numEnabledJoints = enabledJoints.size();
  43. EXPECT_EQ(actorInstance->GetNumEnabledNodes(), actor->GetNumNodes() - disabledJointNames.size())
  44. << "The enabled joints on the actor instance are not in sync with the enabledJoints.";
  45. const size_t numJoints = skeleton->GetNumNodes();
  46. for (size_t i = 0; i < numJoints; ++i)
  47. {
  48. const Node* joint = skeleton->GetNode(i);
  49. // Check the skeletal LOD flag on the joint (actor asset).
  50. const bool isJointEnabled = std::find(disabledJointNames.begin(), disabledJointNames.end(), joint->GetName()) == disabledJointNames.end();
  51. EXPECT_EQ(isJointEnabled, joint->GetSkeletalLODStatus(lodLevel))
  52. << "The skeletal LOD flag on the joint does not match the disabled joints set by the test.";
  53. // Check if the enabled joints on the actor instance is in sync.
  54. bool foundInEnabledJoints = false;
  55. for (size_t j = 0; j < numEnabledJoints; ++j)
  56. {
  57. const AZ::u16 enabledJointIndex = actorInstance->GetEnabledNode(j);
  58. const Node* enabledJoint = skeleton->GetNode(enabledJointIndex);
  59. if (joint == enabledJoint)
  60. {
  61. foundInEnabledJoints = true;
  62. break;
  63. }
  64. }
  65. EXPECT_EQ(isJointEnabled, foundInEnabledJoints)
  66. << "The joint is disabled (enabled) but has (not) been found in the enabled joints in the actor instance.";
  67. }
  68. }
  69. public:
  70. const std::vector<std::string> m_disabledJointNames = { "r_thumb1", "r_thumb2", "r_thumb3", "r_index1", "r_index2", "r_index3" };
  71. };
  72. TEST_F(SkeletalLODFixture, SkeletalLODTest)
  73. {
  74. // Check default LOD 0
  75. m_actorInstance->UpdateTransformations(0.0f);
  76. VerifySkeletalLODFlags(m_actorInstance, {}, 0);
  77. // Set to LOD 1
  78. m_actorInstance->SetLODLevel(1);
  79. m_actorInstance->UpdateTransformations(0.0f);
  80. VerifySkeletalLODFlags(m_actorInstance, m_disabledJointNames, 1);
  81. // Set back to LOD0
  82. m_actorInstance->SetLODLevel(0);
  83. m_actorInstance->UpdateTransformations(0.0f);
  84. VerifySkeletalLODFlags(m_actorInstance, {}, 0);
  85. }
  86. } // namespace EMotionFX