From bdeb1048917667c00f540c17f397443e8f6f76bf Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 29 Dec 2015 10:42:16 +0200 Subject: [PATCH] initial commit --- .gitignore | 6 ++ Makefile | 85 +++++++++++++++++ src/gmath.h | 7 ++ src/matrix.h | 58 +++++++++++ src/quat.h | 19 ++++ src/ray.h | 54 +++++++++++ src/swizzle.h | 135 ++++++++++++++++++++++++++ src/vector.cc | 37 +++++++ src/vector.h | 113 ++++++++++++++++++++++ src/vector.inl | 292 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 806 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 src/gmath.h create mode 100644 src/matrix.h create mode 100644 src/quat.h create mode 100644 src/ray.h create mode 100644 src/swizzle.h create mode 100644 src/vector.cc create mode 100644 src/vector.h create mode 100644 src/vector.inl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..54ebde8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.o +*.d +*.swp +*.so +*.so.* +*.a diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..315b7df --- /dev/null +++ b/Makefile @@ -0,0 +1,85 @@ +# build options +PREFIX ?= /usr/local +warn_flags = -pedantic -Wall +opt_flags = -O0 +dbg_flags = -g +# ------------- +name = gmath +so_major = 0 +so_minor = 1 + +rootdir ?= . +ccsrc = $(wildcard $(rootdir)/src/*.cc) +obj = $(ccsrc:.cc=.o) $(csrc:.c=.o) +dep = $(obj:.o=.d) + +CFLAGS = $(warn_flags) $(opt_flags) $(dbg_flags) $(pic) +CXXFLAGS = $(warn_flags) $(opt_flags) $(dbg_flags) $(pic) + +sys = $(shell uname -s | sed 's/MINGW.*/MINGW/') +ifeq ($(sys), Darwin) + alib = lib$(name).a + solib = lib$(name).dylib + shared = -dynamiclib + +else ifeq ($(sys), MINGW) + alib = $(name).lib + solib = $(name).dll + shared = -shared + +else + alib = lib$(name).a + solib = lib$(name).so.$(so_major).$(so_minor) + soname = lib$(name).so.$(so_major) + ldname = lib$(name).so + shared = -shared -Wl,-soname=$(soname) + pic = -fPIC +endif + +.PHONY: all +all: $(alib) $(solib) + +$(alib): $(obj) Makefile + $(AR) rcs $@ $(obj) + +$(solib): $(obj) Makefile + $(CXX) -o $@ $(shared) $(obj) $(LDFLAGS) + [ -n "$(soname)" ] && \ + rm -f $(soname) $(ldname) && \ + ln -s $(solib) $(soname) && \ + ln -s $(soname) $(ldname) || true + +-include $(dep) + +%.d: %.c + @$(CPP) $(CFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +%.d: %.cc + @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(alib) $(solib) + +.PHONY: cleandep +cleandep: + rm -f $(dep) + +.PHONY: install +install: $(alib) $(solib) + mkdir -p $(DESTDIR)$(PREFIX)/include/$(name) $(DESTDIR)$(PREFIX)/lib + cp src/*.h src/*.inl $(DESTDIR)$(PREFIX)/include/$(name)/ + cp $(alib) $(DESTDIR)$(PREFIX)/lib/$(alib) + cp $(solib) $(DESTDIR)$(PREFIX)/lib/$(solib) + [ -n "$(soname)" ] && \ + rm -f $(DESTDIR)$(PREFIX)/lib/$(soname) $(DESTDIR)$(PREFIX)/lib/$(ldname) && \ + cp $(soname) $(DESTDIR)$(PREFIX)/lib/$(soname) && \ + cp $(ldname) $(DESTDIR)$(PREFIX)/lib/$(ldname) || true + +.PHONY: uninstall +uninstall: + rm -f $(DESTDIR)$(PREFIX)/include/$(name)/*.h $(DESTDIR)$(PREFIX)/include/$(name)/*.inl + rm -f $(DESTDIR)$(PREFIX)/lib/$(solib) + [ -n "$(soname)" ] && \ + rm -f $(DESTDIR)$(PREFIX)/lib/$(soname) && \ + rm -f $(DESTDIR)$(PREFIX)/lib/$(ldname) || true diff --git a/src/gmath.h b/src/gmath.h new file mode 100644 index 0000000..6e1cde3 --- /dev/null +++ b/src/gmath.h @@ -0,0 +1,7 @@ +#ifndef GMATH_H_ +#define GMATH_H_ + +#include "vector.h" +#include "matrix.h" + +#endif // GMATH_H_ diff --git a/src/matrix.h b/src/matrix.h new file mode 100644 index 0000000..f5dbaa9 --- /dev/null +++ b/src/matrix.h @@ -0,0 +1,58 @@ +#ifndef GMATH_MATRIX_H_ +#define GMATH_MATRIX_H_ + +#include +#include "vector.h" + +namespace gph { + +class Matrix4x4 { +private: + float m[4][4]; + +public: + static Matrix4x4 identity; + + Matrix4x4() + { + memcpy((float*)m, (const float*)identity.m, 16 * sizeof(float)); + } + + Matrix4x4(const float *m) + { + memcpy((float*)this->m, (const float*)m, 16 * sizeof(float)); + } + + Matrix4x4(float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33) + { + m[0][0] = m00; m[0][1] = m01; m[0][2] = m02; m[0][3] = m03; + m[1][0] = m10; m[1][1] = m11; m[1][2] = m12; m[1][3] = m13; + m[2][0] = m20; m[2][1] = m21; m[2][2] = m22; m[2][3] = m23; + m[3][0] = m30; m[3][1] = m31; m[3][2] = m32; m[3][3] = m33; + } + + Matrix4x4(const Vector4 &v0, const Vector4 &v1, const Vector4 &v2, const Vector4 &v3) + { + m[0][0] = v0.x; m[0][1] = v0.y; m[0][2] = v0.z; m[0][3] = v0.w; + m[1][0] = v1.x; m[1][1] = v1.y; m[1][2] = v1.z; m[1][3] = v1.w; + m[2][0] = v2.x; m[2][1] = v2.y; m[2][2] = v2.z; m[2][3] = v2.w; + m[3][0] = v3.x; m[3][1] = v3.y; m[3][2] = v3.z; m[3][3] = v3.w; + } + + float *operator [](int idx) + { + return m[idx]; + } + + const float *operator [](int idx) const + { + return m[idx]; + } +}; + +} // namespace gph + +#endif // GMATH_MATRIX_H_ diff --git a/src/quat.h b/src/quat.h new file mode 100644 index 0000000..4b71c7c --- /dev/null +++ b/src/quat.h @@ -0,0 +1,19 @@ +#ifndef QUATERNION_H_ +#define QUATERNION_H_ + +namespace gph { + +class Quaternion { +public: + float x, y, z, w; // w + xi + yj + zk + + Quaternion() : x(0), y(0), z(0), w(1) {} + Quaternion(float x_, float y_, float z_, float w_) : x(x_), y(y_), z(z_), w(w_) {} + Quaternion(const Vector3 &v, float s) : x(v.x), y(v.y), z(v.z), w(s) {} + + // TODO more +}; + +} // namespace gph + +#endif // QUATERNION_H_ diff --git a/src/ray.h b/src/ray.h new file mode 100644 index 0000000..2574036 --- /dev/null +++ b/src/ray.h @@ -0,0 +1,54 @@ +#ifndef GMATH_RAY_H_ +#define GMATH_RAY_H_ + +#include "vector.h" +#include "matrix.h" + +namespace gph { + +class Ray { +public: + Vector3 origin, dir; + + Ray() : dir(0, 0, 1) {} + Ray(const Vector3 &o, const Vector3 &d) : o(origin), d(dir) {} +}; + +inline Ray operator *(const Ray &r, const Matrix4x4 &m) +{ + Matrix4x4 up = 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); +} + +inline Ray operator *(const Matrix4x4 &m, const Ray &r) +{ + Matrix4x4 up = 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(m * origin, m * dir); +} + + +inline Ray reflect(const Ray &ray, const Vector3 &n) +{ + return Ray(ray.origin, reflect(ray.dir, n)); +} + +inline Ray refract(const Ray &ray, const Vector3 &n, float ior) +{ + return Ray(ray.origin, refract(ray.dir, n, ior)); +} + +inline Ray refract(const Ray &ray, const Vector3 &n, float from_ior, float to_ior) +{ + return Ray(ray.origin, refract(ray.dir, n, from_ior, to_ior)); +} + + +} + +#endif // GMATH_RAY_H_ diff --git a/src/swizzle.h b/src/swizzle.h new file mode 100644 index 0000000..66d27d5 --- /dev/null +++ b/src/swizzle.h @@ -0,0 +1,135 @@ +// the only function of this file is to hide the swizzle-macro eyesore + +// swizzle macros for Vector2 +#define GPH_VEC2_SWIZZLE \ + GPH_SWIZZLE2(Vector2, x, x) GPH_SWIZZLE2(Vector2, x, y) \ + GPH_SWIZZLE2(Vector2, y, x) GPH_SWIZZLE2(Vector2, y, y) + +// swizzle macros for Vector3 +#define GPH_VEC3_SWIZZLE \ + GPH_SWIZZLE2(Vector3, x, x) GPH_SWIZZLE2(Vector3, x, y) GPH_SWIZZLE2(Vector3, x, z) \ + GPH_SWIZZLE2(Vector3, y, x) GPH_SWIZZLE2(Vector3, y, y) GPH_SWIZZLE2(Vector3, y, z) \ + GPH_SWIZZLE2(Vector3, z, x) GPH_SWIZZLE2(Vector3, z, y) GPH_SWIZZLE2(Vector3, z, z) \ + GPH_SWIZZLE3(Vector3, x, x, x) GPH_SWIZZLE3(Vector3, x, x, y) GPH_SWIZZLE3(Vector3, x, x, z) \ + GPH_SWIZZLE3(Vector3, x, y, x) GPH_SWIZZLE3(Vector3, x, y, y) GPH_SWIZZLE3(Vector3, x, y, z) \ + GPH_SWIZZLE3(Vector3, x, z, x) GPH_SWIZZLE3(Vector3, x, z, y) GPH_SWIZZLE3(Vector3, x, z, z) \ + GPH_SWIZZLE3(Vector3, y, x, x) GPH_SWIZZLE3(Vector3, y, x, y) GPH_SWIZZLE3(Vector3, y, x, z) \ + GPH_SWIZZLE3(Vector3, y, y, x) GPH_SWIZZLE3(Vector3, y, y, y) GPH_SWIZZLE3(Vector3, y, y, z) \ + GPH_SWIZZLE3(Vector3, y, z, x) GPH_SWIZZLE3(Vector3, y, z, y) GPH_SWIZZLE3(Vector3, y, z, z) \ + GPH_SWIZZLE3(Vector3, z, x, x) GPH_SWIZZLE3(Vector3, z, x, y) GPH_SWIZZLE3(Vector3, z, x, z) \ + GPH_SWIZZLE3(Vector3, z, y, x) GPH_SWIZZLE3(Vector3, z, y, y) GPH_SWIZZLE3(Vector3, z, y, z) \ + GPH_SWIZZLE3(Vector3, z, z, x) GPH_SWIZZLE3(Vector3, z, z, y) GPH_SWIZZLE3(Vector3, z, z, z) \ + GPH_SWIZZLE4(Vector3, x, x, x, x) GPH_SWIZZLE4(Vector3, x, x, x, y) GPH_SWIZZLE4(Vector3, x, x, x, z) \ + GPH_SWIZZLE4(Vector3, x, x, y, x) GPH_SWIZZLE4(Vector3, x, x, y, y) GPH_SWIZZLE4(Vector3, x, x, y, z) \ + GPH_SWIZZLE4(Vector3, x, x, z, x) GPH_SWIZZLE4(Vector3, x, x, z, y) GPH_SWIZZLE4(Vector3, x, x, z, z) \ + GPH_SWIZZLE4(Vector3, x, y, x, x) GPH_SWIZZLE4(Vector3, x, y, x, y) GPH_SWIZZLE4(Vector3, x, y, x, z) \ + GPH_SWIZZLE4(Vector3, x, y, y, x) GPH_SWIZZLE4(Vector3, x, y, y, y) GPH_SWIZZLE4(Vector3, x, y, y, z) \ + GPH_SWIZZLE4(Vector3, x, y, z, x) GPH_SWIZZLE4(Vector3, x, y, z, y) GPH_SWIZZLE4(Vector3, x, y, z, z) \ + GPH_SWIZZLE4(Vector3, x, z, x, x) GPH_SWIZZLE4(Vector3, x, z, x, y) GPH_SWIZZLE4(Vector3, x, z, x, z) \ + GPH_SWIZZLE4(Vector3, x, z, y, x) GPH_SWIZZLE4(Vector3, x, z, y, y) GPH_SWIZZLE4(Vector3, x, z, y, z) \ + GPH_SWIZZLE4(Vector3, x, z, z, x) GPH_SWIZZLE4(Vector3, x, z, z, y) GPH_SWIZZLE4(Vector3, x, z, z, z) \ + GPH_SWIZZLE4(Vector3, y, x, x, x) GPH_SWIZZLE4(Vector3, y, x, x, y) GPH_SWIZZLE4(Vector3, y, x, x, z) \ + GPH_SWIZZLE4(Vector3, y, x, y, x) GPH_SWIZZLE4(Vector3, y, x, y, y) GPH_SWIZZLE4(Vector3, y, x, y, z) \ + GPH_SWIZZLE4(Vector3, y, x, z, x) GPH_SWIZZLE4(Vector3, y, x, z, y) GPH_SWIZZLE4(Vector3, y, x, z, z) \ + GPH_SWIZZLE4(Vector3, y, y, x, x) GPH_SWIZZLE4(Vector3, y, y, x, y) GPH_SWIZZLE4(Vector3, y, y, x, z) \ + GPH_SWIZZLE4(Vector3, y, y, y, x) GPH_SWIZZLE4(Vector3, y, y, y, y) GPH_SWIZZLE4(Vector3, y, y, y, z) \ + GPH_SWIZZLE4(Vector3, y, y, z, x) GPH_SWIZZLE4(Vector3, y, y, z, y) GPH_SWIZZLE4(Vector3, y, y, z, z) \ + GPH_SWIZZLE4(Vector3, y, z, x, x) GPH_SWIZZLE4(Vector3, y, z, x, y) GPH_SWIZZLE4(Vector3, y, z, x, z) \ + GPH_SWIZZLE4(Vector3, y, z, y, x) GPH_SWIZZLE4(Vector3, y, z, y, y) GPH_SWIZZLE4(Vector3, y, z, y, z) \ + GPH_SWIZZLE4(Vector3, y, z, z, x) GPH_SWIZZLE4(Vector3, y, z, z, y) GPH_SWIZZLE4(Vector3, y, z, z, z) \ + GPH_SWIZZLE4(Vector3, z, x, x, x) GPH_SWIZZLE4(Vector3, z, x, x, y) GPH_SWIZZLE4(Vector3, z, x, x, z) \ + GPH_SWIZZLE4(Vector3, z, x, y, x) GPH_SWIZZLE4(Vector3, z, x, y, y) GPH_SWIZZLE4(Vector3, z, x, y, z) \ + GPH_SWIZZLE4(Vector3, z, x, z, x) GPH_SWIZZLE4(Vector3, z, x, z, y) GPH_SWIZZLE4(Vector3, z, x, z, z) \ + GPH_SWIZZLE4(Vector3, z, y, x, x) GPH_SWIZZLE4(Vector3, z, y, x, y) GPH_SWIZZLE4(Vector3, z, y, x, z) \ + GPH_SWIZZLE4(Vector3, z, y, y, x) GPH_SWIZZLE4(Vector3, z, y, y, y) GPH_SWIZZLE4(Vector3, z, y, y, z) \ + GPH_SWIZZLE4(Vector3, z, y, z, x) GPH_SWIZZLE4(Vector3, z, y, z, y) GPH_SWIZZLE4(Vector3, z, y, z, z) \ + GPH_SWIZZLE4(Vector3, z, z, x, x) GPH_SWIZZLE4(Vector3, z, z, x, y) GPH_SWIZZLE4(Vector3, z, z, x, z) \ + GPH_SWIZZLE4(Vector3, z, z, y, x) GPH_SWIZZLE4(Vector3, z, z, y, y) GPH_SWIZZLE4(Vector3, z, z, y, z) \ + GPH_SWIZZLE4(Vector3, z, z, z, x) GPH_SWIZZLE4(Vector3, z, z, z, y) GPH_SWIZZLE4(Vector3, z, z, z, z) + +// swizzle macros for Vector4 (oh shit...) +#define GPH_VEC4_SWIZZLE \ + GPH_SWIZZLE2(Vector4, x, x) GPH_SWIZZLE2(Vector4, x, y) GPH_SWIZZLE2(Vector4, x, z) GPH_SWIZZLE2(Vector4, x, w) \ + GPH_SWIZZLE2(Vector4, y, x) GPH_SWIZZLE2(Vector4, y, y) GPH_SWIZZLE2(Vector4, y, z) GPH_SWIZZLE2(Vector4, y, w) \ + GPH_SWIZZLE2(Vector4, z, x) GPH_SWIZZLE2(Vector4, z, y) GPH_SWIZZLE2(Vector4, z, z) GPH_SWIZZLE2(Vector4, z, w) \ + GPH_SWIZZLE2(Vector4, w, x) GPH_SWIZZLE2(Vector4, w, y) GPH_SWIZZLE2(Vector4, w, z) GPH_SWIZZLE2(Vector4, w, w) \ + GPH_SWIZZLE3(Vector4, x, x, x) GPH_SWIZZLE3(Vector4, x, x, y) GPH_SWIZZLE3(Vector4, x, x, z) GPH_SWIZZLE3(Vector4, x, x, w) \ + GPH_SWIZZLE3(Vector4, x, y, x) GPH_SWIZZLE3(Vector4, x, y, y) GPH_SWIZZLE3(Vector4, x, y, z) GPH_SWIZZLE3(Vector4, x, y, w) \ + GPH_SWIZZLE3(Vector4, x, z, x) GPH_SWIZZLE3(Vector4, x, z, y) GPH_SWIZZLE3(Vector4, x, z, z) GPH_SWIZZLE3(Vector4, x, z, w) \ + GPH_SWIZZLE3(Vector4, x, w, x) GPH_SWIZZLE3(Vector4, x, w, y) GPH_SWIZZLE3(Vector4, x, w, z) GPH_SWIZZLE3(Vector4, x, w, w) \ + GPH_SWIZZLE3(Vector4, y, x, x) GPH_SWIZZLE3(Vector4, y, x, y) GPH_SWIZZLE3(Vector4, y, x, z) GPH_SWIZZLE3(Vector4, y, x, w) \ + GPH_SWIZZLE3(Vector4, y, y, x) GPH_SWIZZLE3(Vector4, y, y, y) GPH_SWIZZLE3(Vector4, y, y, z) GPH_SWIZZLE3(Vector4, y, y, w) \ + GPH_SWIZZLE3(Vector4, y, z, x) GPH_SWIZZLE3(Vector4, y, z, y) GPH_SWIZZLE3(Vector4, y, z, z) GPH_SWIZZLE3(Vector4, y, z, w) \ + GPH_SWIZZLE3(Vector4, y, w, x) GPH_SWIZZLE3(Vector4, y, w, y) GPH_SWIZZLE3(Vector4, y, w, z) GPH_SWIZZLE3(Vector4, y, w, w) \ + GPH_SWIZZLE3(Vector4, z, x, x) GPH_SWIZZLE3(Vector4, z, x, y) GPH_SWIZZLE3(Vector4, z, x, z) GPH_SWIZZLE3(Vector4, z, x, w) \ + GPH_SWIZZLE3(Vector4, z, y, x) GPH_SWIZZLE3(Vector4, z, y, y) GPH_SWIZZLE3(Vector4, z, y, z) GPH_SWIZZLE3(Vector4, z, y, w) \ + GPH_SWIZZLE3(Vector4, z, z, x) GPH_SWIZZLE3(Vector4, z, z, y) GPH_SWIZZLE3(Vector4, z, z, z) GPH_SWIZZLE3(Vector4, z, z, w) \ + GPH_SWIZZLE3(Vector4, z, w, x) GPH_SWIZZLE3(Vector4, z, w, y) GPH_SWIZZLE3(Vector4, z, w, z) GPH_SWIZZLE3(Vector4, z, w, w) \ + GPH_SWIZZLE3(Vector4, w, x, x) GPH_SWIZZLE3(Vector4, w, x, y) GPH_SWIZZLE3(Vector4, w, x, z) GPH_SWIZZLE3(Vector4, w, x, w) \ + GPH_SWIZZLE3(Vector4, w, y, x) GPH_SWIZZLE3(Vector4, w, y, y) GPH_SWIZZLE3(Vector4, w, y, z) GPH_SWIZZLE3(Vector4, w, y, w) \ + GPH_SWIZZLE3(Vector4, w, z, x) GPH_SWIZZLE3(Vector4, w, z, y) GPH_SWIZZLE3(Vector4, w, z, z) GPH_SWIZZLE3(Vector4, w, z, w) \ + GPH_SWIZZLE3(Vector4, w, w, x) GPH_SWIZZLE3(Vector4, w, w, y) GPH_SWIZZLE3(Vector4, w, w, z) GPH_SWIZZLE3(Vector4, w, w, w) \ + GPH_SWIZZLE4(Vector4, x, x, x, x) GPH_SWIZZLE4(Vector4, x, x, x, y) GPH_SWIZZLE4(Vector4, x, x, x, z) GPH_SWIZZLE4(Vector4, x, x, x, w) \ + GPH_SWIZZLE4(Vector4, x, x, y, x) GPH_SWIZZLE4(Vector4, x, x, y, y) GPH_SWIZZLE4(Vector4, x, x, y, z) GPH_SWIZZLE4(Vector4, x, x, y, w) \ + GPH_SWIZZLE4(Vector4, x, x, z, x) GPH_SWIZZLE4(Vector4, x, x, z, y) GPH_SWIZZLE4(Vector4, x, x, z, z) GPH_SWIZZLE4(Vector4, x, x, z, w) \ + GPH_SWIZZLE4(Vector4, x, x, w, x) GPH_SWIZZLE4(Vector4, x, x, w, y) GPH_SWIZZLE4(Vector4, x, x, w, z) GPH_SWIZZLE4(Vector4, x, x, w, w) \ + GPH_SWIZZLE4(Vector4, x, y, x, x) GPH_SWIZZLE4(Vector4, x, y, x, y) GPH_SWIZZLE4(Vector4, x, y, x, z) GPH_SWIZZLE4(Vector4, x, y, x, w) \ + GPH_SWIZZLE4(Vector4, x, y, y, x) GPH_SWIZZLE4(Vector4, x, y, y, y) GPH_SWIZZLE4(Vector4, x, y, y, z) GPH_SWIZZLE4(Vector4, x, y, y, w) \ + GPH_SWIZZLE4(Vector4, x, y, z, x) GPH_SWIZZLE4(Vector4, x, y, z, y) GPH_SWIZZLE4(Vector4, x, y, z, z) GPH_SWIZZLE4(Vector4, x, y, z, w) \ + GPH_SWIZZLE4(Vector4, x, y, w, x) GPH_SWIZZLE4(Vector4, x, y, w, y) GPH_SWIZZLE4(Vector4, x, y, w, z) GPH_SWIZZLE4(Vector4, x, y, w, w) \ + GPH_SWIZZLE4(Vector4, x, z, x, x) GPH_SWIZZLE4(Vector4, x, z, x, y) GPH_SWIZZLE4(Vector4, x, z, x, z) GPH_SWIZZLE4(Vector4, x, z, x, w) \ + GPH_SWIZZLE4(Vector4, x, z, y, x) GPH_SWIZZLE4(Vector4, x, z, y, y) GPH_SWIZZLE4(Vector4, x, z, y, z) GPH_SWIZZLE4(Vector4, x, z, y, w) \ + GPH_SWIZZLE4(Vector4, x, z, z, x) GPH_SWIZZLE4(Vector4, x, z, z, y) GPH_SWIZZLE4(Vector4, x, z, z, z) GPH_SWIZZLE4(Vector4, x, z, z, w) \ + GPH_SWIZZLE4(Vector4, x, z, w, x) GPH_SWIZZLE4(Vector4, x, z, w, y) GPH_SWIZZLE4(Vector4, x, z, w, z) GPH_SWIZZLE4(Vector4, x, z, w, w) \ + GPH_SWIZZLE4(Vector4, x, w, x, x) GPH_SWIZZLE4(Vector4, x, w, x, y) GPH_SWIZZLE4(Vector4, x, w, x, z) GPH_SWIZZLE4(Vector4, x, w, x, w) \ + GPH_SWIZZLE4(Vector4, x, w, y, x) GPH_SWIZZLE4(Vector4, x, w, y, y) GPH_SWIZZLE4(Vector4, x, w, y, z) GPH_SWIZZLE4(Vector4, x, w, y, w) \ + GPH_SWIZZLE4(Vector4, x, w, z, x) GPH_SWIZZLE4(Vector4, x, w, z, y) GPH_SWIZZLE4(Vector4, x, w, z, z) GPH_SWIZZLE4(Vector4, x, w, z, w) \ + GPH_SWIZZLE4(Vector4, x, w, w, x) GPH_SWIZZLE4(Vector4, x, w, w, y) GPH_SWIZZLE4(Vector4, x, w, w, z) GPH_SWIZZLE4(Vector4, x, w, w, w) \ + GPH_SWIZZLE4(Vector4, y, x, x, x) GPH_SWIZZLE4(Vector4, y, x, x, y) GPH_SWIZZLE4(Vector4, y, x, x, z) GPH_SWIZZLE4(Vector4, y, x, x, w) \ + GPH_SWIZZLE4(Vector4, y, x, y, x) GPH_SWIZZLE4(Vector4, y, x, y, y) GPH_SWIZZLE4(Vector4, y, x, y, z) GPH_SWIZZLE4(Vector4, y, x, y, w) \ + GPH_SWIZZLE4(Vector4, y, x, z, x) GPH_SWIZZLE4(Vector4, y, x, z, y) GPH_SWIZZLE4(Vector4, y, x, z, z) GPH_SWIZZLE4(Vector4, y, x, z, w) \ + GPH_SWIZZLE4(Vector4, y, x, w, x) GPH_SWIZZLE4(Vector4, y, x, w, y) GPH_SWIZZLE4(Vector4, y, x, w, z) GPH_SWIZZLE4(Vector4, y, x, w, w) \ + GPH_SWIZZLE4(Vector4, y, y, x, x) GPH_SWIZZLE4(Vector4, y, y, x, y) GPH_SWIZZLE4(Vector4, y, y, x, z) GPH_SWIZZLE4(Vector4, y, y, x, w) \ + GPH_SWIZZLE4(Vector4, y, y, y, x) GPH_SWIZZLE4(Vector4, y, y, y, y) GPH_SWIZZLE4(Vector4, y, y, y, z) GPH_SWIZZLE4(Vector4, y, y, y, w) \ + GPH_SWIZZLE4(Vector4, y, y, z, x) GPH_SWIZZLE4(Vector4, y, y, z, y) GPH_SWIZZLE4(Vector4, y, y, z, z) GPH_SWIZZLE4(Vector4, y, y, z, w) \ + GPH_SWIZZLE4(Vector4, y, y, w, x) GPH_SWIZZLE4(Vector4, y, y, w, y) GPH_SWIZZLE4(Vector4, y, y, w, z) GPH_SWIZZLE4(Vector4, y, y, w, w) \ + GPH_SWIZZLE4(Vector4, y, z, x, x) GPH_SWIZZLE4(Vector4, y, z, x, y) GPH_SWIZZLE4(Vector4, y, z, x, z) GPH_SWIZZLE4(Vector4, y, z, x, w) \ + GPH_SWIZZLE4(Vector4, y, z, y, x) GPH_SWIZZLE4(Vector4, y, z, y, y) GPH_SWIZZLE4(Vector4, y, z, y, z) GPH_SWIZZLE4(Vector4, y, z, y, w) \ + GPH_SWIZZLE4(Vector4, y, z, z, x) GPH_SWIZZLE4(Vector4, y, z, z, y) GPH_SWIZZLE4(Vector4, y, z, z, z) GPH_SWIZZLE4(Vector4, y, z, z, w) \ + GPH_SWIZZLE4(Vector4, y, z, w, x) GPH_SWIZZLE4(Vector4, y, z, w, y) GPH_SWIZZLE4(Vector4, y, z, w, z) GPH_SWIZZLE4(Vector4, y, z, w, w) \ + GPH_SWIZZLE4(Vector4, y, w, x, x) GPH_SWIZZLE4(Vector4, y, w, x, y) GPH_SWIZZLE4(Vector4, y, w, x, z) GPH_SWIZZLE4(Vector4, y, w, x, w) \ + GPH_SWIZZLE4(Vector4, y, w, y, x) GPH_SWIZZLE4(Vector4, y, w, y, y) GPH_SWIZZLE4(Vector4, y, w, y, z) GPH_SWIZZLE4(Vector4, y, w, y, w) \ + GPH_SWIZZLE4(Vector4, y, w, z, x) GPH_SWIZZLE4(Vector4, y, w, z, y) GPH_SWIZZLE4(Vector4, y, w, z, z) GPH_SWIZZLE4(Vector4, y, w, z, w) \ + GPH_SWIZZLE4(Vector4, y, w, w, x) GPH_SWIZZLE4(Vector4, y, w, w, y) GPH_SWIZZLE4(Vector4, y, w, w, z) GPH_SWIZZLE4(Vector4, y, w, w, w) \ + GPH_SWIZZLE4(Vector4, z, x, x, x) GPH_SWIZZLE4(Vector4, z, x, x, y) GPH_SWIZZLE4(Vector4, z, x, x, z) GPH_SWIZZLE4(Vector4, z, x, x, w) \ + GPH_SWIZZLE4(Vector4, z, x, y, x) GPH_SWIZZLE4(Vector4, z, x, y, y) GPH_SWIZZLE4(Vector4, z, x, y, z) GPH_SWIZZLE4(Vector4, z, x, y, w) \ + GPH_SWIZZLE4(Vector4, z, x, z, x) GPH_SWIZZLE4(Vector4, z, x, z, y) GPH_SWIZZLE4(Vector4, z, x, z, z) GPH_SWIZZLE4(Vector4, z, x, z, w) \ + GPH_SWIZZLE4(Vector4, z, x, w, x) GPH_SWIZZLE4(Vector4, z, x, w, y) GPH_SWIZZLE4(Vector4, z, x, w, z) GPH_SWIZZLE4(Vector4, z, x, w, w) \ + GPH_SWIZZLE4(Vector4, z, y, x, x) GPH_SWIZZLE4(Vector4, z, y, x, y) GPH_SWIZZLE4(Vector4, z, y, x, z) GPH_SWIZZLE4(Vector4, z, y, x, w) \ + GPH_SWIZZLE4(Vector4, z, y, y, x) GPH_SWIZZLE4(Vector4, z, y, y, y) GPH_SWIZZLE4(Vector4, z, y, y, z) GPH_SWIZZLE4(Vector4, z, y, y, w) \ + GPH_SWIZZLE4(Vector4, z, y, z, x) GPH_SWIZZLE4(Vector4, z, y, z, y) GPH_SWIZZLE4(Vector4, z, y, z, z) GPH_SWIZZLE4(Vector4, z, y, z, w) \ + GPH_SWIZZLE4(Vector4, z, y, w, x) GPH_SWIZZLE4(Vector4, z, y, w, y) GPH_SWIZZLE4(Vector4, z, y, w, z) GPH_SWIZZLE4(Vector4, z, y, w, w) \ + GPH_SWIZZLE4(Vector4, z, z, x, x) GPH_SWIZZLE4(Vector4, z, z, x, y) GPH_SWIZZLE4(Vector4, z, z, x, z) GPH_SWIZZLE4(Vector4, z, z, x, w) \ + GPH_SWIZZLE4(Vector4, z, z, y, x) GPH_SWIZZLE4(Vector4, z, z, y, y) GPH_SWIZZLE4(Vector4, z, z, y, z) GPH_SWIZZLE4(Vector4, z, z, y, w) \ + GPH_SWIZZLE4(Vector4, z, z, z, x) GPH_SWIZZLE4(Vector4, z, z, z, y) GPH_SWIZZLE4(Vector4, z, z, z, z) GPH_SWIZZLE4(Vector4, z, z, z, w) \ + GPH_SWIZZLE4(Vector4, z, z, w, x) GPH_SWIZZLE4(Vector4, z, z, w, y) GPH_SWIZZLE4(Vector4, z, z, w, z) GPH_SWIZZLE4(Vector4, z, z, w, w) \ + GPH_SWIZZLE4(Vector4, z, w, x, x) GPH_SWIZZLE4(Vector4, z, w, x, y) GPH_SWIZZLE4(Vector4, z, w, x, z) GPH_SWIZZLE4(Vector4, z, w, x, w) \ + GPH_SWIZZLE4(Vector4, z, w, y, x) GPH_SWIZZLE4(Vector4, z, w, y, y) GPH_SWIZZLE4(Vector4, z, w, y, z) GPH_SWIZZLE4(Vector4, z, w, y, w) \ + GPH_SWIZZLE4(Vector4, z, w, z, x) GPH_SWIZZLE4(Vector4, z, w, z, y) GPH_SWIZZLE4(Vector4, z, w, z, z) GPH_SWIZZLE4(Vector4, z, w, z, w) \ + GPH_SWIZZLE4(Vector4, z, w, w, x) GPH_SWIZZLE4(Vector4, z, w, w, y) GPH_SWIZZLE4(Vector4, z, w, w, z) GPH_SWIZZLE4(Vector4, z, w, w, w) \ + GPH_SWIZZLE4(Vector4, w, x, x, x) GPH_SWIZZLE4(Vector4, w, x, x, y) GPH_SWIZZLE4(Vector4, w, x, x, z) GPH_SWIZZLE4(Vector4, w, x, x, w) \ + GPH_SWIZZLE4(Vector4, w, x, y, x) GPH_SWIZZLE4(Vector4, w, x, y, y) GPH_SWIZZLE4(Vector4, w, x, y, z) GPH_SWIZZLE4(Vector4, w, x, y, w) \ + GPH_SWIZZLE4(Vector4, w, x, z, x) GPH_SWIZZLE4(Vector4, w, x, z, y) GPH_SWIZZLE4(Vector4, w, x, z, z) GPH_SWIZZLE4(Vector4, w, x, z, w) \ + GPH_SWIZZLE4(Vector4, w, x, w, x) GPH_SWIZZLE4(Vector4, w, x, w, y) GPH_SWIZZLE4(Vector4, w, x, w, z) GPH_SWIZZLE4(Vector4, w, x, w, w) \ + GPH_SWIZZLE4(Vector4, w, y, x, x) GPH_SWIZZLE4(Vector4, w, y, x, y) GPH_SWIZZLE4(Vector4, w, y, x, z) GPH_SWIZZLE4(Vector4, w, y, x, w) \ + GPH_SWIZZLE4(Vector4, w, y, y, x) GPH_SWIZZLE4(Vector4, w, y, y, y) GPH_SWIZZLE4(Vector4, w, y, y, z) GPH_SWIZZLE4(Vector4, w, y, y, w) \ + GPH_SWIZZLE4(Vector4, w, y, z, x) GPH_SWIZZLE4(Vector4, w, y, z, y) GPH_SWIZZLE4(Vector4, w, y, z, z) GPH_SWIZZLE4(Vector4, w, y, z, w) \ + GPH_SWIZZLE4(Vector4, w, y, w, x) GPH_SWIZZLE4(Vector4, w, y, w, y) GPH_SWIZZLE4(Vector4, w, y, w, z) GPH_SWIZZLE4(Vector4, w, y, w, w) \ + GPH_SWIZZLE4(Vector4, w, z, x, x) GPH_SWIZZLE4(Vector4, w, z, x, y) GPH_SWIZZLE4(Vector4, w, z, x, z) GPH_SWIZZLE4(Vector4, w, z, x, w) \ + GPH_SWIZZLE4(Vector4, w, z, y, x) GPH_SWIZZLE4(Vector4, w, z, y, y) GPH_SWIZZLE4(Vector4, w, z, y, z) GPH_SWIZZLE4(Vector4, w, z, y, w) \ + GPH_SWIZZLE4(Vector4, w, z, z, x) GPH_SWIZZLE4(Vector4, w, z, z, y) GPH_SWIZZLE4(Vector4, w, z, z, z) GPH_SWIZZLE4(Vector4, w, z, z, w) \ + GPH_SWIZZLE4(Vector4, w, z, w, x) GPH_SWIZZLE4(Vector4, w, z, w, y) GPH_SWIZZLE4(Vector4, w, z, w, z) GPH_SWIZZLE4(Vector4, w, z, w, w) \ + GPH_SWIZZLE4(Vector4, w, w, x, x) GPH_SWIZZLE4(Vector4, w, w, x, y) GPH_SWIZZLE4(Vector4, w, w, x, z) GPH_SWIZZLE4(Vector4, w, w, x, w) \ + GPH_SWIZZLE4(Vector4, w, w, y, x) GPH_SWIZZLE4(Vector4, w, w, y, y) GPH_SWIZZLE4(Vector4, w, w, y, z) GPH_SWIZZLE4(Vector4, w, w, y, w) \ + GPH_SWIZZLE4(Vector4, w, w, z, x) GPH_SWIZZLE4(Vector4, w, w, z, y) GPH_SWIZZLE4(Vector4, w, w, z, z) GPH_SWIZZLE4(Vector4, w, w, z, w) \ + GPH_SWIZZLE4(Vector4, w, w, w, x) GPH_SWIZZLE4(Vector4, w, w, w, y) GPH_SWIZZLE4(Vector4, w, w, w, z) GPH_SWIZZLE4(Vector4, w, w, w, w) diff --git a/src/vector.cc b/src/vector.cc new file mode 100644 index 0000000..4af8dab --- /dev/null +++ b/src/vector.cc @@ -0,0 +1,37 @@ +#include "vector.h" +#include "matrix.h" + +namespace gph { + +Vector2::Vector2(const Vector3 &v) + : x(v.x), y(v.y) +{ +} + +Vector3::Vector3(const Vector4 &v) + : x(v.x), y(v.y), z(v.z) +{ +} + +Vector3 operator *(const Vector3 &v, const Matrix4x4 &m) +{ + float x = v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + m[3][0]; + float y = v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + m[3][1]; + float z = v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + m[3][2]; + return Vector3(x, y, z); +} + +Vector3 operator *(const Matrix4x4 &m, const Vector3 &v) +{ + float x = m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3]; + float y = m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3]; + float z = m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3]; + return Vector3(x, y, z); +} + +Vector4::Vector4(const Vector3 &v) + : x(v.x), y(v.y), z(v.z), w(1.0f) +{ +} + +} // namespace gph diff --git a/src/vector.h b/src/vector.h new file mode 100644 index 0000000..02aeddf --- /dev/null +++ b/src/vector.h @@ -0,0 +1,113 @@ +#ifndef GMATH_VEC_H_ +#define GMATH_VEC_H_ + +#include +#include "swizzle.h" + +namespace gph { + +#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; + +class Vector3; +class Vector4; +class Matrix4x4; +class Quaternion; + +class Vector2 { +public: + float x, y; + + Vector2() : x(0), y(0) {} + Vector2(float x_, float y_) : x(x_), y(y_) {} + Vector2(const Vector3 &v); + + inline void normalize(); + inline float &operator[] (int idx); + inline const float &operator[] (int idx) const; + + GPH_VEC2_SWIZZLE +}; + +class Vector3 { +public: + float x, y, z; + + Vector3() : x(0), y(0), z(0) {} + Vector3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) {} + Vector3(const Vector4 &v); + + inline void normalize(); + inline float &operator[] (int idx); + inline const float &operator[] (int idx) const; + + GPH_VEC3_SWIZZLE +}; + + +class Vector4 { +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); + + inline void normalize(); + inline float &operator[] (int idx); + inline const float &operator[] (int idx) const; + + GPH_VEC4_SWIZZLE +}; + +// ---- Vector3 functions ---- +inline Vector3 operator -(const Vector3 &v); +inline Vector3 operator +(const Vector3 &a, const Vector3 &b); +inline Vector3 operator -(const Vector3 &a, const Vector3 &b); +inline Vector3 operator *(const Vector3 &a, const Vector3 &b); +inline Vector3 operator /(const Vector3 &a, const Vector3 &b); +inline Vector3 operator *(const Vector3 &v, float s); +inline Vector3 operator *(float s, const Vector3 &v); +inline Vector3 operator /(const Vector3 &v, float s); +inline Vector3 operator /(float s, const Vector3 &v); +inline Vector3 &operator +=(Vector3 &a, const Vector3 &b); +inline Vector3 &operator -=(Vector3 &a, const Vector3 &b); +inline Vector3 &operator *=(Vector3 &a, const Vector3 &b); +inline Vector3 &operator /=(Vector3 &a, const Vector3 &b); +inline Vector3 &operator *=(Vector3 &v, float s); +inline Vector3 &operator /=(Vector3 &v, float s); + +Vector3 operator *(const Vector3 &v, const Matrix4x4 &m); +Vector3 operator *(const Matrix4x4 &m, const Vector3 &v); + +inline bool operator ==(const Vector3 &a, const Vector3 &b); +inline bool operator !=(const Vector3 &a, const Vector3 &b); + +inline float dot(const Vector3 &a, const Vector3 &b); +inline Vector3 cross(const Vector3 &a, const Vector3 &b); +inline float length(const Vector3 &v); +inline float length_sq(const Vector3 &v); +inline Vector3 normalize(const Vector3 &v); + +inline Vector3 reflect(const Vector3 &v, const Vector3 &n); +inline Vector3 refract(const Vector3 &v, const Vector3 &n, float ior); +inline Vector3 refract(const Vector3 &v, const Vector3 &n, float from_ior, float to_ior); + +inline float distance(const Vector3 &a, const Vector3 &b); +inline float distance_sq(const Vector3 &a, const Vector3 &b); +inline Vector3 faceforward(const Vector3 &n, const Vector3 &vi, const Vector3 &ng); + +inline Vector3 major(const Vector3 &v); +inline int major_idx(const Vector3 &v); +inline Vector3 proj_axis(const Vector3 &v, const Vector3 &axis); + +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" + +#endif /* GMATH_VEC_H_ */ diff --git a/src/vector.inl b/src/vector.inl new file mode 100644 index 0000000..1aeae0f --- /dev/null +++ b/src/vector.inl @@ -0,0 +1,292 @@ +#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 -- 1.7.10.4