Obi Official Forum

Full Version: Obi Particle Attachment marking constraint as dirty every frame
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
When using ObiParticleAttachment as Dynamic constraint, the constraints are set to dirty every frame.
This causes the constraints to be re-created every frame which allocates GC every frame. 

A good example of what I mean is in the "Rocker" sample scene. I see 1 KB GC being allocated every frame.

Is there some way to check if the constraint actually changed before it is marked as dirty?
(21-10-2020, 04:10 PM)Kristianstoyl Wrote: [ -> ]When using ObiParticleAttachment as Dynamic constraint, the constraints are set to dirty every frame.
This causes the constraints to be re-created every frame which allocates GC every frame. 

A good example of what I mean is in the "Rocker" sample scene. I see 1 KB GC being allocated every frame.

Is there some way to check if the constraint actually changed before it is marked as dirty?

Hi,

Replace the UpdateDynamicAttachment method in ObiParticleAttachment.cs with this:

Code:
private void UpdateDynamicAttachment(float stepTime)
        {

            if (enabled && m_AttachmentType == AttachmentType.Dynamic && m_Actor.isLoaded && isBound)
            {

                var solver = m_Actor.solver;
                var blueprint = m_Actor.sourceBlueprint;

                var actorConstraints = m_Actor.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;
                var solverConstraints = solver.GetConstraintsByType(Oni.ConstraintType.Pin) as ObiConstraints<ObiPinConstraintsBatch>;

                bool torn = false;
                if (actorConstraints != null && pinBatch != null)
                {
                    // deactivate constraints over the break threshold.
                    int offset = actor.solverBatchOffsets[(int)Oni.ConstraintType.Pin][pinBatchIndex];
                    var solverBatch = solverConstraints.batches[pinBatchIndex];

                    float sqrTime = stepTime * stepTime;
                    for (int i = 0; i < pinBatch.activeConstraintCount; i++)
                    {
                        if (-solverBatch.lambdas[(offset + i) * 4 + 3] / sqrTime > pinBatch.breakThresholds[i])
                        {
                            pinBatch.DeactivateConstraint(i);
                            torn = true;
                        }
                    }
                }

                // constraints are recreated at the start of a step.
                if (torn)
                    m_Actor.SetConstraintsDirty(Oni.ConstraintType.Pin);
            }
        }

That should get rid of the allocation. Thanks for reporting this!