// // Lol Engine // // Copyright: (c) 2010-2011 Sam Hocevar // This program is free software; you can redistribute it and/or // modify it under the terms of the Do What The Fuck You Want To // Public License, Version 2, as published by Sam Hocevar. See // http://sam.zoy.org/projects/COPYING.WTFPL for more details. // // // The Matrix classes // ------------------ // #if !defined __DH_MATRIX_H__ #define __DH_MATRIX_H__ #include #define VECTOR_OP(elems, op) \ template \ inline Vec##elems operator op(Vec##elems const &val) const \ { \ Vec##elems ret; \ for (int n = 0; n < elems; n++) \ ret[n] = (*this)[n] op val[n]; \ return ret; \ } #define BOOL_OP(elems, op, ret) \ inline bool operator op(Vec##elems const &val) const \ { \ for (int n = 0; n < elems; n++) \ if ((*this)[n] != val[n]) \ return ret; \ return !ret; \ } #define SCALAR_OP(elems, op) \ inline Vec##elems operator op(T const &val) const \ { \ Vec##elems ret; \ for (int n = 0; n < elems; n++) \ ret[n] = (*this)[n] op val; \ return ret; \ } #define CAST_OP(elems, dest) \ inline operator Vec##dest() const \ { \ Vec##dest ret; \ for (int n = 0; n < elems && n < dest; n++) \ ret[n] = (*this)[n]; \ return ret; \ } #define OPERATORS(elems) \ inline T& operator[](int n) { return *(&x + n); } \ inline T const& operator[](int n) const { return *(&x + n); } \ \ VECTOR_OP(elems, -) \ VECTOR_OP(elems, +) \ VECTOR_OP(elems, *) \ VECTOR_OP(elems, /) \ \ BOOL_OP(elems, ==, false) \ BOOL_OP(elems, !=, true) \ \ SCALAR_OP(elems, -) \ SCALAR_OP(elems, +) \ SCALAR_OP(elems, *) \ SCALAR_OP(elems, /) \ \ CAST_OP(elems, 2) \ CAST_OP(elems, 3) \ CAST_OP(elems, 4) \ \ template \ inline operator Vec##elems() const \ { \ Vec##elems ret; \ for (int n = 0; n < elems; n++) \ ret[n] = static_cast((*this)[n]); \ return ret; \ } \ \ inline T sqlen() const \ { \ T acc = 0; \ for (int n = 0; n < elems; n++) \ acc += (*this)[n] * (*this)[n]; \ return acc; \ } \ \ inline float len() const \ { \ return sqrtf((float)sqlen()); \ } template struct Vec2; template struct Vec3; template struct Vec4; template struct Vec2 { inline Vec2() { } inline Vec2(T val) { x = y = val; } inline Vec2(T _x, T _y) { x = _x; y = _y; } OPERATORS(2) union { T x; T a; T i; }; union { T y; T b; T j; }; }; typedef Vec2 float2; typedef Vec2 int2; template struct Vec3 { inline Vec3() { } inline Vec3(T val) { x = y = z = val; } inline Vec3(T _x, T _y, T _z) { x = _x; y = _y; z = _z; } OPERATORS(3) union { T x; T a; T i; }; union { T y; T b; T j; }; union { T z; T c; T k; }; }; typedef Vec3 float3; typedef Vec3 int3; template struct Vec4 { inline Vec4() { } inline Vec4(T val) { x = y = z = w = val; } inline Vec4(T _x, T _y, T _z, T _w) { x = _x; y = _y; z = _z; w = _w; } OPERATORS(4) union { T x; T a; T i; }; union { T y; T b; T j; }; union { T z; T c; T k; }; union { T w; T d; T l; }; }; typedef Vec4 float4; typedef Vec4 int4; #define SCALAR_GLOBAL(elems, op, U) \ template \ static inline Vec##elems operator op(U const &val, \ Vec##elems const &that) \ { \ Vec##elems ret; \ for (int n = 0; n < elems; n++) \ ret[n] = val op that[n]; \ return ret; \ } #define SCALAR_GLOBAL2(elems, op) \ SCALAR_GLOBAL(elems, op, int) \ SCALAR_GLOBAL(elems, op, float) #define GLOBALS(elems) \ SCALAR_GLOBAL2(elems, -) \ SCALAR_GLOBAL2(elems, +) \ SCALAR_GLOBAL2(elems, *) \ SCALAR_GLOBAL2(elems, /) GLOBALS(2) GLOBALS(3) GLOBALS(4) template struct Mat4 { inline Mat4() { } inline Mat4(T val) { for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) v[i][j] = (i == j) ? val : 0; } inline Mat4(Vec4 v0, Vec4 v1, Vec4 v2, Vec4 v3) { v[0] = v0; v[1] = v1; v[2] = v2; v[3] = v3; } inline Vec4& operator[](int n) { return v[n]; } inline Vec4 const& operator[](int n) const { return v[n]; } T det() const; Mat4 invert() const; static Mat4 ortho(T left, T right, T bottom, T top, T near, T far); static Mat4 frustum(T left, T right, T bottom, T top, T near, T far); static Mat4 perspective(T theta, T width, T height, T near, T far); static Mat4 translate(T x, T y, T z); inline Mat4 operator +(Mat4 const val) const { Mat4 ret; for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) ret[i][j] = v[i][j] + val[i][j]; return ret; } inline Mat4 operator -(Mat4 const val) const { Mat4 ret; for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) ret[i][j] = v[i][j] - val[i][j]; return ret; } inline Mat4 operator *(Mat4 const val) const { Mat4 ret; for (int j = 0; j < 4; j++) for (int i = 0; i < 4; i++) { T tmp = 0; for (int k = 0; k < 4; k++) tmp += v[k][j] * val[i][k]; ret[i][j] = tmp; } return ret; } inline Vec4 operator *(Vec4 const val) const { Vec4 ret; for (int j = 0; j < 4; j++) { T tmp = 0; for (int i = 0; i < 4; i++) tmp += v[i][j] * val[i]; ret[j] = tmp; } return ret; } Vec4 v[4]; }; typedef Mat4 float4x4; typedef Mat4 int4x4; #endif // __DH_MATRIX_H__