Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Tear, Pin, Cut, Fold and Mark
#1
Triste 
Hi, 

I am new to Unity and Obi and am currently trying to build several cloth interaction scenes. Such as: Tear, Pin, Cut, Fold and Mark. Pin I have figured out, but I am really having trouble with Cut, Fold and Tear. I am not sure how to implement the code in the threads into my scene...

I have had a look inside the other thread but I have not been able to accomplish this.


Could someone help?

Best,
Valerie
Reply
#2
Hi Valerie,

Tear, Pin, Cut, Fold and Mark...these are really vague terms. Take for instance, "Fold". What do you mean by that? cloth already folds when appropriate as a result of the simulation, so you must be referring to some kind of user interaction that results in the cloth being folded in some specific way?

Same for "Tear": ObiTearableCloth already tears as a result of forces exceeding a threshold.

Can you describe these giving more specifics details? Also, what have you tried so far?
Reply
#3
(06-01-2021, 01:04 PM)josemendez Wrote: Hi Valerie,

Tear, Pin, Cut, Fold and Mark...these are really vague terms. Take for instance, "Fold". What do you mean by that? cloth already folds when appropriate as a result of the simulation, so you must be referring to some kind of user interaction that results in the cloth being folded in some specific way?

Same for "Tear": ObiTearableCloth already tears as a result of forces exceeding a threshold.

Can you describe these giving more specifics details? Also, what have you tried so far?
Hi Jose,
Thank you for getting back to me. 

Currently, I have managed to replicate these in Virtual Reality (Tear and Pin) but I would like to interact in real-time with them in Virtual Reality. 
For example, hold on to a fabric in virtual reality with my controllers. How would I achieve this?

If not in virtual reality: how do I set a trigger for it in unity?

Sorry for being vague and thank you for trying to be helpful.

Best,
Valerie
Reply
#4
Pregunta 
Hi Jose,

I have been working more in Unity and now know what I would like to achieve.
I am trying to build a personalised Controller that can trigger the cutting of fabric so it would be shaped like a pair of scissors. In the attached picture you see an example of the controller that I made.

Do you know how I would go about this? 

Build a pair of scissors in Cinema4D and then import them to make the two legs of the scissors Obi Colliders?

I would be thrilled to hear some input/ideas if you have any?

Best,
Valerie
Reply
#5
(16-03-2021, 06:17 PM)Valerize Wrote: I have been working more in Unity and now know what I would like to achieve.
I am trying to build a personalised Controller that can trigger the cutting of fabric so it would be shaped like a pair of scissors.
Build a pair of scissors in Cinema4D and then import them to make the two legs of the scissors Obi Colliders.

Hi Valerie,

So you want the cloth to be cut/torn upon contact with a collider (scissor-shaped, in this case), correct?

It's important to realize that cloth can only be cut along existing mesh edges. This means that you can't cut arbitrary shapes out of it, as that would require generating new geometry (changing the topology or, re-topologizing the mesh). This is considerably expensive so cloth in games generally avoids it. Only really specific use cases for industrial/medical applications actually require it.

With this in mind, cutting the cloth upon contact with a collider requires two steps:

1)- Get the contacts between the cloth and the scissor collider(s).
2)- For each contact, determine the closest mesh edge and tear it.

First step is trivial using collision callbacks: http://obi.virtualmethodstudio.com/tutor...sions.html

Second step is a bit more involved, and requires understanding how cloth simulation works. Cloth is simulated by creating a particle for each mesh vertex, then placing "distance constraint" in each edge of the mesh. Each distance constraint glues together 2 particles, you can think of them as simple springs between particles.

Constraints are grouped into "batches" for efficient parallelization. So for example, if the mesh has 600 edges you will have 600 distance constraints, grouped into a few batches (120 in one batch, 232 in another, etc). This is explained in detail here: http://obi.virtualmethodstudio.com/tutor...aints.html

With this out of the way, we now get to the actual tearing: Cloth has a Tear() method that takes a StructuralConstraint struct as parameter. StructuralConstraints are DTOs (data transfer objects) that contain a batch index and a constraint index for a given distance constraint in the cloth. You pass one of these to the Tear() method, and both the cloth mesh and its particle/constraint representation are updated to reflect the newly torn edge.

From step 1) you know the index of a particle that is touching the scissors. You now have to find which constraint(s) reference that particle (by iterating trough all constraints), create a StructuralConstraint our of the batch/constraint index, and call Tear(). You can see an example of this in the cloth's ApplyTearing() method: it iterates trough all distance constraints in the cloth, finds the ones that are under too much force, and tears them. You just need to find the ones that contain the particle index found in 1) instead.

Needless to say, some C# coding experience is necessary to implement this. Let me know how it goes! Sonrisa
Reply
#6
(17-03-2021, 08:54 AM)josemendez Wrote: Hi Valerie,

