summaryrefslogtreecommitdiff
path: root/src/common/math_util.h
diff options
context:
space:
mode:
authorGravatar bunnei2014-04-08 19:25:03 -0400
committerGravatar bunnei2014-04-08 19:25:03 -0400
commit63e46abdb8764bc97e91bae862c8d461e61b1965 (patch)
treee73f4aa25d7b4015a265e7bbfb6004dab7561027 /src/common/math_util.h
parentfixed some license headers that I missed (diff)
downloadyuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.tar.gz
yuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.tar.xz
yuzu-63e46abdb8764bc97e91bae862c8d461e61b1965.zip
got rid of 'src' folders in each sub-project
Diffstat (limited to 'src/common/math_util.h')
-rw-r--r--src/common/math_util.h200
1 files changed, 200 insertions, 0 deletions
diff --git a/src/common/math_util.h b/src/common/math_util.h
new file mode 100644
index 000000000..4410c5e01
--- /dev/null
+++ b/src/common/math_util.h
@@ -0,0 +1,200 @@
1// Copyright 2013 Dolphin Emulator Project
2// Licensed under GPLv2
3// Refer to the license.txt file included.
4
5
6#ifndef _MATH_UTIL_H_
7#define _MATH_UTIL_H_
8
9#include "common.h"
10
11#include <vector>
12
13namespace MathUtil
14{
15
16static const u64 DOUBLE_SIGN = 0x8000000000000000ULL,
17 DOUBLE_EXP = 0x7FF0000000000000ULL,
18 DOUBLE_FRAC = 0x000FFFFFFFFFFFFFULL,
19 DOUBLE_ZERO = 0x0000000000000000ULL;
20
21static const u32 FLOAT_SIGN = 0x80000000,
22 FLOAT_EXP = 0x7F800000,
23 FLOAT_FRAC = 0x007FFFFF,
24 FLOAT_ZERO = 0x00000000;
25
26union IntDouble {
27 double d;
28 u64 i;
29};
30union IntFloat {
31 float f;
32 u32 i;
33};
34
35inline bool IsNAN(double d)
36{
37 IntDouble x; x.d = d;
38 return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
39 ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) );
40}
41
42inline bool IsQNAN(double d)
43{
44 IntDouble x; x.d = d;
45 return ( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
46 ((x.i & 0x0007fffffffffffULL) == 0x000000000000000ULL) &&
47 ((x.i & 0x000800000000000ULL) == 0x000800000000000ULL) );
48}
49
50inline bool IsSNAN(double d)
51{
52 IntDouble x; x.d = d;
53 return( ((x.i & DOUBLE_EXP) == DOUBLE_EXP) &&
54 ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) &&
55 ((x.i & 0x0008000000000000ULL) == DOUBLE_ZERO) );
56}
57
58inline float FlushToZero(float f)
59{
60 IntFloat x; x.f = f;
61 if ((x.i & FLOAT_EXP) == 0)
62 x.i &= FLOAT_SIGN; // turn into signed zero
63 return x.f;
64}
65
66inline double FlushToZeroAsFloat(double d)
67{
68 IntDouble x; x.d = d;
69 if ((x.i & DOUBLE_EXP) < 0x3800000000000000ULL)
70 x.i &= DOUBLE_SIGN; // turn into signed zero
71 return x.d;
72}
73
74enum PPCFpClass
75{
76 PPC_FPCLASS_QNAN = 0x11,
77 PPC_FPCLASS_NINF = 0x9,
78 PPC_FPCLASS_NN = 0x8,
79 PPC_FPCLASS_ND = 0x18,
80 PPC_FPCLASS_NZ = 0x12,
81 PPC_FPCLASS_PZ = 0x2,
82 PPC_FPCLASS_PD = 0x14,
83 PPC_FPCLASS_PN = 0x4,
84 PPC_FPCLASS_PINF = 0x5,
85};
86
87// Uses PowerPC conventions for the return value, so it can be easily
88// used directly in CPU emulation.
89u32 ClassifyDouble(double dvalue);
90// More efficient float version.
91u32 ClassifyFloat(float fvalue);
92
93template<class T>
94struct Rectangle
95{
96 T left;
97 T top;
98 T right;
99 T bottom;
100
101 Rectangle()
102 { }
103
104 Rectangle(T theLeft, T theTop, T theRight, T theBottom)
105 : left(theLeft), top(theTop), right(theRight), bottom(theBottom)
106 { }
107
108 bool operator==(const Rectangle& r) { return left==r.left && top==r.top && right==r.right && bottom==r.bottom; }
109
110 T GetWidth() const { return abs(right - left); }
111 T GetHeight() const { return abs(bottom - top); }
112
113 // If the rectangle is in a coordinate system with a lower-left origin, use
114 // this Clamp.
115 void ClampLL(T x1, T y1, T x2, T y2)
116 {
117 if (left < x1) left = x1;
118 if (right > x2) right = x2;
119 if (top > y1) top = y1;
120 if (bottom < y2) bottom = y2;
121 }
122
123 // If the rectangle is in a coordinate system with an upper-left origin,
124 // use this Clamp.
125 void ClampUL(T x1, T y1, T x2, T y2)
126 {
127 if (left < x1) left = x1;
128 if (right > x2) right = x2;
129 if (top < y1) top = y1;
130 if (bottom > y2) bottom = y2;
131 }
132};
133
134} // namespace MathUtil
135
136inline float pow2f(float x) {return x * x;}
137inline double pow2(double x) {return x * x;}
138
139float MathFloatVectorSum(const std::vector<float>&);
140
141#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
142#define ROUND_DOWN(x, a) ((x) & ~((a) - 1))
143
144// Rounds down. 0 -> undefined
145inline u64 Log2(u64 val)
146{
147#if defined(__GNUC__)
148 return 63 - __builtin_clzll(val);
149
150#elif defined(_MSC_VER) && defined(_M_X64)
151 unsigned long result = -1;
152 _BitScanReverse64(&result, val);
153 return result;
154
155#else
156 u64 result = -1;
157 while (val != 0)
158 {
159 val >>= 1;
160 ++result;
161 }
162 return result;
163#endif
164}
165
166// Tiny matrix/vector library.
167// Used for things like Free-Look in the gfx backend.
168
169class Matrix33
170{
171public:
172 static void LoadIdentity(Matrix33 &mtx);
173
174 // set mtx to be a rotation matrix around the x axis
175 static void RotateX(Matrix33 &mtx, float rad);
176 // set mtx to be a rotation matrix around the y axis
177 static void RotateY(Matrix33 &mtx, float rad);
178
179 // set result = a x b
180 static void Multiply(const Matrix33 &a, const Matrix33 &b, Matrix33 &result);
181 static void Multiply(const Matrix33 &a, const float vec[3], float result[3]);
182
183 float data[9];
184};
185
186class Matrix44
187{
188public:
189 static void LoadIdentity(Matrix44 &mtx);
190 static void LoadMatrix33(Matrix44 &mtx, const Matrix33 &m33);
191 static void Set(Matrix44 &mtx, const float mtxArray[16]);
192
193 static void Translate(Matrix44 &mtx, const float vec[3]);
194
195 static void Multiply(const Matrix44 &a, const Matrix44 &b, Matrix44 &result);
196
197 float data[16];
198};
199
200#endif // _MATH_UTIL_H_