/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #ifndef BASE_VMATH_H #define BASE_VMATH_H #include #include "math.h" // ------------------------------------ template class vector2_base { public: union { T x, u; }; union { T y, v; }; vector2_base() {} vector2_base(T nx, T 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); } 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); } vector2_base operator/(const vector2_base &v) const { return vector2_base(x / v.x, y / v.y); } 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; } 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; } const vector2_base &operator/=(const vector2_base &v) { x /= v.x; y /= v.y; return *this; } bool operator==(const vector2_base &v) const { return x == v.x && y == v.y; } //TODO: do this with an eps instead bool operator!=(const vector2_base &v) const { return x != v.x || y != v.y; } operator const T *() { return &x; } T &operator[](const int index) { return index ? y : x; } }; template inline T length(const vector2_base &a) { return sqrtf(a.x * a.x + a.y * a.y); } template inline T distance(const vector2_base a, const vector2_base &b) { return length(a - b); } template inline T dot(const vector2_base a, const vector2_base &b) { return a.x * b.x + a.y * b.y; } template inline vector2_base normalize(const vector2_base &v) { T l = (T)(1.0f / sqrtf(v.x * v.x + v.y * v.y)); return vector2_base(v.x * l, v.y * l); } template inline vector2_base normalize_pre_length(const vector2_base &v, T len) { return vector2_base(v.x / len, v.y / len); } typedef vector2_base vec2; typedef vector2_base bvec2; typedef vector2_base ivec2; template inline bool closest_point_on_line(vector2_base line_point0, vector2_base line_point1, vector2_base target_point, vector2_base &out_pos) { vector2_base c = target_point - line_point0; vector2_base v = (line_point1 - line_point0); T d = length(line_point0 - line_point1); if(d > 0) { v = normalize_pre_length(v, d); T t = dot(v, c) / d; out_pos = mix(line_point0, line_point1, clamp(t, (T)0, (T)1)); return true; } else return false; } // ------------------------------------ template class vector3_base { public: union { T x, r, h; }; union { T y, g, s; }; union { T z, b, v, l; }; vector3_base() {} vector3_base(T nx, T ny, T nz) { x = nx; y = ny; z = nz; } 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); } vector3_base operator/(const vector3_base &v) const { return vector3_base(x / v.x, y / v.y, z / v.z); } 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; } 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; } const vector3_base &operator/=(const vector3_base &v) { x /= v.x; y /= v.y; z /= v.z; 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 inline T length(const vector3_base &a) { return sqrtf(a.x * a.x + a.y * a.y + a.z * a.z); } template inline vector2_base rotate(const vector2_base &a, float angle) { angle = angle * pi / 180.0f; float s = sinf(angle); float c = cosf(angle); return vector2_base((T)(c * a.x - s * a.y), (T)(s * a.x + c * a.y)); } template inline T distance(const vector3_base &a, const vector3_base &b) { return length(a - b); } template inline T dot(const vector3_base &a, const vector3_base &b) { return a.x * b.x + a.y * b.y + a.z * b.z; } template inline vector3_base normalize(const vector3_base &v) { T l = (T)(1.0f / sqrtf(v.x * v.x + v.y * v.y + v.z * v.z)); return vector3_base(v.x * l, v.y * l, v.z * l); } template inline vector3_base cross(const vector3_base &a, const vector3_base &b) { return vector3_base( 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 vec3; typedef vector3_base bvec3; typedef vector3_base ivec3; // ------------------------------------ template class vector4_base { public: union { T x, r, h; }; union { T y, g, s; }; union { T z, b, l; }; union { T w, a; }; vector4_base() {} vector4_base(T nx, T ny, T nz, T 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); } 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 T v) { x *= v; y *= v; z *= v; w *= v; 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; } const vector4_base &operator/=(const vector4_base &v) { x /= v.x; y /= v.y; z /= v.z; w /= v.w; 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 vec4; typedef vector4_base bvec4; typedef vector4_base ivec4; #endif