Integrating up through commit 90f050496

This commit is contained in:
alexpete
2021-04-07 14:03:29 -07:00
parent 8f2ed080a9
commit c2cbd430fe
2694 changed files with 285622 additions and 176874 deletions
@@ -27,6 +27,7 @@
#include <Atom/RPI.Reflect/Material/MaterialAsset.h>
#include <Atom/RPI.Reflect/Model/ModelAssetCreator.h>
#include <Atom/RPI.Reflect/Model/ModelLodAssetCreator.h>
#include <Atom/RPI.Reflect/Model/MorphTargetDelta.h>
#include <Atom/RPI.Reflect/Model/SkinMetaAssetCreator.h>
#include <SceneAPI/SceneCore/Containers/Scene.h>
@@ -36,6 +37,7 @@
#include <SceneAPI/SceneCore/Containers/Views/SceneGraphUpwardsIterator.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IBoneData.h>
#include <SceneAPI/SceneCore/DataTypes/GraphData/IBlendShapeData.h>
#include <SceneAPI/SceneCore/DataTypes/Rules/ICoordinateSystemRule.h>
#include <SceneAPI/SceneCore/DataTypes/Rules/ILodRule.h>
#include <SceneAPI/SceneCore/DataTypes/Rules/ISkinRule.h>
#include <SceneAPI/SceneCore/Events/ExportEventContext.h>
@@ -43,6 +45,7 @@
#include <SceneAPI/SceneCore/Utilities/Reporting.h>
#include <SceneAPI/SceneData/Groups/MeshGroup.h>
#include <SceneAPI/SceneData/Rules/StaticMeshAdvancedRule.h>
#include <SceneAPI/SceneCore/Containers/Utilities/SceneUtilities.h>
#include <SceneAPI/SceneCore/Containers/Utilities/Filters.h>
/**
@@ -84,7 +87,7 @@ namespace
const AZ::RHI::Format SkinWeightFormat = AZ::RHI::Format::R32_FLOAT; // Single-component, 32-bit floating point per weight
// Morph targets
const char* ShaderSemanticName_MorphTargetVertexIndices = "MORPHTARGET_VERTEXINDICES";
const char* ShaderSemanticName_MorphTargetDeltas = "MORPHTARGET_VERTEXDELTAS";
const AZ::RHI::Format MorphTargetVertexIndexFormat = AZ::RHI::Format::R32_UINT; // Single-component, 32-bit integer as vertex index
const char* ShaderSemanticName_MorphTargetPositionDeltas = "MORPHTARGET_POSITIONDELTAS";
const AZ::RHI::Format MorphTargetPositionDeltaFormat = AZ::RHI::Format::R16_UINT; // 16-bit integer per compressed position delta component
@@ -105,7 +108,7 @@ namespace AZ
if (auto* serialize = azrtti_cast<SerializeContext*>(context))
{
serialize->Class<ModelAssetBuilderComponent, SceneAPI::SceneCore::ExportingComponent>()
->Version(24); // [ATOM-14876]
->Version(25); // [ATOM-14876]
}
}
@@ -303,7 +306,8 @@ namespace AZ
sourceMesh.m_name = meshName;
const auto node = sceneGraph.Find(meshPath);
sourceMesh.m_worldTransform = GetWorldTransform(sceneGraph, node);
sourceMesh.m_worldTransform = AZ::SceneAPI::Utilities::DetermineWorldTransform(scene, node, context.m_group.GetRuleContainerConst());
auto sibling = sceneGraph.GetNodeChild(node);
AddToMeshContent(viewIt.second, sourceMesh);
@@ -712,6 +716,22 @@ namespace AZ
colorSet.reserve(vertexCount * ColorFloatsPerVert);
}
if (!sourceMesh.m_skinData.empty())
{
// Skinned meshes require that positions, normals, tangents, bitangents, all exist and have the same number
// of total elements. Pad buffers with missing data to make them align with positions and normals
if (!sourceMesh.m_meshTangents)
{
tangents.resize(vertexCount * TangentFloatsPerVert, 1.0f);
AZ_Warning(s_builderName, false, "Mesh '%s' is missing tangents and no defaults were generated. Skinned meshes require tangents. Dummy tangents will be inserted, which may result in rendering artifacts.", sourceMesh.m_name.GetCStr());
}
if (!sourceMesh.m_meshBitangents)
{
bitangents.resize(vertexCount * BitangentFloatsPerVert, 1.0f);
AZ_Warning(s_builderName, false, "Mesh '%s' is missing bitangents and no defaults were generated. Skinned meshes require bitangents. Dummy bitangents will be inserted, which may result in rendering artifacts.", sourceMesh.m_name.GetCStr());
}
}
for (const auto& itr : oldToNewIndices)
{
// We use the 'old' index as that properly indexes
@@ -950,7 +970,7 @@ namespace AZ
}
template<typename T>
void ModelAssetBuilderComponent::ValidateStreamSize(size_t expectedVertexCount, const AZStd::vector<T>& bufferData, AZ::RHI::Format format, const char* streamName) const
void ModelAssetBuilderComponent::ValidateStreamSize([[maybe_unused]] size_t expectedVertexCount, const AZStd::vector<T>& bufferData, AZ::RHI::Format format, [[maybe_unused]] const char* streamName) const
{
size_t actualVertexCount = (bufferData.size() * sizeof(T)) / RHI::GetFormatSize(format);
AZ_Error(s_builderName, expectedVertexCount == actualVertexCount, "VertexStream '%s' does not match the expected vertex count. This typically means multiple sub-meshes have mis-matched vertex stream layouts (such as one having more uv sets than the other) but are assigned the same material in the dcc tool so they were merged.", streamName);
@@ -1056,36 +1076,10 @@ namespace AZ
meshView.m_skinWeightsView = RHI::BufferViewDescriptor::CreateTyped(0, numSkinInfluences, SkinWeightFormat);
}
if (!mesh.m_morphTargetVertexData.m_vertexIndices.empty())
if (!mesh.m_morphTargetVertexData.empty())
{
ProductMeshView::MorphTargetVertexDataView& mtDataView = meshView.m_morphTargetVertexDataView;
const size_t numTotalVertices = mesh.m_morphTargetVertexData.m_vertexIndices.size();
mtDataView.m_vertexIndexView = RHI::BufferViewDescriptor::CreateStructured(0, numTotalVertices, sizeof(uint32_t));
AZ_Assert(3 * numTotalVertices == mesh.m_morphTargetVertexData.m_positionDeltas.size(),
"Number compressed position deltas (%d) incorrect, should be (%d).", mesh.m_morphTargetVertexData.m_positionDeltas.size(), 3 * numTotalVertices);
mtDataView.m_positionDeltaView = RHI::BufferViewDescriptor::CreateTyped(0, numTotalVertices * 3, MorphTargetPositionDeltaFormat);
AZ_Assert(3 * numTotalVertices == mesh.m_morphTargetVertexData.m_normalDeltas.size(),
"Number compressed normal deltas (%d) incorrect, should be (%d).", mesh.m_morphTargetVertexData.m_normalDeltas.size(), 3 * numTotalVertices);
mtDataView.m_normalDeltaView = RHI::BufferViewDescriptor::CreateTyped(0, numTotalVertices * 3, MorphTargetNormalDeltaFormat);
}
if (!mesh.m_morphTargetVertexData.m_vertexIndices.empty())
{
ProductMeshView::MorphTargetVertexDataView& mtDataView = meshView.m_morphTargetVertexDataView;
const size_t numTotalVertices = mesh.m_morphTargetVertexData.m_vertexIndices.size();
mtDataView.m_vertexIndexView = RHI::BufferViewDescriptor::CreateTyped(0, numTotalVertices, MorphTargetVertexIndexFormat);
AZ_Assert(3 * numTotalVertices == mesh.m_morphTargetVertexData.m_positionDeltas.size(),
"Number compressed position deltas (%d) incorrect, should be (%d).", mesh.m_morphTargetVertexData.m_positionDeltas.size(), 3 * numTotalVertices);
mtDataView.m_positionDeltaView = RHI::BufferViewDescriptor::CreateTyped(0, numTotalVertices * 3, MorphTargetPositionDeltaFormat);
AZ_Assert(3 * numTotalVertices == mesh.m_morphTargetVertexData.m_normalDeltas.size(),
"Number compressed normal deltas (%d) incorrect, should be (%d).", mesh.m_morphTargetVertexData.m_normalDeltas.size(), 3 * numTotalVertices);
mtDataView.m_normalDeltaView = RHI::BufferViewDescriptor::CreateTyped(0, numTotalVertices * 3, MorphTargetNormalDeltaFormat);
const size_t numTotalVertices = mesh.m_morphTargetVertexData.size();
meshView.m_morphTargetVertexDataView = RHI::BufferViewDescriptor::CreateStructured(0, numTotalVertices, sizeof(PackedCompressedMorphTargetDelta));
}
meshView.m_materialUid = mesh.m_materialUid;
@@ -1229,15 +1223,12 @@ namespace AZ
lodBufferInfo.m_skinInfluencesCount += numNewSkinInfluences;
}
if (!mesh.m_morphTargetVertexData.m_vertexIndices.empty())
if (!mesh.m_morphTargetVertexData.empty())
{
const size_t numPrevVertexDeltas = lodBufferInfo.m_morphTargetVertexDeltaCount;
const size_t numNewVertexDeltas = mesh.m_morphTargetVertexData.m_vertexIndices.size();
const size_t numNewVertexDeltas = mesh.m_morphTargetVertexData.size();
ProductMeshView::MorphTargetVertexDataView& mtDataView = meshView.m_morphTargetVertexDataView;
mtDataView.m_vertexIndexView = RHI::BufferViewDescriptor::CreateTyped(/*elementOffset=*/numPrevVertexDeltas, numNewVertexDeltas, MorphTargetVertexIndexFormat);
mtDataView.m_positionDeltaView = RHI::BufferViewDescriptor::CreateTyped(/*elementOffset=*/numPrevVertexDeltas * 3, numNewVertexDeltas * 3, MorphTargetPositionDeltaFormat);
mtDataView.m_normalDeltaView = RHI::BufferViewDescriptor::CreateTyped(/*elementOffset=*/numPrevVertexDeltas * 3, numNewVertexDeltas * 3, MorphTargetNormalDeltaFormat);
meshView.m_morphTargetVertexDataView = RHI::BufferViewDescriptor::CreateStructured(/*elementOffset=*/numPrevVertexDeltas, numNewVertexDeltas, sizeof(PackedCompressedMorphTargetDelta));
lodBufferInfo.m_morphTargetVertexDeltaCount += numNewVertexDeltas;
}
@@ -1427,25 +1418,39 @@ namespace AZ
mergedMesh.m_skinWeights.end(), mesh.m_skinWeights.begin(), mesh.m_skinWeights.end());
}
if (!mesh.m_morphTargetVertexData.m_vertexIndices.empty())
if (!mesh.m_morphTargetVertexData.empty())
{
const auto& sourceIndices = mesh.m_morphTargetVertexData.m_vertexIndices;
auto& mergedIndices = mergedMesh.m_morphTargetVertexData.m_vertexIndices;
mergedIndices.insert(mergedIndices.end(), sourceIndices.begin(), sourceIndices.end());
const auto& sourcePosDeltas = mesh.m_morphTargetVertexData.m_positionDeltas;
auto& mergedPosDeltas = mergedMesh.m_morphTargetVertexData.m_positionDeltas;
mergedPosDeltas.insert(mergedPosDeltas.end(), sourcePosDeltas.begin(), sourcePosDeltas.end());
const auto& sourceNormalDeltas = mesh.m_morphTargetVertexData.m_normalDeltas;
auto& mergedNormalDeltas = mergedMesh.m_morphTargetVertexData.m_normalDeltas;
mergedNormalDeltas.insert(mergedNormalDeltas.end(), sourceNormalDeltas.begin(), sourceNormalDeltas.end());
const auto& sourceMorphTargetData = mesh.m_morphTargetVertexData;
auto& mergedMorphTargetData = mergedMesh.m_morphTargetVertexData;
mergedMorphTargetData.insert(mergedMorphTargetData.end(), sourceMorphTargetData.begin(), sourceMorphTargetData.end());
}
}
return mergedMesh;
}
template<typename T>
bool ModelAssetBuilderComponent::BuildStructuredStreamBuffer(
AZStd::vector<ModelLodAsset::Mesh::StreamBufferInfo>& outStreamBuffers,
const AZStd::vector<T>& bufferData,
const RHI::ShaderSemantic& semantic,
const AZ::Name& customStreamName)
{
AZStd::string bufferName = semantic.ToString();
size_t elementCount = bufferData.size();
size_t elementSize = sizeof(T);
Outcome<Data::Asset<BufferAsset>> bufferOutcome = CreateStructuredBufferAsset(bufferData.data(), elementCount, elementSize, bufferName);
if (!bufferOutcome.IsSuccess())
{
AZ_Error(s_builderName, false, "Failed to build %s stream", semantic.ToString().data());
return false;
}
outStreamBuffers.push_back({ semantic, customStreamName, {bufferOutcome.GetValue(), bufferOutcome.GetValue()->GetBufferViewDescriptor()} });
return true;
};
template<typename T>
bool ModelAssetBuilderComponent::BuildRawStreamBuffer(
AZStd::vector<ModelLodAsset::Mesh::StreamBufferInfo>& outStreamBuffers,
@@ -1468,7 +1473,7 @@ namespace AZ
};
template<typename T>
bool ModelAssetBuilderComponent::BuildStreamBuffer(
bool ModelAssetBuilderComponent::BuildTypedStreamBuffer(
AZStd::vector<ModelLodAsset::Mesh::StreamBufferInfo>& outStreamBuffers,
const AZStd::vector<T>& bufferData,
AZ::RHI::Format format,
@@ -1546,19 +1551,19 @@ namespace AZ
}
// Build various stream buffers ...
if (!BuildStreamBuffer<float>(outStreamBuffers, positions, PositionFormat, RHI::ShaderSemantic{"POSITION"}))
if (!BuildTypedStreamBuffer<float>(outStreamBuffers, positions, PositionFormat, RHI::ShaderSemantic{"POSITION"}))
{
return false;
}
if (!BuildStreamBuffer<float>(outStreamBuffers, normals, NormalFormat, RHI::ShaderSemantic{"NORMAL"}))
if (!BuildTypedStreamBuffer<float>(outStreamBuffers, normals, NormalFormat, RHI::ShaderSemantic{"NORMAL"}))
{
return false;
}
if (!tangents.empty())
{
if (!BuildStreamBuffer<float>(outStreamBuffers, tangents, TangentFormat, RHI::ShaderSemantic{"TANGENT"}))
if (!BuildTypedStreamBuffer<float>(outStreamBuffers, tangents, TangentFormat, RHI::ShaderSemantic{"TANGENT"}))
{
return false;
}
@@ -1566,7 +1571,7 @@ namespace AZ
if (!bitangents.empty())
{
if (!BuildStreamBuffer<float>(outStreamBuffers, bitangents, BitangentFormat, RHI::ShaderSemantic{"BITANGENT"}))
if (!BuildTypedStreamBuffer<float>(outStreamBuffers, bitangents, BitangentFormat, RHI::ShaderSemantic{"BITANGENT"}))
{
return false;
}
@@ -1574,7 +1579,7 @@ namespace AZ
for (size_t i = 0; i < uvSets.size(); ++i)
{
if (!BuildStreamBuffer<float>(outStreamBuffers, uvSets[i], UVFormat, RHI::ShaderSemantic{"UV", i}, uvCustomNames[i]))
if (!BuildTypedStreamBuffer<float>(outStreamBuffers, uvSets[i], UVFormat, RHI::ShaderSemantic{"UV", i}, uvCustomNames[i]))
{
return false;
}
@@ -1582,7 +1587,7 @@ namespace AZ
for (size_t i = 0; i < colorSets.size(); ++i)
{
if (!BuildStreamBuffer<float>(outStreamBuffers, colorSets[i], ColorFormat, RHI::ShaderSemantic{"COLOR", i}, colorCustomNames[i]))
if (!BuildTypedStreamBuffer<float>(outStreamBuffers, colorSets[i], ColorFormat, RHI::ShaderSemantic{"COLOR", i}, colorCustomNames[i]))
{
return false;
}
@@ -1610,29 +1615,11 @@ namespace AZ
}
// Morph target buffers
const AZStd::vector<uint32_t>& mtVertexIndices = lodBufferContent.m_morphTargetVertexData.m_vertexIndices;
if (!mtVertexIndices.empty())
const AZStd::vector<PackedCompressedMorphTargetDelta>& morphTargetVertexDeltas = lodBufferContent.m_morphTargetVertexData;
if (!morphTargetVertexDeltas.empty())
{
// Vertex indices
const size_t numTotalVertices = mtVertexIndices.size();
if (!BuildStreamBuffer<uint32_t>(numTotalVertices, outStreamBuffers, mtVertexIndices,
MorphTargetVertexIndexFormat, RHI::ShaderSemantic{ShaderSemanticName_MorphTargetVertexIndices}))
{
return false;
}
// Position deltas
const AZStd::vector<uint16_t>& mtPositionDeltas = lodBufferContent.m_morphTargetVertexData.m_positionDeltas;
if (!BuildStreamBuffer<uint16_t>(numTotalVertices * 3, outStreamBuffers, mtPositionDeltas,
MorphTargetPositionDeltaFormat, RHI::ShaderSemantic{ShaderSemanticName_MorphTargetPositionDeltas}))
{
return false;
}
// Normal deltas
const AZStd::vector<uint8_t>& mtNormalDeltas = lodBufferContent.m_morphTargetVertexData.m_normalDeltas;
if (!BuildStreamBuffer<uint8_t>(numTotalVertices * 3, outStreamBuffers, mtNormalDeltas,
MorphTargetNormalDeltaFormat, RHI::ShaderSemantic{ShaderSemanticName_MorphTargetNormalDeltas}))
if (!BuildStructuredStreamBuffer<PackedCompressedMorphTargetDelta>(outStreamBuffers, morphTargetVertexDeltas,
RHI::ShaderSemantic{ ShaderSemanticName_MorphTargetDeltas }))
{
return false;
}
@@ -1762,22 +1749,10 @@ namespace AZ
}
// Set morph target buffers
if (meshView.m_morphTargetVertexDataView.m_vertexIndexView.m_elementCount > 0)
if (meshView.m_morphTargetVertexDataView.m_elementCount > 0)
{
if (!SetMeshStreamBufferById(RHI::ShaderSemantic{ShaderSemanticName_MorphTargetVertexIndices}, AZ::Name(),
meshView.m_morphTargetVertexDataView.m_vertexIndexView, lodStreamBuffers, lodAssetCreator))
{
return false;
}
if (!SetMeshStreamBufferById(RHI::ShaderSemantic{ShaderSemanticName_MorphTargetPositionDeltas}, AZ::Name(),
meshView.m_morphTargetVertexDataView.m_positionDeltaView, lodStreamBuffers, lodAssetCreator))
{
return false;
}
if (!SetMeshStreamBufferById(RHI::ShaderSemantic{ShaderSemanticName_MorphTargetNormalDeltas}, AZ::Name(),
meshView.m_morphTargetVertexDataView.m_normalDeltaView, lodStreamBuffers, lodAssetCreator))
if (!SetMeshStreamBufferById(RHI::ShaderSemantic{ShaderSemanticName_MorphTargetDeltas}, AZ::Name(),
meshView.m_morphTargetVertexDataView, lodStreamBuffers, lodAssetCreator))
{
return false;
}
@@ -1797,6 +1772,15 @@ namespace AZ
return CreateBufferAsset(data, bufferViewDescriptor, bufferName);
}
Outcome<Data::Asset<BufferAsset>> ModelAssetBuilderComponent::CreateStructuredBufferAsset(
const void* data, const size_t elementCount, const size_t elementSize, const AZStd::string& bufferName)
{
RHI::BufferViewDescriptor bufferViewDescriptor =
RHI::BufferViewDescriptor::CreateStructured(0, static_cast<uint32_t>(elementCount), static_cast<uint32_t>(elementSize));
return CreateBufferAsset(data, bufferViewDescriptor, bufferName);
}
Outcome<Data::Asset<BufferAsset>> ModelAssetBuilderComponent::CreateRawBufferAsset(
const void* data, const size_t totalSizeInBytes, const AZStd::string& bufferName)
{