dimforge / rapier.js

Official JavaScript bindings for the Rapier physics engine.
https://rapier.rs
Apache License 2.0
416 stars 57 forks source link

How to ensure determinism used in js #151

Open wuluwululang opened 2 years ago

wuluwululang commented 2 years ago

We know that 0.1 + 0.2 != 0.3 in js, if I pass the result of 0.1+0.2 into rapier.js in different operating systems and processor architectures, will it cause non-deterministic?

for example,

const currentControlling: RigidBody = ...
currentControlling.setLinvel({x: 0.1+0.2, y: 0.1+0.2}, true);
currentControlling.setAngvel(0.1+0.2, true);
currentControlling.setRotation(Math.sin(60), true);
sebcrozet commented 2 years ago

0.1 + 0.2 will return the same results on all platforms because JS complies to the IEEE 754 standard. So:

currentControlling.setLinvel({x: 0.1+0.2, y: 0.1+0.2}, true);
currentControlling.setAngvel(0.1+0.2, true);

will behave deterministically.

However Math.sin may result in different results on different platforms because each platform can have its own implementation of Math.sin (transcendental functions are not specified in IEEE 754). So you need to either provide your own implementation of Math.sin or find a package that implements this for you.

LeXXik commented 2 years ago

Speaking of sin and cos, I was using them to find the position of an object in the frame of another object: image

But then, I suppose, I am losing the determinism every time I do it. Is there a way to do it without using sin/cos? I guess I could try storing the position in a matrix, then use an inverse of it to transform the position. That should preserve determinism presumably?

wuluwululang commented 2 years ago

0.1 + 0.2 will return the same results on all platforms because JS complies to the IEEE 754 standard. So:

currentControlling.setLinvel({x: 0.1+0.2, y: 0.1+0.2}, true);
currentControlling.setAngvel(0.1+0.2, true);

will behave deterministically.

However Math.sin may result in different results on different platforms because each platform can have its own implementation of Math.sin (transcendental functions are not specified in IEEE 754). So you need to either provide your own implementation of Math.sin or find a package that implements this for you.

Thanks for the answer, it helped me a lot.

myagoo commented 1 year ago

Speaking of sin and cos, I was using them to find the position of an object in the frame of another object: image

But then, I suppose, I am losing the determinism every time I do it. Is there a way to do it without using sin/cos? I guess I could try storing the position in a matrix, then use an inverse of it to transform the position. That should preserve determinism presumably?

As @sebcrozet said :

However Math.sin may result in different results on different platforms because each platform can have its own implementation of Math.sin (transcendental functions are not specified in IEEE 754). So you need to either provide your own implementation of Math.sin or find a package that implements this for you.