Add support for multiple physical materials in terrain - one for each painted layer

#1112 #2159
This commit is contained in:
Wojtek Figat
2024-02-16 17:11:40 +01:00
parent f04f1cc90e
commit 42b4443e14
8 changed files with 306 additions and 298 deletions

View File

@@ -644,6 +644,19 @@ void GetShapeGeometry(const CollisionShape& shape, PxGeometryHolder& geometry)
}
}
void GetShapeMaterials(Array<PxMaterial*, InlinedAllocation<1>>& materialsPhysX, Span<JsonAsset*> materials)
{
materialsPhysX.Resize(materials.Length());
for (int32 i = 0; i < materials.Length(); i++)
{
PxMaterial* materialPhysX = DefaultMaterial;
const JsonAsset* material = materials.Get()[i];
if (material && !material->WaitForLoaded() && material->Instance)
materialPhysX = (PxMaterial*)((PhysicalMaterial*)material->Instance)->GetPhysicsMaterial();
materialsPhysX.Get()[i] = materialPhysX;
}
}
PxFilterFlags FilterShader(
PxFilterObjectAttributes attributes0, PxFilterData filterData0,
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
@@ -2449,17 +2462,14 @@ void PhysicsBackend::AddRigidDynamicActorTorque(void* actor, const Vector3& torq
actorPhysX->addTorque(C2P(torque), static_cast<PxForceMode::Enum>(mode));
}
void* PhysicsBackend::CreateShape(PhysicsColliderActor* collider, const CollisionShape& geometry, JsonAsset* material, bool enabled, bool trigger)
void* PhysicsBackend::CreateShape(PhysicsColliderActor* collider, const CollisionShape& geometry, Span<JsonAsset*> materials, bool enabled, bool trigger)
{
const PxShapeFlags shapeFlags = GetShapeFlags(trigger, enabled);
PxMaterial* materialPhysX = DefaultMaterial;
if (material && !material->WaitForLoaded() && material->Instance)
{
materialPhysX = (PxMaterial*)((PhysicalMaterial*)material->Instance)->GetPhysicsMaterial();
}
Array<PxMaterial*, InlinedAllocation<1>> materialsPhysX;
GetShapeMaterials(materialsPhysX, materials);
PxGeometryHolder geometryPhysX;
GetShapeGeometry(geometry, geometryPhysX);
PxShape* shapePhysX = PhysX->createShape(geometryPhysX.any(), *materialPhysX, true, shapeFlags);
PxShape* shapePhysX = PhysX->createShape(geometryPhysX.any(), materialsPhysX.Get(), materialsPhysX.Count(), true, shapeFlags);
shapePhysX->userData = collider;
#if PHYSX_DEBUG_NAMING
shapePhysX->setName("Shape");
@@ -2549,15 +2559,12 @@ void PhysicsBackend::SetShapeContactOffset(void* shape, float value)
shapePhysX->setContactOffset(Math::Max(shapePhysX->getRestOffset() + ZeroTolerance, value));
}
void PhysicsBackend::SetShapeMaterial(void* shape, JsonAsset* material)
void PhysicsBackend::SetShapeMaterials(void* shape, Span<JsonAsset*> materials)
{
auto shapePhysX = (PxShape*)shape;
PxMaterial* materialPhysX = DefaultMaterial;
if (material && !material->WaitForLoaded() && material->Instance)
{
materialPhysX = (PxMaterial*)((PhysicalMaterial*)material->Instance)->GetPhysicsMaterial();
}
shapePhysX->setMaterials(&materialPhysX, 1);
Array<PxMaterial*, InlinedAllocation<1>> materialsPhysX;
GetShapeMaterials(materialsPhysX, materials);
shapePhysX->setMaterials(materialsPhysX.Get(), materialsPhysX.Count());
}
void PhysicsBackend::SetShapeGeometry(void* shape, const CollisionShape& geometry)
@@ -4077,10 +4084,17 @@ void PhysicsBackend::GetHeightFieldSize(void* heightField, int32& rows, int32& c
columns = (int32)heightFieldPhysX->getNbColumns();
}
float PhysicsBackend::GetHeightFieldHeight(void* heightField, float x, float z)
float PhysicsBackend::GetHeightFieldHeight(void* heightField, int32 x, int32 z)
{
auto heightFieldPhysX = (PxHeightField*)heightField;
return heightFieldPhysX->getHeight(x, z);
return heightFieldPhysX->getHeight((float)x, (float)z);
}
PhysicsBackend::HeightFieldSample PhysicsBackend::GetHeightFieldSample(void* heightField, int32 x, int32 z)
{
auto heightFieldPhysX = (PxHeightField*)heightField;
auto sample = heightFieldPhysX->getSample(x, z);
return { sample.height, sample.materialIndex0, sample.materialIndex1 };
}
bool PhysicsBackend::ModifyHeightField(void* heightField, int32 startCol, int32 startRow, int32 cols, int32 rows, const HeightFieldSample* data)

View File

@@ -4,6 +4,7 @@
#include "Physics.h"
#include "PhysicsSettings.h"
#include "Engine/Core/Types/Span.h"
struct HingeJointDrive;
struct SpringParameters;
@@ -182,7 +183,7 @@ public:
static void AddRigidDynamicActorTorque(void* actor, const Vector3& torque, ForceMode mode);
// Shapes
static void* CreateShape(PhysicsColliderActor* collider, const CollisionShape& geometry, JsonAsset* material, bool enabled, bool trigger);
static void* CreateShape(PhysicsColliderActor* collider, const CollisionShape& geometry, Span<JsonAsset*> materials, bool enabled, bool trigger);
static void SetShapeState(void* shape, bool enabled, bool trigger);
static void SetShapeFilterMask(void* shape, uint32 mask0, uint32 mask1);
static void* GetShapeActor(void* shape);
@@ -191,7 +192,7 @@ public:
static void GetShapeLocalPose(void* shape, Vector3& position, Quaternion& orientation);
static void SetShapeLocalPose(void* shape, const Vector3& position, const Quaternion& orientation);
static void SetShapeContactOffset(void* shape, float value);
static void SetShapeMaterial(void* shape, JsonAsset* material);
static void SetShapeMaterials(void* shape, Span<JsonAsset*> materials);
static void SetShapeGeometry(void* shape, const CollisionShape& geometry);
static void AttachShape(void* shape, void* actor);
static void DetachShape(void* shape, void* actor);
@@ -303,7 +304,8 @@ public:
static void GetTriangleMeshTriangles(void* triangleMesh, Array<Float3, HeapAllocation>& vertexBuffer, Array<int32, HeapAllocation>& indexBuffer);
static const uint32* GetTriangleMeshRemap(void* triangleMesh, uint32& count);
static void GetHeightFieldSize(void* heightField, int32& rows, int32& columns);
static float GetHeightFieldHeight(void* heightField, float x, float z);
static float GetHeightFieldHeight(void* heightField, int32 x, int32 z);
static HeightFieldSample GetHeightFieldSample(void* heightField, int32 x, int32 z);
static bool ModifyHeightField(void* heightField, int32 startCol, int32 startRow, int32 cols, int32 rows, const HeightFieldSample* data);
static void FlushRequests();
static void FlushRequests(void* scene);
@@ -330,6 +332,14 @@ public:
flags = (RigidDynamicFlags)(((uint32)flags & ~(uint32)flag) | (value ? (uint32)flag : 0));
SetRigidDynamicActorFlags(actor, flags);
}
FORCE_INLINE static void* CreateShape(PhysicsColliderActor* collider, const CollisionShape& geometry, JsonAsset* material, bool enabled, bool trigger)
{
return CreateShape(collider, geometry, Span<JsonAsset*>(&material, 1), enabled, trigger);
}
FORCE_INLINE static void SetShapeMaterial(void* shape, JsonAsset* material)
{
SetShapeMaterials(shape, Span<JsonAsset*>(&material, 1));
}
};
DECLARE_ENUM_OPERATORS(PhysicsBackend::ActorFlags);

