source: trunk/src/matrix.h @ 929

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

core: add std::ostream operators for vector and matrix classes.

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