Vector4 inline definitions, and rearrangement into multiple inl files
authorJohn Tsiombikas <nuclear@mutantstargoat.com>
Tue, 29 Dec 2015 10:05:19 +0000 (12:05 +0200)
committerJohn Tsiombikas <nuclear@mutantstargoat.com>
Tue, 29 Dec 2015 10:05:19 +0000 (12:05 +0200)
Makefile
src/gmath.h
src/ray.h
src/vector.cc
src/vector.h
src/vector.inl [deleted file]
src/vector2.inl [new file with mode: 0644]
src/vector3.inl [new file with mode: 0644]
src/vector4.inl [new file with mode: 0644]

index 315b7df..cfbb34d 100644 (file)
--- 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)
index 6e1cde3..14d5eb0 100644 (file)
@@ -3,5 +3,10 @@
 
 #include "vector.h"
 #include "matrix.h"
+#include "ray.h"
+
+#ifndef GPH_NAMESPACE
+using namespace gph;
+#endif
 
 #endif // GMATH_H_
index 2574036..72dfc26 100644 (file)
--- 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_
index 4af8dab..9532ccf 100644 (file)
@@ -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
index 02aeddf..da3b09b 100644 (file)
@@ -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 (file)
index 1aeae0f..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-#include <math.h>
-
-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 (file)
index 0000000..64aa0c4
--- /dev/null
@@ -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 (file)
index 0000000..8f6167c
--- /dev/null
@@ -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 (file)
index 0000000..c37eed1
--- /dev/null
@@ -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
+}