View File

@@ -408,7 +408,7 @@ void PhysicsBackend::AddRigidDynamicActorTorque(void* actor, const Vector3& torq
{
}
void* PhysicsBackend::CreateShape(PhysicsColliderActor* collider, const CollisionShape& geometry, JsonAsset* material, bool enabled, bool trigger)
void* PhysicsBackend::CreateShape(PhysicsColliderActor* collider, const CollisionShape& geometry, Span<JsonAsset*> materials, bool enabled, bool trigger)
{
return DUMY_HANDLE;
}
@@ -447,7 +447,7 @@ void PhysicsBackend::SetShapeContactOffset(void* shape, float value)
{
}
void PhysicsBackend::SetShapeMaterial(void* shape, JsonAsset* material)
void PhysicsBackend::SetShapeMaterials(void* shape, Span<JsonAsset*> materials)
{
}
@@ -826,11 +826,16 @@ void PhysicsBackend::GetHeightFieldSize(void* heightField, int32& rows, int32& c
columns = 0;
}
float PhysicsBackend::GetHeightFieldHeight(void* heightField, float x, float z)
float PhysicsBackend::GetHeightFieldHeight(void* heightField, int32 x, int32 z)
{
return 0.0f;
}
PhysicsBackend::HeightFieldSample PhysicsBackend::GetHeightFieldSample(void* heightField, int32 x, int32 z)
{
return HeightFieldSample();
}
bool PhysicsBackend::ModifyHeightField(void* heightField, int32 startCol, int32 startRow, int32 cols, int32 rows, const HeightFieldSample* data)
{
return true;