source: trunk/src/matrix.h @ 815

Last change on this file since 815 was 815, checked in by sam, 8 years ago

core: fix a bug in vector casts; vec2 -> vec3 promotion for instance would
forget to zero the 3rd coordinate.

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