source: trunk/src/matrix.h @ 660

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

Implement float4x4::ortho() and float4x4::translate().

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