Merge pull request #7171 from aws-lumberyard-dev/TerrainMaterialsFix
LYN-7637 Allow Terrain Physics Collider to assign a default physics material
This commit is contained in:
@@ -72,8 +72,9 @@ namespace Terrain
|
||||
if (auto serialize = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serialize->Class<TerrainPhysicsColliderConfig, AZ::ComponentConfig>()
|
||||
->Version(2)->Field(
|
||||
"Mappings", &TerrainPhysicsColliderConfig::m_surfaceMaterialMappings)
|
||||
->Version(3)
|
||||
->Field("DefaultMaterial", &TerrainPhysicsColliderConfig::m_defaultMaterialSelection)
|
||||
->Field("Mappings", &TerrainPhysicsColliderConfig::m_surfaceMaterialMappings)
|
||||
;
|
||||
|
||||
if (auto edit = serialize->GetEditContext())
|
||||
@@ -84,6 +85,8 @@ namespace Terrain
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly)
|
||||
->Attribute(AZ::Edit::Attributes::AutoExpand, true)
|
||||
->DataElement(AZ::Edit::UIHandlers::Default, &TerrainPhysicsColliderConfig::m_defaultMaterialSelection,
|
||||
"Default Surface Physics Material", "Select a material to be used by unmapped surfaces by default")
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::Default, &TerrainPhysicsColliderConfig::m_surfaceMaterialMappings,
|
||||
"Surface to Material Mappings", "Maps surfaces to physics materials")
|
||||
@@ -321,7 +324,7 @@ namespace Terrain
|
||||
}
|
||||
|
||||
// If this surface isn't mapped, use the default material.
|
||||
return Physics::MaterialId();
|
||||
return m_configuration.m_defaultMaterialSelection.GetMaterialId();
|
||||
}
|
||||
|
||||
void TerrainPhysicsColliderComponent::GenerateHeightsAndMaterialsInBounds(
|
||||
@@ -419,7 +422,7 @@ namespace Terrain
|
||||
AZStd::vector<Physics::MaterialId> materialList;
|
||||
|
||||
// Ensure the list contains the default material as the first entry.
|
||||
materialList.emplace_back(Physics::MaterialId());
|
||||
materialList.emplace_back(m_configuration.m_defaultMaterialSelection.GetMaterialId());
|
||||
|
||||
for (auto& mapping : m_configuration.m_surfaceMaterialMappings)
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Terrain
|
||||
AZ_CLASS_ALLOCATOR(TerrainPhysicsColliderConfig, AZ::SystemAllocator, 0);
|
||||
AZ_RTTI(TerrainPhysicsColliderConfig, "{E9EADB8F-C3A5-4B9C-A62D-2DBC86B4CE59}", AZ::ComponentConfig);
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
Physics::MaterialSelection m_defaultMaterialSelection;
|
||||
AZStd::vector<TerrainPhysicsSurfaceMaterialMapping> m_surfaceMaterialMappings;
|
||||
};
|
||||
|
||||
|
||||
@@ -46,10 +46,17 @@ protected:
|
||||
appDesc.m_stackRecordLevels = 20;
|
||||
|
||||
m_app.Create(appDesc);
|
||||
|
||||
CreateEntity();
|
||||
|
||||
m_boxComponent = m_entity->CreateComponent<UnitTest::MockAxisAlignedBoxShapeComponent>();
|
||||
m_app.RegisterComponentDescriptor(m_boxComponent->CreateDescriptor());
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
m_entity.reset();
|
||||
|
||||
m_app.Destroy();
|
||||
}
|
||||
|
||||
@@ -61,12 +68,9 @@ protected:
|
||||
m_entity->Init();
|
||||
}
|
||||
|
||||
void AddTerrainPhysicsColliderAndShapeComponentToEntity()
|
||||
void AddTerrainPhysicsColliderToEntity(const Terrain::TerrainPhysicsColliderConfig& configuration)
|
||||
{
|
||||
m_boxComponent = m_entity->CreateComponent<UnitTest::MockAxisAlignedBoxShapeComponent>();
|
||||
m_app.RegisterComponentDescriptor(m_boxComponent->CreateDescriptor());
|
||||
|
||||
m_colliderComponent = m_entity->CreateComponent<Terrain::TerrainPhysicsColliderComponent>(Terrain::TerrainPhysicsColliderConfig());
|
||||
m_colliderComponent = m_entity->CreateComponent<Terrain::TerrainPhysicsColliderComponent>(configuration);
|
||||
m_app.RegisterComponentDescriptor(m_colliderComponent->CreateDescriptor());
|
||||
}
|
||||
|
||||
@@ -113,21 +117,17 @@ protected:
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, ActivateEntityActivateSuccess)
|
||||
{
|
||||
// Check that the entity activates with a collider and the required shape attached.
|
||||
CreateEntity();
|
||||
AddTerrainPhysicsColliderAndShapeComponentToEntity();
|
||||
AddTerrainPhysicsColliderToEntity(Terrain::TerrainPhysicsColliderConfig());
|
||||
|
||||
m_entity->Activate();
|
||||
EXPECT_EQ(m_entity->GetState(), AZ::Entity::State::Active);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderTransformChangedNotifiesHeightfieldBus)
|
||||
{
|
||||
// Check that the HeightfieldBus is notified when the transform of the entity changes.
|
||||
CreateEntity();
|
||||
|
||||
AddTerrainPhysicsColliderAndShapeComponentToEntity();
|
||||
AddTerrainPhysicsColliderToEntity(Terrain::TerrainPhysicsColliderConfig());
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
@@ -138,16 +138,12 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderTransformChang
|
||||
LmbrCentral::ShapeComponentNotificationsBus::Event(
|
||||
m_entity->GetId(), &LmbrCentral::ShapeComponentNotificationsBus::Events::OnShapeChanged,
|
||||
LmbrCentral::ShapeComponentNotifications::ShapeChangeReasons::TransformChanged);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderShapeChangedNotifiesHeightfieldBus)
|
||||
{
|
||||
// Check that the Heightfield bus is notified when the shape component changes.
|
||||
CreateEntity();
|
||||
|
||||
AddTerrainPhysicsColliderAndShapeComponentToEntity();
|
||||
AddTerrainPhysicsColliderToEntity(Terrain::TerrainPhysicsColliderConfig());
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
@@ -157,16 +153,12 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderShapeChangedNo
|
||||
LmbrCentral::ShapeComponentNotificationsBus::Event(
|
||||
m_entity->GetId(), &LmbrCentral::ShapeComponentNotificationsBus::Events::OnShapeChanged,
|
||||
LmbrCentral::ShapeComponentNotifications::ShapeChangeReasons::ShapeChanged);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsAlignedRowBoundsCorrectly)
|
||||
{
|
||||
// Check that the heightfield grid size is correct when the shape bounds match the grid resolution.
|
||||
CreateEntity();
|
||||
|
||||
AddTerrainPhysicsColliderAndShapeComponentToEntity();
|
||||
AddTerrainPhysicsColliderToEntity(Terrain::TerrainPhysicsColliderConfig());
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
@@ -188,17 +180,13 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsAligned
|
||||
// With the bounds set at 0-1024 and a resolution of 1.0, the heightfield grid should be 1024x1024.
|
||||
EXPECT_EQ(cols, 1024);
|
||||
EXPECT_EQ(rows, 1024);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderExpandsMinBoundsCorrectly)
|
||||
{
|
||||
// Check that the heightfield grid is correctly expanded if the minimum value of the bounds needs expanding
|
||||
// to correctly encompass it.
|
||||
CreateEntity();
|
||||
|
||||
AddTerrainPhysicsColliderAndShapeComponentToEntity();
|
||||
AddTerrainPhysicsColliderToEntity(Terrain::TerrainPhysicsColliderConfig());
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
@@ -221,17 +209,13 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderExpandsMinBoun
|
||||
// the values returned would be 1023.
|
||||
EXPECT_EQ(cols, 1024);
|
||||
EXPECT_EQ(rows, 1024);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderExpandsMaxBoundsCorrectly)
|
||||
{
|
||||
// Check that the heightfield grid is correctly expanded if the maximum value of the bounds needs expanding
|
||||
// to correctly encompass it.
|
||||
CreateEntity();
|
||||
|
||||
AddTerrainPhysicsColliderAndShapeComponentToEntity();
|
||||
AddTerrainPhysicsColliderToEntity(Terrain::TerrainPhysicsColliderConfig());
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
@@ -254,16 +238,12 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderExpandsMaxBoun
|
||||
// the values returned would be 1023.
|
||||
EXPECT_EQ(cols, 1024);
|
||||
EXPECT_EQ(rows, 1024);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsReturnsHeights)
|
||||
{
|
||||
// Check that the TerrainPhysicsCollider returns a heightfield of the expected size.
|
||||
CreateEntity();
|
||||
|
||||
AddTerrainPhysicsColliderAndShapeComponentToEntity();
|
||||
AddTerrainPhysicsColliderToEntity(Terrain::TerrainPhysicsColliderConfig());
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
@@ -298,16 +278,12 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsRetu
|
||||
EXPECT_EQ(cols, 1024);
|
||||
EXPECT_EQ(rows, 1024);
|
||||
EXPECT_EQ(heights.size(), cols * rows);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsRelativeHeightsCorrectly)
|
||||
{
|
||||
// Check that the values stored in the heightfield returned by the TerrainPhysicsCollider are correct.
|
||||
CreateEntity();
|
||||
|
||||
AddTerrainPhysicsColliderAndShapeComponentToEntity();
|
||||
AddTerrainPhysicsColliderToEntity(Terrain::TerrainPhysicsColliderConfig());
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
@@ -341,18 +317,11 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsRelativ
|
||||
|
||||
const float expectedHeightValue = 16384.0f;
|
||||
EXPECT_NEAR(heights[0], expectedHeightValue, 0.01f);
|
||||
|
||||
m_entity->Reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsMaterials)
|
||||
{
|
||||
// Check that the TerrainPhysicsCollider returns all the assigned materials.
|
||||
CreateEntity();
|
||||
|
||||
m_boxComponent = m_entity->CreateComponent<UnitTest::MockAxisAlignedBoxShapeComponent>();
|
||||
m_app.RegisterComponentDescriptor(m_boxComponent->CreateDescriptor());
|
||||
|
||||
// Create two SurfaceTag/Material mappings and add them to the collider.
|
||||
Terrain::TerrainPhysicsColliderConfig config;
|
||||
|
||||
@@ -372,8 +341,7 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsMateria
|
||||
mapping2.m_surfaceTag = tag2;
|
||||
config.m_surfaceMaterialMappings.emplace_back(mapping2);
|
||||
|
||||
m_colliderComponent = m_entity->CreateComponent<Terrain::TerrainPhysicsColliderComponent>(config);
|
||||
m_app.RegisterComponentDescriptor(m_colliderComponent->CreateDescriptor());
|
||||
AddTerrainPhysicsColliderToEntity(config);
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
@@ -388,20 +356,12 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsMateria
|
||||
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());
|
||||
AddTerrainPhysicsColliderToEntity(Terrain::TerrainPhysicsColliderConfig());
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
@@ -414,18 +374,11 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderReturnsMateria
|
||||
|
||||
Physics::MaterialId defaultMaterial = Physics::MaterialId();
|
||||
EXPECT_EQ(materialList[0], defaultMaterial);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsAndMaterialsReturnsCorrectly)
|
||||
{
|
||||
// Check that the TerrainPhysicsCollider returns a heightfield of the expected size.
|
||||
CreateEntity();
|
||||
|
||||
m_boxComponent = m_entity->CreateComponent<UnitTest::MockAxisAlignedBoxShapeComponent>();
|
||||
m_app.RegisterComponentDescriptor(m_boxComponent->CreateDescriptor());
|
||||
|
||||
// Create two SurfaceTag/Material mappings and add them to the collider.
|
||||
Terrain::TerrainPhysicsColliderConfig config;
|
||||
|
||||
@@ -445,8 +398,7 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsAndM
|
||||
mapping2.m_surfaceTag = tag2;
|
||||
config.m_surfaceMaterialMappings.emplace_back(mapping2);
|
||||
|
||||
m_colliderComponent = m_entity->CreateComponent<Terrain::TerrainPhysicsColliderComponent>(config);
|
||||
m_app.RegisterComponentDescriptor(m_colliderComponent->CreateDescriptor());
|
||||
AddTerrainPhysicsColliderToEntity(config);
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
@@ -460,15 +412,10 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsAndM
|
||||
const float mockHeight = 32768.0f;
|
||||
AZ::Vector2 mockHeightResolution = AZ::Vector2(1.0f);
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeight return1;
|
||||
return1.m_surfaceType = tag1;
|
||||
return1.m_weight = 1.0f;
|
||||
AzFramework::SurfaceData::SurfaceTagWeight tagWeight1(tag1, 1.0f);
|
||||
AzFramework::SurfaceData::SurfaceTagWeight tagWeight2(tag2, 1.0f);
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeight return2;
|
||||
return2.m_surfaceType = tag2;
|
||||
return2.m_weight = 1.0f;
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList surfaceTags = { return1, return2 };
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList surfaceTags = { tagWeight1, tagWeight2 };
|
||||
|
||||
NiceMock<UnitTest::MockTerrainDataRequests> terrainListener;
|
||||
ON_CALL(terrainListener, GetTerrainHeightQueryResolution).WillByDefault(Return(mockHeightResolution));
|
||||
@@ -499,6 +446,148 @@ TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderGetHeightsAndM
|
||||
// Check an entry from the second half of the list
|
||||
EXPECT_EQ(heightsAndMaterials[256 * 128].m_materialIndex, 2);
|
||||
EXPECT_NEAR(heightsAndMaterials[256 * 128].m_height, expectedHeightValue, 0.01f);
|
||||
|
||||
m_entity.reset();
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderDefaultMaterialAssignedWhenTagHasNoMapping)
|
||||
{
|
||||
// Create two SurfaceTag/Material mappings and add them to the collider.
|
||||
Terrain::TerrainPhysicsColliderConfig config;
|
||||
|
||||
const Physics::MaterialId defaultSurfaceMaterial = Physics::MaterialId::Create();
|
||||
const Physics::MaterialId mat1 = Physics::MaterialId::Create();
|
||||
|
||||
const SurfaceData::SurfaceTag tag1 = SurfaceData::SurfaceTag("tag1");
|
||||
const SurfaceData::SurfaceTag tag2 = SurfaceData::SurfaceTag("tag2");
|
||||
|
||||
Terrain::TerrainPhysicsSurfaceMaterialMapping mapping1;
|
||||
mapping1.m_materialId = mat1;
|
||||
mapping1.m_surfaceTag = tag1;
|
||||
config.m_surfaceMaterialMappings.emplace_back(mapping1);
|
||||
config.m_defaultMaterialSelection.SetMaterialId(defaultSurfaceMaterial);
|
||||
|
||||
// Intentionally don't set the mapping for "tag2". It's expected the default material will substitute.
|
||||
AddTerrainPhysicsColliderToEntity(config);
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
// Validate material list is generated with the default material
|
||||
{
|
||||
AZStd::vector<Physics::MaterialId> materialList;
|
||||
Physics::HeightfieldProviderRequestsBus::EventResult(
|
||||
materialList, m_entity->GetId(), &Physics::HeightfieldProviderRequestsBus::Events::GetMaterialList);
|
||||
|
||||
// The materialList should be 2 items long: the default material and mat1.
|
||||
EXPECT_EQ(materialList.size(), 2);
|
||||
EXPECT_EQ(materialList[0], defaultSurfaceMaterial);
|
||||
EXPECT_EQ(materialList[1], mat1);
|
||||
}
|
||||
|
||||
const AZ::Vector3 boundsMin = AZ::Vector3(0.0f);
|
||||
const AZ::Vector3 boundsMax = AZ::Vector3(256.0f, 256.0f, 32768.0f);
|
||||
|
||||
NiceMock<UnitTest::MockShapeComponentRequests> boxShape(m_entity->GetId());
|
||||
const AZ::Aabb bounds = AZ::Aabb::CreateFromMinMax(boundsMin, boundsMax);
|
||||
ON_CALL(boxShape, GetEncompassingAabb).WillByDefault(Return(bounds));
|
||||
|
||||
const float mockHeight = 32768.0f;
|
||||
AZ::Vector2 mockHeightResolution = AZ::Vector2(1.0f);
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeight tagWeight1(tag1, 1.0f);
|
||||
AzFramework::SurfaceData::SurfaceTagWeight tagWeight2(tag2, 1.0f);
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList surfaceTags = { tagWeight1, tagWeight2 };
|
||||
|
||||
NiceMock<UnitTest::MockTerrainDataRequests> terrainListener;
|
||||
ON_CALL(terrainListener, GetTerrainHeightQueryResolution).WillByDefault(Return(mockHeightResolution));
|
||||
ON_CALL(terrainListener, ProcessSurfacePointsFromRegion).WillByDefault(
|
||||
[this, mockHeight, &surfaceTags](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize,
|
||||
AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback,
|
||||
[[maybe_unused]] AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter)
|
||||
{
|
||||
ProcessRegionLoop(inRegion, stepSize, perPositionCallback, &surfaceTags, mockHeight);
|
||||
}
|
||||
);
|
||||
|
||||
// Validate material indices
|
||||
{
|
||||
AZStd::vector<Physics::HeightMaterialPoint> heightsAndMaterials;
|
||||
Physics::HeightfieldProviderRequestsBus::EventResult(
|
||||
heightsAndMaterials, m_entity->GetId(), &Physics::HeightfieldProviderRequestsBus::Events::GetHeightsAndMaterials);
|
||||
|
||||
// We set the bounds to 256, so check that the correct number of entries are present.
|
||||
EXPECT_EQ(heightsAndMaterials.size(), 256 * 256);
|
||||
|
||||
// Check an entry from the first half of the returned list.
|
||||
EXPECT_EQ(heightsAndMaterials[0].m_materialIndex, 1);
|
||||
|
||||
// Check an entry from the second half of the list.
|
||||
// This should point to the default material (0) since we don't have a mapping for "tag2"
|
||||
EXPECT_EQ(heightsAndMaterials[256 * 128].m_materialIndex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(TerrainPhysicsColliderComponentTest, TerrainPhysicsColliderDefaultMaterialAssignedWhenNoMappingsExist)
|
||||
{
|
||||
// Create only the default material with no mapping for the tags. It's expected the default material will be assigned to both tags.
|
||||
Terrain::TerrainPhysicsColliderConfig config;
|
||||
const Physics::MaterialId defaultSurfaceMaterial = Physics::MaterialId::Create();
|
||||
config.m_defaultMaterialSelection.SetMaterialId(defaultSurfaceMaterial);
|
||||
AddTerrainPhysicsColliderToEntity(config);
|
||||
|
||||
m_entity->Activate();
|
||||
|
||||
// Validate material list is generated with the default material
|
||||
{
|
||||
AZStd::vector<Physics::MaterialId> materialList;
|
||||
Physics::HeightfieldProviderRequestsBus::EventResult(
|
||||
materialList, m_entity->GetId(), &Physics::HeightfieldProviderRequestsBus::Events::GetMaterialList);
|
||||
|
||||
EXPECT_EQ(materialList.size(), 1);
|
||||
EXPECT_EQ(materialList[0], defaultSurfaceMaterial);
|
||||
}
|
||||
|
||||
const AZ::Vector3 boundsMin = AZ::Vector3(0.0f);
|
||||
const AZ::Vector3 boundsMax = AZ::Vector3(256.0f, 256.0f, 32768.0f);
|
||||
|
||||
NiceMock<UnitTest::MockShapeComponentRequests> boxShape(m_entity->GetId());
|
||||
const AZ::Aabb bounds = AZ::Aabb::CreateFromMinMax(boundsMin, boundsMax);
|
||||
ON_CALL(boxShape, GetEncompassingAabb).WillByDefault(Return(bounds));
|
||||
|
||||
const float mockHeight = 32768.0f;
|
||||
AZ::Vector2 mockHeightResolution = AZ::Vector2(1.0f);
|
||||
|
||||
const SurfaceData::SurfaceTag tag1 = SurfaceData::SurfaceTag("tag1");
|
||||
AzFramework::SurfaceData::SurfaceTagWeight tagWeight1(tag1, 1.0f);
|
||||
|
||||
const SurfaceData::SurfaceTag tag2 = SurfaceData::SurfaceTag("tag2");
|
||||
AzFramework::SurfaceData::SurfaceTagWeight tagWeight2(tag2, 1.0f);
|
||||
|
||||
AzFramework::SurfaceData::SurfaceTagWeightList surfaceTags = { tagWeight1, tagWeight2 };
|
||||
|
||||
NiceMock<UnitTest::MockTerrainDataRequests> terrainListener;
|
||||
ON_CALL(terrainListener, GetTerrainHeightQueryResolution).WillByDefault(Return(mockHeightResolution));
|
||||
ON_CALL(terrainListener, ProcessSurfacePointsFromRegion).WillByDefault(
|
||||
[this, mockHeight, &surfaceTags](const AZ::Aabb& inRegion, const AZ::Vector2& stepSize,
|
||||
AzFramework::Terrain::SurfacePointRegionFillCallback perPositionCallback,
|
||||
[[maybe_unused]] AzFramework::Terrain::TerrainDataRequests::Sampler sampleFilter)
|
||||
{
|
||||
ProcessRegionLoop(inRegion, stepSize, perPositionCallback, &surfaceTags, mockHeight);
|
||||
}
|
||||
);
|
||||
|
||||
// Validate material indices
|
||||
{
|
||||
AZStd::vector<Physics::HeightMaterialPoint> heightsAndMaterials;
|
||||
Physics::HeightfieldProviderRequestsBus::EventResult(
|
||||
heightsAndMaterials, m_entity->GetId(), &Physics::HeightfieldProviderRequestsBus::Events::GetHeightsAndMaterials);
|
||||
|
||||
// We set the bounds to 256, so check that the correct number of entries are present.
|
||||
EXPECT_EQ(heightsAndMaterials.size(), 256 * 256);
|
||||
|
||||
// Check an entry from the first half of the returned list. Should be the default material index 0.
|
||||
EXPECT_EQ(heightsAndMaterials[0].m_materialIndex, 0);
|
||||
|
||||
// Check an entry from the second half of the list. Should be the default material index 0.
|
||||
EXPECT_EQ(heightsAndMaterials[256 * 128].m_materialIndex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user