So you want the cloth to be cut/torn upon contact with a collider (scissor-shaped, in this case), correct?

It's important to realize that cloth can only be cut along existing mesh edges. This means that you can't cut arbitrary shapes out of it, as that would require generating new geometry (changing the topology or, re-topologizing the mesh). This is considerably expensive so cloth in games generally avoids it. Only really specific use cases for industrial/medical applications actually require it.

With this in mind, cutting the cloth upon contact with a collider requires two steps:

1)- Get the contacts between the cloth and the scissor collider(s).
2)- For each contact, determine the closest mesh edge and tear it.

First step is trivial using collision callbacks: http://obi.virtualmethodstudio.com/tutor...sions.html

Second step is a bit more involved, and requires understanding how cloth simulation works. Cloth is simulated by creating a particle for each mesh vertex, then placing "distance constraint" in each edge of the mesh. Each distance constraint glues together 2 particles, you can think of them as simple springs between particles.

Constraints are grouped into "batches" for efficient parallelization. So for example, if the mesh has 600 edges you will have 600 distance constraints, grouped into a few batches (120 in one batch, 232 in another, etc). This is explained in detail here: http://obi.virtualmethodstudio.com/tutor...aints.html

With this out of the way, we now get to the actual tearing: Cloth has a Tear() method that takes a StructuralConstraint struct as parameter. StructuralConstraints are DTOs (data transfer objects) that contain a batch index and a constraint index for a given distance constraint in the cloth. You pass one of these to the Tear() method, and both the cloth mesh and its particle/constraint representation are updated to reflect the newly torn edge.

From step 1) you know the index of a particle that is touching the scissors. You now have to find which constraint(s) reference that particle (by iterating trough all constraints), create a StructuralConstraint our of the batch/constraint index, and call Tear(). You can see an example of this in the cloth's ApplyTearing() method: it iterates trough all distance constraints in the cloth, finds the ones that are under too much force, and tears them. You just need to find the ones that contain the particle index found in 1) instead.

Needless to say, some C# coding experience is necessary to implement this. Let me know how it goes! Sonrisa
Hi Jose, 
Thank you so much for taking the time to respond to my question to elaborately! As much as I wish I were able to do C#, I can't and am only progressing so slowly that this project is not taking on any shape. Even the very detailed explanation of yours leaves me with a lot of question marks.
Do you know someone who might be interested in helping me/collaborating on this project?
I am aware that I am probably not the only person who needs help with this stuff and demand must be high but I thought it might be worth asking. 
Have a nice day! 
Best, Valerie
Reply
#7
Hi Valerie!

Unfortunately we don't do contract work/collaborations, as we don't have time left to do it.

Most intermediate C#/Unity programmers should be able to do this though, all it involves is basic programming patterns and structures (linear searches, arrays, lists, etc). Maybe you can look for some help in the Unity forums, they have a specific sections for commercial as well as unpaid collaborations:

https://forum.unity.com

kind regards,
Reply
#8
(17-03-2021, 08:54 AM)josemendez Wrote: Hi Valerie,

So you want the cloth to be cut/torn upon contact with a collider (scissor-shaped, in this case), correct?

It's important to realize that cloth can only be cut along existing mesh edges. This means that you can't cut arbitrary shapes out of it, as that would require generating new geometry (changing the topology or, re-topologizing the mesh). This is considerably expensive so cloth in games generally avoids it. Only really specific use cases for industrial/medical applications actually require it.

With this in mind, cutting the cloth upon contact with a collider requires two steps:

1)- Get the contacts between the cloth and the scissor collider(s).
2)- For each contact, determine the closest mesh edge and tear it.

First step is trivial using collision callbacks: http://obi.virtualmethodstudio.com/tutor...sions.html

Second step is a bit more involved, and requires understanding how cloth simulation works. Cloth is simulated by creating a particle for each mesh vertex, then placing "distance constraint" in each edge of the mesh. Each distance constraint glues together 2 particles, you can think of them as simple springs between particles.

Constraints are grouped into "batches" for efficient parallelization. So for example, if the mesh has 600 edges you will have 600 distance constraints, grouped into a few batches (120 in one batch, 232 in another, etc). This is explained in detail here: http://obi.virtualmethodstudio.com/tutor...aints.html

With this out of the way, we now get to the actual tearing: Cloth has a Tear() method that takes a StructuralConstraint struct as parameter. StructuralConstraints are DTOs (data transfer objects) that contain a batch index and a constraint index for a given distance constraint in the cloth. You pass one of these to the Tear() method, and both the cloth mesh and its particle/constraint representation are updated to reflect the newly torn edge.

