10-12-2022, 11:27 AM
(This post was last modified: 10-12-2022, 11:58 AM by josemendez.)
(09-12-2022, 08:36 PM)idmah Wrote:Code:var pos = pathSmoother.transform.TransformPoint(ropeComp.solver.positions[ropeComp.solverIndices[i]]);
The important thing to remember is that particle data in Obi is always expressed in the solver's local space. This will return a position in world space as long as the rope and the solver spaces overlap (that is, the rope's local position and rotation are zero w.r.t. the solver). Your original FindClosestRopeParticle() function did it like this, so I assumed this was the case.
If it isn't, to return the position in world space regardless of the relationship between the rope and the solver you should do:
Code:
ropeComp.solver.transform.TransformPoint(ropeComp.solver.positions[ropeComp.solverIndices[i]]);
This is pretty much equivalent to:
Code:
pos = ropeComp.GetParticlePosition(ropeComp.solverIndices[i]);
It's easy to see why by looking at the implementation of GetParticlePosition():
Code:
/// <summary>
/// Given a solver particle index, returns the position of that particle in world space.
/// </summary>
/// <param name="solverIndex"> Index of the particle in the solver arrays.</param>
/// <returns>
/// The position of a given particle in world space.
/// </returns>
public Vector3 GetParticlePosition(int solverIndex)
{
if (isLoaded)
return m_Solver.transform.TransformPoint(m_Solver.renderablePositions[solverIndex]);
return Vector3.zero;
}
If the actor is loaded, it transforms the particle position from the solver's local space to world space and returns it. The only difference is that GetParticlePosition() returns an interpolated position in case solver interpolation is enabled (that's what "renderablePositions" are, as opposed to just "positions" which are not interpolated between frames). Otherwise it's identical to ropeComp.solver.transform.TransformPoint(ropeComp.solver.positions[ropeComp.solverIndices[i]]);
Quote:So exploring the idea that TransformPoint is giving me troubles.
So wrote found this and modified it.
No need to reimplement transform.TransformPoint(). Your function basically builds the transform's localToWorldMatrix and multiplies the input point by it, which is the exact same thing Unity does internally.
This:
Code:
var worldPos = transform.TransformPoint(localPos);
this:
Code:
var worldPos = transform.localToWorldMatrix.MultiplyPoint3x4(localPos);
and this:
Code:
Matrix4x4 localToWorld = Matrix4x4.TRS (transform.position, transform.rotation, transform.lossyScale);
var worldPos = localToWorld.MultiplyPoint3x4(localPos);
Are the same thing, in increasingly complicated forms (note: the last one should use lossyScale instead of localScale, although that's not 100% accurate scaling in all cases since correct composite scale can only be expressed in matrix form). Juggling data between vector spaces is something you'll find yourself doing very often when making games in any engine, so I would advise to keep working on it until you're reasonably sure you understand it perfectly. Keep up the good work!
