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