Integrating github/staging through commit 5f214be

This commit is contained in:
alexpete
2021-04-13 17:18:57 -07:00
parent 2a9dfb7a1d
commit 8469c9ca0a
904 changed files with 9289 additions and 7157 deletions
@@ -211,41 +211,44 @@ namespace AZ
const uint32_t* sourceOriginalVertex = static_cast<uint32_t*>(mesh->FindOriginalVertexData(EMotionFX::Mesh::ATTRIB_ORGVTXNUMBERS));
const uint32_t vertexCount = subMesh->GetNumVertices();
const uint32_t vertexStart = subMesh->GetStartVertex();
for (uint32_t vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex)
if (sourceSkinningInfo)
{
const uint32_t originalVertex = sourceOriginalVertex[vertexIndex + vertexStart];
const uint32_t influenceCount = AZStd::GetMin<uint32_t>(MaxSupportedSkinInfluences, sourceSkinningInfo->GetNumInfluences(originalVertex));
uint32_t influenceIndex = 0;
float weightError = 1.0f;
AZStd::vector<uint32_t> localIndices;
for (; influenceIndex < influenceCount; ++influenceIndex)
for (uint32_t vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex)
{
EMotionFX::SkinInfluence* influence = sourceSkinningInfo->GetInfluence(originalVertex, influenceIndex);
localIndices.push_back(static_cast<uint32_t>(influence->GetNodeNr()));
blendWeightBufferData[atomVertexBufferOffset + vertexIndex][influenceIndex] = influence->GetWeight();
weightError -= blendWeightBufferData[atomVertexBufferOffset + vertexIndex][influenceIndex];
}
const uint32_t originalVertex = sourceOriginalVertex[vertexIndex + vertexStart];
const uint32_t influenceCount = AZStd::GetMin<uint32_t>(MaxSupportedSkinInfluences, sourceSkinningInfo->GetNumInfluences(originalVertex));
uint32_t influenceIndex = 0;
float weightError = 1.0f;
// Zero out any unused ids/weights
for (; influenceIndex < MaxSupportedSkinInfluences; ++influenceIndex)
{
localIndices.push_back(0);
blendWeightBufferData[atomVertexBufferOffset + vertexIndex][influenceIndex] = 0.0f;
}
// Now that we have the 16-bit indices, pack them into 32-bit uints
for (size_t i = 0; i < localIndices.size(); ++i)
{
if (i % 2 == 0)
AZStd::vector<uint32_t> localIndices;
for (; influenceIndex < influenceCount; ++influenceIndex)
{
// Put the first/even ids in the most significant bits
blendIndexBufferData[atomVertexBufferOffset + vertexIndex][i/2] = localIndices[i] << 16;
EMotionFX::SkinInfluence* influence = sourceSkinningInfo->GetInfluence(originalVertex, influenceIndex);
localIndices.push_back(static_cast<uint32_t>(influence->GetNodeNr()));
blendWeightBufferData[atomVertexBufferOffset + vertexIndex][influenceIndex] = influence->GetWeight();
weightError -= blendWeightBufferData[atomVertexBufferOffset + vertexIndex][influenceIndex];
}
else
// Zero out any unused ids/weights
for (; influenceIndex < MaxSupportedSkinInfluences; ++influenceIndex)
{
// Put the next/odd ids in the least significant bits
blendIndexBufferData[atomVertexBufferOffset + vertexIndex][i / 2] |= localIndices[i];
localIndices.push_back(0);
blendWeightBufferData[atomVertexBufferOffset + vertexIndex][influenceIndex] = 0.0f;
}
// Now that we have the 16-bit indices, pack them into 32-bit uints
for (size_t i = 0; i < localIndices.size(); ++i)
{
if (i % 2 == 0)
{
// Put the first/even ids in the most significant bits
blendIndexBufferData[atomVertexBufferOffset + vertexIndex][i / 2] = localIndices[i] << 16;
}
else
{
// Put the next/odd ids in the least significant bits
blendIndexBufferData[atomVertexBufferOffset + vertexIndex][i / 2] |= localIndices[i];
}
}
}
}
@@ -268,7 +271,9 @@ namespace AZ
// Static triangles are the ones that all its vertices won't move during simulation and
// therefore its weights won't be altered so they are controlled by GPU.
// This additional simplification has been disabled in ClothComponentMesh.cpp for now.
if (hasClothData)
// If there is no skinning info, default to 0 weights and display an error
if (hasClothData || !sourceSkinningInfo)
{
for (uint32_t vertexIndex = 0; vertexIndex < vertexCount; ++vertexIndex)
{
@@ -471,41 +476,44 @@ namespace AZ
} // for all submeshes
} // for all meshes
// Now that the data has been prepped, create the actual buffers
// Now that the data has been prepped, set the actual buffers
skinnedMeshLod.SetModelLodAsset(modelLodAsset);
// Create read-only buffers and views for input buffers that are shared across all instances
// Set read-only buffers and views for input buffers that are shared across all instances
AZStd::string lodString = AZStd::string::format("_Lod%zu", lodIndex);
skinnedMeshLod.SetSkinningInputBufferAsset(mesh0.GetSemanticBufferAssetView(Name{ "POSITION" })->GetBufferAsset(), SkinnedMeshInputVertexStreams::Position);
skinnedMeshLod.SetSkinningInputBufferAsset(mesh0.GetSemanticBufferAssetView(Name{ "NORMAL" })->GetBufferAsset(), SkinnedMeshInputVertexStreams::Normal);
skinnedMeshLod.SetSkinningInputBufferAsset(mesh0.GetSemanticBufferAssetView(Name{ "TANGENT" })->GetBufferAsset(), SkinnedMeshInputVertexStreams::Tangent);
skinnedMeshLod.SetSkinningInputBufferAsset(mesh0.GetSemanticBufferAssetView(Name{ "BITANGENT" })->GetBufferAsset(), SkinnedMeshInputVertexStreams::BiTangent);
Data::Asset<RPI::BufferAsset> jointIndicesBufferAsset = mesh0.GetSemanticBufferAssetView(Name{ "SKIN_JOINTINDICES" })->GetBufferAsset();
skinnedMeshLod.SetSkinningInputBufferAsset(jointIndicesBufferAsset, SkinnedMeshInputVertexStreams::BlendIndices);
Data::Asset<RPI::BufferAsset> skinWeightsBufferAsset = mesh0.GetSemanticBufferAssetView(Name{ "SKIN_WEIGHTS" })->GetBufferAsset();
skinnedMeshLod.SetSkinningInputBufferAsset(skinWeightsBufferAsset, SkinnedMeshInputVertexStreams::BlendWeights);
// We're using the indices/weights buffers directly from the model.
// However, EMFX has done some re-mapping of the id's, so we need to update the GPU buffer for it to have the correct data.
size_t remappedJointIndexBufferSizeInBytes = blendIndexBufferData.size() * sizeof(blendIndexBufferData[0]);
size_t remappedSkinWeightsBufferSizeInBytes = blendWeightBufferData.size() * sizeof(blendWeightBufferData[0]);
if (!mesh0.GetSemanticBufferAssetView(Name{ "SKIN_JOINTINDICES" }) || !mesh0.GetSemanticBufferAssetView(Name{ "SKIN_WEIGHTS" }))
{
AZ_Error("ProcessSkinInfluences", false, "Actor '%s' lod '%zu' has no skin influences, and will be stuck in bind pose.", fullFileName.c_str(), lodIndex);
}
else
{
Data::Asset<RPI::BufferAsset> jointIndicesBufferAsset = mesh0.GetSemanticBufferAssetView(Name{ "SKIN_JOINTINDICES" })->GetBufferAsset();
skinnedMeshLod.SetSkinningInputBufferAsset(jointIndicesBufferAsset, SkinnedMeshInputVertexStreams::BlendIndices);
Data::Asset<RPI::BufferAsset> skinWeightsBufferAsset = mesh0.GetSemanticBufferAssetView(Name{ "SKIN_WEIGHTS" })->GetBufferAsset();
skinnedMeshLod.SetSkinningInputBufferAsset(skinWeightsBufferAsset, SkinnedMeshInputVertexStreams::BlendWeights);
AZ_Assert(jointIndicesBufferAsset->GetBufferDescriptor().m_byteCount == remappedJointIndexBufferSizeInBytes, "Joint indices data from EMotionFX is not the same size as the buffer from the model in '%s', lod '%d'", fullFileName.c_str(), lodIndex);
AZ_Assert(skinWeightsBufferAsset->GetBufferDescriptor().m_byteCount == remappedSkinWeightsBufferSizeInBytes, "Skin weights data from EMotionFX is not the same size as the buffer from the model in '%s', lod '%d'", fullFileName.c_str(), lodIndex);
// We're using the indices/weights buffers directly from the model.
// However, EMFX has done some re-mapping of the id's, so we need to update the GPU buffer for it to have the correct data.
size_t remappedJointIndexBufferSizeInBytes = blendIndexBufferData.size() * sizeof(blendIndexBufferData[0]);
size_t remappedSkinWeightsBufferSizeInBytes = blendWeightBufferData.size() * sizeof(blendWeightBufferData[0]);
Data::Instance<RPI::Buffer> jointIndicesBuffer = RPI::Buffer::FindOrCreate(jointIndicesBufferAsset);
jointIndicesBuffer->UpdateData(blendIndexBufferData.data(), remappedJointIndexBufferSizeInBytes);
Data::Instance<RPI::Buffer> skinWeightsBuffer = RPI::Buffer::FindOrCreate(skinWeightsBufferAsset);
skinWeightsBuffer->UpdateData(blendWeightBufferData.data(), remappedSkinWeightsBufferSizeInBytes);
AZ_Assert(jointIndicesBufferAsset->GetBufferDescriptor().m_byteCount == remappedJointIndexBufferSizeInBytes, "Joint indices data from EMotionFX is not the same size as the buffer from the model in '%s', lod '%d'", fullFileName.c_str(), lodIndex);
AZ_Assert(skinWeightsBufferAsset->GetBufferDescriptor().m_byteCount == remappedSkinWeightsBufferSizeInBytes, "Skin weights data from EMotionFX is not the same size as the buffer from the model in '%s', lod '%d'", fullFileName.c_str(), lodIndex);
Data::Instance<RPI::Buffer> jointIndicesBuffer = RPI::Buffer::FindOrCreate(jointIndicesBufferAsset);
jointIndicesBuffer->UpdateData(blendIndexBufferData.data(), remappedJointIndexBufferSizeInBytes);
Data::Instance<RPI::Buffer> skinWeightsBuffer = RPI::Buffer::FindOrCreate(skinWeightsBufferAsset);
skinWeightsBuffer->UpdateData(blendWeightBufferData.data(), remappedSkinWeightsBufferSizeInBytes);
}
// Create read-only input assembly buffers that are not modified during skinning and shared across all instances
skinnedMeshLod.SetIndexBuffer(mesh0.GetIndexBufferAssetView().GetBufferAsset());
skinnedMeshLod.CreateStaticBuffer(uvBufferData.data(), SkinnedMeshStaticVertexStreams::UV_0, fullFileName + lodString + "_SkinnedMeshStaticUVs");
// Set the data that needs to be tracked on a per-sub-mesh basis
// and create the common, shared sub-mesh buffer views
skinnedMeshLod.SetSubMeshProperties(subMeshes);
skinnedMeshLod.SetIndexBufferAsset(mesh0.GetIndexBufferAssetView().GetBufferAsset());
skinnedMeshLod.SetStaticBufferAsset(mesh0.GetSemanticBufferAssetView(Name{ "UV" })->GetBufferAsset(), SkinnedMeshStaticVertexStreams::UV_0);
const RPI::BufferAssetView* morphBufferAssetView = mesh0.GetSemanticBufferAssetView(Name{ "MORPHTARGET_VERTEXDELTAS" });
if (morphBufferAssetView)
@@ -513,6 +521,28 @@ namespace AZ
ProcessMorphsForLod(actor, morphBufferAssetView->GetBufferAsset(), lodIndex, fullFileName, skinnedMeshLod);
}
// Set colors after morphs are set, so that we know whether or not they are dynamic (if they exist)
const RPI::BufferAssetView* colorView = mesh0.GetSemanticBufferAssetView(Name{ "COLOR" });
if (colorView)
{
if (skinnedMeshLod.HasDynamicColors())
{
// If colors are being morphed,
// add them as input to the skinning compute shader, which will apply the morph
skinnedMeshLod.SetSkinningInputBufferAsset(colorView->GetBufferAsset(), SkinnedMeshInputVertexStreams::Color);
}
else
{
// If colors exist but are not modified dynamically,
// add them to the static streams that are shared by all instances of the same skinned mesh
skinnedMeshLod.SetStaticBufferAsset(colorView->GetBufferAsset(), SkinnedMeshStaticVertexStreams::Color);
}
}
// Set the data that needs to be tracked on a per-sub-mesh basis
// and create the common, shared sub-mesh buffer views
skinnedMeshLod.SetSubMeshProperties(subMeshes);
skinnedMeshInputBuffers->SetLod(lodIndex, skinnedMeshLod);
} // for all lods