#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);
}