# source:trunk/src/matrix.h@768Tweet

Last change on this file since 768 was 768, checked in by sam, 9 years ago

core: add the unary minus operator to vectors.

• Property svn:keywords set to `Id`
File size: 7.1 KB
Line
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11//
12// The Matrix classes
13// ------------------
14//
15
16#if !defined __LOL_MATRIX_H__
17#define __LOL_MATRIX_H__
18
19#include <cmath>
20
21namespace lol
22{
23
24#define VECTOR_OP(elems, op) \
25    template<typename U> \
26    inline Vec##elems<T> operator op(Vec##elems<U> const &val) const \
27    { \
28        Vec##elems<T> ret; \
29        for (int n = 0; n < elems; n++) \
30            ret[n] = (*this)[n] op val[n]; \
31        return ret; \
32    } \
33    \
34    template<typename U> \
35    inline Vec##elems<T> operator op##=(Vec##elems<U> const &val) \
36    { \
37        return *this = (*this) op val; \
38    }
39
40#define BOOL_OP(elems, op, op2, ret) \
41    inline bool operator op(Vec##elems<T> const &val) const \
42    { \
43        for (int n = 0; n < elems; n++) \
44            if (!((*this)[n] op2 val[n])) \
45                return !ret; \
46        return ret; \
47    }
48
49#define SCALAR_OP(elems, op) \
50    inline Vec##elems<T> operator op(T const &val) const \
51    { \
52        Vec##elems<T> ret; \
53        for (int n = 0; n < elems; n++) \
54            ret[n] = (*this)[n] op val; \
55        return ret; \
56    } \
57    \
58    inline Vec##elems<T> operator op##=(T const &val) \
59    { \
60        return *this = (*this) op val; \
61    }
62
63#define CAST_OP(elems, dest) \
64    inline operator Vec##dest<T>() const \
65    { \
66        Vec##dest<T> ret; \
67        for (int n = 0; n < elems && n < dest; n++) \
68            ret[n] = (*this)[n]; \
69        return ret; \
70    }
71
72#define OPERATORS(elems) \
73    inline T& operator[](int n) { return *(&x + n); } \
74    inline T const& operator[](int n) const { return *(&x + n); } \
75    \
76    VECTOR_OP(elems, -) \
77    VECTOR_OP(elems, +) \
78    VECTOR_OP(elems, *) \
79    VECTOR_OP(elems, /) \
80    \
81    BOOL_OP(elems, ==, ==, true) \
82    BOOL_OP(elems, !=, ==, false) \
83    BOOL_OP(elems, <=, <=, true) \
84    BOOL_OP(elems, >=, >=, true) \
85    BOOL_OP(elems, <, <, true) \
86    BOOL_OP(elems, >, >, true) \
87    \
88    SCALAR_OP(elems, -) \
89    SCALAR_OP(elems, +) \
90    SCALAR_OP(elems, *) \
91    SCALAR_OP(elems, /) \
92    \
93    CAST_OP(elems, 2) \
94    CAST_OP(elems, 3) \
95    CAST_OP(elems, 4) \
96    \
97    template<typename U> \
98    inline operator Vec##elems<U>() const \
99    { \
100        Vec##elems<U> ret; \
101        for (int n = 0; n < elems; n++) \
102            ret[n] = static_cast<U>((*this)[n]); \
103        return ret; \
104    } \
105    \
106    inline Vec##elems<T> operator -() const \
107    { \
108        Vec##elems<T> ret; \
109        for (int n = 0; n < elems; n++) \
110            ret[n] = -(*this)[n]; \
111        return ret; \
112    } \
113    \
114    inline T sqlen() const \
115    { \
116        T acc = 0; \
117        for (int n = 0; n < elems; n++) \
118            acc += (*this)[n] * (*this)[n]; \
119        return acc; \
120    } \
121    \
122    inline float len() const \
123    { \
124        using namespace std; \
125        return sqrtf((float)sqlen()); \
126    }
127
128template <typename T> struct Vec2;
129template <typename T> struct Vec3;
130template <typename T> struct Vec4;
131
132template <typename T> struct Vec2
133{
134    inline Vec2() { }
135    inline Vec2(T val) { x = y = val; }
136    inline Vec2(T _x, T _y) { x = _x; y = _y; }
137
138    OPERATORS(2)
139
140    union { T x; T a; T i; };
141    union { T y; T b; T j; };
142};
143
144typedef Vec2<float> vec2;
145typedef Vec2<int> vec2i;
146
147template <typename T> struct Vec3
148{
149    inline Vec3() { }
150    inline Vec3(T val) { x = y = z = val; }
151    inline Vec3(T _x, T _y, T _z) { x = _x; y = _y; z = _z; }
152
153    OPERATORS(3)
154
155    union { T x; T a; T i; };
156    union { T y; T b; T j; };
157    union { T z; T c; T k; };
158};
159
160typedef Vec3<float> vec3;
161typedef Vec3<int> vec3i;
162
163template <typename T> struct Vec4
164{
165    inline Vec4() { }
166    inline Vec4(T val) { x = y = z = w = val; }
167    inline Vec4(T _x, T _y, T _z, T _w) { x = _x; y = _y; z = _z; w = _w; }
168
169    OPERATORS(4)
170
171    union { T x; T a; T i; };
172    union { T y; T b; T j; };
173    union { T z; T c; T k; };
174    union { T w; T d; T l; };
175};
176
177typedef Vec4<float> vec4;
178typedef Vec4<int> vec4i;
179
180#define SCALAR_GLOBAL(elems, op, U) \
181    template<typename T> \
182    static inline Vec##elems<U> operator op(U const &val, \
183                                            Vec##elems<T> const &that) \
184    { \
185        Vec##elems<U> ret; \
186        for (int n = 0; n < elems; n++) \
187            ret[n] = val op that[n]; \
188        return ret; \
189    }
190
191#define SCALAR_GLOBAL2(elems, op) \
192    SCALAR_GLOBAL(elems, op, int) \
193    SCALAR_GLOBAL(elems, op, float)
194
195#define GLOBALS(elems) \
196    SCALAR_GLOBAL2(elems, -) \
197    SCALAR_GLOBAL2(elems, +) \
198    SCALAR_GLOBAL2(elems, *) \
199    SCALAR_GLOBAL2(elems, /)
200
201GLOBALS(2)
202GLOBALS(3)
203GLOBALS(4)
204
205template <typename T> struct Mat4
206{
207    inline Mat4() { }
208    inline Mat4(T val)
209    {
210        for (int j = 0; j < 4; j++)
211            for (int i = 0; i < 4; i++)
212                v[i][j] = (i == j) ? val : 0;
213    }
214    inline Mat4(Vec4<T> v0, Vec4<T> v1, Vec4<T> v2, Vec4<T> v3)
215    {
216        v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3;
217    }
218
219    inline Vec4<T>& operator[](int n) { return v[n]; }
220    inline Vec4<T> const& operator[](int n) const { return v[n]; }
221
222    T det() const;
223    Mat4<T> invert() const;
224
225    static Mat4<T> ortho(T left, T right, T bottom, T top, T near, T far);
226    static Mat4<T> frustum(T left, T right, T bottom, T top, T near, T far);
227    static Mat4<T> perspective(T theta, T width, T height, T near, T far);
228    static Mat4<T> translate(T x, T y, T z);
229    static Mat4<T> rotate(T theta, T x, T y, T z);
230
231    void printf() const;
232
233    inline Mat4<T> operator +(Mat4<T> const val) const
234    {
235        Mat4<T> ret;
236        for (int j = 0; j < 4; j++)
237            for (int i = 0; i < 4; i++)
238                ret[i][j] = v[i][j] + val[i][j];
239        return ret;
240    }
241
242    inline Mat4<T> operator +=(Mat4<T> const val)
243    {
244        return *this = *this + val;
245    }
246
247    inline Mat4<T> operator -(Mat4<T> const val) const
248    {
249        Mat4<T> ret;
250        for (int j = 0; j < 4; j++)
251            for (int i = 0; i < 4; i++)
252                ret[i][j] = v[i][j] - val[i][j];
253        return ret;
254    }
255
256    inline Mat4<T> operator -=(Mat4<T> const val)
257    {
258        return *this = *this - val;
259    }
260
261    inline Mat4<T> operator *(Mat4<T> const val) const
262    {
263        Mat4<T> ret;
264        for (int j = 0; j < 4; j++)
265            for (int i = 0; i < 4; i++)
266            {
267                T tmp = 0;
268                for (int k = 0; k < 4; k++)
269                    tmp += v[k][j] * val[i][k];
270                ret[i][j] = tmp;
271            }
272        return ret;
273    }
274
275    inline Mat4<T> operator *=(Mat4<T> const val)
276    {
277        return *this = *this * val;
278    }
279
280    inline Vec4<T> operator *(Vec4<T> const val) const
281    {
282        Vec4<T> ret;
283        for (int j = 0; j < 4; j++)
284        {
285            T tmp = 0;
286            for (int i = 0; i < 4; i++)
287                tmp += v[i][j] * val[i];
288            ret[j] = tmp;
289        }
290        return ret;
291    }
292
293    Vec4<T> v[4];
294};
295
296typedef Mat4<float> mat4;
297typedef Mat4<int> mat4i;
298
299} /* namespace lol */
300
301#endif // __LOL_MATRIX_H__
302
Note: See TracBrowser for help on using the repository browser.