Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
What is the role of Shape Matching Constraints?
#1
I cannot change the TransForm of an OBi SoftBody if the Shape Matching Constraints of the OBi SoftBody is enabled.


I don't see anything in the documentation about that...
http://obi.virtualmethodstudio.com/manua...aints.html

However, if Shape Matching Constraints is not enabled, you cannot change that parameter.
How can I change TransForm while Shape Matching Constraints is enabled?

What are Shape Matching Constraints anyway?
Reply
#2
(25-11-2023, 03:06 PM)KBTIT_ Wrote: I cannot change the TransForm of an OBi SoftBody if the Shape Matching Constraints of the OBi SoftBody is enabled.

Hi,

You can't change the transform of a softbody, or any deformable object for that matter. Due to their mathematical nature transforms only work on rigid objects: a transform specifies a single position/rotation/scale, but on a deformable object all of its parts can be at different positions/rotations/sizes so using a single transform on the entire object doesn't make any sense.

(25-11-2023, 03:06 PM)KBTIT_ Wrote: I don't see anything in the documentation about that...

Transforms are a part of Unity, and this is the usual behavior of transforms in all kinds of 3d software. As such, it is not mentioned in Obi's documentation since it is a basic concept in 3d. Transforms behave the same way with Unity's own deformable objects such as cloth or particles, and in all other existing 3d software (Blender, Maya, 3dsMax, etc): changing the transform either has no effect on the deformable object, or it is impossible to change it.

(25-11-2023, 03:06 PM)KBTIT_ Wrote: However, if Shape Matching Constraints is not enabled, you cannot change that parameter. How can I change TransForm while Shape Matching Constraints is enabled?

Depending on what your specific goal is, you can:
  • Rigidly attach some particles to a transform using a static attachment, then move the transform. This will move the attached particles, and all other particles in the softbody will follow due to physics. You can see an example of this in the included "RubberDragon" sample scene, the bottom part of the dragon is attached to a transform and will follow it.
  • Teleport the softbody to a new location using softbody.Teleport(); This will instantly move all particles in the softbody to a new position/rotation, using the body center of mass as the pivot point.
  • Move individual particles around using the particles API
  • Use the solver transform, which will translate/rotate/scale the entire simulation space and all actors (such as softbodies) contained in it. This is because simulation takes place in the solver’s local space, as explained in the manual.

(25-11-2023, 03:06 PM)KBTIT_ Wrote: What are Shape Matching Constraints anyway?

Obi is a particle-based engine, where particles are linked to each other using constraints:

http://obi.virtualmethodstudio.com/manua...index.html
Quote:Obi is a collection of particle-based physics plugins for Unity. Everything in Obi is made out of small spheres called particles. Particles can interact with each other, affect and be affected by other objects trough the the use of constraints.

Shape matching constraints are a specific type of constraint that groups multiple particles in what's called a "cluster", allowing them to move together giving rise to softbody deformation.

http://obi.virtualmethodstudio.com/manua...aints.html
Quote:Shape matching constraints link a group of particles together and try to keep them in the same position and orientation relative to each other, while allowing the group as a whole to rotate and translate freely. Each individual group of particles is generally referred to as a "cluster". Multiple clusters can overlap, and the particles shared between them will try to minimize deformation for all clusters they're involved with. This mechanism is used to allow some degree of deformation in softbodies.

You can find a detailed explanation of how the engine works in the manual, along with a comprehensive list of all constraint types besides shape matching:
http://obi.virtualmethodstudio.com/manua...gence.html

Shape matching is a very common rigid and softbody simulation technique in all kinds of software (the other most common method being FEM). If you're interested in some more techical info here's some documents/videos explaining shape matching in detail:

https://graphics.stanford.edu/courses/cs...muller.pdf
https://matthias-research.github.io/page...ticles.pdf
https://mmacklin.com/uppfrta_preprint.pdf
https://youtu.be/3OmkehAJoyo?feature=shared&t=563

Many other softbody simulation software uses shape matching constraints, a couple examples:
https://www.sidefx.com/docs/houdini/vell...ching.html
https://grasshopperdocs.com/components/f...raint.html
Reply
#3
Thank you for your response.

I tried using Softbody.Teleport() and confirmed that Softbody starts moving mysteriously unless all of the Quaternion rotation is 0.
The Gravity in Obi Solver is all 0.
The object to which the Obi Collider is attached does not exist in the scene.

There is no documentation for Softbody.Teleport and I cannot solve this problem.
What is the reason for this?
Reply
#4
(26-11-2023, 05:01 PM)KBTIT_ Wrote: Thank you for your response.

I tried using Softbody.Teleport() and confirmed that Softbody starts moving mysteriously unless all of the Quaternion rotation is 0.
The Gravity in Obi Solver is all 0.

Hi,

