/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Common vector class #pragma once /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // class Vec4_tpl /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// template struct Vec4_tpl { typedef F value_type; enum { component_count = 4 }; F x, y, z, w; #if defined(_DEBUG) ILINE Vec4_tpl() { if (sizeof(F) == 4) { uint32* p = alias_cast(&x); p[0] = F32NAN; p[1] = F32NAN; p[2] = F32NAN; p[3] = F32NAN; } if (sizeof(F) == 8) { uint64* p = alias_cast(&x); p[0] = F64NAN; p[1] = F64NAN; p[2] = F64NAN; p[3] = F64NAN; } } #else ILINE Vec4_tpl() {} #endif template ILINE Vec4_tpl& operator = (const Vec4_tpl& v1) { x = F(v1.x); y = F(v1.y); z = F(v1.z); w = F(v1.w); return (*this); } ILINE Vec4_tpl(F vx, F vy, F vz, F vw) { x = vx; y = vy; z = vz; w = vw; }; ILINE Vec4_tpl(const Vec3_tpl& v, F vw) { x = v.x; y = v.y; z = v.z; w = vw; }; explicit ILINE Vec4_tpl(F m) { x = y = z = w = m; } ILINE Vec4_tpl(type_zero) { x = y = z = w = F(0); } ILINE void operator () (F vx, F vy, F vz, F vw) { x = vx; y = vy; z = vz; w = vw; }; ILINE void operator () (const Vec3_tpl& v, F vw) { x = v.x; y = v.y; z = v.z; vw = vw; }; ILINE F& operator [] (int index) { assert(index >= 0 && index <= 3); return ((F*)this)[index]; } ILINE F operator [] (int index) const { assert(index >= 0 && index <= 3); return ((F*)this)[index]; } template ILINE Vec4_tpl(const Vec4_tpl& v) : x((F)v.x) , y((F)v.y) , z((F)v.z) , w((F)v.w) { assert(this->IsValid()); } ILINE Vec4_tpl& zero() { x = y = z = w = 0; return *this; } ILINE bool IsEquivalent(const Vec4_tpl& v1, F epsilon = VEC_EPSILON) const { assert(v1.IsValid()); assert(this->IsValid()); return ((fabs_tpl(x - v1.x) <= epsilon) && (fabs_tpl(y - v1.y) <= epsilon) && (fabs_tpl(z - v1.z) <= epsilon) && (fabs_tpl(w - v1.w) <= epsilon)); } ILINE Vec4_tpl& operator=(const Vec4_tpl& src) { x = src.x; y = src.y; z = src.z; w = src.w; return *this; } ILINE Vec4_tpl operator * (F k) const { return Vec4_tpl(x * k, y * k, z * k, w * k); } ILINE Vec4_tpl operator / (F k) const { k = (F)1.0 / k; return Vec4_tpl(x * k, y * k, z * k, w * k); } ILINE Vec4_tpl& operator *= (F k) { x *= k; y *= k; z *= k; w *= k; return *this; } ILINE Vec4_tpl& operator /= (F k) { k = (F)1.0 / k; x *= k; y *= k; z *= k; w *= k; return *this; } ILINE void operator += (const Vec4_tpl& v) { x += v.x; y += v.y; z += v.z; w += v.w; } ILINE void operator -= (const Vec4_tpl& v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; } ILINE F Dot (const Vec4_tpl& vec2) const { return x * vec2.x + y * vec2.y + z * vec2.z + w * vec2.w; } ILINE F GetLength() const { return sqrt_tpl(Dot(*this)); } ILINE F GetLengthSquared() const { return Dot(*this); } bool IsValid() const { if (!NumberValid(x)) { return false; } if (!NumberValid(y)) { return false; } if (!NumberValid(z)) { return false; } if (!NumberValid(w)) { return false; } return true; } /*! * functions and operators to compare vector * * Example: * if (v0==v1) dosomething; */ ILINE bool operator==(const Vec4_tpl& vec) { return x == vec.x && y == vec.y && z == vec.z && w == vec.w; } ILINE bool operator!=(const Vec4_tpl& vec) { return !(*this == vec); } ILINE friend bool operator ==(const Vec4_tpl& v0, const Vec4_tpl& v1) { return ((v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z) && (v0.w == v1.w)); } ILINE friend bool operator !=(const Vec4_tpl& v0, const Vec4_tpl& v1) { return !(v0 == v1); } //! normalize the vector // The default Normalize function is in fact "safe". 0 vectors remain unchanged. ILINE void Normalize() { assert(this->IsValid()); F fInvLen = isqrt_safe_tpl(x * x + y * y + z * z + w * w); x *= fInvLen; y *= fInvLen; z *= fInvLen; w *= fInvLen; } //! may be faster and less accurate ILINE void NormalizeFast() { assert(this->IsValid()); F fInvLen = isqrt_fast_tpl(x * x + y * y + z * z + w * w); x *= fInvLen; y *= fInvLen; z *= fInvLen; w *= fInvLen; } ILINE void SetLerp(const Vec4_tpl& p, const Vec4_tpl& q, F t) { *this = p * (1.0f - t) + q * t; } ILINE static Vec4_tpl CreateLerp(const Vec4_tpl& p, const Vec4_tpl& q, F t) { return p * (1.0f - t) + q * t; } AUTO_STRUCT_INFO }; typedef Vec4_tpl Vec4; // always 32 bit typedef Vec4_tpl Vec4d; // always 64 bit typedef Vec4_tpl Vec4i; typedef Vec4_tpl Vec4ui; typedef Vec4_tpl Vec4r; // variable float precision. depending on the target system it can be 32, 64 or 80 bit #if defined(WIN32) || defined(WIN64) || defined(LINUX) || defined(APPLE) typedef Vec4_tpl Vec4A; #elif defined(AZ_RESTRICTED_PLATFORM) #if defined(AZ_PLATFORM_XENIA) #include "Xenia/Cry_Vector4_h_xenia.inl" #elif defined(AZ_PLATFORM_PROVO) #include "Provo/Cry_Vector4_h_provo.inl" #elif defined(AZ_PLATFORM_SALEM) #include "Salem/Cry_Vector4_h_salem.inl" #endif #endif //vector self-addition template ILINE Vec4_tpl& operator += (Vec4_tpl& v0, const Vec4_tpl& v1) { v0 = v0 + v1; return v0; } //vector addition template ILINE Vec4_tpl operator + (const Vec4_tpl& v0, const Vec4_tpl& v1) { return Vec4_tpl(v0.x + v1.x, v0.y + v1.y, v0.z + v1.z, v0.w + v1.w); } //vector subtraction template ILINE Vec4_tpl operator - (const Vec4_tpl& v0, const Vec4_tpl& v1) { return Vec4_tpl(v0.x - v1.x, v0.y - v1.y, v0.z - v1.z, v0.w - v1.w); } //vector multiplication template ILINE Vec4_tpl operator * (const Vec4_tpl v0, const Vec4_tpl& v1) { return Vec4_tpl(v0.x * v1.x, v0.y * v1.y, v0.z * v1.z, v0.w * v1.w); } //vector division template ILINE Vec4_tpl operator / (const Vec4_tpl& v0, const Vec4_tpl& v1) { return Vec4_tpl(v0.x / v1.x, v0.y / v1.y, v0.z / v1.z, v0.w / v1.w); }