jrouwe / JoltPhysics.js

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

Expose methods for exporting and importing the physics state's data #207

Closed RobvandenBerg closed 1 day ago

RobvandenBerg commented 4 days ago

When creating a synchronized experience between clients, it is sometimes necessary to send over the physics system's state, for example if a new client joins after the simulation has already started.

To allow this to happen, I propose that the following functions in StateRecorderImpl get exposed:

I suspect that exposing those functions would be enough to implement state synchronization over a network, but correct me if I am wrong.

jrouwe commented 3 days ago

The WriteBytes and ReadBytes functions are implementations of the StateRecorder interface and are used in Jolt to serialize/deserialize stuff. I think they're not too useful to the JS side.

The GetData and GetDataSize calls could be exposed (and I guess we'd need a SetData call then as well). As far as I can see JS can handle \0 characters anywhere in the string so it should not be an issue that the string is actually a binary blob.

Would that work for you? (i.e. can you send a string containing nulls over the net?)

RobvandenBerg commented 3 days ago

You are right that if WriteBytes and ReadBytes are not useful to the JS side, then a SetData function is indeed also necessary.

Getting the binary blob into a string should work just fine. Even a naïve approach of parsing the string to JSON (along with other state-related data) using JSON.stringify() and then decoding the JSON using JSON.parse() on the other client works fine for strings containing the \0 character.

And if that doesn't suffice, the binary blob string can always simply be converted to an Uint8Array before sending instead: let utf8Encode = new TextEncoder(); utf8Encode.encode("a binary string containing the \0 character");

In other words, your proposed solution should definitely be sufficient for this use-case!

jrouwe commented 1 day ago

I ran into an issue with WebIDL. It only supports exposing JS strings via char * which means I have no way of transferring 0 bytes from C++ to JS. So instead I exposed the StateRecorder interface so that you can write your own serialization logic. There's a (crude) example here:

https://github.com/jrouwe/JoltPhysics.js/blob/b242e26de4c8cf25a2dd39b8f2016dafe1285f10/Examples/snapshot.html#L47-L68