OpenMoHAA 0.82.0
Loading...
Searching...
No Matches
SkelMat4.h
1/*
2===========================================================================
3Copyright (C) 2023 the OpenMoHAA team
4
5This file is part of OpenMoHAA source code.
6
7OpenMoHAA source code is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 2 of the License,
10or (at your option) any later version.
11
12OpenMoHAA source code is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with OpenMoHAA source code; if not, write to the Free Software
19Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20===========================================================================
21*/
22
23// SkelMat4.h : Skeletor
24
25#pragma once
26
27#ifdef __cplusplus
28
29class SkelQuat;
30
31class SkelMat4
32{
33public:
34 float val[4][3];
35
36protected:
37 void copy(const SkelMat4&);
38
39public:
40 void MakeIdentity();
41 void MakeTranslate(float, float, float);
42 void MakeXRotation(float);
43 void MakeYRotation(float);
44 void MakeZRotation(float);
45
46 SkelMat4(const float mat[3][3]);
47 SkelMat4();
48
49 SkelVec3 *XAxis();
50 SkelVec3 *YAxis();
51 SkelVec3 *ZAxis();
52 SkelVec3 *XAxis() const;
53 SkelVec3 *YAxis() const;
54 SkelVec3 *ZAxis() const;
55
56 operator float *();
57 operator float *() const;
58
59 bool IsOrthonormal() const;
60 bool IsValid() const;
61
62 float *operator[](int index);
63 float *operator[](int index) const;
64
65 int CompareExact(const SkelMat4& skel) const;
66
67 void Sum(const SkelMat4 &m1, const SkelMat4 &m2);
68 void Difference(const SkelMat4 &m1, const SkelMat4 &m2);
69 void Multiply(const SkelMat4 &m1, const SkelMat4 &m2);
70 void InvertAxis(int);
71 void RotateBy(const SkelMat3 &m);
72 void RotateByInverse(const SkelMat3 &m);
73 void RotateXAxis(float x);
74 void RotateYAxis(float y);
75 void RotateZAxis(float z);
76 void RotateXAxis(float, float);
77 void RotateYAxis(float, float);
78 void RotateZAxis(float, float);
79 void MoveOnXAxis(float x);
80 void MoveOnYAxis(float y);
81 void MoveOnZAxis(float z);
82 void TransformVector(float *) const;
83 void TransposeRot();
84 void TransposeOf(const SkelMat4 &m);
85 void TransposeRotOf(const SkelMat4 &m);
86 void InverseRotOf(const SkelMat4 &m);
87 float Determinant(void);
88 void Inverse(void);
89 void GetRotationMatrix(float (*)[3]) const;
90 void GetRotationMatrix(float (*)[4]) const;
91 void ReplacePos(const float *);
92 void ReplaceRot(const SkelMat3 &m);
93 void ReplaceRot(const SkelMat4 &m);
94 void GetPos(float *pos) const;
95 void GetScale(float *scale) const;
96 void DeltaPos(const SkelMat4 &m, float *delta) const;
97 void RotateYaw(float, float);
98
99 void GetQuat(SkelQuat& quat);
100};
101
102inline SkelMat4::SkelMat4(const float mat[3][3])
103{
104 VectorCopy(mat[0], val[0]);
105 VectorCopy(mat[1], val[1]);
106 VectorCopy(mat[2], val[2]);
107 val[3][0] = 0.0f;
108 val[3][1] = 0.0f;
109 val[3][2] = 0.0f;
110}
111
112inline SkelMat4::SkelMat4()
113{
114 MakeIdentity();
115}
116
117inline void SkelMat4::copy(const SkelMat4& m)
118{
119 MatrixCopy(*m.val, *val);
120}
121
122inline void SkelMat4::MakeIdentity()
123{
124 memset(val, 0, sizeof(val));
125 val[0][0] = 1.0f;
126 val[1][1] = 1.0f;
127 val[2][2] = 1.0f;
128}
129
130inline SkelVec3 *SkelMat4::XAxis()
131{
132 return (SkelVec3 *)&val[0];
133}
134
135inline SkelVec3 *SkelMat4::YAxis()
136{
137 return (SkelVec3 *)&val[1];
138}
139
140inline SkelVec3 *SkelMat4::ZAxis()
141{
142 return (SkelVec3 *)&val[2];
143}
144
145inline SkelVec3 *SkelMat4::XAxis() const
146{
147 return (SkelVec3 *)&val[0];
148}
149
150inline SkelVec3 *SkelMat4::YAxis() const
151{
152 return (SkelVec3 *)&val[1];
153}
154
155inline SkelVec3 *SkelMat4::ZAxis() const
156{
157 return (SkelVec3 *)&val[2];
158}
159
160inline SkelMat4::operator float *()
161{
162 return &val[0][0];
163}
164
165inline SkelMat4::operator float *() const
166{
167 return (float *)&val[0][0];
168}
169
170inline float *SkelMat4::operator[](int index)
171{
172 return val[index];
173}
174
175inline float *SkelMat4::operator[](int index) const
176{
177 return (float *)val[index];
178}
179
180inline bool SkelMat4::IsOrthonormal() const
181{
182 // FIXME: stub
183 return false;
184}
185
186inline bool SkelMat4::IsValid() const
187{
188 // FIXME: stub
189 return false;
190}
191
192inline void SkelMat4::Sum(const SkelMat4& m1, const SkelMat4& m2)
193{
194 VectorAdd(m1.val[0], m2.val[0], val[0]);
195 VectorAdd(m1.val[1], m2.val[1], val[1]);
196 VectorAdd(m1.val[2], m2.val[2], val[2]);
197}
198
199inline void SkelMat4::Difference(const SkelMat4& m1, const SkelMat4& m2)
200{
201 VectorSubtract(m1.val[0], m2.val[0], val[0]);
202 VectorSubtract(m1.val[1], m2.val[1], val[1]);
203 VectorSubtract(m1.val[2], m2.val[2], val[2]);
204}
205
206inline void SkelMat4::Multiply(const SkelMat4& m1, const SkelMat4& m2)
207{
208 val[0][0] = m1[0][0] * m2[0][0] + m1[0][1] * m2[1][0] + m1[0][2] * m2[2][0];
209 val[1][0] = m1[1][0] * m2[0][0] + m1[1][1] * m2[1][0] + m1[1][2] * m2[2][0];
210 val[2][0] = m1[2][0] * m2[0][0] + m1[2][1] * m2[1][0] + m1[2][2] * m2[2][0];
211 val[3][0] = m1[3][0] * m2[0][0] + m1[3][1] * m2[1][0] + m1[3][2] * m2[2][0] + m2[3][0];
212
213 val[0][1] = m1[0][0] * m2[0][1] + m1[0][1] * m2[1][1] + m1[0][2] * m2[2][1];
214 val[1][1] = m1[1][0] * m2[0][1] + m1[1][1] * m2[1][1] + m1[1][2] * m2[2][1];
215 val[2][1] = m1[2][0] * m2[0][1] + m1[2][1] * m2[1][1] + m1[2][2] * m2[2][1];
216 val[3][1] = m1[3][0] * m2[0][1] + m1[3][1] * m2[1][1] + m1[3][2] * m2[2][1] + m2[3][1];
217
218 val[0][2] = m1[0][0] * m2[0][2] + m1[0][1] * m2[1][2] + m1[0][2] * m2[2][2];
219 val[1][2] = m1[1][0] * m2[0][2] + m1[1][1] * m2[1][2] + m1[1][2] * m2[2][2];
220 val[2][2] = m1[2][0] * m2[0][2] + m1[2][1] * m2[1][2] + m1[2][2] * m2[2][2];
221 val[3][2] = m1[3][0] * m2[0][2] + m1[3][1] * m2[1][2] + m1[3][2] * m2[2][2] + m2[3][2];
222}
223
224inline void SkelMat4::InvertAxis(int a)
225{
226 val[a][0] = -val[a][0];
227 val[a][1] = -val[a][1];
228 val[a][2] = -val[a][2];
229}
230
231inline float SkelMat4::Determinant(void)
232{
233 float mat4x4[4][4];
234
235 mat4x4[0][0] = val[0][0];
236 mat4x4[0][1] = val[0][1];
237 mat4x4[0][2] = val[0][2];
238 mat4x4[0][3] = 0;
239 mat4x4[1][0] = val[1][0];
240 mat4x4[1][1] = val[1][1];
241 mat4x4[1][2] = val[1][2];
242 mat4x4[1][3] = 0;
243 mat4x4[2][0] = val[2][0];
244 mat4x4[2][1] = val[2][1];
245 mat4x4[2][2] = val[2][2];
246 mat4x4[2][3] = 0;
247 mat4x4[3][0] = val[3][0];
248 mat4x4[3][1] = val[3][1];
249 mat4x4[3][2] = val[3][2];
250 mat4x4[3][3] = 1;
251
252 return mat4x4[0][0]
253 * (mat4x4[1][1] * (mat4x4[2][2] * mat4x4[3][3] - mat4x4[2][3] * mat4x4[3][2])
254 - mat4x4[2][1] * (mat4x4[1][2] * mat4x4[3][3] - mat4x4[1][3] * mat4x4[3][2])
255 + mat4x4[3][1] * (mat4x4[1][2] * mat4x4[2][3] - mat4x4[1][3] * mat4x4[2][2]))
256 - mat4x4[1][0]
257 * (mat4x4[0][1] * (mat4x4[2][2] * mat4x4[3][3] - mat4x4[2][3] * mat4x4[3][2])
258 - mat4x4[2][1] * (mat4x4[0][2] * mat4x4[3][3] - mat4x4[0][3] * mat4x4[3][2])
259 + mat4x4[3][1] * (mat4x4[0][2] * mat4x4[2][3] - mat4x4[0][3] * mat4x4[2][2]))
260 + mat4x4[2][0]
261 * (mat4x4[0][1] * (mat4x4[1][2] * mat4x4[3][3] - mat4x4[1][3] * mat4x4[3][2])
262 - mat4x4[1][1] * (mat4x4[0][2] * mat4x4[3][3] - mat4x4[0][3] * mat4x4[3][2])
263 + mat4x4[3][1] * (mat4x4[0][2] * mat4x4[1][3] - mat4x4[0][3] * mat4x4[1][2]))
264 - mat4x4[3][0]
265 * (mat4x4[0][1] * (mat4x4[1][2] * mat4x4[2][3] - mat4x4[1][3] * mat4x4[2][2])
266 - mat4x4[1][1] * (mat4x4[0][2] * mat4x4[2][3] - mat4x4[0][3] * mat4x4[2][2])
267 + mat4x4[2][1] * (mat4x4[0][2] * mat4x4[1][3] - mat4x4[0][3] * mat4x4[1][2]));
268}
269
270inline void SkelMat4::Inverse(void)
271{
272 float mat4x4[4][4];
273 float outmat4x4[4][4];
274 const float Det = Determinant();
275
276 mat4x4[0][0] = val[0][0];
277 mat4x4[0][1] = val[0][1];
278 mat4x4[0][2] = val[0][2];
279 mat4x4[0][3] = 0;
280 mat4x4[1][0] = val[1][0];
281 mat4x4[1][1] = val[1][1];
282 mat4x4[1][2] = val[1][2];
283 mat4x4[1][3] = 0;
284 mat4x4[2][0] = val[2][0];
285 mat4x4[2][1] = val[2][1];
286 mat4x4[2][2] = val[2][2];
287 mat4x4[2][3] = 0;
288 mat4x4[3][0] = val[3][0];
289 mat4x4[3][1] = val[3][1];
290 mat4x4[3][2] = val[3][2];
291 mat4x4[3][3] = 1;
292
293 if (Det == 0.0f) {
294 MakeIdentity();
295 } else {
296 VectorMatrixInverse(outmat4x4, mat4x4);
297
298 val[0][0] = outmat4x4[0][0];
299 val[0][1] = outmat4x4[0][1];
300 val[0][2] = outmat4x4[0][2];
301 val[1][0] = outmat4x4[1][0];
302 val[1][1] = outmat4x4[1][1];
303 val[1][2] = outmat4x4[1][2];
304 val[2][0] = outmat4x4[2][0];
305 val[2][1] = outmat4x4[2][1];
306 val[2][2] = outmat4x4[2][2];
307 val[3][0] = outmat4x4[3][0];
308 val[3][1] = outmat4x4[3][1];
309 val[3][2] = outmat4x4[3][2];
310 }
311}
312
313inline void SkelMat4::RotateBy(const SkelMat3& m)
314{
315 SkelMat4 temp = *this;
316
317 val[0][0] = temp[0][0] * m[0][0] + temp[0][1] * m[1][0] + temp[0][2] * m[2][0];
318 val[0][1] = temp[0][0] * m[0][1] + temp[0][1] * m[1][1] + temp[0][2] * m[2][1];
319 val[0][2] = temp[0][0] * m[0][2] + temp[0][1] * m[1][2] + temp[0][2] * m[2][2];
320
321 val[1][0] = temp[1][0] * m[0][0] + temp[1][1] * m[1][0] + temp[1][2] * m[2][0];
322 val[1][1] = temp[1][0] * m[0][1] + temp[1][1] * m[1][1] + temp[1][2] * m[2][1];
323 val[1][2] = temp[1][0] * m[0][2] + temp[1][1] * m[1][2] + temp[1][2] * m[2][2];
324
325 val[2][0] = temp[2][0] * m[0][0] + temp[2][1] * m[1][0] + temp[2][2] * m[2][0];
326 val[2][1] = temp[2][0] * m[0][1] + temp[2][1] * m[1][1] + temp[2][2] * m[2][1];
327 val[2][2] = temp[2][0] * m[0][2] + temp[2][1] * m[1][2] + temp[2][2] * m[2][2];
328}
329
330inline void SkelMat4::RotateByInverse(const SkelMat3& m)
331{
332 // FIXME: stub
333}
334
335inline void SkelMat4::TransposeRotOf(const SkelMat4& m)
336{
337 val[0][0] = m.val[0][0];
338 val[0][1] = m.val[1][0];
339 val[0][2] = m.val[2][0];
340 val[1][0] = m.val[0][1];
341 val[1][1] = m.val[1][1];
342 val[1][2] = m.val[2][1];
343 val[2][0] = m.val[0][2];
344 val[2][1] = m.val[1][2];
345 val[2][2] = m.val[2][2];
346}
347
348inline void SkelMat4::GetQuat(SkelQuat& quat)
349{
350 MatToQuat(val, (float *)&quat);
351}
352
353#else
354
355typedef struct {
356 float val[4][3];
357} SkelMat4;
358
359#endif
Definition SkelMat3.h:192
Definition SkelMat4.h:355
Definition SkelQuat.h:274
Definition SkelVec3.h:197