WhiteBoxTestRailsAutomation.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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 "WhiteBoxTestFixtures.h"
  9. #include "WhiteBoxTestUtil.h"
  10. #include <AzToolsFramework/Entity/EditorEntityHelpers.h>
  11. namespace UnitTest
  12. {
  13. using TestRailsAutomationFixture = EditorWhiteBoxModifierTestFixture;
  14. constexpr bool LogActions = false;
  15. TEST_F(TestRailsAutomationFixture, C28798184_PressAndDragOnAPolygonTranslatesItAlongTheSurfaceNormal)
  16. {
  17. namespace Api = WhiteBox::Api;
  18. using ::testing::Pointwise;
  19. // the initial starting position of the entity (in front and to the left of the camera)
  20. const AZ::Transform initialEntityTransformWorld =
  21. AZ::Transform::CreateTranslation(AZ::Vector3(-10.0f, 10.0f, 0.0f));
  22. // world space delta we will be moving the polygon face
  23. const auto worldTranslationDelta = AZ::Vector3::CreateAxisX(20.0f);
  24. // the face handle we will use to get the parent polygon from
  25. const int faceHandle = 7;
  26. // move the entity to its starting position
  27. AzToolsFramework::SetWorldTransform(m_whiteBoxEntityId, initialEntityTransformWorld);
  28. // select the entity with the White Box Component
  29. AzToolsFramework::SelectEntity(m_whiteBoxEntityId);
  30. // mimic pressing the 'Edit' button on the Component Card
  31. EnterComponentMode<WhiteBox::EditorWhiteBoxComponent>();
  32. // grab the White Box Mesh (for use with the White Box Tool Api)
  33. WhiteBox::WhiteBoxMesh* whiteBox;
  34. WhiteBox::EditorWhiteBoxComponentRequestBus::EventResult(
  35. whiteBox, AZ::EntityComponentIdPair(m_whiteBoxEntityId, m_whiteBoxComponent->GetId()),
  36. &WhiteBox::EditorWhiteBoxComponentRequestBus::Events::GetWhiteBoxMesh);
  37. // the initial position of the white box mesh vertices
  38. const auto initialVertexLocalPositions = Api::MeshVertexPositions(*whiteBox);
  39. // the center position of the polygon modifier
  40. MultiSpacePoint initialModifierMidPoint(
  41. Api::PolygonMidpoint(*whiteBox, Api::FacePolygonHandle(*whiteBox, Api::FaceHandle(faceHandle))),
  42. initialEntityTransformWorld, m_cameraState);
  43. // where we expect the interaction to leave the modifier after the movement
  44. const auto finalScreenModifierMidPoint =
  45. AzFramework::WorldToScreen(initialModifierMidPoint.GetWorldSpace() + worldTranslationDelta, m_cameraState);
  46. // clone the initial vertex positions as our starting point for the expected positions
  47. AZStd::vector<AZ::Vector3> expectedFinalLocalFaceVertexPositions(initialVertexLocalPositions);
  48. // where we expect the polygon vertices to end up after the movement
  49. expectedFinalLocalFaceVertexPositions[1] += worldTranslationDelta;
  50. expectedFinalLocalFaceVertexPositions[2] += worldTranslationDelta;
  51. expectedFinalLocalFaceVertexPositions[5] += worldTranslationDelta;
  52. expectedFinalLocalFaceVertexPositions[6] += worldTranslationDelta;
  53. m_actionDispatcher->LogActions(LogActions)
  54. ->CameraState(m_cameraState)
  55. ->Trace(WhiteBox::VerticesToString(whiteBox, initialEntityTransformWorld).c_str())
  56. ->Trace("Moving mouse to polygon modifier midpoint")
  57. ->MousePosition(initialModifierMidPoint.GetScreenSpace())
  58. ->Trace("Dragging polygon to extrude")
  59. ->MouseLButtonDown()
  60. ->MousePosition(finalScreenModifierMidPoint)
  61. ->MouseLButtonUp()
  62. ->Trace(WhiteBox::VerticesToString(whiteBox, initialEntityTransformWorld).c_str());
  63. // grab the white box mesh vertices
  64. const auto finalVertexLocalPositions = Api::MeshVertexPositions(*whiteBox);
  65. // check that the number of vertices hasn't changed (no extrusions)
  66. EXPECT_EQ(finalVertexLocalPositions.size(), initialVertexLocalPositions.size());
  67. // check our expected modified vertices and the vertices after the modifier match
  68. EXPECT_THAT(
  69. finalVertexLocalPositions,
  70. Pointwise(ContainerIsCloseTolerance(0.01f), expectedFinalLocalFaceVertexPositions));
  71. }
  72. TEST_F(TestRailsAutomationFixture, C28798192_PressAndDragOutwardsFromAPolygonWithCtrlHeldWillExtrudeThePolygon)
  73. {
  74. namespace Api = WhiteBox::Api;
  75. using ::testing::Pointwise;
  76. // the initial starting position of the entity (in front and to the left of the camera)
  77. const AZ::Transform initialEntityTransformWorld =
  78. AZ::Transform::CreateTranslation(AZ::Vector3(-10.0f, 10.0f, 0.0f));
  79. // world space delta we will be moving the polygon face
  80. const auto worldTranslationDelta = AZ::Vector3::CreateAxisX(20.0f);
  81. // the face handle we will use to get the parent polygon from
  82. const int faceHandle = 7;
  83. // move the entity to its starting position
  84. AzToolsFramework::SetWorldTransform(m_whiteBoxEntityId, initialEntityTransformWorld);
  85. // select the entity with the White Box Component
  86. AzToolsFramework::SelectEntity(m_whiteBoxEntityId);
  87. // mimic pressing the 'Edit' button on the Component Card
  88. EnterComponentMode<WhiteBox::EditorWhiteBoxComponent>();
  89. // grab the White Box Mesh (for use with the White Box Tool Api)
  90. WhiteBox::WhiteBoxMesh* whiteBox;
  91. WhiteBox::EditorWhiteBoxComponentRequestBus::EventResult(
  92. whiteBox, AZ::EntityComponentIdPair(m_whiteBoxEntityId, m_whiteBoxComponent->GetId()),
  93. &WhiteBox::EditorWhiteBoxComponentRequestBus::Events::GetWhiteBoxMesh);
  94. // the initial position of the white box mesh vertices
  95. const auto initialVertexLocalPositions = Api::MeshVertexPositions(*whiteBox);
  96. // the center position of the polygon modifier
  97. MultiSpacePoint initialModifierMidPoint(
  98. Api::PolygonMidpoint(*whiteBox, Api::FacePolygonHandle(*whiteBox, Api::FaceHandle(faceHandle))),
  99. initialEntityTransformWorld, m_cameraState);
  100. // where we expect the interaction to leave the modifier after the movement
  101. const auto finalScreenModifierMidPoint =
  102. AzFramework::WorldToScreen(initialModifierMidPoint.GetWorldSpace() + worldTranslationDelta, m_cameraState);
  103. // clone the initial vertex positions as our starting point for the expected positions
  104. AZStd::vector<AZ::Vector3> expectedFinalLocalFaceVertexPositions(initialVertexLocalPositions);
  105. // where we expect the extra polygon vertices added by the extrusion to be after the movement
  106. expectedFinalLocalFaceVertexPositions.emplace_back(initialVertexLocalPositions[5] + worldTranslationDelta);
  107. expectedFinalLocalFaceVertexPositions.emplace_back(initialVertexLocalPositions[6] + worldTranslationDelta);
  108. expectedFinalLocalFaceVertexPositions.emplace_back(initialVertexLocalPositions[2] + worldTranslationDelta);
  109. expectedFinalLocalFaceVertexPositions.emplace_back(initialVertexLocalPositions[1] + worldTranslationDelta);
  110. m_actionDispatcher->LogActions(LogActions)
  111. ->CameraState(m_cameraState)
  112. ->Trace(WhiteBox::VerticesToString(whiteBox, initialEntityTransformWorld).c_str())
  113. ->Trace("Moving mouse to polygon modifier midpoint")
  114. ->MousePosition(initialModifierMidPoint.GetScreenSpace())
  115. ->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Ctrl)
  116. ->Trace("Dragging polygon to extrude")
  117. ->MouseLButtonDown()
  118. ->MousePosition(finalScreenModifierMidPoint)
  119. ->MouseLButtonUp()
  120. ->Trace(WhiteBox::VerticesToString(whiteBox, initialEntityTransformWorld).c_str());
  121. // grab the white box mesh vertices
  122. const auto finalVertexLocalPositions = Api::MeshVertexPositions(*whiteBox);
  123. // check that the number of vertices has changed (one extrusion)
  124. EXPECT_EQ(finalVertexLocalPositions.size(), initialVertexLocalPositions.size() + 4);
  125. // check our expected modified vertices and the vertices after the modifier match
  126. EXPECT_THAT(
  127. finalVertexLocalPositions,
  128. Pointwise(ContainerIsCloseTolerance(0.01f), expectedFinalLocalFaceVertexPositions));
  129. }
  130. TEST_F(
  131. TestRailsAutomationFixture, C28798192_PressAndDragOnAPolygonScaleModifierScalesTheVerticesAboutThePolygonCenter)
  132. {
  133. namespace Api = WhiteBox::Api;
  134. using ::testing::Pointwise;
  135. // the initial starting position of the entity (in front and to the left of the camera)
  136. const AZ::Transform initialEntityTransformWorld =
  137. AZ::Transform::CreateTranslation(AZ::Vector3(-10.0f, 10.0f, 0.0f));
  138. // the face handle we will use to get the parent polygon from
  139. const int faceHandle = 7;
  140. // the polygon vertex handle we will be dragging
  141. const int vertexHandle = 2;
  142. // lerp amount to derive mid point between polygon vertex and polygon mid point
  143. const float vertexLerp = 0.5f;
  144. // move the entity to its starting position
  145. AzToolsFramework::SetWorldTransform(m_whiteBoxEntityId, initialEntityTransformWorld);
  146. // select the entity with the White Box Component
  147. AzToolsFramework::SelectEntity(m_whiteBoxEntityId);
  148. // mimic pressing the 'Edit' button on the Component Card
  149. EnterComponentMode<WhiteBox::EditorWhiteBoxComponent>();
  150. // grab the White Box Mesh (for use with the White Box Tool Api)
  151. WhiteBox::WhiteBoxMesh* whiteBox;
  152. WhiteBox::EditorWhiteBoxComponentRequestBus::EventResult(
  153. whiteBox, AZ::EntityComponentIdPair(m_whiteBoxEntityId, m_whiteBoxComponent->GetId()),
  154. &WhiteBox::EditorWhiteBoxComponentRequestBus::Events::GetWhiteBoxMesh);
  155. // the initial position of the white box mesh vertices
  156. const auto initialVertexLocalPositions = Api::MeshVertexPositions(*whiteBox);
  157. // the center position of the polygon modifier
  158. MultiSpacePoint initialModifierMidPoint(
  159. Api::PolygonMidpoint(*whiteBox, Api::FacePolygonHandle(*whiteBox, Api::FaceHandle(faceHandle))),
  160. initialEntityTransformWorld, m_cameraState);
  161. // the position of the vertex handle of the polygon we will be resizing
  162. MultiSpacePoint initialModifierVertex(
  163. initialVertexLocalPositions[vertexHandle], initialEntityTransformWorld, m_cameraState);
  164. // mid point between polygon vertex and polygon modifier mid point
  165. MultiSpacePoint finalModifierVertex(
  166. initialModifierVertex.GetLocalSpace().Lerp(initialModifierMidPoint.GetLocalSpace(), vertexLerp),
  167. initialEntityTransformWorld, m_cameraState);
  168. // clone the initial vertex positions as our starting point for the expected positions
  169. AZStd::vector<AZ::Vector3> expectedFinalLocalFaceVertexPositions(initialVertexLocalPositions);
  170. // where we expect the polygon vertices to end up after the movement (moved half-way towards the face mid point)
  171. expectedFinalLocalFaceVertexPositions[1] =
  172. initialVertexLocalPositions[1].Lerp(initialModifierMidPoint.GetLocalSpace(), vertexLerp);
  173. expectedFinalLocalFaceVertexPositions[2] =
  174. initialVertexLocalPositions[2].Lerp(initialModifierMidPoint.GetLocalSpace(), vertexLerp);
  175. expectedFinalLocalFaceVertexPositions[5] =
  176. initialVertexLocalPositions[5].Lerp(initialModifierMidPoint.GetLocalSpace(), vertexLerp);
  177. expectedFinalLocalFaceVertexPositions[6] =
  178. initialVertexLocalPositions[6].Lerp(initialModifierMidPoint.GetLocalSpace(), vertexLerp);
  179. m_actionDispatcher->LogActions(LogActions)
  180. ->CameraState(m_cameraState)
  181. ->Trace(WhiteBox::VerticesToString(whiteBox, initialEntityTransformWorld).c_str())
  182. ->Trace("Moving mouse to polygon modifier midpoint")
  183. ->MousePosition(initialModifierMidPoint.GetScreenSpace())
  184. ->Trace("Selecting polygon")
  185. ->MouseLButtonDown()
  186. ->MouseLButtonUp()
  187. ->Trace("Moving mouse to polygon vertex % d", vertexHandle)
  188. ->MousePosition(initialModifierVertex.GetScreenSpace())
  189. ->Trace("Selecting polygon vertex % d", vertexHandle)
  190. ->MouseLButtonDown()
  191. ->Trace("Dragging vertex %d towards centroid of polygon", vertexHandle)
  192. ->MousePosition(finalModifierVertex.GetScreenSpace())
  193. ->MouseLButtonUp()
  194. ->Trace(WhiteBox::VerticesToString(whiteBox, initialEntityTransformWorld).c_str());
  195. // grab the white box mesh vertices
  196. const auto finalVertexLocalPositions = Api::MeshVertexPositions(*whiteBox);
  197. // check that the number of vertices has not changed
  198. EXPECT_EQ(finalVertexLocalPositions.size(), initialVertexLocalPositions.size());
  199. // check our expected modified vertices and the vertices after the modifier match
  200. EXPECT_THAT(
  201. finalVertexLocalPositions,
  202. Pointwise(ContainerIsCloseTolerance(0.01f), expectedFinalLocalFaceVertexPositions));
  203. }
  204. TEST_F(TestRailsAutomationFixture, C28798193_PressAndDragInwardsFromAPolygonWithCtrlHeldWillImpressThePolygon)
  205. {
  206. namespace Api = WhiteBox::Api;
  207. using ::testing::Pointwise;
  208. // the initial starting position of the entity (in front and to the left of the camera)
  209. const AZ::Transform initialEntityTransformWorld =
  210. AZ::Transform::CreateTranslation(AZ::Vector3(-10.0f, 10.0f, 0.0f));
  211. // world space delta we will be moving the polygon face
  212. const auto worldTranslationDelta = AZ::Vector3::CreateAxisX(20.0f);
  213. // the face handle we will use to get the parent polygon from
  214. const int faceHandle = 7;
  215. // the polygon vertex handle we will be dragging
  216. const int vertexHandle = 2;
  217. // lerp amount to derive mid point between polygon vertex and polygon mid point
  218. const float vertexLerp = 0.5f;
  219. // move the entity to its starting position
  220. AzToolsFramework::SetWorldTransform(m_whiteBoxEntityId, initialEntityTransformWorld);
  221. // select the entity with the White Box Component
  222. AzToolsFramework::SelectEntity(m_whiteBoxEntityId);
  223. // mimic pressing the 'Edit' button on the Component Card
  224. EnterComponentMode<WhiteBox::EditorWhiteBoxComponent>();
  225. // grab the White Box Mesh (for use with the White Box Tool Api)
  226. WhiteBox::WhiteBoxMesh* whiteBox;
  227. WhiteBox::EditorWhiteBoxComponentRequestBus::EventResult(
  228. whiteBox, AZ::EntityComponentIdPair(m_whiteBoxEntityId, m_whiteBoxComponent->GetId()),
  229. &WhiteBox::EditorWhiteBoxComponentRequestBus::Events::GetWhiteBoxMesh);
  230. // the initial position of the white box mesh vertices
  231. const auto initialVertexLocalPositions = Api::MeshVertexPositions(*whiteBox);
  232. // the center position of the polygon modifier
  233. MultiSpacePoint initialModifierMidPoint(
  234. Api::PolygonMidpoint(*whiteBox, Api::FacePolygonHandle(*whiteBox, Api::FaceHandle(faceHandle))),
  235. initialEntityTransformWorld, m_cameraState);
  236. // the position of the vertex handle of the polygon we will be resizing
  237. MultiSpacePoint initialModifierVertex(
  238. initialVertexLocalPositions[vertexHandle], initialEntityTransformWorld, m_cameraState);
  239. // mid point between polygon vertex and polygon modifier mid point
  240. MultiSpacePoint finalModifierVertex(
  241. initialModifierVertex.GetLocalSpace().Lerp(initialModifierMidPoint.GetLocalSpace(), vertexLerp),
  242. initialEntityTransformWorld, m_cameraState);
  243. // where we expect the interaction to leave the modifier after the movement
  244. const auto finalScreenModifierMidPoint =
  245. AzFramework::WorldToScreen(initialModifierMidPoint.GetWorldSpace() + worldTranslationDelta, m_cameraState);
  246. // clone the initial vertex positions as our starting point for the expected positions
  247. AZStd::vector<AZ::Vector3> expectedFinalLocalFaceVertexPositions(initialVertexLocalPositions);
  248. // where we expect the polygon vertices to end up after the movement (moved half-way towards the face mid point)
  249. expectedFinalLocalFaceVertexPositions[1] =
  250. initialVertexLocalPositions[1].Lerp(initialModifierMidPoint.GetLocalSpace(), vertexLerp);
  251. expectedFinalLocalFaceVertexPositions[2] =
  252. initialVertexLocalPositions[2].Lerp(initialModifierMidPoint.GetLocalSpace(), vertexLerp);
  253. expectedFinalLocalFaceVertexPositions[5] =
  254. initialVertexLocalPositions[5].Lerp(initialModifierMidPoint.GetLocalSpace(), vertexLerp);
  255. expectedFinalLocalFaceVertexPositions[6] =
  256. initialVertexLocalPositions[6].Lerp(initialModifierMidPoint.GetLocalSpace(), vertexLerp);
  257. // where we expect the extra polygon vertices added by the impression to be after the movement
  258. expectedFinalLocalFaceVertexPositions.emplace_back(
  259. expectedFinalLocalFaceVertexPositions[5] + worldTranslationDelta);
  260. expectedFinalLocalFaceVertexPositions.emplace_back(
  261. expectedFinalLocalFaceVertexPositions[6] + worldTranslationDelta);
  262. expectedFinalLocalFaceVertexPositions.emplace_back(
  263. expectedFinalLocalFaceVertexPositions[2] + worldTranslationDelta);
  264. expectedFinalLocalFaceVertexPositions.emplace_back(
  265. expectedFinalLocalFaceVertexPositions[1] + worldTranslationDelta);
  266. m_actionDispatcher->LogActions(LogActions)
  267. ->CameraState(m_cameraState)
  268. ->Trace(WhiteBox::VerticesToString(whiteBox, initialEntityTransformWorld).c_str())
  269. ->Trace("Moving mouse to polygon modifier midpoint")
  270. ->MousePosition(initialModifierMidPoint.GetScreenSpace())
  271. ->Trace("Selecting polygon")
  272. ->MouseLButtonDown()
  273. ->MouseLButtonUp()
  274. ->Trace("Moving mouse to polygon vertex % d", vertexHandle)
  275. ->MousePosition(initialModifierVertex.GetScreenSpace())
  276. ->Trace("Selecting polygon vertex % d", vertexHandle)
  277. ->MouseLButtonDown()
  278. ->Trace("Dragging vertex %d towards centroid of polygon", vertexHandle)
  279. ->MousePosition(finalModifierVertex.GetScreenSpace())
  280. ->MouseLButtonUp()
  281. ->Trace(WhiteBox::VerticesToString(whiteBox, initialEntityTransformWorld).c_str())
  282. ->Trace("Moving mouse to centroid of polygon")
  283. ->MousePosition(initialModifierMidPoint.GetScreenSpace())
  284. ->Trace("Impressing polygon and extruding")
  285. ->KeyboardModifierDown(AzToolsFramework::ViewportInteraction::KeyboardModifier::Ctrl)
  286. ->MouseLButtonDown()
  287. ->MousePosition(finalScreenModifierMidPoint)
  288. ->MouseLButtonUp()
  289. ->Trace(WhiteBox::VerticesToString(whiteBox, initialEntityTransformWorld).c_str());
  290. // grab the white box mesh vertices
  291. const auto finalVertexLocalPositions = Api::MeshVertexPositions(*whiteBox);
  292. // check that the number of vertices has changed (one impression)
  293. EXPECT_EQ(finalVertexLocalPositions.size(), initialVertexLocalPositions.size() + 4);
  294. // check our expected modified vertices and the vertices after the modifier match
  295. EXPECT_THAT(
  296. finalVertexLocalPositions,
  297. Pointwise(ContainerIsCloseTolerance(0.01f), expectedFinalLocalFaceVertexPositions));
  298. }
  299. } // namespace UnitTest