-
Notifications
You must be signed in to change notification settings - Fork 271
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
Introduce Clock from three.js for step simulation of bullet world #1206
base: master
Are you sure you want to change the base?
Conversation
Yeah, the constant time step must be wrong. Clock is a small object but it would be great if it would be possible to avoid introducing another object. Are there plans to use it for something else ? Ammo itself has a btClock but it does not seem to do much. Does Ammo have a timer or another clock ? I could not find much.. A new TimeSensor seems like overkill, hm.. The RAF callback actually gets the current time as an argument:
main() does not use it but it would be possible to keep track of deltaTime there: main( time ). If the other Clock methods are not used that would avoid having to introduce the Clock object. What about passing deltaTime to updateRigidBodies from main: updateRigidBodies( time - lastTime ) ? Could that work ? That could be leaner. Do you want to try that ? [ In any case, src/util would be a better place for Clock.js Would there be advantages in using performance.now instead of Date.now ? Perhaps there is a Three.js issue. Is there a place to destroy/dereference the clock instance when the bulletworld/collidableShape is removed from the scene ? ] |
Using a btClock like this:
Using the current time of The RAF callback like this:
|
Well, performance.now may be better. |
That means the timestamp may not be fresh. |
Thanks for looking into all these. Could we just use the time in the RAF callback ? This seems simplest unless the Clock class is needed elsewhere. The lastTime declaration could be moved up into the first var statement. The check for undefined may be avoidable if lastTime is initialized in initScene or so but that does not seem to be worth the trouble. |
|
I think that timestamp may be more correct since we are concerned about the delta time between displayed frames, not the exact time the timestepping occurs ? RAF at time0: RAF at time1 = time0 + 1/60 or possibly 2/60 or 3/60s: This sequence would mean that the rendered physics is one frame behind (but perhaps all the other X3D animation is also one step behind since it is using the same delta time). Ideally, the physics call probably should happen before the render callback but how the callbacks are queued is unclear. If the physics callback happens first, I think the timestamp would be fresh anyways, |
|
Not only the callback of RAF, many other tasks may also be in the queue. That makes the timestamp not fresh. So I suggest getting a fresh timestamp when executing stepSimulation. |
|
In my mind, the timestamp should not be fresh for the Physics. It should be just close to the time a frame is rendered. This way the rendering can properly reflect the Physics. What am I missing ? Did you find a perceivable difference in practice ? |
Should all objects drop down at the same time ? |
Physics always earlier than graphics rendering. So the timestamp should be fresh. |
https://www.youtube.com/watch?v=dXZJdWgwOHk |
I just thought such a delay may actually be better for a smooth experience since the rendered state does not need to reflect the actual current time but I take your word for it. So let's just use performance.now. https://developer.mozilla.org/en-US/docs/Web/API/Performance/now#browser_compatibility says performance.now is well supported. Do we still need the fallback to Date.now ? |
performance.now is good. There are two reasons to use Clock.js: |
mrdoob/three.js#10732 was for node.js support which x3dom does not have. x3dom probably does not work well any more for browsers older than IE10 in any case. We could attach a lastTime to each bulletWorld, same as a new Clock is attached but a little cheaper. clock.stop() would be useful. On the other hand, the RigidBodyPhysics component ( https://www.web3d.org/specifications/X3Dv4Draft/ISO-IEC19775-1v4-CD1/Part01/components/rigidBodyPhysics.html#t-Topics ) does not seem to have a way to stop (or start) time. So I do not think we really need Clock.js and can keep it simpler. |
Maybe x3dom can provide a pause feature earlier than x3d. Now, the improvement should be like this:
|
Looks good. |
I am not sure but it may be possible to have multiple bulletWorlds using Inlines or Protos since they set up their own scenes. So perhaps saving lastTime per bulletWorld is safer: bulletWorld.setGravity( new Ammo.btVector3( 0, -9.81, 0 ) );
//Initialize lastTime. updateRigidbodies should be executed immediately
bulletWorld.lastTime = performance.now(); var deltaTime = ( timeStamp - bulletWorld.lastTime ) / 1000;
bulletWorld.lastTime = timeStamp; But it looks like substantial other changes would be also necessary. Getting and setting an object property like this is probably slightly slower than using a scoped variable. |
I prefer to put the lastTime into the bulletWorld. It works well. |
A bit less code and more future proof as well. |
Did you want to update the PR to just use performance.now and bulletWorld.lastTime ? |
Introduce Clock from three.js for step simulation of bullet world.
Clock.js requires es6.