Two physics don’t interfere with each other, that’s right.
If you are just trying to update a vehicle over a short time frame I’m not sure how much you need to mirror. I would have thought it would be enough just to mirror all the static geometry and nothing more. That is really simple to do: every time you add or remove a static actor make sure you do that to both scenes. That’s where I would start to see if this is good enough.
If you want the vehicle in the mirror scene to knock dynamic actors out of the way then you have a more complex problem because you need to communicate the vehicle and dynamic actors near the vehicle between the two scenes. You don’t need to mirror the entire scene because only a small number of dynamics could ever be affected by the vehicle each frame. A simple solution would be to work out each frame which dynamic actors in the main scene are within a radius of the vehicle. The radius depends on the maximum distance that the vehicle can travel in one frame. You could then mirror those actors in the second scene.
Your code might look like this when you create an actor. This is just a suggestion and uses the userData ptr to store a mapping between the two scenes.
struct ActorMirror
{
PxRigidDynamic* firstScene;
PxRigidDynamic* mirrorScene;
};
//Create an actor and a mirror of it and add each to a scene.
PxRigidActor* firstActor = createMyActor();
mainScene->addActor(firstActor);
PxRigidActor mirrorActor = createMyActor();
mirrorScene->addActor(*secondActor);
//Create the mapping between the actor and its mirror.
ActorMirror* actorMirror = new ActorMirror(firstActor, mirrorActor);
firstActor->userData = actorMirror;
mirrorActor->userData = actorMirror;
Here is some pseudo-code to communicate dynamic actor data between the two scenes.
//Get the actors that could be affected.
PxRigidActor* actorsInRange[1024];
PxU32 nbActorsInRange;
PxVec3 vehiclePos = getVehiclePos();
float radius = vehicleRadius + maxDistTravelledInPingTime;
getActorsInRange(mainScene, vehiclePos, radius, actorsInRange, nbActorsInRange);
//Update the potentially affected actors in the mirror scene.
for(PxU32 i = 0; i < nbActorsInRange; i++)
{
ActorMirror* actorMirror = static_cast<ActorMirror*>(actorsInRange[i]->userData);
PxRigidDynamic* main = actorMirror->firstScene;
PxRigidDynamic* mirror = actorMirror->mirrorScene;
mirror->setGlobalPose(main->getGlobalPose());
mirror->setLinearVelocity(main->getLinearVelocity());
mirror->setAngularVelocity(main->getAngularVelocity());
}
mirrorScene->simulate(pingTime);
//Communicate back to the main scene.
for(PxU32 i = 0; i < nbActorsInRange; i++)
{
ActorMirror* actorMirror = static_cast<ActorMirror*>(actorsInRange[i]->userData);
PxRigidDynamic* main = actorMirror->firstScene;
PxRigidDynamic* mirror = actorMirror->mirrorScene;
main->setGlobalPose(mirror->getGlobalPose());
main->setLinearVelocity(mirror->getLinearVelocity());
main->setAngularVelocity(mirror->getAngularVelocity());
}
If you make the variable radius large enough you will end up mirroring the entire scene.
I hope this gives you a flavour of the kind of code involved.
Cheers,
Gordon