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