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