Exclude bodys from phsyx simulation

Hello everyone,

I am currently working on Rewind & Replay Network-Synchronization.

Therefore, I perform additional Physx-Substeps by adding DeltaTime (resulting in more sub-steps). However, this only should be the case for specific bodys (only the client owned pawn). Although the network sync works brilliantly fine (way better than I expected), other physic actors jitter because of this additional time inserted into the physics clock. Now my question is, how can I exclude bodys from being simulated, temporarily? I am working with Unreal Engine 4, and at this point I am not sure whether to ask here or in the UE4 forums.

I appreciate every idea and help :)

Thanks a lot,
Mykon

I don’t fully understand your use case but if you make the bodies you don’t want to simulate kinematic they won’t respond to any forces, collisions, etc. They will still impact other actors in the event of a collision but you could filter that out by changing the collision filter (no idea if/how UE4 lets you do that). I would be careful removing and readding actors rapidly from/to the world as adding an actor which is overlapping (and collides with) another actor is likely to cause you problems.

Hello asdasdasdasdasdf, thanks for your reply.

Okay, I’ll explain my use case better. For network-sync, I implemented a Rewind&Replay “algorythm”, that resets the vehicle to a position received by a server and recalculates where the vehicle should be now, if it would have been at this position X milliseconds ago, where X equals roughly ping * 2.

So when I want to replay 200ms at 100ms ping, I need to calculate 100ms of time and timesteps within one actual “real (game) world” tick. So I increase the Substep count for this tick and increase the DeltaSeconds for the physics-scene. Now the physics engine calculates basically 200ms worth of physics time within one tick. This works fine for my vehicle, but as I said, all the other physics actors also get affected by this. They basically should just remain where they were, not changing any of their properties.

So it actually would be best to find a place where I could allow only certain objects to simulate, so by default block it for all bodies, but then allow it for certain ones (so I don’t have to disable it for each physics body manually)

Have you thought of creating a second scene with just the vehicle in it? This would complement your main scene. You could integrate that second scene forwards in time and get the velocity and transform of the vehicle’s rigid body. Then you could pass that data to the equivalent rigid body in your main scene.

There is no direct mechanism to integrate a sub-set of bodies in a scene. Our usual advice is to mirror a sub-set of the main scene in a second scene and then implement code to communicate transforms and velocities between the two scenes.

The alternative is to stay with a single scene and mark everything as kinematic except for the rigid body that represents the vehicle.

One last thing to try is to have a second scene and to move the vehicle’s rigid body between the main scene and the second scene as required using removeActor and addActor. I’m hoping that these functions preserve the velocity and pose of the rigid body. You will need to look at the doxy for these functions to confirm if this is the case. If it is just a single rigid body this might be fairly fast. If it involves a large number of rigid bodies it will be much more efficient to mirror the scene.

Cheers,

Gordon

Hello Gordon (gyeoman),

thanks for your answer! That sounds like a very good idea. To be honest, I am not very experienced with physx yet, but I assume a physics scene is like a “world”, right? Two physics scenes don’t interfere with each other.

So, I would create a mirror of the main-physics scene and calculate the rewind logic there, and then transfer the results to my main-scene? Sounds perfect, actually, except the mirror stuff. Does that mean I have to manually update changes in the physical environment from my main scene to the mirror scene? Or is there a way to easily mirror a physics scene? I do not request a tutorial here, but maybe you have a link or some small tips for me, where I can start my research.

Thanks again for your effort!

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

Thanks again for your awesome help! I will definitely try that.

But I am wondering, is that such an uncommon concept (rewind & replay)?
So, short summarized, I am basically replaying the last 200ms, with the data that now arrived from the server.
The client stores it’s input history, and when the server-data arrives (position / velocity / rotation…), it resets the vehicle (in my case) to that position, and at a ping of 100ms, goes pack 200ms in the input history and replays physics with this input until the present moment, to give a latency free, server-authoritive and smooth vehicle-movement.

Is there no other way to simulate physics within one tick, simulating the result over a bigger time-span? I am pretty sure, just multiplying forces won’t do the trick :D

I am willing to learn what you wrote, but it sounds very performance heavy, and maybe there is a more simple solution to this.

Another option might be to just store the transform and velocity of all phyiscs bodys temporarily, and after the rewind & replay I just reapply those values. Or, I do a snapshot rewind, where I actually recalculate the whole world (all the physics actors), so when a Rewind starts, all actors look up their transforms and velocitys at the desired moment in time and apply them, which then SHOULD result in the same positions again.

What do you think would be the most suited solution to this? :)

Greetings and thanks again :)

I don’t know if it’s uncommon but none of the physx stuff I’ve done required networking so I haven’t had to deal with it. Out of interest, does the server update contain only the vehicle’s position or the position of all bodies? If your vehicle pushes an object out of the way and then the server tells you that actually the vehicle didn’t go that way, what happens to the object that was pushed out of the way. Do you not want to rewind everything to ensure that the state of all your objects is in agreement? If so then it should be a question of repositioning all dynamic actors kinematically and then ticking for the replay timestep. Consider whether you want to take one step equal to your ping or N timesteps of a fixed length which add up to roughly your ping as the dynamics results can be subtly different.

Okay, when a Server Correction arrives, that should be the same time the corrections for all the other networked physics bodys arrive. I would have to assure that though.
Then I could just use the same algorythm for them. Since they don’t rely on player input, they do not need any special replay code, only their velocity and transform (which is replicated via UE4 automatically).

Problem then would be not networked physics objects…

Okay, quick update, I tried it implementing with just storing physics data of each physics actor in the scene before the FF and reset them afterwards. For our game that works fine, with no large amount of physical actors. But since I am offering my solution to another one’s project, I will have to check that for performance hit though. Can’t imagine it being more performance heavy than creating a second physx scene.