4 * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@gmail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files
8 * (the "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sublicense, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Basic linear algebra and a matrix stack helper.
37 struct gl_m4_entry *next;
42 struct gl_m4_entry stack;
43 struct gl_m4_entry *cache;
46 void gl_m4_identity(float *m)
72 void gl_m4_copy(float *dest, const float *src)
98 /* Matrix Multiplication
99 * This is the simplest algorithm to multiply two matrices. It computes:
101 * That is, n is left side and m is right side.
103 * Matrix-multiplication is heavy, avoid it if possible.
105 void gl_m4_mult_dest(float *dest, const float *n, const float *m)
107 unsigned int row, col, j;
109 if (!dest || !n || !m)
112 for (row = 0; row < 4; ++row) {
113 for (col = 0; col < 4; ++col) {
114 dest[row * 4 + col] = 0;
115 for (j = 0; j < 4; ++j)
116 dest[row * 4 + col] +=
117 n[row * 4 + j] * m[j * 4 + col];
122 /* this computes n = n * m */
123 void gl_m4_mult(float *n, const float *m)
130 gl_m4_mult_dest(tmp, n, m);
134 void gl_m4_translate(float *m, float x, float y, float z)
136 float trans[16] = { 1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1 };
141 gl_m4_mult(m, trans);
144 void gl_m4_scale(float *m, float x, float y, float z)
146 float scale[16] = { x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1 };
151 gl_m4_mult(m, scale);
154 void gl_m4_transpose_dest(float *dest, const float *src)
183 void gl_m4_transpose(float *m)
215 int gl_m4_stack_new(struct gl_m4_stack **out)
217 struct gl_m4_stack *stack;
222 stack = malloc(sizeof(*stack));
226 memset(stack, 0, sizeof(*stack));
227 gl_m4_identity(stack->stack.matrix);
233 void gl_m4_stack_free(struct gl_m4_stack *stack)
235 struct gl_m4_entry *tmp;
240 while (stack->stack.next) {
241 tmp = stack->stack.next;
242 stack->stack.next = tmp->next;
246 while (stack->cache) {
248 stack->cache = tmp->next;
255 float *gl_m4_stack_push(struct gl_m4_stack *stack)
257 struct gl_m4_entry *entry;
260 entry = stack->cache;
261 stack->cache = entry->next;
263 entry = malloc(sizeof(*entry));
268 gl_m4_copy(entry->matrix, stack->stack.matrix);
269 entry->next = stack->stack.next;
270 stack->stack.next = entry;
272 return stack->stack.matrix;
275 float *gl_m4_stack_pop(struct gl_m4_stack *stack)
277 struct gl_m4_entry *entry;
282 entry = stack->stack.next;
284 gl_m4_identity(stack->stack.matrix);
285 return stack->stack.matrix;
288 stack->stack.next = entry->next;
289 entry->next = stack->cache;
290 stack->cache = entry;
292 gl_m4_copy(stack->stack.matrix, entry->matrix);
294 return stack->stack.matrix;
297 float *gl_m4_stack_tip(struct gl_m4_stack *stack)
302 return stack->stack.matrix;