How to setTransform on a Matrix I calculate?

I have calculated a matrix, and now I want to set the transform to that matrix?

Is this possible?

If not, is there a Matrix.Decompose Function which can be used to set localPosition, rotation, scale...

If not, how the hell can you develop anything complicated with this engine?

thanks, stringa

4 Answers

4

Unity doesn't store transforms as matrices. Instead it stores a transform as a local position (Vector3), local rotation (Quaternion), and local scale (Vector3). Some things, like shear, can't be represented this way.

You can modify the transform by setting the localPosition, localRotation, and localScale.

If your calculations have to go through a matrix, you can still convert a matrix into a position and rotation. The below code does that, although it doesn't support scale (because I didn't need that when I wrote the code):

public static void TransformFromMatrix(Matrix4x4 matrix, Transform trans) {
    trans.rotation = Util.QuaternionFromMatrix(matrix);
    trans.position = matrix.GetColumn(3); // uses implicit conversion from Vector4 to Vector3
}

public static Quaternion QuaternionFromMatrix(Matrix4x4 m) {
    // Adapted from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
    Quaternion q = new Quaternion();
    q.w = Mathf.Sqrt( Mathf.Max( 0, 1 + m[0,0] + m[1,1] + m[2,2] ) ) / 2; 
    q.x = Mathf.Sqrt( Mathf.Max( 0, 1 + m[0,0] - m[1,1] - m[2,2] ) ) / 2; 
    q.y = Mathf.Sqrt( Mathf.Max( 0, 1 - m[0,0] + m[1,1] - m[2,2] ) ) / 2; 
    q.z = Mathf.Sqrt( Mathf.Max( 0, 1 - m[0,0] - m[1,1] + m[2,2] ) ) / 2; 
    q.x *= Mathf.Sign( q.x * ( m[2,1] - m[1,2] ) );
    q.y *= Mathf.Sign( q.y * ( m[0,2] - m[2,0] ) );
    q.z *= Mathf.Sign( q.z * ( m[1,0] - m[0,1] ) );
    return q;
}

If not, how the hell can you develop anything complicated with this engine?

People develop complicated things with this engine all the time, so apparently it's not much of a problem for most people :)

That said, I don't know the answer to your question for sure, but since no one's answered yet, I'll go ahead and offer a couple of thoughts.

Based on the documentation at least, it doesn't seem like there's a way to assign an arbitrary transform to a Transform component, so I'm not sure how you'd apply (for example) shear. I've never needed to do that in Unity though, so there may be a way that I'm not aware of.

You can certainly decompose an SRT matrix into its constituent transforms if you want. I think it would be helpful to know though what you're trying to do, and what you're being prevented from doing. (Are you trying to apply shear? Or just scale, rotation, and translation? And if the latter, why not just use the appropriate Transform fields/properties?)

If you could edit your original post to include some additional information, it would probably help.

To translate a point or a vector from one location to another would require an affine transformation.

point = (x1, x2, x3, 1) or

vector = (x1, x2, x3, 0)

translationVector = (u1, u2, u3) placed in the block matrix T.

Example:

Below is a Translation Matrix T that has the vector u = (1, 2, 3).

The point (vertex) v = (1, 1, 1, 1).

The translated point is v * T = (2, 3, 4, 1).

alt text

This translation matrix T then can be multiplied to other 4x4 affine matrices (ie rotation, scale, etc.). Source: Geometric tools for computer graphics: By Philip J. Schneider, David H. Eberly: Chapter 4.

If you translate a vector instead of a point, you'll get the same vector... Why?

Thanks CSDG

An addendum to runevision :diamonds::diamonds:’s answer. It should read “GetColumn(2)”