/* * 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. #ifndef CRYINCLUDE_CRYAISYSTEM_NAVIGATION_MNM_FIXEDVEC3_H #define CRYINCLUDE_CRYAISYSTEM_NAVIGATION_MNM_FIXEDVEC3_H #pragma once #include namespace MNM { template struct FixedVec3 { typedef fixed_t value_type; typedef typename CryFixedPoint::unsigned_overflow_type::type unsigned_overflow_type; value_type x, y, z; inline FixedVec3() { } inline FixedVec3(const value_type& _x) : x(_x) , y(_x) , z(_x) { } template inline FixedVec3(const FixedVec3& _x) : x(value_type(_x.x)) , y(value_type(_x.y)) , z(value_type(_x.z)) { } inline FixedVec3(const value_type& _x, const value_type& _y, const value_type& _z) : x(_x) , y(_y) , z(_z) { } inline FixedVec3(const Vec3& _vec) : x(value_type(_vec.x)) , y(value_type(_vec.y)) , z(value_type(_vec.z)) { } inline const value_type& operator[](size_t i) const { assert(i < 3); return ((value_type*)&x)[i]; } inline value_type& operator[](size_t i) { assert(i < 3); return ((value_type*)&x)[i]; } template inline FixedVec3 operator+(const FixedVec3& other) const { return FixedVec3(x + other.x, y + other.y, z + other.z); } template inline FixedVec3 operator-(const FixedVec3& other) const { return FixedVec3(x - other.x, y - other.y, z - other.z); } template inline FixedVec3& operator+=(const FixedVec3& other) { x += other.x; y += other.y; z += other.z; return *this; } template inline FixedVec3& operator-=(const FixedVec3& other) { x -= other.x; y -= other.y; z -= other.z; return *this; } template inline FixedVec3 operator/(const FixedVec3& other) const { return FixedVec3(x / other.x, y / other.y, z / other.z); } template inline FixedVec3 operator*(const FixedVec3& other) const { return FixedVec3(x * other.x, y * other.y, z * other.z); } template inline FixedVec3 operator/(const fixed_t& value) const { return FixedVec3(x / value, y / value, z / value); } template inline FixedVec3 operator*(const fixed_t& value) const { return FixedVec3(x * value, y * value, z * value); } template inline bool operator==(const FixedVec3& other) const { return (x == other.x) && (y == other.y) && (z == other.z); } template inline bool operator!=(const FixedVec3& other) const { return (x != other.x) || (y != other.y || (z != other.z)); } inline void Set(const value_type& _x, const value_type& _y, const value_type& _z) { x = _x; y = _y; z = _z; } inline value_type dot(const FixedVec3& other) const { return x * other.x + y * other.y + z * other.z; } inline value_type approximatedLen() const { const value_type heuristicFactor1(0.5f * (1.0f + (1.0f / (4.0f * sqrtf(3.0f))))); const value_type heuristicFactor2(1.0f / sqrtf(3.0f)); const value_type targetDistAbsX = fabsf(x), targetDistAbsY = fabsf(y), targetDistAbsZ = fabsf(z); return heuristicFactor1 * min(heuristicFactor2 * (targetDistAbsX + targetDistAbsY + targetDistAbsZ), max(max(targetDistAbsX, targetDistAbsY), targetDistAbsZ)); } // Be careful. This function can be safely used only when the vector length // respects len^2 <= value_type::max(). // In all the other cases the value returned is incorrect and undefined inline value_type len() const { return sqrtf(lenSq()); } // Be careful. This function can be safely used only when the vector length // respects len^2 <= value_type::max(). // In all the other cases the value returned is incorrect and undefined template inline fixed_t len() const { return sqrtf(lenSq()); } inline value_type lenNoOverflow() const { assert(value_type::sqrtf(lenSqNoOverflow()) >= value_type(0)); return value_type::sqrtf(lenSqNoOverflow()); } // Note: This function can overflow inline value_type lenSq() const { assert((x * x + y * y + z * z) >= value_type(0)); return x * x + y * y + z * z; } inline unsigned_overflow_type lenSqNoOverflow() const { return x.sqr() + y.sqr() + z.sqr(); } template inline fixed_t lenSq() const { return fixed_t(x) * fixed_t(x) + fixed_t(y) * fixed_t(y) + fixed_t(z) * fixed_t(z); } inline FixedVec3 abs() const { return FixedVec3(fabsf(x), fabsf(y), fabsf(z)); } // This function uses the len() value to normalize the vector. // If the vector is really long, len() could overflow and the normalized // resulting vector could be not correct. inline FixedVec3 normalized() const { const value_type invLen = value_type(1) / len(); return FixedVec3(x * invLen, y * invLen, z * invLen); } // This function uses the len() value to normalize the vector. // If the vector is really long, len() could overflow and the normalized // resulting vector could be not correct. template inline FixedVec3 normalized() const { const fixed_t invLen = fixed_t(1) / len(); return FixedVec3(fixed_t(x) * invLen, fixed_t(y) * invLen, fixed_t(z) * invLen); } inline static FixedVec3 minimize(const FixedVec3& a, const FixedVec3& b) { return FixedVec3(std::min(a.x, b.x), std::min(a.y, b.y), std::min(a.z, b.z)); } inline static FixedVec3 minimize(const FixedVec3& a, const FixedVec3& b, const FixedVec3& c) { return FixedVec3(std::min(std::min(a.x, b.x), c.x), std::min(std::min(a.y, b.y), c.y), std::min(std::min(a.z, b.z), c.z)); } inline static FixedVec3 maximize(const FixedVec3& a, const FixedVec3& b) { return FixedVec3(std::max(a.x, b.x), std::max(a.y, b.y), std::max(a.z, b.z)); } inline static FixedVec3 maximize(const FixedVec3& a, const FixedVec3& b, const FixedVec3& c) { return FixedVec3(std::max(std::max(a.x, b.x), c.x), std::max(std::max(a.y, b.y), c.y), std::max(std::max(a.z, b.z), c.z)); } inline Vec3 GetVec3() const { return Vec3(x.as_float(), y.as_float(), z.as_float()); } AUTO_STRUCT_INFO }; } #endif // CRYINCLUDE_CRYAISYSTEM_NAVIGATION_MNM_FIXEDVEC3_H