Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to read out stretch
#1
Hi,
Is there a way to read out the current "stretchedness" of an ObiCloth actor?

Thank you!
Jan
Reply
#2
(05-11-2017, 02:44 PM)mbbmbbmm Wrote: Hi,
Is there a way to read out the current "stretchedness" of an ObiCloth actor?

Thank you!
Jan

Hi Jan!

There's no built in functionality for this. But read on for details:

The technical term for this is "strain". The "stress" is the amount of force you're applying on an object, and the "strain" is how much it has deformed due to this force.
To measure strain in 2D or 3D, you need to define in which direction you want to measure it. Some materials (anisotropic materials) do not have the same resistance to stress in all directions, while others do (isotropic materials). In Obi's case, the cloth is slightly anisotropic, but the anisotropy depends to the exact mesh topology.

However, if you're just interested in a rough estimation on the overall strain in no particular direction as a single scalar value (i.e, 1 for "no stretch" and > 1 for "very stretched"), one very easy way to calculate it is measuring strains for all individual distance constraints in the cloth and averaging them. Note that this can be a bit intensive performance-wise for large meshes.


Code:
ObiDistanceConstraintBatch distanceBatch = cloth.DistanceConstraints.GetBatches()[0] as ObiDistanceConstraintBatch; 
float averageStrain = 0;
for (int i = 0; i < distanceBatch.ConstraintCount; i++){
    float distance = Vector3.Distance(GetParticlePosition(distanceBatch.springIndices[i*2]),
                                       GetParticlePosition(distanceBatch.springIndices[i*2+1]));
    averageStrain += distance/distanceBatch.restLengths[i];
}
averageStrain /= distanceBatch.ConstraintCount;

// averageStrain will be 1 for cloth in rest state, > 1 for stretched cloth and < 1 for compressed cloth. The more "stretchedness", the larger averageStrain will be.
Reply
#3
Pregunta 
Thanks for your help, that sounds nice, the rough estimation would be totally sufficient for me. The cloth mesh is not tooo huge as well (ConstrainCount is 620). Maybe I could even skip every other Particle to optimize or so.
BUT.. the moment I divide distance / distanceBatch.restLengths[i] I get NaN!  Huh
So the final result is also NaN. Is this some weird floating point precision problem?


Also I am not sure about the GetParticlePosition ? Is it correct using it with cloth and the dot operator? It gave me red squigglies when I had it directly like in your example...

Code:
  float distance = Vector3.Distance(cloth.GetParticlePosition(distanceBatch.springIndices[i * 2]),
                                              cloth.GetParticlePosition(distanceBatch.springIndices[i * 2 + 1]));

Thank you!
J



Aha, it appears there are a few zeros in the distanceBath.restLengths. Checking and adding 0f instead seems to do the trick. Thanks again!
Reply
#4
(05-11-2017, 04:53 PM)mbbmbbmm Wrote: Thanks for your help, that sounds nice, the rough estimation would be totally sufficient for me. The cloth mesh is not tooo huge as well (ConstrainCount is 620). Maybe I could even skip every other Particle to optimize or so.
BUT.. the moment I divide distance / distanceBatch.restLengths[i] I get NaN!  Huh
So the final result is also NaN. Is this some weird floating point precision problem?


Also I am not sure about the GetParticlePosition ? Is it correct using it with cloth and the dot operator? It gave me red squigglies when I had it directly like in your example...


Code:
  float distance = Vector3.Distance(cloth.GetParticlePosition(distanceBatch.springIndices[i * 2]),
                                              cloth.GetParticlePosition(distanceBatch.springIndices[i * 2 + 1]));

Thank you!
J




Aha, it appears there are a few zeros in the distanceBath.restLengths. Checking and adding 0f instead seems to do the trick. Thanks again!

A restLenght of 0 indicates a zero-length edge in your mesh. This should generally be best avoided as it is a form of non-manifoldness, but if it works for you then I wouldn't worry too much.

GetParticlePosition() is part of ObiActor, from which ObiCloth is derived. Depending on where you're writing this code you should be able to call GetParticlePosition() directly.
Reply