Obi Official Forum
End of the rope! Match position - Printable Version

+- Obi Official Forum (https://obi.virtualmethodstudio.com/forum)
+-- Forum: Obi Users Category (https://obi.virtualmethodstudio.com/forum/forum-1.html)
+--- Forum: Obi Rope (https://obi.virtualmethodstudio.com/forum/forum-4.html)
+--- Thread: End of the rope! Match position (/thread-3965.html)

Pages: 1 2


End of the rope! Match position - Renman3000 - 07-08-2023

Hi there, 
I have a rope. 

Is there a way to child a transform, renderer to the rope and specifuiclally a particle attachment so that this transform rednerer is always, whereever the selected particle attachment is, relative to its rope?

Basically, I would like a spehre to always be at the end of the rope.


Thanks


RE: End of the rope! Match position - josemendez - 09-08-2023

(07-08-2023, 03:12 PM)Renman3000 Wrote: Hi there, 
I have a rope. 

Is there a way to child a transform, renderer to the rope and specifuiclally a particle attachment so that this transform rednerer is always, whereever the selected particle attachment is, relative to its rope?

Basically, I would like a spehre to always be at the end of the rope.


Thanks

Hi,

There's many ways to do this, depending on what you want exactly.

If you want to make sure a transform is always at the position of the last particle in the rope, you can just set the position of the transform to the position of the last particle:

Code:
int lastParticle = rope.elements[rope.elements.Count-1].particle2;
transform.position = rope.solver.TransformPoint(rope.solver.positions[lastParticle]);

Another option is to retrieve the position of the last frame in the rope, which will provide you with orientation information as well. You do this by using
Code:
var frame = rope.GetComponent<ObiPathSmoother>().GetSectionAt(1); // normalized coord from 0/start to 1/end
transform.position = frame.position;
transform.rotation = Quaternion.LookRotation(frame.tangent, frame.binormal);

A third option is to use the utility ObiRopeAttach component, which implements the second option (GetSectionAt) so you don't have to write it yourself.


kind regards,


RE: End of the rope! Match position - Alexander34 - 09-08-2023

(09-08-2023, 07:11 AM)josemendez Wrote: Hi,

There's many ways to do this, depending on what you want exactly.

If you want to make sure a transform is always at the position of the last particle in the rope, you can just set the position of the transform to the position of the last particle:

Code:
int lastParticle = rope.elements[rope.elements.Count-1].particle2;
transform.position = rope.solver.TransformPoint(rope.solver.positions[lastParticle]);

Another option is to retrieve the position of the last frame in the rope, which will provide you with orientation information as well. You do this by using
Code:
var frame = rope.GetComponent<ObiPathSmoother>().GetSectionAt(1); // normalized coord from 0/start to 1/end
transform.position = frame.position;
transform.rotation = Quaternion.LookRotation(frame.tangent, frame.binormal);

A third option is to use the utility ObiRopeAttach component, which implements the second option (GetSectionAt) so you don't have to write it yourself.


kind regards,
Cannot resolve symbol 'TransformPoint'  - rope.solver.TransformPoint


RE: End of the rope! Match position - josemendez - 09-08-2023

(09-08-2023, 12:23 PM)Alexander34 Wrote: Cannot resolve symbol 'TransformPoint'  - rope.solver.TransformPoint

Sorry, typo. Should be rope.solver.transform.TransformPoint


RE: End of the rope! Match position - Renman3000 - 09-08-2023

(09-08-2023, 07:11 AM)josemendez Wrote: Hi,

There's many ways to do this, depending on what you want exactly.

If you want to make sure a transform is always at the position of the last particle in the rope, you can just set the position of the transform to the position of the last particle:

Code:
int lastParticle = rope.elements[rope.elements.Count-1].particle2;
transform.position = rope.solver.TransformPoint(rope.solver.positions[lastParticle]);

Another option is to retrieve the position of the last frame in the rope, which will provide you with orientation information as well. You do this by using
Code:
var frame = rope.GetComponent<ObiPathSmoother>().GetSectionAt(1); // normalized coord from 0/start to 1/end
transform.position = frame.position;
transform.rotation = Quaternion.LookRotation(frame.tangent, frame.binormal);

A third option is to use the utility ObiRopeAttach component, which implements the second option (GetSectionAt) so you don't have to write it yourself.


kind regards,
Thanks!


RE: End of the rope! Match position - Renman3000 - 11-08-2023

Hi there, 
So a peculiar issue that I can not solve.


Code:
Vector3 posEnd = obiRope.solver.positions[i_lastParticle];


So some background, this is running on an instance of my own Class, TentacleUnit, of which I have a half dozen in an array. Despite double-checking and rechecking that each instance of TentacleUnit is referencing its own obiRope, the position being reported is one position, across all units. 

Is there any reason, you can think of where calling one instance of an obiRope.Solver would imply this across all?


Thanks


RE: End of the rope! Match position - josemendez - 14-08-2023

(11-08-2023, 04:33 PM)Renman3000 Wrote: Hi there, 
So a peculiar issue that I can not solve.


Code:
Vector3 posEnd = obiRope.solver.positions[i_lastParticle];


So some background, this is running on an instance of my own Class, TentacleUnit, of which I have a half dozen in an array. Despite double-checking and rechecking that each instance of TentacleUnit is referencing its own obiRope, the position being reported is one position, across all units. 

Is there any reason, you can think of where calling one instance of an obiRope.Solver would imply this across all?


Thanks

Hi!

Particle data is stored in the solver, for all actors in it. So if you're accessing the same particle index for all ropes, the position reported will be the same for all of them.

How are you calculating i_lastParticle for each rope?

kind regards,


RE: End of the rope! Match position - Renman3000 - 14-08-2023

(14-08-2023, 06:18 AM)josemendez Wrote: Hi!

Particle data is stored in the solver, for all actors in it. So if you're accessing the same particle index for all ropes, the position reported will be the same for all of them.

How are you calculating i_lastParticle for each rope?

kind regards,


Hi,
So a little confused in that, I was thinking that if I called via my own script, an instance of an ObiRope obiRopeX that by further calling obiRopeX.Solver.positions[i_lastParticleIndex], that this would generate the last particle attachment, particle group position, on obiRopeX.



If this is incorrect, how do I get a position of a Particle Attachment, Particle Group?
Thanks


RE: End of the rope! Match position - josemendez - 14-08-2023

(14-08-2023, 04:26 PM)Renman3000 Wrote: Hi,
So a little confused in that, I was thinking that if I called via my own script, an instance of an ObiRope obiRopeX that by further calling obiRopeX.Solver.positions[i_lastParticleIndex], that this would generate the last particle attachment, particle group position, on obiRopeX.

Hi,

It entirely depends on the value of “i_lastParticleIndex”, that’s why I asked how you are calculating it. But in general no, rope.solver.positions contains all particles managed by that solver, not just the particles for one particular rope. See:

http://obi.virtualmethodstudio.com/manual/6.3/bigpicture.html
http://obi.virtualmethodstudio.com/manual/6.3/scriptingparticles.html

Quote:If this is incorrect, how do I get a position of a Particle Attachment, Particle Group?
Thanks

Particle, Particle group and Attachment are 3 completely different things. If you mean how to get the position of the last particle in the rope, you can use this snippet I suggested before:

Code:
int lastParticleIndex = rope.elements[rope.elements.Count-1].particle2;
var position = rope.solver.transform.TransformPoint(rope.solver.positions[lastParticleIndex]);

If you're interested in particle groups instead, to get the index of a particle in a group you do:

Code:
var group= rope.blueprint.groups[groupIndex];
int particleIndex = rope.solverIndices[group.particleIndices[0]]; // in a rope, all groups contain a single particle.

Using this index you can look up its position in the solver.positions array as well.

Attachments have no position, since they're just a constraint relationship between a particle group and a transform.


RE: End of the rope! Match position - Renman3000 - 15-08-2023

(14-08-2023, 08:29 PM)josemendez Wrote: Hi,

It entirely depends on the value of “i_lastParticleIndex”, that’s why I asked how you are calculating it. But in general no, rope.solver.positions contains all particles managed by that solver, not just the particles for one particular rope. See:

http://obi.virtualmethodstudio.com/manual/6.3/bigpicture.html
http://obi.virtualmethodstudio.com/manual/6.3/scriptingparticles.html


Particle, Particle group and Attachment are 3 completely different things. If you mean how to get the position of the last particle in the rope, you can use this snippet I suggested before:

Code:
int lastParticleIndex = rope.elements[rope.elements.Count-1].particle2;
var position = rope.solver.transform.TransformPoint(rope.solver.positions[lastParticleIndex]);

If you're interested in particle groups instead, to get the index of a particle in a group you do:

Code:
var group= rope.blueprint.groups[groupIndex];
int particleIndex = rope.solverIndices[group.particleIndices[0]]; // in a rope, all groups contain a single particle.

Using this index you can look up its position in the solver.positions array as well.

Attachments have no position, since they're just a constraint relationship between a particle group and a transform.




Hi, so if you imagine a rope, with three particleAttachments, each with a unique particleGroup, where index 0 is left, index 1 is middle and index 2 is the right end of the rope. 

I want to know the position that is, index 2.