1 /*
2  * Copyright © 2018 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "igt_core.h"
25 #include "igt_matrix.h"
26 
27 /**
28  * SECTION:igt_matrix
29  * @short_description: Matrix math library
30  * @title: Matrix
31  * @include: igt.h
32  *
33  * This library contains helper functions for basic matrix math.
34  * The library operates on #igt_mat4 and #igt_vec4 structures.
35  */
36 
37 /**
38  * igt_matrix_print:
39  * @m: the matrix
40  *
41  * Print out the matrix elements.
42  */
igt_matrix_print(const struct igt_mat4 * m)43 void igt_matrix_print(const struct igt_mat4 *m)
44 {
45 	for (int row = 0; row < 4; row++) {
46 		igt_info("|");
47 		for (int col = 0; col < 4; col++) {
48 			igt_info("%4.4f,", m->d[m(row, col)]);
49 		}
50 		igt_info("|\n");
51 	}
52 }
53 
54 /**
55  * igt_matrix_identity:
56  *
57  * Returns:
58  * An identity matrix.
59  */
igt_matrix_identity(void)60 struct igt_mat4 igt_matrix_identity(void)
61 {
62 	static const struct igt_mat4 ret = {
63 		.d[m(0, 0)] = 1.0f,
64 		.d[m(1, 1)] = 1.0f,
65 		.d[m(2, 2)] = 1.0f,
66 		.d[m(3, 3)] = 1.0f,
67 	};
68 
69 	return ret;
70 }
71 
72 /**
73  * igt_matrix_scale:
74  * @x: x scaling amount
75  * @y: y scaling amount
76  * @z: z scaling amount
77  *
78  * Returns:
79  * An scaling matrix.
80  */
igt_matrix_scale(float x,float y,float z)81 struct igt_mat4 igt_matrix_scale(float x, float y, float z)
82 {
83 	struct igt_mat4 ret = {
84 		.d[m(0, 0)] = x,
85 		.d[m(1, 1)] = y,
86 		.d[m(2, 2)] = z,
87 		.d[m(3, 3)] = 1.0f,
88 	};
89 
90 	return ret;
91 }
92 
93 /**
94  * igt_matrix_translate:
95  * @x: x translation amount
96  * @y: y translation amount
97  * @z: z translation amount
98  *
99  * Returns:
100  * A translation matrix.
101  */
igt_matrix_translate(float x,float y,float z)102 struct igt_mat4 igt_matrix_translate(float x, float y, float z)
103 {
104 	struct igt_mat4 ret = {
105 		.d[m(0, 0)] = 1.0f,
106 		.d[m(1, 1)] = 1.0f,
107 		.d[m(2, 2)] = 1.0f,
108 		.d[m(0, 3)] = x,
109 		.d[m(1, 3)] = y,
110 		.d[m(2, 3)] = z,
111 		.d[m(3, 3)] = 1.0f,
112 	};
113 
114 	return ret;
115 }
116 
117 /**
118  * igt_matrix_multiply:
119  * @a: Left matrix
120  * @b: Right matrix
121  *
122  * Multiply two matrices together. @a is on the left,
123  * @b on the right.
124  *
125  * Returns:
126  * The resulting matrix.
127  */
igt_matrix_multiply(const struct igt_mat4 * a,const struct igt_mat4 * b)128 struct igt_mat4 igt_matrix_multiply(const struct igt_mat4 *a,
129 				    const struct igt_mat4 *b)
130 {
131 	struct igt_mat4 ret = {};
132 
133 	for (int col = 0; col < 4; col++) {
134 		for (int row = 0; row < 4; row++) {
135 			for (int i = 0; i < 4; i++)
136 				ret.d[m(row, col)] += a->d[m(row, i)] * b->d[m(i, col)];
137 		}
138 	}
139 
140 	return ret;
141 }
142