-
Notifications
You must be signed in to change notification settings - Fork 710
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Correct way to change a body's position and orientation? #215
Comments
Hi, For many cases, your code should be fine. If you use interpolation, sleeping, or if you have custom force fields, you might want to add some more stuff. Here's some draft code to reset the (hopefully) whole state. // Position
body.position.setZero();
body.previousPosition.setZero();
body.interpolatedPosition.setZero();
body.initPosition.setZero();
// orientation
body.quaternion.set(0,0,0,1);
body.initQuaternion.set(0,0,0,1);
body.previousQuaternion.set(0,0,0,1);
body.interpolatedQuaternion.set(0,0,0,1);
// Velocity
body.velocity.setZero();
body.initVelocity.setZero();
body.angularVelocity.setZero();
body.initAngularVelocity.setZero();
// Force
body.force.setZero();
body.torque.setZero();
// Sleep state reset
body.sleepState = 0;
body.timeLastSleepy = 0;
body._wakeUpAfterNarrowphase = false; I've been wondering if this code should be in a method, but I'm not sure how... The position and interpolation stuff could fit in a |
Thanks! A teleport method would be fantastic - maybe with an option or two to handle the dynamic stuff? |
+1 |
In addition, since I'm writing a game where I need to do key-frame physics synchronisation, it would be great to have a serialise and deserialise method which generates a JSON compatible array which clones exact object state so the physics can be copied from server to client. |
Okay, yeah, this is causing me problems. Trying to sync the state between the server and client is causing issues. If I sync all these values, should that (in theory) work? |
Here is a really quick hack to see if this would fix sync bugs I'm having.. doesn't seem to be working well.. any ideas? CANNON.Body.prototype.serialize = function() {
return [
// Position
this.position.x, this.position.y, this.position.z,
this.previousPosition.x, this.previousPosition.y, this.previousPosition.z,
this.interpolatedPosition.x, this.interpolatedPosition.y, this.interpolatedPosition.z,
this.initPosition.x, this.initPosition.y, this.initPosition.z,
// Orientation
this.quaternion.x, this.quaternion.y, this.quaternion.z, this.quaternion.w,
this.previousQuaternion.x, this.previousQuaternion.y, this.previousQuaternion.z, this.previousQuaternion.w,
this.interpolatedQuaternion.x, this.interpolatedQuaternion.y, this.interpolatedQuaternion.z, this.interpolatedQuaternion.w,
this.initQuaternion.x, this.initQuaternion.y, this.initQuaternion.z, this.initQuaternion.w,
// Velocity
this.velocity.x, this.velocity.y, this.velocity.z,
this.initVelocity.x, this.initVelocity.y, this.initVelocity.z,
this.angularVelocity.x, this.angularVelocity.y, this.angularVelocity.z,
this.initAngularVelocity.x, this.initAngularVelocity.y, this.initAngularVelocity.z,
this.force.x, this.force.y, this.force.z,
this.torque.x, this.torque.y, this.torque.z,
this.sleepState,
this.timeLastSleepy,
this._wakeUpAfterNarrowphase
];
}
CANNON.Body.prototype.deserialize = function(data) {
this.position.set(data[0], data[1], data[2]);
this.previousPosition.set(data[3], data[4], data[5]);
this.interpolatedPosition.set(data[6], data[7], data[8]);
this.initPosition.set(data[9], data[10], data[11]);
// orientation
this.quaternion.set(data[12], data[13], data[14], data[15]);
this.previousQuaternion.set(data[16], data[17], data[18], data[19]);
this.interpolatedQuaternion.set(data[20], data[21], data[22], data[23]);
this.initQuaternion.set(data[24], data[25], data[26], data[27]);
// Velocity
this.velocity.set(data[28], data[29], data[30]);
this.initVelocity.set(data[31], data[32], data[33]);
this.angularVelocity.set(data[34], data[35], data[36]);
this.initAngularVelocity.set(data[37], data[38], data[39]);
// Force
this.force.set(data[40], data[41], data[42]);
this.torque.set(data[43], data[44], data[45]);
// Sleep state reset
this.sleepState = data[46];
this.timeLastSleepy = data[47];
this._wakeUpAfterNarrowphase = data[48];
} |
@ioquatix I made a serializer for p2.js, but I removed it after a while. It's a bit of work to maintain it, and in the end I realized that it's not being used in practice. You always want a custom file format for whatever you are building, so the only value in a serializer is just the knowledge how to serialize and deserialize a physics state. Synchronizing those values should probably work for one given point in time. Do you use client side prediction or any similar algorithm? (This is a difficult problem you know - even the big game titles avoid this :P) |
@schteppe So we are using Node.js and running the physics both server and client side. The idea is to send keyframe sync but in general the two simulations run independently, but I'm seeing some pretty wonky behaviour, but most of the time it is working "reasonable". I've had a lot of issues with player movement.. This is a work in progress :) I'd really appreciate if you have some time to check it out: |
I've just committed to the development branch, a commit that only does server side physics and has a client side update rate of 15 FPS., just FYI. |
Sorry to bother you but one more issue that comes up is that sometimes player cannot move. I wonder if they got stuck in the ground plane. I tried to add a small +ve Z value in applyImpulse but I'm not sure if that helps or not. |
@ioquatix All right. It should work perfectly for a single body without contacts. If you have contacts you should probably not touch the position or velocity. Maybe you can add a force toward the authoritative server position, and if the player is way off, teleport? I never got client/server physics sync working - I've always avoided it because it's a really difficult problem. Maybe you are interested in how UDK does it. For small corrections they add an impulse toward the server position. https://udn.epicgames.com/Three/NetworkingOverview.html 15FPS is probably too bad for rigid body physics. Probably works for game-specific physics like minecraft but for general rigid body simulation, probably not. Try this link, set FPS to 15 and drag the ragdoll around: https://schteppe.github.io/p2.js/demos/ragdoll.html |
+1 for teleport method :) |
+1 again for a teleport method. It would be great if the teleport method would not only handle position/rotation and interpolation for both, but also to change the direction of forces/impulses that are currently applied to move in the direction of the new rotation. That would be great! |
I want to change a body's position and orientation and reset all of its dynamic properties like velocity, angular velocity, and anything else that affects the simulation. Currently I use the following (where
x
,y
,z
is my new position anda
,b
,c
,w
is my new quaternion):I'm wondering whether this is the most efficient way to do it and/or whether I've missed anything?
Thanks!
The text was updated successfully, but these errors were encountered: