/*************************************************************************/ /* File : VxVector.h */ /* Author : Romain SIDIDRIS */ /* */ /* Virtools SDK */ /* Copyright (c) Virtools 2000, All Rights Reserved. */ /*************************************************************************/ #ifndef VXVECTOR_H #define VXVECTOR_H #ifdef macintosh #include "VxMacHeader.h" #endif VX_EXPORT int radToAngle(float val); VX_EXPORT float Tsin(int angle); VX_EXPORT float Tcos(int angle); //______________________ // some global variables /******************************************************* {filename:VxVector} Name: VxVector Summary: Class representation of a Vector in 3 dimensions Remarks: A VxVector is defined as: typedef struct VxVector { union { struct { float x,y,z; }; float v[3]; }; } Elements can be accessed with x,y,z value or through the array v. ***********************************************************/ struct VxVector { #if defined(_LINUX) float x,y,z; #else union { struct { float x,y,z; }; float v[3]; }; #endif public: // ===================================== // Constructors // ===================================== VxVector(); VX_EXPORT explicit VxVector(const VxCompressedVector& v); VxVector(float f); VxVector(float _x, float _y, float _z); VxVector(const float f[3]); void Absolute(); /************************************************* Summary: Returns the square magnitude(length) of a vector. Return Value: Square magnitude of the vector Remarks: This method returns the square magnitude (length*length) of the vector v. See also: Magnitude *************************************************/ float SquareMagnitude () const {return x*x + y*y + z*z;} /************************************************* Summary: Returns the magnitude(length) of a vector. Return Value: Magnitude of the vector Remarks: This method returns the length of the vector v. WARNING: Calling this function with a null vector (0,0,0) will return an indefinite value (constant NaN - not a number) See also: SquareMagnitude *************************************************/ float Magnitude () const {return XSqrt(SquareMagnitude());} // ===================================== // Access grants // ===================================== const float& operator[](int i) const; float& operator[](int i); void Set(float X,float Y,float Z); VxVector& operator += (const VxVector& v); VxVector& operator -= (const VxVector& v); VxVector& operator *= (const VxVector& v); VxVector& operator /= (const VxVector& v); VxVector& operator *= (float s); VxVector& operator /= (float s); VX_EXPORT VxVector& operator = (const VxCompressedVector& v); float Dot(const VxVector& iV) const {return x*iV.x + y * iV.y + z * iV.z;} VxVector operator + (float s) const {return VxVector(x+s,y+s,z+s);} VxVector operator - (float s) const {return VxVector(x-s,y-s,z-s);} // ===================================== // Unary operators // ===================================== friend const VxVector operator + (const VxVector& v); friend const VxVector operator - (const VxVector& v); // ===================================== // Binary operators // ===================================== // Addition and subtraction friend const VxVector operator + (const VxVector& v1, const VxVector& v2); friend const VxVector operator - (const VxVector& v1, const VxVector& v2); // Scalar multiplication and division friend const VxVector operator * (const VxVector& v, float s); friend const VxVector operator * (float s, const VxVector& v); friend const VxVector operator / (const VxVector& v, float s); // Memberwise multiplication and division friend const VxVector operator * (const VxVector& v1, const VxVector& v2); friend const VxVector operator / (const VxVector& v1, const VxVector& v2); // Vector dominance friend int operator < (const VxVector& v1, const VxVector& v2); friend int operator <= (const VxVector& v1, const VxVector& v2); // Bitwise equality friend int operator == (const VxVector& v1, const VxVector& v2); friend int operator != (const VxVector& v1, const VxVector& v2); // Return min/max component of the input vector friend float Min (const VxVector& v); friend float Max (const VxVector& v); // Return memberwise min/max of input vectors friend const VxVector Minimize (const VxVector& v1, const VxVector& v2); friend const VxVector Maximize (const VxVector& v1, const VxVector& v2); // Interpolate two vectors friend const VxVector Interpolate (float step, const VxVector& v1, const VxVector& v2); // In-place interpolate void Interpolate(float amount, const VxVector& target); VX_EXPORT void Normalize(); VX_EXPORT void Rotate(const VxMatrix& M); VX_EXPORT const static VxVector& axisX(); VX_EXPORT const static VxVector& axisY(); VX_EXPORT const static VxVector& axisZ(); VX_EXPORT const static VxVector& axis0(); VX_EXPORT const static VxVector& axis1(); const static VxVector m_AxisX; const static VxVector m_AxisY; const static VxVector m_AxisZ; const static VxVector m_Axis0; const static VxVector m_Axis1; }; /************************************************* Name: Interpolate Summary: Constructs a vector representing the interpolation of two vectors. Arguments: amount : The interpolation factor. target: The vector toward which this vector is interpolated Return value: None. See also: VxVector *************************************************/ inline void VxVector::Interpolate(float amount, const VxVector& target) { x += amount * (target.x - x); y += amount * (target.y - y); z += amount * (target.z - z); } /************************************************* Name: SquareMagnitude Summary: Returns the square magnitude(length) of a vector. Input Arguments: v: a pointer to a VxVector which magnitude should be returned Return Value: Square magnitude of v Remarks: This method returns the square magnitude (length*length) of the vector v. See also: Magnitude *************************************************/ inline float SquareMagnitude (const VxVector& v) {return v.x*v.x + v.y*v.y + v.z*v.z;} /************************************************* Name: Magnitude Summary: Returns the magnitude(length) of a vector. Input Arguments: v: a pointer to a VxVector which magnitude should be returned Return Value: Magnitude of v Remarks: This method returns the length of the vector v. WARNING: Calling this function with a null vector (0,0,0) will return an indefinite value (constant NaN - not a number) See also: SquareMagnitude *************************************************/ inline float Magnitude (const VxVector& v) {return XSqrt(SquareMagnitude(v));} /************************************************* Name: InvSquareMagnitude Summary: Returns the inverse square magnitude(length) of a vector. Input Arguments: v: a pointer to a VxVector which inverse magnitude should be returned Return Value: Inverse Square magnitude of v Remarks: This method returns the inverse square magnitude (1/(length*length)) of the vector v. See also: SquareMagnitude *************************************************/ inline float InvSquareMagnitude (const VxVector& v) {return 1.0f/SquareMagnitude(v);} /************************************************* Name: InvMagnitude Summary: Returns the inverse magnitude(length) of a vector. Input Arguments: v: a pointer to a VxVector which inverse magnitude should be returned Remarks: This method returns the inverse magnitude (1/length) of the vector v. WARNING: Calling this function with a null vector (0,0,0) will return an indefinite value (constant NaN - not a number) Return Value: Inverse magnitude of v See also: Magnitude *************************************************/ inline float InvMagnitude (const VxVector& v) {return 1.0f/Magnitude(v);} /************************************************* Name: Normalize Summary: Returns a normalized vector (length=1). Input Arguments: Vect: a pointer to a VxVector v: Vector to normalize. Return Value: A Vector equal to Vect Normalized. Remarks: This method returns a vector equal to Vect normalized to length 1.0. WARNING: Calling this function with a null vector (0,0,0) will return an indefinite vector (constant NaN - not a number). This function is more precise than VxVector::Normalize. See also: Magnitude,VxVector,Vx2DVector *************************************************/ inline const VxVector Normalize (const VxVector& v) {return v*InvMagnitude(v);} // Necessary for binding in VSL #if defined(macintosh) || defined(PSX2) || defined(PSP) const VxVector NormalizeVectorNotInlined(const VxVector& v); #endif inline const VxVector Normalize (const VxVector *vect) {return Normalize(*vect);} /************************************************* Name: DotProduct Summary: Calculates the dot product of two vectors. Input Arguments: Vect1: First source Vector. Vect2: Second source Vector. Return Value: A float result of the dot product of Vect1.Vect2. Remarks: See also: VxVector,Vx2DVector *************************************************/ inline float DotProduct (const VxVector& v1, const VxVector& v2) { return v1.x*v2.x + v1.y * v2.y + v1.z * v2.z; } /************************************************* Name: CrossProduct Summary: Calculates the cross product of two vectors. Input Arguments: Vect1: First source Vector. Vect2: Second source Vector. Return Value: A VxVector result of the cross product of Vect1^Vect2. See also: VxVector *************************************************/ inline const VxVector CrossProduct (const VxVector& Vect1, const VxVector& Vect2) { return VxVector(Vect1.y * Vect2.z - Vect1.z * Vect2.y, Vect1.z * Vect2.x - Vect1.x * Vect2.z ,Vect1.x * Vect2.y - Vect1.y * Vect2.x); } /************************************************* Summary: Returns the reflection of vector against a plane. Input Arguments: v1: A pointer to a VxVector giving the incident vector (pointing away from the plane) Norm: A VxVector giving the normal point away from the plane of reflection. Return Value: A Vector equal to the reflection of v1. Remarks: This method calculates the vector reflection of v1 against the plane described by normal Norm. using the following equation : R = 2*(V dot N)*N - V It is expected that the incident vector v1 is pointing away from the plane. The resultant vector R will also be pointing away from the plane. See also: DotProduct *************************************************/ inline const VxVector Reflect(const VxVector& v1,const VxVector& Norm) { float dp2 = 2.0f*(DotProduct(v1,Norm)); return VxVector(dp2*Norm.x-v1.x,dp2*Norm.y-v1.y,dp2*Norm.z-v1.z); } VX_EXPORT const VxVector Rotate(const VxMatrix& mat,const VxVector& pt); VX_EXPORT const VxVector Rotate(const VxVector& v1, const VxVector& v2,float angle); VX_EXPORT const VxVector Rotate(const VxVector* v1, const VxVector* v2,float angle); // For VSL Binding #if defined(macintosh) || defined(PSX2) || defined(PSP) VX_EXPORT const VxVector RotateMV(const VxMatrix& mat,const VxVector& pt); VX_EXPORT const VxVector RotateVVF(const VxVector& v1, const VxVector& v2,float angle); #endif /******************************************************* Name: VxCompressedVector Summary: Class representation of a unit vector in 3 dimensions Remarks: A VxCompressedVector is defined as: typedef struct VxCompressedVector { short int xa,ya } The xa and ya members are polar angles This representation can be used to store normals or unit vectors using less memory than a conventionnal vector. ***********************************************************/ typedef struct VxCompressedVector { public: short int xa,ya; // Polar Angles VxCompressedVector() { xa=ya=0; } VxCompressedVector(float _x, float _y, float _z) { Set(_x,_y,_z); } // Set from a normalized vector VX_EXPORT void Set(float X,float Y,float Z); // Spherical linear interpolation void Slerp(float step,VxCompressedVector &v1,VxCompressedVector &v2); // Linear interpolation. The vector is kept normalized void Lerp(float step,VxCompressedVector &v1,VxCompressedVector &v2); // ===================================== // Unary operators // ===================================== VxCompressedVector& operator = (const VxVector& v); VxCompressedVector& operator = (const VxCompressedVectorOld& v); } VxCompressedVector; /************************************************* Summary: Spherical linear interpolation of a compressed vector by the given amount. Contrary to Lerp, Angle variation is linear. Input Arguments: step: Interpolation amount vx1: Vector we are interpolating from vx2: Vector we are interpolating to *************************************************/ inline void VxCompressedVector::Slerp(float step,VxCompressedVector &v1,VxCompressedVector &v2) { VxVector cv1; cv1 = v1; VxVector cv2; cv2 = v2; // compute angle between the 2 vectors float dot = cv1.Dot(cv2); const float dotThreshold = 0.995f; if (dot > dotThreshold) { // The 2 vectors are very close, computing an orthonormal basis // may not be precise enough (sinus of the angle is close to 0, as the orthogonal component of v1 is -> normalization will be imprecise) // -> just interpolate linearly and renormalize // Linear interpolation is ok in this case because angle is ~ to sin(angle) for small angles cv1 = step * cv2 + (1.f - step) * cv1; cv1.Normalize(); } else { // Slerp implies linearly interpolating the angle (linear interpolation of 2 unit vector doesn't lead // to a linear interpolation of their angle) // compute the desired angle XThreshold(dot, -1.f, 1.f); // stay in admissible values for acos float targetAngle = step * acosf(dot); // Now, construct an orthonormal basis cv2 = cv2 - dot * cv1; // only kept orthogonal part of v2 relative to v1 cv2.Normalize(); // (v1, v2) is now orthogonal // in the orthonormal basis, just build target vector from desired angle cv1 = cosf(targetAngle) * cv1 + sinf(targetAngle) * cv2; } // back to polar coordinates Set(cv1.x, cv1.y, cv1.z); } /************************************************* Summary: Linear interpolation of a compressed vector by the given amount. Because the vector is stored in polar coordinate, it will remains unit sized after the interpolation. Input Arguments: step: Interpolation amount vx1: Vector we are interpolating from vx2: Vector we are interpolating to *************************************************/ inline void VxCompressedVector::Lerp(float step,VxCompressedVector &v1,VxCompressedVector &v2) { VxVector cv1(v1); VxVector cv2(v2); cv1.Interpolate(step, cv2); cv1.Normalize(); // back to polar coordinates Set(cv1.x, cv1.y, cv1.z); } typedef struct VxCompressedVectorOld { public: int xa,ya; // Polar Angles VxCompressedVectorOld() { xa=ya=0; } VxCompressedVectorOld(float _x, float _y, float _z) { Set(_x,_y,_z); } void Set(float X,float Y,float Z); void Slerp(float step,VxCompressedVectorOld &v1,VxCompressedVectorOld &v2); // ===================================== // Unary operators // ===================================== VxCompressedVectorOld& operator = (const VxVector& v); VxCompressedVectorOld& operator = (const VxCompressedVector& v); } VxCompressedVectorOld; /******************************************************* {filename:VxVector4} Name: VxVector4 Summary: Class representation of a Vector of 4 elements (x,y,z,w) Remarks: VxVector4 is used for 3D Transformation when the w component is used for perspective information. Most of the methods available for a VxVector are also implemented for the VxVector4 A VxVector4 is defined as: typedef struct VxVector4 { union { struct { float x,y,z,w; }; float v[4]; }; } ***********************************************************/ class VxVector4 : public VxVector { public: float w; VxVector4() { x=y=z=w=0.0f; } VxVector4(float f) { x=y=z=w=f; } VxVector4(float _x, float _y, float _z,float _w) { x=_x; y=_y; z=_z; w=_w; } VxVector4(const float f[4]){ x=f[0]; y=f[1]; z=f[2]; w=f[3]; } VxVector4& operator = (const VxVector& v) {x=v.x;y=v.y;z=v.z;return *this;} // ===================================== // Access grants // ===================================== const float&operator[](int i) const; float&operator[](int i); #if defined(_LINUX) operator float*() const {return (float*)&x;} #else operator float*() const {return (float*)&v[0];} #endif // Initialization void Set(float X,float Y,float Z,float W); void Set(float X,float Y,float Z); float Dot(const VxVector4& iV) const {return x*iV.x + y * iV.y + z * iV.z;} VxVector4& operator += (const VxVector4& v); VxVector4& operator -= (const VxVector4& v); VxVector4& operator *= (const VxVector4& v); VxVector4& operator /= (const VxVector4& v); VxVector4& operator += (const VxVector& v); VxVector4& operator -= (const VxVector& v); VxVector4& operator *= (const VxVector& v); VxVector4& operator /= (const VxVector& v); VxVector4& operator *= (float s); VxVector4& operator /= (float s); VxVector4 operator + (float s) const {return VxVector4(x+s,y+s,z+s,w+s);} VxVector4 operator - (float s) const {return VxVector4(x-s,y-s,z-s,w-s);} // ===================================== // Unary operators // ===================================== friend const VxVector4 operator + (const VxVector4& v); friend const VxVector4 operator - (const VxVector4& v); // ===================================== // Binary operators // ===================================== // Addition and subtraction friend const VxVector4 operator + (const VxVector4& v1, const VxVector4& v2); friend const VxVector4 operator - (const VxVector4& v1, const VxVector4& v2); // Scalar multiplication and division friend const VxVector4 operator * (const VxVector4& v, float s); friend const VxVector4 operator * (float s, const VxVector4& v); friend const VxVector4 operator / (const VxVector4& v, float s); // Memberwise multiplication and division friend const VxVector4 operator * (const VxVector4& v1, const VxVector4& v2); friend const VxVector4 operator / (const VxVector4& v1, const VxVector4& v2); // Bitwise equality friend int operator == (const VxVector4& v1, const VxVector4& v2); friend int operator != (const VxVector4& v1, const VxVector4& v2); }; /******************************************************* {filename:VxBbox} Summary: Class representation of a Bounding Box Remarks: The VxBbox structure contains two VxVector Min and Max to represents the Minimum and Maximum coordinates of the corners of a box. A VxBbox is defined as: typedef struct VxBbox { union { struct { VxVector Max; VxVector Min; } }; float v[6]; }; } ***********************************************************/ typedef struct VxBbox { #if defined(_LINUX) || defined(PSX2) || defined(PSP) || defined (__GNUC__) VxVector Max; // Maximum corner of the box VxVector Min; // Minimum corner of the box #else union { struct { VxVector Max; // Maximum corner of the box VxVector Min; // Minimum corner of the box }; float v[6]; }; #endif public: VxBbox():Max(-1e6f,-1e6f,-1e6f),Min(1e6f,1e6f,1e6f) {} VxBbox(VxVector iMin, VxVector iMax):Max(iMax),Min(iMin) {} VxBbox( float value ) { Max.x=value; Max.y=value; Max.z=value; Min.x=-value; Min.y=-value; Min.z=-value; } BOOL IsValid() const { if (Min.x > Max.x) return FALSE; if (Min.y > Max.y) return FALSE; if (Min.z > Max.z) return FALSE; return TRUE; } VxVector GetSize() const {return Max - Min;} VxVector GetHalfSize() const {return (Max-Min)*0.5f;} VxVector GetCenter() const {return (Max+Min)*0.5f;} void SetCorners(const VxVector& min,const VxVector& max){Min = min;Max = max;} void SetDimension(const VxVector& position,const VxVector& size){Min = position;Max = position+size;} void SetCenter(const VxVector& center,const VxVector& halfsize) { Min = center-halfsize; Max = center+halfsize; } //------------------------------------------------------- // Name: Outline // Summary: Outline bbox extent by the given radius //------------------------------------------------------- void Outline(float radius) { Min.x -= radius; Min.y -= radius; Min.z -= radius; Max.x += radius; Max.y += radius; Max.z += radius; } //------------------------------------------------------- // Name: Reset // Summary: Resets the minimum and maximum values of the box // Remarks: // The Reset method sets the Minimum Value to (1E6,1E6,1E6) // and maximum value to (-1E6,-1E6,-1E6) //------------------------------------------------------- void Reset() { Max.x=-1e6f; Max.y=-1e6f; Max.z=-1e6f; Min.x=1e6f; Min.y=1e6f; Min.z=1e6f; } //------------------------------------------------------- // Name: Merge // Summary: Merges two boxes // Arguments: // v : A VxBbox to merge to this box // Remarks: // The Merge method calculates the new extents of this box // so it contains the v Box //------------------------------------------------------- void Merge (const VxBbox& v) { Max.x = XMax(v.Max.x,Max.x); Max.y = XMax(v.Max.y,Max.y); Max.z = XMax(v.Max.z,Max.z); Min.x = XMin(v.Min.x,Min.x); Min.y = XMin(v.Min.y,Min.y); Min.z = XMin(v.Min.z,Min.z); } //------------------------------------------------------- // Name: Merge // Summary: Merges a vector with a box // Arguments: // v : A vector to merge to this box // Remarks: // The Merge method calculates the new extents of this box // so it contains the v point //------------------------------------------------------- void Merge (const VxVector& v) { if (v.x > Max.x) Max.x = v.x; if (v.x < Min.x) Min.x = v.x; if (v.y > Max.y) Max.y = v.y; if (v.y < Min.y) Min.y = v.y; if (v.z > Max.z) Max.z = v.z; if (v.z < Min.z) Min.z = v.z; } //------------------------------------------------------- // Name: Classify // Summary: Returns on which side a point is // Remarks: // // Return Value: // A combination of the culling flags // //------------------------------------------------------- DWORD Classify(const VxVector& iPoint) const { DWORD flag = 0; if (iPoint.x < Min.x) flag |= VXCLIP_LEFT; else if (iPoint.x > Max.x) flag |= VXCLIP_RIGHT; if (iPoint.y < Min.y) flag |= VXCLIP_BOTTOM; else if (iPoint.y > Max.y) flag |= VXCLIP_TOP; if (iPoint.z < Min.z) flag |= VXCLIP_BACK; else if (iPoint.z > Max.z) flag |= VXCLIP_FRONT; return flag; } //------------------------------------------------------- // Name: Classify // Summary: Returns on which side a box is // Remarks: // // Return Value: // A combination of the culling flags // //------------------------------------------------------- DWORD Classify(const VxBbox& iBox) const { DWORD flag = 0; if (iBox.Max.zMax.z) flag |= VXCLIP_FRONT; if (iBox.Max.xMax.x) flag |= VXCLIP_RIGHT; if (iBox.Max.yMax.y) flag |= VXCLIP_TOP; return flag; } //------------------------------------------------------- // Name: Classify // Summary: Returns on which side a box is compared to point // Remarks: // // Return Value: // 2 : If viewed from point pt the box box2 is on the opposite side of this box // 1 : box2 is inside this box // 0 : No idea where the box is // //------------------------------------------------------- VX_EXPORT int Classify(const VxBbox& box2,const VxVector& pt) const; //------------------------------------------------------- // Summary: classify an array of vertices against // the box. An array of dword is filled with // flags from the enum VXCLIP_BOXFLAGS // Remarks: // //------------------------------------------------------- VX_EXPORT void ClassifyVertices(const int iVcount, BYTE* iVertices, DWORD iStride, DWORD* oFlags) const; //------------------------------------------------------- // Summary: classify an array of vertices against // one axis of the box. An array of dword is filled with // flags 0x01 if < min, 0x10 if > max // Remarks: // //------------------------------------------------------- VX_EXPORT void ClassifyVerticesOneAxis(const int iVcount, BYTE* iVertices, DWORD iStride, const int iAxis,DWORD* oFlags) const; //------------------------------------------------------- // Name: Intersect // Summary: Intersects two boxes // Arguments: // v : A VxBbox to intersect with this box // Remarks: // The Intersect method calculates the new extents of this box // so it only contains the intersection with the v Box //------------------------------------------------------- void Intersect(const VxBbox& v) { Max.x = XMin(v.Max.x,Max.x); Max.y = XMin(v.Max.y,Max.y); Max.z = XMin(v.Max.z,Max.z); Min.x = XMax(v.Min.x,Min.x); Min.y = XMax(v.Min.y,Min.y); Min.z = XMax(v.Min.z,Min.z); } //------------------------------------------------------- // Name: VectorIn // Summary: Tests if a point is inside the box. // Arguments: // v : A VxVector to test if it is inside the box. // // Return Value: TRUE if v is inside this box, FALSE otherwise //------------------------------------------------------- BOOL VectorIn(const VxVector& v) const { if (v.xMax.x) return FALSE; if (v.yMax.y) return FALSE; if (v.zMax.z) return FALSE; return TRUE; } //------------------------------------------------------- // Name: IsBoxInside // Summary: Tests if a box is totally inside this box. // Arguments: // b : A VxBbox to test if it is inside the box. // // Return Value: TRUE if b is inside this box, FALSE otherwise //------------------------------------------------------- BOOL IsBoxInside(const VxBbox& b) const { if (b.Min.xMax.x) return 0; if (b.Max.y>Max.y) return 0; if (b.Max.z>Max.z) return 0; return 1; } bool operator == (const VxBbox& iBox) const { return (Max == iBox.Max) && (Min == iBox.Min); } // Transform this box to eight points according to matrix mat VX_EXPORT void TransformTo(VxVector *pts,const VxMatrix& Mat) const; // Creates this box from sbox acording to matrix mat VX_EXPORT void TransformFrom(const VxBbox& sbox,const VxMatrix& Mat); // Get this bbox corners inline void GetCorners(VxVector corners[8]) const; } VxBbox; inline VxVector::VxVector():x(0),y(0),z(0) { } inline VxVector::VxVector(float f):x(f),y(f),z(f) { } inline VxVector::VxVector(float _x, float _y, float _z):x(_x),y(_y),z(_z) { } inline VxVector::VxVector(const float f[3]):x(f[0]),y(f[1]),z(f[2]) { } inline void VxBbox::GetCorners(VxVector corners[8]) const { corners[0].Set(Min.x, Min.y, Min.z); corners[1].Set(Max.x, Min.y, Min.z); corners[2].Set(Min.x, Max.y, Min.z); corners[3].Set(Max.x, Max.y, Min.z); // corners[4].Set(Min.x, Min.y, Max.z); corners[5].Set(Max.x, Min.y, Max.z); corners[6].Set(Min.x, Max.y, Max.z); corners[7].Set(Max.x, Max.y, Max.z); } // Initialization inline void VxVector::Set(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } inline const float& VxVector::operator[](int i) const { return *((&x)+i); } inline float& VxVector::operator[](int i) { return *((&x)+i); } inline VxVector& VxVector::operator += (const VxVector& v) { x += v.x; y += v.y; z += v.z; return *this; } inline VxVector& VxVector::operator -= (const VxVector& v) { x -= v.x; y -= v.y; z -= v.z; return *this; } inline VxVector& VxVector::operator *= (const VxVector& v) { x *= v.x; y *= v.y; z *= v.z; return *this; } inline VxVector& VxVector::operator /= (const VxVector& v) { x /= v.x; y /= v.y; z /= v.z; return *this; } inline VxVector& VxVector::operator *= (float s) { x *= s; y *= s; z *= s; return *this; } inline VxVector& VxVector::operator /= (float s) { float temp=1.0f/s; x *= temp; y *= temp; z *= temp; return *this; } // inline const VxVector operator + (const VxVector& v) { return v; } // inline const VxVector operator - (const VxVector& v) { return VxVector(-v.x, -v.y, -v.z); } inline const VxVector operator + (const VxVector& v1, const VxVector& v2) { return VxVector(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z); } inline const VxVector operator - (const VxVector& v1, const VxVector& v2) { return VxVector(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); } // inline const VxVector operator * (const VxVector& v1, const VxVector& v2) { return VxVector(v1.x*v2.x, v1.y*v2.y, v1.z*v2.z); } // inline const VxVector operator / (const VxVector& v1, const VxVector& v2) { return VxVector(v1.x/v2.x, v1.y/v2.y, v1.z/v2.z); } // inline int operator < (const VxVector& v1, const VxVector& v2) { return v1[0] < v2[0] && v1[1] < v2[1] && v1[2] < v2[2]; } // inline int operator <= (const VxVector& v1, const VxVector& v2) { return v1[0] <= v2[0] && v1[1] <= v2[1] && v1[2] <= v2[2]; } inline const VxVector operator * (const VxVector& v, float s) { return VxVector(s*v.x, s*v.y, s*v.z); } inline const VxVector operator * (float s, const VxVector& v) { return VxVector(s*v.x, s*v.y, s*v.z); } inline const VxVector operator / (const VxVector& v, float s) { float temp=1.0f/s; return VxVector(v.x*temp, v.y*temp, v.z*temp); } // inline int operator == (const VxVector& v1, const VxVector& v2) { return ( (v1.x==v2.x) && (v1.y==v2.y) && (v1.z==v2.z) ); } // inline int operator != (const VxVector& v1, const VxVector& v2) { return !(v1==v2); } /************************************************* Name: Absolute Summary: Calculates absolute value of a vector. - v: A reference to a VxVector. Return value: A VxVector with each element set to the absolute value of the corresponding element in v. See also: VxVector, *************************************************/ inline const VxVector Absolute (const VxVector& v) { return VxVector(XAbs(v.x),XAbs(v.y),XAbs(v.z)); } /************************************************* Name: Absolute Summary: Calculates absolute value of a vector. Each element is set to its absolute value. See also: VxVector *************************************************/ void inline VxVector::Absolute () { x = XAbs(x); y = XAbs(y); z = XAbs(z); } /************************************************* Name: MultiplyAdd Summary: 'dest' is set to 'factor' * 'arg0' + 'arg1' Arguments: 'dest': The target vector *************************************************/ inline const void MultiplyAdd(VxVector& dest, float factor, const VxVector& arg0, const VxVector& arg1) { dest.Set(factor * arg0.x + arg1.x, factor * arg0.y + arg1.y, factor * arg0.z + arg1.z); } /************************************************* Name: Min Summary: Calculates the minimum value among the elements of a vector. Arguments: v: A Vector. Return value: A float value containing the minimum of the elements of v. See also: VxVector,Vx2DVector *************************************************/ inline float Min (const VxVector& v) { return XMin(v.x,v.y,v.z); } /************************************************* Name: Max Summary: Calculates the maximum value among the elements of a vector. Arguments: v: A Vector. Return value: A float value containing the maximum of the elements of v. See also: VxVector,Vx2DVector ************************************************/ inline float Max (const VxVector& v) { float ret = v.x; if (ret < v.y) ret = v.y; if (ret < v.z) ret = v.z; return ret; } /************************************************* Name: Minimize Summary: Constructs a vector containing minimum values of two vectors. Arguments: v1: A Vector. v2: A Vector. Return value: A VxVector containing with each element equal to the smallest element of v1 or v2. See also: VxVector *************************************************/ inline const VxVector Minimize (const VxVector& v1, const VxVector& v2) { return VxVector(XMin(v1[0],v2[0]),XMin(v1[1],v2[1]),XMin(v1[2],v2[2])); } /************************************************* Name: Maximize Summary: Constructs a vector containing maximum values of two vectors. Arguments: v1: A reference to a VxVector. v2: A reference to a VxVector. Return value: A VxVector containing with each element equal to the greatest element of v1 or v2. See also: VxVector *************************************************/ inline const VxVector Maximize (const VxVector& v1, const VxVector& v2) { return VxVector(XMax(v1[0],v2[0]),XMax(v1[1],v2[1]),XMax(v1[2],v2[2])); } /************************************************* Name: Interpolate Summary: Constructs a vector representing the interpolation of two vectors. Arguments: step : The interpolation factor. v1: A reference to a VxVector. v2: A reference to a VxVector. Return value: A VxVector . See also: VxVector *************************************************/ inline const VxVector Interpolate (float step, const VxVector& v1, const VxVector& v2) { return VxVector( v1.x + (v2.x-v1.x) * step, v1.y + (v2.y-v1.y) * step, v1.z + (v2.z-v1.z) * step); } //------------------------------------------------------------------------------------------------------ // VxVector4 //------------------------------------------------------------------------------------------------------- inline VxVector4& VxVector4::operator += (const VxVector4& v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; } inline VxVector4& VxVector4::operator -= (const VxVector4& v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; } inline VxVector4& VxVector4::operator *= (const VxVector4& v) { x *= v.x; y *= v.y; z *= v.z; w *= v.w; return *this; } inline VxVector4& VxVector4::operator /= (const VxVector4& v) { x /= v.x; y /= v.y; z /= v.z; w /= v.w; return *this; } inline VxVector4& VxVector4::operator += (const VxVector& v) { x += v.x; y += v.y; z += v.z; return *this; } inline VxVector4& VxVector4::operator -= (const VxVector& v) { x -= v.x; y -= v.y; z -= v.z; return *this; } inline VxVector4& VxVector4::operator *= (const VxVector& v) { x *= v.x; y *= v.y; z *= v.z; return *this; } inline VxVector4& VxVector4::operator /= (const VxVector& v) { x /= v.x; y /= v.y; z /= v.z; return *this; } inline VxVector4& VxVector4::operator *= (float s) { x *= s; y *= s; z *= s; w *= s; return *this; } inline VxVector4& VxVector4::operator /= (float s) { float temp=1.0f/s; x *= temp; y *= temp; z *= temp; w *= temp; return *this; } // inline const VxVector4 operator + (const VxVector4& v) { return v; } // inline const VxVector4 operator - (const VxVector4& v) { return VxVector4(-v.x, -v.y, -v.z,-v.w); } inline const VxVector4 operator + (const VxVector4& v1, const VxVector4& v2) { return VxVector4(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z,v1.w+v2.w); } inline const VxVector4 operator - (const VxVector4& v1, const VxVector4& v2) { return VxVector4(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z,v1.w - v2.w); } // inline const VxVector4 operator * (const VxVector4& v1, const VxVector4& v2) { return VxVector4(v1.x*v2.x, v1.y*v2.y, v1.z*v2.z,v1.w * v2.w); } // inline const VxVector4 operator / (const VxVector4& v1, const VxVector4& v2) { return VxVector4(v1.x/v2.x, v1.y/v2.y, v1.z/v2.z,v1.w/v2.w); } inline const VxVector4 operator * (const VxVector4& v, float s) { return VxVector4(s*v.x, s*v.y, s*v.z,s*v.w); } inline const VxVector4 operator * (float s, const VxVector4& v) { return VxVector4(s*v.x, s*v.y, s*v.z,s*v.w); } inline const VxVector4 operator / (const VxVector4& v, float s) { float invs = 1.0f / s; return VxVector4(invs*v.x, invs*v.y, invs*v.z,invs*v.w); } // inline int operator == (const VxVector4& v1, const VxVector4& v2) { return ((v1.x==v2.x) && (v1.y == v2.y) && (v1.z == v2.z) && (v1.w == v2.w)); } // inline int operator != (const VxVector4& v1, const VxVector4& v2) { return !(v1==v2); } // Initialization inline void VxVector4::Set(float _x, float _y, float _z,float _w) { x = _x; y = _y; z = _z; w=_w; } // Initialization inline void VxVector4::Set(float _x, float _y, float _z) { x = _x; y = _y; z = _z; } inline const float& VxVector4::operator[](int i) const { #if defined(_LINUX) return *((&x)+i); #else return v[i]; #endif } inline float& VxVector4::operator[](int i) { #if defined(_LINUX) return *((&x)+i); #else return v[i]; #endif } //------------------------------------------------------------------------------------------------------ // VxCompressed Vector //------------------------------------------------------------------------------------------------------- /************************************************* Name: Slerp Summary: Performs a linear interpolation between two vectors. Arguments: v1: A reference to a VxCompressedVectorOld. v2: A reference to a VxCompressedVectorOld. step: The interpolation factor, 0 means v1 and 1 means v2. Remarks: See also: VxVector *************************************************/ inline void VxCompressedVectorOld::Slerp(float step,VxCompressedVectorOld &v1,VxCompressedVectorOld &v2) { int v1y=((int)v1.ya+16384) & 16383; int v2y=((int)v2.ya+16384) & 16383; v2y=(v2y-v1y); if (v2y>8192) v2y=16384-v2y; else if (v2y<-8192) v2y=16384+v2y; xa=(int)((float)v1.xa+(float)(v2.xa-v1.xa)*step); ya=(int)((float)v1y+(float)v2y*step); } // inline VxCompressedVectorOld& VxCompressedVectorOld::operator = (const VxVector& v) { Set(v.x,v.y,v.z); return *this; } /************************************************* Name: Set Summary: Creates a VxCompressedVectorOld from 3 components. Arguments: X,Y,Z: float components. Remarks: See also: VxVector *************************************************/ inline void VxCompressedVectorOld::Set(float X,float Y,float Z) { // calcul de l'angle x xa = -radToAngle((float)asin(Y)); // calcul de l'angle y ya = radToAngle((float)atan2(X,Z)); } // inline VxCompressedVector& VxCompressedVector::operator = (const VxVector& v) { Set(v.x,v.y,v.z); return *this; } /* inline void VxCompressedVector::Set(float X,float Y,float Z) { // calcul de l'angle x xa = (short int)-radToAngle((float)asin(Y)); // calcul de l'angle y ya = (short int)radToAngle((float)atan2(X,Z)); } */ // inline VxCompressedVectorOld& VxCompressedVectorOld::operator = (const VxCompressedVector& v) { xa=(int)v.xa; ya=(int)v.ya; return *this; } // inline VxCompressedVector& VxCompressedVector::operator = (const VxCompressedVectorOld& v) { xa=(short int)v.xa; ya=(short int)v.ya; return *this; } #endif