/* Vec3f.inl Written by Matthew Fisher Inline file for a 3-dimensional vector of floats */ #pragma once Vec3f::Vec3f() { } Vec3f::Vec3f(const Vec2f &V, float _z) { x = V.x; y = V.y; z = _z; } Vec3f::Vec3f(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } Vec3f::Vec3f(const Vec3f &V) { x = V.x; y = V.y; z = V.z; } Vec3f::Vec3f(const RGBColor &c) { x = c.r / 255.0f; y = c.g / 255.0f; z = c.b / 255.0f; } __forceinline Vec3f& Vec3f::operator = (const Vec3f &V) { x = V.x; y = V.y; z = V.z; return *this; } __forceinline Vec3f Vec3f::StdRandomVector() { float x, y, z; x = float(rand()) / RAND_MAX * 2.0f - 1.0f; y = float(rand()) / RAND_MAX * 2.0f - 1.0f; z = float(rand()) / RAND_MAX * 2.0f - 1.0f; return Vec3f(x, y, z); } __forceinline Vec3f Vec3f::StdRandomNormal() { return Normalize(StdRandomVector()); } __forceinline float Vec3f::Length() const { return sqrtf(x * x + y * y + z * z); } __forceinline float Vec3f::LengthSq() const { return x * x + y * y + z * z; } __forceinline bool Vec3f::Valid() const { return ((x == x) && (y == y) && (z == z)); } __forceinline Vec3f Vec3f::Normalize(const Vec3f &V) { float Len = V.Length(); if(Len == 0.0f) { return V; } else { float Factor = 1.0f / Len; return Vec3f(V.x * Factor, V.y * Factor, V.z * Factor); } } __forceinline void Vec3f::SetLength(float NewLength) { float Len = Length(); if(Len != 0.0f) { float Factor = NewLength / Len; x *= Factor; y *= Factor; z *= Factor; } } #ifdef USE_D3D __forceinline Vec3f::operator D3DXVECTOR3() const { D3DXVECTOR3 V(x, y, z); return V; } #endif __forceinline float Vec3f::AngleBetween(const Vec3f &Left, const Vec3f &Right) { float LeftLength = Left.Length(); float RightLength = Right.Length(); if(LeftLength > 0.0f && RightLength > 0.0f) { return acosf(Utility::Bound(Vec3f::Dot(Left, Right) / LeftLength / RightLength, -1.0f, 1.0f)); } else { return 0.0f; } } __forceinline Vec3f Vec3f::Cross(const Vec3f &Left, const Vec3f &Right) { Vec3f Result; Result.x = Left.y * Right.z - Left.z * Right.y; Result.y = Left.z * Right.x - Left.x * Right.z; Result.z = Left.x * Right.y - Left.y * Right.x; return Result; } __forceinline float Vec3f::Dot(const Vec3f &Left, const Vec3f &Right) { return (Left.x * Right.x + Left.y * Right.y + Left.z * Right.z); } __forceinline Vec3f Vec3f::DirectProduct(const Vec3f &Left, const Vec3f &Right) { return Vec3f(Left.x * Right.x, Left.y * Right.y, Left.z * Right.z); } __forceinline Vec3f Vec3f::Lerp(const Vec3f &Left, const Vec3f &Right, float s) { return (Left + s * (Right - Left)); } __forceinline Vec3f Vec3f::Maximize(const Vec3f &Left, const Vec3f &Right) { Vec3f Result = Right; if(Left.x > Right.x) Result.x = Left.x; if(Left.y > Right.y) Result.y = Left.y; if(Left.z > Right.z) Result.z = Left.z; return Result; } __forceinline Vec3f Vec3f::Minimize(const Vec3f &Left, const Vec3f &Right) { Vec3f Result = Right; if(Left.x < Right.x) Result.x = Left.x; if(Left.y < Right.y) Result.y = Left.y; if(Left.z < Right.z) Result.z = Left.z; return Result; } __forceinline Vec3f Vec3f::SphericalFromCartesian(const Vec3f &Cartesian) { Vec3f Result; Result.x = Cartesian.Length(); Result.y = atan2f(Cartesian.y, Cartesian.x); if(Result.x == 0.0f) { Result.z = 0.0f; } else { Result.z = acosf(Cartesian.z / Result.x); } return Result; } __forceinline Vec3f Vec3f::CartesianFromSpherical(const Vec3f &Spherical) { const float &r = Spherical.x; const float &Theta = Spherical.y; const float &Phi = Spherical.z; float RSinPhi = r * sinf(Phi); return Vec3f(cosf(Theta) * RSinPhi, sinf(Theta) * RSinPhi, r * cosf(Phi)); } __forceinline bool Vec3f::WithinRect(const Vec3f &Pt, const Rectangle3f &Rect) { return((Pt.x >= Rect.Min.x && Pt.x <= Rect.Max.x) && (Pt.y >= Rect.Min.y && Pt.y <= Rect.Max.y) && (Pt.z >= Rect.Min.z && Pt.z <= Rect.Max.z)); } __forceinline Vec3f Vec3f::LinearMap(const Vec3f &s1, const Vec3f &e1, const Vec3f &s2, const Vec3f &e2, const Vec3f &s) { return Vec3f(float(Math::LinearMap(s1.x, e1.x, s2.x, e2.x, s.x)), float(Math::LinearMap(s1.y, e1.y, s2.y, e2.y, s.y)), float(Math::LinearMap(s1.z, e1.z, s2.z, e2.z, s.z))); } __forceinline void Vec3f::CompleteOrthonormalBasis(const Vec3f &Normal, Vec3f &v1, Vec3f &v2) { Vec3f AxisTest1 = Cross(Normal, Vec3f::eX); Vec3f AxisTest2 = Cross(Normal, Vec3f::eY); if(AxisTest1.Length() >= AxisTest2.Length()) { v1 = Normalize(AxisTest1); } else { v1 = Normalize(AxisTest2); } v2 = Normalize(Cross(v1, Normal)); Math::ReorientBasis(v1, v2, Normal); } __forceinline Vec3f& Vec3f::operator *= (float Right) { x *= Right; y *= Right; z *= Right; return *this; } __forceinline Vec3f& Vec3f::operator /= (float Right) { x /= Right; y /= Right; z /= Right; return *this; } __forceinline Vec3f& Vec3f::operator *= (UINT Right) { x *= Right; y *= Right; z *= Right; return *this; } __forceinline Vec3f& Vec3f::operator /= (UINT Right) { x /= Right; y /= Right; z /= Right; return *this; } __forceinline Vec3f& Vec3f::operator += (const Vec3f &Right) { x += Right.x; y += Right.y; z += Right.z; return *this; } __forceinline Vec3f& Vec3f::operator -= (const Vec3f &Right) { x -= Right.x; y -= Right.y; z -= Right.z; return *this; } __forceinline Vec3f operator * (const Vec3f &Left, float Right) { return Vec3f(Left.x * Right, Left.y * Right, Left.z * Right); } __forceinline Vec3f operator * (float Left, const Vec3f &Right) { return Vec3f(Right.x * Left, Right.y * Left, Right.z * Left); } __forceinline Vec3f operator / (const Vec3f &Left, float Right) { return Vec3f(Left.x / Right, Left.y / Right, Left.z / Right); } __forceinline Vec3f operator + (const Vec3f &Left, const Vec3f &Right) { return Vec3f(Left.x + Right.x, Left.y + Right.y, Left.z + Right.z); } __forceinline Vec3f operator - (const Vec3f &Left, const Vec3f &Right) { return Vec3f(Left.x - Right.x, Left.y - Right.y, Left.z - Right.z); } __forceinline Vec3f operator - (const Vec3f &V) { return Vec3f(-V.x, -V.y, -V.z); } __forceinline float Vec3f::Dist(const Vec3f &Left, const Vec3f &Right) { const float XDiff = Right.x - Left.x; const float YDiff = Right.y - Left.y; const float ZDiff = Right.z - Left.z; return sqrtf(XDiff * XDiff + YDiff * YDiff + ZDiff * ZDiff); } __forceinline float Vec3f::DistSq(const Vec3f &Left, const Vec3f &Right) { const float XDiff = Right.x - Left.x; const float YDiff = Right.y - Left.y; const float ZDiff = Right.z - Left.z; return (XDiff * XDiff + YDiff * YDiff + ZDiff * ZDiff); }