19-10-2021, 09:14 AM
(This post was last modified: 19-10-2021, 09:19 AM by josemendez.)
Hi Jasper,
Constraints reference particles. However, particles do not reference constraints in any way. So in general, there's no way to know which constraints affect a given particle except for checking all constraints.
There's no efficient way to know this. Data layout is optimized to know which particles are affected by a given constraint, not the other way around. The only possible approach is to go over all constraints of a given type, then check the particleIndices array for each constraint to see if a given constraint affects the particle(s) you're interested in. This is of course extremely costly if done for all particles and constraints, since it requires P * C checks, where P is the amount of particles and C the amount of constraints.
Nope. This applies only to skin constraints, since each skin constraint only affects 1 particle and there's exactly 1 constraint per particle. Shape matching constraints in particular can affect any number of particles each, and there can be an arbitrary number of constraints affecting a single particle.
If you take a look at the API docs for ObiShapeMatchingConstraintsBatch, you'll see it has 2 arrays (in addition to the particleIndices array, that all constraint types have):
so constraint k affects particles (firstIndex[k]....firstIndex[k] + numIndices[k]). These are indices into the particleIndices array. There's also a GetParticlesInvolved(int index, List<int> particles) method that fills a list with the particles affected by a given constraint. This is implemented as:
Again, this is specific for shape matching constraints. They're probably the most complex case since they can affect an arbitrary number of particles each. Other constraint types store indices in a different way. For instance, distance constraints affect *exactly* 2 particles each. They're stored as consecutive pairs in the constraint's particleIndices array. So the GetParticlesInvolved method looks like this:
As you can see this is much simpler than shape matching constraints.
Hope this makes sense. Let me know if you need further help!
Constraints reference particles. However, particles do not reference constraints in any way. So in general, there's no way to know which constraints affect a given particle except for checking all constraints.
(19-10-2021, 08:57 AM)Jschol Wrote: Lets say I have an particle index of 3 in the actor, which corresponds to an index of 6 in the solver.
What would be the corresponding constraint(s) index/indices in the solver?
There's no efficient way to know this. Data layout is optimized to know which particles are affected by a given constraint, not the other way around. The only possible approach is to go over all constraints of a given type, then check the particleIndices array for each constraint to see if a given constraint affects the particle(s) you're interested in. This is of course extremely costly if done for all particles and constraints, since it requires P * C checks, where P is the amount of particles and C the amount of constraints.
(19-10-2021, 08:57 AM)Jschol Wrote: From obi scripting constraints documentation, it is said that:
However, this does not seem te be the case for shape matching constraints in softbodies?Code:// there's only one skin constraint per particle,
// so particleIndex == constraintIndex,
Nope. This applies only to skin constraints, since each skin constraint only affects 1 particle and there's exactly 1 constraint per particle. Shape matching constraints in particular can affect any number of particles each, and there can be an arbitrary number of constraints affecting a single particle.
If you take a look at the API docs for ObiShapeMatchingConstraintsBatch, you'll see it has 2 arrays (in addition to the particleIndices array, that all constraint types have):
Quote:firstIndex: index of the first particle in each constraint.
numIndices: amount of particles in each constraint.
so constraint k affects particles (firstIndex[k]....firstIndex[k] + numIndices[k]). These are indices into the particleIndices array. There's also a GetParticlesInvolved(int index, List<int> particles) method that fills a list with the particles affected by a given constraint. This is implemented as:
Code:
int first = firstIndex[index];
int num = numIndices[index];
for (int i = first; i < first + num; ++i)
particles.Add(particleIndices[i]);
Again, this is specific for shape matching constraints. They're probably the most complex case since they can affect an arbitrary number of particles each. Other constraint types store indices in a different way. For instance, distance constraints affect *exactly* 2 particles each. They're stored as consecutive pairs in the constraint's particleIndices array. So the GetParticlesInvolved method looks like this:
Code:
particles.Add(particleIndices[index * 2]);
particles.Add(particleIndices[index * 2 + 1]);
As you can see this is much simpler than shape matching constraints.
Hope this makes sense. Let me know if you need further help!