Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Obi Particle Attachment marking constraint as dirty every frame
#1
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?
Reply
#2
(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!
Reply