source:trunk/src/matrix.h@663Tweet

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

Implement +=, -= and *= for matrices and vectors.
Add new types, closer to the GLSL ones.

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