Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Releasing softbody particles from anchor
#1
Following along the script example here:
Code:
using UnityEngine;
using System.Collections;
using Obi;

[RequireComponent(typeof(ObiActor))]
public class DistanceAnchor : MonoBehaviour {

    ObiActor actor;
    public Transform anchor;
    public float anchorRadius = 0.5f;

    void Awake(){
        actor = GetComponent<ObiActor>();
    }

    void Start(){
        if (actor.isLoaded){
            for (int i = 0; i < actor.solverIndices.Length; ++i){

                int solverIndex = actor.solverIndices[i];

                // if the particle is visually close enough to the anchor, fix it.
                if (Vector3.Distance(actor.GetParticlePosition(solverIndex), anchor.position)
                        < anchorRadius)
                {
                    actor.solver.velocities[solverIndex] = Vector3.zero;
                    actor.solver.invMasses[solverIndex] = 0;
                }
            }
        }
    }
}
From: http://obi.virtualmethodstudio.com/manua...icles.html

What is a good approach to later release the softbody particles from the anchor?
I tried saving a copy of `velocities` and `invMasses` prior to setting them to 0, and then restoring them on the actor's solver when some callback gets invoked. This did not seem to work.

or is there a way to disable gravity on the exclusively on the softbody particles?
Reply
#2
(26-03-2023, 11:57 PM)blobman Wrote: What is a good approach to later release the softbody particles from the anchor?
I tried saving a copy of `velocities` and `invMasses` prior to setting them to 0, and then restoring them on the actor's solver when some callback gets invoked. This did not seem to work.

Hi!

Make sure to call UpdateParticleProperties() on a softbody after modifying its particle properties. This is needed for softbodies only, because the rest shape configuration of the softbody needs to be updated if the mass or position of particles are modified.

See the ObiContactGrabber.cs sample script for reference.

(26-03-2023, 11:57 PM)blobman Wrote: or is there a way to disable gravity on the exclusively on the softbody particles?

You can disable gravity for the entire solver by setting it to zero, and then implement your own gravity by adding a custom acceleration to particles of your choice. (that is, increasing their velocity)


let me know if you need further help,
Reply
#3
Thanks for your reply. For now we found a workaround using the Teleport method on the softbody. Will let you know if we try the anchor method again!

FYI: I don't think this bug got patched:
http://obi.virtualmethodstudio.com/forum...l#pid13810

Had to manually patch it in Obi Softbody 6.5.1

Okay. The teleport work around seem work yesterday. However today, I'm running into index out of bounds at a different line:

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 <b6c5d0f08ddf477186f780f49bb14dee>:0)
Obi.ObiSoftbody.Teleport (UnityEngine.Vector3 position, UnityEngine.Quaternion rotation) (at Assets/Obi/Scripts/Softbody/Actors/ObiSoftbody.cs:198)
ModelAPI.Teleport (UnityEngine.Vector3 position) (at Assets/Scripts/Model/API.cs:22)
API.Start () (at Assets/Scripts/API.cs:86)

Code at Assets/Obi/Scripts/Softbody/Actors/ObiSoftbody.cs:198:

Code:
        public override void Teleport(Vector3 position, Quaternion rotation)
        {
            base.Teleport(position, 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;

            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]; // Line 198

                for (int j = 0; j < ac.batches[i].activeConstraintCount; ++j)
                {
                    sc.batches[i].orientations[batchOffset + j] = rotOffset * sc.batches[i].orientations[batchOffset + j];  // http://obi.virtualmethodstudio.com/forum/thread-3742-post-13810.html#pid13810
                }
            }

        }

Tried setting rotation to `Quaternion.identity` or rotation on the model's transform.

Update:
Teleport method seems to work when I invoke in `Update`, but does not in `Start`. So perhaps there is some softbody initialize at runtime I need to watch out for?

Update2: 
Perhaps the issue is here:
Code:
        public override void LoadBlueprint(ObiSolver solver)
        {
            base.LoadBlueprint(solver);
            RecalculateCenterShape();
            SetSelfCollisions(m_SelfCollisions);
        }
Where the softbody actor is set to loaded after running `base.LoadBlueprint(solver);` but needs to run `RecalculateCenterShape();` to be fully loaded?

Update3: 
Found the issue. It's due to application not yet playing ... so have to wait until that flag is flipped!
Reply