CoordinateSystemRule.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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 <AzCore/Serialization/EditContext.h>
  9. #include <AzCore/Serialization/SerializeContext.h>
  10. #include <AzCore/std/smart_ptr/make_shared.h>
  11. #include <AzCore/RTTI/ReflectContext.h>
  12. #include <AzCore/Memory/SystemAllocator.h>
  13. #include <SceneAPI/SceneCore/Containers/RuleContainer.h>
  14. #include <SceneAPI/SceneCore/Utilities/Reporting.h>
  15. #include <SceneAPI/SceneData/Rules/CoordinateSystemRule.h>
  16. namespace AZ::SceneAPI::SceneData
  17. {
  18. AZ_CLASS_ALLOCATOR_IMPL(CoordinateSystemRule, AZ::SystemAllocator)
  19. CoordinateSystemRule::CoordinateSystemRule()
  20. : m_targetCoordinateSystem(ZUpPositiveYForward)
  21. {
  22. }
  23. void CoordinateSystemRule::UpdateCoordinateSystemConverter()
  24. {
  25. if (m_useAdvancedData)
  26. {
  27. m_coordinateSystemConverter = {};
  28. }
  29. else
  30. {
  31. switch (m_targetCoordinateSystem)
  32. {
  33. case ZUpPositiveYForward:
  34. {
  35. // Source coordinate system, use identity for now, which will currently just assume LY's coordinate system.
  36. const AZ::Vector3 sourceBasisVectors[3] = { AZ::Vector3( 1.0f, 0.0f, 0.0f),
  37. AZ::Vector3( 0.0f, 1.0f, 0.0f),
  38. AZ::Vector3( 0.0f, 0.0f, 1.0f) };
  39. // The target coordinate system, with X and Y inverted (rotate 180 degrees over Z)
  40. const AZ::Vector3 targetBasisVectors[3] = { AZ::Vector3(-1.0f, 0.0f, 0.0f),
  41. AZ::Vector3( 0.0f,-1.0f, 0.0f),
  42. AZ::Vector3( 0.0f, 0.0f, 1.0f) };
  43. // X, Y and Z are all at the same indices inside the target coordinate system, compared to the source coordinate system.
  44. const AZ::u32 targetBasisIndices[3] = { 0, 1, 2 };
  45. m_coordinateSystemConverter = CoordinateSystemConverter::CreateFromBasisVectors(sourceBasisVectors, targetBasisVectors, targetBasisIndices);
  46. }
  47. break;
  48. case ZUpNegativeYForward:
  49. {
  50. // Source coordinate system, use identity for now, which will currently just assume LY's coordinate system.
  51. const AZ::Vector3 sourceBasisVectors[3] = { AZ::Vector3( 1.0f, 0.0f, 0.0f),
  52. AZ::Vector3( 0.0f, 1.0f, 0.0f),
  53. AZ::Vector3( 0.0f, 0.0f, 1.0f) };
  54. // The target coordinate system, which is the same as the source, so basically we won't do anything here.
  55. const AZ::Vector3 targetBasisVectors[3] = { AZ::Vector3( 1.0f, 0.0f, 0.0f),
  56. AZ::Vector3( 0.0f, 1.0f, 0.0f),
  57. AZ::Vector3( 0.0f, 0.0f, 1.0f) };
  58. // X, Y and Z are all at the same indices inside the target coordinate system, compared to the source coordinate system.
  59. const AZ::u32 targetBasisIndices[3] = { 0, 1, 2 };
  60. m_coordinateSystemConverter = CoordinateSystemConverter::CreateFromBasisVectors(sourceBasisVectors, targetBasisVectors, targetBasisIndices);
  61. }
  62. break;
  63. default:
  64. AZ_Assert(false, "Unsupported coordinate system conversion");
  65. };
  66. }
  67. }
  68. void CoordinateSystemRule::SetTargetCoordinateSystem(CoordinateSystem targetCoordinateSystem)
  69. {
  70. m_targetCoordinateSystem = targetCoordinateSystem;
  71. UpdateCoordinateSystemConverter();
  72. }
  73. CoordinateSystemRule::CoordinateSystem CoordinateSystemRule::GetTargetCoordinateSystem() const
  74. {
  75. return m_targetCoordinateSystem;
  76. }
  77. void CoordinateSystemRule::Reflect(AZ::ReflectContext* context)
  78. {
  79. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  80. if (!serializeContext)
  81. {
  82. return;
  83. }
  84. serializeContext->Class<CoordinateSystemRule, IRule>()->Version(2) // LYN-2442
  85. ->Field("targetCoordinateSystem", &CoordinateSystemRule::m_targetCoordinateSystem)
  86. ->Field("useAdvancedData", &CoordinateSystemRule::m_useAdvancedData)
  87. ->Field("originNodeName", &CoordinateSystemRule::m_originNodeName)
  88. ->Field("rotation", &CoordinateSystemRule::m_rotation)
  89. ->Field("translation", &CoordinateSystemRule::m_translation)
  90. ->Field("scale", &CoordinateSystemRule::m_scale);
  91. AZ::EditContext* editContext = serializeContext->GetEditContext();
  92. if (editContext)
  93. {
  94. editContext->Class<CoordinateSystemRule>("Coordinate system change",
  95. "Modify the target coordinate system, applying a transformation to all data (transforms and vertex data if it exists).")
  96. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  97. ->Attribute(AZ::Edit::Attributes::AutoExpand, true)
  98. ->Attribute(AZ::Edit::Attributes::NameLabelOverride, "")
  99. ->DataElement(AZ::Edit::UIHandlers::Default, &CoordinateSystemRule::m_useAdvancedData,
  100. "Use Advanced Settings",
  101. "Toggles on the advanced settings for transforming the mesh group.")
  102. ->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
  103. ->DataElement(AZ::Edit::UIHandlers::ComboBox, &CoordinateSystemRule::m_targetCoordinateSystem,
  104. "Facing direction",
  105. "Change the direction the actor/motion will face by applying a post transformation to the data.")
  106. ->EnumAttribute(CoordinateSystem::ZUpNegativeYForward, "Do nothing")
  107. ->EnumAttribute(CoordinateSystem::ZUpPositiveYForward, "Rotate 180 degrees around the up axis")
  108. ->Attribute(AZ::Edit::Attributes::Visibility, &CoordinateSystemRule::GetBasicVisibility)
  109. ->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues)
  110. ->DataElement("NodeListSelection", &CoordinateSystemRule::m_originNodeName,
  111. "Relative Origin Node",
  112. "Select a Node from the scene as the origin for this export.")
  113. ->Attribute("DisabledOption", "")
  114. ->Attribute("DefaultToDisabled", false)
  115. ->Attribute("ExcludeEndPoints", true)
  116. ->Attribute(AZ::Edit::Attributes::Visibility, &CoordinateSystemRule::GetAdvancedVisibility)
  117. ->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::EntireTree)
  118. ->DataElement(AZ::Edit::UIHandlers::Default, &CoordinateSystemRule::m_translation,
  119. "Translation",
  120. "Moves the group along the given vector.")
  121. ->Attribute(AZ::Edit::Attributes::Visibility, &CoordinateSystemRule::GetAdvancedVisibility)
  122. ->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues)
  123. ->DataElement(AZ::Edit::UIHandlers::Default, &CoordinateSystemRule::m_rotation,
  124. "Rotation",
  125. "Sets the orientation offset of the processed mesh in degrees. Rotates the group after translation.")
  126. ->Attribute(Edit::Attributes::LabelForX, "P")
  127. ->Attribute(Edit::Attributes::LabelForY, "R")
  128. ->Attribute(Edit::Attributes::LabelForZ, "Y")
  129. ->Attribute(AZ::Edit::Attributes::Visibility, &CoordinateSystemRule::GetAdvancedVisibility)
  130. ->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues)
  131. ->DataElement(AZ::Edit::UIHandlers::Default, &CoordinateSystemRule::m_scale,
  132. "Scale",
  133. "Sets the scale offset of the processed mesh.")
  134. ->Attribute(Edit::Attributes::Min, 0.0001)
  135. ->Attribute(Edit::Attributes::Max, 1000.0)
  136. ->Attribute(AZ::Edit::Attributes::Visibility, &CoordinateSystemRule::GetAdvancedVisibility)
  137. ->Attribute(AZ::Edit::Attributes::ChangeNotify, AZ::Edit::PropertyRefreshLevels::AttributesAndValues);
  138. }
  139. }
  140. AZ::Crc32 CoordinateSystemRule::GetBasicVisibility() const
  141. {
  142. return (m_useAdvancedData) ? AZ::Edit::PropertyVisibility::Hide : AZ::Edit::PropertyVisibility::Show;
  143. }
  144. AZ::Crc32 CoordinateSystemRule::GetAdvancedVisibility() const
  145. {
  146. return (m_useAdvancedData) ? AZ::Edit::PropertyVisibility::Show : AZ::Edit::PropertyVisibility::Hide;
  147. }
  148. bool CoordinateSystemRule::ConvertLegacyCoordinateSystemRule(AZ::SerializeContext& serializeContext,
  149. AZ::SerializeContext::DataElementNode& classElement)
  150. {
  151. AZ::SerializeContext::DataElementNode* ruleContainerNode = classElement.FindSubElement(AZ_CRC_CE("rules"));
  152. if (!ruleContainerNode)
  153. {
  154. AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Can't find rule container.\n");
  155. return false;
  156. }
  157. AZ::SerializeContext::DataElementNode* rulesNode = ruleContainerNode->FindSubElement(AZ_CRC_CE("rules"));
  158. if (!rulesNode)
  159. {
  160. AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Can't find rules within rule container.\n");
  161. return false;
  162. }
  163. const AZ::Uuid oldCoordSysRuleId("{603207E2-4F55-4C33-9AAB-98CA75C1E351}");
  164. const int numRules = rulesNode->GetNumSubElements();
  165. for (int i = 0; i < numRules; ++i)
  166. {
  167. AZ::SerializeContext::DataElementNode& sharedPointerNode = rulesNode->GetSubElement(i);
  168. if (sharedPointerNode.GetNumSubElements() == 1)
  169. {
  170. AZ::SerializeContext::DataElementNode& currentRuleNode = sharedPointerNode.GetSubElement(0);
  171. // Convert the coordinate system rule
  172. if (currentRuleNode.GetId() == oldCoordSysRuleId)
  173. {
  174. int targetCoordinateSystem = 0;
  175. currentRuleNode.FindSubElementAndGetData(AZ_CRC_CE("targetCoordinateSystem"), targetCoordinateSystem);
  176. AZStd::shared_ptr<CoordinateSystemRule> coordSysRule = AZStd::make_shared<CoordinateSystemRule>();
  177. coordSysRule->SetTargetCoordinateSystem(static_cast<AZ::SceneAPI::DataTypes::ICoordinateSystemRule::CoordinateSystem>(targetCoordinateSystem));
  178. rulesNode->RemoveElement(i);
  179. rulesNode->AddElementWithData<AZStd::shared_ptr<AZ::SceneAPI::DataTypes::IRule>>(serializeContext, "element", coordSysRule);
  180. return true;
  181. }
  182. }
  183. }
  184. return true;
  185. }
  186. bool CoordinateSystemRule::GetUseAdvancedData() const
  187. {
  188. return m_useAdvancedData;
  189. }
  190. void CoordinateSystemRule::SetUseAdvancedData(bool useAdvancedData)
  191. {
  192. m_useAdvancedData = useAdvancedData;
  193. }
  194. const AZStd::string& CoordinateSystemRule::GetOriginNodeName() const
  195. {
  196. return m_originNodeName;
  197. }
  198. void CoordinateSystemRule::SetOriginNodeName(const AZStd::string& originNodeName)
  199. {
  200. m_originNodeName = originNodeName;
  201. }
  202. const Quaternion& CoordinateSystemRule::GetRotation() const
  203. {
  204. return m_rotation;
  205. }
  206. void CoordinateSystemRule::SetRotation(const Quaternion& rotation)
  207. {
  208. m_rotation = rotation;
  209. }
  210. const Vector3& CoordinateSystemRule::GetTranslation() const
  211. {
  212. return m_translation;
  213. }
  214. void CoordinateSystemRule::SetTranslation(const Vector3& translation)
  215. {
  216. m_translation = translation;
  217. }
  218. float CoordinateSystemRule::GetScale() const
  219. {
  220. return m_scale;
  221. }
  222. void CoordinateSystemRule::SetScale(float scale)
  223. {
  224. m_scale = scale;
  225. }
  226. } // namespace AZ::SceneAPI::SceneData