Posts: 6,323
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
(28-01-2022, 01:14 PM)MoonBoop Wrote: I'm using the obi cloth stitcher to stitch together parts of a garment to form a complete garment.
Ive got the pieces being stitched together currently by giving the stitcher vertices that are known to be on stitch points for the garment.
I believe the stitching it working properly.
It might be easier to show you the flying off behaviour.
garment flying off gif
(I tried the extension for .gif, but it didn't work)
in short, when a garment is stitched together, what happens is that it will fly off of the model below it.
Might be a case of tunneling due to high velocities, but it's weird that it is flying off in that specific direction. Are you adding these stitches at runtime? if so, can you share the code you're using?
Posts: 18
Threads: 2
Joined: Jan 2022
Reputation:
0
yes I am stitching at runtime.
this is the stitching code:
Code: // Sew all sides together:
ObiStitcher stitcher = gameObject.AddComponent<ObiStitcher>();
stitcher.Actor1 = cloths[0];
stitcher.Actor2 = cloths[1];
//Add stitches:
var stencilData = stencil.Generate();
foreach (ShapeData shapeData in stencilData)
{
foreach (CurveData curveData in shapeData)
{
if (curveData.Stitched)
{
int[][] stitches = new int[2][];
for (int i = 0; i < meshData.Length; i++)
{
stitches[i] = meshData[i].VerticesOnCurve(curveData);
}
for (int i = 0; i < stitches[0].Length; i++)
{
Debug.Log(stitches[1].Length);
stitcher.AddStitch(stitches[0][i], stitches[1][i]);
}
}
}
}
stitcher.PushDataToSolver();
cloths[0].maxBending = 0.1f;
cloths[1].maxBending = 0.1f;
its pretty much pairing up vertices that exist on the same stitched curve on different meshes.
could it be the mesh im generating before stitching causing problems? like its too tight?
Posts: 18
Threads: 2
Joined: Jan 2022
Reputation:
0
30-01-2022, 12:13 AM
(This post was last modified: 30-01-2022, 12:20 AM by MoonBoop.)
Ive tried some more adjustments to get the mesh into a better shape for the body, and it is kinda staying on the body now, but unity has gotten really unstable now.
Its now flying forward off of the mannequin.
Posts: 6,323
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
31-01-2022, 08:28 AM
(This post was last modified: 31-01-2022, 08:30 AM by josemendez.)
(28-01-2022, 01:14 PM)MoonBoop Wrote: I'm using the obi cloth stitcher to stitch together parts of a garment to form a complete garment.
Ive got the pieces being stitched together currently by giving the stitcher vertices that are known to be on stitch points for the garment.
I believe the stitching it working properly.
If I had to make a blind guess, I'd say the issue is that parts of the cloth that aren't adjacent to each other are being incorrectly stitched. This puts a lot of potential energy into the cloth and causes a "slingshot" effect, sending it flying in a random direction.
Try visually debugging this: stitch the cloth without using any avatar mesh, see if it stitches correctly. Add a proper material to it so that you can actually see the cloth instead of a pink blob.
On a side note: the stitching code you shared doesn't help much, since the important implementation bits are left out. For instance, how's VerticesOnCurve() implemented? What's stitches[0][i] and stitches[1][i]?
Code: //Add stitches:
var stencilData = stencil.Generate();
foreach (ShapeData shapeData in stencilData)
{
foreach (CurveData curveData in shapeData)
{
if (curveData.Stitched)
{
int[][] stitches = new int[2][];
for (int i = 0; i < meshData.Length; i++)
{
stitches[i] = meshData[i].VerticesOnCurve(curveData);
}
for (int i = 0; i < stitches[0].Length; i++)
{
Debug.Log(stitches[1].Length);
stitcher.AddStitch(stitches[0][i], stitches[1][i]);
}
}
}
}
Note that in the general case, vertex != particle. You can't use mesh vertex indices as particle indices, since vertices are welded together before creating particles. This is specially important if your mesh contains texture or normal seams.
Take a look at the "RuntimeCloth" sample scene: it creates a basic garment and stitches it together, all at runtime.
Posts: 18
Threads: 2
Joined: Jan 2022
Reputation:
0
Quote:On a side note: the stitching code you shared doesn't help much, since the important implementation bits are left out. For instance, how's VerticesOnCurve() implemented? What's stitches[0][i] and stitches[1][i]?
Yea, it wasn't a great example that code for how it works, but its kind of tricky to share too much since it is for a project that is apart of an NDA, but we're getting too pressed for time.
What I can give though is the mesh generated to be used for stitching to create a garment has all of its vertices stored within a custom vertex class to hold more information about which vertices should be stitched as it can store if a vertex is on a curve and what order to stitch that vertex in.
I should add, that the mesh generation process works by creating a mesh from a 2D cubic spline
This stitched value is based on if the vertices are on the curves that represent the garment if they are stitched.
Quote:Try visually debugging this: stitch the cloth without using any avatar mesh, see if it stitches correctly. Add a proper material to it so that you can actually see the cloth instead of a pink blob.
I'll add in a proper double sided material to start checking the garment properly. I have added it in a few times, but I haven't used a good material yet for it.
Quote:Note that in the general case, vertex != particle. You can't use mesh vertex indices as particle indices, since vertices are welded together before creating particles. This is specially important if your mesh contains texture or normal seams.
Take a look at the "RuntimeCloth" sample scene: it creates a basic garment and stitches it together, all at runtime.
I'll review the runtime scene again and have a look at the mesh generation. While I followed the cloth segment of the example, I didn't follow the mesh generation part
Posts: 18
Threads: 2
Joined: Jan 2022
Reputation:
0
How can I get the right particles to stitch?
Im not quite sure why the sack generator works in the way it does since it still seems to be relying on the logic that was used to build the mesh and not fetching the particles that are in the right positions to stitch.
also from testing I can see that the garment is going inside out, which yea is a strong indicator the stitching is going very wrong somewhere.
I was attempting to get the positions of particles to match the right vertices, which I think will require a local to world transform matrix that would work only on the first loop, but Im not sure how to get the particles.
I thought cloths[i].GetParticlePosition(j) would work, but it doesn't work past j = 0.
Posts: 18
Threads: 2
Joined: Jan 2022
Reputation:
0
I think im getting it, I need to use the actor to access the particles.
I had assumed it was the cloth, but looking at the document I need the actors to get the positions
Posts: 6,323
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
01-02-2022, 10:02 AM
(This post was last modified: 01-02-2022, 10:03 AM by josemendez.)
(01-02-2022, 07:39 AM)MoonBoop Wrote: Im not quite sure why the sack generator works in the way it does since it still seems to be relying on the logic that was used to build the mesh and not fetching the particles that are in the right positions to stitch.
The mesh created by the sack generator is guaranteed to have one particle per vertex, and in the exact same order, since it has no normal/color/uv seams.
When you create a mesh, multiple vertices may share the same position but have different normals, uv coordinates, colors, etc. This is very common. When generating particles from a mesh, Obi welds together vertices that have the same position, and generates a single particle for all of them. Because of this there is not a 1-1 relationship between vertices and particles, some particles represent multiple vertices. Otherwise there would be "cuts" in the cloth whenever there's a discontinuity in any vertex property.
In the general case, you need to use particles and forget about mesh vertices. Vertices should only be used for rendering, and particles only used for physics. The best way to access particles is the pattern explained in the manual:
http://obi.virtualmethodstudio.com/manua...icles.html
Code: // index of the first particle in the actor:
int actorIndex = 0;
// solver index of the first particle in the actor.
int solverIndex = actor.solverIndices[actorIndex];
// use it to get the particle's current velocity. (or position, or mass, radius, etc)
Vector3 velocity = solver.velocities[solverIndex];
Posts: 18
Threads: 2
Joined: Jan 2022
Reputation:
0
01-02-2022, 12:32 PM
(This post was last modified: 01-02-2022, 12:35 PM by MoonBoop.)
ah okay, so then I should remove the vertices based stitching completely.
would replacing it with a system that can detect if a particle needs to be stitched based on its position be good?
I'm trying to figure out how to get the particles I need to stitch since the garment generation has seams specified where the garment must stitch
Posts: 6,323
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
01-02-2022, 02:10 PM
(This post was last modified: 01-02-2022, 02:17 PM by josemendez.)
(01-02-2022, 12:32 PM)MoonBoop Wrote: ah okay, so then I should remove the vertices based stitching completely.
would replacing it with a system that can detect if a particle needs to be stitched based on its position be good?
I'm trying to figure out how to get the particles I need to stitch since the garment generation has seams specified where the garment must stitch
Are you generating the garment meshes programmatically? for instance, delaunay triangulation of a bezier patch. If so there's a good chance that your mesh does not have any uv/normal/color discontinuity (at least not for each individual garment piece). In that case, assuming vertex == particle is ok. This is what I did some time ago for a similar app that used ObiCloth for simulation:
Each garment piece was defined by multiple curves, and the interior area triangulated. Start/end positions in the curves define regions that should be stitched together. The vertex index of these are used as actor particle indices, since there's a 1-1 correspondence between vertex and particle when there's no discontinuities/seams in the mesh.
The stitching code for a "stitch line" (a seam specified as start/end points in two bezier curves) is this:
Code: public void Commit()
{
stitcher.Clear();
if (!StitchSide.IsValid(sideA) || !StitchSide.IsValid(sideB))
return;
ObiCloth clothA = sideA.pattern.cloth;
ObiCloth clothB = sideB.pattern.cloth;
if (clothA != null && clothB != null)
{
stitcher.Actor1 = clothA;
stitcher.Actor2 = clothB;
int startIndexA = sideA.pattern.GetBoundaryIndexAtMu(sideA.range.x);
int endIndexA = sideA.pattern.GetBoundaryIndexAtMu(sideA.range.y);
int startIndexB = sideB.pattern.GetBoundaryIndexAtMu(sideB.range.x);
int endIndexB = sideB.pattern.GetBoundaryIndexAtMu(sideB.range.y);
int pointRangeA = endIndexA - startIndexA;
int pointRangeB = endIndexB - startIndexB;
int pointCountA = Mathf.Abs(pointRangeA);
int pointCountB = Mathf.Abs(pointRangeB);
if (pointCountA > 0 && pointCountB > 0)
{
float maxCount = Mathf.Max(pointCountA, pointCountB);
float a = 0, b = 0;
while (Mathf.Abs(a) < pointCountA || Mathf.Abs(b) < pointCountB)
{
stitcher.AddStitch(startIndexA + Mathf.RoundToInt(a), startIndexB + Mathf.RoundToInt(b));
a += pointRangeA / maxCount;
b += pointRangeB / maxCount;
}
}
}
stitcher.PushDataToSolver();
onStitchUpdated?.Invoke(this);
}
I know this code doesn't mean much without context, but suffice to say that "startIndexA" and "startIndexB" passed to AddStitch() are vertex indices. When triangulating the garment piece to generate a mesh, I create the vertices at the borders last, this way I have an easy way to identify vertices at the borders: they're always at the end of the mesh vertex list.
Since there's no uv/normal/color discontinuities in the mesh, I know particles and vertices appear in the same order in their respective arrays and there's always one particle per vertex. This allows me to use vertex indices and particle indices interchangeably.
Of course this isn't possible if you do have (or plan to have) discontinuities in your meshes, in that case you can map from vertex index to particle index using the cloth blueprint:
Code: cloth.clothBlueprintBase.Topology.rawToWelded //<-- this array maps from vertex index to particle index.
int particleIndex = cloth.clothBlueprintBase.Topology.rawToWelded[5]; // get the particle index that corresponds to vertex #5 in the mesh.
let me know if I can be of further help,
|