- Home /
Math behind Transform.TransformPoint?
So I need the functionality of Transform.TransformPoint and Transform.InverseTransformPoint inside a thread. I can't call those functions directly since they are not thread safe.
I do know safely that the transform won't change while the thread is running so I figured I could achieve the same results if I can figure out the math behind those two functions and do some magic with the transform.worldToLocal and transform.localToWorld matrix.
Unfortunately I'm not a magician, especially when it comes to complex vector and matrix math. Can anybody help me with this? I tried something like transform.localToWorldMatrix * p
but that doesn't seem to produce the same results as transform.TransformPoint(p)
edit: actually that was not thread safe too, but that keeps me from just copying the Matrix4x4 values into the threads memory
Long story short, I'm trying to figure the formula behind the two transform functions and rebuild them in a thread safe method that I can use for my heavy calculations.
Answer by Bunny83 · Nov 28, 2017 at 02:39 AM
Well you almost solved your problem ^^. The problem here is that you most likely pass in a Vector3 position. However a 4x4 matrix represents a homogeneous coordinate space. A position / point / direction in homogeneous coordinates has 4 elements and not 3. Unity has implicit conversion operators for it's Vector2 / 3 / 4 structs. So it implicitly converts your Vector3 into a Vector4. However the "w" coordinate is initialized to 0 in this case. This would turn your vector into a "direction" vector. Directions are not affected by the translation that the matrix might apply. So it only scales and rotates the vector.
To fix this you have to pass in a Vector4 with w set to "1".
Vector3 pos;
Vector4 v = pos;
v.w = 1;
Vector4 wPos = localToWorld * v;
Keep in mind that you have to read the localToWorld property on the main thread. Once you have the matrix you can use it in another thread.
Another way is to use MultiplyPoint3x4. This would be probably the better solution ^^. It does the direct multiplication with the matrix and assumes that the matrix is a 3 by 4 matrix.
ps: $$anonymous$$atrices are not blackmagic. Just have a look at Unity's implementation. "$$anonymous$$ultiplyPoint" does an actual homogeneous multiplication by perfor$$anonymous$$g the homogeneous divide at the end (dividing the whole result by "w").
$$anonymous$$ultiplyPoint3x4 does not do the homogeneous divide. However this is only required for the projection matrix when you actually project a point into screen space.
$$anonymous$$ultiplyVector is pretty much the same as "$$anonymous$$ultiplyPoint3x4" but it basically expects a direction vector. So it does not add the translation but only applies the rotation and scale.
Oh i just found my matrix crash course. The question over there was mainly about the projection matrix but the first part of my answer does explain the matrix basics and what a transformation matrix actually does.
And just two days ago someone posted a question about rotation matrices.
That's exactly what I've been looking for, thanks a lot for the great explanation!
$$anonymous$$ade me read a little more about matrices in your crash course and some other sources and I think I understand the math behind it now. You are right, it's no black magic it makes sence! :D I always expected that matrices are not 'human readable' so I never made the effort to figure that out (and I back in school slacked on that topic I guess), I feel a lot smarter now :) codingskill+1
Code in the thread works as expected now, my problem is solved, I'm happy.
cheers!
Your answer
Follow this Question
Related Questions
How to avoid changing transform.parent? 2 Answers
Is there such a thing as Unity Algebra? 0 Answers
How to edit one axis of the transform position 1 Answer
Vector3 Projection 2 Answers
CharacterController on Moving Surface 4 Answers