Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  I want to control the SkinCompliance of individual particles from a script.
#1
Hello.
I would like to know how to control SkinCompliance from a C# script. (It's SkinCompliance in BluePrint's Property).
I'm trying to create a system that allows interactive contact with a character's clothes, as shown in the URL

http://obi.virtualmethodstudio.com/forum...hp?tid=606

I'm using obi Skinned Cloth + Obi Particle Picker + Obi Particle Dragger, and I'm trying to customize the inside of Obi Particle Dragger a bit.
Specifically, I'd like to set SkinCompliance to 0 before contact, and then add a small value like 0.0001 when contact is made.
Would that work correctly?

I'm using automatic translation, so sorry if the English is weird.

Translated with www.DeepL.com/Translator (free version)
Reply
#2
(09-10-2021, 12:28 PM)CP0029 Wrote: Hello.
I would like to know how to control SkinCompliance from a C# script.

I'm using obi Skinned Cloth + Obi Particle Picker + Obi Particle Dragger, and I'm trying to customize the inside of Obi Particle Dragger a bit.
Specifically, I'd like to set SkinCompliance to 0 before contact, and then add a small value like 0.0001 when contact is made.
Would that work correctly?

It's done differently depending on whether you want to change the skin compliance globally (for the entire cloth actor) or on a per-constraint basis. The manual explains how to do both:

http://obi.virtualmethodstudio.com/manua...aints.html

Let me know if you need help with it.
Reply
#3
(10-10-2021, 11:14 AM)josemendez Wrote: It's done differently depending on whether you want to change the skin compliance globally (for the entire cloth actor) or on a per-constraint basis. The manual explains how to do both:

http://obi.virtualmethodstudio.com/manua...aints.html

Let me know if you need help with it.
Thank you for your reply.
I wrote a script to operate the blueprint property with reference to the link.
It seemed to work, but ... Unity crashed when I did the Play, Script, and Stop steps in the Editor...
I will send you the reproduction procedure and the attached file.
Thank you for your support Sonrisa

-- unity version --
2019.4.31f1

-- install package (from packageManager) --
obi Cloth    6.2.0
burst        1.4.11
jobs        0.2.10-preview.13
collections  0.9.0-preview.6
mathematics  1.2.4

-- How to reproduce the crash --
Import the Obi_TEST.unitypackage at the link.
Press the Play button and then the spacebar.
Unity crashes during or after playback.

-- unityPackage & error log & editor log DownLoad URL --
https://drive.google.com/drive/folders/1...sp=sharing
Reply
#4
Hi there,

The cause of the crash is your "GrabberTrigger" script: there's an out of bounds access on the skinCompliance native arrays, since these are unmanaged arrays you're overwriting whatever the contents of memory are outside of the array. No bounds checks are performed for unmanaged memory, so you must be *extra* careful. Writing outside of the allocated memory can cause crashes, freezes, and all sorts of problems.

The documentation for the skinCompliance array says:
Quote:One compliance value per skin constraint.

So if there's say, 1200 constraints, this array is 1200 entries long. For some reason you're accessing the second value out of every 3:

Code:
solverSkinBatch.skinCompliance[index * 3 + 2] = 0.0f;

Which would be correct for skinRadiiBackstop (since it contains 3 values for each constraint, being 3 times as long), but not for skinCompliance.
This code writes "0" outside of the array. Depending on what the memory adjacent to the array is being used for, the results will vary, but almost always you will get a crash or a freeze.

Access skinCompliance correctly, like this:
Code:
solverSkinBatch.skinCompliance[index] = 0.0f;
Reply
#5
(13-10-2021, 09:51 AM)josemendez Wrote: Hi there,

The cause of the crash is your "GrabberTrigger" script: there's an out of bounds access on the skinCompliance native arrays, since these are unmanaged arrays you're overwriting whatever the contents of memory are outside of the array. No bounds checks are performed for unmanaged memory, so you must be *extra* careful. Writing outside of the allocated memory can cause crashes, freezes, and all sorts of problems.

The documentation for the skinCompliance array says:

So if there's say, 1200 constraints, this array is 1200 entries long. For some reason you're accessing the second value out of every 3:

Code:
solverSkinBatch.skinCompliance[index * 3 + 2] = 0.0f;

Which would be correct for skinRadiiBackstop (since it contains 3 values for each constraint, being 3 times as long), but not for skinCompliance.
This code writes "0" outside of the array. Depending on what the memory adjacent to the array is being used for, the results will vary, but almost always you will get a crash or a freeze.

Access skinCompliance correctly, like this:
Code:
solverSkinBatch.skinCompliance[index] = 0.0f;

It worked correctly the way you taught me.
I love this tool even more !
Thank you for your support.
Reply
#6
Hello.
I enjoy using the tools every day Sonrisa
I have another question.
I want to stop simulating particles that collide with a particular object,
I used the ObiActor.DeactivateParticle function (I put each Particle ID in the argument and looped with foreach).
Stopping the SkinCloth simulation with this function gave strange results.
I uploaded the video and unity package to Google Drive.
It may be helpful.
The processing of ObiActor.DeactivateParticle is controlled by a script called ObiSimStop.cs.

https://drive.google.com/drive/folders/1...sp=sharing

Also, is there a way to return the SkinCloth to its initial position after stopping the simulation?
Thank you for any help.
Reply
#7
DeactivateParticle() does what it claims to do: deactivates the particle. However it does not deal with any constraints that might currently be referencing or depending on that particle. Since behavior when a constraint references an inactive particle is undefined, you'll get strange results unless you deactivate these constraints too.

You must deactivate all constraints that reference an inactive particle. This can get pretty complex and resource intensive if you're going to do it multiple times every frame, since you must iterate trough all active constraints of all kinds and check which ones reference the particle. Another option that might be enough for your use case is to just freeze the particle in place by setting its inverse mass to zero (see:http://obi.virtualmethodstudio.com/manual/6.2/scriptingparticles.html):

Quote:Inverse mass for each particle. An inverse mass of 0 means the particle's mass is infinite, so its position will be unaffected by dynamics (allowing you to override it manually).

Won't take it out of the simulation, but will ignore any changes done to it, which in practice has the same effect. You can also manually override its position/velocity while frozen.

(18-10-2021, 10:33 AM)CP0029 Wrote: Also, is there a way to return the SkinCloth to its initial position after stopping the simulation?

Yes, call actor.ResetParticles();
Reply
#8
(18-10-2021, 11:20 AM)josemendez Wrote: DeactivateParticle() does what it claims to do: deactivates the particle. However it does not deal with any constraints that might currently be referencing or depending on that particle. Since behavior when a constraint references an inactive particle is undefined, you'll get strange results unless you deactivate these constraints too.

You must deactivate all constraints that reference an inactive particle. This can get pretty complex and resource intensive if you're going to do it multiple times every frame, since you must iterate trough all active constraints of all kinds and check which ones reference the particle. Another option that might be enough for your use case is to just freeze the particle in place by setting its inverse mass to zero (see:http://obi.virtualmethodstudio.com/manual/6.2/scriptingparticles.html):


Won't take it out of the simulation, but will ignore any changes done to it, which in practice has the same effect. You can also manually override its position/velocity while frozen.


Yes, call actor.ResetParticles();


Thank you for replying.
I tried it and it worked!
Reply