AssImpSkinWeightsImporter.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. }
  32. void AssImpSkinWeightsImporter::Reflect(ReflectContext* context)
  33. {
  34. SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
  35. if (serializeContext)
  36. {
  37. serializeContext->Class<AssImpSkinWeightsImporter, SceneCore::LoadingComponent>()->Version(3); // LYN-2576
  38. }
  39. }
  40. Events::ProcessingResult AssImpSkinWeightsImporter::ImportSkinWeights(AssImpSceneNodeAppendedContext& context)
  41. {
  42. AZ_TraceContext("Importer", "Skin Weights");
  43. const aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
  44. const aiScene* scene = context.m_sourceScene.GetAssImpScene();
  45. if(currentNode->mNumMeshes <= 0)
  46. {
  47. return Events::ProcessingResult::Ignored;
  48. }
  49. Events::ProcessingResultCombiner combinedSkinWeightsResult;
  50. // Don't create this until a bone with weights is encountered
  51. Containers::SceneGraph::NodeIndex weightsIndexForMesh;
  52. AZStd::string skinWeightName;
  53. AZStd::shared_ptr<SceneData::GraphData::SkinWeightData> skinWeightData;
  54. const uint64_t totalVertices = GetVertexCountForAllMeshesOnNode(*currentNode, *scene);
  55. int vertexCount = 0;
  56. for(unsigned nodeMeshIndex = 0; nodeMeshIndex < currentNode->mNumMeshes; ++nodeMeshIndex)
  57. {
  58. int sceneMeshIndex = currentNode->mMeshes[nodeMeshIndex];
  59. const aiMesh* mesh = scene->mMeshes[sceneMeshIndex];
  60. for(unsigned b = 0; b < mesh->mNumBones; ++b)
  61. {
  62. const aiBone* bone = mesh->mBones[b];
  63. if(bone->mNumWeights <= 0)
  64. {
  65. continue;
  66. }
  67. if (!weightsIndexForMesh.IsValid())
  68. {
  69. skinWeightName = s_skinWeightName;
  70. RenamedNodesMap::SanitizeNodeName(skinWeightName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
  71. weightsIndexForMesh =
  72. context.m_scene.GetGraph().AddChild(context.m_currentGraphPosition, skinWeightName.c_str());
  73. AZ_Error("SkinWeightsImporter", weightsIndexForMesh.IsValid(), "Failed to create SceneGraph node for attribute.");
  74. if (!weightsIndexForMesh.IsValid())
  75. {
  76. combinedSkinWeightsResult += Events::ProcessingResult::Failure;
  77. continue;
  78. }
  79. skinWeightData = AZStd::make_shared<SceneData::GraphData::SkinWeightData>();
  80. skinWeightData->ResizeContainerSpace(totalVertices);
  81. }
  82. AZStd::string sanitizedName = bone->mName.C_Str();
  83. RenamedNodesMap::SanitizeNodeName(sanitizedName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
  84. int boneId = skinWeightData->GetBoneId(sanitizedName);
  85. for (unsigned weight = 0; weight < bone->mNumWeights; ++weight)
  86. {
  87. DataTypes::ISkinWeightData::Link link;
  88. link.boneId = boneId;
  89. link.weight = bone->mWeights[weight].mWeight;
  90. skinWeightData->AddAndSortLink(bone->mWeights[weight].mVertexId + vertexCount, link);
  91. }
  92. }
  93. vertexCount += mesh->mNumVertices;
  94. }
  95. Events::ProcessingResult skinWeightsResult;
  96. AssImpSceneAttributeDataPopulatedContext dataPopulated(context, skinWeightData, weightsIndexForMesh, skinWeightName);
  97. skinWeightsResult = Events::Process(dataPopulated);
  98. if (skinWeightsResult != Events::ProcessingResult::Failure)
  99. {
  100. skinWeightsResult = AddAttributeDataNodeWithContexts(dataPopulated);
  101. }
  102. combinedSkinWeightsResult += skinWeightsResult;
  103. return combinedSkinWeightsResult.GetResult();
  104. }
  105. } // namespace SceneBuilder
  106. } // namespace SceneAPI
  107. } // namespace AZ