From step 1) you know the index of a particle that is touching the scissors. You now have to find which constraint(s) reference that particle (by iterating trough all constraints), create a StructuralConstraint our of the batch/constraint index, and call Tear(). You can see an example of this in the cloth's ApplyTearing() method: it iterates trough all distance constraints in the cloth, finds the ones that are under too much force, and tears them. You just need to find the ones that contain the particle index found in 1) instead.

Needless to say, some C# coding experience is necessary to implement this. Let me know how it goes! Sonrisa


Hi josemendez,

I'm working on a project with similar needs, I guess it's not necessary to open a new thread. So I'm replying you here. Hope that's not too much trouble for you.
So I understand that I need to get the particles first, then get the edges (or StructuralConstraint in term of the class name) to tear. I'm reading the source codes in ObiTearableCloth.cs and RaycastLasers.cs as an example.
And I understand you can get the "particle" by loop through all the ObiSolver.simplices. It seems it only return with an int, I'm assuming it's some sort of index? And it seems it's a mix of "points", "edges", and "triangles"?
But I didn't find any way to related that index with batchIndex and constraintIndex to find the according StructuralConstraint. Could you please show me who to approach? Thx a lot   Sonrisa 
Reply
#9
Hi there!

(13-01-2022, 01:58 AM)cycle6 Wrote: And I understand you can get the "particle" by loop through all the ObiSolver.simplices. It seems it only return with an int, I'm assuming it's some sort of index? And it seems it's a mix of "points", "edges", and "triangles"?

ObiSolver.simplices contains simplex indices. A simplex is a convex shape made up of 1, 2, or 3 particles (point, edge, or triangle respectively). In the case of cloth, a simplex is always 1 particle (if not using surface collisions) or 3 particles (if using surface collisions).

Once you get a simplex index, you need to retrieve the particle indices in it. This is done using ObiSolver.simplexCounts.GetSimplexStartAndSize(simplexIndex, simplexSize);

This is all thoroughly documented and explained here with sample code (see "Retrieving the particle involved in a contact"):
http://obi.virtualmethodstudio.com/manua...sions.html

(13-01-2022, 01:58 AM)cycle6 Wrote: But I didn't find any way to related that index [color=#333333][font=Tahoma, Verdana, Arial, sans-serif][color=#333333][font=Tahoma, Verdana, Arial, sans-serif]with batchIndex and constraintIndex to find the according StructuralConstraint. Could you please show me who to approach? Thx a lot   Sonrisa 

There's no direct map from a particle index to a batch and constraint index, because one particle might be involved in an arbitrary number of constraints. It's not a 1-1 relationship. The only way to find a constraint given a particle index is to iterate trough all constraints until you find the one(s) that involve that particle. See:

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

let me know if I can be of further help. Sonrisa
Reply
#10
(13-01-2022, 09:37 AM)josemendez Wrote: Hi there!


ObiSolver.simplices contains simplex indices. A simplex is a convex shape made up of 1, 2, or 3 particles (point, edge, or triangle respectively). In the case of cloth, a simplex is always 1 particle (if not using surface collisions) or 3 particles (if using surface collisions).

Once you get a simplex index, you need to retrieve the particle indices in it. This is done using ObiSolver.simplexCounts.GetSimplexStartAndSize(simplexIndex, simplexSize);

This is all thoroughly documented and explained here with sample code (see "Retrieving the particle involved in a contact"):
http://obi.virtualmethodstudio.com/manua...sions.html


There's no direct map from a particle index to a batch and constraint index, because one particle might be involved in an arbitrary number of constraints. It's not a 1-1 relationship. The only way to find a constraint given a particle index is to iterate trough all constraints until you find the one(s) that involve that particle. See:

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

let me know if I can be of further help. Sonrisa

Ok let's say I have 
    int startPatical = solver.simplexCounts.GetSimplexStartAndSize(results.simplexIndex, out int simplexSize);
I'm assuming I can use "startPatical" as a reference to compare with all the particles in a constraint? So first, I just wanna confirm if "startPatical" is the correct parameter I can use?

Then let's say I get the batches
    var dc = GetConstraintsByType(Oni.ConstraintType.Distance) as ObiConstraints<ObiDistanceConstraintsBatch>;
    var theFirstBatch = dc.batches[0] as ObiDistanceConstraintsBatch;

There I want to find if "startPatical" is in one of the constraint in "theFirstBatch" right? OK, let's iterate through it.
    for (int i = 0; i < theFirstBatch.constraintCount; i++){
             //here how do I get a constraint?
             //and how do I check if startPatical is in that constraint?
    }
OK how do I get a constraint from the batch? There's no "theFirstBatch.ActiveConstraints[i]" or "theFirstBatch.GetConstraint(int index)", so how do I get each constraint object from the batch by iteration? And after that, how do I test if "startPatical" is in a constraint?

Please advice, thx.
Reply