14-05-2024, 12:47 PM
(This post was last modified: 14-05-2024, 12:56 PM by josemendez.)
Hi,
Your script is incorrect:
Say you collide against a simplex of size 1: the if (simplexSize > 1) condition won't be met, so you won't iterate trough all particles in the simplex to find the closest one and instead will keep the original value of particleIndex = solver.simplices[contact.bodyA]; which is incorrect in case the solver contains *any* simplex of size other than 1.
So what's happening is that you collide against the softbody, and since its simplices have size 1 the "if" clause is skipped, so you keep solver.simplices[contact.bodyA] as your particle index which may belong to any other actor - in this case one of the ropes.
Keep in mind that simplices are stored as tuples of particle indices. The first few entries in the solver.simplices array are tuples of 3 (triangle simplices, used by cloth), the ones in the middle are tuples of 2 (used by ropes) and the ones at the end are single particle indices. Given a simplex index, the GetSimplexStartAndSize function will calculate for you the index of its first particle in the simplices array. For instance if you have 4 3-simplices, 5 2-simplices and 10 1-simplices, the starting index of the 6th simplex would be 4*3 + 2*2 = 16. The starting index of the 12th simplex would be 4*3 + 5*2 + 3*1 = 25, so even if its a 1-simplex its starting index would not be 12. If you used 12 as your index instead of 25, you would be accessing a particle belonging to another actor.
So if there's anything other than just 1-simplices in your solver, as seems to be your case, you can't assume solver.simplices[contact.bodyA] will contain the correct index. You must then always use GetSimplexStartAndSize. As per the manual:
http://obi.virtualmethodstudio.com/manua...sions.html
Your script is incorrect:
Code:
// get the particle index directly, as all simplices are guaranteed to have size 1:
int particleIndex = solver.simplices[contact.bodyA];
//check surface collisions
// retrieve the offset and size of the simplex in the solver.simplices array:
int simplexStart = solver.simplexCounts.GetSimplexStartAndSize(contact.bodyA, out int simplexSize);
// starting at simplexStart, iterate over all particles in the simplex:
if (simplexSize > 1)
{
//now this is surface collision, we have to find the real particleIndex which is nearest to the local Pos B
var minDist = 9999f;
var localPosB = contact.pointB;
for (int i = 0; i < simplexSize; ++i)
{
var testParticleIndex = solver.simplices[simplexStart + i];
var dist = Vector3.Distance(solver.positions[testParticleIndex], localPosB);
if (dist < minDist) {
minDist = dist;
particleIndex = testParticleIndex;
}
}
}
Say you collide against a simplex of size 1: the if (simplexSize > 1) condition won't be met, so you won't iterate trough all particles in the simplex to find the closest one and instead will keep the original value of particleIndex = solver.simplices[contact.bodyA]; which is incorrect in case the solver contains *any* simplex of size other than 1.
So what's happening is that you collide against the softbody, and since its simplices have size 1 the "if" clause is skipped, so you keep solver.simplices[contact.bodyA] as your particle index which may belong to any other actor - in this case one of the ropes.
Keep in mind that simplices are stored as tuples of particle indices. The first few entries in the solver.simplices array are tuples of 3 (triangle simplices, used by cloth), the ones in the middle are tuples of 2 (used by ropes) and the ones at the end are single particle indices. Given a simplex index, the GetSimplexStartAndSize function will calculate for you the index of its first particle in the simplices array. For instance if you have 4 3-simplices, 5 2-simplices and 10 1-simplices, the starting index of the 6th simplex would be 4*3 + 2*2 = 16. The starting index of the 12th simplex would be 4*3 + 5*2 + 3*1 = 25, so even if its a 1-simplex its starting index would not be 12. If you used 12 as your index instead of 25, you would be accessing a particle belonging to another actor.
So if there's anything other than just 1-simplices in your solver, as seems to be your case, you can't assume solver.simplices[contact.bodyA] will contain the correct index. You must then always use GetSimplexStartAndSize. As per the manual:
http://obi.virtualmethodstudio.com/manua...sions.html
Quote:In case there isn't any actor using surface collisions in your solver, all simplices will have size 1 and the code above can be simplified to:
// get the particle index directly, as all simplices are guaranteed to have size 1:
int particleIndex = solver.simplices[contact.bodyA];