diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2009-10-29 12:14:31 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2009-10-29 12:14:31 +0000 |
| commit | e56feb597bc743677633432f77513b02907fd169 (patch) | |
| tree | 5b6bbb983fcf33cfe5eef8aec1298608257036b5 /src/base | |
| parent | 878ede3080ab2cfb627aca505c397d9765052996 (diff) | |
| download | zcatch-e56feb597bc743677633432f77513b02907fd169.tar.gz zcatch-e56feb597bc743677633432f77513b02907fd169.zip | |
added missing headers
Diffstat (limited to 'src/base')
| -rw-r--r-- | src/base/tl/math.hpp | 45 | ||||
| -rw-r--r-- | src/base/tl/matrix.hpp | 163 | ||||
| -rw-r--r-- | src/base/tl/quat.hpp | 211 | ||||
| -rw-r--r-- | src/base/tl/stream.hpp | 65 | ||||
| -rw-r--r-- | src/base/tl/vector.hpp | 198 |
5 files changed, 682 insertions, 0 deletions
diff --git a/src/base/tl/math.hpp b/src/base/tl/math.hpp new file mode 100644 index 00000000..b323dea8 --- /dev/null +++ b/src/base/tl/math.hpp @@ -0,0 +1,45 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#ifndef BASE_MATH_H +#define BASE_MATH_H + +#include <stdlib.h> + +template <typename T> +inline T clamp(T val, T min, T max) +{ + if(val < min) + return min; + if(val > max) + return max; + return val; +} + +inline float sign(float f) +{ + return f<0.0f?-1.0f:1.0f; +} + +inline int round(float f) +{ + if(f > 0) + return (int)(f+0.5f); + return (int)(f-0.5f); +} + +template<typename T, typename TB> +inline T mix(const T a, const T b, TB amount) +{ + return a + (b-a)*amount; +} + +inline float frandom() { return rand()/(float)(RAND_MAX); } + +const float pi = 3.1415926535897932384626433f; + +template <typename T> inline T min(T a, T b) { return a<b?a:b; } +template <typename T> inline T max(T a, T b) { return a>b?a:b; } + +template <typename T> inline T min(T a, T b, T c) { return min(min(a,b),c); } +template <typename T> inline T max(T a, T b, T c) { return max(max(a,b),c); } + +#endif // BASE_MATH_H diff --git a/src/base/tl/matrix.hpp b/src/base/tl/matrix.hpp new file mode 100644 index 00000000..b723eaa7 --- /dev/null +++ b/src/base/tl/matrix.hpp @@ -0,0 +1,163 @@ +#ifndef TL_FILE_MATRIX_HPP +#define TL_FILE_MATRIX_HPP + +/* + + Looks like OpenGL + + Column Major + + / m[0][0] m[1][0] m[2][0] m[3][0] \ / v[0] \ + | | | | + | m[0][1] m[1][1] m[2][1] m[3][1] | | v[1] | + | | | | + M(v) = | m[0][2] m[1][2] m[2][2] m[3][2] | X | v[2] | + | | | | + \ m[0][3] m[1][3] m[2][3] m[3][3] / \ v[3] / + + v[0] = x + v[1] = y + v[2] = z + v[3] = w or 1 + + +y + | + | + |_____ +x + / + / + +z + + right = +x + up = +y + forward = -z + +*/ + +template<class T> +class matrix4_base +{ +public: + // [col][row] + T m[4][4]; + + // + inline matrix4_base() + {} + + inline vector3_base<T> get_column3(const int i) const { return vector3_base<T>(m[i][0], m[i][1], m[i][2]); } + inline vector3_base<T> get_column4(const int i) const { return vector4_base<T>(m[i][0], m[i][1], m[i][2], m[i][3]); } + inline vector3_base<T> get_row3(const int i) const { return vector3_base<T>(m[0][i], m[1][i], m[2][i]); } + inline vector4_base<T> get_row4(const int i) const { return vector4_base<T>(m[0][i], m[1][i], m[2][i], m[3][i]); } + + inline vector3_base<T> get_right() const { return get_row3(0); } + inline vector3_base<T> get_up() const { return get_row3(1); } + inline vector3_base<T> get_forward() const { return -get_row3(2); } + inline vector3_base<T> get_translation() const { return get_column3(3); } + + // + void unit() + { + m[0][1] = m[0][2] = m[0][3] = 0; + m[1][0] = m[1][2] = m[1][3] = 0; + m[2][0] = m[2][1] = m[2][3] = 0; + m[3][0] = m[3][1] = m[3][2] = 0; + + m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1; + } + + // + vector3_base<T> operator *(const vector3_base<T> &v) const + { + vector3_base<T> r(0,0,0); + + r.x += v.x*m[0][0] + v.y*m[1][0] + v.z*m[2][0] + m[3][0]; + r.y += v.x*m[0][1] + v.y*m[1][1] + v.z*m[2][1] + m[3][1]; + r.z += v.x*m[0][2] + v.y*m[1][2] + v.z*m[2][2] + m[3][2]; + return r; + } + + // + vector4_base<T> operator *(const vector4_base<T> &v) const + { + vector4_base<T> r(0,0,0,0); + + r.x += v.x*m[0][0] + v.y*m[1][0] + v.z*m[2][0] + v.w*m[3][0]; + r.y += v.x*m[0][1] + v.y*m[1][1] + v.z*m[2][1] + v.w*m[3][1]; + r.z += v.x*m[0][2] + v.y*m[1][2] + v.z*m[2][2] + v.w*m[3][2]; + r.w += v.x*m[0][3] + v.y*m[1][3] + v.z*m[2][3] + v.w*m[3][3]; + return r; + } + // + matrix4_base operator *(const matrix4_base &other) const + { + matrix4_base r; + + for(int i = 0; i < 4; i++) + for(int j = 0; j < 4; j++) + { + r.m[i][j] = 0; + for(int a = 0; a < 4; a++) + r.m[i][j] += m[a][j] * other.m[i][a]; + } + return r; + } + + + // + // THIS PART IS KINDA UGLY BECAUSE MAT4 IS NOT IMMUTABLE + // + + inline void set_row(const vector3_base<T>& v, const int row) + { + m[0][row] = v.x; + m[1][row] = v.y; + m[2][row] = v.z; + } + + inline void set_column(const vector3_base<T>& v, const int col) + { + m[col][0] = v.x; + m[col][1] = v.y; + m[col][2] = v.z; + } + + inline void set_translation(const vector3_base<T>& v) { set_column(v,3); } + + // + void rot_x(T angle) + { + T sina = (T)sin(angle); + T cosa = (T)cos(angle); + + unit(); + m[1][1] = cosa; m[2][1] =-sina; + m[1][2] = sina; m[2][2] = cosa; + } + + // + void rot_y(T angle) + { + T sina = (T)sin(-angle); + T cosa = (T)cos(-angle); + + unit(); + m[0][0] = cosa; m[2][0] =-sina; + m[0][2] = sina; m[2][2] = cosa; + } + + // + void rot_z(T angle) + { + T sina = (T)sin(angle); + T cosa = (T)cos(angle); + + unit(); + m[0][0] = cosa; m[1][0] =-sina; + m[0][1] = sina; m[1][1] = cosa; + } +}; + +typedef matrix4_base<float> mat4; + +#endif diff --git a/src/base/tl/quat.hpp b/src/base/tl/quat.hpp new file mode 100644 index 00000000..2f381e11 --- /dev/null +++ b/src/base/tl/quat.hpp @@ -0,0 +1,211 @@ + + +template<class T> +class quaternion_base +{ +public: + T k[4]; + + /*void Unit() + { + k[0] = 0; + k[1] = 0; + k[2] = 0; + k[3] = 1; + }*/ + + inline quaternion_base(){} + + inline quaternion_base(T x, T y, T z, T w) + { + k[0] = x; + k[1] = y; + k[2] = z; + k[3] = w; + } + + inline quaternion_base(vector3_base<T> axis, T angle) + { + T sin_angle = sin(angle * (T)0.5); + T cos_angle = cos(angle * (T)0.5); + k[0] = axis.x * sin_angle; + k[1] = axis.y * sin_angle; + k[2] = axis.z * sin_angle; + k[3] = cos_angle; + } + + + T magnitude() + { + return sqrt(k[0] * k[0] + k[1] * k[1] + k[2] * k[2] + k[3] * k[3]); + } + + matrix4_base<T> create_matrix() const + { + matrix4_base<T> mat; + + T xx = k[0] * k[0]; + T xy = k[0] * k[1]; + T xz = k[0] * k[2]; + T xw = k[0] * k[3]; + T yy = k[1] * k[1]; + T yz = k[1] * k[2]; + T yw = k[1] * k[3]; + T zz = k[2] * k[2]; + T zw = k[2] * k[3]; + + mat.k[0][0] = 1 - 2 * (yy + zz); + mat.k[0][1] = 2 * (xy + zw); + mat.k[0][2] = 2 * (xz - yw); + mat.k[0][3] = 0; + + mat.k[1][0] = 2 * (xy - zw); + mat.k[1][1] = 1 - 2 * (xx + zz); + mat.k[1][2] = 2 * (yz + xw); + mat.k[1][3] = 0; + + mat.k[2][0] = 2 * (xz + yw); + mat.k[2][1] = 2 * (yz - xw); + mat.k[2][2] = 1 - 2 * (xx + yy); + mat.k[2][3] = 0; + + mat.k[3][0] = 0; + mat.k[3][1] = 0; + mat.k[3][2] = 0; + mat.k[3][3] = 1; + } + + /* + void CreateDOOM(T x, T y, T z) + { + k[0] = x; + k[1] = y; + k[2] = z; + T Term = 1 - (x * x) - (y * y) - (z * z); + if (Term < 0) + k[3] = 0; + else + k[3] = -sqrt(Term); + + Normalize(); + } + + T DotProd(const TQuaternion<T>& Quat) const + { + return (k[0] * Quat.k[0] + k[1] * Quat.k[1] + k[2] * Quat.k[2] + k[3] * Quat.k[3]); + } + + void Interpolate(const TQuaternion<T>& Quat, TQuaternion& Dest, T Scale) + { + T Separation = k[0] * Quat.k[0] + k[1] * Quat.k[1] + k[2] * Quat.k[2] + k[3] * Quat.k[3]; + T Factor1,Factor2; + + if (Separation > 1) + Separation = 1; + if (Separation < -1) + Separation = -1; + Separation = acos(Separation); + if (Separation == 0 || Separation == pi) + { + Factor1 = 1; + Factor2 = 0; + } + else + { + Factor1 = sin((1 - Scale)*Separation) / sin(Separation); + Factor2 = sin(Scale * Separation) / sin(Separation); + } + + Dest.k[0] = k[0] * Factor1 + Quat.k[0] * Factor2; + Dest.k[1] = k[1] * Factor1 + Quat.k[1] * Factor2; + Dest.k[2] = k[2] * Factor1 + Quat.k[2] * Factor2; + Dest.k[3] = k[3] * Factor1 + Quat.k[3] * Factor2; + } + + void Slerp(const TQuaternion<T>& Quat, TQuaternion& Dest, T Scale) const + { + T Sq1,Sq2; + T Dot = DotProd(Quat); + + TQuaternion Temp; + + if (Dot < 0.0f) + { + Dot = -Dot; + Temp.k[0] = -Quat.k[0]; + Temp.k[1] = -Quat.k[1]; + Temp.k[2] = -Quat.k[2]; + Temp.k[3] = -Quat.k[3]; + } + else + { + Temp = Quat; + } + + if ((1.0 + Dot) > 0.00001) + { + if ((1.0 - Dot) > 0.00001) + { + T om = (T)acos(Dot); + T rsinom = (T)(1.0f / sin(om)); + Sq1 = (T)sin(((T)1.0 - Scale) * om) * rsinom; + Sq2 = (T)sin(Scale * om) * rsinom; + } + else + { + Sq1 = (T)(1.0 - Scale); + Sq2 = Scale; + } + Dest.k[0] = Sq1 * k[0] + Sq2 * Temp[0]; + Dest.k[1] = Sq1 * k[1] + Sq2 * Temp[1]; + Dest.k[2] = Sq1 * k[2] + Sq2 * Temp[2]; + Dest.k[3] = Sq1 * k[3] + Sq2 * Temp[3]; + } + else + { + Sq1 = (T)sin(((T)1.0 - Scale) * (T)0.5 * pi); + Sq2 = (T)sin(Scale * (T)0.5 * pi); + + Dest.k[0] = Sq1 * k[0] + Sq2 * Temp[1]; + Dest.k[1] = Sq1 * k[1] + Sq2 * Temp[0]; + Dest.k[2] = Sq1 * k[2] + Sq2 * Temp[3]; + Dest.k[3] = Sq1 * k[3] + Sq2 * Temp[2]; + } + }*/ + + // perators + T& operator [] (int i) { return k[i]; } + + // quaternion multiply + quaternion_base operator *(const quaternion_base& other) const + { + // (w1 dot w2 - v1 dot v2, w1 dot v2 + w2 dot v1 + v1 cross v2) + quaternion_base r; + r.k[0] = k[3] * other.k[0] + k[0] * other.k[3] + k[1] * other.k[2] - k[2] * other.k[1]; + r.k[1] = k[3] * other.k[1] + k[1] * other.k[3] + k[2] * other.k[0] - k[0] * other.k[2]; + r.k[2] = k[3] * other.k[2] + k[2] * other.k[3] + k[0] * other.k[1] - k[1] * other.k[0]; + r.k[3] = k[3] * other.k[3] - k[0] * other.k[0] - k[1] * other.k[1] - k[2] * other.k[2]; + + return normalize(r); + } + + /* + bool operator == (const quaternion_base<T>& t) const { return ((k[0] == t.k[0]) && (k[1] == t.k[1]) && (k[2] == t.k[2]) && (k[3] == t.k[3])); } + bool operator != (const quaternion_base<T>& t) const { return ((k[0] != t.k[0]) || (k[1] != t.k[1]) || (k[2] != t.k[2]) || (k[3] != t.k[3])); } + + void operator = (const quaternion_base<T>& other) { k[0] = other.k[0]; k[1] = other.k[1]; k[2] = other.k[2]; k[3] = other.k[3]; } + */ + + /*void operator *= (const TQuaternion<T>& t) { TQuaternion Temp = Multiply(t); *this = Temp; } + TQuaternion operator * (const TQuaternion<T>& t) const { return Multiply(t); } + */ +}; + +template<typename T> +inline quaternion_base<T> normalize(const quaternion_base<T> &v) +{ + T factor = 1.0f/v.magnitude(); + return quaternion_base<T>(v.k[0]*factor, v.k[1]*factor,v. k[2]*factor,v. k[3]*factor); +} + + diff --git a/src/base/tl/stream.hpp b/src/base/tl/stream.hpp new file mode 100644 index 00000000..c307b968 --- /dev/null +++ b/src/base/tl/stream.hpp @@ -0,0 +1,65 @@ +#ifndef TL_FILE_STREAM_HPP +#define TL_FILE_STREAM_HPP + +class input_stream +{ +public: + virtual ~input_stream() {} + virtual size_t read(void *data, size_t size) = 0; + virtual size_t size() = 0; +}; + +class output_stream +{ +public: + virtual ~output_stream() {} + virtual size_t write(const void *data, size_t size) = 0; +}; + + +// input wrapping +// RAII style +class file_backend +{ +private: + file_backend(const file_backend &other) { /* no copy allowed */ } +protected: + IOHANDLE file_handle; + + explicit file_backend(const char *filename, int flags) + { + file_handle = io_open(filename, flags); + } + + ~file_backend() + { + if(file_handle) + io_close(file_handle); + } +public: + bool is_open() const { return file_handle != 0; } +}; + +class file_reader : public input_stream, public file_backend +{ +public: + explicit file_reader(const char *filename) + : file_backend(filename, IOFLAG_READ) + {} + + virtual size_t read(void *data, size_t size) { return io_read(file_handle, data, size); } + virtual size_t size() { return io_length(file_handle); } +}; + + +class file_writer : public output_stream, public file_backend +{ +public: + explicit file_writer(const char *filename) + : file_backend(filename, IOFLAG_WRITE) + {} + + virtual size_t write(const void *data, size_t size) { return io_write(file_handle, data, size); } +}; + +#endif diff --git a/src/base/tl/vector.hpp b/src/base/tl/vector.hpp new file mode 100644 index 00000000..1c1bb804 --- /dev/null +++ b/src/base/tl/vector.hpp @@ -0,0 +1,198 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#ifndef TL_FILE_VECTOR_HPP +#define TL_FILE_VECTOR_HPP + +#include <math.h> + +// ------------------------------------ + +template<typename T> +class vector2_base +{ +public: + union { T x,u; }; + union { T y,v; }; + + vector2_base() {} + vector2_base(float nx, float ny) + { + x = nx; + y = ny; + } + + vector2_base operator -() const { return vector2_base(-x, -y); } + vector2_base operator -(const vector2_base &v) const { return vector2_base(x-v.x, y-v.y); } + vector2_base operator +(const vector2_base &v) const { return vector2_base(x+v.x, y+v.y); } + vector2_base operator *(const T v) const { return vector2_base(x*v, y*v); } + + const vector2_base &operator =(const vector2_base &v) { x = v.x; y = v.y; return *this; } + + const vector2_base &operator +=(const vector2_base &v) { x += v.x; y += v.y; return *this; } + const vector2_base &operator -=(const vector2_base &v) { x -= v.x; y -= v.y; return *this; } + const vector2_base &operator *=(const T v) { x *= v; y *= v; return *this; } + + bool operator ==(const vector2_base &v) const { return x == v.x && y == v.y; } //TODO: do this with an eps instead + + operator const T* () { return &x; } +}; + + +template<typename T> +inline T length(const vector2_base<T> &a) +{ + return sqrtf(a.x*a.x + a.y*a.y); +} + +template<typename T> +inline T distance(const vector2_base<T> a, const vector2_base<T> &b) +{ + return length(a-b); +} + +template<typename T> +inline T dot(const vector2_base<T> a, const vector2_base<T> &b) +{ + return a.x*b.x + a.y*b.y; +} + +template<typename T> +inline vector2_base<T> normalize(const vector2_base<T> &v) +{ + T l = (T)(1.0f/sqrtf(v.x*v.x + v.y*v.y)); + return vector2_base<T>(v.x*l, v.y*l); +} + +typedef vector2_base<float> vec2; +typedef vector2_base<bool> bvec2; +typedef vector2_base<int> ivec2; + +template<typename T> +inline vector2_base<T> closest_point_on_line(vector2_base<T> line_point0, vector2_base<T> line_point1, vector2_base<T> target_point) +{ + vector2_base<T> c = target_point - line_point0; + vector2_base<T> v = (line_point1 - line_point0); + v = normalize(v); + T d = length(line_point0-line_point1); + T t = dot(v, c)/d; + return mix(line_point0, line_point1, clamp(t, (T)0, (T)1)); + /* + if (t < 0) t = 0; + if (t > 1.0f) return 1.0f; + return t;*/ +} + +// ------------------------------------ +template<typename T> +class vector3_base +{ +public: + union { T x,r,h; }; + union { T y,g,s; }; + union { T z,b,v,l; }; + + vector3_base() {} + vector3_base(float nx, float ny, float nz) + { + x = nx; + y = ny; + z = nz; + } + + const vector3_base &operator =(const vector3_base &v) { x = v.x; y = v.y; z = v.z; return *this; } + + vector3_base operator -(const vector3_base &v) const { return vector3_base(x-v.x, y-v.y, z-v.z); } + vector3_base operator -() const { return vector3_base(-x, -y, -z); } + vector3_base operator +(const vector3_base &v) const { return vector3_base(x+v.x, y+v.y, z+v.z); } + vector3_base operator *(const T v) const { return vector3_base(x*v, y*v, z*v); } + vector3_base operator *(const vector3_base &v) const { return vector3_base(x*v.x, y*v.y, z*v.z); } + vector3_base operator /(const T v) const { return vector3_base(x/v, y/v, z/v); } + + const vector3_base &operator +=(const vector3_base &v) { x += v.x; y += v.y; z += v.z; return *this; } + const vector3_base &operator -=(const vector3_base &v) { x -= v.x; y -= v.y; z -= v.z; return *this; } + const vector3_base &operator *=(const T v) { x *= v; y *= v; z *= v; return *this; } + + bool operator ==(const vector3_base &v) const { return x == v.x && y == v.y && z == v.z; } //TODO: do this with an eps instead + + operator const T* () { return &x; } +}; + +template<typename T> +inline T length(const vector3_base<T> &a) +{ + return sqrtf(a.x*a.x + a.y*a.y + a.z*a.z); +} + +template<typename T> +inline T distance(const vector3_base<T> &a, const vector3_base<T> &b) +{ + return length(a-b); +} + +template<typename T> +inline T dot(const vector3_base<T> &a, const vector3_base<T> &b) +{ + return a.x*b.x + a.y*b.y + a.z*b.z; +} + +template<typename T> +inline vector3_base<T> normalize(const vector3_base<T> &v) +{ + T l = (T)(1.0f/sqrtf(v.x*v.x + v.y*v.y + v.z*v.z)); + return vector3_base<T>(v.x*l, v.y*l, v.z*l); +} + +template<typename T> +inline vector3_base<T> cross(const vector3_base<T> &a, const vector3_base<T> &b) +{ + return vector3_base<T>( + a.y*b.z - a.z*b.y, + a.z*b.x - a.x*b.z, + a.x*b.y - a.y*b.x); +} + +typedef vector3_base<float> vec3; +typedef vector3_base<bool> bvec3; +typedef vector3_base<int> ivec3; + +// ------------------------------------ + +template<typename T> +class vector4_base +{ +public: + union { T x,r; }; + union { T y,g; }; + union { T z,b; }; + union { T w,a; }; + + vector4_base() {} + vector4_base(float nx, float ny, float nz, float nw) + { + x = nx; + y = ny; + z = nz; + w = nw; + } + + vector4_base operator +(const vector4_base &v) const { return vector4_base(x+v.x, y+v.y, z+v.z, w+v.w); } + vector4_base operator -(const vector4_base &v) const { return vector4_base(x-v.x, y-v.y, z-v.z, w-v.w); } + vector4_base operator -() const { return vector4_base(-x, -y, -z, -w); } + vector4_base operator *(const vector4_base &v) const { return vector4_base(x*v.x, y*v.y, z*v.z, w*v.w); } + vector4_base operator *(const T v) const { return vector4_base(x*v, y*v, z*v, w*v); } + + const vector4_base &operator =(const vector4_base &v) { x = v.x; y = v.y; z = v.z; w = v.w; return *this; } + + const vector4_base &operator +=(const vector4_base &v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; } + const vector4_base &operator -=(const vector4_base &v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; } + const vector4_base &operator *=(const T v) { x *= v; y *= v; z *= v; w *= v; return *this; } + + bool operator ==(const vector4_base &v) const { return x == v.x && y == v.y && z == v.z && w == v.w; } //TODO: do this with an eps instead + + operator const T* () { return &x; } +}; + +typedef vector4_base<float> vec4; +typedef vector4_base<bool> bvec4; +typedef vector4_base<int> ivec4; + +#endif |