21-08-2023, 05:41 PM
(This post was last modified: 21-08-2023, 05:43 PM by sebjf.
Edit Reason: Added attachment
)
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.)
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);
}
}