adding time to a single body (0.9)

jchmack

27-05-2008 10:46:38

I'm working on my netcode again and i need to add time/simulate only one body for x milliseconds. When i create a box/rocket/anything there is going to be a delay between clients and i need to have the clients create the object then simulate ONLY this object for x milliseconds (x being the time passed since packet was sent).

I dont thing that calling any of these moves the object:


(*iter)->mBody->shapeSimulate(Time);
(*iter)->mBody->shapeRender(Time);
(*iter)->mBody->simulate(Time);
(*iter)->mBody->render(Time);


I turned off the worldsimulate / world render in my main loop

//mWorld->getPhysXDriver()->simulate(Time);
//mWorld->getPhysXDriver()->render(Time);


I would expect that all the other objects would freeze except the objects i MANUALLY simulated with any of the simulate/render functions in the first codeblock, but they all stay still.

It seems the scene::simulate just calls the actor::simulate:
void Scene::simulate(NxReal time) {
...
for(Actor* actor = mActors.begin();actor = mActors.next();) {
actor->simulate(time);
...
}

So why doesn't me manually calling the actor::simulate move the object?
Sigh i am confused its 5am. I'm off to bed.
Thanks to anyone who helps =).

betajaen

27-05-2008 11:40:51

It does move the object. But the Scene hasn't been updated for the object to move to the new position; which your turning off in the second block of code.

How about you make every actor kinematic; turn on the Scene simulate/render and just move any actor that needs to be moved, and leave the simulate/render stuff to NxOgre.

I've tried it with "FxScenes" and it works pretty well.

jchmack

27-05-2008 12:00:37


It does move the object. But the Scene hasn't been updated for the object to move to the new position; which your turning off in the second block of code.


Ok so if I disable the simulate but leave the render


//mWorld->getPhysXDriver()->simulate(Time);
mWorld->getPhysXDriver()->render(Time);


and I also call the Simulate manually:


(*iter)->mBody->simulate(Time);
//(*iter)->mBody->render(Time);


It will move the object because i called the simulate and it will update the scene because i am leaving ON the world::Render. Thx I will try it out =)

edit: I just tried it and it isn't moving my Bodies...


How about you make every actor kinematic; turn on the Scene simulate/render and just move any actor that needs to be moved, and leave the simulate/render stuff to NxOgre.


Because i like the collision callback system that nxogre has implemented. If i just teleport the object at first it won't hit any objects that it was supposed to hit in that timeframe. It should work perfectly because the delay over a network is only like 10ms so it should be like simulating the body for about one frame.


I've tried it with "FxScenes" and it works pretty well.


Ill take a look at how u do this in FxScenes.

betajaen

27-05-2008 12:09:18

No, no, no. Leave everything on by default. Simulate/Render for World/Scene/Actor both on. Anything that has been simulated outside the client should be represented as an Actor which is kinematic. To represent physically the changes; you need to send the change of position from the server to the clients (Sporadically the actual position - but I'll let you work that bit out), you use the moveGlobalPosition and moveGlobalOrientation to move the kinematic actor; so proper one-way collision works.

FxScenes are basically a main scene and a secondary scene. The Secondary scene is filled up with short term actors for special effects, anything that is in the main scene that is in the field of view of the secondary scene; i.e. a table or chair is regarded as kinematic, any movements is converted to relative and is positioned using the moveGlobalPosition/Orientation functions.

It's worked very well in the past and there is no reason why it won't work with network code.

jchmack

27-05-2008 12:28:06

No, no, no. Leave everything on by default. Simulate/Render for World/Scene/Actor both on. Anything that has been simulated outside the client should be represented as an Actor which is kinematic. To represent physically the changes; you need to send the change of position from the server to the clients (Sporadically the actual position - but I'll let you work that bit out), you use the moveGlobalPosition and moveGlobalOrientation to move the kinematic actor; so proper one-way collision works.

FxScenes are basically a main scene and a secondary scene. The Secondary scene is filled up with short term actors for special effects, anything that is in the main scene that is in the field of view of the secondary scene; i.e. a table or chair is regarded as kinematic, any movements is converted to relative and is positioned using the moveGlobalPosition/Orientation functions.

It's worked very well in the past and there is no reason why it won't work with network code.


I apologize if i haven't been clear. I have the netcode working. I am sending the updates and everything is fine, But i have a small workaround:

When i receive a packet that a projectile has been created I create the object and i calculate where the body SHOULD BE and i teleport it there.
This works fine for now but there are problems that arise because of this initial teleport.

For example If a player is by a wall he can shoot through it because the client gets the packet with its velocity of lets say Vector3(1,0,0) and my teleport function will take this and ask where it should be now. So i will take the time it took to send the packet times its velocity Vector3(1,0,0) *delay and i will add this to the current position of the body. But this just teleports the object to this spot. If the body was supposed to hit a wall in this timestep or a character or whatever it doesn't and i get differences in the server/client.

My hope is that if instead of calculating where it should be and teleporting it i use body::simulate(Delay) PhysX will calulate the body for me just like it would if i was just calculating a normal frame. This means that if It was supposed to hit a wall or a character it will and it will report it automatically in the collision callback.

But i cant seem to get body::simulate() to move the body any more. I tried to leave the world simulate and render on:

mWorld->getPhysXDriver()->simulate(Time);
mWorld->getPhysXDriver()->render(Time);

but also just add my own simulate as well:

(*iter)->mBody->simulate(Time);

I believe that this SHOULD make my body travel twice as fast because it is adding the time 2x correct? But i see no difference even if i add tons of time to it:

(*iter)->mBody->simulate(Time*10);