Obi Official Forum
Help Upgrading version 4 code (esp. GetConstraintsInvolvingParticle) - Printable Version

+- Obi Official Forum (https://obi.virtualmethodstudio.com/forum)
+-- Forum: Obi Users Category (https://obi.virtualmethodstudio.com/forum/forum-1.html)
+--- Forum: Obi Cloth (https://obi.virtualmethodstudio.com/forum/forum-2.html)
+--- Thread: Help Upgrading version 4 code (esp. GetConstraintsInvolvingParticle) (/thread-3447.html)



Upgrading version 4 code (esp. GetConstraintsInvolvingParticle) - itkdk - 09-05-2022

Hi,

I recently took over a project (from people no longer at my company) and am trying to upgrade Obi (Cloth and Rope) from version 4.0 to 6.4. I get a handful of errors because of API changes and managed to adjust most of the code, but one method in particular is hard to update. One part of the problem is that our code is not well documented (or well written, sadly), but also I'm having trouble finding info on how to replace methods that no longer exist, especially ObiConstraint(s)Batch#GetConstraintsInvolvingParticle(int particleIndex). In the old version, our method borrowed heavily from ObiTearableCloth#ApplyTearing(), but it changed drastically after the upgrade. Our method was added to ObiTearableCloth and is called from within a solver collision callback with the index of a ParticleInActor for each contact in the ObiCollisionEventArgs.
Here's the method, I added comments behind the lines I believe to be unnecessary:
DistanceConstraints.AddToSolver(this); // unnecessary? ApplyTearing() no longer calls it
Code:
public void CustomCut(int index)
{
    ObiDistanceConstraintBatch distanceBatch = DistanceConstraints.GetFirstBatch();
    float[] forces = new float[distanceBatch.ConstraintCount]; // unnecessary and...
    Oni.GetBatchConstraintForces(distanceBatch.OniBatch, forces, distanceBatch.ConstraintCount, 0); // unnecessary, because "forces" isn't used

    List<TornEdge> tornEdges = new List<TornEdge>();

    foreach (ObiConstraintBatch batch in DistanceConstraints.GetBatches())
    {
        List<int> affectedConstraints = batch.GetConstraintsInvolvingParticle(index);

        for(int i = 0; i<affectedConstraints.Count; i++)
        {
            Tear(affectedConstraints[i]);
        }

        //Tear(affectedConstraints[0]);

        DistanceConstraints.AddToSolver(this); // unnecessary? ApplyTearing() no longer does this in new version

        // update active bending constraints:
        BendingConstraints.SetActiveConstraints(); // unnecessary? ApplyTearing() no longer does this in new version

        // update solver deformable triangle indices:
        UpdateDeformableTriangles();

        // upload active particle list to solver:
        solver.UpdateActiveParticles(); // unnecessary? ApplyTearing() no longer does this in new version
    }
}

Here's where I'm at right now, stuck on how to replace GetConstraintsInvolvingParticle() and construct the correct StructuralConstraints for the Tear() call:

Code:
public void CustomCut(int index)
{
    var distanceConstraints = GetConstraintsByType(Oni.ConstraintType.Distance) as ObiDistanceConstraintsData;
    foreach (ObiConstraintsBatch batch in distanceConstraints.batches)
    {
        List<int> affectedConstraints = batch.GetConstraintsInvolvingParticle(index);
        
        for(int i = 0; i < affectedConstraints.Count; i++)
        {
            Tear(affectedConstraints[i]);
        }
        // update solver deformable triangle indices:
        UpdateDeformableTriangles();
    }
}
Any hints on how to rewrite this or confirmation on the three calls after the loop I marked no longer being necessary?
Thanks!


RE: Upgrading version 4 code (esp. GetConstraintsInvolvingParticle) - josemendez - 10-05-2022

Hi there!

The 3 calls above are no longer necessary. Actors are automatically added to the first solver up their hierarchy, no need to call AddToSolver() manually. Also, the solver stores some "dirty" flags which automatically update active constraints or particles when necessary, so no need for SetActiveConstraints() or UpdateActiveParticles().

Regarding batch.GetConstraintsInvolvingParticle(), it was removed due to how inefficient it is (linear search trough all constraints in the cloth). Note you can still reimplement it if you want, it just iterates trough all constraints in the batch checking its particleIndices array for references to that particle. Each distance constraint references 2 particles, so something like:

Code:
for (int i = 0; i < activeConstraintCount; ++i)
{
if (particleIndices[i*2] == particleIndex || particleIndices[i*2+1] == particleIndex)
    affectedConstraints.Add(i/2);
}