Integrating up through commit 90f050496
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/scene.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
@@ -38,8 +39,10 @@ namespace AZ
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
const char* AssImpAnimationImporter::s_animationNodeName = "animation";
|
||||
const FbxSDKWrapper::FbxTimeWrapper::TimeMode AssImpAnimationImporter::s_defaultTimeMode =
|
||||
FbxSDKWrapper::FbxTimeWrapper::frames30;
|
||||
|
||||
// Downstream only supports 30 frames per second sample rate. Adjusting to 60 doubles the
|
||||
// length of the animations, they still play back at 30 frames per second.
|
||||
const double AssImpAnimationImporter::s_defaultTimeStepSampleRate = 1.0 / 30.0;
|
||||
|
||||
AssImpAnimationImporter::AssImpAnimationImporter()
|
||||
{
|
||||
@@ -51,7 +54,7 @@ namespace AZ
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
serializeContext->Class<AssImpAnimationImporter, SceneCore::LoadingComponent>()->Version(2); // [LYN-2281] Skinned mesh loading fixes
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,13 +118,13 @@ namespace AZ
|
||||
}
|
||||
|
||||
// These variables are named using AssImp naming convention for consistency
|
||||
unsigned int mNumPositionKeys{};
|
||||
AZ::u32 mNumPositionKeys{};
|
||||
aiVectorKey* mPositionKeys{};
|
||||
|
||||
unsigned int mNumRotationKeys{};
|
||||
AZ::u32 mNumRotationKeys{};
|
||||
aiQuatKey* mRotationKeys{};
|
||||
|
||||
unsigned int mNumScalingKeys{};
|
||||
AZ::u32 mNumScalingKeys{};
|
||||
aiVectorKey* mScalingKeys{};
|
||||
|
||||
AZStd::vector<aiVectorKey> m_ownedPositionKeys{};
|
||||
@@ -156,7 +159,6 @@ namespace AZ
|
||||
return AZStd::make_pair(animation, anim);
|
||||
}
|
||||
|
||||
|
||||
Events::ProcessingResult AssImpAnimationImporter::ImportAnimation(AssImpSceneNodeAppendedContext& context)
|
||||
{
|
||||
AZ_TraceContext("Importer", "Animation");
|
||||
@@ -181,11 +183,11 @@ namespace AZ
|
||||
// all the animations for a given node
|
||||
// In the case of bone animations, the data is copied into a ConsolidatedNodeAnim so we can
|
||||
// do fix-ups later without affecting the original data
|
||||
auto mapAnimationsFunc = [](unsigned numChannels, auto** channels, const aiAnimation* animation, auto& map)
|
||||
auto mapAnimationsFunc = [](AZ::u32 numChannels, auto** channels, const aiAnimation* animation, auto& map)
|
||||
{
|
||||
map.reserve(numChannels);
|
||||
|
||||
for (unsigned channelIndex = 0; channelIndex < numChannels; ++channelIndex)
|
||||
for (AZ::u32 channelIndex = 0; channelIndex < numChannels; ++channelIndex)
|
||||
{
|
||||
auto* nodeAnim = channels[channelIndex];
|
||||
AZStd::string name = GetName(nodeAnim);
|
||||
@@ -194,13 +196,13 @@ namespace AZ
|
||||
}
|
||||
};
|
||||
|
||||
for (unsigned animIndex = 0; animIndex < scene->mNumAnimations; ++animIndex)
|
||||
for (AZ::u32 animIndex = 0; animIndex < scene->mNumAnimations; ++animIndex)
|
||||
{
|
||||
const aiAnimation* animation = scene->mAnimations[animIndex];
|
||||
|
||||
mapAnimationsFunc(animation->mNumChannels, animation->mChannels, animation, boneAnimations);
|
||||
|
||||
for (unsigned channelIndex = 0; channelIndex < animation->mNumMorphMeshChannels; ++channelIndex)
|
||||
for (AZ::u32 channelIndex = 0; channelIndex < animation->mNumMorphMeshChannels; ++channelIndex)
|
||||
{
|
||||
auto* nodeAnim = animation->mMorphMeshChannels[channelIndex];
|
||||
AZStd::string name = GetName(nodeAnim);
|
||||
@@ -280,7 +282,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
Events::ProcessingResultCombiner combinedAnimationResult;
|
||||
for (unsigned meshIndex = 0; meshIndex < currentNode->mNumMeshes; ++meshIndex)
|
||||
for (AZ::u32 meshIndex = 0; meshIndex < currentNode->mNumMeshes; ++meshIndex)
|
||||
{
|
||||
aiMesh* mesh = scene->mMeshes[currentNode->mMeshes[meshIndex]];
|
||||
|
||||
@@ -321,7 +323,7 @@ namespace AZ
|
||||
DataTypes::MatrixType localTransform = AssImpSDKWrapper::AssImpTypeConverter::ToTransform(combinedTransform);
|
||||
context.m_sourceSceneSystem.SwapTransformForUpAxis(localTransform);
|
||||
context.m_sourceSceneSystem.ConvertUnit(localTransform);
|
||||
for (unsigned time = 0; time <= animation->mDuration; ++time)
|
||||
for (AZ::u32 time = 0; time <= animation->mDuration; ++time)
|
||||
{
|
||||
createdAnimationData->AddKeyFrame(localTransform);
|
||||
}
|
||||
@@ -408,15 +410,8 @@ namespace AZ
|
||||
anim->mNumPositionKeys, anim->mNumRotationKeys, anim->mNumScalingKeys);
|
||||
return Events::ProcessingResult::Failure;
|
||||
}
|
||||
|
||||
unsigned numAnimationKeys = anim->mNumPositionKeys;
|
||||
|
||||
if (numAnimationKeys <= 1)
|
||||
{
|
||||
numAnimationKeys = AZStd::GetMax(anim->mNumRotationKeys, anim->mNumScalingKeys);
|
||||
}
|
||||
|
||||
auto sampleKeyFrame = [](const auto& keys, unsigned numKeys, double time)
|
||||
|
||||
auto sampleKeyFrame = [](const auto& keys, AZ::u32 numKeys, double time, AZ::u32& lastIndex)
|
||||
{
|
||||
AZ_Error("AnimationImporter", numKeys > 0, "Animation key set must have at least 1 key");
|
||||
|
||||
@@ -427,9 +422,10 @@ namespace AZ
|
||||
|
||||
auto returnValue = keys[0].mValue;
|
||||
|
||||
for (unsigned keyIndex = 0; keyIndex < numKeys; ++keyIndex)
|
||||
for (AZ::u32 keyIndex = lastIndex; keyIndex < numKeys; ++keyIndex)
|
||||
{
|
||||
const auto& key = keys[keyIndex];
|
||||
lastIndex = keyIndex;
|
||||
|
||||
// We want to return the key that exactly matches the time if possible, otherwise we'll keep track of the previous time
|
||||
// If we don't find an exact match and end up going past the desired time (or run out of keyframes) then we return the previous key
|
||||
@@ -437,7 +433,7 @@ namespace AZ
|
||||
{
|
||||
returnValue = key.mValue;
|
||||
}
|
||||
else if (key.mTime == time)
|
||||
else if (AZ::IsClose(key.mTime, time))
|
||||
{
|
||||
return key.mValue;
|
||||
}
|
||||
@@ -450,16 +446,34 @@ namespace AZ
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
// Resample the animations at a fixed time step. This matches the behaviour of
|
||||
// the previous SDK used. Longer term, this could be data driven, or based on the
|
||||
// smallest time step between key frames.
|
||||
// AssImp has an animation->mTicksPerSecond and animation->mDuration, but those
|
||||
// are less predictable than just using a fixed time step.
|
||||
const double duration = animation->mDuration / animation->mTicksPerSecond;
|
||||
|
||||
AZ::u32 numKeyFrames = AZStd::max(AZStd::max(anim->mNumScalingKeys, anim->mNumPositionKeys), anim->mNumRotationKeys);
|
||||
if (!AZ::IsClose(duration / s_defaultTimeStepSampleRate, numKeyFrames, 1))
|
||||
{
|
||||
double dT = duration / s_defaultTimeStepSampleRate;
|
||||
numKeyFrames = AZStd::ceilf(dT) + 1; // +1 because the animation is from [0, duration] - we have a keyframe at the end of the duration which needs to be included
|
||||
}
|
||||
|
||||
AZStd::shared_ptr<SceneData::GraphData::AnimationData> createdAnimationData =
|
||||
AZStd::make_shared<SceneData::GraphData::AnimationData>();
|
||||
createdAnimationData->ReserveKeyFrames(animation->mDuration + 1); // +1 because we start at 0 and the last keyframe is at mDuration instead of mDuration-1
|
||||
createdAnimationData->SetTimeStepBetweenFrames(1.0 / animation->mTicksPerSecond);
|
||||
|
||||
for (unsigned time = 0; time <= animation->mDuration; ++time)
|
||||
createdAnimationData->ReserveKeyFrames(numKeyFrames);
|
||||
createdAnimationData->SetTimeStepBetweenFrames(s_defaultTimeStepSampleRate);
|
||||
|
||||
AZ::u32 lastScaleIndex = 0;
|
||||
AZ::u32 lastPositionIndex = 0;
|
||||
AZ::u32 lastRotationIndex = 0;
|
||||
for (AZ::u32 frame = 0; frame < numKeyFrames; ++frame)
|
||||
{
|
||||
auto scale = sampleKeyFrame(anim->mScalingKeys, anim->mNumScalingKeys, time);
|
||||
auto position = sampleKeyFrame(anim->mPositionKeys, anim->mNumPositionKeys, time);
|
||||
auto rotation = sampleKeyFrame(anim->mRotationKeys, anim->mNumRotationKeys, time);
|
||||
double time = frame * s_defaultTimeStepSampleRate * animation->mTicksPerSecond;
|
||||
aiVector3D scale = sampleKeyFrame(anim->mScalingKeys, anim->mNumScalingKeys, time, lastScaleIndex);
|
||||
aiVector3D position = sampleKeyFrame(anim->mPositionKeys, anim->mNumPositionKeys, time, lastPositionIndex);
|
||||
aiQuaternion rotation = sampleKeyFrame(anim->mRotationKeys, anim->mNumRotationKeys, time, lastRotationIndex);
|
||||
|
||||
aiMatrix4x4 transform(scale, rotation, position);
|
||||
|
||||
@@ -555,9 +569,9 @@ namespace AZ
|
||||
aiAnimMesh* aiAnimMesh = mesh->mAnimMeshes[meshIdx];
|
||||
AZStd::string_view nodeName(aiAnimMesh->mName.C_Str());
|
||||
|
||||
const unsigned maxKeys = keys.size();
|
||||
unsigned keyIdx = 0;
|
||||
for (unsigned time = 0; time <= animation->mDuration; ++time)
|
||||
const AZ::u32 maxKeys = keys.size();
|
||||
AZ::u32 keyIdx = 0;
|
||||
for (AZ::u32 time = 0; time <= animation->mDuration; ++time)
|
||||
{
|
||||
if (keyIdx < maxKeys - 1 && time >= keys[keyIdx+1].m_time)
|
||||
{
|
||||
|
||||
@@ -45,9 +45,10 @@ namespace AZ
|
||||
const aiMeshMorphAnim* meshMorphAnim,
|
||||
const aiMesh* mesh);
|
||||
|
||||
static const double s_defaultTimeStepSampleRate;
|
||||
|
||||
protected:
|
||||
static const char* s_animationNodeName;
|
||||
static const FbxSDKWrapper::FbxTimeWrapper::TimeMode s_defaultTimeMode;
|
||||
};
|
||||
} // namespace FbxSceneBuilder
|
||||
} // namespace SceneAPI
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBitangentStreamImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshVertexBitangentData.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
@@ -42,7 +43,7 @@ namespace AZ
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpBitangentStreamImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
serializeContext->Class<AssImpBitangentStreamImporter, SceneCore::LoadingComponent>()->Version(2); // LYN-2576
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,15 +57,13 @@ namespace AZ
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
|
||||
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
|
||||
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
|
||||
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
|
||||
if (!meshDataResult.IsSuccess())
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct bitangent stream attribute for invalid or non-mesh parent data");
|
||||
return Events::ProcessingResult::Failure;
|
||||
return meshDataResult.GetError();
|
||||
}
|
||||
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
|
||||
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
|
||||
|
||||
size_t vertexCount = parentMeshData->GetVertexCount();
|
||||
|
||||
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <AzCore/std/string/conversions.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpBlendShapeImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
|
||||
@@ -43,7 +44,7 @@ namespace AZ
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpBlendShapeImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
serializeContext->Class<AssImpBlendShapeImporter, SceneCore::LoadingComponent>()->Version(3); // LYN-2576
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,13 +69,24 @@ namespace AZ
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
|
||||
if (!meshDataResult.IsSuccess())
|
||||
{
|
||||
return meshDataResult.GetError();
|
||||
}
|
||||
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
|
||||
int parentMeshIndex = parentMeshData->GetSdkMeshIndex();
|
||||
|
||||
Events::ProcessingResultCombiner combinedBlendShapeResult;
|
||||
|
||||
for (int meshIdx = 0; meshIdx < numMesh; meshIdx++)
|
||||
for (int nodeMeshIdx = 0; nodeMeshIdx < numMesh; nodeMeshIdx++)
|
||||
{
|
||||
int meshId = context.m_sourceNode.GetAssImpNode()->mMeshes[meshIdx];
|
||||
aiMesh* aiMesh = context.m_sourceScene.GetAssImpScene()->mMeshes[meshId];
|
||||
if (!aiMesh->mNumAnimMeshes)
|
||||
int sceneMeshIdx = context.m_sourceNode.GetAssImpNode()->mMeshes[nodeMeshIdx];
|
||||
const aiMesh* aiMesh = context.m_sourceScene.GetAssImpScene()->mMeshes[sceneMeshIdx];
|
||||
|
||||
// Each mesh gets its own node in the scene graph, so only generate
|
||||
// morph targets for the current mesh.
|
||||
if (parentMeshIndex != nodeMeshIdx || !aiMesh->mNumAnimMeshes)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -96,9 +108,22 @@ namespace AZ
|
||||
|
||||
int firstMeshVertexIndex = -1;
|
||||
int previousMeshVertexIndex = -1;
|
||||
|
||||
int verticesInMeshFace = 0;
|
||||
|
||||
AZStd::bitset<SceneData::GraphData::BlendShapeData::MaxNumUVSets> uvSetUsedFlags;
|
||||
for (AZ::u8 uvSetIndex = 0; uvSetIndex < SceneData::GraphData::BlendShapeData::MaxNumUVSets; ++uvSetIndex)
|
||||
{
|
||||
uvSetUsedFlags.set(uvSetIndex, aiAnimMesh->HasTextureCoords(uvSetIndex));
|
||||
}
|
||||
AZStd::bitset<SceneData::GraphData::BlendShapeData::MaxNumColorSets> colorSetUsedFlags;
|
||||
for (AZ::u8 colorSetIndex = 0; colorSetIndex < SceneData::GraphData::BlendShapeData::MaxNumColorSets;
|
||||
++colorSetIndex)
|
||||
{
|
||||
colorSetUsedFlags.set(colorSetIndex, aiAnimMesh->HasVertexColors(colorSetIndex));
|
||||
}
|
||||
blendShapeData->ReserveData(
|
||||
aiAnimMesh->mNumVertices, aiAnimMesh->HasTangentsAndBitangents(), uvSetUsedFlags, colorSetUsedFlags);
|
||||
|
||||
for (int vertIdx = 0; vertIdx < aiAnimMesh->mNumVertices; ++vertIdx)
|
||||
{
|
||||
AZ::Vector3 vertex(AssImpSDKWrapper::AssImpTypeConverter::ToVector3(aiAnimMesh->mVertices[vertIdx]));
|
||||
@@ -106,7 +131,7 @@ namespace AZ
|
||||
context.m_sourceSceneSystem.SwapVec3ForUpAxis(vertex);
|
||||
context.m_sourceSceneSystem.ConvertUnit(vertex);
|
||||
|
||||
|
||||
// Add normals
|
||||
AZ::Vector3 normal;
|
||||
if (aiAnimMesh->HasNormals())
|
||||
{
|
||||
@@ -116,6 +141,39 @@ namespace AZ
|
||||
}
|
||||
blendShapeData->AddVertex(vertex, normal);
|
||||
blendShapeData->SetVertexIndexToControlPointIndexMap(vertIdx, vertIdx);
|
||||
|
||||
// Add tangents and bitangents
|
||||
if (aiAnimMesh->HasTangentsAndBitangents())
|
||||
{
|
||||
// Vector4's constructor that takes in a vector3 sets w to 1.0f automatically.
|
||||
const AZ::Vector4 tangent(AssImpSDKWrapper::AssImpTypeConverter::ToVector3(aiAnimMesh->mTangents[vertIdx]));
|
||||
const AZ::Vector3 bitangent = AssImpSDKWrapper::AssImpTypeConverter::ToVector3(aiAnimMesh->mBitangents[vertIdx]);
|
||||
blendShapeData->AddTangentAndBitangent(tangent, bitangent);
|
||||
}
|
||||
|
||||
// Add UVs
|
||||
for (AZ::u8 uvSetIdx = 0; uvSetIdx < SceneData::GraphData::BlendShapeData::MaxNumUVSets; ++uvSetIdx)
|
||||
{
|
||||
if (aiAnimMesh->HasTextureCoords(uvSetIdx))
|
||||
{
|
||||
const AZ::Vector2 vertexUV(
|
||||
aiAnimMesh->mTextureCoords[uvSetIdx][vertIdx].x,
|
||||
// The engine's V coordinate is reverse of how it's stored in assImp.
|
||||
1.0f - aiAnimMesh->mTextureCoords[uvSetIdx][vertIdx].y);
|
||||
blendShapeData->AddUV(vertexUV, uvSetIdx);
|
||||
}
|
||||
}
|
||||
|
||||
// Add colors
|
||||
for (AZ::u8 colorSetIdx = 0; colorSetIdx < SceneData::GraphData::BlendShapeData::MaxNumColorSets; ++colorSetIdx)
|
||||
{
|
||||
if (aiAnimMesh->HasVertexColors(colorSetIdx))
|
||||
{
|
||||
SceneAPI::DataTypes::Color color =
|
||||
AssImpSDKWrapper::AssImpTypeConverter::ToColor(aiAnimMesh->mColors[colorSetIdx][vertIdx]);
|
||||
blendShapeData->AddColor(color, colorSetIdx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// aiAnimMesh just has a list of positions for vertices. The face indices are on the original mesh.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpColorStreamImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpTypeConverter.h>
|
||||
@@ -42,7 +43,7 @@ namespace AZ
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpColorStreamImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
serializeContext->Class<AssImpColorStreamImporter, SceneCore::LoadingComponent>()->Version(2); // LYN-2576
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,15 +57,13 @@ namespace AZ
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
|
||||
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
|
||||
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
|
||||
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
|
||||
if (!meshDataResult.IsSuccess())
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct color stream attribute for invalid or non-mesh parent data");
|
||||
return Events::ProcessingResult::Failure;
|
||||
return meshDataResult.GetError();
|
||||
}
|
||||
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
|
||||
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
|
||||
|
||||
size_t vertexCount = parentMeshData->GetVertexCount();
|
||||
|
||||
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <AzCore/StringFunc/StringFunc.h>
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
|
||||
@@ -16,8 +16,10 @@
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpSkinWeightsImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/RenamedNodesMap.h>
|
||||
#include <SceneAPI/SceneCore/Events/ImportEventContext.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshData.h>
|
||||
#include <SceneAPI/SceneData/GraphData/SkinWeightData.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
@@ -41,7 +43,7 @@ namespace AZ
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpSkinWeightsImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
serializeContext->Class<AssImpSkinWeightsImporter, SceneCore::LoadingComponent>()->Version(3); // LYN-2576
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,11 +59,29 @@ namespace AZ
|
||||
return Events::ProcessingResult::Ignored;
|
||||
}
|
||||
|
||||
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
|
||||
if (!meshDataResult.IsSuccess())
|
||||
{
|
||||
return meshDataResult.GetError();
|
||||
}
|
||||
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
|
||||
|
||||
int parentMeshIndex = parentMeshData->GetSdkMeshIndex();
|
||||
|
||||
Events::ProcessingResultCombiner combinedSkinWeightsResult;
|
||||
|
||||
for(unsigned m = 0; m < currentNode->mNumMeshes; ++m)
|
||||
for(unsigned nodeMeshIndex = 0; nodeMeshIndex < currentNode->mNumMeshes; ++nodeMeshIndex)
|
||||
{
|
||||
auto mesh = scene->mMeshes[currentNode->mMeshes[m]];
|
||||
if (nodeMeshIndex != parentMeshIndex)
|
||||
{
|
||||
// Only generate skinning data for the parent mesh.
|
||||
// Each AssImp mesh is assigned to a unique node,
|
||||
// so the skinning data should be generated as a child node
|
||||
// for the associated parent mesh.
|
||||
continue;
|
||||
}
|
||||
int sceneMeshIndex = currentNode->mMeshes[nodeMeshIndex];
|
||||
const aiMesh* mesh = scene->mMeshes[sceneMeshIndex];
|
||||
|
||||
// Don't create this until a bone with weights is encountered
|
||||
Containers::SceneGraph::NodeIndex weightsIndexForMesh;
|
||||
@@ -80,7 +100,7 @@ namespace AZ
|
||||
if (!weightsIndexForMesh.IsValid())
|
||||
{
|
||||
skinWeightName = s_skinWeightName;
|
||||
skinWeightName += AZStd::to_string(m);
|
||||
skinWeightName += AZStd::to_string(nodeMeshIndex);
|
||||
RenamedNodesMap::SanitizeNodeName(skinWeightName, context.m_scene.GetGraph(), context.m_currentGraphPosition);
|
||||
|
||||
weightsIndexForMesh =
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <AzToolsFramework/Debug/TraceContext.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpTangentStreamImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshVertexTangentData.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
@@ -42,7 +43,7 @@ namespace AZ
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpTangentStreamImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
serializeContext->Class<AssImpTangentStreamImporter, SceneCore::LoadingComponent>()->Version(2); // LYN-2576
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,15 +57,13 @@ namespace AZ
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
|
||||
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
|
||||
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
|
||||
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
|
||||
if (!meshDataResult.IsSuccess())
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct tangent stream attribute for invalid or non-mesh parent data");
|
||||
return Events::ProcessingResult::Failure;
|
||||
return meshDataResult.GetError();
|
||||
}
|
||||
const SceneData::GraphData::MeshData* const parentMeshData = azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
|
||||
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
|
||||
|
||||
size_t vertexCount = parentMeshData->GetVertexCount();
|
||||
|
||||
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/AssImpUvMapImporter.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/FbxImporterUtilities.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpNodeWrapper.h>
|
||||
#include <SceneAPI/SDKWrapper/AssImpSceneWrapper.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshData.h>
|
||||
@@ -43,7 +44,7 @@ namespace AZ
|
||||
SerializeContext* serializeContext = azrtti_cast<SerializeContext*>(context);
|
||||
if (serializeContext)
|
||||
{
|
||||
serializeContext->Class<AssImpUvMapImporter, SceneCore::LoadingComponent>()->Version(1);
|
||||
serializeContext->Class<AssImpUvMapImporter, SceneCore::LoadingComponent>()->Version(2); // LYN-2576
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,16 +58,14 @@ namespace AZ
|
||||
aiNode* currentNode = context.m_sourceNode.GetAssImpNode();
|
||||
const aiScene* scene = context.m_sourceScene.GetAssImpScene();
|
||||
|
||||
AZStd::shared_ptr<DataTypes::IGraphObject> parentData =
|
||||
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition);
|
||||
if (!parentData || !parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
|
||||
GetMeshDataFromParentResult meshDataResult(GetMeshDataFromParent(context));
|
||||
if (!meshDataResult.IsSuccess())
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to construct uv stream attribute for invalid or non-mesh parent data");
|
||||
return Events::ProcessingResult::Failure;
|
||||
return meshDataResult.GetError();
|
||||
}
|
||||
const SceneData::GraphData::MeshData* const parentMeshData =
|
||||
azrtti_cast<SceneData::GraphData::MeshData*>(parentData.get());
|
||||
const SceneData::GraphData::MeshData* const parentMeshData(meshDataResult.GetValue());
|
||||
int parentMeshIndex = parentMeshData->GetSdkMeshIndex();
|
||||
|
||||
size_t vertexCount = parentMeshData->GetVertexCount();
|
||||
|
||||
int sdkMeshIndex = parentMeshData->GetSdkMeshIndex();
|
||||
|
||||
+32
@@ -15,9 +15,11 @@
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/FbxSceneSystem.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/ImportContexts/AssImpImportContexts.h>
|
||||
#include <SceneAPI/FbxSceneBuilder/Importers/Utilities/AssImpMeshImporterUtilities.h>
|
||||
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
|
||||
#include <SceneAPI/SceneData/GraphData/BlendShapeData.h>
|
||||
#include <SceneAPI/SceneData/GraphData/BoneData.h>
|
||||
#include <SceneAPI/SceneData/GraphData/MeshData.h>
|
||||
|
||||
namespace AZ::SceneAPI::FbxSceneBuilder
|
||||
@@ -95,4 +97,34 @@ namespace AZ::SceneAPI::FbxSceneBuilder
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GetMeshDataFromParentResult GetMeshDataFromParent(AssImpSceneNodeAppendedContext& context)
|
||||
{
|
||||
const DataTypes::IGraphObject* const parentData =
|
||||
context.m_scene.GetGraph().GetNodeContent(context.m_currentGraphPosition).get();
|
||||
|
||||
if (!parentData)
|
||||
{
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"GetMeshDataFromParent failed because the parent was null, it should only be called with a valid parent node");
|
||||
return AZ::Failure(Events::ProcessingResult::Failure);
|
||||
}
|
||||
|
||||
if (!parentData->RTTI_IsTypeOf(SceneData::GraphData::MeshData::TYPEINFO_Uuid()))
|
||||
{
|
||||
// The parent node may contain bone information and not mesh information, skip it.
|
||||
if (parentData->RTTI_IsTypeOf(SceneData::GraphData::BoneData::TYPEINFO_Uuid()))
|
||||
{
|
||||
// Return the ignore processing result in the failure.
|
||||
return AZ::Failure(Events::ProcessingResult::Ignored);
|
||||
}
|
||||
AZ_Error(Utilities::ErrorWindow, false,
|
||||
"Tried to get mesh data from parent for non-mesh parent data");
|
||||
return AZ::Failure(Events::ProcessingResult::Failure);
|
||||
}
|
||||
|
||||
const SceneData::GraphData::MeshData* const parentMeshData =
|
||||
azrtti_cast<const SceneData::GraphData::MeshData* const>(parentData);
|
||||
return AZ::Success(parentMeshData);
|
||||
}
|
||||
}
|
||||
|
||||
+7
-1
@@ -12,6 +12,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <SceneAPI/SceneCore/Events/ProcessingResult.h>
|
||||
|
||||
struct aiNode;
|
||||
struct aiScene;
|
||||
|
||||
@@ -37,12 +39,16 @@ namespace AZ
|
||||
{
|
||||
class IGraphObject;
|
||||
}
|
||||
|
||||
struct AssImpSceneNodeAppendedContext;
|
||||
class FbxSceneSystem;
|
||||
|
||||
namespace FbxSceneBuilder
|
||||
{
|
||||
bool BuildSceneMeshFromAssImpMesh(aiNode* currentNode, const aiScene* scene, const FbxSceneSystem& sceneSystem, AZStd::vector<AZStd::shared_ptr<DataTypes::IGraphObject>>& meshes,
|
||||
const AZStd::function<AZStd::shared_ptr<SceneData::GraphData::MeshData>()>& makeMeshFunc);
|
||||
|
||||
typedef AZ::Outcome<const SceneData::GraphData::MeshData* const, Events::ProcessingResult> GetMeshDataFromParentResult;
|
||||
GetMeshDataFromParentResult GetMeshDataFromParent(AssImpSceneNodeAppendedContext& context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user