2
0

affine.rst 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. .. default-domain:: C
  2. 3D Affine Transforms
  3. ================================================================================
  4. Header: cglm/affine.h
  5. Before starting, **cglm** provides two kind of transform functions; pre and post.
  6. Pre functions (`T' = Tnew * T`) are like `glm_translate`, `glm_rotate` which means it will translate the vector first and then apply the model transformation.
  7. Post functions (`T' = T * Tnew`) are like `glm_translated`, `glm_rotated` which means it will apply the model transformation first and then translate the vector.
  8. `glm_translate`, `glm_rotate` are pre functions and are similar to C++ **glm** which you are familiar with.
  9. In new versions of **cglm** we added `glm_translated`, `glm_rotated`... which are post functions,
  10. they are useful in some cases, e.g. append transform to existing transform (apply/append transform as last transform T' = T * Tnew).
  11. Post functions are named after pre functions with `ed` suffix, e.g. `glm_translate` -> `glm_translated`. So don't mix them up.
  12. Initialize Transform Matrices
  13. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  14. Functions with **_make** prefix expect you don't have a matrix and they create
  15. a matrix for you. You don't need to pass identity matrix.
  16. But other functions expect you have a matrix and you want to transform them. If
  17. you didn't have any existing matrix you have to initialize matrix to identity
  18. before sending to transform functions.
  19. There are also functions to decompose transform matrix. These functions can't
  20. decompose matrix after projected.
  21. Rotation Center
  22. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  23. Rotating functions uses origin as rotation center (pivot/anchor point),
  24. since scale factors are stored in rotation matrix, same may also true for scalling.
  25. cglm provides some functions for rotating around at given point e.g.
  26. **glm_rotate_at**, **glm_quat_rotate_at**. Use them or follow next section for algorithm ("Rotate or Scale around specific Point (Pivot Point / Anchor Point)").
  27. Also **cglm** provides :c:func:`glm_spin` and :c:func:`glm_spinned` functions to rotate around itself. No need to give pivot.
  28. These functions are useful for rotating around center of object.
  29. Rotate or Scale around specific Point (Anchor Point)
  30. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  31. If you want to rotate model around arbitrary point follow these steps:
  32. 1. Move model from pivot point to origin: **translate(-pivot.x, -pivot.y, -pivot.z)**
  33. 2. Apply rotation (or scaling maybe)
  34. 3. Move model back from origin to pivot (reverse of step-1): **translate(pivot.x, pivot.y, pivot.z)**
  35. **glm_rotate_at**, **glm_quat_rotate_at** and their helper functions works that way.
  36. So if you use them you don't need to do these steps manually which are done by **cglm**.
  37. The implementation would be:
  38. .. code-block:: c
  39. :linenos:
  40. glm_translate(m, pivot);
  41. glm_rotate(m, angle, axis);
  42. glm_translate(m, pivotInv); /* pivotInv = -pivot */
  43. or just:
  44. .. code-block:: c
  45. :linenos:
  46. glm_rotate_at(m, pivot, angle, axis);
  47. .. _TransformsOrder:
  48. Transforms Order
  49. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  50. It is important to understand this part especially if you call transform
  51. functions multiple times
  52. `glm_translate`, `glm_rotate`, `glm_scale` and `glm_quat_rotate` and their
  53. helpers functions works like this (cglm provides reverse order as `ed` suffix e.g `glm_translated`, `glm_rotated` see post transforms):
  54. .. code-block:: c
  55. :linenos:
  56. TransformMatrix = TransformMatrix * TranslateMatrix; // glm_translate()
  57. TransformMatrix = TransformMatrix * RotateMatrix; // glm_rotate(), glm_quat_rotate()
  58. TransformMatrix = TransformMatrix * ScaleMatrix; // glm_scale()
  59. As you can see it is multiplied as right matrix. For instance what will happen if you call `glm_translate` twice?
  60. .. code-block:: c
  61. :linenos:
  62. glm_translate(transform, translate1); /* transform = transform * translate1 */
  63. glm_translate(transform, translate2); /* transform = transform * translate2 */
  64. glm_rotate(transform, angle, axis) /* transform = transform * rotation */
  65. Now lets try to understand this:
  66. 1. You call translate using `translate1` and you expect it will be first transform
  67. because you call it first, do you?
  68. Result will be **`transform = transform * translate1`**
  69. 2. Then you call translate using `translate2` and you expect it will be second transform?
  70. Result will be **`transform = transform * translate2`**. Now lets expand transform,
  71. it was `transform * translate1` before second call.
  72. Now it is **`transform = transform * translate1 * translate2`**, now do you understand what I say?
  73. 3. After last call transform will be:
  74. **`transform = transform * translate1 * translate2 * rotation`**
  75. The order will be; **rotation will be applied first**, then **translate2** then **translate1**
  76. It is all about matrix multiplication order. It is similar to MVP matrix:
  77. `MVP = Projection * View * Model`, model will be applied first, then view then projection.
  78. **Confused?**
  79. In the end the last function call applied first in shaders.
  80. As alternative way, you can create transform matrices individually then combine manually,
  81. but don't forget that `glm_translate`, `glm_rotate`, `glm_scale`... are optimized and should be faster (an smaller assembly output) than manual multiplication
  82. .. code-block:: c
  83. :linenos:
  84. mat4 transform1, transform2, transform3, finalTransform;
  85. glm_translate_make(transform1, translate1);
  86. glm_translate_make(transform2, translate2);
  87. glm_rotate_make(transform3, angle, axis);
  88. /* first apply transform1, then transform2, thentransform3 */
  89. glm_mat4_mulN((mat4 *[]){&transform3, &transform2, &transform1}, 3, finalTransform);
  90. /* if you don't want to use mulN, same as above */
  91. glm_mat4_mul(transform3, transform2, finalTransform);
  92. glm_mat4_mul(finalTransform, transform1, finalTransform);
  93. Now transform1 will be applied first, then transform2 then transform3
  94. Table of contents (click to go):
  95. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  96. Functions:
  97. 1. :c:func:`glm_translate_to`
  98. #. :c:func:`glm_translate`
  99. #. :c:func:`glm_translate_x`
  100. #. :c:func:`glm_translate_y`
  101. #. :c:func:`glm_translate_z`
  102. #. :c:func:`glm_translate_make`
  103. #. :c:func:`glm_scale_to`
  104. #. :c:func:`glm_scale_make`
  105. #. :c:func:`glm_scale`
  106. #. :c:func:`glm_scale_uni`
  107. #. :c:func:`glm_rotate_x`
  108. #. :c:func:`glm_rotate_y`
  109. #. :c:func:`glm_rotate_z`
  110. #. :c:func:`glm_rotate_make`
  111. #. :c:func:`glm_rotate`
  112. #. :c:func:`glm_rotate_at`
  113. #. :c:func:`glm_rotate_atm`
  114. #. :c:func:`glm_decompose_scalev`
  115. #. :c:func:`glm_uniscaled`
  116. #. :c:func:`glm_decompose_rs`
  117. #. :c:func:`glm_decompose`
  118. Post functions (**NEW**):
  119. 1. :c:func:`glm_translated_to`
  120. #. :c:func:`glm_translated`
  121. #. :c:func:`glm_translated_x`
  122. #. :c:func:`glm_translated_y`
  123. #. :c:func:`glm_translated_z`
  124. #. :c:func:`glm_rotated_x`
  125. #. :c:func:`glm_rotated_y`
  126. #. :c:func:`glm_rotated_z`
  127. #. :c:func:`glm_rotated`
  128. #. :c:func:`glm_rotated_at`
  129. #. :c:func:`glm_spinned`
  130. Functions documentation
  131. ~~~~~~~~~~~~~~~~~~~~~~~
  132. .. toctree::
  133. :maxdepth: 1
  134. :caption: Affine categories:
  135. affine-common
  136. affine-pre
  137. affine-post