From 9a5958d353db8da50e5982989e84e38d3dc78f6c Mon Sep 17 00:00:00 2001 From: neobrain Date: Thu, 25 Jul 2013 14:54:53 +0200 Subject: [PATCH] GPU/Math3D: Add a Vec4 class. --- GPU/Math3D.cpp | 53 ++++++++++++++++++++ GPU/Math3D.h | 131 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 184 insertions(+) diff --git a/GPU/Math3D.cpp b/GPU/Math3D.cpp index 6570a9201c..f65884835a 100644 --- a/GPU/Math3D.cpp +++ b/GPU/Math3D.cpp @@ -68,3 +68,56 @@ float Vec3::Normalize() (*this) = (*this)/len; return len; } + +template<> +Vec4 Vec4::FromRGBA(unsigned int rgba) +{ + return Vec4((rgba & 0xFF) * (1.0f/255.0f), + ((rgba >> 8) & 0xFF) * (1.0f/255.0f), + ((rgba >> 16) & 0xFF) * (1.0f/255.0f), + ((rgba >> 24) & 0xFF) * (1.0f/255.0f)); +} + +template<> +Vec4 Vec4::FromRGBA(unsigned int rgba) +{ + return Vec4(rgba & 0xFF, (rgba >> 8) & 0xFF, (rgba >> 16) & 0xFF, (rgba >> 24) & 0xFF); +} + +template<> +float Vec4::Length() const +{ + return sqrtf(Length2()); +} + +template<> +void Vec4::SetLength(const float l) +{ + (*this) *= l / Length(); +} + +template<> +Vec4 Vec4::WithLength(const float l) const +{ + return (*this) * l / Length(); +} + +template<> +float Vec4::Distance2To(Vec4 &other) +{ + return Vec4(other-(*this)).Length2(); +} + +template<> +Vec4 Vec4::Normalized() const +{ + return (*this) / Length(); +} + +template<> +float Vec4::Normalize() +{ + float len = Length(); + (*this) = (*this)/len; + return len; +} diff --git a/GPU/Math3D.h b/GPU/Math3D.h index bf759dcf5f..447aa81083 100644 --- a/GPU/Math3D.h +++ b/GPU/Math3D.h @@ -158,6 +158,131 @@ Vec3 operator * (const V& f, const Vec3& vec) typedef Vec3 Vec3f; +template +class Vec4 +{ +public: + struct + { + T x,y,z,w; + }; + + T* AsArray() { return &x; } + + Vec4() {} + Vec4(const T a[4]) : x(a[0]), y(a[1]), z(a[2]), w(a[3]) {} + Vec4(const T& _x, const T& _y, const T& _z, const T& _w) : x(_x), y(_y), z(_z), w(_w) {} + + // Only implemented for T=int and T=float + static Vec4 FromRGBA(unsigned int rgba); + + static Vec4 AssignToAll(const T& f) + { + return Vec4(f, f, f, f); + } + + void Write(T a[4]) + { + a[0] = x; a[1] = y; a[2] = z; a[3] = w; + } + + Vec4 operator +(const Vec4& other) const + { + return Vec4(x+other.x, y+other.y, z+other.z, w+other.w); + } + void operator += (const Vec4& other) + { + x+=other.x; y+=other.y; z+=other.z; w+=other.w; + } + Vec4 operator -(const Vec4 &other) const + { + return Vec4(x-other.x, y-other.y, z-other.z, w-other.w); + } + void operator -= (const Vec4 &other) + { + x-=other.x; y-=other.y; z-=other.z; w-=other.w; + } + Vec4 operator -() const + { + return Vec4(-x,-y,-z,-w); + } + Vec4 Mul(const Vec4 &other) const + { + return Vec4(x*other.x, y*other.y, z*other.z, w*other.w); + } + template + Vec4 operator * (const V& f) const + { + return Vec4(x*f,y*f,z*f,w*f); + } + template + void operator *= (const V& f) + { + x*=f; y*=f; z*=f; w*=f; + } + template + Vec4 operator / (const V& f) const + { + return Vec4(x/f,y/f,z/f,w/f); + } + template + void operator /= (const V& f) + { + *this = *this / f; + } + + T Length2() const + { + return x*x + y*y + z*z + w*w; + } + + // Only implemented for T=float + float Length() const; + void SetLength(const float l); + Vec4 WithLength(const float l) const; + float Distance2To(Vec4 &other); + Vec4 Normalized() const; + float Normalize(); // returns the previous length, which is often useful + + T& operator [] (int i) //allow vector[2] = 3 (vector.z=3) + { + return *((&x) + i); + } + T operator [] (const int i) const + { + return *((&x) + i); + } + + Vec4 Lerp(const Vec4 &other, const float t) const + { + return (*this)*(1-t) + other*t; + } + + void SetZero() + { + x=0; y=0; z=0; + } + + // Common alias: RGBA (colors) + T& r() { return x; } + T& g() { return y; } + T& b() { return z; } + T& a() { return w; } + + const T& r() const { return x; } + const T& g() const { return y; } + const T& b() const { return z; } + const T& a() const { return w; } +}; + +template +Vec4 operator * (const V& f, const Vec4& vec) +{ + return Vec4(f*vec.x,f*vec.y,f*vec.z,f*vec.w); +} + +typedef Vec4 Vec4f; + inline void Vec3ByMatrix43(float vecOut[3], const float v[3], const float m[12]) { vecOut[0] = v[0] * m[0] + v[1] * m[3] + v[2] * m[6] + m[9]; @@ -183,6 +308,12 @@ inline T Dot(const Vec3& a, const Vec3& b) return a.x*b.x + a.y*b.y + a.z*b.z; } +template +inline T Dot(const Vec4& a, const Vec4& b) +{ + return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; +} + template inline Vec3 Cross(const Vec3& a, const Vec3& b) {