Add proper vehicle setup after editing wheel colliders

This commit is contained in:
Wojtek Figat
2021-03-26 17:11:26 +01:00
parent 2ce14b5e9c
commit e21c9d24de
6 changed files with 60 additions and 46 deletions

View File

@@ -383,6 +383,15 @@ void RigidBody::OnTriggerExit(PhysicsColliderActor* c)
TriggerExit(c);
}
void RigidBody::OnColliderChanged(Collider* c)
{
UpdateMass();
// TODO: maybe wake up only if one ore more shapes attached is active?
//if (GetStartAwake())
// WakeUp();
}
void RigidBody::CreateActor()
{
ASSERT(_actor == nullptr);
@@ -394,7 +403,7 @@ void RigidBody::CreateActor()
// Setup flags
#if WITH_PVD
PxActorFlags actorFlags = PxActorFlag::eVISUALIZATION;
PxActorFlags actorFlags = PxActorFlag::eVISUALIZATION;
#else
PxActorFlags actorFlags = static_cast<PxActorFlags>(0);
#endif

View File

@@ -551,6 +551,9 @@ public:
void OnTriggerEnter(PhysicsColliderActor* c);
void OnTriggerExit(PhysicsColliderActor* c);
// Called when collider gets detached from this rigidbody or activated/deactivated. Used to update rigidbody mass.
virtual void OnColliderChanged(Collider* c);
protected:
/// <summary>

View File

@@ -182,6 +182,14 @@ void WheeledVehicle::Setup()
return;
auto& drive = (PxVehicleDrive4W*&)_drive;
// Release previous
if (drive)
{
WheelVehicles.Remove(this);
drive->free();
drive = nullptr;
}
// Get wheels
Array<Wheel*, FixedAllocation<PX_MAX_NB_WHEELS>> wheels;
_wheelsData.Clear();
@@ -202,18 +210,15 @@ void WheeledVehicle::Setup()
LOG(Warning, "Invalid wheel collider {1} in vehicle {0} cannot be a trigger", ToString(), wheel.Collider->ToString());
continue;
}
wheels.Add(&wheel);
if (wheel.Collider->IsDuringPlay())
{
wheels.Add(&wheel);
}
}
if (wheels.IsEmpty())
{
// No wheel, no car
// No woman, no cry
if (drive)
{
WheelVehicles.Remove(this);
drive->free();
drive = nullptr;
}
return;
}
_wheelsData.Resize(wheels.Count());
@@ -294,14 +299,22 @@ void WheeledVehicle::Setup()
wheelsSimData->setTireForceAppPointOffset(i, forceAppPointOffset);
PxShape* wheelShape = wheel.Collider->GetPxShape();
wheelsSimData->setWheelShapeMapping(i, shapes.Find(wheelShape));
if (wheel.Collider->IsActiveInHierarchy())
{
wheelsSimData->setWheelShapeMapping(i, shapes.Find(wheelShape));
// Setup Vehicle ID inside word3 for suspension raycasts to ignore self
PxFilterData filter = wheelShape->getQueryFilterData();
filter.word3 = _id.D + 1;
wheelShape->setQueryFilterData(filter);
wheelShape->setSimulationFilterData(filter);
wheelsSimData->setSceneQueryFilterData(i, filter);
// Setup Vehicle ID inside word3 for suspension raycasts to ignore self
PxFilterData filter = wheelShape->getQueryFilterData();
filter.word3 = _id.D + 1;
wheelShape->setQueryFilterData(filter);
wheelShape->setSimulationFilterData(filter);
wheelsSimData->setSceneQueryFilterData(i, filter);
}
else
{
wheelsSimData->setWheelShapeMapping(i, -1);
wheelsSimData->disableWheel(i);
}
}
for (auto child : Children)
{
@@ -375,7 +388,7 @@ void WheeledVehicle::Setup()
// Create vehicle drive
drive = PxVehicleDrive4W::allocate(wheels.Count());
_actor->setSolverIterationCounts(12, 4);
drive->setup(CPhysX, _actor, *wheelsSimData, driveSimData, wheels.Count() - 4);
drive->setup(CPhysX, _actor, *wheelsSimData, driveSimData, Math::Max(wheels.Count() - 4, 0));
WheelVehicles.Add(this);
// Initialize
@@ -442,6 +455,14 @@ void WheeledVehicle::Deserialize(DeserializeStream& stream, ISerializeModifier*
DESERIALIZE_MEMBER(Gearbox, _gearbox);
}
void WheeledVehicle::OnColliderChanged(Collider* c)
{
RigidBody::OnColliderChanged(c);
// Rebuild vehicle when someone adds/removed wheels
Setup();
}
void WheeledVehicle::BeginPlay(SceneBeginData* data)
{
RigidBody::BeginPlay(data);

View File

@@ -254,6 +254,7 @@ public:
#endif
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
void OnColliderChanged(Collider* c) override;
protected: