#pragma once #include #include "memstrm.h" #include "scalar.h" class AbstractVector3D; class Vector3D; class LBE3Vector3D; class TIVector3D; class AffineMatrix; class LinearMatrix; class Matrix4x4; class Point3D; enum Axes { X_Axis, Y_Axis, Z_Axis, W_Axis }; //~~~~~~~~~~~~~~~~~~~~~~~~~ AbstractVector3D ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class AbstractVector3D { public: Scalar x, y , z; #if defined(USE_SIGNATURE) friend int Is_Signature_Bad(const volatile AbstractVector3D *p); #endif AbstractVector3D& operator = (const AbstractVector3D& v); friend Logical Small_Enough(const AbstractVector3D &v, Scalar e=SMALL); Logical operator ! () const { return Small_Enough(*this, SMALL); } friend Logical Close_Enough(const AbstractVector3D &v1, const AbstractVector3D &v2, Scalar e=SMALL); Logical operator == (const AbstractVector3D& v) const { return Close_Enough(*this, v, SMALL); } Logical operator != (const AbstractVector3D& v) const { return !Close_Enough(*this,v,SMALL); } Logical TestInstance() const; protected: AbstractVector3D() {} AbstractVector3D(Scalar x, Scalar y, Scalar z) : x(x), y(y), z(z) {} }; inline MemoryStream& MemoryStream_Read(MemoryStream* stream, AbstractVector3D *output) { return stream->ReadBytes(output, sizeof(*output)); } inline MemoryStream& MemoryStream_Write(MemoryStream* stream, const AbstractVector3D *input) { return stream->WriteBytes(input, sizeof(*input)); } class LBE3Vector3D; class TIVector3D; class AffineMatrix; class LinearMatrix; class Matrix4x4; class Point3D; class Vector3D : public AbstractVector3D { public: static const Vector3D Identity; // // Constructors // Vector3D() {} Vector3D(Scalar x, Scalar y, Scalar z) : AbstractVector3D(x,y,z) {} // // Assignment operators // Vector3D& operator = (const Vector3D &vector) { AbstractVector3D::operator=(vector); return *this; } Vector3D& operator = (const LBE3Vector3D &vector); Vector3D& operator = (const TIVector3D &vector); // Comparison operator (for sorting by length, GDU 1/26/96) Logical operator > (const Vector3D &v) const { return LengthSquared() > v.LengthSquared(); } Logical operator < (const Vector3D &v) const { return LengthSquared() < v.LengthSquared(); } // // Indexing operations // const Scalar& operator[](size_t index) const { Warn(index>Z_Axis); return (&x)[index]; } Scalar& operator[](size_t index) { Warn(index>Z_Axis); return (&x)[index]; } // // The following operators all assume that this points to the destination // of the operation results // Vector3D& Negate(const Vector3D &v); Vector3D& Add(const Vector3D& v1, const Vector3D& v2); Vector3D& AddScaled(const Vector3D& v1, const Vector3D& v2, Scalar scale); Vector3D& operator+=(const Vector3D& v) { return Add(*this,v); } Vector3D& Subtract(const Vector3D& v1, const Vector3D& v2); Vector3D& operator -= (const Vector3D& v) { return Subtract(*this,v); } Scalar operator * (const Vector3D& v) const { Check(this); Check(&v); return x * v.x + y * v.y + z * v.z; } Vector3D& Cross(const Vector3D& v1, const Vector3D& v2); Vector3D& Multiply(const Vector3D& v, Scalar Scale); Vector3D& operator *= (Scalar v) { return Multiply(*this, v); } Vector3D& Multiply(const Vector3D& v1, const Vector3D& v2); Vector3D& operator *= (const Vector3D &v) { return Multiply(*this, v); } Vector3D& Divide(const Vector3D& v, Scalar scale); Vector3D& operator /= (Scalar v) { return Divide(*this,v); } Vector3D& Divide(const Vector3D& v1, const Vector3D& v2); Vector3D& operator /= (const Vector3D &v) { return Divide(*this, v); } // // Transform operators // Vector3D& Multiply(const Vector3D &v, const AffineMatrix &m); Vector3D& operator *= (const AffineMatrix &m) { Vector3D src(*this); return Multiply(src, m); } Vector3D& MultiplyByInverse(const Vector3D &v, const LinearMatrix &m); // // Miscellaneous functions // Scalar LengthSquared() const { Check(this); return x * x + y * y + z * z; } Scalar Length() const { return sqrt(LengthSquared()); } Vector3D& Normalize(const Vector3D &v); Vector3D& Combine(const Vector3D& v1, Scalar t1, const Vector3D& v2, Scalar t2); // // Template support // Vector3D& Lerp(const Vector3D& v1, const Vector3D& v2, Scalar t) { return Combine(v1, 1.0f - t, v2, t); } // // Support functions // friend std::ostream& operator << (std::ostream& stream, const Vector3D& v); static Logical TestClass(); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~ Vector3D functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void Convert_From_Ascii(const char *str, Vector3D *vector_3D); //~~~~~~~~~~~~~~~~~~~~~~~~~~~ LBE3Vector3D ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class LBE3Vector3D : public AbstractVector3D { public: // // Constructors // LBE3Vector3D() {} LBE3Vector3D(Scalar x, Scalar y, Scalar z) : AbstractVector3D(x, y, z) {} // // Assignment operators // LBE3Vector3D& operator = (const LBE3Vector3D &vector) { Check_Pointer(this); Check(&vector); AbstractVector3D::operator=(vector); return *this; } LBE3Vector3D& operator = (const Vector3D& vector); LBE3Vector3D& operator = (const TIVector3D &vector); // // Support functions // friend std::ostream& operator << (std::ostream &stream, const LBE3Vector3D &vector); static Logical TestClass(); }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TIVector3D ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ class TIVector3D : public AbstractVector3D { public: // // Constructors // TIVector3D() {} TIVector3D(Scalar x, Scalar y, Scalar z) : AbstractVector3D(x,y,z) {} // // Assignment operators // TIVector3D& operator = (const TIVector3D &vector) { AbstractVector3D::operator=(vector); return *this; } TIVector3D& operator = (const Vector3D &vector); TIVector3D& operator = (const LBE3Vector3D &vector); // // Support functions // friend std::ostream& operator << (std::ostream &stream, const TIVector3D &vector); static Logical TestClass(); };