affine.rst 11 KB

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