I’m unable to reproduce this, Teleport() only changes particle positions. It will not affect velocities, so if particles weren’t moving before being teleported, they shouldn’t move after.

After testing this is multiple settings, I've discovered a regression bug in ObiSoftbody's implementation of Teleport in the latest version that introduces rotational energy when using a non-unit quaternion, just like you described. Here's a corrected version, replace the Teleport() function in Obi/Scripts/Softbody/Actors/ObiSoftbody.cs with this one:

Code:
public override void Teleport(Vector3 position, Quaternion rotation)
        {
            if (!isLoaded)
                return;

            Matrix4x4 offset = solver.transform.worldToLocalMatrix *
                   Matrix4x4.TRS(position, Quaternion.identity, Vector3.one) *
                   Matrix4x4.TRS(Vector3.zero, rotation, Vector3.one) *
                   Matrix4x4.TRS(Vector3.zero, Quaternion.Inverse(transform.rotation), Vector3.one) *
                   Matrix4x4.TRS(-transform.position, Quaternion.identity, Vector3.one) *
                   solver.transform.localToWorldMatrix;

            Quaternion rotOffset = offset.rotation;

            base.Teleport(position, rotation);

            var ac = GetConstraintsByType(Oni.ConstraintType.ShapeMatching) as ObiConstraints<ObiShapeMatchingConstraintsBatch>;
            var sc = solver.GetConstraintsByType(Oni.ConstraintType.ShapeMatching) as ObiConstraints<ObiShapeMatchingConstraintsBatch>;

            // rotate clusters accordingly:
            for (int i = 0; i < ac.GetBatchCount(); ++i)
            {
                int batchOffset = solverBatchOffsets[(int)Oni.ConstraintType.ShapeMatching][i];

                for (int j = 0; j < ac.batches[i].activeConstraintCount; ++j)
                {
                    sc.batches[i].orientations[batchOffset + j] = rotOffset * sc.batches[i].orientations[batchOffset + j];
                }
            }
        }

Quote:The object to which the Obi Collider is attached does not exist in the scene.

Not sure what you mean by this. If the object does not exist, how can it have a component (ObiCollider) attached to it? What does this have to do with the Teleport() problem?

kind regards,
Reply
#5
Thanks for the confirmation.

I have applied the Teleport fix.
However, I am getting the following error in Teleport.

Code:
ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
System.Collections.Generic.List`1[T].get_Item (System.Int32 index) (at <88e4733ac7bc4ae1b496735e6b83bbd3>:0)
Obi.ObiSoftbody.Teleport (UnityEngine.Vector3 position, UnityEngine.Quaternion rotation) (at Assets/Obi/Scripts/Softbody/Actors/ObiSoftbody.cs:183)
This occurred before the Teleport modification, so the use of the Teleport source code is irrelevant.

The SoftBody that Teleport is using is based on the following method.
http://obi.virtualmethodstudio.com/manua...ctors.html

The error is generated by the following code

Code:
// parent the softbody under a solver to start simulation:
softbody.transform.parent = solver.transform;

IEnumerator bind = skinner.BindSkin();
while (bind.MoveNext()) { }

softbody.transform.parent = solver.transform;
softbody.Teleport(new Vector3(0, 0, 0) , Quaternion.Euler(0, 0, 90)); //Error

The solution to this problem is simple: simply wait in front of Teleport as shown below. However, this is not preferred.
Code:
yield return new WaitForSeconds(1.0f);
How do I resolve this ArgumentOutOfRangeException error?
Reply
#6
(27-11-2023, 04:53 PM)KBTIT_ Wrote: The solution to this problem is simple: simply wait in front of Teleport as shown below. However, this is not preferred.
Code:
yield return new WaitForSeconds(1.0f);
How do I resolve this ArgumentOutOfRangeException error?

Hi,

You can't Teleport() an actor that hasn't yet been loaded in the solver. You must wait for it to be loaded, either by waiting one frame or by subscribing to the actor's OnBlueprintLoaded event. Note that you can use actor.isLoaded to check whether the actor has had its data loaded on the solver or not.

Also note that there isn't any need to teleport the actor right after instantiating it. Simulation hasn't started yet, so you can just instantiate it in the correct position/orientation by modifying softbody.transform directly.

kind regards,
Reply
#7
(27-11-2023, 05:19 PM)josemendez Wrote: Hi,

You can't Teleport() an actor that hasn't yet been loaded in the solver. You must wait for it to be loaded, either by waiting one frame or by subscribing to the actor's OnBlueprintLoaded event. Note that you can use actor.isLoaded to check whether the actor has had its data loaded on the solver or not.

Also note that there isn't any need to teleport the actor right after instantiating it. Simulation hasn't started yet, so you can just instantiate it in the correct position/orientation by modifying softbody.transform directly.

kind regards,
Thank you very much. This issue has been resolved.
Reply