Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/cpp11_v2/src/libraries/util/Math.h @ 10976

Last change on this file since 10976 was 10976, checked in by muemart, 8 years ago

Add some static asserts

  • Property svn:eol-style set to native
File size: 12.0 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program 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 this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Wolfgang Roenninger
26 *
27 */
28
29/**
30    @defgroup Math Mathematical functions
31    @ingroup Util
32*/
33
34/**
35    @file
36    @ingroup Math
37    @brief Declaration and implementation of several math-functions, typedefs of some Ogre::Math classes to the orxonox namespace.
38*/
39
40#ifndef _Util_Math_H__
41#define _Util_Math_H__
42
43#include "UtilPrereqs.h"
44
45#include <string>
46#include <cmath>
47#include <cstdlib>
48#include <random>
49
50#include <OgreMath.h>
51#include <OgreVector2.h>
52#include <OgreVector3.h>
53#include <OgreVector4.h>
54#include <OgreQuaternion.h>
55#include <OgreColourValue.h>
56
57// Certain headers might define unwanted macros...
58#undef max
59#undef min
60#undef sgn
61#undef clamp
62#undef sqrt
63#undef square
64#undef mod
65#undef rnd
66
67namespace orxonox
68{
69    /** Often used numerical constants because C++ doesn't define any.
70    @note
71        The values here are decimal representations of the approximate floating
72        point value as it is stored according to the IEEE 754 standard.
73    */
74    namespace math
75    {
76        constexpr float twoPi   = 6.283185482025146484375f;     ///< PI * 2
77        constexpr float pi      = 3.1415927410125732421875f;    ///< PI
78        constexpr float pi_2    = 1.57079637050628662109375f;   ///< PI / 2
79        constexpr float pi_4    = 0.785398185253143310546875f;  ///< PI / 4
80        constexpr float e       = 2.718281269073486328125f;     ///< e
81        constexpr float sqrt2   = 1.41421353816986083984375f;   ///< sqrt(2)
82        constexpr float sqrt2_2 = 0.707106769084930419921875f;  ///< sqrt(2) / 2
83    }
84
85#if OGRE_VERSION < 0x010603
86    _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian);
87    _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree);
88#endif
89    _UtilExport std::istream& operator>>(std::istream& in, orxonox::Radian& radian);
90    _UtilExport std::istream& operator>>(std::istream& in, orxonox::Degree& degree);
91
92    _UtilExport float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition);
93    _UtilExport orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
94    _UtilExport orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
95    _UtilExport orxonox::Vector2 get3DProjection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition, const float mapangle, const float detectionlimit);
96    _UtilExport bool isObjectHigherThanShipOnMap(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition, const float mapangle);
97    _UtilExport int determineMap3DZOrder(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition, const float detectionlimit);
98    _UtilExport orxonox::Vector3 getTransformedVector(const orxonox::Vector3& distance, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& myside);
99    _UtilExport orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity);
100
101    /**
102        @brief Returns the sign of the given value.
103        @param x The value
104        @return 1 if the value is positive or zero, -1 if the value is negative
105    */
106    template <typename T>
107    constexpr inline T sgn(T x)
108    {
109        return (x >= 0) ? (T)1 : (T)-1;
110    }
111
112    /**
113        @brief Keeps a value between a lower and an upper limit. Values beyond these limits are limited to either @a min or @a max.
114        @param x The value
115        @param min The lower limit
116        @param max The upper limit
117    */
118    template <typename T>
119    constexpr inline T clamp(T x, T min, T max)
120    {
121        return x < min ? min : (x > max ? max : x);
122    }
123
124    /**
125        @brief Returns the squared value (x^2).
126    */
127    template <typename T>
128    constexpr inline T square(T x)
129    {
130        return x*x;
131    }
132
133    /**
134        @brief Returns the cubed value (x^3).
135    */
136    template <typename T>
137    constexpr inline T cube(T x)
138    {
139        return x*x*x;
140    }
141
142    /**
143        @brief The modulo operation, enhanced to work properly with negative values.
144        @param x The value
145        @param max The operand
146
147        The built in modulo operator % yields a strange behavior with negative values.
148        This function corrects this - the result is guaranteed to lie always between
149        zero and (max-1).
150
151        Example:
152        @code
153        int var = 11 % 10;      //  1
154        int var = -1 % 10;      // -1
155
156        int var = mod(11, 10);  //  1
157        int var = mod(-1, 10);  //  9
158        @endcode
159    */
160    template <typename T>
161    inline int mod(T x, int max)
162    {
163        if (x >= 0)
164            return (x % max);
165        else
166        {
167            T temp = x % max;
168            return (temp < 0) ? (temp + max) : temp;
169        }
170    }
171
172    /**
173        @brief Returns a "zero" value for the given type.
174        @note This is the default template of the zeroise() function. The template is spezialized for each supported type.
175
176        The exact return value of the function depends on the type. For @c int this is 0,
177        for @c float it's 0.0f. For a @c std::string the function returns "" and for
178        @c Vector3 you get <tt>Vector3(0, 0, 0)</tt>.
179    */
180    template <typename T>
181    inline T zeroise()
182    {
183        static_assert(sizeof(T) != sizeof(T), "No template specialization available for T");
184        return temp;
185    }
186
187    template <> inline char                 zeroise<char>()                 { return 0; }
188    template <> inline unsigned char        zeroise<unsigned char>()        { return 0; }
189    template <> inline short                zeroise<short>()                { return 0; }
190    template <> inline unsigned short       zeroise<unsigned short>()       { return 0; }
191    template <> inline int                  zeroise<int>()                  { return 0; }
192    template <> inline unsigned int         zeroise<unsigned int>()         { return 0; }
193    template <> inline long                 zeroise<long>()                 { return 0; }
194    template <> inline unsigned long        zeroise<unsigned long>()        { return 0; }
195    template <> inline long long            zeroise<long long>()            { return 0; }
196    template <> inline unsigned long long   zeroise<unsigned long long>()   { return 0; }
197    template <> inline float                zeroise<float>()                { return 0; }
198    template <> inline double               zeroise<double>()               { return 0; }
199    template <> inline long double          zeroise<long double>()          { return 0; }
200    template <> inline bool                 zeroise<bool>()                 { return 0; }
201    template <> inline void*                zeroise<void*>()                { return nullptr; }
202    template <> inline std::string          zeroise<std::string>()          { return std::string(); }
203    template <> inline orxonox::Radian      zeroise<orxonox::Radian>()      { return orxonox::Radian(0.0f); }
204    template <> inline orxonox::Degree      zeroise<orxonox::Degree>()      { return orxonox::Degree(0.0f); }
205    template <> inline orxonox::Vector2     zeroise<orxonox::Vector2>()     { return orxonox::Vector2    (0, 0)      ; }
206    template <> inline orxonox::Vector3     zeroise<orxonox::Vector3>()     { return orxonox::Vector3    (0, 0, 0)   ; }
207    template <> inline orxonox::Vector4     zeroise<orxonox::Vector4>()     { return orxonox::Vector4    (0, 0, 0, 0); }
208    template <> inline orxonox::ColourValue zeroise<orxonox::ColourValue>() { return orxonox::ColourValue(0, 0, 0, 0); }
209    template <> inline orxonox::Quaternion  zeroise<orxonox::Quaternion>()  { return orxonox::Quaternion (0, 0, 0, 0); }
210
211    /**
212        @brief Provides zero value symbols that can be returned as reference
213        @see zeroise()
214    */
215    template <typename T>
216    struct NilValue
217    {
218        inline operator const T&() const
219        {
220            return value;
221        }
222        static T value;
223    };
224    template <typename T>
225    T NilValue<T>::value = zeroise<T>();
226
227    /**
228        @brief Interpolates between two values for a time between 0 and 1.
229        @param time The time is a value between 0 and 1 - the function returns @a start if @a time is 0, @a end if @a time is 1, and interpolates if @a time is between 0 and 1.
230        @param start The value at @a time = 0
231        @param end The value at @a time = 1
232        @return The interpolated value at a given time
233    */
234    template <typename T>
235    inline T interpolate(float time, const T& start, const T& end)
236    {
237        return static_cast<T>(time * (end - start) + start);
238    }
239
240    /**
241        @brief Interpolates smoothly between two values for a time between 0 and 1. The function starts slowly, increases faster and stops slowly again.
242        @param time The time is a value between 0 and 1 - the function returns @a start if @a time is 0, @a end if @a time is 1, and interpolates if @a time is between 0 and 1.
243        @param start The value at @a time = 0
244        @param end The value at @a time = 1
245        @return The interpolated value at a given time
246    */
247    template <typename T>
248    inline T interpolateSmooth(float time, const T& start, const T& end)
249    {
250        return static_cast<T>((-2 * (end - start) * cube(time)) + (3 * (end - start) * square(time)) + start);
251    }
252
253    namespace detail
254    {
255        /**
256        Random number generator used for the functions below. Marked extern to only have one global instance.
257        */
258        _UtilExport extern std::mt19937 rngen;
259    }
260
261    /**
262    @brief Seeds the random number generator used for the functions below.
263    */
264    inline void rndseed(unsigned int seed)
265    {
266        detail::rngen.seed(seed);
267    }
268
269    /**
270    @brief Returns a random number between @a min and almost @a max: <tt>min <= rnd < max</tt>.
271    @param min The minimum
272    @param max The maximum
273    */
274    inline float rnd(float min, float max)
275    {
276        std::uniform_real_distribution<float> dist(min, max);
277        return dist(detail::rngen);
278    }
279
280    /**
281        @brief Returns a random number between 0 and almost 1: <tt>0 <= rnd < 1</tt>.
282    */
283    inline float rnd()
284    {
285        return rnd(0, 1);
286    }
287
288    /**
289        @brief Returns a random number between 0 and almost @a max: <tt>0 <= rnd < max</tt>.
290        @param max The maximum
291    */
292    inline float rnd(float max)
293    {
294        return rnd(0, max);
295    }
296
297    /**
298        @brief Returns randomly 1 or -1 with equal probability.
299    */
300    inline float rndsgn()
301    {
302        std::uniform_int_distribution<> dist;
303        return static_cast<float>((dist(detail::rngen) & 0x2) - 1); // dist(...) & 0x2 is either 2 or 0
304    }
305
306    _UtilExport unsigned long getUniqueNumber();
307}
308
309#endif /* _Util_Math_H__ */
Note: See TracBrowser for help on using the repository browser.