Fixed cloth simulation generating incorrect normals
Fixed cloth simulation generating incorrect normals. Also added option in Cloth Component to update normals of static particles (disabled by default). User will want to keep the option disabled when continuity of the normals is important, like in characters, but for environmental cloth the mesh could look better when the normals of static particles are updated too. Enable 'Update normals of static particles' option on blind slices of Nvcloth gem Fix unit tests
This commit is contained in:
@@ -39,13 +39,13 @@
|
||||
<Class name="Vector3" field="Scale" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
|
||||
<Class name="bool" field="Locked" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
<Class name="bool" field="AddNonUniformScaleButton" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="Transform" field="Cached World Transform" value="0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 1.0000000 1.0000000 0.0000000 0.0000000 0.0000000" version="1" type="{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}"/>
|
||||
<Class name="EntityId" field="Cached World Transform Parent" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
|
||||
<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="Parent Activation Transform Mode" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="IsStatic" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="Sync Enabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="unsigned int" field="InterpolatePosition" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="InterpolateRotation" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
@@ -188,6 +188,7 @@
|
||||
<Class name="float" field="Solver Frequency" value="300.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned int" field="Acceleration Filter Iterations" value="30" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="Remove Static Triangles" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="Update Normals of Static Particles" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZ::Render::EditorMeshComponent" field="element" version="2" type="{DCE68F6E-2E16-4CB4-A834-B6C2F900A7E9}">
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
<Class name="Vector3" field="Scale" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
|
||||
<Class name="bool" field="Locked" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
<Class name="bool" field="AddNonUniformScaleButton" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="Transform" field="Cached World Transform" value="0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 1.0000000 1.0000000 0.0000000 0.0000000 0.0000000" version="1" type="{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}"/>
|
||||
<Class name="EntityId" field="Cached World Transform Parent" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
|
||||
<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="Parent Activation Transform Mode" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="IsStatic" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="Sync Enabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="unsigned int" field="InterpolatePosition" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="InterpolateRotation" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
@@ -188,6 +188,7 @@
|
||||
<Class name="float" field="Solver Frequency" value="300.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned int" field="Acceleration Filter Iterations" value="30" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="Remove Static Triangles" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="Update Normals of Static Particles" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZ::Render::EditorMeshComponent" field="element" version="2" type="{DCE68F6E-2E16-4CB4-A834-B6C2F900A7E9}">
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
<Class name="Vector3" field="Scale" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
|
||||
<Class name="bool" field="Locked" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
<Class name="bool" field="AddNonUniformScaleButton" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="Transform" field="Cached World Transform" value="0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 1.0000000 1.0000000 0.0000000 0.0000000 0.0000000" version="1" type="{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}"/>
|
||||
<Class name="EntityId" field="Cached World Transform Parent" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
|
||||
<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="Parent Activation Transform Mode" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="IsStatic" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="Sync Enabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="unsigned int" field="InterpolatePosition" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="InterpolateRotation" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
@@ -188,6 +188,7 @@
|
||||
<Class name="float" field="Solver Frequency" value="0.1000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned int" field="Acceleration Filter Iterations" value="30" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="Remove Static Triangles" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="Update Normals of Static Particles" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZ::Render::EditorMeshComponent" field="element" version="2" type="{DCE68F6E-2E16-4CB4-A834-B6C2F900A7E9}">
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
<Class name="Vector3" field="Scale" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
|
||||
<Class name="bool" field="Locked" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
<Class name="bool" field="AddNonUniformScaleButton" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="Transform" field="Cached World Transform" value="0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 1.0000000 1.0000000 0.0000000 0.0000000 0.0000000" version="1" type="{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}"/>
|
||||
<Class name="EntityId" field="Cached World Transform Parent" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
|
||||
<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="Parent Activation Transform Mode" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="IsStatic" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="Sync Enabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="unsigned int" field="InterpolatePosition" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="InterpolateRotation" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
@@ -188,6 +188,7 @@
|
||||
<Class name="float" field="Solver Frequency" value="0.5000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned int" field="Acceleration Filter Iterations" value="30" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="Remove Static Triangles" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="Update Normals of Static Particles" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZ::Render::EditorMeshComponent" field="element" version="2" type="{DCE68F6E-2E16-4CB4-A834-B6C2F900A7E9}">
|
||||
|
||||
@@ -39,13 +39,13 @@
|
||||
<Class name="Vector3" field="Scale" value="1.0000000 1.0000000 1.0000000" type="{8379EB7D-01FA-4538-B64B-A6543B4BE73D}"/>
|
||||
<Class name="bool" field="Locked" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
<Class name="bool" field="AddNonUniformScaleButton" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="Transform" field="Cached World Transform" value="0.0000000 0.0000000 0.0000000 1.0000000 1.0000000 1.0000000 1.0000000 0.0000000 0.0000000 0.0000000" version="1" type="{5D9958E9-9F1E-4985-B532-FFFDE75FEDFD}"/>
|
||||
<Class name="EntityId" field="Cached World Transform Parent" version="1" type="{6383F1D3-BB27-4E6B-A49A-6409B2059EAA}">
|
||||
<Class name="AZ::u64" field="id" value="4294967295" type="{D6597933-47CD-4FC8-B911-63F3E2B0993A}"/>
|
||||
</Class>
|
||||
<Class name="unsigned int" field="Parent Activation Transform Mode" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="IsStatic" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="Sync Enabled" value="false" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="unsigned int" field="InterpolatePosition" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="unsigned int" field="InterpolateRotation" value="0" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
</Class>
|
||||
@@ -188,6 +188,7 @@
|
||||
<Class name="float" field="Solver Frequency" value="300.0000000" type="{EA2C3E90-AFBE-44D4-A90D-FAAF79BAF93D}"/>
|
||||
<Class name="unsigned int" field="Acceleration Filter Iterations" value="30" type="{43DA906B-7DEF-4CA8-9790-854106D3F983}"/>
|
||||
<Class name="bool" field="Remove Static Triangles" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
<Class name="bool" field="Update Normals of Static Particles" value="true" type="{A0CA880C-AFE4-43CB-926C-59AC48496112}"/>
|
||||
</Class>
|
||||
</Class>
|
||||
<Class name="AZ::Render::EditorMeshComponent" field="element" version="2" type="{DCE68F6E-2E16-4CB4-A834-B6C2F900A7E9}">
|
||||
|
||||
@@ -430,10 +430,12 @@ namespace NvCloth
|
||||
AZStd::unique_ptr<ActorClothSkinning> ActorClothSkinning::Create(
|
||||
AZ::EntityId entityId,
|
||||
const MeshNodeInfo& meshNodeInfo,
|
||||
const size_t numVertices,
|
||||
const AZStd::vector<SimParticleFormat>& originalMeshParticles,
|
||||
const size_t numSimulatedVertices,
|
||||
const AZStd::vector<int>& meshRemappedVertices)
|
||||
{
|
||||
const size_t numVertices = originalMeshParticles.size();
|
||||
|
||||
AZStd::vector<SkinningInfluence> skinningInfluences;
|
||||
if (!Internal::ObtainSkinningInfluences(entityId, meshNodeInfo, numVertices, skinningInfluences))
|
||||
{
|
||||
@@ -480,11 +482,14 @@ namespace NvCloth
|
||||
for (size_t vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex)
|
||||
{
|
||||
const int remappedIndex = meshRemappedVertices[vertexIndex];
|
||||
|
||||
if (remappedIndex >= 0)
|
||||
{
|
||||
actorClothSkinning->m_simulatedVertices[remappedIndex] = vertexIndex;
|
||||
}
|
||||
else
|
||||
|
||||
if (remappedIndex < 0 ||
|
||||
originalMeshParticles[vertexIndex].GetW() == 0.0f)
|
||||
{
|
||||
actorClothSkinning->m_nonSimulatedVertices.emplace_back(vertexIndex);
|
||||
}
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
|
||||
namespace NvCloth
|
||||
{
|
||||
struct MeshNodeInfo;
|
||||
|
||||
//! One skinning influence of a vertex.
|
||||
struct SkinningInfluence
|
||||
{
|
||||
@@ -45,7 +43,7 @@ namespace NvCloth
|
||||
static AZStd::unique_ptr<ActorClothSkinning> Create(
|
||||
AZ::EntityId entityId,
|
||||
const MeshNodeInfo& meshNodeInfo,
|
||||
const size_t numVertices,
|
||||
const AZStd::vector<SimParticleFormat>& originalMeshParticles,
|
||||
const size_t numSimulatedVertices,
|
||||
const AZStd::vector<int>& meshRemappedVertices);
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace NvCloth
|
||||
m_actorClothSkinning = ActorClothSkinning::Create(
|
||||
m_entityId,
|
||||
m_meshNodeInfo,
|
||||
m_meshClothInfo.m_particles.size(),
|
||||
m_meshClothInfo.m_particles,
|
||||
m_cloth->GetParticles().size(),
|
||||
m_meshRemappedVertices);
|
||||
m_numberOfClothSkinningUpdates = 0;
|
||||
@@ -406,7 +406,7 @@ namespace NvCloth
|
||||
|
||||
auto& renderData = GetRenderData();
|
||||
|
||||
if (m_config.m_removeStaticTriangles && m_actorClothSkinning)
|
||||
if (m_actorClothSkinning)
|
||||
{
|
||||
// Apply skinning to the non-simulated part of the mesh.
|
||||
m_actorClothSkinning->ApplySkinningOnNonSimulatedVertices(m_meshClothInfo, renderData);
|
||||
@@ -427,7 +427,15 @@ namespace NvCloth
|
||||
if (remappedIndex >= 0)
|
||||
{
|
||||
renderData.m_particles[index] = particles[remappedIndex];
|
||||
renderData.m_normals[index] = normals[remappedIndex];
|
||||
|
||||
// For static particles only use the updated normal when indicated in the configuration.
|
||||
const bool useSimulatedClothParticleNormal =
|
||||
m_meshClothInfo.m_particles[index].GetW() != 0.0f ||
|
||||
m_config.m_updateNormalsOfStaticParticles;
|
||||
if (useSimulatedClothParticleNormal)
|
||||
{
|
||||
renderData.m_normals[index] = normals[remappedIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ namespace NvCloth
|
||||
->Field("Solver Frequency", &ClothConfiguration::m_solverFrequency)
|
||||
->Field("Acceleration Filter Iterations", &ClothConfiguration::m_accelerationFilterIterations)
|
||||
->Field("Remove Static Triangles", &ClothConfiguration::m_removeStaticTriangles)
|
||||
->Field("Update Normals of Static Particles", &ClothConfiguration::m_updateNormalsOfStaticParticles)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,7 @@ namespace NvCloth
|
||||
float m_solverFrequency = 300.0f;
|
||||
uint32_t m_accelerationFilterIterations = 30;
|
||||
bool m_removeStaticTriangles = true;
|
||||
bool m_updateNormalsOfStaticParticles = false;
|
||||
|
||||
// Fabric phases parameters
|
||||
float m_horizontalStiffness = 1.0f;
|
||||
|
||||
@@ -374,12 +374,15 @@ namespace NvCloth
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ClothConfiguration::m_solverFrequency, "Solver frequency",
|
||||
"Target solver iterations per second. At least 1 iteration per frame will be solved regardless of the value set.")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 0.0f)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ClothConfiguration::m_accelerationFilterIterations, "Acceleration filter Iterations",
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ClothConfiguration::m_accelerationFilterIterations, "Acceleration filter iterations",
|
||||
"Number of iterations to average delta time factor used for gravity and external acceleration.")
|
||||
->Attribute(AZ::Edit::Attributes::Min, 1)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ClothConfiguration::m_removeStaticTriangles, "Remove static triangles",
|
||||
"Removing static triangles improves performance by not taking into account triangles whose particles are all static.\n"
|
||||
"The removed static particles will not be present for collision or self collision during simulation.")
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &ClothConfiguration::m_updateNormalsOfStaticParticles, "Update normals of static particles",
|
||||
"When enabled the normals of static particles will be updated according with the movement of the simulated mesh.\n"
|
||||
"When disabled the static particles will keep the same normals as the original mesh.")
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +172,7 @@ namespace NvCloth
|
||||
meshClothInfo.m_uvs.reserve(numTotalVertices);
|
||||
meshClothInfo.m_motionConstraints.reserve(numTotalVertices);
|
||||
meshClothInfo.m_backstopData.reserve(numTotalVertices);
|
||||
meshClothInfo.m_normals.reserve(numTotalVertices);
|
||||
meshClothInfo.m_indices.reserve(numTotalIndices);
|
||||
|
||||
struct Vec2
|
||||
@@ -192,10 +193,15 @@ namespace NvCloth
|
||||
{
|
||||
const auto sourceIndices = mesh->GetIndexBufferTyped<uint32_t>();
|
||||
const auto sourcePositions = mesh->GetSemanticBufferTyped<Vec3>(AZ::Name("POSITION"));
|
||||
const auto sourceNormals = mesh->GetSemanticBufferTyped<Vec3>(AZ::Name("NORMAL"));
|
||||
const auto sourceClothData = mesh->GetSemanticBufferTyped<Vec4>(AZ::Name("CLOTH_DATA"));
|
||||
const auto sourceUVs = mesh->GetSemanticBufferTyped<Vec2>(AZ::Name("UV"));
|
||||
|
||||
if (sourceIndices.empty() || sourcePositions.empty() || sourceClothData.empty())
|
||||
if (sourceIndices.empty() ||
|
||||
sourcePositions.empty() ||
|
||||
sourceNormals.empty() ||
|
||||
sourceClothData.empty() ||
|
||||
sourceUVs.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -214,6 +220,11 @@ namespace NvCloth
|
||||
sourcePositions[index].z,
|
||||
inverseMass);
|
||||
|
||||
meshClothInfo.m_normals.emplace_back(
|
||||
sourceNormals[index].x,
|
||||
sourceNormals[index].y,
|
||||
sourceNormals[index].z);
|
||||
|
||||
meshClothInfo.m_motionConstraints.emplace_back(motionConstraint);
|
||||
meshClothInfo.m_backstopData.emplace_back(backstopOffset, backstopRadius);
|
||||
|
||||
@@ -226,12 +237,12 @@ namespace NvCloth
|
||||
meshClothInfo.m_indices.insert(meshClothInfo.m_indices.end(), sourceIndices.begin(), sourceIndices.end());
|
||||
}
|
||||
|
||||
// Calculate tangent space for the mesh.
|
||||
[[maybe_unused]] bool tangentSpaceCalculated =
|
||||
AZ::Interface<ITangentSpaceHelper>::Get()->CalculateTangentSpace(
|
||||
meshClothInfo.m_particles, meshClothInfo.m_indices, meshClothInfo.m_uvs,
|
||||
meshClothInfo.m_tangents, meshClothInfo.m_bitangents, meshClothInfo.m_normals);
|
||||
AZ_Assert(tangentSpaceCalculated, "Failed to calculate tangent space.");
|
||||
// Calculate tangents and bitangents for the whole mesh
|
||||
[[maybe_unused]] bool tangentsAndBitangentsCalculated =
|
||||
AZ::Interface<ITangentSpaceHelper>::Get()->CalculateTangentsAndBitagents(
|
||||
meshClothInfo.m_particles, meshClothInfo.m_indices, meshClothInfo.m_uvs, meshClothInfo.m_normals,
|
||||
meshClothInfo.m_tangents, meshClothInfo.m_bitangents);
|
||||
AZ_Assert(tangentsAndBitangentsCalculated, "Failed to calculate tangents and bitangents.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,12 @@ namespace UnitTest
|
||||
AZ::Vector3(1.0f, 0.0f, 0.0f),
|
||||
AZ::Vector3(0.0f, 1.0f, 0.0f)
|
||||
}};
|
||||
|
||||
const AZStd::vector<NvCloth::SimParticleFormat> MeshParticles = {{
|
||||
NvCloth::SimParticleFormat::CreateFromVector3AndFloat(MeshVertices[0], 1.0f),
|
||||
NvCloth::SimParticleFormat::CreateFromVector3AndFloat(MeshVertices[1], 1.0f),
|
||||
NvCloth::SimParticleFormat::CreateFromVector3AndFloat(MeshVertices[2], 1.0f),
|
||||
}};
|
||||
|
||||
const AZStd::vector<NvCloth::SimIndexType> MeshIndices = {{
|
||||
0, 1, 2
|
||||
@@ -98,7 +104,7 @@ namespace UnitTest
|
||||
{
|
||||
AZ::EntityId entityId;
|
||||
AZStd::unique_ptr<NvCloth::ActorClothSkinning> actorClothSkinning =
|
||||
NvCloth::ActorClothSkinning::Create(entityId, {}, 0, 0, {});
|
||||
NvCloth::ActorClothSkinning::Create(entityId, {}, {}, 0, {});
|
||||
|
||||
EXPECT_TRUE(actorClothSkinning.get() == nullptr);
|
||||
}
|
||||
@@ -107,7 +113,7 @@ namespace UnitTest
|
||||
{
|
||||
AZ::EntityId entityId;
|
||||
AZStd::unique_ptr<NvCloth::ActorClothSkinning> actorClothSkinning =
|
||||
NvCloth::ActorClothSkinning::Create(entityId, MeshNodeInfo, MeshVertices.size(), MeshVertices.size(), MeshRemappedVertices);
|
||||
NvCloth::ActorClothSkinning::Create(entityId, MeshNodeInfo, MeshParticles, MeshParticles.size(), MeshRemappedVertices);
|
||||
|
||||
EXPECT_TRUE(actorClothSkinning.get() == nullptr);
|
||||
}
|
||||
@@ -122,7 +128,7 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<NvCloth::ActorClothSkinning> actorClothSkinning =
|
||||
NvCloth::ActorClothSkinning::Create(m_actorComponent->GetEntityId(), {}, 0, 0, {});
|
||||
NvCloth::ActorClothSkinning::Create(m_actorComponent->GetEntityId(), {}, {}, 0, {});
|
||||
|
||||
EXPECT_TRUE(actorClothSkinning.get() == nullptr);
|
||||
}
|
||||
@@ -139,7 +145,7 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<NvCloth::ActorClothSkinning> actorClothSkinning =
|
||||
NvCloth::ActorClothSkinning::Create(m_actorComponent->GetEntityId(), MeshNodeInfo, MeshVertices.size(), MeshVertices.size(), MeshRemappedVertices);
|
||||
NvCloth::ActorClothSkinning::Create(m_actorComponent->GetEntityId(), MeshNodeInfo, MeshParticles, MeshParticles.size(), MeshRemappedVertices);
|
||||
|
||||
EXPECT_TRUE(actorClothSkinning.get() == nullptr);
|
||||
}
|
||||
@@ -156,7 +162,7 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<NvCloth::ActorClothSkinning> actorClothSkinning =
|
||||
NvCloth::ActorClothSkinning::Create(m_actorComponent->GetEntityId(), MeshNodeInfo, MeshVertices.size(), MeshVertices.size(), MeshRemappedVertices);
|
||||
NvCloth::ActorClothSkinning::Create(m_actorComponent->GetEntityId(), MeshNodeInfo, MeshParticles, MeshParticles.size(), MeshRemappedVertices);
|
||||
|
||||
EXPECT_TRUE(actorClothSkinning.get() != nullptr);
|
||||
}
|
||||
@@ -184,20 +190,15 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<NvCloth::ActorClothSkinning> actorClothSkinning =
|
||||
NvCloth::ActorClothSkinning::Create(actorComponent->GetEntityId(), MeshNodeInfo, MeshVertices.size(), MeshVertices.size(), MeshRemappedVertices);
|
||||
NvCloth::ActorClothSkinning::Create(actorComponent->GetEntityId(), MeshNodeInfo, MeshParticles, MeshParticles.size(), MeshRemappedVertices);
|
||||
ASSERT_TRUE(actorClothSkinning.get() != nullptr);
|
||||
|
||||
const AZStd::vector<NvCloth::SimParticleFormat> clothParticles = {{
|
||||
NvCloth::SimParticleFormat::CreateFromVector3AndFloat(MeshVertices[0], 1.0f),
|
||||
NvCloth::SimParticleFormat::CreateFromVector3AndFloat(MeshVertices[1], 1.0f),
|
||||
NvCloth::SimParticleFormat::CreateFromVector3AndFloat(MeshVertices[2], 1.0f),
|
||||
}};
|
||||
AZStd::vector<NvCloth::SimParticleFormat> skinnedClothParticles(clothParticles.size(), NvCloth::SimParticleFormat(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
AZStd::vector<NvCloth::SimParticleFormat> skinnedClothParticles(MeshParticles.size(), NvCloth::SimParticleFormat(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
actorClothSkinning->UpdateSkinning();
|
||||
actorClothSkinning->ApplySkinning(clothParticles, skinnedClothParticles);
|
||||
actorClothSkinning->ApplySkinning(MeshParticles, skinnedClothParticles);
|
||||
|
||||
EXPECT_THAT(skinnedClothParticles, ::testing::Pointwise(ContainerIsCloseTolerance(Tolerance), clothParticles));
|
||||
EXPECT_THAT(skinnedClothParticles, ::testing::Pointwise(ContainerIsCloseTolerance(Tolerance), MeshParticles));
|
||||
|
||||
// Update actor instance's joints transforms
|
||||
const AZ::Transform newMeshNodeTransform = AZ::Transform::CreateRotationY(AZ::DegToRad(180.0f));
|
||||
@@ -205,10 +206,10 @@ namespace UnitTest
|
||||
currentPose->SetLocalSpaceTransform(0, newMeshNodeTransform);
|
||||
actorComponent->GetActorInstance()->UpdateSkinningMatrices();
|
||||
|
||||
AZStd::vector<NvCloth::SimParticleFormat> newSkinnedClothParticles(clothParticles.size(), NvCloth::SimParticleFormat(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
AZStd::vector<NvCloth::SimParticleFormat> newSkinnedClothParticles(MeshParticles.size(), NvCloth::SimParticleFormat(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
actorClothSkinning->UpdateSkinning();
|
||||
actorClothSkinning->ApplySkinning(clothParticles, newSkinnedClothParticles);
|
||||
actorClothSkinning->ApplySkinning(MeshParticles, newSkinnedClothParticles);
|
||||
|
||||
const AZ::Transform diffTransform = AZ::Transform::CreateRotationY(AZ::DegToRad(90.0f));
|
||||
const AZStd::vector<NvCloth::SimParticleFormat> clothParticlesResult = {{
|
||||
@@ -245,20 +246,15 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<NvCloth::ActorClothSkinning> actorClothSkinning =
|
||||
NvCloth::ActorClothSkinning::Create(m_actorComponent->GetEntityId(), MeshNodeInfo, MeshVertices.size(), MeshVertices.size(), MeshRemappedVertices);
|
||||
NvCloth::ActorClothSkinning::Create(m_actorComponent->GetEntityId(), MeshNodeInfo, MeshParticles, MeshParticles.size(), MeshRemappedVertices);
|
||||
ASSERT_TRUE(actorClothSkinning.get() != nullptr);
|
||||
|
||||
const AZStd::vector<NvCloth::SimParticleFormat> clothParticles = {{
|
||||
NvCloth::SimParticleFormat::CreateFromVector3AndFloat(MeshVertices[0], 1.0f),
|
||||
NvCloth::SimParticleFormat::CreateFromVector3AndFloat(MeshVertices[1], 1.0f),
|
||||
NvCloth::SimParticleFormat::CreateFromVector3AndFloat(MeshVertices[2], 1.0f),
|
||||
}};
|
||||
AZStd::vector<NvCloth::SimParticleFormat> skinnedClothParticles(clothParticles.size(), NvCloth::SimParticleFormat(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
AZStd::vector<NvCloth::SimParticleFormat> skinnedClothParticles(MeshParticles.size(), NvCloth::SimParticleFormat(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
actorClothSkinning->UpdateSkinning();
|
||||
actorClothSkinning->ApplySkinning(clothParticles, skinnedClothParticles);
|
||||
actorClothSkinning->ApplySkinning(MeshParticles, skinnedClothParticles);
|
||||
|
||||
EXPECT_THAT(skinnedClothParticles, ::testing::Pointwise(ContainerIsCloseTolerance(Tolerance), clothParticles));
|
||||
EXPECT_THAT(skinnedClothParticles, ::testing::Pointwise(ContainerIsCloseTolerance(Tolerance), MeshParticles));
|
||||
|
||||
// Update actor instance's joints transforms
|
||||
const AZ::Transform newJointRootTransform = AZ::Transform::CreateFromQuaternionAndTranslation(AZ::Quaternion::CreateRotationZ(AZ::DegToRad(-32.0f)), AZ::Vector3(2.5f, -6.0f, 0.2f));
|
||||
@@ -268,10 +264,10 @@ namespace UnitTest
|
||||
currentPose->SetLocalSpaceTransform(1, newJointChildTransform);
|
||||
m_actorComponent->GetActorInstance()->UpdateSkinningMatrices();
|
||||
|
||||
AZStd::vector<NvCloth::SimParticleFormat> newSkinnedClothParticles(clothParticles.size(), NvCloth::SimParticleFormat(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
AZStd::vector<NvCloth::SimParticleFormat> newSkinnedClothParticles(MeshParticles.size(), NvCloth::SimParticleFormat(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
actorClothSkinning->UpdateSkinning();
|
||||
actorClothSkinning->ApplySkinning(clothParticles, newSkinnedClothParticles);
|
||||
actorClothSkinning->ApplySkinning(MeshParticles, newSkinnedClothParticles);
|
||||
|
||||
const AZStd::vector<NvCloth::SimParticleFormat> clothParticlesResult = {{
|
||||
NvCloth::SimParticleFormat(-48.4177f, -31.9446f, 45.2279f, 1.0f),
|
||||
@@ -294,7 +290,7 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
AZStd::unique_ptr<NvCloth::ActorClothSkinning> actorClothSkinning =
|
||||
NvCloth::ActorClothSkinning::Create(m_actorComponent->GetEntityId(), MeshNodeInfo, MeshVertices.size(), MeshVertices.size(), MeshRemappedVertices);
|
||||
NvCloth::ActorClothSkinning::Create(m_actorComponent->GetEntityId(), MeshNodeInfo, MeshParticles, MeshParticles.size(), MeshRemappedVertices);
|
||||
ASSERT_TRUE(actorClothSkinning.get() != nullptr);
|
||||
|
||||
EXPECT_FALSE(actorClothSkinning->IsActorVisible());
|
||||
|
||||
Reference in New Issue
Block a user