ColliderScalingTests.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  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 <AZTestShared/Math/MathTestHelpers.h>
  9. #include <AzToolsFramework/ToolsComponents/EditorNonUniformScaleComponent.h>
  10. #include <BaseColliderComponent.h>
  11. #include <BoxColliderComponent.h>
  12. #include <CapsuleColliderComponent.h>
  13. #include <EditorColliderComponent.h>
  14. #include <EditorRigidBodyComponent.h>
  15. #include <EditorStaticRigidBodyComponent.h>
  16. #include <EditorTestUtilities.h>
  17. #include <RigidBodyComponent.h>
  18. #include <RigidBodyStatic.h>
  19. #include <SphereColliderComponent.h>
  20. #include <StaticRigidBodyComponent.h>
  21. namespace PhysXEditorTests
  22. {
  23. void ExpectSingleConvexRuntimeConfig(AZ::Entity* gameEntity)
  24. {
  25. PhysX::BaseColliderComponent* colliderComponent = gameEntity->FindComponent<PhysX::BaseColliderComponent>();
  26. ASSERT_TRUE(colliderComponent != nullptr);
  27. AzPhysics::ShapeColliderPairList shapeConfigList = colliderComponent->GetShapeConfigurations();
  28. EXPECT_EQ(shapeConfigList.size(), 1);
  29. for (const auto& shapeConfigPair : shapeConfigList)
  30. {
  31. EXPECT_EQ(shapeConfigPair.second->GetShapeType(), Physics::ShapeType::CookedMesh);
  32. }
  33. }
  34. TEST_F(PhysXEditorFixture, BoxCollider_NonUniformScaleComponent_RuntimeShapeConfigReplacedWithConvex)
  35. {
  36. const AZ::Vector3 nonUniformScale(2.0f, 2.5f, 0.5f);
  37. EntityPtr editorEntity = CreateBoxPrimitiveColliderEditorEntity(
  38. Physics::ShapeConstants::DefaultBoxDimensions,
  39. AZ::Transform::CreateIdentity(),
  40. AZ::Vector3::CreateZero(),
  41. AZ::Quaternion::CreateIdentity(),
  42. nonUniformScale);
  43. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  44. // because there is a non-uniform scale component, the runtime entity should have a BaseColliderComponent with a
  45. // cooked mesh shape configuration, rather than a BoxColliderComponent
  46. EXPECT_TRUE(gameEntity->FindComponent<PhysX::BoxColliderComponent>() == nullptr);
  47. ExpectSingleConvexRuntimeConfig(gameEntity.get());
  48. }
  49. TEST_F(PhysXEditorFixture, BoxCollider_NonUniformScale_RuntimePhysicsAabbCorrect)
  50. {
  51. const AZ::Vector3 boxDimensions(0.5f, 0.7f, 0.9f);
  52. const AZ::Transform transform(AZ::Vector3(5.0f, 6.0f, 7.0f), AZ::Quaternion::CreateRotationX(AZ::DegToRad(30.0f)), 1.5f);
  53. const AZ::Vector3 translationOffset(1.0f, 2.0f, 3.0f);
  54. const AZ::Quaternion rotationOffset = AZ::Quaternion::CreateRotationZ(AZ::DegToRad(45.0f));
  55. const AZ::Vector3 nonUniformScale(0.7f, 0.9f, 1.1f);
  56. EntityPtr editorEntity = CreateBoxPrimitiveColliderEditorEntity(boxDimensions, transform, translationOffset, rotationOffset, nonUniformScale);
  57. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  58. // since there was no editor rigid body component, the runtime entity should have a static rigid body
  59. const auto* staticBody = azdynamic_cast<PhysX::StaticRigidBody*>(gameEntity->FindComponent<PhysX::StaticRigidBodyComponent>()->GetSimulatedBody());
  60. const AZ::Aabb aabb = staticBody->GetAabb();
  61. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(5.6045f, 4.9960f, 11.7074f), 1e-3f));
  62. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(6.4955f, 6.7305f, 13.5662f), 1e-3f));
  63. }
  64. TEST_F(PhysXEditorFixture, BoxCollider_WithDynamicRigidBody_NonUniformScale_RuntimePhysicsAabbCorrect)
  65. {
  66. const AZ::Vector3 boxDimensions(0.5f, 0.7f, 0.9f);
  67. const AZ::Transform transform(AZ::Vector3(5.0f, 6.0f, 7.0f), AZ::Quaternion::CreateRotationX(AZ::DegToRad(30.0f)), 1.5f);
  68. const AZ::Vector3 translationOffset(1.0f, 2.0f, 3.0f);
  69. const AZ::Quaternion rotationOffset = AZ::Quaternion::CreateRotationZ(AZ::DegToRad(45.0f));
  70. const AZ::Vector3 nonUniformScale(0.7f, 0.9f, 1.1f);
  71. EntityPtr editorEntity = CreateBoxPrimitiveColliderEditorEntity(
  72. boxDimensions, transform, translationOffset, rotationOffset, nonUniformScale, RigidBodyType::Dynamic);
  73. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  74. // since there was an editor rigid body component, the runtime entity should have a dynamic rigid body
  75. const auto* dynamicBody = gameEntity->FindComponent<PhysX::RigidBodyComponent>()->GetRigidBody();
  76. const AZ::Aabb aabb = dynamicBody->GetAabb();
  77. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(5.6045f, 4.9960f, 11.7074f), 1e-3f));
  78. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(6.4955f, 6.7305f, 13.5662f), 1e-3f));
  79. }
  80. TEST_F(PhysXEditorFixture, CapsuleCollider_NonUniformScaleComponent_RuntimeShapeConfigReplacedWithConvex)
  81. {
  82. const AZ::Vector3 nonUniformScale(1.0f, 1.5f, 1.0f);
  83. EntityPtr editorEntity = CreateCapsulePrimitiveColliderEditorEntity(
  84. Physics::ShapeConstants::DefaultCapsuleRadius,
  85. Physics::ShapeConstants::DefaultCapsuleHeight,
  86. AZ::Transform::CreateIdentity(),
  87. AZ::Vector3::CreateZero(),
  88. AZ::Quaternion::CreateIdentity(),
  89. nonUniformScale);
  90. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  91. // because there is a non-uniform scale component, the runtime entity should have a BaseColliderComponent with a
  92. // cooked mesh shape configuration, rather than a CapsuleColliderComponent
  93. EXPECT_TRUE(gameEntity->FindComponent<PhysX::CapsuleColliderComponent>() == nullptr);
  94. ExpectSingleConvexRuntimeConfig(gameEntity.get());
  95. }
  96. TEST_F(PhysXEditorFixture, CapsuleCollider_NonUniformScale_RuntimePhysicsAabbCorrect)
  97. {
  98. const float capsuleRadius = 0.3f;
  99. const float capsuleHeight = 1.4f;
  100. const AZ::Transform transform(AZ::Vector3(3.0f, 1.0f, -4.0f), AZ::Quaternion::CreateRotationY(AZ::DegToRad(90.0f)), 0.5f);
  101. const AZ::Vector3 translationOffset(2.0f, 5.0f, 3.0f);
  102. const AZ::Quaternion rotationOffset = AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f));
  103. const AZ::Vector3 nonUniformScale(1.2f, 0.7f, 0.6f);
  104. EntityPtr editorEntity = CreateCapsulePrimitiveColliderEditorEntity(
  105. capsuleRadius, capsuleHeight, transform, translationOffset, rotationOffset, nonUniformScale);
  106. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  107. // since there was no editor rigid body component, the runtime entity should have a static rigid body
  108. const auto* staticBody = azdynamic_cast<PhysX::StaticRigidBody*>(gameEntity->FindComponent<PhysX::StaticRigidBodyComponent>()->GetSimulatedBody());
  109. const AZ::Aabb aabb = staticBody->GetAabb();
  110. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(3.81f, 2.505f, -5.38f), 1e-3f));
  111. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(3.99f, 2.995f, -5.02f), 1e-3f));
  112. }
  113. TEST_F(PhysXEditorFixture, CapsuleCollider_WithDynamicRigidBody_NonUniformScale_RuntimePhysicsAabbCorrect)
  114. {
  115. const float capsuleRadius = 0.3f;
  116. const float capsuleHeight = 1.4f;
  117. const AZ::Transform transform(AZ::Vector3(3.0f, 1.0f, -4.0f), AZ::Quaternion::CreateRotationY(AZ::DegToRad(90.0f)), 0.5f);
  118. const AZ::Vector3 translationOffset(2.0f, 5.0f, 3.0f);
  119. const AZ::Quaternion rotationOffset = AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f));
  120. const AZ::Vector3 nonUniformScale(1.2f, 0.7f, 0.6f);
  121. EntityPtr editorEntity = CreateCapsulePrimitiveColliderEditorEntity(
  122. capsuleRadius, capsuleHeight, transform, translationOffset, rotationOffset, nonUniformScale, RigidBodyType::Dynamic);
  123. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  124. // since there was an editor rigid body component, the runtime entity should have a dynamic rigid body
  125. const auto* dynamicBody = gameEntity->FindComponent<PhysX::RigidBodyComponent>()->GetRigidBody();
  126. const AZ::Aabb aabb = dynamicBody->GetAabb();
  127. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(3.81f, 2.505f, -5.38f), 1e-3f));
  128. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(3.99f, 2.995f, -5.02f), 1e-3f));
  129. }
  130. TEST_F(PhysXEditorFixture, SphereCollider_NonUniformScaleComponent_RuntimeShapeConfigReplacedWithConvex)
  131. {
  132. const AZ::Vector3 nonUniformScale(1.0f, 1.5f, 1.0f);
  133. EntityPtr editorEntity = CreateSpherePrimitiveColliderEditorEntity(
  134. Physics::ShapeConstants::DefaultSphereRadius,
  135. AZ::Transform::CreateIdentity(),
  136. AZ::Vector3::CreateZero(),
  137. AZ::Quaternion::CreateIdentity(),
  138. nonUniformScale);
  139. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  140. // because there is a non-uniform scale component, the runtime entity should have a BaseColliderComponent with a
  141. // cooked mesh shape configuration, rather than a CapsuleColliderComponent
  142. EXPECT_TRUE(gameEntity->FindComponent<PhysX::SphereColliderComponent>() == nullptr);
  143. ExpectSingleConvexRuntimeConfig(gameEntity.get());
  144. }
  145. TEST_F(PhysXEditorFixture, SphereCollider_NonUniformScale_RuntimePhysicsAabbCorrect)
  146. {
  147. const float sphereRadius = 0.7f;
  148. const AZ::Transform transform(AZ::Vector3(-2.0f, -1.0f, 3.0f), AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f)), 1.2f);
  149. const AZ::Vector3 translationOffset(3.0f, -2.0f, 2.0f);
  150. const AZ::Quaternion rotationOffset = AZ::Quaternion::CreateRotationY(AZ::DegToRad(90.0f));
  151. const AZ::Vector3 nonUniformScale(0.8f, 0.9f, 0.6f);
  152. EntityPtr editorEntity =
  153. CreateSpherePrimitiveColliderEditorEntity(sphereRadius, transform, translationOffset, rotationOffset, nonUniformScale);
  154. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  155. // since there was no editor rigid body component, the runtime entity should have a static rigid body
  156. const auto* staticBody = azdynamic_cast<PhysX::StaticRigidBody*>(gameEntity->FindComponent<PhysX::StaticRigidBodyComponent>()->GetSimulatedBody());
  157. const AZ::Aabb aabb = staticBody->GetAabb();
  158. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(0.208f, -2.944f, 0.084f), 1e-3f));
  159. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(1.552f, -1.936f, 1.596f), 1e-3f));
  160. }
  161. TEST_F(PhysXEditorFixture, SphereCollider_WithDynamicRigidBody_NonUniformScale_RuntimePhysicsAabbCorrect)
  162. {
  163. const float sphereRadius = 0.7f;
  164. const AZ::Transform transform(AZ::Vector3(-2.0f, -1.0f, 3.0f), AZ::Quaternion::CreateRotationX(AZ::DegToRad(90.0f)), 1.2f);
  165. const AZ::Vector3 translationOffset(3.0f, -2.0f, 2.0f);
  166. const AZ::Quaternion rotationOffset = AZ::Quaternion::CreateRotationY(AZ::DegToRad(90.0f));
  167. const AZ::Vector3 nonUniformScale(0.8f, 0.9f, 0.6f);
  168. EntityPtr editorEntity = CreateSpherePrimitiveColliderEditorEntity(
  169. sphereRadius, transform, translationOffset, rotationOffset, nonUniformScale, RigidBodyType::Dynamic);
  170. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  171. // since there was an editor rigid body component, the runtime entity should have a dynamic rigid body
  172. const auto* dynamicBody = gameEntity->FindComponent<PhysX::RigidBodyComponent>()->GetRigidBody();
  173. const AZ::Aabb aabb = dynamicBody->GetAabb();
  174. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(0.208f, -2.944f, 0.084f), 1e-3f));
  175. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(1.552f, -1.936f, 1.596f), 1e-3f));
  176. }
  177. TEST_F(PhysXEditorFixture, CylinderCollider_RuntimeShapeConfigUsingConvex)
  178. {
  179. EntityPtr editorEntity = CreateCylinderPrimitiveColliderEditorEntity(
  180. Physics::ShapeConstants::DefaultCylinderRadius,
  181. Physics::ShapeConstants::DefaultCylinderHeight);
  182. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  183. // Since there is no cylinder shape in PhysX, the runtime entity should have a BaseColliderComponent with a
  184. // cooked mesh shape configuration.
  185. ExpectSingleConvexRuntimeConfig(gameEntity.get());
  186. }
  187. TEST_F(PhysXEditorFixture, CylinderCollider_NonUniformScaleComponent_RuntimeShapeConfigUsingConvex)
  188. {
  189. const AZ::Vector3 nonUniformScale(1.0f, 1.5f, 1.0f);
  190. EntityPtr editorEntity = CreateCylinderPrimitiveColliderEditorEntity(
  191. Physics::ShapeConstants::DefaultCylinderRadius,
  192. Physics::ShapeConstants::DefaultCylinderHeight,
  193. AZ::Transform::CreateIdentity(),
  194. AZ::Vector3::CreateZero(),
  195. AZ::Quaternion::CreateIdentity(),
  196. nonUniformScale);
  197. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  198. // Since there is no cylinder shape in PhysX, the runtime entity should have a BaseColliderComponent with a
  199. // cooked mesh shape configuration.
  200. ExpectSingleConvexRuntimeConfig(gameEntity.get());
  201. }
  202. TEST_F(PhysXEditorFixture, EditorColliderComponent_CylinderWithOffset_CorrectEditorStaticBodyGeometry)
  203. {
  204. const float radius = 1.5f;
  205. const float height = 7.5f;
  206. const AZ::Transform transform(AZ::Vector3(3.0f, 3.0f, 5.0f), AZ::Quaternion(0.5f, -0.5f, -0.5f, 0.5f), 1.5f);
  207. const AZ::Vector3 positionOffset(0.5f, 1.5f, -2.5f);
  208. const AZ::Quaternion rotationOffset(0.3f, -0.1f, -0.3f, 0.9f);
  209. EntityPtr editorEntity = CreateCylinderPrimitiveColliderEditorEntity(radius, height, transform, positionOffset, rotationOffset);
  210. const AZ::Aabb aabb = GetSimulatedBodyAabb(editorEntity->GetId());
  211. // use a relatively large tolerance, because the cylinder will be a convex approximation rather than an exact primitive
  212. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(0.9f, -1.9f, 2.6f), 0.1f));
  213. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(12.6f, 6.4f, 11.9f), 0.1f));
  214. }
  215. TEST_F(PhysXEditorFixture, EditorColliderComponent_CylinderWithOffset_CorrectEditorDynamicBodyGeometry)
  216. {
  217. const float radius = 3.0f;
  218. const float height = 11.0f;
  219. const AZ::Transform transform(AZ::Vector3(5.0f, 6.0f, 7.0f), AZ::Quaternion(0.1f, 0.5f, -0.7f, 0.5f), 1.0f);
  220. const AZ::Vector3 positionOffset(-6.0f, -4.0f, -2.0f);
  221. const AZ::Quaternion rotationOffset(0.4f, 0.8f, 0.2f, 0.4f);
  222. EntityPtr editorEntity = CreateCylinderPrimitiveColliderEditorEntity(
  223. radius, height, transform, positionOffset, rotationOffset, AZStd::nullopt, RigidBodyType::Dynamic);
  224. const AZ::Aabb aabb = GetSimulatedBodyAabb(editorEntity->GetId());
  225. // use a relatively large tolerance, because the cylinder will be a convex approximation rather than an exact primitive
  226. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(-1.7f, 8.2f, 6.1f), 0.1f));
  227. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(9.6f, 14.2f, 18.5f), 0.1f));
  228. }
  229. TEST_F(PhysXEditorFixture, EditorColliderComponent_CylinderWithOffset_CorrectRuntimeStaticBodyGeometry)
  230. {
  231. const float radius = 0.5f;
  232. const float height = 4.0f;
  233. const AZ::Transform transform(AZ::Vector3(3.0f, 5.0f, -9.0f), AZ::Quaternion(0.7f, -0.1f, 0.1f, 0.7f), 0.5f);
  234. const AZ::Vector3 positionOffset(2.0f, 5.0f, 6.0f);
  235. const AZ::Quaternion rotationOffset(-0.9f, 0.1f, -0.3f, 0.3f);
  236. EntityPtr editorEntity = CreateCylinderPrimitiveColliderEditorEntity(radius, height, transform, positionOffset, rotationOffset);
  237. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  238. const AZ::Aabb aabb = GetSimulatedBodyAabb(gameEntity->GetId());
  239. // use a relatively large tolerance, because the cylinder will be a convex approximation rather than an exact primitive
  240. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(2.6f, 1.2f, -7.1f), 0.1f));
  241. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(3.9f, 2.8f, -5.5f), 0.1f));
  242. }
  243. TEST_F(PhysXEditorFixture, EditorColliderComponent_CylinderWithOffset_CorrectRuntimeDynamicBodyGeometry)
  244. {
  245. const float radius = 1.0f;
  246. const float height = 5.5f;
  247. const AZ::Transform transform(AZ::Vector3(-4.0f, -1.0f, 2.0f), AZ::Quaternion(0.4f, 0.4f, -0.2f, 0.8f), 1.0f);
  248. const AZ::Vector3 positionOffset(3.0f, 4.0f, 5.0f);
  249. const AZ::Quaternion rotationOffset(-0.5f, -0.5f, -0.5f, 0.5f);
  250. EntityPtr editorEntity = CreateCylinderPrimitiveColliderEditorEntity(
  251. radius, height, transform, positionOffset, rotationOffset, AZStd::nullopt, RigidBodyType::Dynamic);
  252. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  253. const AZ::Aabb aabb = GetSimulatedBodyAabb(gameEntity->GetId());
  254. // use a relatively large tolerance, because the cylinder will be a convex approximation rather than an exact primitive
  255. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(0.2f, -5.1f, 1.1f), 0.1f));
  256. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(5.3f, -0.2f, 5.5f), 0.1f));
  257. }
  258. TEST_F(PhysXEditorFixture, EditorColliderComponent_CylinderWithOffsetAndNonUniformScale_CorrectEditorStaticBodyGeometry)
  259. {
  260. const float radius = 0.5f;
  261. const float height = 4.0f;
  262. const AZ::Transform transform(AZ::Vector3(4.0f, -3.0f, -2.0f), AZ::Quaternion(0.3f, 0.9f, -0.3f, 0.1f), 2.0f);
  263. const AZ::Vector3 positionOffset(0.5f, 0.2f, 0.3f);
  264. const AZ::Quaternion rotationOffset(0.5f, -0.5f, -0.5f, 0.5f);
  265. const AZ::Vector3 nonUniformScale(0.5f, 2.0f, 2.0f);
  266. EntityPtr editorEntity =
  267. CreateCylinderPrimitiveColliderEditorEntity(radius, height, transform, positionOffset, rotationOffset, nonUniformScale);
  268. const AZ::Aabb aabb = GetSimulatedBodyAabb(editorEntity->GetId());
  269. // use a relatively large tolerance, because the cylinder will be a convex approximation rather than an exact primitive
  270. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(1.3f, -5.7f, -6.1f), 0.1f));
  271. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(6.9f, -0.3f, -1.0f), 0.1f));
  272. }
  273. TEST_F(PhysXEditorFixture, EditorColliderComponent_CylinderWithOffsetAndNonUniformScale_CorrectEditorDynamicBodyGeometry)
  274. {
  275. const float radius = 1.5f;
  276. const float height = 9.0f;
  277. const AZ::Transform transform(AZ::Vector3(2.0f, 5.0f, -3.0f), AZ::Quaternion(0.7f, -0.1f, 0.1f, 0.7f), 0.5f);
  278. const AZ::Vector3 positionOffset(-1.0f, -1.0f, 0.5f);
  279. const AZ::Quaternion rotationOffset(0.9f, -0.3f, -0.3f, 0.1f);
  280. const AZ::Vector3 nonUniformScale(1.5f, 1.0f, 0.5f);
  281. EntityPtr editorEntity = CreateCylinderPrimitiveColliderEditorEntity(
  282. radius, height, transform, positionOffset, rotationOffset, nonUniformScale, RigidBodyType::Dynamic);
  283. const AZ::Aabb aabb = GetSimulatedBodyAabb(editorEntity->GetId());
  284. // use a relatively large tolerance, because the cylinder will be a convex approximation rather than an exact primitive
  285. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(-1.4f, 3.8f, -5.0f), 0.1f));
  286. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(4.3f, 6.0f, -2.4f), 0.1f));
  287. }
  288. TEST_F(PhysXEditorFixture, EditorColliderComponent_CylinderWithOffsetAndNonUniformScale_CorrectRuntimeStaticBodyGeometry)
  289. {
  290. const float radius = 1.0f;
  291. const float height = 5.0f;
  292. const AZ::Transform transform(AZ::Vector3(5.0f, 4.0f, 2.0f), AZ::Quaternion(0.4f, 0.4f, -0.8f, 0.2f), 0.8f);
  293. const AZ::Vector3 positionOffset(2.0f, 1.0f, -2.0f);
  294. const AZ::Quaternion rotationOffset(0.7f, -0.1f, -0.5f, 0.5f);
  295. const AZ::Vector3 nonUniformScale(3.0f, 1.0f, 2.0f);
  296. EntityPtr editorEntity =
  297. CreateCylinderPrimitiveColliderEditorEntity(radius, height, transform, positionOffset, rotationOffset, nonUniformScale);
  298. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  299. const AZ::Aabb aabb = GetSimulatedBodyAabb(gameEntity->GetId());
  300. // use a relatively large tolerance, because the cylinder will be a convex approximation rather than an exact primitive
  301. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(0.6f, 4.0f, -8.8f), 0.1f));
  302. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(7.8f, 8.1f, 2.1f), 0.1f));
  303. }
  304. TEST_F(PhysXEditorFixture, EditorColliderComponent_CylinderWithOffsetAndNonUniformScale_CorrectRuntimeDynamicBodyGeometry)
  305. {
  306. const float radius = 2.0f;
  307. const float height = 7.0f;
  308. const AZ::Transform transform(AZ::Vector3(-2.0f, -3.0f, -6.0f), AZ::Quaternion(0.1f, 0.5f, -0.7f, 0.5f), 3.0f);
  309. const AZ::Vector3 positionOffset(-1.0, 0.5f, -2.0f);
  310. const AZ::Quaternion rotationOffset(0.2f, -0.4f, 0.8f, 0.4f);
  311. const AZ::Vector3 nonUniformScale(2.0f, 2.0f, 5.0f);
  312. EntityPtr editorEntity = CreateCylinderPrimitiveColliderEditorEntity(
  313. radius, height, transform, positionOffset, rotationOffset, nonUniformScale, RigidBodyType::Dynamic);
  314. EntityPtr gameEntity = CreateActiveGameEntityFromEditorEntity(editorEntity.get());
  315. const AZ::Aabb aabb = GetSimulatedBodyAabb(gameEntity->GetId());
  316. // use a relatively large tolerance, because the cylinder will be a convex approximation rather than an exact primitive
  317. EXPECT_THAT(aabb.GetMin(), UnitTest::IsCloseTolerance(AZ::Vector3(-25.0f, -20.8f, -53.9f), 0.1f));
  318. EXPECT_THAT(aabb.GetMax(), UnitTest::IsCloseTolerance(AZ::Vector3(10.0f, 70.0f, 17.2f), 0.1f));
  319. }
  320. } // namespace PhysXEditorTests