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 // utf8 <=> utf32 converter
33 std::wstring_convert<deletable_facet<std::codecvt<char32_t, char, std::mbstate_t>>, char32_t> ConvertUTF8;
34 
35 namespace {
36 
37 constexpr double Cos[360] =
38 		  {1.000000,0.999848,0.999391,0.998630,0.997564,0.996195,0.994522,
39 		   0.992546,0.990268,0.987688,0.984808,0.981627,0.978148,0.974370,
40 		   0.970296,0.965926,0.961262,0.956305,0.951057,0.945519,0.939693,
41 		   0.933580,0.927184,0.920505,0.913545,0.906308,0.898794,0.891007,
42 		   0.882948,0.874620,0.866025,0.857167,0.848048,0.838671,0.829038,
43 		   0.819152,0.809017,0.798636,0.788011,0.777146,0.766044,0.754710,
44 		   0.743145,0.731354,0.719340,0.707107,0.694658,0.681998,0.669131,
45 		   0.656059,0.642788,0.629320,0.615661,0.601815,0.587785,0.573576,
46 		   0.559193,0.544639,0.529919,0.515038,0.500000,0.484810,0.469472,
47 		   0.453990,0.438371,0.422618,0.406737,0.390731,0.374607,0.358368,
48 		   0.342020,0.325568,0.309017,0.292372,0.275637,0.258819,0.241922,
49 		   0.224951,0.207912,0.190809,0.173648,0.156434,0.139173,0.121869,
50 		   0.104528,0.087156,0.069756,0.052336,0.034899,0.017452,0.000000,
51 		   -0.017452,-0.034899,-0.052336,-0.069756,-0.087156,-0.104528,
52 		   -0.121869,-0.139173,-0.156434,-0.173648,-0.190809,-0.207912,
53 		   -0.224951,-0.241922,-0.258819,-0.275637,-0.292372,-0.309017,
54 		   -0.325568,-0.342020,-0.358368,-0.374607,-0.390731,-0.406737,
55 		   -0.422618,-0.438371,-0.453990,-0.469472,-0.484810,-0.500000,
56 		   -0.515038,-0.529919,-0.544639,-0.559193,-0.573576,-0.587785,
57 		   -0.601815,-0.615661,-0.629320,-0.642788,-0.656059,-0.669131,
58 		   -0.681998,-0.694658,-0.707107,-0.719340,-0.731354,-0.743145,
59 		   -0.754710,-0.766044,-0.777146,-0.788011,-0.798636,-0.809017,
60 		   -0.819152,-0.829038,-0.838671,-0.848048,-0.857167,-0.866025,
61 		   -0.874620,-0.882948,-0.891007,-0.898794,-0.906308,-0.913545,
62 		   -0.920505,-0.927184,-0.933580,-0.939693,-0.945519,-0.951057,
63 		   -0.956305,-0.961262,-0.965926,-0.970296,-0.974370,-0.978148,
64 		   -0.981627,-0.984808,-0.987688,-0.990268,-0.992546,-0.994522,
65 		   -0.996195,-0.997564,-0.998630,-0.999391,-0.999848,-1.000000,
66 		   -0.999848,-0.999391,-0.998630,-0.997564,-0.996195,-0.994522,
67 		   -0.992546,-0.990268,-0.987688,-0.984808,-0.981627,-0.978148,
68 		   -0.974370,-0.970296,-0.965926,-0.961262,-0.956305,-0.951057,
69 		   -0.945519,-0.939693,-0.933580,-0.927184,-0.920505,-0.913545,
70 		   -0.906308,-0.898794,-0.891007,-0.882948,-0.874620,-0.866025,
71 		   -0.857167,-0.848048,-0.838671,-0.829038,-0.819152,-0.809017,
72 		   -0.798636,-0.788011,-0.777146,-0.766044,-0.754710,-0.743145,
73 		   -0.731354,-0.719340,-0.707107,-0.694658,-0.681998,-0.669131,
74 		   -0.656059,-0.642788,-0.629320,-0.615661,-0.601815,-0.587785,
75 		   -0.573576,-0.559193,-0.544639,-0.529919,-0.515038,-0.500000,
76 		   -0.484810,-0.469472,-0.453990,-0.438371,-0.422618,-0.406737,
77 		   -0.390731,-0.374607,-0.358368,-0.342020,-0.325568,-0.309017,
78 		   -0.292372,-0.275637,-0.258819,-0.241922,-0.224951,-0.207912,
79 		   -0.190809,-0.173648,-0.156434,-0.139173,-0.121869,-0.104528,
80 		   -0.087156,-0.069756,-0.052336,-0.034899,-0.017452,-0.000000,
81 		   0.017452,0.034899,0.052336,0.069756,0.087156,0.104528,0.121869,
82 		   0.139173,0.156434,0.173648,0.190809,0.207912,0.224951,0.241922,
83 		   0.258819,0.275637,0.292372,0.309017,0.325568,0.342020,
84 		   0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,0.453990,
85 		   0.469472,0.484810,0.500000,0.515038,0.529919,0.544639,0.559193,
86 		   0.573576,0.587785,0.601815,0.615661,0.629320,0.642788,0.656059,
87 		   0.669131,0.681998,0.694658,0.707107,0.719340,0.731354,0.743145,
88 		   0.754710,0.766044,0.777146,0.788011,0.798636,0.809017,0.819152,
89 		   0.829038,0.838671,0.848048,0.857167,0.866025,0.874620,0.882948,
90 		   0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,0.933580,
91 		   0.939693,0.945519,0.951057,0.956305,0.961262,0.965926,0.970296,
92 		   0.974370,0.978148,0.981627,0.984808,0.987688,0.990268,0.992546,
93 		   0.994522,0.996195,0.997564,0.998630,0.999391,0.999848
94 		  };
95 
96 constexpr double Sin[360] =
97 		  {0.000000,0.017452,0.034899,0.052336,0.069756,0.087156,
98 		   0.104528,0.121869,0.139173,0.156434,0.173648,0.190809,0.207912,
99 		   0.224951,0.241922,0.258819,0.275637,0.292372,0.309017,0.325568,
100 		   0.342020,0.358368,0.374607,0.390731,0.406737,0.422618,0.438371,
101 		   0.453990,0.469472,0.484810,0.500000,0.515038,0.529919,0.544639,
102 		   0.559193,0.573576,0.587785,0.601815,0.615661,0.629320,0.642788,
103 		   0.656059,0.669131,0.681998,0.694658,0.707107,0.719340,0.731354,
104 		   0.743145,0.754710,0.766044,0.777146,0.788011,0.798636,0.809017,
105 		   0.819152,0.829038,0.838671,0.848048,0.857167,0.866025,0.874620,
106 		   0.882948,0.891007,0.898794,0.906308,0.913545,0.920505,0.927184,
107 		   0.933580,0.939693,0.945519,0.951057,0.956305,0.961262,0.965926,
108 		   0.970296,0.974370,0.978148,0.981627,0.984808,0.987688,0.990268,
109 		   0.992546,0.994522,0.996195,0.997564,0.998630,0.999391,0.999848,
110 		   1.000000,0.999848,0.999391,0.998630,0.997564,0.996195,0.994522,
111 		   0.992546,0.990268,0.987688,0.984808,0.981627,0.978148,0.974370,
112 		   0.970296,0.965926,0.961262,0.956305,0.951057,0.945519,0.939693,
113 		   0.933580,0.927184,0.920505,0.913545,0.906308,0.898794,0.891007,
114 		   0.882948,0.874620,0.866025,0.857167,0.848048,0.838671,0.829038,
115 		   0.819152,0.809017,0.798636,0.788011,0.777146,0.766044,0.754710,
116 		   0.743145,0.731354,0.719340,0.707107,0.694658,0.681998,0.669131,
117 		   0.656059,0.642788,0.629320,0.615661,0.601815,0.587785,0.573576,
118 		   0.559193,0.544639,0.529919,0.515038,0.500000,0.484810,0.469472,
119 		   0.453990,0.438371,0.422618,0.406737,0.390731,0.374607,0.358368,
120 		   0.342020,0.325568,0.309017,0.292372,0.275637,0.258819,0.241922,
121 		   0.224951,0.207912,0.190809,0.173648,0.156434,0.139173,0.121869,
122 		   0.104528,0.087156,0.069756,0.052336,0.034899,0.017452,0.000000,
123 		   -0.017452,-0.034899,-0.052336,-0.069756,-0.087156,-0.104528,
124 		   -0.121869,-0.139173,-0.156434,-0.173648,-0.190809,-0.207912,
125 		   -0.224951,-0.241922,-0.258819,-0.275637,-0.292372,-0.309017,
126 		   -0.325568,-0.342020,-0.358368,-0.374607,-0.390731,-0.406737,
127 		   -0.422618,-0.438371,-0.453990,-0.469472,-0.484810,-0.500000,
128 		   -0.515038,-0.529919,-0.544639,-0.559193,-0.573576,-0.587785,
129 		   -0.601815,-0.615661,-0.629320,-0.642788,-0.656059,-0.669131,
130 		   -0.681998,-0.694658,-0.707107,-0.719340,-0.731354,-0.743145,
131 		   -0.754710,-0.766044,-0.777146,-0.788011,-0.798636,-0.809017,
132 		   -0.819152,-0.829038,-0.838671,-0.848048,-0.857167,-0.866025,
133 		   -0.874620,-0.882948,-0.891007,-0.898794,-0.906308,-0.913545,
134 		   -0.920505,-0.927184,-0.933580,-0.939693,-0.945519,-0.951057,
135 		   -0.956305,-0.961262,-0.965926,-0.970296,-0.974370,-0.978148,
136 		   -0.981627,-0.984808,-0.987688,-0.990268,-0.992546,-0.994522,
137 		   -0.996195,-0.997564,-0.998630,-0.999391,-0.999848,-1.000000,
138 		   -0.999848,-0.999391,-0.998630,-0.997564,-0.996195,-0.994522,
139 		   -0.992546,-0.990268,-0.987688,-0.984808,-0.981627,-0.978148,
140 		   -0.974370,-0.970296,-0.965926,-0.961262,-0.956305,-0.951057,
141 		   -0.945519,-0.939693,-0.933580,-0.927184,-0.920505,-0.913545,
142 		   -0.906308,-0.898794,-0.891007,-0.882948,-0.874620,-0.866025,
143 		   -0.857167,-0.848048,-0.838671,-0.829038,-0.819152,-0.809017,
144 		   -0.798636,-0.788011,-0.777146,-0.766044,-0.754710,-0.743145,
145 		   -0.731354,-0.719340,-0.707107,-0.694658,-0.681998,-0.669131,
146 		   -0.656059,-0.642788,-0.629320,-0.615661,-0.601815,-0.587785,
147 		   -0.573576,-0.559193,-0.544639,-0.529919,-0.515038,-0.500000,
148 		   -0.484810,-0.469472,-0.453990,-0.438371,-0.422618,-0.406737,
149 		   -0.390731,-0.374607,-0.358368,-0.342020,-0.325568,-0.309017,
150 		   -0.292372,-0.275637,-0.258819,-0.241922,-0.224951,-0.207912,
151 		   -0.190809,-0.173648,-0.156434,-0.139173,-0.121869,-0.104528,
152 		   -0.087156,-0.069756,-0.052336,-0.034899,-0.017452
153 		  };
154 
155 } // unnamed namespace
156 
157 /*
158  * Fast cosine function.
159  */
vw_dcos(int Angle)160 double vw_dcos(int Angle)
161 {
162 	return Cos[Angle];
163 }
164 
165 /*
166  * Fast sine function.
167  */
vw_dsin(int Angle)168 double vw_dsin(int Angle)
169 {
170 	return Sin[Angle];
171 }
172 
173 /*
174  * Fast root (without sqrtf)
175  */
176 #ifdef WIN32
InvSqrt(const float x)177 static float __fastcall InvSqrt(const float x)
178 #else
179 static float InvSqrt(const float x)
180 #endif
181 {
182 	union {
183 		float f;
184 		int i;
185 	} t;
186 	float y;
187 
188 	t.f = x;
189 	t.i = 0x5f3759df - (t.i >> 1);
190 	y = t.f;
191 	y = y * (1.5F - (0.5F * x * y * y));
192 
193 	return y;
194 }
195 
196 /*
197  * Fast sqrtf function.
198  */
vw_sqrtf(float x)199 float vw_sqrtf(float x)
200 {
201 	return x * InvSqrt(x);
202 }
203 
204 /*
205  * sVECTOR3D Vector
206  */
Length() const207 float sVECTOR3D::Length() const
208 {
209 	return vw_sqrtf(x * x + y * y + z * z);
210 }
211 
Normalize()212 void sVECTOR3D::Normalize()
213 {
214 	float L_squared, one_over_L;
215 	L_squared = (x * x) + (y * y) + (z * z);
216 	one_over_L = InvSqrt(L_squared);
217 	x = x * one_over_L;
218 	y = y * one_over_L;
219 	z = z * one_over_L;
220 }
221 
NormalizeHi()222 void sVECTOR3D::NormalizeHi()
223 {
224 	float Length;
225 	Length = sqrtf((x * x) + (y * y) + (z * z));
226 	if (Length < 0.001f)
227 		return;
228 	x = x / Length;
229 	y = y / Length;
230 	z = z / Length;
231 }
232 
Multiply(const sVECTOR3D & A)233 void sVECTOR3D::Multiply(const sVECTOR3D &A)
234 {
235 	float tV[3]{y * A.z - z * A.y,
236 		    z * A.x - x * A.z,
237 		    x * A.y - y * A.x};
238 	x = tV[0];
239 	y = tV[1];
240 	z = tV[2];
241 }
242 
243 /*
244  * Calculates the plane equation given three points.
245  */
vw_GetPlaneABCD(float & A,float & B,float & C,float & D,const sVECTOR3D & Point1,const sVECTOR3D & Point2,const sVECTOR3D & Point3)246 void vw_GetPlaneABCD(float &A, float &B, float &C, float &D,
247 		     const sVECTOR3D &Point1, const sVECTOR3D &Point2, const sVECTOR3D &Point3)
248 {
249 	A = (Point2.y - Point1.y) * (Point3.z - Point1.z) - (Point2.z - Point1.z) * (Point3.y - Point1.y);
250 	B = (Point2.z - Point1.z) * (Point3.x - Point1.x) - (Point2.x - Point1.x) * (Point3.z - Point1.z);
251 	C = (Point2.x - Point1.x) * (Point3.y - Point1.y) - (Point2.y - Point1.y) * (Point3.x - Point1.x);
252 	D = - Point1.x * (Point2.y - Point1.y) * (Point3.z - Point1.z)
253 	    - Point1.y * (Point2.z - Point1.z) * (Point3.x - Point1.x)
254 	    - Point1.z * (Point2.x - Point1.x) * (Point3.y - Point1.y)
255 	    + Point1.z * (Point2.y - Point1.y) * (Point3.x - Point1.x)
256 	    + Point1.y * (Point2.x - Point1.x) * (Point3.z - Point1.z)
257 	    + Point1.x * (Point2.z - Point1.z) * (Point3.y - Point1.y);
258 }
259 
260 /*
261  * Calculate point rotation.
262  */
vw_RotatePoint(sVECTOR3D & Point,const sVECTOR3D & Angle)263 void vw_RotatePoint(sVECTOR3D &Point, const sVECTOR3D &Angle)
264 {
265 	constexpr float DegToRadFactor = 0.0174532925f; // conversion factor to convert degrees to radians
266 	float tmpX = Point.x;
267 	float tmpY = Point.y;
268 	float tmpZ = Point.z;
269 
270 	// X
271 	if (Angle.x != 0) {
272 		float a = -Angle.x * DegToRadFactor;
273 		float c = cosf(a);
274 		float s = sinf(a);
275 		Point.y = tmpY * c + tmpZ * s;
276 		Point.z = -tmpY * s + tmpZ * c;
277 		tmpX = Point.x;
278 		tmpY = Point.y;
279 		tmpZ = Point.z;
280 	}
281 	// Y
282 	if (Angle.y != 0) {
283 		float a = Angle.y * DegToRadFactor;
284 		float c = cosf(a);
285 		float s = sinf(a);
286 		Point.x = tmpX*c + tmpZ * s;
287 		Point.z = -tmpX*s + tmpZ * c;
288 		tmpX = Point.x;
289 		tmpY = Point.y;
290 	}
291 	// Z
292 	if (Angle.z != 0) {
293 		float a = -Angle.z * DegToRadFactor;
294 		float c = cosf(a);
295 		float s = sinf(a);
296 		Point.x = tmpX * c + tmpY * s;
297 		Point.y = -tmpX * s + tmpY * c;
298 	}
299 }
300 
301 /*
302  * Calculate point inverse rotation.
303  */
vw_RotatePointInv(sVECTOR3D & Point,const sVECTOR3D & Angle)304 void vw_RotatePointInv(sVECTOR3D &Point, const sVECTOR3D &Angle)
305 {
306 	constexpr float DegToRadFactor = 0.0174532925f; // conversion factor to convert degrees to radians
307 	float tmpX = Point.x;
308 	float tmpY = Point.y;
309 	float tmpZ = Point.z;
310 
311 	// Z
312 	if (Angle.z != 0) {
313 		float a = -Angle.z * DegToRadFactor;
314 		float c = cosf(a);
315 		float s = sinf(a);
316 		Point.x = tmpX * c + tmpY * s;
317 		Point.y = -tmpX * s + tmpY * c;
318 		tmpX = Point.x;
319 		tmpY = Point.y;
320 		tmpZ = Point.z;
321 	}
322 	// Y
323 	if (Angle.y != 0) {
324 		float a = Angle.y * DegToRadFactor;
325 		float c = cosf(a);
326 		float s = sinf(a);
327 		Point.x = tmpX * c + tmpZ * s;
328 		Point.z = -tmpX * s + tmpZ * c;
329 		tmpY = Point.y;
330 		tmpZ = Point.z;
331 	}
332 	// X
333 	if (Angle.x != 0) {
334 		float a = -Angle.x * DegToRadFactor;
335 		float c = cosf(a);
336 		float s = sinf(a);
337 		Point.y = tmpY * c + tmpZ * s;
338 		Point.z = -tmpY * s + tmpZ * c;
339 	}
340 }
341 
342 } // viewizard namespace
343