From a8539a7b03fa389226b538e2da85f26e8144e266 Mon Sep 17 00:00:00 2001 From: sphrose <82213493+sphrose@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:35:46 +0000 Subject: [PATCH] Added default material return when no mapping is assigned. Signed-off-by: sphrose <82213493+sphrose@users.noreply.github.com> --- .../TerrainPhysicsColliderComponent.cpp | 35 +++++++++++++--- .../TerrainPhysicsColliderComponent.h | 3 +- .../Tests/TerrainPhysicsColliderTests.cpp | 40 ++++++++++++++++--- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp index 6572b008b3..1299403659 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp +++ b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.cpp @@ -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& materialList) const + { + const auto& materialIter = AZStd::find(materialList.begin(), materialList.end(), materialId); + if (materialIter != materialList.end()) + { + return static_cast(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 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 TerrainPhysicsColliderComponent::GetMaterialList() const { AZStd::vector 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; diff --git a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h index 79acca7e71..1a7fbf9c72 100644 --- a/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h +++ b/Gems/Terrain/Code/Source/Components/TerrainPhysicsColliderComponent.h @@ -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& materialList) const; + Physics::MaterialId FindMaterialIdForSurfaceTag(const SurfaceData::SurfaceTag tag) const; void GenerateHeightsInBounds(AZStd::vector& heights) const; void GenerateHeightsAndMaterialsInBounds(AZStd::vector& heightMaterials) const; diff --git a/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp b/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp index b0eb5399cf..340acfbaac 100644 --- a/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp +++ b/Gems/Terrain/Code/Tests/TerrainPhysicsColliderTests.cpp @@ -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(); + m_app.RegisterComponentDescriptor(m_boxComponent->CreateDescriptor()); + + m_colliderComponent = m_entity->CreateComponent(); + m_app.RegisterComponentDescriptor(m_colliderComponent->CreateDescriptor()); + + m_entity->Activate(); + + AZStd::vector 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();