1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3 #ifndef MYMATH_H
4 #define MYMATH_H
5
6 #include "Sim/Misc/GlobalConstants.h"
7 #include "System/type2.h"
8 #include "System/float3.h"
9
10 #include <algorithm> // std::{min,max}
11
12 #ifdef __GNUC__
13 #define _const __attribute__((const))
14 #define _pure __attribute__((pure))
15 #define _warn_unused_result __attribute__((warn_unused_result))
16 #else
17 #define _const
18 #define _pure
19 #define _warn_unused_result
20 #endif
21
22 #ifndef M_PI
23 #define M_PI 3.14159265358979323846
24 #endif
25
26
27 static const float INVPI = 1.0f / PI;
28 static const float TWOPI = 2.0f * PI;
29 static const float HALFPI = 0.5f * PI;
30 static const int SHORTINT_MAXVALUE = 32768;
31 static const int SPRING_CIRCLE_DIVS = (SHORTINT_MAXVALUE << 1);
32
33 #define HEADING_CHECKSUM_1024 0x617a9968
34 #define HEADING_CHECKSUM_4096 0x3d51b476
35 #define NUM_HEADINGS 4096
36
37 #if (NUM_HEADINGS == 1024)
38 #define HEADING_CHECKSUM HEADING_CHECKSUM_1024
39 #elif (NUM_HEADINGS == 4096)
40 #define HEADING_CHECKSUM HEADING_CHECKSUM_4096
41 #else
42 #error "HEADING_CHECKSUM not set, invalid NUM_HEADINGS?"
43 #endif
44
45 enum FacingMap {
46 FACING_NORTH = 2,
47 FACING_SOUTH = 0,
48 FACING_EAST = 1,
49 FACING_WEST = 3,
50 NUM_FACINGS = 4,
51 };
52
53 class CMyMath {
54 public:
55 static void Init();
56 static float2 headingToVectorTable[NUM_HEADINGS];
57 };
58
59
60 struct shortint2 {
61 short int x, y;
62 };
63
64
65 short int GetHeadingFromFacing(const int facing) _pure _warn_unused_result;
66 int GetFacingFromHeading(const short int heading) _pure _warn_unused_result;
67 float GetHeadingFromVectorF(const float dx, const float dz) _pure _warn_unused_result;
68 short int GetHeadingFromVector(const float dx, const float dz) _pure _warn_unused_result;
69 shortint2 GetHAndPFromVector(const float3 vec) _pure _warn_unused_result; // vec should be normalized
70 float2 GetHAndPFromVectorF(const float3 vec) _pure _warn_unused_result; // vec should be normalized
71 float3 GetVectorFromHeading(const short int heading) _pure _warn_unused_result;
72 float3 GetVectorFromHAndPExact(const short int heading, const short int pitch) _pure _warn_unused_result;
73
74 float3 CalcBeizer(const float i, const float3 p1, const float3 p2, const float3 p3, const float3 p4) _pure _warn_unused_result;
75
76 float LinePointDist(const float3 l1, const float3 l2, const float3 p) _pure _warn_unused_result;
77 float3 ClosestPointOnLine(const float3 l1, const float3 l2, const float3 p) _pure _warn_unused_result;
78
79 /**
80 * @brief Returns the intersection points of a ray with the map boundary (2d only)
81 * @param start float3 the start point of the line
82 * @param dir float3 direction of the ray
83 * @return <near,far> std::pair<float,float> distance to the intersection points in mulitples of `dir`
84 */
85 std::pair<float,float> GetMapBoundaryIntersectionPoints(const float3 start, const float3 dir) _pure _warn_unused_result;
86
87 /**
88 * @brief clamps a line (start & end points) to the map boundaries
89 * @param start float3 the start point of the line
90 * @param end float3 the end point of the line
91 * @return true if either `end` or `start` was changed
92 */
93 bool ClampLineInMap(float3& start, float3& end);
94
95 /**
96 * @brief clamps a ray (just the end point) to the map boundaries
97 * @param start const float3 the start point of the line
98 * @param end float3 the `end` point of the line
99 * @return true if changed
100 */
101 bool ClampRayInMap(const float3 start, float3& end);
102
103
104 float smoothstep(const float edge0, const float edge1, const float value) _pure _warn_unused_result;
105 float3 smoothstep(const float edge0, const float edge1, float3 vec) _pure _warn_unused_result;
106
107 float linearstep(const float edge0, const float edge1, const float value) _pure _warn_unused_result;
108
109
110 // inlined to avoid multiple definitions due to the specializing templates
argmin(const T v1,const T v2)111 template<class T> inline T argmin(const T v1, const T v2) { return std::min(v1, v2); }
argmax(const T v1,const T v2)112 template<class T> inline T argmax(const T v1, const T v2) { return std::max(v1, v2); }
argmin(const float3 v1,const float3 v2)113 template<> inline float3 argmin(const float3 v1, const float3 v2) { return float3::min(v1, v2); }
argmax(const float3 v1,const float3 v2)114 template<> inline float3 argmax(const float3 v1, const float3 v2) { return float3::max(v1, v2); }
115
116 // template<class T> T mix(const T v1, const T v2, const float a) { return (v1 * (1.0f - a) + v2 * a); }
mix(const T v1,const T v2,const float a)117 template<class T> T mix(const T v1, const T v2, const float a) { return (v1 + (v2 - v1) * a); }
Blend(const T v1,const T v2,const float a)118 template<class T> T Blend(const T v1, const T v2, const float a) { return mix(v1, v2, a); }
119
120 int Round(const float f) _const _warn_unused_result;
121
Square(const T x)122 template<class T> T Square(const T x) { return x*x; }
Clamp(const T v,const T vmin,const T vmax)123 template<class T> T Clamp(const T v, const T vmin, const T vmax) { return std::min(vmax, std::max(vmin, v)); }
124 // NOTE: '>' instead of '>=' s.t. Sign(int(true)) != Sign(int(false)) --> zero is negative!
Sign(const T v)125 template<class T> T Sign(const T v) { return ((v > T(0)) * T(2) - T(1)); }
126
127 /**
128 * @brief Clamps an radian angle between 0 .. 2*pi
129 * @param f float* value to clamp
130 */
131 float ClampRad(float f) _const _warn_unused_result;
132
133
134 /**
135 * @brief Clamps an radian angle between 0 .. 2*pi
136 * @param f float* value to clamp
137 */
138 void ClampRad(float* f);
139
140
141 /**
142 * @brief Checks if 2 radian values discribe the same angle
143 * @param f1 float* first compare value
144 * @param f2 float* second compare value
145 */
146 bool RadsAreEqual(const float f1, const float f2) _const;
147
148
149 /**
150 */
151 float GetRadFromXY(const float dx, const float dy) _const;
152
153
154 /**
155 * convert a color in HS(V) space to RGB
156 */
157 float3 hs2rgb(float h, float s) _pure _warn_unused_result;
158
159
160 #include "myMath.inl"
161
162 #undef _const
163
164 #endif // MYMATH_H
165