diff --git a/Source/Engine/Physics/Actors/WheeledVehicle.h b/Source/Engine/Physics/Actors/WheeledVehicle.h
index fd0e9be4f..b1e858eaf 100644
--- a/Source/Engine/Physics/Actors/WheeledVehicle.h
+++ b/Source/Engine/Physics/Actors/WheeledVehicle.h
@@ -245,6 +245,11 @@ DECLARE_SCENE_OBJECT(WheeledVehicle);
/// The tire longitudinal stiffness to have given longitudinal slip.
///
API_FIELD(Attributes="EditorDisplay(\"Tire\"), EditorOrder(32)") float TireLongitudinalStiffness = 1000.0f;
+
+ ///
+ /// The tire friction scale (scales the drivable surface friction under the tire).
+ ///
+ API_FIELD(Attributes="EditorDisplay(\"Tire\"), EditorOrder(33)") float TireFrictionScale = 1.0f;
};
///
diff --git a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp
index 48d7db8eb..c1a08210d 100644
--- a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp
+++ b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp
@@ -365,6 +365,8 @@ namespace
Array WheelVehiclesResultsPerWheel;
Array WheelVehiclesResultsPerVehicle;
PxVehicleDrivableSurfaceToTireFrictionPairs* WheelTireFrictions = nullptr;
+ bool WheelTireFrictionsDirty = false;
+ Array WheelTireTypes;
#endif
}
@@ -503,6 +505,10 @@ void* PhysicalMaterial::GetPhysicsMaterial()
const PhysicsCombineMode useRestitutionCombineMode = OverrideRestitutionCombineMode ? RestitutionCombineMode : _restitutionCombineMode;
material->setRestitutionCombineMode(static_cast(useRestitutionCombineMode));
+
+#if WITH_VEHICLE
+ WheelTireFrictionsDirty = true;
+#endif
}
return _material;
}
@@ -521,6 +527,10 @@ void PhysicalMaterial::UpdatePhysicsMaterial()
material->setRestitution(Restitution);
const PhysicsCombineMode useRestitutionCombineMode = OverrideRestitutionCombineMode ? RestitutionCombineMode : _restitutionCombineMode;
material->setRestitutionCombineMode(static_cast(useRestitutionCombineMode));
+
+#if WITH_VEHICLE
+ WheelTireFrictionsDirty = true;
+#endif
}
}
@@ -1097,16 +1107,31 @@ void PhysicsBackend::EndSimulateScene(void* scene)
scenePhysX->WheelRaycastBatchQuery = scenePhysX->Scene->createBatchQuery(desc);
}
- // TODO: expose vehicle tires configuration
- if (!WheelTireFrictions)
+ // Update lookup table that maps wheel type into the surface friction
+ if (!WheelTireFrictions || WheelTireFrictionsDirty)
{
- PxVehicleDrivableSurfaceType surfaceTypes[1];
- surfaceTypes[0].mType = 0;
- const PxMaterial* surfaceMaterials[1];
- surfaceMaterials[0] = DefaultMaterial;
- WheelTireFrictions = PxVehicleDrivableSurfaceToTireFrictionPairs::allocate(1, 1);
- WheelTireFrictions->setup(1, 1, surfaceMaterials, surfaceTypes);
- WheelTireFrictions->setTypePairFriction(0, 0, 5.0f);
+ WheelTireFrictionsDirty = false;
+ RELEASE_PHYSX(WheelTireFrictions);
+ Array> materials;
+ materials.Resize(Math::Min((int32)PhysX->getNbMaterials(), PxVehicleDrivableSurfaceToTireFrictionPairs::eMAX_NB_SURFACE_TYPES));
+ PxMaterial** materialsPtr = materials.Get();
+ PhysX->getMaterials(materialsPtr, materials.Count(), 0);
+ Array> tireTypes;
+ tireTypes.Resize(materials.Count());
+ PxVehicleDrivableSurfaceType* tireTypesPtr = tireTypes.Get();
+ for (int32 i = 0; i < tireTypes.Count(); i++)
+ tireTypesPtr[i].mType = i;
+ WheelTireFrictions = PxVehicleDrivableSurfaceToTireFrictionPairs::allocate(WheelTireTypes.Count(), materials.Count());
+ WheelTireFrictions->setup(WheelTireTypes.Count(), materials.Count(), (const PxMaterial**)materialsPtr, tireTypesPtr);
+ for (int32 material = 0; material < materials.Count(); material++)
+ {
+ float friction = materialsPtr[material]->getStaticFriction();
+ for (int32 tireType = 0; tireType < WheelTireTypes.Count(); tireType++)
+ {
+ float scale = WheelTireTypes[tireType];
+ WheelTireFrictions->setTypePairFriction(material, tireType, friction * scale);
+ }
+ }
}
// Setup cache for wheel states
@@ -2522,7 +2547,15 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor)
suspensionData.mSpringDamperRate = wheel.SuspensionDampingRate * 2.0f * Math::Sqrt(suspensionData.mSpringStrength * suspensionData.mSprungMass);
PxVehicleTireData tire;
- tire.mType = 0;
+ int32 tireIndex = WheelTireTypes.Find(wheel.TireFrictionScale);
+ if (tireIndex == -1)
+ {
+ // New tire type
+ tireIndex = WheelTireTypes.Count();
+ WheelTireTypes.Add(wheel.TireFrictionScale);
+ WheelTireFrictionsDirty = true;
+ }
+ tire.mType = tireIndex;
tire.mLatStiffX = wheel.TireLateralMax;
tire.mLatStiffY = wheel.TireLateralStiffness;
tire.mLongitudinalStiffnessPerUnitGravity = wheel.TireLongitudinalStiffness;