Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Creating and Removing Pin Constraints from ObiPinConstraintsBatch
#4
Thank you, I see! 

I have updated it to iterate it in reverse, but unfortunately it still doesn't work.

Below are all the methods involved in the adhesion. I have also attached the entire Component for reference. The issue is the same (trying to remove the wrong indices from the stuck list.)


Code:
// These next functions are concerned with the adhesion behaviour

//q: this will resolve for all particles - isnt there quite an overhead calling this when we are only interested in a subset?
// can we only get this for a few particles or does this mean creating multiple solvers?

private void Solver_OnCollision(ObiSolver solver, ObiSolver.ObiCollisionEventArgs e)
{
    foreach (var item in e.contacts)
    {
        if (item.bodyB == Dummy.Handle.index && item.distance < 0.01)
        {
            var particle = item.bodyA;
            if (!stuck.Contains(particle) && !particlesToStick.Contains(particle))
            {
                particlesToStick.Add(particle);
            }
        }
    }
}

private void AddAdhesionConstraints()
{
    if (particlesToStick.Count > 0)
    {
        var bindMatrix = Dummy.transform.worldToLocalMatrix * actor.solver.transform.localToWorldMatrix;

        if (adhesionBatch == null)
        {
            adhesionBatch = new ObiPinConstraintsBatch();
        }

        foreach (var solverIndex in particlesToStick)
        {
            var positionOffset = bindMatrix.MultiplyPoint3x4(actor.solver.positions[solverIndex]);
            var orientationOffset = bindMatrix.rotation * actor.solver.orientations[solverIndex];

            adhesionBatch.AddConstraint(
                solverIndex,
                Dummy,
                positionOffset,
                orientationOffset,
                0,
                0,
                0.1f
            );

            //q: why is this needed?
            adhesionBatch.activeConstraintCount++;

            if(stuck.Contains(solverIndex))
            {
                Debug.Log("Error Type 1");
            }
            stuck.Add(solverIndex);

            actor.SetConstraintsDirty(Oni.ConstraintType.Pin);
        }

        particlesToStick.Clear();

        UpdateAdhesionBatch(); // This adds or removes the batch depending on whether there are any active constraints, and tells the solver to rebuild the pins[/font][/size][/color]
    }
}

private void BreakAdhesionConstraints(float stepTime)
{
    if (actor.isLoaded)
    {
        var actorConstraints = actor.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
        var solverConstraints = actor.solver.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;

        if (actorConstraints != null && adhesionBatch != null)
        {
            int batchIndex = actorConstraints.batches.IndexOf(adhesionBatch);
            if (batchIndex >= 0 && batchIndex < actor.solverBatchOffsets[(int)Oni.ConstraintType.Pin].Count)
            {
                int offset = actor.solverBatchOffsets[(int)Oni.ConstraintType.Pin][batchIndex];
                var solverBatch = solverConstraints.batches[batchIndex];

                float sqrTime = stepTime * stepTime;
                for (int i = adhesionBatch.constraintCount - 1; i >= 0; i--)
                {
                    // in case the constraint has been broken:

                    var b = -solverBatch.lambdas[(offset + i) * 4 + 3] / sqrTime;
                    if (b > adhesionBatch.breakThresholds[i])
                    {
                        var solverIndex = adhesionBatch.particleIndices[i];
                        if (!stuck.Remove(solverIndex))
                        {
                            Debug.Log("Error Type 2");
                        }
                        adhesionBatch.RemoveConstraint(i);

                        actor.SetConstraintsDirty(Oni.ConstraintType.Pin);
                    }
                }
            }

            UpdateAdhesionBatch(); // This adds or removes the batch depending on whether there are any active constraints, and tells the solver to rebuild the pins
        }
    }
}

/// <summary>
/// Adds or removes adhesionBatch from the solver, and marks it dirty,
/// depending on whether it holds any, or any new, constraints.
/// </summary>
private void UpdateAdhesionBatch()
{
    if(adhesionBatch == null)
    {
        return;
    }

    if(prevAdhesionConstraintCount == 0 && adhesionBatch.constraintCount > 0)
    {
        var pins = actor.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiPinConstraintsData;
        pins.AddBatch(adhesionBatch);
        prevAdhesionConstraintCount = adhesionBatch.constraintCount;
        actor.SetConstraintsDirty(Oni.ConstraintType.Pin);
    }

    if (prevAdhesionConstraintCount > 0 && adhesionBatch.constraintCount == 0)
    {
        var pins = actor.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiPinConstraintsData;
        pins.RemoveBatch(adhesionBatch);
        adhesionBatch = null;
        prevAdhesionConstraintCount = 0;
        actor.SetConstraintsDirty(Oni.ConstraintType.Pin);
    }           
}


Attached Files
.cs   AdhesiveCloth.cs (Size: 14.44 KB / Downloads: 2)
Reply


Messages In This Thread
RE: Creating and Removing Pin Constraints from ObiPinConstraintsBatch - by sebjf - 21-08-2023, 05:41 PM