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