SceneSystem.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project. For complete copyright and license terms please see the LICENSE at the root of this distribution.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0 OR MIT
  5. *
  6. */
  7. #include <AzCore/Math/Vector3.h>
  8. #include <SceneAPI/SceneBuilder/SceneSystem.h>
  9. #include <SceneAPI/SceneCore/Utilities/Reporting.h>
  10. #include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
  11. #include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
  12. #include <assimp/scene.h>
  13. namespace AZ
  14. {
  15. namespace SceneAPI
  16. {
  17. SceneSystem::SceneSystem() :
  18. m_unitSizeInMeters(1.0f),
  19. m_originalUnitSizeInMeters(1.0f),
  20. m_adjustTransform(nullptr),
  21. m_adjustTransformInverse(nullptr)
  22. {
  23. }
  24. void SceneSystem::Set(const SDKScene::SceneWrapperBase* scene)
  25. {
  26. // Get unit conversion factor to meter.
  27. if (!azrtti_istypeof<AssImpSDKWrapper::AssImpSceneWrapper>(scene))
  28. {
  29. return;
  30. }
  31. const AssImpSDKWrapper::AssImpSceneWrapper* assImpScene = azrtti_cast<const AssImpSDKWrapper::AssImpSceneWrapper*>(scene);
  32. // If either meta data piece is not available, the default of 1 will be used.
  33. assImpScene->GetAssImpScene()->mMetaData->Get("UnitScaleFactor", m_unitSizeInMeters);
  34. assImpScene->GetAssImpScene()->mMetaData->Get("OriginalUnitScaleFactor", m_originalUnitSizeInMeters);
  35. /* Conversion factor for converting from centimeters to meters */
  36. m_unitSizeInMeters = m_unitSizeInMeters * .01f;
  37. AZStd::pair<AssImpSDKWrapper::AssImpSceneWrapper::AxisVector, int32_t> upAxisAndSign = assImpScene->GetUpVectorAndSign();
  38. if (upAxisAndSign.second <= 0)
  39. {
  40. AZ_TracePrintf(SceneAPI::Utilities::ErrorWindow, "Negative scene orientation is not a currently supported orientation.");
  41. return;
  42. }
  43. AZStd::pair<AssImpSDKWrapper::AssImpSceneWrapper::AxisVector, int32_t> frontAxisAndSign = assImpScene->GetFrontVectorAndSign();
  44. if (upAxisAndSign.first != AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Z &&
  45. upAxisAndSign.first != AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Unknown)
  46. {
  47. AZ::Matrix4x4 currentCoordMatrix = AZ::Matrix4x4::CreateIdentity();
  48. //(UpVector = +Z, FrontVector = +Y, CoordSystem = -X(RightHanded))
  49. AZ::Matrix4x4 targetCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
  50. AZ::Vector4(-1, 0, 0, 0),
  51. AZ::Vector4(0, 0, 1, 0),
  52. AZ::Vector4(0, 1, 0, 0),
  53. AZ::Vector4(0, 0, 0, 1));
  54. switch (upAxisAndSign.first)
  55. {
  56. case AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::X: {
  57. if (frontAxisAndSign.second == 1)
  58. {
  59. currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
  60. AZ::Vector4(0, -1, 0, 0),
  61. AZ::Vector4(1, 0, 0, 0),
  62. AZ::Vector4(0, 0, 1, 0),
  63. AZ::Vector4(0, 0, 0, 1));
  64. }
  65. else
  66. {
  67. currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
  68. AZ::Vector4(0, 1, 0, 0),
  69. AZ::Vector4(1, 0, 0, 0),
  70. AZ::Vector4(0, 0, -1, 0),
  71. AZ::Vector4(0, 0, 0, 1));
  72. }
  73. }
  74. break;
  75. case AssImpSDKWrapper::AssImpSceneWrapper::AxisVector::Y: {
  76. if (frontAxisAndSign.second == 1)
  77. {
  78. currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
  79. AZ::Vector4(1, 0, 0, 0),
  80. AZ::Vector4(0, 1, 0, 0),
  81. AZ::Vector4(0, 0, 1, 0),
  82. AZ::Vector4(0, 0, 0, 1));
  83. }
  84. else
  85. {
  86. currentCoordMatrix = AZ::Matrix4x4::CreateFromColumns(
  87. AZ::Vector4(-1, 0, 0, 0),
  88. AZ::Vector4(0, 1, 0, 0),
  89. AZ::Vector4(0, 0, -1, 0),
  90. AZ::Vector4(0, 0, 0, 1));
  91. }
  92. }
  93. break;
  94. }
  95. AZ::Matrix4x4 inverse = currentCoordMatrix.GetInverseTransform();
  96. AZ::Matrix4x4 adjustmatrix = targetCoordMatrix * currentCoordMatrix.GetInverseTransform();
  97. m_adjustTransform.reset(new DataTypes::MatrixType(AssImpSDKWrapper::AssImpTypeConverter::ToTransform(adjustmatrix)));
  98. m_adjustTransformInverse.reset(new DataTypes::MatrixType(m_adjustTransform->GetInverseFull()));
  99. }
  100. }
  101. void SceneSystem::SwapVec3ForUpAxis(Vector3& swapVector) const
  102. {
  103. if (m_adjustTransform)
  104. {
  105. swapVector = *m_adjustTransform * swapVector;
  106. }
  107. }
  108. void SceneSystem::SwapTransformForUpAxis(DataTypes::MatrixType& inOutTransform) const
  109. {
  110. if (m_adjustTransform)
  111. {
  112. inOutTransform = (*m_adjustTransform * inOutTransform) * *m_adjustTransformInverse;
  113. }
  114. }
  115. void SceneSystem::ConvertUnit(Vector3& scaleVector) const
  116. {
  117. scaleVector *= m_unitSizeInMeters;
  118. }
  119. void SceneSystem::ConvertUnit(DataTypes::MatrixType& inOutTransform) const
  120. {
  121. Vector3 translation = inOutTransform.GetTranslation();
  122. translation *= m_unitSizeInMeters;
  123. inOutTransform.SetTranslation(translation);
  124. }
  125. void SceneSystem::ConvertBoneUnit(DataTypes::MatrixType& inOutTransform) const
  126. {
  127. // Need to scale translation explicitly as MultiplyByScale won't change the translation component
  128. // and we need to convert to meter unit
  129. Vector3 translation = inOutTransform.GetTranslation();
  130. translation *= m_unitSizeInMeters;
  131. inOutTransform.SetTranslation(translation);
  132. }
  133. }
  134. }