Cry_Vector3.h
class Vec3_tpl
Cry_Vector3.h
struct Ang3_tpl
Cry_Vector3.h
struct CAngleAxis
F angle;
! storage for the Angle&Axis coordinates.
Vec3_tplaxis;
void operator ()(F a, const Vec3_tpl& n);
default quaternion constructor
AngleAxis_tpl(const AngleAxis_tpl& aa);
CAngleAxis aa=angleaxis
Cry_Vector3.h
F d;
!< distance
Vec3_tpln;
!< normal
Plane_tploperator -() const;
Plane_tploperator *(F s) const;
Plane_tploperator /(F s) const;
F operator |(const Vec3_tpl& point) const;
void operator -=(const Plane_tpl& p);
F DistFromPlane(const Vec3_tpl& vPoint) const;
Plane_tpl();
Plane_tpl(const Plane_tpl& p);
Plane_tpl(const Vec3_tpl& normal, const F & distance);
void Set(const Vec3_tpl& vNormal, const F fDist);
! set normal and dist for this plane and then calculate plane type
template <typename T> const Vec3_tplVec3Constants ::fVec3_One (1, 1, 1);
template <typename T> const Vec3_tplVec3Constants ::fVec3_OneX (1, 0, 0);
template <typename T> const Vec3_tplVec3Constants ::fVec3_OneY (0, 1, 0);
template <typename T> const Vec3_tplVec3Constants ::fVec3_OneZ (0, 0, 1);
template <typename T> const Vec3_tplVec3Constants ::fVec3_Zero (0, 0, 0);
define the constants
friend bool operator ==(const Plane_tpl&p1, const Plane_tpl &p2) { if (fabsf(p1.n.x-p2.n.x)>0.0001f) return (false); if (fabsf(p1.n.y-p2.n.y)>0.0001f) return (false); if (fabsf(p1.n.z-p2.n.z)>0.0001f) return (false); if (fabsf(p1.d-p2.d)<0.01f) return(true); return (false); } Vec3_tpl MirrorVector(const Vec3_tpl & i) { return n*(2* (n|i))-i; } Vec3_tpl MirrorPosition(const Vec3_tpl & i) { return i - n*(2* ((n|i)+d)); } AUTO_STRUCT_INFO };
! check for equality between two planes
typedef Plane_tplPlane;
always 32 bit
typedef Plane_tplPlaned;
always 64 bit
typedef Plane_tplPlaner;
variable float precision. depending on the target system it can be between 32, 64 or 80 bit
F x;
F y;
F z;
Ang3_tploperator -() const;
vector subtraction
bool operator !=(const Ang3_tpl& vec);
void operator ()(F vx, F vy, F vz);
Ang3_tploperator *(F k) const;
Ang3_tpl& operator *=(F k);
Ang3_tploperator /(F k) const;
vector addition
vector self-addition
vector self-subtraction
bool operator ==(const Ang3_tpl& vec);
Ang3_tpl();
Ang3_tpl(F vx, F vy, F vz);
explicit Ang3_tpl(const Vec3_tpl& v);
Ang3_tpl(type_zero);
template <typename F> const Vec3_tplAngleAxis_tpl ::* (const Vec3_tpl& v) const;
friend bool operator ==(const Ang3_tpl&v0, const Ang3_tpl &v1) { return ((v0.x==v1.x) && (v0.y==v1.y) && (v0.z==v1.z)); } void Set(F xval,F yval,F zval) { x=xval; y=yval; z=zval; } bool IsEquivalent( const Ang3_tpl & v1, F epsilon=VEC_EPSILON) const { return ((fabs_tpl(x-v1.x) <= epsilon) && (fabs_tpl(y-v1.y) <= epsilon)&& (fabs_tpl(z-v1.z) <= epsilon)); } bool IsInRangePI() const { F pi=(F)(gf_PI+0.001); return ( (x>-pi)&&(x y>-pi)&&(y z>-pi)&&(z void RangePI() { const F modX = fmod(x+gf_PI, gf_PI2); x = if_neg_else(modX, modX+gf_PI, modX - gf_PI); const F modY = fmod(y+gf_PI, gf_PI2); y = if_neg_else(modY, modY+gf_PI, modY - gf_PI); const F modZ = fmod(z+gf_PI, gf_PI2); z = if_neg_else(modZ, modZ+gf_PI, modZ - gf_PI); } template<class F1> explicit Ang3_tpl( const Quat_tpl & q ) { assert(q.IsValid()); y = F( asin_tpl(max((F)-1.0,min((F)1.0,-(q.v.x*q.v.z-q.w*q.v.y)*2))) ); if (fabs_tpl(fabs_tpl(y)-(F)((F)g_PI*(F)0.5))<(F)0.01) { x = F(0); z = F(atan2_tpl(-2*(q.v.x*q.v.y-q.w*q.v.z),1-(q.v.x*q.v.x+q.v.z*q.v.z)*2)); } else { x = F(atan2_tpl((q.v.y*q.v.z+q.w*q.v.x)*2, 1-(q.v.x*q.v.x+q.v.y*q.v.y)*2)); z = F(atan2_tpl((q.v.x*q.v.y+q.w*q.v.z)*2, 1-(q.v.z*q.v.z+q.v.y*q.v.y)*2)); } } template<class F1> explicit Ang3_tpl( const Matrix33_tpl & m ) { assert( m.IsOrthonormalRH(0.001f) ); y = (F)asin_tpl(max((F)-1.0,min((F)1.0,-m.m20))); if (fabs_tpl(fabs_tpl(y)-(F)((F)g_PI*(F)0.5))<(F)0.01) { x = F(0); z = F(atan2_tpl(-m.m01,m.m11)); } else { x = F(atan2_tpl(m.m21, m.m22)); z = F(atan2_tpl(m.m10, m.m00)); } } template<class F1> explicit Ang3_tpl( const Matrix34_tpl & m ) { assert( m.IsOrthonormalRH(0.001f) ); y = F( asin_tpl(max((F)-1.0,min((F)1.0,-m.m20))) ); if (fabs_tpl(fabs_tpl(y)-(F)((F)g_PI*(F)0.5))<(F)0.01) { x = F(0); z = F(atan2_tpl(-m.m01,m.m11)); } else { x = F(atan2_tpl(m.m21, m.m22)); z = F(atan2_tpl(m.m10, m.m00)); } } template<class F1> explicit Ang3_tpl( const Matrix44_tpl & m ) { assert( Matrix33(m).IsOrthonormalRH(0.001f) ); y = F( asin_tpl(max((F)-1.0,min((F)1.0,-m.m20))) ); if (fabs_tpl(fabs_tpl(y)-(F)((F)g_PI*(F)0.5))<(F)0.01) { x = F(0); z = F(atan2_tpl(-m.m01,m.m11)); } else { x = F(atan2_tpl(m.m21, m.m22)); z = F(atan2_tpl(m.m10, m.m00)); } } template<typename F1> static F CreateRadZ( const Vec2_tpl & v0, const Vec2_tpl & v1 ) { F cz = v0.x*v1.y-v0.y*v1.x; F c = v0.x*v1.x+v0.y*v1.y; return F( atan2_tpl(cz,c) ); } template<typename F1> static F CreateRadZ( const Vec3_tpl & v0, const Vec3_tpl & v1 ) { F cz = v0.x*v1.y-v0.y*v1.x; F c = v0.x*v1.x+v0.y*v1.y; return F( atan2_tpl(cz,c) ); } template<typename F1> static Ang3_tpl GetAnglesXYZ( const Quat_tpl & q ) { return Ang3_tpl (q); } template<typename F1> void SetAnglesXYZ( const Quat_tpl & q ) { *this=Ang3_tpl (q); } template<typename F1> static Ang3_tpl GetAnglesXYZ( const Matrix33_tpl & m ) { return Ang3_tpl (m); } template<typename F1> void SetAnglesXYZ( const Matrix33_tpl & m ) { *this=Ang3_tpl (m); } template<typename F1> static Ang3_tpl GetAnglesXYZ( const Matrix34_tpl & m ) { return Ang3_tpl (m); } template<typename F1> void SetAnglesXYZ( const Matrix34_tpl & m ) { *this=Ang3_tpl (m); } F &operator [] (int index) { assert(index>=0 && index<=2); return ((F*)this)[index]; } F operator [] (int index) const { assert(index>=0 && index<=2); return ((F*)this)[index]; } bool IsValid() const { if (!NumberValid(x)) return false; if (!NumberValid(y)) return false; if (!NumberValid(z)) return false; return true; } AUTO_STRUCT_INFO };
typedef Ang3_tplAng3;
typedef Ang3_tplAng3_f64;
typedef Ang3_tplAng3r;
typedef AngleAxis_tplAngleAxis;
typedef AngleAxis_tplAngleAxis_f64;
F x;
F y;
F z;
vector subtraction
void operator ()(F vx, F vy, F vz);
Vec3_tploperator *(F k) const;
dot product (2 versions)
Vec3_tploperator /(F k) const;
cross product (2 versions)
vector addition
vector addition
vector addition
vector self-addition
vector self-subtraction
template <class F> bool IsEquivalent(const Vec3_tpl& v0, const Vec3_tpl & v1, f32 epsilon = VEC_EPSILON);
Random vector functions.
Vec3_tpl& Set(const F xval, const F yval, const F zval);
Vec3 SphereRandom(float fRadius);
Random point in sphere.
Vec3_tpl();
explicit Vec3_tpl(const Ang3_tpl & v);
template <class T> explicit Vec3_tpl(const Ang3_tpl & v);
explicit Vec3_tpl(F f);
Vec3_tpl(F vx, F vy, F vz);
Vec3_tpl(const Vec2_tpl & v);
template <class T> Vec3_tpl(const Vec2_tpl & v);
Vec3_tpl(const Vec3_tpl& v);
template <class F1> Vec3_tpl(const Vec3_tpl & v);
explicit Vec3_tpl(const Vec4_tpl & v);
template <class T> explicit Vec3_tpl(const Vec4_tpl & v);
Vec3_tpl(type_max);
Vec3_tpl(type_min);
Vec3_tpl(type_zero);
friend Vec3_tploperator * (f32 f, const Vec3_tpl &vec) { return Vec3_tpl((F)(f*vec.x), (F)(f*vec.y), (F)(f*vec.z)); } Vec3_tpl & operator *= (F k) { x*=k;y*=k;z*=k; return *this; } Vec3_tpl & operator /= (F k) { k=(F)1.0/k; x*=k;y*=k;z*=k; return *this; } Vec3_tpl operator - ( void ) const { return Vec3_tpl (-x,-y,-z); } Vec3_tpl & Flip() { x=-x; y=-y; z=-z; return *this; } F &operator [] (int32 index) { assert(index>=0 && index<=2); return ((F*)this)[index]; } F operator [] (int32 index) const { assert(index>=0 && index<=2); return ((F*)this)[index]; } bool operator==(const Vec3_tpl &vec) { return x == vec.x && y == vec.y && z == vec.z; } bool operator!=(const Vec3_tpl &vec) { return !(*this == vec); } friend bool operator ==(const Vec3_tpl &v0, const Vec3_tpl &v1) { return ((v0.x==v1.x) && (v0.y==v1.y) && (v0.z==v1.z)); } friend bool operator !=(const Vec3_tpl &v0, const Vec3_tpl &v1) { return !(v0==v1); } bool IsZero(F e = (F)0.0) const { return (fabs_tpl(x) <= e) && (fabs_tpl(y) <= e) && (fabs_tpl(z) <= e); } bool IsZeroFast(F e = (F)0.0003) const { return (fabs_tpl(x) + fabs_tpl(y) + fabs_tpl(z)) <= e; } bool IsEquivalent(const Vec3_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)); } static bool IsEquivalent(const Vec3_tpl & v0, const Vec3_tpl & v1, F epsilon=VEC_EPSILON) { assert(v0.IsValid()); assert(v1.IsValid()); return ((fabs_tpl(v0.x-v1.x) <= epsilon) && (fabs_tpl(v0.y-v1.y) <= epsilon)&& (fabs_tpl(v0.z-v1.z) <= epsilon)); } bool IsUnit(F epsilon=VEC_EPSILON) const { return (fabs_tpl(1 - GetLengthSquared()) <= epsilon); } bool IsValid() const { if (!NumberValid(x)) return false; if (!NumberValid(y)) return false; if (!NumberValid(z)) return false; return true; } void SetLength(F fLen) { F fLenMe = GetLengthSquared(); if(fLenMe<0.00001f*0.00001f) return; fLenMe = fLen * isqrt_tpl(fLenMe); x*=fLenMe; y*=fLenMe; z*=fLenMe; } void ClampLength(F maxLength) { F sqrLength = GetLengthSquared(); if (sqrLength > (maxLength * maxLength)) { F scale = maxLength * isqrt_tpl(sqrLength); x *= scale; y *= scale; z *= scale; } } F GetLength() const { return sqrt_tpl(x*x+y*y+z*z); } F GetLengthFloat() const { return GetLength(); } F GetLengthFast() const { return sqrt_fast_tpl(x*x+y*y+z*z); } F GetLengthSquared() const { return x*x+y*y+z*z; } F GetLengthSquaredFloat() const { return GetLengthSquared(); } F GetLength2D() const { return sqrt_tpl(x*x+y*y); } F GetLengthSquared2D() const { return x*x+y*y; } F GetDistance(const Vec3_tpl &vec1) const { return sqrt_tpl((x-vec1.x)*(x-vec1.x)+(y-vec1.y)*(y-vec1.y)+(z-vec1.z)*(z-vec1.z)); } F GetSquaredDistance ( const Vec3_tpl &v) const { return (x-v.x)*(x-v.x) + (y-v.y)*(y-v.y) + (z-v.z)*(z-v.z); } F GetSquaredDistance2D ( const Vec3_tpl &v) const { return (x-v.x)*(x-v.x) + (y-v.y)*(y-v.y); } void Normalize() { assert(this->IsValid()); F fInvLen = isqrt_safe_tpl( x*x+y*y+z*z ); x*=fInvLen; y*=fInvLen; z*=fInvLen; } void NormalizeFast() { assert(this->IsValid()); F fInvLen = isqrt_fast_tpl( x*x+y*y+z*z ); x*=fInvLen; y*=fInvLen; z*=fInvLen; } F NormalizeSafe(const struct Vec3_tpl & safe = Vec3Constants ::fVec3_Zero) { assert(this->IsValid()); F fLen2 = x*x+y*y+z*z; IF (VecPrecisionValues ::CheckGreater(fLen2), 1) { F fInvLen = isqrt_tpl(fLen2); x*=fInvLen; y*=fInvLen; z*=fInvLen; return F(1) / fInvLen; } else { *this = safe; return F(0); } } Vec3_tpl GetNormalizedFloat() const { return GetNormalized(); } Vec3_tpl GetNormalized() const { F fInvLen = isqrt_safe_tpl( x*x+y*y+z*z ); return *this * fInvLen; } Vec3_tpl GetNormalizedFast() const { F fInvLen = isqrt_fast_tpl( x*x+y*y+z*z ); return *this * fInvLen; } Vec3_tpl GetNormalizedSafe(const struct Vec3_tpl & safe = Vec3Constants ::fVec3_OneX) const { F fLen2 = x*x+y*y+z*z; IF (VecPrecisionValues ::CheckGreater(fLen2), 1) { F fInvLen = isqrt_tpl(fLen2); return *this * fInvLen; } else { return safe; } } Vec3_tpl GetNormalizedSafeFloat(const struct Vec3_tpl & safe = Vec3Constants ::fVec3_OneX) const { return GetNormalizedSafe(safe); } Vec3_tpl GetPermutated(int new_z) const { return Vec3_tpl(*(&x+inc_mod3[new_z]), *(&x+dec_mod3[new_z]), *(&x+new_z)); } F GetVolume() const { return x*y*z; } Vec3_tpl abs() const { return Vec3_tpl(fabs_tpl(x),fabs_tpl(y),fabs_tpl(z)); } void CheckMin(const Vec3_tpl other) { x = min(other.x,x); y = min(other.y,y); z = min(other.z,z); } void CheckMax(const Vec3_tpl other) { x = max(other.x,x); y = max(other.y,y); z = max(other.z,z); } void SetOrthogonal( const Vec3_tpl & v ) { sqr(F(0.9))*(v|v)-v.x*v.x<0 ? (x=-v.z,y=0,z=v.x) : (x=0,y=v.z,z=-v.y); } Vec3_tpl GetOrthogonal() const { return sqr(F(0.9))*(x*x+y*y+z*z)-x*x<0 ? Vec3_tpl (-z,0,x) : Vec3_tpl (0,z,-y); } void SetProjection( const Vec3_tpl& i, const Vec3_tpl& n ) { *this = i-n*(n|i); } static Vec3_tpl CreateProjection( const Vec3_tpl& i, const Vec3_tpl& n ) { return i-n*(n|i); } void SetReflection( const Vec3_tpl & i, const Vec3_tpl & n) { *this=(n*(i|n)*2)-i; } static Vec3_tpl CreateReflection( const Vec3_tpl & i, const Vec3_tpl & n ) { return (n*(i|n)*2)-i; } void SetLerp( const Vec3_tpl & p, const Vec3_tpl & q, F t ) { const Vec3_tpl diff = q-p; *this = p + (diff*t); } static Vec3_tpl CreateLerp( const Vec3_tpl & p, const Vec3_tpl & q, F t ) { const Vec3_tpl diff = q-p; return p+(diff*t); } void SetSlerp( const Vec3_tpl & p, const Vec3_tpl & q, F t ) { assert(p.IsUnit(0.005f)); assert(q.IsUnit(0.005f)); F cosine = clamp_tpl((p|q), F(-1), F(1)); if(cosine>=(F)0.99) { SetLerp(p,q,t); Normalize(); } else { F rad = acos_tpl(cosine); F scale_0 = sin_tpl((1-t)*rad); F scale_1 = sin_tpl(t*rad); *this=(p*scale_0 + q*scale_1) / sin_tpl(rad); Normalize(); } } static Vec3_tpl CreateSlerp( const Vec3_tpl & p, const Vec3_tpl & q, F t ) { Vec3_tpl v; v.SetSlerp(p,q,t); return v; } void SetQuadraticCurve(const Vec3_tpl & v0, const Vec3_tpl & v1, const Vec3_tpl & v2, F t1) { F t0=1.0f-t1; *this = t0*t0*v0 + t0*t1*2.0f*v1 + t1*t1*v2; } static Vec3_tpl CreateQuadraticCurve(const Vec3_tpl & v0, const Vec3_tpl & v1, const Vec3_tpl & v2, F t) { Vec3_tpl ip; ip.SetQuadraticCurve(v0,v1,v2,t); return ip; } void SetCubicCurve(const Vec3_tpl & v0, const Vec3_tpl & v1, const Vec3_tpl & v2, const Vec3_tpl & v3, F t1) { F t0=1.0f-t1; *this=t0*t0*t0*v0 + 3*t0*t0*t1*v1 + 3*t0*t1*t1*v2 + t1*t1*t1*v3; } static Vec3_tpl CreateCubicCurve(const Vec3_tpl & v0, const Vec3_tpl & v1, const Vec3_tpl & v2, const Vec3_tpl & v3, F t) { Vec3_tpl ip; ip.SetCubicCurve(v0,v1,v2,v3,t); return ip; } void SetQuadraticSpline(const Vec3_tpl & v0, const Vec3_tpl & v1, const Vec3_tpl & v2, F t) { SetQuadraticCurve(v0,v1-(v0*0.5f+v1+v2*0.5f-v1*2.0f),v2,t); } static Vec3_tpl CreateQuadraticSpline(const Vec3_tpl & v0, const Vec3_tpl & v1, const Vec3_tpl & v2, F t) { Vec3_tpl ip; ip.SetQuadraticSpline(v0,v1,v2,t); return ip; } void SetRandomDirection( void ) { int nMax = 5; F Length2; do { x = 1.0f - 2.0f*cry_frand(); y = 1.0f - 2.0f*cry_frand(); z = 1.0f - 2.0f*cry_frand(); Length2 = len2(); nMax--; } while((Length2>1.0f || Length2<0.0001f) && nMax > 0); F InvScale = isqrt_tpl(Length2); x *= InvScale; y *= InvScale; z *= InvScale; } Vec3_tpl GetRotated(const Vec3_tpl & axis, F angle) const { return GetRotated(axis,cos_tpl(angle),sin_tpl(angle)); } Vec3_tpl GetRotated(const Vec3_tpl & axis, F cosa,F sina) const { Vec3_tpl zax = axis*(*this|axis); Vec3_tpl xax = *this-zax; Vec3_tpl yax = axis%xax; return xax*cosa + yax*sina + zax; } Vec3_tpl GetRotated(const Vec3_tpl& center,const Vec3_tpl & axis, F angle) const { return center+(*this-center).GetRotated(axis,angle); } Vec3_tpl GetRotated(const Vec3_tpl & center,const Vec3_tpl & axis, F cosa,F sina) const { return center+(*this-center).GetRotated(axis,cosa,sina); } Vec3_tpl CompMul( const Vec3_tpl rhs ) const { return( Vec3_tpl( x * rhs.x, y * rhs.y, z * rhs.z ) ); } F Dot (const Vec3_tpl v) const { return x*v.x + y*v.y + z*v.z; } Vec3_tpl Cross (const Vec3_tpl vec2) const { return Vec3_tpl ( y*vec2.z - z*vec2.y, z*vec2.x - x*vec2.z, x*vec2.y - y*vec2.x); } DEPRICATED operator F* () { return (F*)this; } template <class T> explicit DEPRICATED Vec3_tpl(const T *src) { x=src[0]; y=src[1]; z=src[2]; } Vec3_tpl& zero() { x=y=z=0; return *this; } F len() const { return sqrt_tpl(x*x+y*y+z*z); } F len2() const { return x*x +y*y + z*z; } Vec3_tpl& normalize() { F len2 = x*x+y*y+z*z; if (len2>(F)1e-20f) { F rlen = isqrt_tpl(len2); x*=rlen; y*=rlen; z*=rlen; } else Set(0,0,1); return *this; } Vec3_tpl normalized() const { F len2 = x*x+y*y+z*z; if (len2>(F)1e-20f) { F rlen = isqrt_tpl(len2); return Vec3_tpl(x*rlen,y*rlen,z*rlen); } else return Vec3_tpl(0,0,1); } template<class F1> Vec3_tpl sub(const Vec3_tpl & v) const { return Vec3_tpl (x-v.x, y-v.y, z-v.z); } template<class F1> Vec3_tpl scale(const F1 k) const { return Vec3_tpl (x*k,y*k,z*k); } template<class F1> F1 dot(const Vec3_tpl & v) const { return (F1)(x*v.x+y*v.y+z*v.z); } template<class F1> Vec3_tpl cross(const Vec3_tpl &v) const { return Vec3_tpl (y*v.z-z*v.y, z*v.x-x*v.z, x*v.y-y*v.x); } AUTO_STRUCT_INFO };
typedef F value_type;
typedef Vec3_tplVec3;
always 32 bit
typedef Vec3_tplVec3d;
always 64 bit
typedef Vec3_tpl<int> Vec3i;
typedef Vec3_tplVec3r;
variable float precision. depending on the target system it can be 32, 64 or 80 bit