Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Save/Load Obi Rope state and rope network state synchronization
#1
Hello! Does anyone have any code or ideas for serializing/deserializing a rope over a network?
Reply
#2
(24-05-2021, 07:32 AM)pmike Wrote: Hello! Does anyone have any code or ideas for serializing/deserializing a rope over a network?

You do this just like you'd do with any other object: send positions and velocities over. In Obi's case, particle positions and velocities.

If you're using UDP, passing a timestamp would be a good idea too. Client side you can implement dead reckoning by just letting the simulation run in-between snapshots.

You can get/set per-particle data (positions, velocities, etc) using the particles API:
http://obi.virtualmethodstudio.com/tutor...icles.html
Reply
#3
(24-05-2021, 07:41 AM)josemendez Wrote: You do this just like you'd do with any other object: send positions and velocities over. In Obi's case, particle positions and velocities.

If you're using UDP, passing a timestamp would be a good idea too. Client side you can implement dead reckoning by just letting the simulation run in-between snapshots.

You can get/set per-particle data (positions, velocities, etc) using the particles API:
http://obi.virtualmethodstudio.com/tutor...icles.html

Can you give a sample code for saving and loading the rope state using particles API?
Reply
#4
(24-05-2021, 08:05 AM)pmike Wrote: Can you give a sample code for saving and loading the rope state using particles API?

There's sample code for this in the link I just posted. To read:

Code:
for (int i = 0; i < actor.solverIndices.Length; ++i)
{
    int solverIndex = actor.solverIndices[i];
    var pos = actor.solver.positions[solverIndex];
    var vel =  actor.solver.velocities[solverIndex];
}

To write:

Code:
for (int i = 0; i < actor.solverIndices.Length; ++i)
{
    int solverIndex = actor.solverIndices[i];
    actor.solver.positions[solverIndex] = yourPos;
    actor.solver.velocities[solverIndex] = yourVel;
}
Reply
#5
(24-05-2021, 08:27 AM)josemendez Wrote: There's sample code for this in the link I just posted. To read:

Code:
for (int i = 0; i < actor.solverIndices.Length; ++i)
{
    int solverIndex = actor.solverIndices[i];
    var pos = actor.solver.positions[solverIndex];
    var vel =  actor.solver.velocities[solverIndex];
}

To write:

Code:
for (int i = 0; i < actor.solverIndices.Length; ++i)
{
    int solverIndex = actor.solverIndices[i];
    actor.solver.positions[solverIndex] = yourPos;
    actor.solver.velocities[solverIndex] = yourVel;
}

Thanks a lot!
Reply
#6
Another question: how to effectively serialize and deserialize object of type ObiNativeVector4List? 

Direct serialization via BinaryFormatter does not work:

SerializationException: Type 'Obi.ObiNativeList`1[[UnityEngine.Vector4, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]' in Assembly 'Obi, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

But type


namespace Obi
{
    [Serializable]
    public class ObiNativeVector4List : ObiNativeList<Vector4>
    { ...
Reply
#7
(24-05-2021, 12:16 PM)pmike Wrote: Another question: how to effectively serialize and deserialize object of type ObiNativeVector4List? 

Direct serialization via BinaryFormatter does not work:

SerializationException: Type 'Obi.ObiNativeList`1[[UnityEngine.Vector4, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]' in Assembly 'Obi, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

But type


namespace Obi
{
    [Serializable]
    public class ObiNativeVector4List : ObiNativeList<Vector4>
    { ...

ObiNativeList internally holds a raw pointer to unmanaged data, so BinaryFormatter won't work. Furthermore, serializing the entire list does not make much sense in this context, as you're interested in the data for each individual actor, not the entire solver. There's no guarantee data belonging to different actors will be laid out in memory in exactly the same way in different machines.

Internally we use Unity's ISerializationCallbackReceiver interface to manually serialize/deserialize this data using unsafe operations (Unity.Collections.LowLevel.Unsafe), however this is *unsafe* as the name implies and can easily crash if you're not 100% sure of what you're doing.

Easiest way is probably to just iterate trough the list manually and serialize each entry to a format of your choice.
Reply
#8
(24-05-2021, 12:26 PM)josemendez Wrote: ObiNativeList internally holds a raw pointer to unmanaged data, so BinaryFormatter won't work. Furthermore, serializing the entire list does not make much sense in this context, as you're interested in the data for each individual actor, not the entire solver. There's no guarantee data belonging to different actors will be laid out in memory in exactly the same way in different machines.

Internally we use Unity's ISerializationCallbackReceiver interface to manually serialize/deserialize this data using unsafe operations (Unity.Collections.LowLevel.Unsafe), however this is *unsafe* as the name implies and can easily crash if you're not 100% sure of what you're doing.

Easiest way is probably to just iterate trough the list manually and serialize each entry to a format of your choice.

Thanks!
Reply
#9
Hello! 
One more question. How can I pause the rope after loading the state, i.e. turn it into a "static spline" for a while?
Reply
#10
(27-05-2021, 08:28 AM)pmike Wrote: Hello! 
One more question. How can I pause the rope after loading the state, i.e. turn it into a "static spline" for a while?
Depending on what you want to do, you can disable the ObiRope component or the ObiSolver component.

Disabling the rope will remove all particle/constraint data from the solver, but keep the rope mesh being rendered. Disabling the solver will keep all particle/constraint data in place, but will stop updating the simulation.
Reply