affine.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. .. default-domain:: C
  2. 3D Affine Transforms
  3. ================================================================================
  4. Header: cglm/affine.h
  5. Initialize Transform Matrices
  6. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  7. Functions with **_make** prefix expect you don't have a matrix and they create
  8. a matrix for you. You don't need to pass identity matrix.
  9. But other functions expect you have a matrix and you want to transform them. If
  10. you didn't have any existing matrix you have to initialize matrix to identity
  11. before sending to transfrom functions.
  12. There are also functions to decompose transform matrix. These functions can't
  13. decompose matrix after projected.
  14. Rotation Center
  15. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  16. Rotating functions uses origin as rotation center (pivot/anchor point),
  17. since scale factors are stored in rotation matrix, same may also true for scalling.
  18. cglm provides some functions for rotating around at given point e.g.
  19. **glm_rotate_at**, **glm_quat_rotate_at**. Use them or follow next section for algorihm ("Rotate or Scale around specific Point (Pivot Point / Anchor Point)").
  20. Rotate or Scale around specific Point (Anchor Point)
  21. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  22. If you want to rotate model around arbibtrary point follow these steps:
  23. 1. Move model from pivot point to origin: **translate(-pivot.x, -pivot.y, -pivot.z)**
  24. 2. Apply rotation (or scaling maybe)
  25. 3. Move model back from origin to pivot (reverse of step-1): **translate(pivot.x, pivot.y, pivot.z)**
  26. **glm_rotate_at**, **glm_quat_rotate_at** and their helper functions works that way.
  27. The implementation would be:
  28. .. code-block:: c
  29. :linenos:
  30. glm_translate(m, pivot);
  31. glm_rotate(m, angle, axis);
  32. glm_translate(m, pivotInv); /* pivotInv = -pivot */
  33. .. _TransformsOrder:
  34. Transforms Order
  35. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  36. It is important to understand this part especially if you call transform
  37. functions multiple times
  38. `glm_translate`, `glm_rotate`, `glm_scale` and `glm_quat_rotate` and their
  39. helpers functions works like this (cglm may provide reverse order too as alternative in the future):
  40. .. code-block:: c
  41. :linenos:
  42. TransformMatrix = TransformMatrix * TraslateMatrix; // glm_translate()
  43. TransformMatrix = TransformMatrix * RotateMatrix; // glm_rotate(), glm_quat_rotate()
  44. TransformMatrix = TransformMatrix * ScaleMatrix; // glm_scale()
  45. As you can see it is multipled as right matrix. For instance what will happen if you call `glm_translate` twice?
  46. .. code-block:: c
  47. :linenos:
  48. glm_translate(transform, translate1); /* transform = transform * translate1 */
  49. glm_translate(transform, translate2); /* transform = transform * translate2 */
  50. glm_rotate(transform, angle, axis) /* transform = transform * rotation */
  51. Now lets try to understand this:
  52. 1. You call translate using `translate1` and you expect it will be first transform
  53. because you call it first, do you?
  54. Result will be **`transform = transform * translate1`**
  55. 2. Then you call translate using `translate2` and you expect it will be second transform?
  56. Result will be **`transform = transform * translate2`**. Now lets expand transform,
  57. it was `transform * translate1` before second call.
  58. Now it is **`transform = transform * translate1 * translate2`**, now do you understand what I say?
  59. 3. After last call transform will be:
  60. **`transform = transform * translate1 * translate2 * rotation`**
  61. The order will be; **rotation will be applied first**, then **translate2** then **translate1**
  62. It is all about matrix multiplication order. It is similar to MVP matrix:
  63. `MVP = Projection * View * Model`, model will be applied first, then view then projection.
  64. **Confused?**
  65. In the end the last function call applied first in shaders.
  66. As alternative way, you can create transform matrices individually then combine manually,
  67. but don't forget that `glm_translate`, `glm_rotate`, `glm_scale`... are optimized and should be faster (an smaller assembly output) than manual multiplication
  68. .. code-block:: c
  69. :linenos:
  70. mat4 transform1, transform2, transform3, finalTransform;
  71. glm_translate_make(transform1, translate1);
  72. glm_translate_make(transform2, translate2);
  73. glm_rotate_make(transform3, angle, axis);
  74. /* first apply transform1, then transform2, thentransform3 */
  75. glm_mat4_mulN((mat4 *[]){&transform3, &transform2, &transform1}, 3, finalTransform);
  76. /* if you don't want to use mulN, same as above */
  77. glm_mat4_mul(transform3, transform2, finalTransform);
  78. glm_mat4_mul(finalTransform, transform1, finalTransform);
  79. Now transform1 will be applied first, then transform2 then transform3
  80. Table of contents (click to go):
  81. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  82. Functions:
  83. 1. :c:func:`glm_translate_to`
  84. #. :c:func:`glm_translate`
  85. #. :c:func:`glm_translate_x`
  86. #. :c:func:`glm_translate_y`
  87. #. :c:func:`glm_translate_z`
  88. #. :c:func:`glm_translate_make`
  89. #. :c:func:`glm_scale_to`
  90. #. :c:func:`glm_scale_make`
  91. #. :c:func:`glm_scale`
  92. #. :c:func:`glm_scale_uni`
  93. #. :c:func:`glm_rotate_x`
  94. #. :c:func:`glm_rotate_y`
  95. #. :c:func:`glm_rotate_z`
  96. #. :c:func:`glm_rotate_make`
  97. #. :c:func:`glm_rotate`
  98. #. :c:func:`glm_rotate_at`
  99. #. :c:func:`glm_rotate_atm`
  100. #. :c:func:`glm_decompose_scalev`
  101. #. :c:func:`glm_uniscaled`
  102. #. :c:func:`glm_decompose_rs`
  103. #. :c:func:`glm_decompose`
  104. Functions documentation
  105. ~~~~~~~~~~~~~~~~~~~~~~~
  106. .. c:function:: void glm_translate_to(mat4 m, vec3 v, mat4 dest)
  107. translate existing transform matrix by *v* vector and store result in dest
  108. Parameters:
  109. | *[in]* **m** affine transfrom
  110. | *[in]* **v** translate vector [x, y, z]
  111. | *[out]* **dest** translated matrix
  112. .. c:function:: void glm_translate(mat4 m, vec3 v)
  113. translate existing transform matrix by *v* vector
  114. and stores result in same matrix
  115. Parameters:
  116. | *[in, out]* **m** affine transfrom
  117. | *[in]* **v** translate vector [x, y, z]
  118. .. c:function:: void glm_translate_x(mat4 m, float x)
  119. translate existing transform matrix by x factor
  120. Parameters:
  121. | *[in, out]* **m** affine transfrom
  122. | *[in]* **v** x factor
  123. .. c:function:: void glm_translate_y(mat4 m, float y)
  124. translate existing transform matrix by *y* factor
  125. Parameters:
  126. | *[in, out]* **m** affine transfrom
  127. | *[in]* **v** y factor
  128. .. c:function:: void glm_translate_z(mat4 m, float z)
  129. translate existing transform matrix by *z* factor
  130. Parameters:
  131. | *[in, out]* **m** affine transfrom
  132. | *[in]* **v** z factor
  133. .. c:function:: void glm_translate_make(mat4 m, vec3 v)
  134. creates NEW translate transform matrix by *v* vector.
  135. Parameters:
  136. | *[in, out]* **m** affine transfrom
  137. | *[in]* **v** translate vector [x, y, z]
  138. .. c:function:: void glm_scale_to(mat4 m, vec3 v, mat4 dest)
  139. scale existing transform matrix by *v* vector and store result in dest
  140. Parameters:
  141. | *[in]* **m** affine transfrom
  142. | *[in]* **v** scale vector [x, y, z]
  143. | *[out]* **dest** scaled matrix
  144. .. c:function:: void glm_scale_make(mat4 m, vec3 v)
  145. creates NEW scale matrix by v vector
  146. Parameters:
  147. | *[out]* **m** affine transfrom
  148. | *[in]* **v** scale vector [x, y, z]
  149. .. c:function:: void glm_scale(mat4 m, vec3 v)
  150. scales existing transform matrix by v vector
  151. and stores result in same matrix
  152. Parameters:
  153. | *[in, out]* **m** affine transfrom
  154. | *[in]* **v** scale vector [x, y, z]
  155. .. c:function:: void glm_scale_uni(mat4 m, float s)
  156. applies uniform scale to existing transform matrix v = [s, s, s]
  157. and stores result in same matrix
  158. Parameters:
  159. | *[in, out]* **m** affine transfrom
  160. | *[in]* **v** scale factor
  161. .. c:function:: void glm_rotate_x(mat4 m, float angle, mat4 dest)
  162. rotate existing transform matrix around X axis by angle
  163. and store result in dest
  164. Parameters:
  165. | *[in]* **m** affine transfrom
  166. | *[in]* **angle** angle (radians)
  167. | *[out]* **dest** rotated matrix
  168. .. c:function:: void glm_rotate_y(mat4 m, float angle, mat4 dest)
  169. rotate existing transform matrix around Y axis by angle
  170. and store result in dest
  171. Parameters:
  172. | *[in]* **m** affine transfrom
  173. | *[in]* **angle** angle (radians)
  174. | *[out]* **dest** rotated matrix
  175. .. c:function:: void glm_rotate_z(mat4 m, float angle, mat4 dest)
  176. rotate existing transform matrix around Z axis by angle
  177. and store result in dest
  178. Parameters:
  179. | *[in]* **m** affine transfrom
  180. | *[in]* **angle** angle (radians)
  181. | *[out]* **dest** rotated matrix
  182. .. c:function:: void glm_rotate_make(mat4 m, float angle, vec3 axis)
  183. creates NEW rotation matrix by angle and axis,
  184. axis will be normalized so you don't need to normalize it
  185. Parameters:
  186. | *[out]* **m** affine transfrom
  187. | *[in]* **axis** angle (radians)
  188. | *[in]* **axis** axis
  189. .. c:function:: void glm_rotate(mat4 m, float angle, vec3 axis)
  190. rotate existing transform matrix around Z axis by angle and axis
  191. Parameters:
  192. | *[in, out]* **m** affine transfrom
  193. | *[in]* **angle** angle (radians)
  194. | *[in]* **axis** axis
  195. .. c:function:: void glm_rotate_at(mat4 m, vec3 pivot, float angle, vec3 axis)
  196. rotate existing transform around given axis by angle at given pivot point (rotation center)
  197. Parameters:
  198. | *[in, out]* **m** affine transfrom
  199. | *[in]* **pivot** pivot, anchor point, rotation center
  200. | *[in]* **angle** angle (radians)
  201. | *[in]* **axis** axis
  202. .. c:function:: void glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis)
  203. | creates NEW rotation matrix by angle and axis at given point
  204. | this creates rotation matrix, it assumes you don't have a matrix
  205. | this should work faster than glm_rotate_at because it reduces one glm_translate.
  206. Parameters:
  207. | *[in, out]* **m** affine transfrom
  208. | *[in]* **pivot** pivot, anchor point, rotation center
  209. | *[in]* **angle** angle (radians)
  210. | *[in]* **axis** axis
  211. .. c:function:: void glm_decompose_scalev(mat4 m, vec3 s)
  212. decompose scale vector
  213. Parameters:
  214. | *[in]* **m** affine transform
  215. | *[out]* **s** scale vector (Sx, Sy, Sz)
  216. .. c:function:: bool glm_uniscaled(mat4 m)
  217. returns true if matrix is uniform scaled.
  218. This is helpful for creating normal matrix.
  219. Parameters:
  220. | *[in]* **m** matrix
  221. .. c:function:: void glm_decompose_rs(mat4 m, mat4 r, vec3 s)
  222. decompose rotation matrix (mat4) and scale vector [Sx, Sy, Sz]
  223. DON'T pass projected matrix here
  224. Parameters:
  225. | *[in]* **m** affine transform
  226. | *[out]* **r** rotation matrix
  227. | *[out]* **s** scale matrix
  228. .. c:function:: void glm_decompose(mat4 m, vec4 t, mat4 r, vec3 s)
  229. decompose affine transform, TODO: extract shear factors.
  230. DON'T pass projected matrix here
  231. Parameters:
  232. | *[in]* **m** affine transfrom
  233. | *[out]* **t** translation vector
  234. | *[out]* **r** rotation matrix (mat4)
  235. | *[out]* **s** scaling vector [X, Y, Z]