1a46c0ec8Sopenharmony_ci/* 2a46c0ec8Sopenharmony_ci * Copyright © 2008 Kristian Høgsberg 3a46c0ec8Sopenharmony_ci * Copyright © 2013-2015 Red Hat, Inc. 4a46c0ec8Sopenharmony_ci * 5a46c0ec8Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6a46c0ec8Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7a46c0ec8Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8a46c0ec8Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9a46c0ec8Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10a46c0ec8Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11a46c0ec8Sopenharmony_ci * 12a46c0ec8Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13a46c0ec8Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14a46c0ec8Sopenharmony_ci * Software. 15a46c0ec8Sopenharmony_ci * 16a46c0ec8Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17a46c0ec8Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18a46c0ec8Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19a46c0ec8Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20a46c0ec8Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21a46c0ec8Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22a46c0ec8Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 23a46c0ec8Sopenharmony_ci */ 24a46c0ec8Sopenharmony_ci 25a46c0ec8Sopenharmony_ci#pragma once 26a46c0ec8Sopenharmony_ci 27a46c0ec8Sopenharmony_ci#include "config.h" 28a46c0ec8Sopenharmony_ci 29a46c0ec8Sopenharmony_ci#include <string.h> 30a46c0ec8Sopenharmony_ci#include <stdbool.h> 31a46c0ec8Sopenharmony_ci#include <math.h> 32a46c0ec8Sopenharmony_ci 33a46c0ec8Sopenharmony_cistruct matrix { 34a46c0ec8Sopenharmony_ci float val[3][3]; /* [row][col] */ 35a46c0ec8Sopenharmony_ci}; 36a46c0ec8Sopenharmony_ci 37a46c0ec8Sopenharmony_cistatic inline double 38a46c0ec8Sopenharmony_cideg2rad(int degree) 39a46c0ec8Sopenharmony_ci{ 40a46c0ec8Sopenharmony_ci return M_PI * degree / 180.0; 41a46c0ec8Sopenharmony_ci} 42a46c0ec8Sopenharmony_ci 43a46c0ec8Sopenharmony_cistatic inline void 44a46c0ec8Sopenharmony_cimatrix_init_identity(struct matrix *m) 45a46c0ec8Sopenharmony_ci{ 46a46c0ec8Sopenharmony_ci memset(m, 0, sizeof(*m)); 47a46c0ec8Sopenharmony_ci m->val[0][0] = 1; 48a46c0ec8Sopenharmony_ci m->val[1][1] = 1; 49a46c0ec8Sopenharmony_ci m->val[2][2] = 1; 50a46c0ec8Sopenharmony_ci} 51a46c0ec8Sopenharmony_ci 52a46c0ec8Sopenharmony_cistatic inline void 53a46c0ec8Sopenharmony_cimatrix_from_farray6(struct matrix *m, const float values[6]) 54a46c0ec8Sopenharmony_ci{ 55a46c0ec8Sopenharmony_ci matrix_init_identity(m); 56a46c0ec8Sopenharmony_ci m->val[0][0] = values[0]; 57a46c0ec8Sopenharmony_ci m->val[0][1] = values[1]; 58a46c0ec8Sopenharmony_ci m->val[0][2] = values[2]; 59a46c0ec8Sopenharmony_ci m->val[1][0] = values[3]; 60a46c0ec8Sopenharmony_ci m->val[1][1] = values[4]; 61a46c0ec8Sopenharmony_ci m->val[1][2] = values[5]; 62a46c0ec8Sopenharmony_ci} 63a46c0ec8Sopenharmony_ci 64a46c0ec8Sopenharmony_cistatic inline void 65a46c0ec8Sopenharmony_cimatrix_init_scale(struct matrix *m, float sx, float sy) 66a46c0ec8Sopenharmony_ci{ 67a46c0ec8Sopenharmony_ci matrix_init_identity(m); 68a46c0ec8Sopenharmony_ci m->val[0][0] = sx; 69a46c0ec8Sopenharmony_ci m->val[1][1] = sy; 70a46c0ec8Sopenharmony_ci} 71a46c0ec8Sopenharmony_ci 72a46c0ec8Sopenharmony_cistatic inline void 73a46c0ec8Sopenharmony_cimatrix_init_translate(struct matrix *m, float x, float y) 74a46c0ec8Sopenharmony_ci{ 75a46c0ec8Sopenharmony_ci matrix_init_identity(m); 76a46c0ec8Sopenharmony_ci m->val[0][2] = x; 77a46c0ec8Sopenharmony_ci m->val[1][2] = y; 78a46c0ec8Sopenharmony_ci} 79a46c0ec8Sopenharmony_ci 80a46c0ec8Sopenharmony_cistatic inline void 81a46c0ec8Sopenharmony_cimatrix_init_rotate(struct matrix *m, int degrees) 82a46c0ec8Sopenharmony_ci{ 83a46c0ec8Sopenharmony_ci double s, c; 84a46c0ec8Sopenharmony_ci 85a46c0ec8Sopenharmony_ci s = sin(deg2rad(degrees)); 86a46c0ec8Sopenharmony_ci c = cos(deg2rad(degrees)); 87a46c0ec8Sopenharmony_ci 88a46c0ec8Sopenharmony_ci matrix_init_identity(m); 89a46c0ec8Sopenharmony_ci m->val[0][0] = c; 90a46c0ec8Sopenharmony_ci m->val[0][1] = -s; 91a46c0ec8Sopenharmony_ci m->val[1][0] = s; 92a46c0ec8Sopenharmony_ci m->val[1][1] = c; 93a46c0ec8Sopenharmony_ci} 94a46c0ec8Sopenharmony_ci 95a46c0ec8Sopenharmony_cistatic inline bool 96a46c0ec8Sopenharmony_cimatrix_is_identity(const struct matrix *m) 97a46c0ec8Sopenharmony_ci{ 98a46c0ec8Sopenharmony_ci return (m->val[0][0] == 1 && 99a46c0ec8Sopenharmony_ci m->val[0][1] == 0 && 100a46c0ec8Sopenharmony_ci m->val[0][2] == 0 && 101a46c0ec8Sopenharmony_ci m->val[1][0] == 0 && 102a46c0ec8Sopenharmony_ci m->val[1][1] == 1 && 103a46c0ec8Sopenharmony_ci m->val[1][2] == 0 && 104a46c0ec8Sopenharmony_ci m->val[2][0] == 0 && 105a46c0ec8Sopenharmony_ci m->val[2][1] == 0 && 106a46c0ec8Sopenharmony_ci m->val[2][2] == 1); 107a46c0ec8Sopenharmony_ci} 108a46c0ec8Sopenharmony_ci 109a46c0ec8Sopenharmony_cistatic inline void 110a46c0ec8Sopenharmony_cimatrix_mult(struct matrix *dest, 111a46c0ec8Sopenharmony_ci const struct matrix *m1, 112a46c0ec8Sopenharmony_ci const struct matrix *m2) 113a46c0ec8Sopenharmony_ci{ 114a46c0ec8Sopenharmony_ci struct matrix m; /* allow for dest == m1 or dest == m2 */ 115a46c0ec8Sopenharmony_ci int row, col, i; 116a46c0ec8Sopenharmony_ci 117a46c0ec8Sopenharmony_ci for (row = 0; row < 3; row++) { 118a46c0ec8Sopenharmony_ci for (col = 0; col < 3; col++) { 119a46c0ec8Sopenharmony_ci double v = 0; 120a46c0ec8Sopenharmony_ci for (i = 0; i < 3; i++) { 121a46c0ec8Sopenharmony_ci v += m1->val[row][i] * m2->val[i][col]; 122a46c0ec8Sopenharmony_ci } 123a46c0ec8Sopenharmony_ci m.val[row][col] = v; 124a46c0ec8Sopenharmony_ci } 125a46c0ec8Sopenharmony_ci } 126a46c0ec8Sopenharmony_ci 127a46c0ec8Sopenharmony_ci memcpy(dest, &m, sizeof(m)); 128a46c0ec8Sopenharmony_ci} 129a46c0ec8Sopenharmony_ci 130a46c0ec8Sopenharmony_cistatic inline void 131a46c0ec8Sopenharmony_cimatrix_mult_vec(const struct matrix *m, int *x, int *y) 132a46c0ec8Sopenharmony_ci{ 133a46c0ec8Sopenharmony_ci int tx, ty; 134a46c0ec8Sopenharmony_ci 135a46c0ec8Sopenharmony_ci tx = *x * m->val[0][0] + *y * m->val[0][1] + m->val[0][2]; 136a46c0ec8Sopenharmony_ci ty = *x * m->val[1][0] + *y * m->val[1][1] + m->val[1][2]; 137a46c0ec8Sopenharmony_ci 138a46c0ec8Sopenharmony_ci *x = tx; 139a46c0ec8Sopenharmony_ci *y = ty; 140a46c0ec8Sopenharmony_ci} 141a46c0ec8Sopenharmony_ci 142a46c0ec8Sopenharmony_cistatic inline void 143a46c0ec8Sopenharmony_cimatrix_mult_vec_double(const struct matrix *m, double *x, double *y) 144a46c0ec8Sopenharmony_ci{ 145a46c0ec8Sopenharmony_ci double tx, ty; 146a46c0ec8Sopenharmony_ci 147a46c0ec8Sopenharmony_ci tx = *x * m->val[0][0] + *y * m->val[0][1] + m->val[0][2]; 148a46c0ec8Sopenharmony_ci ty = *x * m->val[1][0] + *y * m->val[1][1] + m->val[1][2]; 149a46c0ec8Sopenharmony_ci 150a46c0ec8Sopenharmony_ci *x = tx; 151a46c0ec8Sopenharmony_ci *y = ty; 152a46c0ec8Sopenharmony_ci} 153a46c0ec8Sopenharmony_ci 154a46c0ec8Sopenharmony_cistatic inline void 155a46c0ec8Sopenharmony_cimatrix_to_farray6(const struct matrix *m, float out[6]) 156a46c0ec8Sopenharmony_ci{ 157a46c0ec8Sopenharmony_ci out[0] = m->val[0][0]; 158a46c0ec8Sopenharmony_ci out[1] = m->val[0][1]; 159a46c0ec8Sopenharmony_ci out[2] = m->val[0][2]; 160a46c0ec8Sopenharmony_ci out[3] = m->val[1][0]; 161a46c0ec8Sopenharmony_ci out[4] = m->val[1][1]; 162a46c0ec8Sopenharmony_ci out[5] = m->val[1][2]; 163a46c0ec8Sopenharmony_ci} 164a46c0ec8Sopenharmony_ci 165a46c0ec8Sopenharmony_cistatic inline void 166a46c0ec8Sopenharmony_cimatrix_to_relative(struct matrix *dest, const struct matrix *src) 167a46c0ec8Sopenharmony_ci{ 168a46c0ec8Sopenharmony_ci matrix_init_identity(dest); 169a46c0ec8Sopenharmony_ci dest->val[0][0] = src->val[0][0]; 170a46c0ec8Sopenharmony_ci dest->val[0][1] = src->val[0][1]; 171a46c0ec8Sopenharmony_ci dest->val[1][0] = src->val[1][0]; 172a46c0ec8Sopenharmony_ci dest->val[1][1] = src->val[1][1]; 173a46c0ec8Sopenharmony_ci} 174