ScummVM API documentation
matrix_inv.h
1/* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22/*
23* Files matrix_inv.h are a part of the MESA 3D Library (MIT License)
24*
25* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
26*
27* Permission is hereby granted, free of charge, to any person obtaining a
28* copy of this software and associated documentation files (the "Software"),
29* to deal in the Software without restriction, including without limitation
30* the rights to use, copy, modify, merge, publish, distribute, sublicense,
31* and/or sell copies of the Software, and to permit persons to whom the
32* Software is furnished to do so, subject to the following conditions:
33*
34* The above copyright notice and this permission notice shall be included
35* in all copies or substantial portions of the Software.
36*
37* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
38* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
40* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
43* SOFTWARE.
44*
45*/
46
47#ifndef TITANIC_MATRIX_INV_H
48#define TITANIC_MATRIX_INV_H
49
50namespace Titanic {
51
52// 4x4 Matrix m is column major, e.x., m[3] is the row 4 column 1 element
53// Modified version of MESA 3D library function (MIT license)
54template <typename T>
55bool matrix4Inverse(const T m[16], T invOut[16])
56{
57 T temp_inv[16];
58 T determinant;
59 T determinant_inv;
60 int i;
61
62 temp_inv[0] = m[5] * m[10] * m[15] -
63 m[5] * m[11] * m[14] -
64 m[9] * m[6] * m[15] +
65 m[9] * m[7] * m[14] +
66 m[13] * m[6] * m[11] -
67 m[13] * m[7] * m[10];
68
69 temp_inv[4] = -m[4] * m[10] * m[15] +
70 m[4] * m[11] * m[14] +
71 m[8] * m[6] * m[15] -
72 m[8] * m[7] * m[14] -
73 m[12] * m[6] * m[11] +
74 m[12] * m[7] * m[10];
75
76 temp_inv[8] = m[4] * m[9] * m[15] -
77 m[4] * m[11] * m[13] -
78 m[8] * m[5] * m[15] +
79 m[8] * m[7] * m[13] +
80 m[12] * m[5] * m[11] -
81 m[12] * m[7] * m[9];
82
83 temp_inv[12] = -m[4] * m[9] * m[14] +
84 m[4] * m[10] * m[13] +
85 m[8] * m[5] * m[14] -
86 m[8] * m[6] * m[13] -
87 m[12] * m[5] * m[10] +
88 m[12] * m[6] * m[9];
89
90 temp_inv[1] = -m[1] * m[10] * m[15] +
91 m[1] * m[11] * m[14] +
92 m[9] * m[2] * m[15] -
93 m[9] * m[3] * m[14] -
94 m[13] * m[2] * m[11] +
95 m[13] * m[3] * m[10];
96
97 temp_inv[5] = m[0] * m[10] * m[15] -
98 m[0] * m[11] * m[14] -
99 m[8] * m[2] * m[15] +
100 m[8] * m[3] * m[14] +
101 m[12] * m[2] * m[11] -
102 m[12] * m[3] * m[10];
103
104 temp_inv[9] = -m[0] * m[9] * m[15] +
105 m[0] * m[11] * m[13] +
106 m[8] * m[1] * m[15] -
107 m[8] * m[3] * m[13] -
108 m[12] * m[1] * m[11] +
109 m[12] * m[3] * m[9];
110
111 temp_inv[13] = m[0] * m[9] * m[14] -
112 m[0] * m[10] * m[13] -
113 m[8] * m[1] * m[14] +
114 m[8] * m[2] * m[13] +
115 m[12] * m[1] * m[10] -
116 m[12] * m[2] * m[9];
117
118 temp_inv[2] = m[1] * m[6] * m[15] -
119 m[1] * m[7] * m[14] -
120 m[5] * m[2] * m[15] +
121 m[5] * m[3] * m[14] +
122 m[13] * m[2] * m[7] -
123 m[13] * m[3] * m[6];
124
125 temp_inv[6] = -m[0] * m[6] * m[15] +
126 m[0] * m[7] * m[14] +
127 m[4] * m[2] * m[15] -
128 m[4] * m[3] * m[14] -
129 m[12] * m[2] * m[7] +
130 m[12] * m[3] * m[6];
131
132 temp_inv[10] = m[0] * m[5] * m[15] -
133 m[0] * m[7] * m[13] -
134 m[4] * m[1] * m[15] +
135 m[4] * m[3] * m[13] +
136 m[12] * m[1] * m[7] -
137 m[12] * m[3] * m[5];
138
139 temp_inv[14] = -m[0] * m[5] * m[14] +
140 m[0] * m[6] * m[13] +
141 m[4] * m[1] * m[14] -
142 m[4] * m[2] * m[13] -
143 m[12] * m[1] * m[6] +
144 m[12] * m[2] * m[5];
145
146 temp_inv[3] = -m[1] * m[6] * m[11] +
147 m[1] * m[7] * m[10] +
148 m[5] * m[2] * m[11] -
149 m[5] * m[3] * m[10] -
150 m[9] * m[2] * m[7] +
151 m[9] * m[3] * m[6];
152
153 temp_inv[7] = m[0] * m[6] * m[11] -
154 m[0] * m[7] * m[10] -
155 m[4] * m[2] * m[11] +
156 m[4] * m[3] * m[10] +
157 m[8] * m[2] * m[7] -
158 m[8] * m[3] * m[6];
159
160 temp_inv[11] = -m[0] * m[5] * m[11] +
161 m[0] * m[7] * m[9] +
162 m[4] * m[1] * m[11] -
163 m[4] * m[3] * m[9] -
164 m[8] * m[1] * m[7] +
165 m[8] * m[3] * m[5];
166
167 temp_inv[15] = m[0] * m[5] * m[10] -
168 m[0] * m[6] * m[9] -
169 m[4] * m[1] * m[10] +
170 m[4] * m[2] * m[9] +
171 m[8] * m[1] * m[6] -
172 m[8] * m[2] * m[5];
173
174 determinant = m[0] * temp_inv[0] + m[1] * temp_inv[4] + m[2] * temp_inv[8] + m[3] * temp_inv[12];
175
176 if (determinant == 0)
177 return false;
178
179 determinant_inv = 1.0 / determinant;
180
181 for (i = 0; i < 16; i++)
182 invOut[i] = temp_inv[i] * determinant_inv;
183
184 return true;
185}
186
187} // End of namespace Titanic
188
189#endif /* TITANIC_MATRIX_INV_H */