Posts: 51
Threads: 11
Joined: Aug 2021
Reputation:
0
28-04-2022, 08:31 PM
(This post was last modified: 28-04-2022, 09:59 PM by snowtv.)
Hey guys,
I am looking at the document for Scripting Particles:
http://obi.virtualmethodstudio.com/manua...icles.html
From the look of it, seems like they are actual class objects, but I can't seem to find for example, if I know the index of a particle in an actor, how can I retrieve that particle object.
So maybe this "scripting particle" is just an arbitrary thing that exists in the form of all the arrays of data about it?
Additional question, when I inspect solver.orientations array, it seems that all the values are (0, 0, 0, 1), no matter how I'm moving my ObiCloth in the scene. Which makes me a bit confused...
Posts: 6,326
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
28-04-2022, 11:02 PM
(This post was last modified: 28-04-2022, 11:09 PM by josemendez.)
(28-04-2022, 08:31 PM)snowtv Wrote: From the look of it, seems like they are actual class objects, but I can't seem to find for example, if I know the index of a particle in an actor, how can I retrieve that particle object.
So maybe this "scripting particle" is just an arbitrary thing that exists in the form of all the arrays of data about it?
HI there!
"Scripting particles" refers to the act of controlling particles via script. It's not the name of a thing .
Particles are not classes or structs. Obi uses a data-oriented approach, which means particles are just an index, that you can use to access data in several arrays of the same length. Quoting the manual:
Quote:*Lists all properties* [...] Each ObiSolver has an array for each one of these properties, that stores the current data for all particles in use by any actor managed by the solver.
So to access the position of the Nth particle in a cloth, you do:
Code: var pos = solver.positions[cloth.solverIndices[N]];
Similarly, to access its velocity:
Code: var pos = solver.velocities[cloth.solverIndices[N]];
FYI, Unity's DOTS (data-oriented technology stack) uses the same approach: entities are not classes or structs, an entity is just an index into arrays of components.
The main advantage of this approach is the ability to deal with large amounts of data in a very performant way, because cache misses are minimized and memory is used efficiently: when you need to operate over say, particle positions and velocities, you *only* operate on that. No need to bring single every property from memory (mass, radius, color, etc) like you'd be forced to do if particles were structs - since you could not have partial access to a particle.
(28-04-2022, 08:31 PM)snowtv Wrote: Additional question, when I inspect solver.orientations array, it seems that all the values are (0, 0, 0, 1), no matter how I'm moving my ObiCloth in the scene. Which makes me a bit confused...
Orientations are only used by some actors, and cloth isn't one of them: cloth particles are just points in space with no orientation.
Currently, only rods (ObiRope) and soft bodies (ObiSoftbody) use oriented particles.
kind regards,
Posts: 51
Threads: 11
Joined: Aug 2021
Reputation:
0
(28-04-2022, 11:02 PM)josemendez Wrote: HI there!
"Scripting particles" refers to the act of controlling particles via script. It's not the name of a thing .
Particles are not classes or structs. Obi uses a data-oriented approach, which means particles are just an index, that you can use to access data in several arrays of the same length. Quoting the manual:
So to access the position of the Nth particle in a cloth, you do:
Code: var pos = solver.positions[cloth.solverIndices[N]];
Similarly, to access its velocity:
Code: var pos = solver.velocities[cloth.solverIndices[N]];
FYI, Unity's DOTS (data-oriented technology stack) uses the same approach: entities are not classes or structs, an entity is just an index into arrays of components.
The main advantage of this approach is the ability to deal with large amounts of data in a very performant way, because cache misses are minimized and memory is used efficiently: when you need to operate over say, particle positions and velocities, you *only* operate on that. No need to bring single every property from memory (mass, radius, color, etc) like you'd be forced to do if particles were structs - since you could not have partial access to a particle.
Orientations are only used by some actors, and cloth isn't one of them: cloth particles are just points in space with no orientation.
Currently, only rods (ObiRope) and soft bodies (ObiSoftbody) use oriented particles.
kind regards,
Thanks for the explanation!
I'm trying to implement a cutting algorithm, find a list of pairs of particles connected by DistanceConstraints that are as close as along a given straight line. I think that I need the particle orientation to determine if two particles connected by a DistanceConstraint don't have any "mesh gap" between them. Because my mesh has two sides that are close to each other, and I'm worrying that Obi will create constraints from the outside vertices to the inside vertices.
If Obi won't create DistanceConstraint between two cloth particles if there is "mesh gap" between them, then I probably don't need the particle orientation.
Or, is it possible to get the mesh vertex index for a corresponding particle/closest to a particle? Maybe I can resolve my issue if I can get the vertex information.
Posts: 6,326
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
(29-04-2022, 03:58 PM)snowtv Wrote: Thanks for the explanation!
I'm trying to implement a cutting algorithm, find a list of pairs of particles connected by DistanceConstraints that are as close as along a given straight line. I think that I need the particle orientation to determine if two particles connected by a DistanceConstraint don't have any "mesh gap" between them. Because my mesh has two sides that are close to each other, and I'm worrying that Obi will create constraints from the outside vertices to the inside vertices.
If Obi won't create DistanceConstraint between two cloth particles if there is "mesh gap" between them, then I probably don't need the particle orientation.
Or, is it possible to get the mesh vertex index for a corresponding particle/closest to a particle? Maybe I can resolve my issue if I can get the vertex information.
Hi!
Obi will only create constraints along triangle edges, so as long as your vertices aren’t physically in the same position (distance below 0.00001) you won’t have to worry about constraints “bridging” across gaps in the mesh.
Posts: 51
Threads: 11
Joined: Aug 2021
Reputation:
0
(02-05-2022, 08:52 PM)josemendez Wrote: Hi!
Obi will only create constraints along triangle edges, so as long as your vertices aren’t physically in the same position (distance below 0.00001) you won’t have to worry about constraints “bridging” across gaps in the mesh.
That's wonderful news to know. I think that's enough info for me to keep working on my algorithm, but just to "future-proof", is it possible to get the index of a mesh vertex that is the closest to a particle? Maybe I can use the particle's start position to compare with each vertices' position?
Posts: 6,326
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
(03-05-2022, 08:24 PM)snowtv Wrote: That's wonderful news to know. I think that's enough info for me to keep working on my algorithm, but just to "future-proof", is it possible to get the index of a mesh vertex that is the closest to a particle? Maybe I can use the particle's start position to compare with each vertices' position?
Obi stores a particle index for each vertex, since there's always more vertices than particles. This results in efficient storage and efficient mesh updated for either simulation or tearing, since each vertex knows which particle it should pick its position from.
Doing it the other way around is rather inconvenient, since there may be multiple vertices equally distant from a particle. The only way to do that is just iterate trough all particle positions in the blueprint and compare them with the vertex position to find the closest one.
kind regards,
Posts: 51
Threads: 11
Joined: Aug 2021
Reputation:
0
(04-05-2022, 09:48 AM)josemendez Wrote: Obi stores a particle index for each vertex, since there's always more vertices than particles. This results in efficient storage and efficient mesh updated for either simulation or tearing, since each vertex knows which particle it should pick its position from.
Doing it the other way around is rather inconvenient, since there may be multiple vertices equally distant from a particle. The only way to do that is just iterate trough all particle positions in the blueprint and compare them with the vertex position to find the closest one.
kind regards,
That's reasonable. So for the particle index for each vertex data, will this gets updated at runtime based on changes on constraints/tearing, etc.? If not, I think I can build a data structure based on the particle index for each vertex info at start, and use it later.
Also can you point me to the document for particle index for each vertex please?
Thank you very much!
Posts: 6,326
Threads: 24
Joined: Jun 2017
Reputation:
400
Obi Owner:
(05-05-2022, 07:49 PM)snowtv Wrote: That's reasonable. So for the particle index for each vertex data, will this gets updated at runtime based on changes on constraints/tearing, etc.?
Yes, this does get updated at runtime.
(05-05-2022, 07:49 PM)snowtv Wrote: Also can you point me to the document for particle index for each vertex please?
This isn't really documented anywhere, as it's very low-level stuff: to generate cloth from a mesh, Obi uses a half-edge data structure. You can find the implementation in HalfEdgeMesh.cs file. The half-edge structure contains a rawToWelded array with as many entries as vertices in your mesh. For each vertex, it contains the index of the actor particle that represents that vertex.
The cloth blueprint has a public "topology" member, which is of type HalfEdgeMesh.
Tearable cloth actors create a copy of their blueprint at runtime, since they need to modify the topology (the half-edge structure) so they can't share the same blueprint, unlike other cloth types. This copy gets updated every time the cloth is torn, as I mentioned above.
Wrapping up: to get the particle for vertex N at runtime, do:
Code: int actorParticleIndex = cloth.blueprint.topology.rawToWelded[N];
Posts: 51
Threads: 11
Joined: Aug 2021
Reputation:
0
(06-05-2022, 08:01 AM)josemendez Wrote: Yes, this does get updated at runtime.
This isn't really documented anywhere, as it's very low-level stuff: to generate cloth from a mesh, Obi uses a half-edge data structure. You can find the implementation in HalfEdgeMesh.cs file. The half-edge structure contains a rawToWelded array with as many entries as vertices in your mesh. For each vertex, it contains the index of the actor particle that represents that vertex.
The cloth blueprint has a public "topology" member, which is of type HalfEdgeMesh.
Tearable cloth actors create a copy of their blueprint at runtime, since they need to modify the topology (the half-edge structure) so they can't share the same blueprint, unlike other cloth types. This copy gets updated every time the cloth is torn, as I mentioned above.
Wrapping up: to get the particle for vertex N at runtime, do:
Code: int actorParticleIndex = cloth.blueprint.topology.rawToWelded[N];
Great! Thank you so much for the info!
Posts: 51
Threads: 11
Joined: Aug 2021
Reputation:
0
(02-05-2022, 08:52 PM)josemendez Wrote: Hi!
Obi will only create constraints along triangle edges, so as long as your vertices aren’t physically in the same position (distance below 0.00001) you won’t have to worry about constraints “bridging” across gaps in the mesh.
Hello, I have another question about this: is it possible to create DistanceConstraint between particles that "bridging" across gaps in the mesh? Or I can only use particle attachment?
|