2
0

AssImpSkinWeightsImporter.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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/SerializeContext.h>
  9. #include <AzCore/std/smart_ptr/make_shared.h>
  10. #include <AzCore/std/string/conversions.h>
  11. #include <AzToolsFramework/Debug/TraceContext.h>
  12. #include <SceneAPI/SceneBuilder/Importers/AssImpSkinWeightsImporter.h>
  13. #include <SceneAPI/SceneBuilder/Importers/ImporterUtilities.h>
  14. #include <SceneAPI/SceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
  15. #include <SceneAPI/SceneBuilder/Importers/Utilities/RenamedNodesMap.h>
  16. #include <SceneAPI/SceneCore/Events/ImportEventContext.h>
  17. #include <SceneAPI/SceneData/GraphData/MeshData.h>
  18. #include <SceneAPI/SceneData/GraphData/SkinWeightData.h>
  19. #include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
  20. #include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
  21. namespace AZ
  22. {
  23. namespace SceneAPI
  24. {
  25. namespace SceneBuilder
  26. {
  27. const AZStd::string AssImpSkinWeightsImporter::s_skinWeightName = "SkinWeight_";
  28. AssImpSkinWeightsImporter::AssImpSkinWeightsImporter()
  29. {
  30. BindToCall(&AssImpSkinWeightsImporter::ImportSkinWeights);
  31. BindToCall(&AssImpSkinWeightsImporter::SetupNamedBoneLinks);
  32. }
  33. void AssImpSkinWeightsImporter::Reflect(ReflectContext* context)
  34. {
  35. SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
  36. if (serializeContext)
  37. {
  38. serializeContext->Class<AssImpSkinWeightsImporter, SceneCore::LoadingComponent>()->Version(3); // LYN-2576
  39. }
  40. }
  41. Events::ProcessingResult AssImpSkinWeightsImporter::ImportSkinWeights(AssImpSceneNodeAppendedContext& context)
  42. {
  43. AZ_TraceContext("Importer", "Skin Weights");
  44. const aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
  45. const aiScene* scene = context.m_sourceScene.GetAssImpScene();
  46. if(currentNode->mNumMeshes <= 0)
  47. {
  48. return Events::ProcessingResult::Ignored;
  49. }
  50. Events::ProcessingResultCombiner combinedSkinWeightsResult;
  51. // Don't create this until a bone with weights is encountered
  52. Containers::SceneGraph::NodeIndex weightsIndexForMesh;
  53. AZStd::string skinWeightName;
  54. AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> skinWeightData;
  55. const uint64_t totalVertices = GetVertexCountForAllMeshesOnNode(*currentNode, *scene);
  56. int vertexCount = 0;
  57. for(unsigned nodeMeshIndex = 0; nodeMeshIndex < currentNode->mNumMeshes; ++nodeMeshIndex)
  58. {
  59. int sceneMeshIndex = currentNode->mMeshes[nodeMeshIndex];
  60. const aiMesh* mesh = scene->mMeshes[sceneMeshIndex];
  61. for(unsigned b = 0; b < mesh->mNumBones; ++b)
  62. {
  63. const aiBone* bone = mesh->mBones[b];
  64. if(bone->mNumWeights <= 0)
  65. {
  66. continue;
  67. }
  68. if (!weightsIndexForMesh.IsValid())
  69. {
  70. skinWeightName = s_skinWeightName;
  71. RenamedNodesMap::SanitizeNodeName(skinWeightName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
  72. weightsIndexForMesh =
  73. context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, skinWeightName.c_str());
  74. AZ_Error("SkinWeightsImporter", weightsIndexForMesh.IsValid(), "Failed to create SceneGraph node for attribute.");
  75. if (!weightsIndexForMesh.IsValid())
  76. {
  77. combinedSkinWeightsResult += Events::ProcessingResult::Failure;
  78. continue;
  79. }
  80. skinWeightData = AZStd::make_shared<SceneData::GraphData::SkinWeightData>();
  81. }
  82. Pending pending;
  83. pending.m_bone = bone;
  84. pending.m_sanitizedName = bone->mName.C_Str();
  85. RenamedNodesMap::SanitizeNodeName(pending.m_sanitizedName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
  86. pending.m_numVertices = static_cast<unsigned int>(totalVertices);
  87. pending.m_skinWeightData = skinWeightData;
  88. pending.m_vertOffset = vertexCount;
  89. m_pendingSkinWeights.push_back(pending);
  90. }
  91. vertexCount += mesh->mNumVertices;
  92. }
  93. Events::ProcessingResult skinWeightsResult;
  94. AssImpSceneAttributeDataPopulatedContext dataPopulated(context, skinWeightData, weightsIndexForMesh, skinWeightName);
  95. skinWeightsResult = Events::Process(dataPopulated);
  96. if (skinWeightsResult != Events::ProcessingResult::Failure)
  97. {
  98. skinWeightsResult = AddAttributeDataNodeWithContexts(dataPopulated);
  99. }
  100. combinedSkinWeightsResult += skinWeightsResult;
  101. return combinedSkinWeightsResult.GetResult();
  102. }
  103. Events::ProcessingResult AssImpSkinWeightsImporter::SetupNamedBoneLinks(AssImpFinalizeSceneContext& /*context*/)
  104. {
  105. AZ_TraceContext("Importer", "Skin Weights");
  106. for (auto& it : m_pendingSkinWeights)
  107. {
  108. it.m_skinWeightData->ResizeContainerSpace(it.m_numVertices);
  109. int boneId = it.m_skinWeightData->GetBoneId(it.m_sanitizedName);
  110. for(unsigned weight = 0; weight < it.m_bone->mNumWeights; ++weight)
  111. {
  112. DataTypes::ISkinWeightData::Link link;
  113. link.boneId = boneId;
  114. link.weight = it.m_bone->mWeights[weight].mWeight;
  115. it.m_skinWeightData->AddAndSortLink(it.m_bone->mWeights[weight].mVertexId + it.m_vertOffset, link);
  116. }
  117. }
  118. const auto result = m_pendingSkinWeights.empty() ? Events::ProcessingResult::Ignored : Events::ProcessingResult::Success;
  119. m_pendingSkinWeights.clear();
  120. return result;
  121. }
  122. } // namespace SceneBuilder
  123. } // namespace SceneAPI
  124. } // namespace AZ