Why is it necessary to convert CALayer transform3D m34 before applying rotation transform?

The following code can do a perspective rotation conversion for a layer:

CATransform3D transform3DFoo = CATransform3DIdentity; transform3DFoo.m34 = -1.0 / 1000; transform3DFoo = CATransform3DRotate(transform3DFoo, M_PI / 4, 1, 0, 0); 

However, if two lines are reversed:

 CATransform3D transform3DFoo = CATransform3DIdentity; transform3DFoo = CATransform3DRotate(transform3DFoo, M_PI / 4, 1, 0, 0); transform3DFoo.m34 = -1.0 / 1000; 

then the prospect disappeared. Now it's spelling (no perspective). Someone familiar with the prospect knows the reason?


Update:

 // First Identity and then transform3DFoo.m34 = -1.0 / 1000; is done 1.00000 0.00000 0.00000 0.00000 0.00000 1.00000 0.00000 0.00000 0.00000 0.00000 1.00000 -0.00100 0.00000 0.00000 0.00000 1.00000 // and then CATransform3DRotate(transform3DFoo, M_PI / 4, 1, 0, 0); 1.00000 0.00000 0.00000 0.00000 0.00000 0.70711 0.70711 -0.00071 0.00000 -0.70711 0.70711 -0.00071 0.00000 0.00000 0.00000 1.00000 // Now start with Identity and only the Rotate statement is done: 1.00000 0.00000 0.00000 0.00000 0.00000 0.70711 0.70711 0.00000 0.00000 -0.70711 0.70711 0.00000 0.00000 0.00000 0.00000 1.00000 // and then transform3DFoo.m34 = -1.0 / 1000; is done 1.00000 0.00000 0.00000 0.00000 0.00000 0.70711 0.70711 0.00000 0.00000 -0.70711 0.70711 -0.00100 0.00000 0.00000 0.00000 1.00000 

("OpenGL" tag added because it is probably the same principle in OpenGL)

+4
source share
1 answer

Setting m34 first equivalent to rotating and then projecting first. Setting m34 last is roughly equivalent to projecting first and then rotating. Since the input coordinates have z = 0, projection will do nothing at first.

To understand why this is so, you need to understand a little how the transformation matrices work.

I believe that in CA the positions are transformed by the transformation matrix M , doing:

 [xyzw] = [xyzw] * M 

(see http://en.wikipedia.org/wiki/Matrix_multiplication )

Multiplying two transformation matrices is equivalent to combining transformations. First, the transformation / matrix on the left. It is pretty easy to see why this is:

 [xyzw] * (LEFT * RIGHT) = ([xyzw] * LEFT) * RIGHT 

Most (all?) CATransform3DRotate transformation functions of the CATransform3DRotate (for example, CATransform3DRotate ) simply undergo translation of your transformation matrix by another aptly constructed matrix, for example:

 M = ROTATE * M 

The m34 setup m34 roughly equivalent to premultiplexing the projection matrix, i.e.:

 M = PROJ * M 

(where PROJ is the projection matrix is ​​the identity matrix, but with the set m34 )

This is not entirely true (therefore, I continue to speak rudely) - it only works if M has zero values ​​0 and 1 in the right places. Basically, in the general case, just installing m34 is a pointless thing - the right thing is to multiply by the projection matrix.

In any case, if you put it all together, you can understand why what I said in the first paragraph is true (if I made no mistakes :)

+5
source

Source: https://habr.com/ru/post/1416354/


All Articles