#pragma once #include "scalar.h" class Vector3D; class Point3D; class AffineMatrix; class Matrix4x4; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Vector4D ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class Vector4D { public: Scalar x, y, z, w; #if defined(USE_SIGNATURE) friend int Is_Signature_Bad(const volatile Vector4D *); #endif static const Vector4D Identity; // // Constructors // Vector4D() {} Vector4D( Scalar X, Scalar Y, Scalar Z, Scalar W) {x=X; y=Y; z=Z; w=W;} // // Assignment operators // Vector4D& operator=(const Vector4D &v); Vector4D& operator=(const Vector3D &v); Vector4D& operator=(const Point3D &p); // // Index operators // const Scalar& operator[](size_t index) const {Check_Pointer(this); Warn(index>W_Axis); return (&x)[index];} Scalar& operator[](size_t index) {Check_Pointer(this); Warn(index>W_Axis); return (&x)[index];} friend Logical Small_Enough(const Vector4D &v,Scalar e=SMALL); Logical operator!() const {return Small_Enough(*this);} // // "Close-enough" comparison operators // friend Logical Close_Enough( const Vector4D &v1, const Vector4D &v2, Scalar e=SMALL ); Logical operator==(const Vector4D& v) const {return Close_Enough(*this,v);} Logical operator!=(const Vector4D& v) const {return !Close_Enough(*this,v);} // // The following operators all assume that this points to the destination // of the operation results // Vector4D& Negate(const Vector4D &v); Vector4D& Add( const Vector4D& v1, const Vector4D& v2 ); Vector4D& operator+=(const Vector4D& v) {return Add(*this,v);} Vector4D& Subtract( const Vector4D& v1, const Vector4D& v2 ); Vector4D& operator-=(const Vector4D& v) {return Subtract(*this,v);} Scalar operator*(const Vector4D& v) const {Check(this); return x*v.x + y*v.y + z*v.z + w*v.w;} Vector4D& Multiply( const Vector4D& v, Scalar scale ); Vector4D& operator*=(Scalar v) {return Multiply(*this,v);} Vector4D& Multiply( const Vector4D& v1, const Vector4D& v2 ); Vector4D& operator*=(const Vector4D &v) {return Multiply(*this,v);} Vector4D& Divide( const Vector4D& v, Scalar scale ); Vector4D& operator/=(Scalar v) {return Divide(*this,v);} Vector4D& Divide( const Vector4D& v1, const Vector4D& v2 ); Vector4D& operator/=(const Vector4D &v) {return Divide(*this,v);} // // Transforms // Vector4D& Multiply( const Vector4D &v, const AffineMatrix &m ); Vector4D& operator*=(const AffineMatrix &M) {Vector4D src(*this); return Multiply(src,M);} Vector4D& Multiply( const Vector4D &v, const Matrix4x4 &m ); Vector4D& operator*=(const Matrix4x4 &m) {Vector4D src(*this); return Multiply(src,m);} Vector4D& Multiply( const Vector3D &v, const Matrix4x4 &m ); Vector4D& Multiply( const Point3D &p, const Matrix4x4 &m ); // // Support functions // Scalar LengthSquared() const {return operator*(*this);} Scalar Length() const {return Sqrt(LengthSquared());} Vector4D& Combine( const Vector4D& v1, Scalar t1, const Vector4D& v2, Scalar t2 ); Vector4D& Lerp( const Vector4D& v1, const Vector4D& v2, Scalar t ) {return Combine(v1,1.0f-t,v2,t);} friend std::ostream& operator<<(std::ostream& stream, const Vector4D& v); Logical TestInstance() const; static Logical TestClass(); };