jrouwe / JoltPhysics.js

Port of JoltPhysics to JavaScript using emscripten
MIT License
270 stars 21 forks source link

Compile to WASM with double precision #10

Closed Myrindd closed 1 year ago

Myrindd commented 1 year ago

I am trying to compile to WASM with p_threads in order to use as a library inside a larger WASM project that is multithreaded. In the cmakelists, I added "-s USE_PTHREADS" in order to make the compilation work for the larger project. Afterward, I simply replicated the helloworld example, but when creating a shape with the body interface, the application crashes with the traditional "memory access out of bound" error happening during atomic_fetch_add. Is it possible to compile with p_thread to WASM? If so, how should the cmakelist be modified?

edit: the title was changed to reflect the evolution of the problem

Myrindd commented 1 year ago

I have isolated the problem: it appears to be coming from enabling double precision math when compiling Jolt; is 64bit precision compatible with WASM?

jrouwe commented 1 year ago

Do you have a full callstack for this? And are there any interesting things in the console output (e.g. it's running out of memory?)

Myrindd commented 1 year ago

Here is the result in the console:

image
Myrindd commented 1 year ago

Here is the result of -fsanitize=address

image
jrouwe commented 1 year ago

According to ASAN your stack is not big enough. I have -s TOTAL_STACK=1048576 on my emcc commandline to enlarge the stack size.

PhysicsSystem (1.3K) and JobSystemThreadPool (8.6K) are large classes. If you don't want to allocate more stack, you can also new these so they end up on the heap instead of on the stack.

Myrindd commented 1 year ago

Thanks for the explanations; I tried increasing the stack to 2MB and to put the PhysicsSystem on the heap, but the error is still happening:

image

It seems there is a 4 byte overflow at the end of floor_settings, which matches with the double_precision (8 bytes instead of 4). Could it be related to MassProperties.mInertia?

jrouwe commented 1 year ago

The floor_settings object is 240 bytes in single precision mode and 256 bytes in double precision mode. The only difference is in the mPosition member (which is at the beginning of the class). This does not seem to match up with the 'offset 500' that ASAN is complaining about.

Could it be that you compile the Jolt source code with a different set of defines than the rest of your code? E.g. if you compile Jolt with JPH_DOUBLE_PRECISION then Jolt would treat the struct as 256 bytes long and if you compile your own code without JPH_DOUBLE_PRECISION then it would treat it as a 240 bytes object so it would contain garbage for Jolt.

Myrindd commented 1 year ago

I am compiling Jolt as a .a shared library that I incorporate in the cmakelist for my own system; but I also refer to the actual source code, so it could be indeed. I will have a look.

Myrindd commented 1 year ago

You are absolutely right; it appears that was the issue. Sorry for wasting your time! Amazing job by the way; as someone who has developed a functional 3D physics engine before, I understand how painstakingly difficult it is (which is why I am considering using yours!).