1 /************************************************************************************
2
3 AstroMenace
4 Hardcore 3D space scroll-shooter with spaceship upgrade possibilities.
5 Copyright (c) 2006-2019 Mikhail Kurinnoi, Viewizard
6
7
8 AstroMenace is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 AstroMenace is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with AstroMenace. If not, see <https://www.gnu.org/licenses/>.
20
21
22 Website: https://viewizard.com/
23 Project: https://github.com/viewizard/astromenace
24 E-mail: viewizard@viewizard.com
25
26 *************************************************************************************/
27
28 #include "math.h"
29
30 namespace viewizard {
31
32 /*
33 * Setup matrix identity.
34 */
vw_Matrix33Identity(float (& Matrix33)[9])35 void vw_Matrix33Identity(float (&Matrix33)[9])
36 {
37 Matrix33[0] = 1.0f;
38 Matrix33[1] = 0.0f;
39 Matrix33[2] = 0.0f;
40
41 Matrix33[3] = 0.0f;
42 Matrix33[4] = 1.0f;
43 Matrix33[5] = 0.0f;
44
45 Matrix33[6] = 0.0f;
46 Matrix33[7] = 0.0f;
47 Matrix33[8] = 1.0f;
48 }
49
50 /*
51 * Matrix multiplication.
52 */
vw_Matrix33Mult(float (& DstMatrix33)[9],const float (& SrcMatrix33)[9])53 void vw_Matrix33Mult(float (&DstMatrix33)[9], const float (&SrcMatrix33)[9])
54 {
55 float tmp[9]{DstMatrix33[0], DstMatrix33[1], DstMatrix33[2],
56 DstMatrix33[3], DstMatrix33[4], DstMatrix33[5],
57 DstMatrix33[6], DstMatrix33[7], DstMatrix33[8]};
58
59 DstMatrix33[0] = SrcMatrix33[0] * tmp[0] + SrcMatrix33[1] * tmp[3] + SrcMatrix33[2] * tmp[6];
60 DstMatrix33[1] = SrcMatrix33[0] * tmp[1] + SrcMatrix33[1] * tmp[4] + SrcMatrix33[2] * tmp[7];
61 DstMatrix33[2] = SrcMatrix33[0] * tmp[2] + SrcMatrix33[1] * tmp[5] + SrcMatrix33[2] * tmp[8];
62
63 DstMatrix33[3] = SrcMatrix33[3] * tmp[0] + SrcMatrix33[4] * tmp[3] + SrcMatrix33[5] * tmp[6];
64 DstMatrix33[4] = SrcMatrix33[3] * tmp[1] + SrcMatrix33[4] * tmp[4] + SrcMatrix33[5] * tmp[7];
65 DstMatrix33[5] = SrcMatrix33[3] * tmp[2] + SrcMatrix33[4] * tmp[5] + SrcMatrix33[5] * tmp[8];
66
67 DstMatrix33[6] = SrcMatrix33[6] * tmp[0] + SrcMatrix33[7] * tmp[3] + SrcMatrix33[8] * tmp[6];
68 DstMatrix33[7] = SrcMatrix33[6] * tmp[1] + SrcMatrix33[7] * tmp[4] + SrcMatrix33[8] * tmp[7];
69 DstMatrix33[8] = SrcMatrix33[6] * tmp[2] + SrcMatrix33[7] * tmp[5] + SrcMatrix33[8] * tmp[8];
70 }
71
72 /*
73 * Create rotation matrix.
74 */
vw_Matrix33CreateRotate(float (& Matrix33)[9],const sVECTOR3D & Angle)75 void vw_Matrix33CreateRotate(float (&Matrix33)[9], const sVECTOR3D &Angle)
76 {
77 constexpr float DegToRadFactor = 0.0174532925f; // conversion factor to convert degrees to radians
78
79 if ((Angle.z != 0.0f) && (Angle.x == 0.0f) && (Angle.y == 0.0f)) {
80 float a = -Angle.z * DegToRadFactor;
81 float c = cosf(a);
82 float s = sinf(a);
83 Matrix33[0] = c;
84 Matrix33[1] = -s;
85 Matrix33[3] = s;
86 Matrix33[4] = c;
87 Matrix33[2] = Matrix33[5] = Matrix33[6] = Matrix33[7] = 0.0f;
88 Matrix33[8] = 1.0f;
89 } else if ((Angle.y != 0.0f) && (Angle.x == 0.0f) && (Angle.z == 0.0f)) {
90 float a = -Angle.y * DegToRadFactor;
91 float c = cosf(a);
92 float s = sinf(a);
93 Matrix33[0] = c;
94 Matrix33[2] = s;
95 Matrix33[6] = -s;
96 Matrix33[8] = c;
97 Matrix33[1] = Matrix33[3] = Matrix33[5] = Matrix33[7] = 0.0f;
98 Matrix33[4] = 1.0f;
99 } else if ((Angle.x != 0.0f) && (Angle.y == 0.0f) && (Angle.z == 0.0f)) {
100 float a = -Angle.x * DegToRadFactor;
101 float c = cosf(a);
102 float s = sinf(a);
103 Matrix33[4] = c;
104 Matrix33[5] = -s;
105 Matrix33[7] = s;
106 Matrix33[8] = c;
107 Matrix33[1] = Matrix33[2] = Matrix33[3] = Matrix33[6] = 0.0f;
108 Matrix33[0] = 1.0f;
109 } else {
110 // if we need 2 or more angles
111 float a = -Angle.x * DegToRadFactor;
112 float A = cosf(a);
113 float B = sinf(a);
114 a = -Angle.y * DegToRadFactor;
115 float C = cosf(a);
116 float D = sinf(a);
117 a = -Angle.z * DegToRadFactor;
118 float E = cosf(a);
119 float F = sinf(a);
120 float AD = A * D;
121 float BD = B * D;
122 Matrix33[0] = C * E;
123 Matrix33[1] = -C * F;
124 Matrix33[2] = D;
125 Matrix33[3] = BD * E + A * F;
126 Matrix33[4] = -BD * F + A * E;
127 Matrix33[5] = -B * C;
128 Matrix33[6] = -AD * E + B * F;
129 Matrix33[7] = AD * F + B * E;
130 Matrix33[8] = A * C;
131 }
132 }
133
134 /*
135 * Create inverted rotation matrix.
136 */
vw_Matrix33InverseRotate(float (& Matrix33)[9])137 void vw_Matrix33InverseRotate(float (&Matrix33)[9])
138 {
139 float tmp[9]{Matrix33[0], Matrix33[1], Matrix33[2],
140 Matrix33[3], Matrix33[4], Matrix33[5],
141 Matrix33[6], Matrix33[7], Matrix33[8]};
142
143 Matrix33[0] = tmp[0];
144 Matrix33[1] = tmp[3];
145 Matrix33[2] = tmp[6];
146
147 Matrix33[3] = tmp[1];
148 Matrix33[4] = tmp[4];
149 Matrix33[5] = tmp[7];
150
151 Matrix33[6] = tmp[2];
152 Matrix33[7] = tmp[5];
153 Matrix33[8] = tmp[8];
154 }
155
156 /*
157 * Calculate point position by transformation matrix.
158 */
vw_Matrix33CalcPoint(sVECTOR3D & Point,const float (& Matrix33)[9])159 void vw_Matrix33CalcPoint(sVECTOR3D &Point, const float (&Matrix33)[9])
160 {
161 Point(Matrix33[0] * Point.x + Matrix33[3] * Point.y + Matrix33[6] * Point.z,
162 Matrix33[1] * Point.x + Matrix33[4] * Point.y + Matrix33[7] * Point.z,
163 Matrix33[2] * Point.x + Matrix33[5] * Point.y + Matrix33[8] * Point.z);
164 }
165
166 } // viewizard namespace
167