From 016badf08fbd4db92e6ee6e2ad74e7e61c5505e3 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 29 Dec 2015 12:05:19 +0200 Subject: [PATCH] Vector4 inline definitions, and rearrangement into multiple inl files --- Makefile | 5 +- src/gmath.h | 5 + src/ray.h | 8 +- src/vector.cc | 23 +++++ src/vector.h | 73 ++++++++++++-- src/vector.inl | 292 ------------------------------------------------------- src/vector2.inl | 18 ++++ src/vector3.inl | 225 ++++++++++++++++++++++++++++++++++++++++++ src/vector4.inl | 252 +++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 597 insertions(+), 304 deletions(-) delete mode 100644 src/vector.inl create mode 100644 src/vector2.inl create mode 100644 src/vector3.inl create mode 100644 src/vector4.inl diff --git a/Makefile b/Makefile index 315b7df..cfbb34d 100644 --- a/Makefile +++ b/Makefile @@ -12,9 +12,10 @@ rootdir ?= . ccsrc = $(wildcard $(rootdir)/src/*.cc) obj = $(ccsrc:.cc=.o) $(csrc:.c=.o) dep = $(obj:.o=.d) +def = -DGPH_NAMESPACE -CFLAGS = $(warn_flags) $(opt_flags) $(dbg_flags) $(pic) -CXXFLAGS = $(warn_flags) $(opt_flags) $(dbg_flags) $(pic) +CFLAGS = $(warn_flags) $(opt_flags) $(dbg_flags) $(pic) $(def) +CXXFLAGS = $(warn_flags) $(opt_flags) $(dbg_flags) $(pic) $(def) sys = $(shell uname -s | sed 's/MINGW.*/MINGW/') ifeq ($(sys), Darwin) diff --git a/src/gmath.h b/src/gmath.h index 6e1cde3..14d5eb0 100644 --- a/src/gmath.h +++ b/src/gmath.h @@ -3,5 +3,10 @@ #include "vector.h" #include "matrix.h" +#include "ray.h" + +#ifndef GPH_NAMESPACE +using namespace gph; +#endif #endif // GMATH_H_ diff --git a/src/ray.h b/src/ray.h index 2574036..72dfc26 100644 --- a/src/ray.h +++ b/src/ray.h @@ -11,7 +11,7 @@ public: Vector3 origin, dir; Ray() : dir(0, 0, 1) {} - Ray(const Vector3 &o, const Vector3 &d) : o(origin), d(dir) {} + Ray(const Vector3 &o, const Vector3 &d) : origin(o), dir(d) {} }; inline Ray operator *(const Ray &r, const Matrix4x4 &m) @@ -20,7 +20,7 @@ inline Ray operator *(const Ray &r, const Matrix4x4 &m) up[0][3] = up[1][3] = up[2][3] = up[3][0] = up[3][1] = up[3][2] = 0.0; up[3][3] = 1.0; - return Ray(origin * m, dir * up); + return Ray(r.origin * m, r.dir * up); } inline Ray operator *(const Matrix4x4 &m, const Ray &r) @@ -29,7 +29,7 @@ inline Ray operator *(const Matrix4x4 &m, const Ray &r) up[0][3] = up[1][3] = up[2][3] = up[3][0] = up[3][1] = up[3][2] = 0.0; up[3][3] = 1.0; - return Ray(m * origin, m * dir); + return Ray(m * r.origin, m * r.dir); } @@ -49,6 +49,6 @@ inline Ray refract(const Ray &ray, const Vector3 &n, float from_ior, float to_io } -} +} // namespace gph #endif // GMATH_RAY_H_ diff --git a/src/vector.cc b/src/vector.cc index 4af8dab..9532ccf 100644 --- a/src/vector.cc +++ b/src/vector.cc @@ -8,6 +8,8 @@ Vector2::Vector2(const Vector3 &v) { } +// ---- Vector3 ---- + Vector3::Vector3(const Vector4 &v) : x(v.x), y(v.y), z(v.z) { @@ -29,9 +31,30 @@ Vector3 operator *(const Matrix4x4 &m, const Vector3 &v) return Vector3(x, y, z); } +// ---- Vector4 ---- + Vector4::Vector4(const Vector3 &v) : x(v.x), y(v.y), z(v.z), w(1.0f) { } +Vector4 operator *(const Vector4 &v, const Matrix4x4 &m) +{ + float x = v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0]; + float y = v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1]; + float z = v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2]; + float w = v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3]; + return Vector4(x, y, z, w); +} + +Vector4 operator *(const Matrix4x4 &m, const Vector4 &v) +{ + float x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w; + float y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w; + float z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w; + float w = m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w; + return Vector4(x, y, z, w); +} + + } // namespace gph diff --git a/src/vector.h b/src/vector.h index 02aeddf..da3b09b 100644 --- a/src/vector.h +++ b/src/vector.h @@ -6,6 +6,7 @@ namespace gph { +// define the swizzle macros to emit function prototypes #define GPH_SWIZZLE2(T, a, b) inline Vector2 a##b() const; #define GPH_SWIZZLE3(T, a, b, c) inline Vector3 a##b##c() const; #define GPH_SWIZZLE4(T, a, b, c, d) inline Vector4 a##b##c##d() const; @@ -21,7 +22,7 @@ public: Vector2() : x(0), y(0) {} Vector2(float x_, float y_) : x(x_), y(y_) {} - Vector2(const Vector3 &v); + explicit Vector2(const Vector3 &v); inline void normalize(); inline float &operator[] (int idx); @@ -36,7 +37,7 @@ public: Vector3() : x(0), y(0), z(0) {} Vector3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) {} - Vector3(const Vector4 &v); + explicit Vector3(const Vector4 &v); inline void normalize(); inline float &operator[] (int idx); @@ -51,8 +52,8 @@ public: float x, y, z, w; Vector4() : x(0), y(0), z(0), w(0) {} - Vector4(float x_, float y_, float z_, float w_) : x(x_), y(y_), z(z_), w(w_) {} - Vector4(const Vector3 &v); + Vector4(float x_, float y_, float z_, float w_ = 1.0f) : x(x_), y(y_), z(z_), w(w_) {} + explicit Vector4(const Vector3 &v); inline void normalize(); inline float &operator[] (int idx); @@ -106,8 +107,68 @@ inline Vector3 rotate(const Vector3 &v, const Quaternion &q); inline Vector3 rotate(const Vector3 &v, const Vector3 &axis, float angle); inline Vector3 rotate(const Vector3 &v, const Vector3 &euler); -} -#include "vector.inl" +// ---- Vector4 functions ---- +inline Vector4 operator -(const Vector4 &v); +inline Vector4 operator +(const Vector4 &a, const Vector4 &b); +inline Vector4 operator -(const Vector4 &a, const Vector4 &b); +inline Vector4 operator *(const Vector4 &a, const Vector4 &b); +inline Vector4 operator /(const Vector4 &a, const Vector4 &b); +inline Vector4 operator *(const Vector4 &v, float s); +inline Vector4 operator *(float s, const Vector4 &v); +inline Vector4 operator /(const Vector4 &v, float s); +inline Vector4 operator /(float s, const Vector4 &v); +inline Vector4 &operator +=(Vector4 &a, const Vector4 &b); +inline Vector4 &operator -=(Vector4 &a, const Vector4 &b); +inline Vector4 &operator *=(Vector4 &a, const Vector4 &b); +inline Vector4 &operator /=(Vector4 &a, const Vector4 &b); +inline Vector4 &operator *=(Vector4 &v, float s); +inline Vector4 &operator /=(Vector4 &v, float s); + +Vector4 operator *(const Vector4 &v, const Matrix4x4 &m); +Vector4 operator *(const Matrix4x4 &m, const Vector4 &v); + +inline bool operator ==(const Vector4 &a, const Vector4 &b); +inline bool operator !=(const Vector4 &a, const Vector4 &b); + +inline float dot(const Vector4 &a, const Vector4 &b); +inline Vector4 cross(const Vector4 &a, const Vector4 &b, const Vector4 &c); +inline float length(const Vector4 &v); +inline float length_sq(const Vector4 &v); +inline Vector4 normalize(const Vector4 &v); + +inline Vector4 reflect(const Vector4 &v, const Vector4 &n); +inline Vector4 refract(const Vector4 &v, const Vector4 &n, float ior); +inline Vector4 refract(const Vector4 &v, const Vector4 &n, float from_ior, float to_ior); + +inline float distance(const Vector4 &a, const Vector4 &b); +inline float distance_sq(const Vector4 &a, const Vector4 &b); +inline Vector4 faceforward(const Vector4 &n, const Vector4 &vi, const Vector4 &ng); + +inline Vector4 major(const Vector4 &v); +inline int major_idx(const Vector4 &v); +inline Vector4 proj_axis(const Vector4 &v, const Vector4 &axis); + +inline Vector4 rotate(const Vector4 &v, const Quaternion &q); +inline Vector4 rotate(const Vector4 &v, const Vector4 &axis, float angle); +inline Vector4 rotate(const Vector4 &v, const Vector4 &euler); + +// include definitions of all the inline functions above +#include "vector2.inl" +#include "vector3.inl" +#include "vector4.inl" + +// change the swizzle macros to spit out the function definitions and invoke them +#undef GPH_SWIZZLE2 +#undef GPH_SWIZZLE3 +#undef GPH_SWIZZLE4 +#define GPH_SWIZZLE2(T, a, b) inline Vector2 T::a##b() const { return Vector2(a, b); } +#define GPH_SWIZZLE3(T, a, b, c) inline Vector3 T::a##b##c() const { return Vector3(a, b, c); } +#define GPH_SWIZZLE4(T, a, b, c, d) inline Vector4 T::a##b##c##d() const { return Vector4(a, b, c, d); } +GPH_VEC2_SWIZZLE +GPH_VEC3_SWIZZLE +GPH_VEC4_SWIZZLE + +} #endif /* GMATH_VEC_H_ */ diff --git a/src/vector.inl b/src/vector.inl deleted file mode 100644 index 1aeae0f..0000000 --- a/src/vector.inl +++ /dev/null @@ -1,292 +0,0 @@ -#include - -namespace gph { - -#undef GPH_SWIZZLE2 -#undef GPH_SWIZZLE3 -#undef GPH_SWIZZLE4 -#define GPH_SWIZZLE2(T, a, b) inline Vector2 T::a##b() const { return Vector2(a, b); } -#define GPH_SWIZZLE3(T, a, b, c) inline Vector3 T::a##b##c() const { return Vector3(a, b, c); } -#define GPH_SWIZZLE4(T, a, b, c, d) inline Vector4 T::a##b##c##d() const { return Vector4(a, b, c, d); } - -// ---- Vector3 ---- - -inline void Vector3::normalize() -{ - float len = (float)sqrt(x * x + y * y + z * z); - if(len != 0.0f) { - x /= len; - y /= len; - z /= len; - } -} - -inline float &Vector3::operator[] (int idx) -{ - return idx == 0 ? x : (idx == 1 ? y : z); -} - -inline const float &Vector3::operator[] (int idx) const -{ - return idx == 0 ? x : (idx == 1 ? y : z); -} - -inline Vector3 operator -(const Vector3 &v) -{ - return Vector3(-v.x, -v.y, -v.z); -} - -inline Vector3 operator +(const Vector3 &a, const Vector3 &b) -{ - return Vector3(a.x + b.x, a.y + b.y, a.z + b.z); -} - -inline Vector3 operator -(const Vector3 &a, const Vector3 &b) -{ - return Vector3(a.x - b.x, a.y - b.y, a.z - b.z); -} - -inline Vector3 operator *(const Vector3 &a, const Vector3 &b) -{ - return Vector3(a.x * b.x, a.y * b.y, a.z * b.z); -} - -inline Vector3 operator /(const Vector3 &a, const Vector3 &b) -{ - return Vector3(a.x / b.x, a.y / b.y, a.z / b.z); -} - -inline Vector3 operator *(const Vector3 &v, float s) -{ - return Vector3(v.x * s, v.y * s, v.z * s); -} - -inline Vector3 operator *(float s, const Vector3 &v) -{ - return Vector3(s * v.x, s * v.y, s * v.z); -} - -inline Vector3 operator /(const Vector3 &v, float s) -{ - return Vector3(v.x / s, v.y / s, v.z / s); -} - -inline Vector3 operator /(float s, const Vector3 &v) -{ - return Vector3(s / v.x, s / v.y, s / v.z); -} - -inline Vector3 &operator +=(Vector3 &a, const Vector3 &b) -{ - a.x += b.x; - a.y += b.y; - a.z += b.z; - return a; -} - -inline Vector3 &operator -=(Vector3 &a, const Vector3 &b) -{ - a.x -= b.x; - a.y -= b.y; - a.z -= b.z; - return a; -} - -inline Vector3 &operator *=(Vector3 &a, const Vector3 &b) -{ - a.x *= b.x; - a.y *= b.y; - a.z *= b.z; - return a; -} - -inline Vector3 &operator /=(Vector3 &a, const Vector3 &b) -{ - a.x /= b.x; - a.y /= b.y; - a.z /= b.z; - return a; -} - -inline Vector3 &operator *=(Vector3 &v, float s) -{ - v.x *= s; - v.y *= s; - v.z *= s; - return v; -} - -inline Vector3 &operator /=(Vector3 &v, float s) -{ - v.x /= s; - v.y /= s; - v.z /= s; - return v; -} - -inline bool operator ==(const Vector3 &a, const Vector3 &b) -{ - return a.x == b.x && a.y == b.y && a.z == b.z; -} - -inline bool operator !=(const Vector3 &a, const Vector3 &b) -{ - return !(a == b); -} - -inline float dot(const Vector3 &a, const Vector3 &b) -{ - return a.x * b.x + a.y * b.y + a.z * b.z; -} - -inline Vector3 cross(const Vector3 &a, const Vector3 &b) -{ - return Vector3(a.y * b.z - a.z * b.y, - a.z * b.x - a.x * b.z, - a.x * b.y - a.y * b.x); -} - -inline float length(const Vector3 &v) -{ - return (float)sqrt(v.x * v.x + v.y * v.y + v.z * v.z); -} - -inline float length_sq(const Vector3 &v) -{ - return v.x * v.x + v.y * v.y + v.z * v.z; -} - -inline Vector3 normalize(const Vector3 &v) -{ - float len = length(v); - if(len == 0.0f) { - return v; - } - - return Vector3(v.x / len, v.y / len, v.z / len); -} - -inline Vector3 reflect(const Vector3 &v, const Vector3 &n) -{ - return v - n * dot(n, v) * 2.0; -} - -inline Vector3 refract(const Vector3 &v, const Vector3 &n, float ior) -{ - float ndotv = dot(n, v); - float k = 1.0f - ior * ior * (1.0f - ndotv * ndotv); - if(k < 0.0f) { - return Vector3(); - } - return ior * v - (ior * ndotv + sqrt(k)) * n; -} - -inline Vector3 refract(const Vector3 &v, const Vector3 &n, float from_ior, float to_ior) -{ - if(to_ior == 0.0f) to_ior = 1.0f; - return refract(v, n, from_ior / to_ior); -} - -inline float distance(const Vector3 &a, const Vector3 &b) -{ - return length(a - b); -} - -inline float distance_sq(const Vector3 &a, const Vector3 &b) -{ - return length_sq(a - b); -} - -inline Vector3 faceforward(const Vector3 &n, const Vector3 &vi, const Vector3 &ng) -{ - return dot(ng, vi) < 0.0f ? n : -n; -} - -inline Vector3 major(const Vector3 &v) -{ - int m = major_idx(v); - Vector3 res; - res[m] = v[m]; - return res; -} - -inline int major_idx(const Vector3 &v) -{ - return fabs(v.x) >= fabs(v.y) && fabs(v.x) > fabs(v.z) ? 0 : - (fabs(v.y) >= fabs(v.z) ? 1 : 2); -} - -inline Vector3 proj_axis(const Vector3 &v, const Vector3 &axis) -{ - return axis * dot(v, axis); -} - - -inline Vector3 rotate(const Vector3 &v, const Quaternion &q) -{ - return v; // TODO -} - -inline Vector3 rotate(const Vector3 &v, const Vector3 &axis, float angle) -{ - return v; // TODO -} - -inline Vector3 rotate(const Vector3 &v, const Vector3 &euler) -{ - return v; // TODO -} - - -GPH_VEC3_SWIZZLE - -// ---- Vector4 ---- - - -inline void Vector4::normalize() -{ - float len = (float)sqrt(x * x + y * y + z * z + w * w); - if(len != 0.0f) { - x /= len; - y /= len; - z /= len; - w /= len; - } -} - -inline float &Vector4::operator[] (int idx) -{ - return idx == 0 ? x : (idx == 1 ? y : (idx == 2 ? z : w)); -} - -inline const float &Vector4::operator[] (int idx) const -{ - return idx == 0 ? x : (idx == 1 ? y : (idx == 2 ? z : w)); -} - -GPH_VEC4_SWIZZLE - -// ---- Vector2 ---- - -inline void Vector2::normalize() -{ - float len = (float)sqrt(x * x + y * y); - if(len != 0.0f) { - x /= len; - y /= len; - } -} - -inline float &Vector2::operator[] (int idx) -{ - return idx == 0 ? x : y; -} - -inline const float &Vector2::operator[] (int idx) const -{ - return idx == 0 ? x : y; -} - -GPH_VEC2_SWIZZLE - -} // namespace gph diff --git a/src/vector2.inl b/src/vector2.inl new file mode 100644 index 0000000..64aa0c4 --- /dev/null +++ b/src/vector2.inl @@ -0,0 +1,18 @@ +inline void Vector2::normalize() +{ + float len = (float)sqrt(x * x + y * y); + if(len != 0.0f) { + x /= len; + y /= len; + } +} + +inline float &Vector2::operator[] (int idx) +{ + return idx == 0 ? x : y; +} + +inline const float &Vector2::operator[] (int idx) const +{ + return idx == 0 ? x : y; +} diff --git a/src/vector3.inl b/src/vector3.inl new file mode 100644 index 0000000..8f6167c --- /dev/null +++ b/src/vector3.inl @@ -0,0 +1,225 @@ +inline void Vector3::normalize() +{ + float len = (float)sqrt(x * x + y * y + z * z); + if(len != 0.0f) { + x /= len; + y /= len; + z /= len; + } +} + +inline float &Vector3::operator[] (int idx) +{ + return idx == 0 ? x : (idx == 1 ? y : z); +} + +inline const float &Vector3::operator[] (int idx) const +{ + return idx == 0 ? x : (idx == 1 ? y : z); +} + +inline Vector3 operator -(const Vector3 &v) +{ + return Vector3(-v.x, -v.y, -v.z); +} + +inline Vector3 operator +(const Vector3 &a, const Vector3 &b) +{ + return Vector3(a.x + b.x, a.y + b.y, a.z + b.z); +} + +inline Vector3 operator -(const Vector3 &a, const Vector3 &b) +{ + return Vector3(a.x - b.x, a.y - b.y, a.z - b.z); +} + +inline Vector3 operator *(const Vector3 &a, const Vector3 &b) +{ + return Vector3(a.x * b.x, a.y * b.y, a.z * b.z); +} + +inline Vector3 operator /(const Vector3 &a, const Vector3 &b) +{ + return Vector3(a.x / b.x, a.y / b.y, a.z / b.z); +} + +inline Vector3 operator *(const Vector3 &v, float s) +{ + return Vector3(v.x * s, v.y * s, v.z * s); +} + +inline Vector3 operator *(float s, const Vector3 &v) +{ + return Vector3(s * v.x, s * v.y, s * v.z); +} + +inline Vector3 operator /(const Vector3 &v, float s) +{ + return Vector3(v.x / s, v.y / s, v.z / s); +} + +inline Vector3 operator /(float s, const Vector3 &v) +{ + return Vector3(s / v.x, s / v.y, s / v.z); +} + +inline Vector3 &operator +=(Vector3 &a, const Vector3 &b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + return a; +} + +inline Vector3 &operator -=(Vector3 &a, const Vector3 &b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; + return a; +} + +inline Vector3 &operator *=(Vector3 &a, const Vector3 &b) +{ + a.x *= b.x; + a.y *= b.y; + a.z *= b.z; + return a; +} + +inline Vector3 &operator /=(Vector3 &a, const Vector3 &b) +{ + a.x /= b.x; + a.y /= b.y; + a.z /= b.z; + return a; +} + +inline Vector3 &operator *=(Vector3 &v, float s) +{ + v.x *= s; + v.y *= s; + v.z *= s; + return v; +} + +inline Vector3 &operator /=(Vector3 &v, float s) +{ + v.x /= s; + v.y /= s; + v.z /= s; + return v; +} + +inline bool operator ==(const Vector3 &a, const Vector3 &b) +{ + return a.x == b.x && a.y == b.y && a.z == b.z; +} + +inline bool operator !=(const Vector3 &a, const Vector3 &b) +{ + return !(a == b); +} + +inline float dot(const Vector3 &a, const Vector3 &b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +inline Vector3 cross(const Vector3 &a, const Vector3 &b) +{ + return Vector3(a.y * b.z - a.z * b.y, + a.z * b.x - a.x * b.z, + a.x * b.y - a.y * b.x); +} + +inline float length(const Vector3 &v) +{ + return (float)sqrt(v.x * v.x + v.y * v.y + v.z * v.z); +} + +inline float length_sq(const Vector3 &v) +{ + return v.x * v.x + v.y * v.y + v.z * v.z; +} + +inline Vector3 normalize(const Vector3 &v) +{ + float len = length(v); + if(len == 0.0f) { + return v; + } + + return Vector3(v.x / len, v.y / len, v.z / len); +} + +inline Vector3 reflect(const Vector3 &v, const Vector3 &n) +{ + return v - n * dot(n, v) * 2.0; +} + +inline Vector3 refract(const Vector3 &v, const Vector3 &n, float ior) +{ + float ndotv = dot(n, v); + float k = 1.0f - ior * ior * (1.0f - ndotv * ndotv); + if(k < 0.0f) { + return Vector3(); + } + return ior * v - (ior * ndotv + sqrt(k)) * n; +} + +inline Vector3 refract(const Vector3 &v, const Vector3 &n, float from_ior, float to_ior) +{ + if(to_ior == 0.0f) to_ior = 1.0f; + return refract(v, n, from_ior / to_ior); +} + +inline float distance(const Vector3 &a, const Vector3 &b) +{ + return length(a - b); +} + +inline float distance_sq(const Vector3 &a, const Vector3 &b) +{ + return length_sq(a - b); +} + +inline Vector3 faceforward(const Vector3 &n, const Vector3 &vi, const Vector3 &ng) +{ + return dot(ng, vi) < 0.0f ? n : -n; +} + +inline Vector3 major(const Vector3 &v) +{ + int m = major_idx(v); + Vector3 res; + res[m] = v[m]; + return res; +} + +inline int major_idx(const Vector3 &v) +{ + return fabs(v.x) >= fabs(v.y) && fabs(v.x) > fabs(v.z) ? 0 : + (fabs(v.y) >= fabs(v.z) ? 1 : 2); +} + +inline Vector3 proj_axis(const Vector3 &v, const Vector3 &axis) +{ + return axis * dot(v, axis); +} + + +inline Vector3 rotate(const Vector3 &v, const Quaternion &q) +{ + return v; // TODO +} + +inline Vector3 rotate(const Vector3 &v, const Vector3 &axis, float angle) +{ + return v; // TODO +} + +inline Vector3 rotate(const Vector3 &v, const Vector3 &euler) +{ + return v; // TODO +} diff --git a/src/vector4.inl b/src/vector4.inl new file mode 100644 index 0000000..c37eed1 --- /dev/null +++ b/src/vector4.inl @@ -0,0 +1,252 @@ +inline void Vector4::normalize() +{ + float len = (float)sqrt(x * x + y * y + z * z + w * w); + if(len != 0.0f) { + x /= len; + y /= len; + z /= len; + w /= len; + } +} + +inline float &Vector4::operator[] (int idx) +{ + return idx == 0 ? x : (idx == 1 ? y : (idx == 2 ? z : w)); +} + +inline const float &Vector4::operator[] (int idx) const +{ + return idx == 0 ? x : (idx == 1 ? y : (idx == 2 ? z : w)); +} + +inline Vector4 operator -(const Vector4 &v) +{ + return Vector4(-v.x, -v.y, -v.z, -v.w); +} + +inline Vector4 operator +(const Vector4 &a, const Vector4 &b) +{ + return Vector4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); +} + +inline Vector4 operator -(const Vector4 &a, const Vector4 &b) +{ + return Vector4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); +} + +inline Vector4 operator *(const Vector4 &a, const Vector4 &b) +{ + return Vector4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); +} + +inline Vector4 operator /(const Vector4 &a, const Vector4 &b) +{ + return Vector4(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); +} + +inline Vector4 operator *(const Vector4 &v, float s) +{ + return Vector4(v.x * s, v.y * s, v.z * s, v.w * s); +} + +inline Vector4 operator *(float s, const Vector4 &v) +{ + return Vector4(s * v.x, s * v.y, s * v.z, s * v.w); +} + +inline Vector4 operator /(const Vector4 &v, float s) +{ + return Vector4(v.x / s, v.y / s, v.z / s, v.w / s); +} + +inline Vector4 operator /(float s, const Vector4 &v) +{ + return Vector4(s / v.x, s / v.y, s / v.z, s / v.w); +} + +inline Vector4 &operator +=(Vector4 &a, const Vector4 &b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + a.w += b.w; + return a; +} + +inline Vector4 &operator -=(Vector4 &a, const Vector4 &b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; + a.w -= b.w; + return a; +} + +inline Vector4 &operator *=(Vector4 &a, const Vector4 &b) +{ + a.x *= b.x; + a.y *= b.y; + a.z *= b.z; + a.w *= b.w; + return a; +} + +inline Vector4 &operator /=(Vector4 &a, const Vector4 &b) +{ + a.x /= b.x; + a.y /= b.y; + a.z /= b.z; + a.w /= b.w; + return a; +} + +inline Vector4 &operator *=(Vector4 &v, float s) +{ + v.x *= s; + v.y *= s; + v.z *= s; + v.w *= s; + return v; +} + +inline Vector4 &operator /=(Vector4 &v, float s) +{ + v.x /= s; + v.y /= s; + v.z /= s; + v.w /= s; + return v; +} + +inline bool operator ==(const Vector4 &a, const Vector4 &b) +{ + return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; +} + +inline bool operator !=(const Vector4 &a, const Vector4 &b) +{ + return !(a == b); +} + +inline float dot(const Vector4 &a, const Vector4 &b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + +inline Vector4 cross(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3) +{ + /* Calculate intermediate values. */ + float a = (v2.x * v3.y) - (v2.y * v3.x); + float b = (v2.x * v3.z) - (v2.z * v3.x); + float c = (v2.x * v3.w) - (v2.w * v3.x); + float d = (v2.y * v3.z) - (v2.z * v3.y); + float e = (v2.y * v3.w) - (v2.w * v3.y); + float f = (v2.z * v3.w) - (v2.w * v3.z); + + /* Calculate the result-vector components. */ + float x = (v1.y * f) - (v1.z * e) + (v1.w * d); + float y = - (v1.x * f) + (v1.z * c) - (v1.w * b); + float z = (v1.x * e) - (v1.y * c) + (v1.w * a); + float w = - (v1.x * d) + (v1.y * b) - (v1.z * a); + + return Vector4(x, y, z, w); +} + +inline float length(const Vector4 &v) +{ + return (float)sqrt(v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w); +} + +inline float length_sq(const Vector4 &v) +{ + return v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w; +} + +inline Vector4 normalize(const Vector4 &v) +{ + float len = length(v); + if(len == 0.0f) { + return v; + } + + return Vector4(v.x / len, v.y / len, v.z / len, v.w / len); +} + +inline Vector4 reflect(const Vector4 &v, const Vector4 &n) +{ + return v - n * dot(n, v) * 2.0; +} + +inline Vector4 refract(const Vector4 &v, const Vector4 &n, float ior) +{ + float ndotv = dot(n, v); + float k = 1.0f - ior * ior * (1.0f - ndotv * ndotv); + if(k < 0.0f) { + return Vector4(); + } + return ior * v - (ior * ndotv + sqrt(k)) * n; +} + +inline Vector4 refract(const Vector4 &v, const Vector4 &n, float from_ior, float to_ior) +{ + if(to_ior == 0.0f) to_ior = 1.0f; + return refract(v, n, from_ior / to_ior); +} + +inline float distance(const Vector4 &a, const Vector4 &b) +{ + return length(a - b); +} + +inline float distance_sq(const Vector4 &a, const Vector4 &b) +{ + return length_sq(a - b); +} + +inline Vector4 faceforward(const Vector4 &n, const Vector4 &vi, const Vector4 &ng) +{ + return dot(ng, vi) < 0.0f ? n : -n; +} + +inline Vector4 major(const Vector4 &v) +{ + int m = major_idx(v); + Vector4 res; + res[m] = v[m]; + return res; +} + +inline int major_idx(const Vector4 &v) +{ + if(fabs(v.x) >= fabs(v.y) && fabs(v.x) >= fabs(v.z) && fabs(v.x >= v.w)) { + return 0; + } + if(fabs(v.y) >= fabs(v.z) && fabs(v.y) >= fabs(v.w)) { + return 1; + } + if(fabs(v.z) >= fabs(v.w)) { + return 2; + } + return 3; +} + +inline Vector4 proj_axis(const Vector4 &v, const Vector4 &axis) +{ + return axis * dot(v, axis); +} + + +inline Vector4 rotate(const Vector4 &v, const Quaternion &q) +{ + return v; // TODO +} + +inline Vector4 rotate(const Vector4 &v, const Vector4 &axis, float angle) +{ + return v; // TODO +} + +inline Vector4 rotate(const Vector4 &v, const Vector4 &euler) +{ + return v; // TODO +} -- 1.7.10.4