@@ -5,6 +5,8 @@ affine transforms
5
5
6
6
Header: cglm/affine.h
7
7
8
+ Initialize Transform Matrices
9
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8
10
Functions with **_make ** prefix expect you don't have a matrix and they create
9
11
a matrix for you. You don't need to pass identity matrix.
10
12
@@ -15,6 +17,107 @@ before sending to transfrom functions.
15
17
There are also functions to decompose transform matrix. These functions can't
16
18
decompose matrix after projected.
17
19
20
+ Rotation Center
21
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 algorihm ("Rotate or Scale around specific Point (Pivot Point / Anchor Point)").
27
+
28
+ Rotate or Scale around specific Point (Anchor Point)
29
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
30
+
31
+ If you want to rotate model around arbibtrary point follow these steps:
32
+
33
+ 1. Move model from pivot point to origin: **translate(-pivot.x, -pivot.y, -pivot.z) **
34
+ 2. Apply rotation (or scaling maybe)
35
+ 3. Move model back from origin to pivot (reverse of step-1): **translate(pivot.x, pivot.y, pivot.z) **
36
+
37
+ **glm_rotate_at **, **glm_quat_rotate_at ** and their helper functions works that way.
38
+
39
+ The implementation would be:
40
+
41
+ .. code-block :: c
42
+ :linenos:
43
+
44
+ glm_translate(m, pivot);
45
+ glm_rotate(m, angle, axis);
46
+ glm_translate(m, pivotInv); /* pivotInv = -pivot */
47
+
48
+ Transforms Order
49
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
50
+
51
+ It is important to understand this part especially if you call transform
52
+ functions multiple times
53
+
54
+ `glm_translate `, `glm_rotate `, `glm_scale ` and `glm_quat_rotate ` and their
55
+ helpers functions works like this (cglm may provide reverse order too as alternative in the future):
56
+
57
+ .. code-block :: c
58
+ :linenos:
59
+
60
+ TransformMatrix = TransformMatrix * TraslateMatrix; // glm_translate()
61
+ TransformMatrix = TransformMatrix * RotateMatrix; // glm_rotate(), glm_quat_rotate()
62
+ TransformMatrix = TransformMatrix * ScaleMatrix; // glm_scale()
63
+
64
+ As you can see it is multipled as right matrix. For instance what will happen if you call `glm_translate ` twice?
65
+
66
+ .. code-block :: c
67
+ :linenos:
68
+
69
+ glm_translate(transform, translate1); /* transform = transform * translate1 */
70
+ glm_translate(transform, translate2); /* transform = transform * translate2 */
71
+ glm_rotate(transform, angle, axis) /* transform = transform * rotation */
72
+
73
+ Now lets try to understand this:
74
+
75
+ 1. You call translate using `translate1 ` and you expect it will be first transform
76
+ because you call it first, do you?
77
+
78
+ Result will be **`transform = transform * translate1` **
79
+
80
+ 2. Then you call translate using `translate2 ` and you expect it will be second transform?
81
+
82
+ Result will be **`transform = transform * translate2` **. Now lets expand transform,
83
+ it was `transform * translate1 ` before second call.
84
+
85
+ Now it is **`transform = transform * translate1 * translate2` **, now do you understand what I say?
86
+
87
+ 3. After last call transform will be:
88
+
89
+ **`transform = transform * translate1 * translate2 * rotation` **
90
+
91
+ The order will be; **rotation will be applied first **, then **translate2 ** then **translate1 **
92
+
93
+ It is all about matrix multiplication order. It is similar to MVP matrix:
94
+ `MVP = Projection * View * Model `, model will be applied first, then view then projection.
95
+
96
+ **Confused? **
97
+
98
+ In the end the last function call applied first in shaders.
99
+
100
+ As alternative way, you can create transform matrices individually then combine manually,
101
+ but don't forget that `glm_translate `, `glm_rotate `, `glm_scale `... are optimized and should be faster (an smaller assembly output) than manual multiplication
102
+
103
+ .. code-block :: c
104
+ :linenos:
105
+
106
+ mat4 transform1, transform2, transform3, finalTransform;
107
+
108
+ glm_translate_make(transform1, translate1);
109
+ glm_translate_make(transform2, translate2);
110
+ glm_rotate_make(transform3, angle, axis);
111
+
112
+ /* first apply transform1, then transform2, thentransform3 */
113
+ glm_mat4_mulN((mat4 *[]){&transform3, &transform2, &transform1}, 3, finalTransform);
114
+
115
+ /* if you don't want to use mulN, same as above */
116
+ glm_mat4_mul(transform3, transform2, finalTransform);
117
+ glm_mat4_mul(finalTransform, transform1, finalTransform);
118
+
119
+ Now transform1 will be applied first, then transform2 then transform3
120
+
18
121
Table of contents (click to go):
19
122
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20
123
@@ -29,15 +132,14 @@ Functions:
29
132
#. :c:func: `glm_scale_to `
30
133
#. :c:func: `glm_scale_make `
31
134
#. :c:func: `glm_scale `
32
- #. :c:func: `glm_scale1 `
33
135
#. :c:func: `glm_scale_uni `
34
136
#. :c:func: `glm_rotate_x `
35
137
#. :c:func: `glm_rotate_y `
36
138
#. :c:func: `glm_rotate_z `
37
- #. :c:func: `glm_rotate_ndc_make `
38
139
#. :c:func: `glm_rotate_make `
39
- #. :c:func: `glm_rotate_ndc `
40
140
#. :c:func: `glm_rotate `
141
+ #. :c:func: `glm_rotate_at `
142
+ #. :c:func: `glm_rotate_atm `
41
143
#. :c:func: `glm_decompose_scalev `
42
144
#. :c:func: `glm_uniscaled `
43
145
#. :c:func: `glm_decompose_rs `
@@ -122,10 +224,6 @@ Functions documentation
122
224
| *[in, out]* **m** affine transfrom
123
225
| *[in]* **v** scale vector [x, y, z]
124
226
125
- .. c:function:: void glm_scale1(mat4 m, float s)
126
-
127
- DEPRECATED! Use glm_scale_uni
128
-
129
227
.. c:function:: void glm_scale_uni(mat4 m, float s)
130
228
131
229
applies uniform scale to existing transform matrix v = [s, s, s]
@@ -165,16 +263,6 @@ Functions documentation
165
263
| *[in]* **angle** angle (radians)
166
264
| *[out]* **dest** rotated matrix
167
265
168
- .. c:function:: void glm_rotate_ndc_make(mat4 m, float angle, vec3 axis_ndc)
169
-
170
- creates NEW rotation matrix by angle and axis
171
- this name may change in the future. axis must be is normalized
172
-
173
- Parameters:
174
- | *[out]* **m** affine transfrom
175
- | *[in]* **angle** angle (radians)
176
- | *[in]* **axis_ndc** normalized axis
177
-
178
266
.. c:function:: void glm_rotate_make(mat4 m, float angle, vec3 axis)
179
267
180
268
creates NEW rotation matrix by angle and axis,
@@ -185,22 +273,35 @@ Functions documentation
185
273
| *[in]* **axis** angle (radians)
186
274
| *[in]* **axis** axis
187
275
188
- .. c:function:: void glm_rotate_ndc (mat4 m, float angle, vec3 axis_ndc )
276
+ .. c:function:: void glm_rotate (mat4 m, float angle, vec3 axis )
189
277
190
278
rotate existing transform matrix around Z axis by angle and axis
191
- this name may change in the future, axis must be normalized.
192
279
193
280
Parameters:
194
- | *[out]* **m** affine transfrom
195
- | *[in]* **angle** angle (radians)
196
- | *[in]* **axis_ndc ** normalized axis
281
+ | *[in, out]* **m** affine transfrom
282
+ | *[in]* **angle** angle (radians)
283
+ | *[in]* **axis ** axis
197
284
198
- .. c:function:: void glm_rotate (mat4 m, float angle, vec3 axis)
285
+ .. c:function:: void glm_rotate_at (mat4 m, vec3 pivot , float angle, vec3 axis)
199
286
200
- rotate existing transform matrix around Z axis by angle and axis
287
+ rotate existing transform around given axis by angle at given pivot point (rotation center)
288
+
289
+ Parameters:
290
+ | *[in, out]* **m** affine transfrom
291
+ | *[in]* **pivot** pivot, anchor point, rotation center
292
+ | *[in]* **angle** angle (radians)
293
+ | *[in]* **axis** axis
294
+
295
+ .. c:function:: void glm_rotate_atm(mat4 m, vec3 pivot, float angle, vec3 axis)
296
+
297
+ | creates NEW rotation matrix by angle and axis at given point
298
+ | this creates rotation matrix, it assumes you don't have a matrix
299
+
300
+ | this should work faster than glm_rotate_at because it reduces one glm_translate.
201
301
202
302
Parameters:
203
303
| *[in, out]* **m** affine transfrom
304
+ | *[in]* **pivot** pivot, anchor point, rotation center
204
305
| *[in]* **angle** angle (radians)
205
306
| *[in]* **axis** axis
206
307
0 commit comments