source: trunk/src/matrix.h @ 686

Last change on this file since 686 was 686, checked in by sam, 10 years ago

Put everything in the "lol" namespace. Better late than never.

  • Property svn:keywords set to Id
File size: 6.7 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
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11//
12// The Matrix classes
13// ------------------
14//
15
16#if !defined __DH_MATRIX_H__
17#define __DH_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, 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] != 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, ==, false) \
82    BOOL_OP(elems, !=, true) \
83    \
84    SCALAR_OP(elems, -) \
85    SCALAR_OP(elems, +) \
86    SCALAR_OP(elems, *) \
87    SCALAR_OP(elems, /) \
88    \
89    CAST_OP(elems, 2) \
90    CAST_OP(elems, 3) \
91    CAST_OP(elems, 4) \
92    \
93    template<typename U> \
94    inline operator Vec##elems<U>() const \
95    { \
96        Vec##elems<U> ret; \
97        for (int n = 0; n < elems; n++) \
98            ret[n] = static_cast<U>((*this)[n]); \
99        return ret; \
100    } \
101    \
102    inline T sqlen() const \
103    { \
104        T acc = 0; \
105        for (int n = 0; n < elems; n++) \
106            acc += (*this)[n] * (*this)[n]; \
107        return acc; \
108    } \
109    \
110    inline float len() const \
111    { \
112        return sqrtf((float)sqlen()); \
113    }
114
115template <typename T> struct Vec2;
116template <typename T> struct Vec3;
117template <typename T> struct Vec4;
118
119template <typename T> struct Vec2
120{
121    inline Vec2() { }
122    inline Vec2(T val) { x = y = val; }
123    inline Vec2(T _x, T _y) { x = _x; y = _y; }
124
125    OPERATORS(2)
126
127    union { T x; T a; T i; };
128    union { T y; T b; T j; };
129};
130
131typedef Vec2<float> vec2;
132typedef Vec2<int> vec2i;
133
134template <typename T> struct Vec3
135{
136    inline Vec3() { }
137    inline Vec3(T val) { x = y = z = val; }
138    inline Vec3(T _x, T _y, T _z) { x = _x; y = _y; z = _z; }
139
140    OPERATORS(3)
141
142    union { T x; T a; T i; };
143    union { T y; T b; T j; };
144    union { T z; T c; T k; };
145};
146
147typedef Vec3<float> vec3;
148typedef Vec3<int> vec3i;
149
150template <typename T> struct Vec4
151{
152    inline Vec4() { }
153    inline Vec4(T val) { x = y = z = w = val; }
154    inline Vec4(T _x, T _y, T _z, T _w) { x = _x; y = _y; z = _z; w = _w; }
155
156    OPERATORS(4)
157
158    union { T x; T a; T i; };
159    union { T y; T b; T j; };
160    union { T z; T c; T k; };
161    union { T w; T d; T l; };
162};
163
164typedef Vec4<float> vec4;
165typedef Vec4<int> vec4i;
166
167#define SCALAR_GLOBAL(elems, op, U) \
168    template<typename T> \
169    static inline Vec##elems<U> operator op(U const &val, \
170                                            Vec##elems<T> const &that) \
171    { \
172        Vec##elems<U> ret; \
173        for (int n = 0; n < elems; n++) \
174            ret[n] = val op that[n]; \
175        return ret; \
176    }
177
178#define SCALAR_GLOBAL2(elems, op) \
179    SCALAR_GLOBAL(elems, op, int) \
180    SCALAR_GLOBAL(elems, op, float)
181
182#define GLOBALS(elems) \
183    SCALAR_GLOBAL2(elems, -) \
184    SCALAR_GLOBAL2(elems, +) \
185    SCALAR_GLOBAL2(elems, *) \
186    SCALAR_GLOBAL2(elems, /)
187
188GLOBALS(2)
189GLOBALS(3)
190GLOBALS(4)
191
192template <typename T> struct Mat4
193{
194    inline Mat4() { }
195    inline Mat4(T val)
196    {
197        for (int j = 0; j < 4; j++)
198            for (int i = 0; i < 4; i++)
199                v[i][j] = (i == j) ? val : 0;
200    }
201    inline Mat4(Vec4<T> v0, Vec4<T> v1, Vec4<T> v2, Vec4<T> v3)
202    {
203        v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3;
204    }
205
206    inline Vec4<T>& operator[](int n) { return v[n]; }
207    inline Vec4<T> const& operator[](int n) const { return v[n]; }
208
209    T det() const;
210    Mat4<T> invert() const;
211
212    static Mat4<T> ortho(T left, T right, T bottom, T top, T near, T far);
213    static Mat4<T> frustum(T left, T right, T bottom, T top, T near, T far);
214    static Mat4<T> perspective(T theta, T width, T height, T near, T far);
215    static Mat4<T> translate(T x, T y, T z);
216    static Mat4<T> rotate(T theta, T x, T y, T z);
217
218    inline Mat4<T> operator +(Mat4<T> const val) const
219    {
220        Mat4<T> ret;
221        for (int j = 0; j < 4; j++)
222            for (int i = 0; i < 4; i++)
223                ret[i][j] = v[i][j] + val[i][j];
224        return ret;
225    }
226
227    inline Mat4<T> operator +=(Mat4<T> const val)
228    {
229        return *this = *this + val;
230    }
231
232    inline Mat4<T> operator -(Mat4<T> const val) const
233    {
234        Mat4<T> ret;
235        for (int j = 0; j < 4; j++)
236            for (int i = 0; i < 4; i++)
237                ret[i][j] = v[i][j] - val[i][j];
238        return ret;
239    }
240
241    inline Mat4<T> operator -=(Mat4<T> const val)
242    {
243        return *this = *this - val;
244    }
245
246    inline Mat4<T> operator *(Mat4<T> const val) const
247    {
248        Mat4<T> ret;
249        for (int j = 0; j < 4; j++)
250            for (int i = 0; i < 4; i++)
251            {
252                T tmp = 0;
253                for (int k = 0; k < 4; k++)
254                    tmp += v[k][j] * val[i][k];
255                ret[i][j] = tmp;
256            }
257        return ret;
258    }
259
260    inline Mat4<T> operator *=(Mat4<T> const val)
261    {
262        return *this = *this * val;
263    }
264
265    inline Vec4<T> operator *(Vec4<T> const val) const
266    {
267        Vec4<T> ret;
268        for (int j = 0; j < 4; j++)
269        {
270            T tmp = 0;
271            for (int i = 0; i < 4; i++)
272                tmp += v[i][j] * val[i];
273            ret[j] = tmp;
274        }
275        return ret;
276    }
277
278    Vec4<T> v[4];
279};
280
281typedef Mat4<float> mat4;
282typedef Mat4<int> mat4i;
283
284} /* namespace lol */
285
286#endif // __DH_MATRIX_H__
287
Note: See TracBrowser for help on using the repository browser.