Added default material return when no mapping is assigned.
Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com>
This commit is contained in:
@@ -284,7 +284,18 @@ namespace Terrain
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t TerrainPhysicsColliderComponent::FindSurfaceTagIndex(const SurfaceData::SurfaceTag tag) const
|
||||
uint8_t TerrainPhysicsColliderComponent::GetMaterialIdIndex(const Physics::MaterialId& materialId, const AZStd::vector<Physics::MaterialId>& materialList) const
|
||||
{
|
||||
const auto& materialIter = AZStd::find(materialList.begin(), materialList.end(), materialId);
|
||||
if (materialIter != materialList.end())
|
||||
{
|
||||
return static_cast<uint8_t>(materialIter - materialList.begin());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Physics::MaterialId TerrainPhysicsColliderComponent::FindMaterialIdForSurfaceTag(const SurfaceData::SurfaceTag tag) const
|
||||
{
|
||||
uint8_t index = 0;
|
||||
|
||||
@@ -292,12 +303,13 @@ namespace Terrain
|
||||
{
|
||||
if (mapping.m_surfaceTag == tag)
|
||||
{
|
||||
return index;
|
||||
return mapping.m_materialId;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
return InvalidSurfaceTagIndex;
|
||||
// If this surface isn't mapped, use the default material.
|
||||
return Physics::MaterialId();
|
||||
}
|
||||
|
||||
void TerrainPhysicsColliderComponent::GenerateHeightsAndMaterialsInBounds(
|
||||
@@ -317,6 +329,8 @@ namespace Terrain
|
||||
heightMaterials.clear();
|
||||
heightMaterials.reserve(gridWidth * gridHeight);
|
||||
|
||||
AZStd::vector<Physics::MaterialId> materialList = GetMaterialList();
|
||||
|
||||
for (int32_t row = 0; row < gridHeight; row++)
|
||||
{
|
||||
const float y = row * gridResolution.GetY() + worldSize.GetMin().GetY();
|
||||
@@ -346,7 +360,10 @@ namespace Terrain
|
||||
Physics::HeightMaterialPoint point;
|
||||
point.m_height = height - worldCenterZ;
|
||||
point.m_quadMeshType = terrainExists ? Physics::QuadMeshType::SubdivideUpperLeftToBottomRight : Physics::QuadMeshType::Hole;
|
||||
point.m_materialIndex = FindSurfaceTagIndex(surfaceWeight.m_surfaceType);
|
||||
|
||||
Physics::MaterialId materialId = FindMaterialIdForSurfaceTag(surfaceWeight.m_surfaceType);
|
||||
point.m_materialIndex = GetMaterialIdIndex(materialId, materialList);
|
||||
|
||||
heightMaterials.emplace_back(point);
|
||||
}
|
||||
}
|
||||
@@ -391,11 +408,17 @@ namespace Terrain
|
||||
AZStd::vector<Physics::MaterialId> TerrainPhysicsColliderComponent::GetMaterialList() const
|
||||
{
|
||||
AZStd::vector<Physics::MaterialId> materialList;
|
||||
materialList.reserve(m_configuration.m_surfaceMaterialMappings.size());
|
||||
|
||||
// Ensure the list contains the default material as the first entry.
|
||||
materialList.emplace_back(Physics::MaterialId());
|
||||
|
||||
for (auto& mapping : m_configuration.m_surfaceMaterialMappings)
|
||||
{
|
||||
materialList.emplace_back(mapping.m_materialId);
|
||||
const auto& existingInstance = AZStd::find(materialList.begin(), materialList.end(), mapping.m_materialId);
|
||||
if (existingInstance == materialList.end())
|
||||
{
|
||||
materialList.emplace_back(mapping.m_materialId);
|
||||
}
|
||||
}
|
||||
|
||||
return materialList;
|
||||
|
||||
@@ -92,7 +92,8 @@ namespace Terrain
|
||||
bool ReadInConfig(const AZ::ComponentConfig* baseConfig) override;
|
||||
bool WriteOutConfig(AZ::ComponentConfig* outBaseConfig) const override;
|
||||
|
||||
uint8_t FindSurfaceTagIndex(const SurfaceData::SurfaceTag tag) const;
|
||||
uint8_t GetMaterialIdIndex(const Physics::MaterialId& materialId, const AZStd::vector<Physics::MaterialId>& materialList) const;
|
||||
Physics::MaterialId FindMaterialIdForSurfaceTag(const SurfaceData::SurfaceTag tag) const;
|
||||
|
||||
void GenerateHeightsInBounds(AZStd::vector<float>& heights) const;
|
||||
void GenerateHeightsAndMaterialsInBounds(AZStd::vector<Physics::HeightMaterialPoint>& heightMaterials) const;
|
||||
|
||||
@@ -327,10 +327,39 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsMateria
|
||||
Physics::HeightfieldProviderRequestsBus::EventResult(
|
||||
materialList, m_entity->GetId(), &Physics::HeightfieldProviderRequestsBus::Events::GetMaterialList);
|
||||
|
||||
EXPECT_EQ(materialList.size(), 2);
|
||||
// The materialList should be 3 items long: the two materials we've added, plus a default material.
|
||||
EXPECT_EQ(materialList.size(), 3);
|
||||
|
||||
EXPECT_EQ(materialList[0], mat1);
|
||||
EXPECT_EQ(materialList[1], mat2);
|
||||
Physics::MaterialId defaultMaterial = Physics::MaterialId();
|
||||
EXPECT_EQ(materialList[0], defaultMaterial);
|
||||
EXPECT_EQ(materialList[1], mat1);
|
||||
EXPECT_EQ(materialList[2], mat2);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsMaterialsWhenNotMapped)
|
||||
{
|
||||
// Check that the TerrainPhysicsCollider returns a default material when no surfaces are mapped.
|
||||
CreateEntity();
|
||||
|
||||
m_boxComponent = m_entity->CreateComponent<UnitTest::MockAxisAlignedBoxShapeComponent>();
|
||||
m_app.RegisterComponentDescriptor(m_boxComponent->CreateDescriptor());
|
||||
|
||||
m_colliderComponent = m_entity->CreateComponent<Terrain::TerrainPhysicsColliderComponent>();
|
||||
m_app.RegisterComponentDescriptor(m_colliderComponent->CreateDescriptor());
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
AZStd::vector<Physics::MaterialId> materialList;
|
||||
Physics::HeightfieldProviderRequestsBus::EventResult(
|
||||
materialList, m_entity->GetId(), &Physics::HeightfieldProviderRequestsBus::Events::GetMaterialList);
|
||||
|
||||
// The materialList should be 1 items long: which should be the default material.
|
||||
EXPECT_EQ(materialList.size(), 1);
|
||||
|
||||
Physics::MaterialId defaultMaterial = Physics::MaterialId();
|
||||
EXPECT_EQ(materialList[0], defaultMaterial);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
@@ -412,12 +441,13 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsAndM
|
||||
|
||||
const float expectedHeightValue = 16384.0f;
|
||||
|
||||
//
|
||||
// Check an entry from the first half of the returned list.
|
||||
EXPECT_EQ(heightsAndMaterials[0].m_materialIndex, 0);
|
||||
EXPECT_EQ(heightsAndMaterials[0].m_materialIndex, 1);
|
||||
EXPECT_NEAR(heightsAndMaterials[0].m_height, expectedHeightValue, 0.01f);
|
||||
|
||||
// Check an entry from the second half of the list
|
||||
EXPECT_EQ(heightsAndMaterials[256 * 128].m_materialIndex, 1);
|
||||
EXPECT_EQ(heightsAndMaterials[256 * 128].m_materialIndex, 2);
|
||||
EXPECT_NEAR(heightsAndMaterials[256 * 128].m_height, expectedHeightValue, 0.01f);
|
||||
|
||||
m_entity.reset();
|
||||
|
||||
Reference in New Issue
Block a user