08-04-2019, 01:49 PM
(08-04-2019, 01:24 PM)josemendez Wrote: Hi,
The original code is 100% correct.
Rest positions are used internally to ensure particles that initially overlap do not generate inter collisions. So what this code does is :take the first particle in the array as the reference frame (hence lastParticle is only updated if i == 0), then iterate over all other particles calculating the distance from the current particle to the first particle (assuming the rope is tense and completely straight along the X axis): accumulatedDistance += Mathf.Min(interParticleDistance,principalRadii[particle][0],principalRadii[lastParticle][0]);
Your code will generate incorrect rest positions, because it adds to accumulatedDistance the radius of the smallest particle encountered up to the current particle, instead of the minimum between the first one, the current one and the inter-particle distance. This will cause false negatives when dealing with self-collisions, leading to jitter.
So, if I understand you right, this code may work as original implementation but not flow to GC:
public override void RegenerateRestPositions(){
ObiDistanceConstraintBatch distanceBatch = DistanceConstraints.GetFirstBatch();
if (distanceBatch.ConstraintCount > 0)
{
Vector3 right=Vector3.right;
// Iterate trough all distance constraints in order:
float accumulatedDistance = 0;
restPositions[0] = new Vector4(0, 0, 0, 1);
float mindistance = Mathf.Min(interParticleDistance, principalRadii[distanceBatch.springIndices[0]][0]);
for (int i = 1; i < distanceBatch.ConstraintCount; ++i)
{
int particle = distanceBatch.springIndices[i * 2 + 1];
accumulatedDistance += Math.Min(principalRadii[particle][0],mindistance);
var ditanceoffset = right * accumulatedDistance;
restPositions[particle] =new Vector4(ditanceoffset.x,ditanceoffset.y,ditanceoffset.z,1);
}
PushDataToSolver(ParticleData.REST_POSITIONS);
}
}