Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Creating and Removing Pin Constraints from ObiPinConstraintsBatch
#7
I've managed to get it almost completely working now. 

Instead of adding constraints, I find if there is an existing constraint for that solver index. If there is, I update the batch's array properties and activate the index. Similarly, instead of removing constraints they are deactivated.

Code:
bool found = false;
for (int i = 0; i < adhesionBatch.constraintCount; i++)
{
if (adhesionBatch.particleIndices[i] == solverIndex)
{
adhesionBatch.pinBodies[i] = Dummy.Handle;
adhesionBatch.colliderIndices[i] = Dummy.Handle.index;
adhesionBatch.offsets[i] = positionOffset;
adhesionBatch.restDarbouxVectors[i] = orientationOffset;
// And everything else is the same...
found = true;
adhesionBatch.ActivateConstraint(i);
break;
}
}


What is odd is that even after this, when I created constraints on-demand (if they were not found), I would get occasions where the lists would lose sync still! However, if I pre-create a constraint for each actor particle's solver index in Start(), then it works correctly (which makes me think it is something to do with growing the array between activations/deactivations).

I prefer this solution regardless as it avoids reallocations. 

The only thing I don't like is needing to search the particleIndices when activating a constraint. Though my cloth has very few particles, I will try and use the m_ID and m_IDToIndex to persistently associate solver particles with an identity.


This is what I have so far, 

Code:
private void Start()
{
    actor.solver.OnCollision += Solver_OnCollision;
    graspBatch = new ObiPinConstraintsBatch();
    adhesionBatch = new ObiPinConstraintsBatch();

    // Pre-create the adhesion constraints

    actorIndexToConstraintId = new List<int>();
    for (int i = 0; i < actor.particleCount; i++)
    {
        var solverIndex = actor.solverIndices[i];
        adhesionBatch.AddConstraint(
            solverIndex,
            Dummy,
            Vector3.zero,
            Quaternion.identity,
            0,
            0,
            0.1f
        );
        actorIndexToConstraintId.Add(i);
    }
}

And then to look up the constraint from the solver index:

Code:
// Lookup the constraint index
var i = adhesionBatch.GetConstraintIndex(actorIndexToConstraintId[actor.solver.particleToActor[solverIndex].indexInActor]);

However this fails, and I need for now to get the constraintIndex by iterating the particles:

Code:
for (int j = 0; j < adhesionBatch.constraintCount; j++)
{
    if (adhesionBatch.particleIndices[j] == solverIndex)
    {
        if(i != j)
        {
            Debug.Log("Constraint Id Changed");
        }

        i = j;
        break;
    }
}

If I can get the above to work I can do away with the lists entirely and just store flags for each actor particle, which would be much nicer.


Attached Files
.cs   AdhesiveCloth.cs (Size: 15.73 KB / Downloads: 7)
Reply


Messages In This Thread
RE: Creating and Removing Pin Constraints from ObiPinConstraintsBatch - by sebjf - 25-08-2023, 03:13 PM