This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| mMath Lib Submitted by

mMath is a 3d math library intend for games or real-time 3d Viz applications. It is still in development and is still being tested. Currently it is based around a mFrame and mOCS class similar to classes from Chris Hargrove's COTC articles. Optimizations have currently been kept at a portable level. This may change in the future, but for now, please point out anything that you feel is non-optimal. The vector classes are pretty complete. If I have missed a commonly used function, please tell me. The matrix class is meant to be very simple, because the OCS is meant to be used in most places that a matrix is normally used. The volume classes are still being worked on and will be added shortly. These currently include an axis-aligned bounding box, sphere, plane, and frustum. Ellipsoids, cylinders, and possibly an oriented bounding box will be added later. mMath will continue to be in the public domain. All source will be provided each update. If anyone wishes to help, please email me fixes or additions.
* Description quoted from mMath documentation file.

Currently browsing [mmath.zip] (283,561 bytes) - [examples/mMath/VecOcs/VecOCS.cpp] - (3,966 bytes)

    //****************************************************************************
    //**
    //**    VecOCS.cpp
    //**    Source - Simple example of using the mVec3 and mOCS classes.
    //**    Copyright (C)2000 Douglas H. Cox
    //**
    //**    DHC - 8/3/2000
    //**
    //****************************************************************************
    //============================================================================
    //    Headers
    //============================================================================
    #include <mMath.h>
    #include <mVec3.h>
    #include <mOCS.h>
    #include <mMatrix.h>

    #include <stdio.h>
    //============================================================================
    //    Private Defines / Enums / Typedefs
    //============================================================================

    //============================================================================
    //    Private Structs / Functions / Utility Classes
    //============================================================================

    //============================================================================
    //    Private Data
    //============================================================================

    //============================================================================
    //    Function Implementations
    //============================================================================

    //=============================================================
    // vec3Test
    void vec3Test()
    {
      // mVec3 functions
      mVec3 a, b, r;

      a.set(1.5f, 0.0f, 0.0f);
      a.normalize();

      b.set(0.0f, 2.75f, 0.0f);
      b.normalize();

      r.cross(a, b); // should be pointing in +z direction

    }

    //=============================================================
    // ocsTest
    void ocsTest()
    {
      mOCS parentOCS(mVec3(10.0f, 1.0f, -10.0f), mFrame(), mVec3(), mOCS::ORIGIN);
      mOCS childOCS(mVec3(20.0f, 5.0f, -30.0f),  mFrame(), mVec3(), mOCS::ORIGIN);
      // ^ construct 2 ocs's with only the origin component not an identity value.
      mOCS r;

      unsigned parentType = parentOCS.getType();
      // ^ should = mOCS::ORIGIN

      r.xformFrom(parentOCS, childOCS);

      parentOCS.setOrigin(0.0f, 0.0f, 0.0f);
      parentOCS.setHP(90.0f, 0.0f);
      // ^ Heading=Rotation about Z axis,
      // ^ Pitch=Rotation about the X axis,
      //   Roll=Rotation about the Y axis.

      parentType = parentOCS.getType();
      // ^ should = mOCS::ORIGIN | mOCS::FRAME, because the above setHP
      // modifies the frame component.

      r.xformFrom(childOCS, parentOCS);
      // r can now be thought of as the world->child OCS

      mVec3 a(1.0f, 2.0f, 3.0f);
      mVec3 b;
      mVec3 rv1, rv2;

      rv1.xformFrom(a, childOCS);
      // rv1 is now positioned in the parentOCS
      rv1.xformFrom(rv1, parentOCS);
      // rv1 is now positioned in the world OCS

      rv2.xformFrom(a, r);

      // assert(rv1 == rv2);
      // NOTE: ^ may assert because of precision errors.
      // Viewing the variables in the watch window shows they should be the same.
      assert(rv1.approxEqual(rv2));
      // ^ mVec*.approxEqual and mApproxEqual should be used when comparing
      // transformed points.

      b.xformTo(rv1, r); // go from a point in the world ocs to child ocs.

      // assert(b == a);
      // NOTE: ^ may assert because of precision errors.
      // Viewing the variables in the watch window shows they should be the same.

      assert(b.approxEqual(a));
      // ^ mVec*.approxEqual and mApproxEqual should be used when comparing
      // transformed points.

    }

    //=============================================================
    // main
    void main()
    {
      mInitialize(); // * Must be called 1st.

      // Simple mVec3 testing.
      vec3Test();

      // Simple mOCS testing.
      ocsTest();

      mUninitialize();
    }

    //****************************************************************************
    //**    End - VecOCS.cpp
    //****************************************************************************

Currently browsing [mmath.zip] (283,561 bytes) - [include/mFrame.h] - (4,866 bytes)

    #ifndef __mFrame_H__
    #define __mFrame_H__

    /*!
        \file mFrame.h
        \brief 3D Axial Frame
        \author Douglas H. Cox
    */

    //============================================================================
    //    REQUIRED HEADERS
    //============================================================================
    #include "mMath.h"
    #include "mVec3.h"

    //============================================================================
    //    DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS / CLASS FORWARDS
    //============================================================================
    class mQuat;

    //============================================================================
    //    FUNCTION PROTOTYPES
    //============================================================================

    //============================================================================
    //    CLASS PROTOTYPES
    //============================================================================

    //! 3D Axial Frame
    /*! mFrame represents a 3D Axial Frame.  An axial frame consists
        of three normalized, orthogonal vectors.  These describe a rotation
        value for a give coordinate system.

        Transformations \e from an axial frame perform a rotation
        from the frame's local-space into its parents.  Transformations
        \e to an axial frame perform a rotation from the frame's parent-
        space into its local-space.
        \sa http://www.loonygames.com/content/1.29/cotc/  */
    class MMATH_DLL mFrame
    {
    public:
      mVec3 a[3]; //!< normalized x, y, z axes. right handed.

      //! Default constructor
      /*! No initialization is done here. */
      mFrame()
      {
      }

      //! Copy constructor
      mFrame(const mFrame& src)
      {
        a[0].set(src.a[0]);
        a[1].set(src.a[1]);
        a[2].set(src.a[2]);
      }

      //! Constructor from 3 normalized, orthogonal axes.
      mFrame(const mVec3& x, const mVec3& y, const mVec3& z)
      {
        a[0].set(x);
        a[1].set(y);
        a[2].set(z);
      }

      //! Set this to cartesian axes.
      void makeIdentity()
      {
        a[0].set(1.0f, 0.0f, 0.0f);
        a[1].set(0.0f, 1.0f, 0.0f);
        a[2].set(0.0f, 0.0f, 1.0f);
      }

      //! Assignment
      void set(const mFrame& src)
      {
        a[0].set(src.a[0]);
        a[1].set(src.a[1]);
        a[2].set(src.a[2]);
      }

      //! Assignment from 3 normalized, orthogonal axes
      void set(const mVec3& x, const mVec3& y, const mVec3& z)
      {
        a[0].set(x);
        a[1].set(y);
        a[2].set(z);
      }

      //! Assignment
      mFrame& operator = (const mFrame& src)
      {
        a[0].set(src.a[0]);
        a[1].set(src.a[1]);
        a[2].set(src.a[2]);
        return *this;
      }

      //! Accessor
      void get(mVec3& x, mVec3& y, mVec3& z) const
      {
        x.set(a[0]);
        y.set(a[1]);
        z.set(a[2]);
      }

      //! Accessor
      mVec3& operator [] (int i)
      {
        return a[i];
      }

      //! Accessor
      const mVec3& operator [] (int i) const
      {
        return a[i];
      }

      //! Returns true if this == f
      bool operator == (const mFrame& f) const
      {
        return( a[0] == f.a[0] &&
                a[1] == f.a[1] &&
                a[2] == f.a[2] );
      }

      //! Returns true if this != f
      bool operator != (const mFrame& f) const
      {
        return !(operator==(f));
      }

      //! Returns true is this is within some tolerance value of \em f.
      bool approxEqual(const mFrame& f, float tol = mZeroTol) const;

      //! Computes the inverse of f.
      void inverse();

      //! Computes the inverse of f.
      void inverse(const mFrame& f);

      //! Transforms f into 'to's axial frame.
      void xformTo(const mFrame& f, const mFrame& to);

      //! Transforms f from 'from's axial frame.
      void xformFrom(const mFrame& f, const mFrame& from);

      //! Sets this to the rotation defined by the quaternion q.
      void setQuat(const mQuat& q);

      //! Gets a normalized quaternion.
      void getQuat(mQuat& q) const;

      //! Sets this to a rotation about a unit vector n. a is in degrees.
      void setAxisAngle(const mVec3& n, float a);

      //! Gets an angle about a unit vector n.
      void getAxisAngle(mVec3& n, float& a) const;

      //! Sets this to a rotation defined by the heading and pitch in degrees.
      /*! This assumes a roll of 0.0f and is faster than the full setHPR method.
          \todo: Test this. */
      void setHP(float heading, float pitch);

      //! Sets this to a rotation defined by heading, pitch, and roll in degrees.
      /*! \todo: Test this. */
      void setHPR(float heading, float pitch, float roll);

      //! Sets this to a rotation defined by heading, pitch, and roll in degrees.
      void setHPR(const mVec3& hpr)
      {
        setHPR(hpr.v[0], hpr.v[1], hpr.v[2]);
      }

    };

    //****************************************************************************
    //**    END HEADER mFrame.h
    //****************************************************************************
    #endif // __mFrame_H__

Currently browsing [mmath.zip] (283,561 bytes) - [include/mMath.h] - (8,331 bytes)

    #ifndef __mMath_H__
    #define __mMath_H__

    /*!
        \file mMath.h
        \brief Main mMath include file.
        \author Douglas Cox
    */

    //=============================================================
    //    DOCUMENTATION
    //=============================================================

    /*!
      \mainpage mMath Library
      \section Introduction Introduction
      mMath is a 3d math library intend for games or real-time 3d Viz
      applications.  It is still in development and is still being tested.
      Currently it is based around a mFrame and mOCS class similar to
      classes from Chris Hargrove's COTC articles.

      Optimizations have currently been kept at a portable level.  This
      may change in the future, but for now, please point out anything
      that you feel is non-optimal.

      The vector classes are pretty complete.  If I have missed a commonly
      used function, please tell me.  The matrix class is meant to be
      very simple, because the OCS is meant to be used in most places
      that a matrix is normally used.

      The volume classes are still being worked on and will be added shortly.
      These currently include an axis-aligned bounding box, sphere, plane,
      and frustum.  Ellipsoids, cylinders, and possibly an oriented bounding
      box will be added later.

      mMath will continue to be in the public domain.  All source will be
      provided each update.  If anyone wishes to help, please email me fixes
      or additions.

      <a href="http://www.doxygen.org>Doxygen</a> was used for all documentation.

      \section BeforeYouBegin Before You Begin
      Before you begin using any classes from the library, you should note
      the following:  mMath uses a right-handed, +Z = up, +Y = forward (into
      the screen), +X = right coordinate system.  This is different than
      OpenGL (right-handed, +Y = up, -Z = forward, +X = right) and Direct3D
      (left-handed, +Y = up, +Z = forward, +X = right).  Future examples
      will show how to convert to the desired API format.

      Also, heading is defined as a rotation about the +Z axis, pitch is
      a rotation about the +X axis, and roll is a rotation about the +Y axis.

      Finally, make sure you call mInitialize before calling any functions
      in this library.

      \section Compiling Compiling
      mMath.dsp compiles the library into a Win32 DLL.  If you wish to
      compile the code into a large DLL or executable, #define MMATH_STATIC
      in your project's settings (Project / Settings / C++ / Preprocessor
      definitions).
      This code should compile on non-Windows OSs.  If not, please email any
      corrections.

      \section Examples Examples
      Currently there is only a single, very simple example.  It briefly
      demonstrates how to use the mOCS class.  Other examples will be added
      shortly.  Please browse through the per-class documentation as well
      as the source code for further help.

    */

    //============================================================================
    //    REQUIRED HEADERS
    //============================================================================

    #ifdef WIN32
      #include <float.h>
    #endif // WIN32

    #include <assert.h>
    #include <math.h>

    //============================================================================
    //    DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS / CLASS FORWARDS
    //============================================================================

    // Define MMATH_DLL for proper import/export behavior.
    #ifndef WIN32
      #define MMATH_DLL
    #else
      #ifdef MMATH_STATIC
      // ^ Define MMATH_STATIC to compile .cpp files statically
      //   with another project.
        #define MMATH_DLL
      #else
        #ifdef MMATH_EXPORTS
        // ^ Should be defined by the project building the DLL.
          #define MMATH_DLL __declspec(dllexport)
        #else
          #define MMATH_DLL __declspec(dllimport)
          #ifdef _DEBUG
            #pragma comment(lib, "mMath-dbg")
          #else
            #pragma comment(lib, "mMath")
          #endif
        #endif
      #endif
    #endif

    // Common constants

    //! The smallest possible floating point value.
    #define mFloatMin (FLT_MIN)

    //! The largest possible floating point value.
    #define mFloatMax (FLT_MAX)

    //! PI
    #define mPI 3.1415926536f

    //! mPI / 2
    #define mHalfPI 1.5707963268f

    //! A value < this is equal to zero.
    #define mZeroTol 0.000001f

    // Square root table used for fast square root function.
    MMATH_DLL extern unsigned int mFastSqrtTable[0x10000];

    // Macro used by fast sqrt function. (nVidia)
    #define mFPBits(fp) (*(unsigned *)&(fp))

    //============================================================================
    //    FUNCTION PROTOTYPES
    //============================================================================

    //! Initializes the math library.
    /*! This must be called before using any functions in this library. */
    MMATH_DLL bool mInitialize();

    //! Uninitializes the math library.
    MMATH_DLL void mUninitialize();

    //! Returns the absolute value of x.
    inline float mAbs(float x)
    {
      return (x < 0.0f) ? -x : x;
    }

    //! Returns the smaller value.
    template<class T>
    inline T mMin(T a, T b)
    {
      return (a < b ? a : b);
    }

    //! Returns the larger value.
    template<class T>
    inline T mMax(T a, T b)
    {
      return (a > b ? a : b);
    }

    //! Returns the remainder of a / b.
    inline float mMod(float a, float b)
    {
      int n = int(a / b);
      a -= n * b;
      return (a < 0.0f) ? (a + b) : a;
    }

    //! Returns the floor of x.
    inline float mFloor(float x)
    {
      int ix = int(x);
      return float(ix - (x < 0.0f && x != float(ix)));
    }

    //! Returns the ceiling of x.
    inline float mCeil(float x)
    {
      int ix = int(x);
      return float(ix + (x > 0.0f && x != float(ix)));
    }

    //! Clamps x to a specific range [a, b].
    inline float mClamp(float x, float a, float b)
    {
      return (x < a ? a : (x > b ? b : x));
    }

    //! Returns true if a is approximately equal to b +- tol.
    inline bool mApproxEqual(float a, float b, float tol = mZeroTol)
    {
      return (mAbs(a-b) <= tol);
    }

    //! Rounds x to the closest integer.
    inline int mRound(float x)
    {
      return int(x + 0.5f);
    }

    //! Returns x * x.
    inline float mSquare(float x)
    {
      return (x*x);
    }

    //! Table-based square root of x. (nVidia)
    inline float mSqrt(float x)
    {
      if (mFPBits(x) == 0)
        return 0.0f;

      mFPBits(x) = mFastSqrtTable[(mFPBits(x) >> 8) & 0xFFFF] |
        ((((mFPBits(x) - 0x3F800000) >> 1) + 0x3F800000) & 0x7F800000);

      return x;
    }

    //! Slower but more accurate version of mSqrt.
    inline float mSlowSqrt(float x)
    {
      return float(sqrt(x));
    }

    //! Converts radians to degrees
    inline float mRadToDeg(float x)
    {
      return (x * 57.295779513f);
    }

    //! Converts degrees to radians
    inline float mDegToRad(float x)
    {
      return (x * 0.017453292520f);
    }

    //! Calculates the cosine of a in degrees.
    inline float mCos(float a)
    {
      return float(cos(mDegToRad(a)));
    }

    //! Calculates the arc cosine of a in degrees.
    inline float mACos(float a)
    {
      return mRadToDeg(float(acos(mClamp(a, -1.0f, 1.0f))));
    }

    //! Calculates the sine of a in degrees.
    inline float mSin(float a)
    {
      return float(sin(mDegToRad(a)));
    }

    //! Calculates the arc sine of a in degrees.
    inline float mASin(float a)
    {
      return mRadToDeg(float(asin(mClamp(a, -1.0f, 1.0f))));
    }

    //! Calculates the sine and cosine of a in degrees.
    inline void mSinCos(float a, float& sine, float& cosine)
    {
      a = mDegToRad(a);
      sine = float(sin(a));
      cosine = float(cos(a));

      // Don't Intel CPUs have a SINCOS op?
    }

    //! Calculates the tangent of a in degrees.
    inline float mTan(float a)
    {
      return float(tan(mDegToRad(a)));
    }

    //! Calculates the arc tangent of x in degrees.
    inline float mATan(float x)
    {
      return mRadToDeg(float(atan(x)));
    }

    //! Calculates the arc tangent of y/x in degrees.
    inline float mATan2(float y, float x)
    {
      return mRadToDeg(float(atan2(y, x)));
    }

    //============================================================================
    //    CLASS PROTOTYPES
    //============================================================================

    //****************************************************************************
    //**    END HEADER mMath.h
    //****************************************************************************
    #endif // __mMath_H__

Currently browsing [mmath.zip] (283,561 bytes) - [include/mMatrix.h] - (2,133 bytes)

    #ifndef __mMatrix_H__
    #define __mMatrix_H__

    /*!
        \file mMatrix.h
        \brief 4x4 Column-order Matrix
        \author Douglas H. Cox
    */

    //============================================================================
    //    REQUIRED HEADERS
    //============================================================================
    #include "mMath.h"

    //============================================================================
    //    DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS / CLASS FORWARDS
    //============================================================================

    //============================================================================
    //    FUNCTION PROTOTYPES
    //============================================================================

    //============================================================================
    //    CLASS PROTOTYPES
    //============================================================================

    //! 4x4 Column-order Matrix
    /*! Matrices are meant to be used only when needed by the
        rendering API.  OCSes should be used instead.
        \sa mOCS::getMatrix()
    */
    class MMATH_DLL mMatrix
    {
    public:
      float m[16]; //!< Matrix data in column order.

    public:
      //! Default constructor
      /*! No initialization is done here.
      */
      mMatrix()
      {
      }

      //! Copy constructor
      mMatrix(const mMatrix& src)
      {
        set(src);
      }

      //! Assignment
      void set(const mMatrix& src);

      //! Assignment
      mMatrix& operator = (const mMatrix& src)
      {
        set(src);
        return *this;
      }

      //! Accessor
      float& operator [] (int i)
      {
        return m[i];
      }

      //! Accessor
      float operator [] (int i) const
      {
        return m[i];
      }

      //! Creates an identity matrix.
      void makeIdentity();

      //! Multiplies matrix a by matrix b.
      /*! \todo Optimize this. */
      void mult(const mMatrix& a, const mMatrix& b);

    };

    //****************************************************************************
    //**    END HEADER mMatrix.h
    //****************************************************************************
    #endif // __mMatrix_H__

Currently browsing [mmath.zip] (283,561 bytes) - [include/mOCS.h] - (7,059 bytes)

    #ifndef __mOCS_H__
    #define __mOCS_H__

    /*!
        \file mOCS.h
        \brief 3D Orthogonal Coordinate System
        \author Douglas H. Cox
    */

    //============================================================================
    //    REQUIRED HEADERS
    //============================================================================
    #include "mMath.h"
    #include "mVec3.h"
    #include "mFrame.h"

    //============================================================================
    //    DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS / CLASS FORWARDS
    //============================================================================
    class mQuat;
    class mMatrix;

    //============================================================================
    //    FUNCTION PROTOTYPES
    //============================================================================

    //============================================================================
    //    CLASS PROTOTYPES
    //============================================================================

    //! 3D Orthogonal Coordinate System
    /*! mOCS represents a 3D Orthogonal Coordinate System.
        \sa http://www.loonygames.com/content/1.29/cotc/
    */
    class MMATH_DLL mOCS
    {
    private:
      mVec3  o; //!< OCS origin.
      mFrame f; //!< OCS axial frame.
      mVec3  s; //!< OCS axis scale.

    public:
      enum TYPE
      {
        IDENTITY = 0x00,
        ORIGIN   = 0x01,
        FRAME    = 0x02,
        SCALE    = 0x04
      };

    private:
      unsigned type; //!< Specifies the valid components of the OCS.

      friend class mVec3;
      friend class mRay;

    public:
      //! Default constructor
      /*! Initialized to origin at zero, cartesian axes, and unit scale. */
      mOCS()
      {
        type = IDENTITY;
        makeIdentity();
      }

      //! Copy constructor
      mOCS(const mOCS& src);

      //! Constructor specifying origin, axial frame, and scale.
      /*! Example:

          mOCS ocs(&origin, &rot, NULL);

          would create an OCS with an \em origin and a \em frame component.
          Types not specified by \em type are set to an identity value. */
      mOCS(const mVec3& origin,
           const mFrame& frame,
           const mVec3& scale,
           unsigned type = ORIGIN | FRAME | SCALE);

      //! Origin at zero, cartesian axes, unit scale.
      void makeIdentity();

      //! Creates an ocs with specified origin, unit scale, and cartesian axes.
      void makeOrigin(const mVec3& origin)
      {
        makeOrigin(origin[0], origin[1], origin[2]);
      }

      //! Creates an ocs with specified origin, unit scale, and cartesian axes.
      void makeOrigin(float x, float y, float z);

      //! Creates an ocs with specified frame, origin at zero, and unit scale.
      void makeFrame(const mFrame& frame);

      //! Creates an ocs with specified scale, origin at zero, and cartesian axes.
      void makeScale(const mVec3& scale)
      {
        makeScale(scale[0], scale[1], scale[2]);
      }

      //! Creates an ocs with specified scale, origin at zero, and cartesian axes.
      void makeScale(float x, float y, float z);

      //! Assignment
      void set(const mOCS& src);

      //! Assignment specifying origin, axial frame, and scale.
      /*! Types not specified by \em type are set to an identity value. */
      void set(const mVec3& origin,
               const mFrame& frame,
               const mVec3& scale,
               unsigned type = ORIGIN | FRAME | SCALE);

      //! Assignment
      void setOrigin(const mVec3& origin)
      {
        o.set(origin);
        type |= ORIGIN;
      }

      //! Assignment
      void setOrigin(float x, float y, float z)
      {
        o.set(x, y, z);
        type |= ORIGIN;
      }

      //! Assignment
      void setFrame(const mFrame& frame)
      {
        f.set(frame);
        type |= FRAME;
      }

      //! Sets the axial frame to the rotation defined by the quaternion q.
      /*! This call only affects the axial frame. */
      void setQuat(const mQuat& q)
      {
        f.setQuat(q);
        type |= FRAME;
      }

      //! Sets the axial frame to a rotation about a unit vector n. a is in degrees.
      /*! This call only affects the axial frame. */
      void setAxisAngle(const mVec3& n, float a)
      {
        f.setAxisAngle(n, a);
        type |= FRAME;
      }

      //! Sets this to a rotation defined by the heading and pitch in degrees.
      /*! This assumes a roll of 0.0f and is faster than the full setHPR method. */
      void setHP(float heading, float pitch)
      {
        f.setHP(heading, pitch);
        type |= FRAME;
      }

      //! Sets this to a rotation defined by heading, pitch, and roll in degrees.
      void setHPR(float heading, float pitch, float roll)
      {
        f.setHPR(heading, pitch, roll);
        type |= FRAME;
      }

      //! Sets this to a rotation defined by heading, pitch, and roll in degrees.
      void setHPR(const mVec3& hpr)
      {
        setHPR(hpr.v[0], hpr.v[1], hpr.v[2]);
      }

      //! Assignment
      void setScale(const mVec3& scale)
      {
        s.set(scale);
        type |= SCALE;
      }

      //! Assignment
      void setScale(float x, float y, float z)
      {
        s.set(x, y, z);
        type |= SCALE;
      }

      //! Assignment
      mOCS& operator = (const mOCS& src)
      {
        set(src);
        return *this;
      }

      //! Accessor
      void get(mVec3& origin, mFrame& frame, mVec3& scale) const;

      //! Accessor
      const mVec3* getOrigin() const
      {
        return &o;
      }

      //! Accessor
      const mFrame* getFrame() const
      {
        return &f;
      }

      //! Accessor
      const mVec3* getScale() const
      {
        return &s;
      }

      //! Returns the type of valid components in the OCS.
      unsigned getType() const
      {
        return type;
      }

      //! Returns true if the two OCSs are equal.
      bool operator == (const mOCS& ocs) const;

      //! Returns true if the two OCSs are not equal.
      bool operator != (const mOCS& ocs) const
      {
        return !(operator==(ocs));
      }

      //! Returns true is this is within some tolerance value of \em ocs.
      bool approxEqual(const mOCS& ocs, float tol = mZeroTol) const;

      //! Computes the inverse of f.
      void inverse(const mOCS& ocs);

      //! Transforms ocs into 'to's coordinate system.
      /*! \param ocs OCS that will be transformed
          \param to OCS that ocs will be transformed to */
      void xformTo(const mOCS& ocs, const mOCS& to);

      //! Transforms ocs from 'from's coordinate system.
      /*! \param ocs OCS that will be transformed
          \param from OCS that ocs will be transformed from */
      void xformFrom(const mOCS& ocs, const mOCS& from);

      //! Builds a matrix that transforms object into this OCS.
      /*! This builds an OpenGL compatible matrix. That is,
          one that can be loaded into a modelview matrix. */
      void getToMatrix(mMatrix& matrix) const;

      //! Builds a matrix that transforms object from this OCS.
      /*! This builds an OpenGL compatible matrix. That is,
          one that can be loaded into a modelview matrix. */
      void getFromMatrix(mMatrix& matrix) const;
    };

    //****************************************************************************
    //**    END HEADER mOCS.h
    //****************************************************************************
    #endif // __mOCS_H__

Currently browsing [mmath.zip] (283,561 bytes) - [include/mQuat.h] - (3,951 bytes)

    #ifndef __mQuat_H__
    #define __mQuat_H__

    /*!
        \file mQuat.h
        \brief Quaterion
        \author Douglas H. Cox
    */

    //============================================================================
    //    REQUIRED HEADERS
    //============================================================================
    #include "mMath.h"
    #include "mVec4.h"
    #include "mVec3.h"
    #include "mFrame.h"

    //============================================================================
    //    DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS / CLASS FORWARDS
    //============================================================================

    //============================================================================
    //    FUNCTION PROTOTYPES
    //============================================================================

    //============================================================================
    //    CLASS PROTOTYPES
    //============================================================================

    //! Quaternion
    /*! mQuat represents a quaternion.
        \sa http://mathworld.wolfram.com/Quaternion.html
    */
    class MMATH_DLL mQuat : public mVec4
    {
    public:
      //! Default constructor
      /*! No initialization is done here. */
      mQuat() {}

      //! Copy constructor
      mQuat(const mQuat& src)
      {
        v[0] = src.v[0];
        v[1] = src.v[1];
        v[2] = src.v[2];
        v[3] = src.v[3];
      }

      //! Constructor from 4 float values
      mQuat(float x, float y, float z, float w)
      {
        v[0] = x;
        v[1] = y;
        v[2] = z;
        v[3] = w;
      }

      //! Constructor from an array of 4 float values
      mQuat(float *src)
      {
        v[0] = src[0];
        v[1] = src[1];
        v[2] = src[2];
        v[3] = src[3];
      }

      //! Sets this to its conjugate
      void conjugate()
      {
        v[0] = -v[0];
        v[1] = -v[1];
        v[2] = -v[2];
      }

      //! Set this to the conjugate of q
      void conjugate(const mQuat& q)
      {
        v[0] = -q.v[0];
        v[1] = -q.v[1];
        v[2] = -q.v[2];
        v[3] = q.v[3];
      }

      //! Computes the inverse of this. this = 1 / this
      void inverse();

      //! Computes the inverse of q. this = 1 / q
      void inverse(const mQuat& q);

      //! Multiply: this *= q
      void mult(const mQuat& q)
      {
        mult(*this, q);
      }

      //! Multiply: this = q1 * q2
      void mult(const mQuat& q1, const mQuat& q2);

      //! Spherical linear interpolation between q1 and q2.
      void slerp(const mQuat& q1, const mQuat& q2, float t);

      //! Sets this to the rotation about a unit vector n. a is in degrees.
      void setAxisAngle(const mVec3& n, float a);

      //! Gets an angle about a unit vector n defined by this quaternion.
      void getAxisAngle(mVec3& n, float& a) const;

      //! Sets this to the rotation defined by the heading and pitch in degrees.
      /*! This assumes a roll of 0.0f and is faster than the full setHPR method. */
      void setHP(float heading, float pitch);

      //! Returns the heading and pitch defined by this quaternion.
      void getHP(float &heading, float &pitch) const;

      //! Sets this to the rotation defined by heading, pitch, and roll in degrees.
      void setHPR(float heading, float pitch, float roll);

      //! Sets this to the rotation defined by heading, pitch, and roll in degrees.
      void setHPR(const mVec3& hpr)
      {
        setHPR(hpr.v[0], hpr.v[1], hpr.v[2]);
      }

      //! Returns the heading and pitch defined by this quaternion.
      /*! \todo Implement this. */
      void getHPR(mVec3& hpr) const;

      //! Set this to the rotation defined by frame.
      void setFrame(const mFrame& frame)
      {
        frame.getQuat(*this);
      }

      //! Assigns a frame to the rotation defined by this quaternion.
      void getFrame(mFrame& frame) const
      {
        frame.setQuat(*this);
      }

    };

    //****************************************************************************
    //**    END HEADER mQuat.h
    //****************************************************************************
    #endif // __mQuat_H__

Currently browsing [mmath.zip] (283,561 bytes) - [include/mRay.h] - (3,187 bytes)

    #ifndef __mRay_H__
    #define __mRay_H__

    /*!
        \file mRay.h
        \brief Ray class.
        \author Douglas H. Cox
    */

    //============================================================================
    //    REQUIRED HEADERS
    //============================================================================
    #include "mVec3.h"

    //============================================================================
    //    DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS / CLASS FORWARDS
    //============================================================================
    class mOCS;

    //============================================================================
    //    FUNCTION PROTOTYPES
    //============================================================================

    //============================================================================
    //    CLASS PROTOTYPES
    //============================================================================

    //! Ray class.
    class MMATH_DLL mRay
    {
    public:
      mVec3 pos; //!< position of the ray.
      mVec3 dir; //!< normalized direction the ray points.
      float len; //!< length of the ray. if = -1, ray is infinite.

      //! Default constructor
      /*! No initialization is done here.  */
      mRay()
      {
      }

      //! Copy constructor
      mRay(const mRay& src) : pos(src.pos),
                              dir(src.dir),
                              len(src.len)
      {
      }

      //! Constructor from position, direction, and length.
      mRay(const mVec3& position,
           const mVec3& direction,
           const float  length) : pos(position),
                                  dir(direction),
                                  len(length)
      {
      }

      //! Constructor from two points.
      mRay(const mVec3& startPoint, const mVec3& endPoint)
      {
        set(startPoint, endPoint);
      }

      //! Assignment
      void set(const mRay& src)
      {
        pos.set(src.pos);
        dir.set(src.dir);
        len = src.len;
      }

      //! Assignment from position, direction, and length.
      void set(const mVec3& position,
               const mVec3& direction,
               const float  length)
      {
        pos.set(position);
        dir.set(direction);
        len = length;
      }

      //! Assignment from two points.
      void set(const mVec3& startPoint, const mVec3& endPoint);

      //! Returns the starting point for this ray.
      void getStartPoint(mVec3& start) const
      {
        start.set(pos);
      }

      //! Returns the ending point for this ray.
      /*! \todo Check the case when len == -1. */
      void getEndPoint(mVec3& end) const;

      //! Returns true if the two rays are the same.
      bool operator == (const mRay& ray) const;

      //! Returns true if the two rays are not the same.
      bool operator != (const mRay& ray) const
      {
        return !(operator==(ray));
      }

      //! Transforms the ray into the OCS.
      void xformTo(const mRay& ray, const mOCS& ocs);

      //! Transforms the ray from the OCS.
      void xformFrom(const mRay& ray, const mOCS& ocs);

    };

    //****************************************************************************
    //**    END HEADER mRay.h
    //****************************************************************************
    #endif // __mRay_H__

Currently browsing [mmath.zip] (283,561 bytes) - [include/mVec2.h] - (7,641 bytes)

    #ifndef __mVec2_H__
    #define __mVec2_H__

    /*!
        \file mVec2.h
        \brief 2D Vector
        \author Douglas H. Cox
    */

    //============================================================================
    //    REQUIRED HEADERS
    //============================================================================
    #include "mMath.h"

    //============================================================================
    //    DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS / CLASS FORWARDS
    //============================================================================

    //============================================================================
    //    FUNCTION PROTOTYPES
    //============================================================================

    //============================================================================
    //    CLASS PROTOTYPES
    //============================================================================

    //! 2D Vector / Point
    /*! mVec2 represents a vector consisting of an array of two float values. */
    class MMATH_DLL mVec2
    {
    public:
      float v[2];   //!< vector data

      //! Default constructor
      /*! No initialization is done here. */
      mVec2() {}

      //! Copy constructor
      mVec2(const mVec2& src)
      {
        v[0] = src.v[0];
        v[1] = src.v[1];
      }

      //! Constructor from 2 float values
      mVec2(float x, float y)
      {
        v[0] = x;
        v[1] = y;
      }

      //! Constructor from an array of 2 float values
      mVec2(float *src)
      {
        v[0] = src[0];
        v[1] = src[1];
      }

      //! Assignment
      void set(const mVec2& src)
      {
        v[0] = src.v[0];
        v[1] = src.v[1];
      }

      //! Assignment from 2 float values
      void set(float x, float y)
      {
        v[0] = x;
        v[1] = y;
      }

      //! Assignment from an arry of 2 float values
      void set(float *src)
      {
        v[0] = src[0];
        v[1] = src[1];
      }

      //! Assignment
      mVec2& operator = (const mVec2& src)
      {
        v[0] = src.v[0];
        v[1] = src.v[1];
        return *this;
      }

      //! Accessor
      void get(float& x, float& y) const
      {
        x = v[0];
        y = v[1];
      }

      //! Accessor
      float& operator [] (int i)
      {
        return v[i];
      }

      //! Accessor
      float operator [] (int i) const
      {
        return v[i];
      }

      //! Returns true if this == a
      bool operator == (const mVec2& a) const
      {
        return( v[0] == a.v[0] &&
                v[1] == a.v[1] );
      }

      //! Returns true if this != a
      bool operator != (const mVec2& a) const
      {
        return !(operator==(a));
      }

      //! Returns true is this is equal to a within some tolerance value.
      bool approxEqual(const mVec2& a, float tol = mZeroTol)
      {
        return( mApproxEqual(v[0], a.v[0], tol) &&
                mApproxEqual(v[1], a.v[1], tol) );
      }

      //! Sets each component to the min of this and a.
      void setMin(const mVec2& a)
      {
        if (a.v[0] < v[0]) v[0] = a.v[0];
        if (a.v[1] < v[1]) v[1] = a.v[1];
      }

      //! Sets each component to the max of this and a.
      void setMax(const mVec2& a)
      {
        if (a.v[0] > v[0]) v[0] = a.v[0];
        if (a.v[1] > v[1]) v[1] = a.v[1];
      }

      //! Clamps each component of this to [a, b]
      void clamp(float a, float b)
      {
        v[0] = mClamp(v[0], a, b);
        v[1] = mClamp(v[1], a, b);
      }

      //! Clamps each component of vec to [a, b]
      void clamp(const mVec2& vec, float a, float b)
      {
        v[0] = mClamp(vec.v[0], a, b);
        v[1] = mClamp(vec.v[1], a, b);
      }

      //! Addition: this += a
      void add(const mVec2& a)
      {
        v[0] += a.v[0];
        v[1] += a.v[1];
      }

      //! Addition: this = a + b
      void add(const mVec2& a, const mVec2& b)
      {
        v[0] = a.v[0] + b.v[0];
        v[1] = a.v[1] + b.v[1];
      }

      //! Addition: Returns this + a
      mVec2 operator + (const mVec2& a) const
      {
        return mVec2(v[0] + a.v[0],
                     v[1] + a.v[1]);
      }

      //! Addition: this += a
      mVec2& operator += (const mVec2& a)
      {
        v[0] += a.v[0];
        v[1] += a.v[1];
        return *this;
      }

      //! this += a * s
      void addScaled(const mVec2& a, float s)
      {
        v[0] += a.v[0] * s;
        v[1] += a.v[1] * s;
      }

      //! this = a + b * s
      void addScaled(const mVec2& a, const mVec2& b, float s)
      {
        v[0] = a.v[0] + b.v[0] * s;
        v[1] = a.v[1] + b.v[1] * s;
      }

      //! this = a * s1 + b * s2
      void addScaled(const mVec2& a, float s1,
                     const mVec2& b, float s2)
      {
        v[0] = a.v[0] * s1 + b.v[0] * s2;
        v[1] = a.v[1] * s1 + b.v[1] * s2;
      }

      //! Subtraction: this -= a
      void sub(const mVec2& a)
      {
        v[0] -= a.v[0];
        v[1] -= a.v[1];
      }

      //! Subtraction: this = a - b
      void sub(const mVec2& a, const mVec2& b)
      {
        v[0] = a.v[0] - b.v[0];
        v[1] = a.v[1] - b.v[1];
      }

      //! Subtraction: Returns this - a
      mVec2 operator - (const mVec2& a) const
      {
        return mVec2(v[0] - a.v[0],
                     v[1] - a.v[1]);
      }

      //! Subtraction: this -= a
      mVec2& operator -= (const mVec2& a)
      {
        v[0] -= a.v[0];
        v[1] -= a.v[1];
        return *this;
      }

      //! Scales each component by s.
      void scale(float s)
      {
        v[0] *= s;
        v[1] *= s;
      }

      //! Scales each component of a by s.
      void scale(const mVec2& a, float s)
      {
        v[0] = a.v[0] * s;
        v[1] = a.v[1] * s;
      }

      //! Scales each component by s.
      mVec2& operator *= (float s)
      {
        v[0] *= s;
        v[1] *= s;
        return *this;
      }

      //! Negate: this = -this
      void neg()
      {
        v[0] = -v[0];
        v[1] = -v[1];
      }

      //! Negate: this = -a
      void neg(const mVec2& a)
      {
        v[0] = -a.v[0];
        v[1] = -a.v[1];
      }

      //! Negate: Returns -this
      mVec2 operator - () const
      {
        return mVec2(-v[0], -v[1]);
      }

      //! Component multiplication
      void compMult(const mVec2& a)
      {
        v[0] *= a[0];
        v[1] *= a[1];
      }

      //! Component multiplication
      void compMult(const mVec2& a, const mVec2& b)
      {
        v[0] = a[0] * b[0];
        v[1] = a[1] * b[1];
      }

      //! Component division
      void compDiv(const mVec2& a)
      {
        v[0] /= a[0];
        v[1] /= a[1];
      }

      //! Component division
      void compDiv(const mVec2& a, const mVec2& b)
      {
        v[0] = a[0] * b[0];
        v[1] = a[1] * b[1];
      }

      //! Returns the distance squared between this and a.
      float distance2(const mVec2& a) const
      {
        return( mSquare(v[0] - a.v[0]) +
                mSquare(v[1] - a.v[1]) );
      }

      //! Returns the distance between this and a.
      float distance(const mVec2& a) const
      {
        return( mSqrt(distance2(a)) );
      }

      //! Returns the length squared of this.
      float length2() const
      {
        return( mSquare(v[0]) +
                mSquare(v[1]) );
      }

      //! Returns the length of this.
      float length() const
      {
        return( mSqrt(length2()) );
      }

      //! Returns the dot product of this and a.
      float dot(const mVec2& a) const
      {
        return( v[0] * a.v[0] +
                v[1] * a.v[1] );
      }

      //! Normalizes this and returns the previous length.
      float normalize()
      {
        float l(length());
        if (l != 0.0f) scale(1.0f / l);
        return l;
      }

      //! Linearly interpolates between two vectors.
      void lerp(const mVec2& a, const mVec2& b, float t)
      {
        v[0] = a.v[0] + t * (b.v[0] - a.v[0]);
        v[1] = a.v[1] + t * (b.v[1] - a.v[1]);
      }

    };

    // Common constant values.
    const mVec3 mZero2(0.0f, 0.0f);
    const mVec3 mOne2(1.0f, 1.0f);

    //****************************************************************************
    //**    END HEADER mVec2.h
    //****************************************************************************
    #endif // __mVec2_H__

Currently browsing [mmath.zip] (283,561 bytes) - [include/mVec3.h] - (10,352 bytes)

    #ifndef __mVec3_H__
    #define __mVec3_H__

    /*!
        \file mVec3.h
        \brief 3D Vector
        \author Douglas H. Cox
    */

    //============================================================================
    //    REQUIRED HEADERS
    //============================================================================
    #include "mMath.h"

    //============================================================================
    //    DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS / CLASS FORWARDS
    //============================================================================
    class mFrame;
    class mOCS;
    //============================================================================
    //    FUNCTION PROTOTYPES
    //============================================================================

    //============================================================================
    //    CLASS PROTOTYPES
    //============================================================================

    //! 3D Vector / Point
    /*! mVec3 represents a vector consisting of an array of three float values. */
    class MMATH_DLL mVec3
    {
    public:
      float v[3];   //!< vector data

      //! Default constructor
      /*! No initialization is done here. */
      mVec3() {}

      //! Copy constructor
      mVec3(const mVec3& src)
      {
        v[0] = src.v[0];
        v[1] = src.v[1];
        v[2] = src.v[2];
      }

      //! Constructor from 3 float values
      mVec3(float x, float y, float z)
      {
        v[0] = x;
        v[1] = y;
        v[2] = z;
      }

      //! Constructor from an array of 3 float values
      mVec3(float *src)
      {
        v[0] = src[0];
        v[1] = src[1];
        v[2] = src[2];
      }

      //! Assignment
      void set(const mVec3& src)
      {
        v[0] = src.v[0];
        v[1] = src.v[1];
        v[2] = src.v[2];
      }

      //! Assignment from 3 float values
      void set(float x, float y, float z)
      {
        v[0] = x;
        v[1] = y;
        v[2] = z;
      }

      //! Assignment from an arry of 3 float values
      void set(float *src)
      {
        v[0] = src[0];
        v[1] = src[1];
        v[2] = src[2];
      }

      //! Assignment
      mVec3& operator = (const mVec3& src)
      {
        v[0] = src.v[0];
        v[1] = src.v[1];
        v[2] = src.v[2];
        return *this;
      }

      //! Sets this to a vector pointing in the specified heading.
      /*! The resulting vector is normalized. */
      void setH(float heading)
      {
        mSinCos(heading, v[0], v[1]);
        v[0] = -v[0];
        v[2] = 0.0f;
      }

      //! Sets this to a vector pointing in the specified heading and pitch.
      /*! The resulting vector is normalized. */
      void setHP(float heading, float pitch);

      //! Accessor
      void get(float& x, float& y, float& z) const
      {
        x = v[0];
        y = v[1];
        z = v[2];
      }

      //! Returns the heading and pitch for a normalized vector.
      void getHP(float& heading, float& pitch) const;

      //! Accessor
      float& operator [] (int i)
      {
        return v[i];
      }

      //! Accessor
      float operator [] (int i) const
      {
        return v[i];
      }

      //! Returns true if this == a
      bool operator == (const mVec3& a) const
      {
        return( v[0] == a.v[0] &&
                v[1] == a.v[1] &&
                v[2] == a.v[2] );
      }

      //! Returns true if this != a
      bool operator != (const mVec3& a) const
      {
        return !(operator==(a));
      }

      //! Returns true is this is within some tolerance value of a.
      bool approxEqual(const mVec3& a, float tol = mZeroTol) const
      {
        return( mApproxEqual(v[0], a.v[0], tol) &&
                mApproxEqual(v[1], a.v[1], tol) &&
                mApproxEqual(v[2], a.v[2], tol) );
      }

      //! Sets each component to the min of this and a.
      void setMin(const mVec3& a)
      {
        if (a.v[0] < v[0]) v[0] = a.v[0];
        if (a.v[1] < v[1]) v[1] = a.v[1];
        if (a.v[2] < v[2]) v[2] = a.v[2];
      }

      //! Sets each component to the max of this and a.
      void setMax(const mVec3& a)
      {
        if (a.v[0] > v[0]) v[0] = a.v[0];
        if (a.v[1] > v[1]) v[1] = a.v[1];
        if (a.v[2] > v[2]) v[2] = a.v[2];
      }

      //! Clamps each component of this to [a, b]
      void clamp(float a, float b)
      {
        v[0] = mClamp(v[0], a, b);
        v[1] = mClamp(v[1], a, b);
        v[2] = mClamp(v[2], a, b);
      }

      //! Clamps each component of vec to [a, b]
      void clamp(const mVec3& vec, float a, float b)
      {
        v[0] = mClamp(vec.v[0], a, b);
        v[1] = mClamp(vec.v[1], a, b);
        v[2] = mClamp(vec.v[2], a, b);
      }

      //! Addition: this += a
      void add(const mVec3& a)
      {
        v[0] += a.v[0];
        v[1] += a.v[1];
        v[2] += a.v[2];
      }

      //! Addition: this = a + b
      void add(const mVec3& a, const mVec3& b)
      {
        v[0] = a.v[0] + b.v[0];
        v[1] = a.v[1] + b.v[1];
        v[2] = a.v[2] + b.v[2];
      }

      //! Addition: Returns this + a
      mVec3 operator + (const mVec3& a) const
      {
        return mVec3(v[0] + a.v[0],
                     v[1] + a.v[1],
                     v[2] + a.v[2]);
      }

      //! Addition: this += a
      mVec3& operator += (const mVec3& a)
      {
        v[0] += a.v[0];
        v[1] += a.v[1];
        v[2] += a.v[2];
        return *this;
      }

      //! this += a * s
      void addScaled(const mVec3& a, float s)
      {
        v[0] += a.v[0] * s;
        v[1] += a.v[1] * s;
        v[2] += a.v[2] * s;
      }

      //! this = a + b * s
      void addScaled(const mVec3& a, const mVec3& b, float s)
      {
        v[0] = a.v[0] + b.v[0] * s;
        v[1] = a.v[1] + b.v[1] * s;
        v[2] = a.v[2] + b.v[2] * s;
      }

      //! this = a * s1 + b * s2
      void addScaled(const mVec3& a, float s1,
                     const mVec3& b, float s2)
      {
        v[0] = a.v[0] * s1 + b.v[0] * s2;
        v[1] = a.v[1] * s1 + b.v[1] * s2;
        v[2] = a.v[2] * s1 + b.v[2] * s2;
      }

      //! Subtraction: this -= a
      void sub(const mVec3& a)
      {
        v[0] -= a.v[0];
        v[1] -= a.v[1];
        v[2] -= a.v[2];
      }

      //! Subtraction: this = a - b
      void sub(const mVec3& a, const mVec3& b)
      {
        v[0] = a.v[0] - b.v[0];
        v[1] = a.v[1] - b.v[1];
        v[2] = a.v[2] - b.v[2];
      }

      //! Subtraction: Returns this - a
      mVec3 operator - (const mVec3& a) const
      {
        return mVec3(v[0] - a.v[0],
                     v[1] - a.v[1],
                     v[2] - a.v[2]);
      }

      //! Subtraction: this -= a
      mVec3& operator -= (const mVec3& a)
      {
        v[0] -= a.v[0];
        v[1] -= a.v[1];
        v[2] -= a.v[2];
        return *this;
      }

      //! Scales each component by s.
      void scale(float s)
      {
        v[0] *= s;
        v[1] *= s;
        v[2] *= s;
      }

      //! Scales each component of a by s.
      void scale(const mVec3& a, float s)
      {
        v[0] = a.v[0] * s;
        v[1] = a.v[1] * s;
        v[2] = a.v[2] * s;
      }

      //! Scales each component by s.
      mVec3& operator *= (float s)
      {
        v[0] *= s;
        v[1] *= s;
        v[2] *= s;
        return *this;
      }

      //! Negate: this = -this
      void neg()
      {
        v[0] = -v[0];
        v[1] = -v[1];
        v[2] = -v[2];
      }

      //! Negate: this = -a
      void neg(const mVec3& a)
      {
        v[0] = -a.v[0];
        v[1] = -a.v[1];
        v[2] = -a.v[2];
      }

      //! Negate: Returns -this
      mVec3 operator - () const
      {
        return mVec3(-v[0], -v[1], -v[2]);
      }

      //! Component multiplication
      void compMult(const mVec3& a)
      {
        v[0] *= a[0];
        v[1] *= a[1];
        v[2] *= a[2];
      }

      //! Component multiplication
      void compMult(const mVec3& a, const mVec3& b)
      {
        v[0] = a[0] * b[0];
        v[1] = a[1] * b[1];
        v[2] = a[2] * b[2];
      }

      //! Component division
      void compDiv(const mVec3& a)
      {
        v[0] /= a[0];
        v[1] /= a[1];
        v[2] /= a[2];
      }

      //! Component division
      void compDiv(const mVec3& a, const mVec3& b)
      {
        v[0] = a[0] / b[0];
        v[1] = a[1] / b[1];
        v[2] = a[2] / b[2];
      }

      //! Returns the distance squared between this and a.
      float distance2(const mVec3& a) const
      {
        return( mSquare(v[0] - a.v[0]) +
                mSquare(v[1] - a.v[1]) +
                mSquare(v[2] - a.v[2]) );
      }

      //! Returns the distance between this and a.
      float distance(const mVec3& a) const
      {
        return( mSqrt(distance2(a)) );
      }

      //! Returns the length squared of this.
      float length2() const
      {
        return( mSquare(v[0]) +
                mSquare(v[1]) +
                mSquare(v[2]) );
      }

      //! Returns the length of this.
      float length() const
      {
        return( mSqrt(length2()) );
      }

      //! Returns the dot product of this and a.
      float dot(const mVec3& a) const
      {
        return( v[0] * a.v[0] +
                v[1] * a.v[1] +
                v[2] * a.v[2] );
      }

      //! Calculates the cross product of a and b
      void cross(const mVec3& a, const mVec3& b)
      {
        mVec3 cp;
        cp.v[0] = a.v[1]*b.v[2] - a.v[2]*b.v[1];
        cp.v[1] = a.v[2]*b.v[0] - a.v[0]*b.v[2];
        cp.v[2] = a.v[0]*b.v[1] - a.v[1]*b.v[0];
        set(cp);
      }

      //! Normalizes this and returns the previous length.
      float normalize()
      {
        float l(length());
        if (l != 0.0f) scale(1.0f / l);
        return l;
      }

      //! Linearly interpolates between two vectors.
      void lerp(const mVec3& a, const mVec3& b, float t)
      {
        v[0] = a.v[0] + t * (b.v[0] - a.v[0]);
        v[1] = a.v[1] + t * (b.v[1] - a.v[1]);
        v[2] = a.v[2] + t * (b.v[2] - a.v[2]);
      }

      //! Creates a normal from three points.
      void makeNormal(const mVec3& a, const mVec3& b, const mVec3& c);

      //! Transforms the point p into f's axial frame.
      void xformTo(const mVec3& p, const mFrame& f);

      //! Transforms the point p into the OCS.
      void xformTo(const mVec3& p, const mOCS& ocs);

      //! Transforms the vector into the OCS.
      /*! Assumes \e vec is a vector.  The ocs's origin is not used. */
      void xformVecTo(const mVec3& vec, const mOCS& ocs);

      //! Transforms the point p from f's axial frame.
      void xformFrom(const mVec3& p, const mFrame& f);

      //! Transforms the point p from the OCS.
      void xformFrom(const mVec3& p, const mOCS& ocs);

      //! Transforms the vector from the OCS.
      /*! Assumes \e vec is a vector.  The ocs's origin is not used. */
      void xformVecFrom(const mVec3& vec, const mOCS& ocs);

    };

    // Common constant values.
    const mVec3 mZero3(0.0f, 0.0f, 0.0f);
    const mVec3 mOne3(1.0f, 1.0f, 1.0f);

    //****************************************************************************
    //**    END HEADER mVec3.h
    //****************************************************************************
    #endif // __mVec3_H__

Currently browsing [mmath.zip] (283,561 bytes) - [include/mVec4.h] - (9,742 bytes)

    #ifndef __mVec4_H__
    #define __mVec4_H__

    /*!
        \file mVec4.h
        \brief 4D Vector
        \author Douglas H. Cox
    */

    //============================================================================
    //    REQUIRED HEADERS
    //============================================================================
    #include "mMath.h"

    //============================================================================
    //    DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS / CLASS FORWARDS
    //============================================================================

    //============================================================================
    //    FUNCTION PROTOTYPES
    //============================================================================

    //============================================================================
    //    CLASS PROTOTYPES
    //============================================================================

    //! 4D Vector
    /*! mVec4 represents a vector consisting of an array of four float values. */
    class MMATH_DLL mVec4
    {
    public:
      float v[4];   //!< vector data

      //! Default constructor
      /*! No initialization is done here. */
      mVec4() {}

      //! Copy constructor
      mVec4(const mVec4& src)
      {
        v[0] = src.v[0];
        v[1] = src.v[1];
        v[2] = src.v[2];
        v[3] = src.v[3];
      }

      //! Constructor from 4 float values
      mVec4(float x, float y, float z, float w)
      {
        v[0] = x;
        v[1] = y;
        v[2] = z;
        v[3] = w;
      }

      //! Constructor from an array of 4 float values
      mVec4(float *src)
      {
        v[0] = src[0];
        v[1] = src[1];
        v[2] = src[2];
        v[3] = src[3];
      }

      //! Assignment
      void set(const mVec4& src)
      {
        v[0] = src.v[0];
        v[1] = src.v[1];
        v[2] = src.v[2];
        v[3] = src.v[3];
      }

      //! Assignment from 4 float values
      void set(float x, float y, float z, float w)
      {
        v[0] = x;
        v[1] = y;
        v[2] = z;
        v[3] = w;
      }

      //! Assignment from an arry of 4 float values
      void set(float *src)
      {
        v[0] = src[0];
        v[1] = src[1];
        v[2] = src[2];
        v[3] = src[3];
      }

      //! Assignment
      mVec4& operator = (const mVec4& src)
      {
        v[0] = src.v[0];
        v[1] = src.v[1];
        v[2] = src.v[2];
        v[3] = src.v[3];
        return *this;
      }

      //! Accessor
      void get(float& x, float& y, float& z, float& w) const
      {
        x = v[0];
        y = v[1];
        z = v[2];
        w = v[3];
      }

      //! Accessor
      float& operator [] (int i)
      {
        return v[i];
      }

      //! Accessor
      float operator [] (int i) const
      {
        return v[i];
      }

      //! Returns true if this == a
      bool operator == (const mVec4& a) const
      {
        return( v[0] == a.v[0] &&
                v[1] == a.v[1] &&
                v[2] == a.v[2] &&
                v[3] == a.v[3] );
      }

      //! Returns true if this != a
      bool operator != (const mVec4& a) const
      {
        return !(operator==(a));
      }

      //! Returns true is this is equal to a within some tolerance value.
      bool approxEqual(const mVec4& a, float tol = mZeroTol)
      {
        return( mApproxEqual(v[0], a.v[0], tol) &&
                mApproxEqual(v[1], a.v[1], tol) &&
                mApproxEqual(v[2], a.v[2], tol) &&
                mApproxEqual(v[3], a.v[3], tol) );
      }

      //! Sets each component to the min of this and a.
      void setMin(const mVec4& a)
      {
        if (a.v[0] < v[0]) v[0] = a.v[0];
        if (a.v[1] < v[1]) v[1] = a.v[1];
        if (a.v[2] < v[2]) v[2] = a.v[2];
        if (a.v[3] < v[3]) v[3] = a.v[3];
      }

      //! Sets each component to the max of this and a.
      void setMax(const mVec4& a)
      {
        if (a.v[0] > v[0]) v[0] = a.v[0];
        if (a.v[1] > v[1]) v[1] = a.v[1];
        if (a.v[2] > v[2]) v[2] = a.v[2];
        if (a.v[3] > v[3]) v[3] = a.v[3];
      }

      //! Clamps each component of this to [a, b]
      void clamp(float a, float b)
      {
        v[0] = mClamp(v[0], a, b);
        v[1] = mClamp(v[1], a, b);
        v[2] = mClamp(v[2], a, b);
        v[3] = mClamp(v[3], a, b);
      }

      //! Clamps each component of vec to [a, b]
      void clamp(const mVec4& vec, float a, float b)
      {
        v[0] = mClamp(vec.v[0], a, b);
        v[1] = mClamp(vec.v[1], a, b);
        v[2] = mClamp(vec.v[2], a, b);
        v[3] = mClamp(vec.v[3], a, b);
      }

      //! Addition: this += a
      void add(const mVec4& a)
      {
        v[0] += a.v[0];
        v[1] += a.v[1];
        v[2] += a.v[2];
        v[3] += a.v[3];
      }

      //! Addition: this = a + b
      void add(const mVec4& a, const mVec4& b)
      {
        v[0] = a.v[0] + b.v[0];
        v[1] = a.v[1] + b.v[1];
        v[2] = a.v[2] + b.v[2];
        v[3] = a.v[3] + b.v[3];
      }

      //! Addition: Returns this + a
      mVec4 operator + (const mVec4& a) const
      {
        return mVec4(v[0] + a.v[0],
                     v[1] + a.v[1],
                     v[2] + a.v[2],
                     v[3] + a.v[3]);
      }

      //! Addition: this += a
      mVec4& operator += (const mVec4& a)
      {
        v[0] += a.v[0];
        v[1] += a.v[1];
        v[2] += a.v[2];
        v[3] += a.v[3];
        return *this;
      }

      //! this += a * s
      void addScaled(const mVec4& a, float s)
      {
        v[0] += a.v[0] * s;
        v[1] += a.v[1] * s;
        v[2] += a.v[2] * s;
        v[3] += a.v[3] * s;
      }

      //! this = a + b * s
      void addScaled(const mVec4& a, const mVec4& b, float s)
      {
        v[0] = a.v[0] + b.v[0] * s;
        v[1] = a.v[1] + b.v[1] * s;
        v[2] = a.v[2] + b.v[2] * s;
        v[3] = a.v[3] + b.v[3] * s;
      }

      //! this = a * s1 + b * s2
      void addScaled(const mVec4& a, float s1,
                     const mVec4& b, float s2)
      {
        v[0] = a.v[0] * s1 + b.v[0] * s2;
        v[1] = a.v[1] * s1 + b.v[1] * s2;
        v[2] = a.v[2] * s1 + b.v[2] * s2;
        v[3] = a.v[3] * s1 + b.v[3] * s2;
      }

      //! Subtraction: this -= a
      void sub(const mVec4& a)
      {
        v[0] -= a.v[0];
        v[1] -= a.v[1];
        v[2] -= a.v[2];
        v[3] -= a.v[3];
      }

      //! Subtraction: this = a - b
      void sub(const mVec4& a, const mVec4& b)
      {
        v[0] = a.v[0] - b.v[0];
        v[1] = a.v[1] - b.v[1];
        v[2] = a.v[2] - b.v[2];
        v[3] = a.v[3] - b.v[3];
      }

      //! Subtraction: Returns this - a
      mVec4 operator - (const mVec4& a) const
      {
        return mVec4(v[0] - a.v[0],
                     v[1] - a.v[1],
                     v[2] - a.v[2],
                     v[3] - a.v[3]);
      }

      //! Subtraction: this -= a
      mVec4& operator -= (const mVec4& a)
      {
        v[0] -= a.v[0];
        v[1] -= a.v[1];
        v[2] -= a.v[2];
        v[3] -= a.v[3];
        return *this;
      }

      //! Scales each component by s.
      void scale(float s)
      {
        v[0] *= s;
        v[1] *= s;
        v[2] *= s;
        v[3] *= s;
      }

      //! Scales each component of a by s.
      void scale(const mVec4& a, float s)
      {
        v[0] = a.v[0] * s;
        v[1] = a.v[1] * s;
        v[2] = a.v[2] * s;
        v[3] = a.v[3] * s;
      }

      //! Scales each component by s.
      mVec4& operator *= (float s)
      {
        v[0] *= s;
        v[1] *= s;
        v[2] *= s;
        v[3] *= s;
        return *this;
      }

      //! Negate: this = -this
      void neg()
      {
        v[0] = -v[0];
        v[1] = -v[1];
        v[2] = -v[2];
        v[3] = -v[3];
      }

      //! Negate: this = -a
      void neg(const mVec4& a)
      {
        v[0] = -a.v[0];
        v[1] = -a.v[1];
        v[2] = -a.v[2];
        v[3] = -a.v[3];
      }

      //! Negate: Returns -this
      mVec4 operator - () const
      {
        return mVec4(-v[0], -v[1], -v[2], -v[3]);
      }

      //! Component multiplication
      void compMult(const mVec4& a)
      {
        v[0] *= a[0];
        v[1] *= a[1];
        v[2] *= a[2];
        v[3] *= a[3];
      }

      //! Component multiplication
      void compMult(const mVec4& a, const mVec4& b)
      {
        v[0] = a[0] * b[0];
        v[1] = a[1] * b[1];
        v[2] = a[2] * b[2];
        v[3] = a[3] * b[3];
      }

      //! Component division
      void compDiv(const mVec4& a)
      {
        v[0] /= a[0];
        v[1] /= a[1];
        v[2] /= a[2];
        v[3] /= a[3];
      }

      //! Component division
      void compDiv(const mVec4& a, const mVec4& b)
      {
        v[0] = a[0] * b[0];
        v[1] = a[1] * b[1];
        v[2] = a[2] * b[2];
        v[3] = a[3] * b[3];
      }

      //! Returns the distance squared between this and a.
      float distance2(const mVec4& a) const
      {
        return( mSquare(v[0] - a.v[0]) +
                mSquare(v[1] - a.v[1]) +
                mSquare(v[2] - a.v[2]) +
                mSquare(v[3] - a.v[3]) );
      }

      //! Returns the distance between this and a.
      float distance(const mVec4& a) const
      {
        return( mSqrt(distance2(a)) );
      }

      //! Returns the length squared of this.
      float length2() const
      {
        return( mSquare(v[0]) +
                mSquare(v[1]) +
                mSquare(v[2]) +
                mSquare(v[3]) );
      }

      //! Returns the length of this.
      float length() const
      {
        return( mSqrt(length2()) );
      }

      //! Returns the dot product of this and a.
      float dot(const mVec4& a) const
      {
        return( v[0] * a.v[0] +
                v[1] * a.v[1] +
                v[2] * a.v[2] +
                v[3] * a.v[3] );
      }

      //! Normalizes this and returns the previous length.
      float normalize()
      {
        float l(length());
        if (l != 0.0f) scale(1.0f / l);
        return l;
      }

      //! Linearly interpolates between two vectors.
      void lerp(const mVec4& a, const mVec4& b, float t)
      {
        v[0] = a.v[0] + t * (b.v[0] - a.v[0]);
        v[1] = a.v[1] + t * (b.v[1] - a.v[1]);
        v[2] = a.v[2] + t * (b.v[2] - a.v[2]);
        v[3] = a.v[3] + t * (b.v[3] - a.v[3]);
      }

    };

    // Common constant values.
    const mVec4 mZero4(0.0f, 0.0f, 0.0f, 0.0f);
    const mVec4 mOne4(1.0f, 1.0f, 1.0f, 1.0f);

    //****************************************************************************
    //**    END HEADER mVec4.h
    //****************************************************************************
    #endif // __mVec4_H__

Currently browsing [mmath.zip] (283,561 bytes) - [src/mMath/mFrame.cpp] - (6,246 bytes)

    //****************************************************************************
    //**
    //**    mFrame.cpp
    //**    Implementation for mFrame.
    //**    (C) 2000 - Douglas H. Cox
    //**
    //****************************************************************************
    //============================================================================
    //    HEADERS
    //============================================================================
    #include "mFrame.h"

    #include "mQuat.h"

    //============================================================================
    //    PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
    //============================================================================

    //============================================================================
    //    PRIVATE STRUCTURES / UTILITY CLASSES
    //============================================================================

    //============================================================================
    //    PRIVATE DATA
    //============================================================================

    //============================================================================
    //    PRIVATE FUNCTIONS
    //============================================================================

    //============================================================================
    //    FUNCTIONS
    //============================================================================

    //============================================================================
    //    CLASS METHODS
    //============================================================================

    //=============================================================
    // mFrame::approxEqual
    bool mFrame::approxEqual(const mFrame& f, float tol) const
    {
      return (a[0].approxEqual(f.a[0], tol) &&
              a[1].approxEqual(f.a[1], tol) &&
              a[2].approxEqual(f.a[2], tol));
    }

    //=============================================================
    // mFrame::inverse
    void mFrame::inverse()
    {
      float tmp;
      tmp = a[0].v[1];
      a[0].v[1] = a[1].v[0];
      a[1].v[0] = tmp;

      tmp = a[0].v[2];
      a[0].v[2] = a[2].v[0];
      a[2].v[0] = tmp;

      tmp = a[1].v[2];
      a[1].v[2] = a[2].v[1];
      a[2].v[1] = tmp;
    }

    //=============================================================
    // mFrame::inverse
    void mFrame::inverse(const mFrame& f)
    {
      float tmp;
      tmp = f.a[0].v[1];
      a[0].v[1] = f.a[1].v[0];
      a[1].v[0] = tmp;

      tmp = f.a[0].v[2];
      a[0].v[2] = f.a[2].v[0];
      a[2].v[0] = tmp;

      tmp = f.a[1].v[2];
      a[1].v[2] = f.a[2].v[1];
      a[2].v[1] = tmp;

      // diagonal
      a[0].v[0] = f.a[0].v[0];
      a[1].v[1] = f.a[1].v[1];
      a[2].v[2] = f.a[2].v[2];
    }

    //=============================================================
    // mFrame::xformTo
    void mFrame::xformTo(const mFrame& f, const mFrame& to)
    {
      mFrame nf;

      nf.a[0].xformTo(f.a[0], to);
      nf.a[1].xformTo(f.a[1], to);
      nf.a[2].xformTo(f.a[2], to);

      set(nf);
    }

    //=============================================================
    // mFrame::xformFrom
    void mFrame::xformFrom(const mFrame& f, const mFrame& from)
    {
      mFrame nf;

      nf.a[0].xformFrom(f.a[0], from);
      nf.a[1].xformFrom(f.a[1], from);
      nf.a[2].xformFrom(f.a[2], from);

      set(nf);
    }

    //=============================================================
    // mFrame::setQuat
    void mFrame::setQuat(const mQuat& q)
    {
      // standard quaternion to matrix operations
      float x(q.v[0]), y(q.v[1]), z(q.v[2]), w(q.v[3]);
      float x2(x*2.0f), y2(y*2.0f), z2(z*2.0f), w2(w*2.0f);
    	float xx2(x*x2), yy2(y*y2), zz2(z*z2), ww2(w*w2);
    	float xy2(x*y2), xz2(x*z2), xw2(x*w2), yz2(y*z2), yw2(y*w2), zw2(z*w2);

      a[0].set(1.0f - (yy2 + zz2), xy2 - zw2, xz2 + yw2);
      a[1].set(xy2 + zw2, 1.0f - (xx2 + zz2), yz2 - xw2);
      a[2].set(xz2 - yw2, yz2 + xw2, 1.0f - (xx2 + yy2));
    }

    //=============================================================
    // mFrame::getQuat
    void mFrame::getQuat(mQuat& q) const
    {
      float tr, s;
      tr = a[0].v[0] + a[1].v[1] + a[2].v[2];

      if (tr > 0.0f)
      {
        s = mSqrt(tr + 1.0f);
        q.v[3] = s*0.5f;
        s = 0.5f / s;

        q.v[0] = s * (a[2].v[1] - a[1].v[2]);
        q.v[1] = s * (a[0].v[2] - a[2].v[0]);
        q.v[2] = s * (a[1].v[0] - a[0].v[1]);
      }
      else
      {
        const int n[3] = {1, 2, 0};
        int i, j, k;

        i = 0;
        if (a[1].v[1] > a[0].v[0])
          i = 1;
        if (a[2].v[2] > a[i].v[i])
          i = 2;
        j = n[i];
        k = n[j];

        s = mSqrt((a[i].v[i] - (a[j].v[j] + a[k].v[k])) + 1.0f);

        q.v[i] = s * 0.5f;
        assert(s !=  0.0f);

        s = 0.5f / s;

        q.v[3] = (a[k].v[j] - a[j].v[k]) * s;
        q.v[j] = (a[j].v[i] + a[i].v[j]) * s;
        q.v[k] = (a[k].v[i] + a[i].v[k]) * s;

        // TODO: Test this.
        bool bNotYetTested = false;
        assert(bNotYetTested);
      }
    }

    //=============================================================
    // mFrame::setAxisAngle
    void mFrame::setAxisAngle(const mVec3& n, float a)
    {
      mQuat q;
      q.setAxisAngle(n, a);
      setQuat(q);
    }

    //=============================================================
    // mFrame::getAxisAngle
    void mFrame::getAxisAngle(mVec3& n, float& a) const
    {
      mQuat q;
      getQuat(q);
      q.getAxisAngle(n, a);
    }

    // ============================================================
    // mFrame::setHP
    void mFrame::setHP(float heading, float pitch)
    {
      float sh, ch, sp, cp;
      mSinCos(heading, sh, ch);
      mSinCos(pitch, sp, cp);

      a[0].set(ch, sh, 0.0f);
      a[1].set(-cp*sh, ch*cp, sp);
      a[2].set(sp*sh, sp*ch, cp);
    }

    // ============================================================
    // mFrame::setHPR
    void mFrame::setHPR(float heading, float pitch, float roll)
    {
      float sh, ch, sp, cp, sr, cr;
      mSinCos(heading, sh, ch);
      mSinCos(pitch, sp, cp);
      mSinCos(roll, sr, cr);

      float srsp = sr*sp;
      float crsp = cr*sp;

      a[0].set(cr*ch - srsp*sh, cr*sh + srsp*ch, -sr * cp);
      a[1].set(-cp*sh, ch*cp, sp);
      a[2].set(sr*ch + crsp*sh, sr*sh - crsp*ch, cr * cp);
    }

    //****************************************************************************
    //**    END MODULE mFrame.cpp
    //****************************************************************************

Currently browsing [mmath.zip] (283,561 bytes) - [src/mMath/mMath.cpp] - (3,478 bytes)

    //****************************************************************************
    //**
    //**    mMath.cpp
    //**    Common math functions.
    //**    (C) 2000 - Douglas H. Cox
    //**
    //****************************************************************************
    //============================================================================
    //    HEADERS
    //============================================================================
    #include "mMath.h"

    // The following results in a ~10k drop in size for a release build.
    #ifdef NDEBUG
    #if _MSC_VER >= 1000
    #pragma comment(linker,"/OPT:nowin98")
    #endif // _MSC_VER >= 1000
    #endif // NDEBUG

    //============================================================================
    //    PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
    //============================================================================

    //============================================================================
    //    PRIVATE STRUCTURES / UTILITY CLASSES
    //============================================================================

    //============================================================================
    //    PRIVATE DATA
    //============================================================================

    // Square root table used for fast square root function.
    unsigned int mFastSqrtTable[0x10000];

    // Keep track of initialized ref count
    static int s_initRefCount = 0;

    //============================================================================
    //    PRIVATE FUNCTIONS
    //============================================================================

    // ============================================================
    // buildSqrtTable - from nVidia's fastmath.cpp
    void buildFastSqrtTable()
    {
      union uFloatUInt
      {
        float f;
        unsigned int i;
      } s;

      unsigned int i;

      for (i = 0; i <= 0x7FFF; i++)
      {
        // Build a float with the bit pattern i as mantissa
        // and an exponent of 0, stored as 127

        s.i = (i << 8) | (0x7F << 23);
        s.f = (float)sqrt(s.f);

        // Take the square root then strip the first 7 bits of
        // the mantissa into the table

        mFastSqrtTable[i + 0x8000] = (s.i & 0x7FFFFF);

        // Repeat the process, this time with an exponent of 1,
        // stored as 128

        s.i = (i << 8) | (0x80 << 23);
        s.f = (float)sqrt(s.f);

        mFastSqrtTable[i] = (s.i & 0x7FFFFF);
      }
    }

    //============================================================================
    //    FUNCTIONS
    //============================================================================

    // ============================================================
    // mInitialize
    bool mInitialize()
    {
      s_initRefCount++;
      if (s_initRefCount > 1)
        return true;

      // Initialize fast square root table.
      buildFastSqrtTable();

      return true;
    }

    // ============================================================
    // mUninitialize
    void mUninitialize()
    {
      s_initRefCount--;
      if (s_initRefCount > 0)
        return;

      // Free up any allocated memory here.
    }

    //============================================================================
    //    CLASS METHODS
    //============================================================================

    //****************************************************************************
    //**    END MODULE mMath.cpp
    //****************************************************************************

Currently browsing [mmath.zip] (283,561 bytes) - [src/mMath/mMatrix.cpp] - (3,575 bytes)

    //****************************************************************************
    //**
    //**    mMatrix.cpp
    //**    Implementation for mMatrix.
    //**    (C) 2000 - Douglas H. Cox
    //**
    //****************************************************************************
    //============================================================================
    //    HEADERS
    //============================================================================
    #include "mMatrix.h"

    //============================================================================
    //    PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
    //============================================================================

    //============================================================================
    //    PRIVATE STRUCTURES / UTILITY CLASSES
    //============================================================================

    //============================================================================
    //    PRIVATE DATA
    //============================================================================

    //============================================================================
    //    PRIVATE FUNCTIONS
    //============================================================================

    //============================================================================
    //    FUNCTIONS
    //============================================================================

    //============================================================================
    //    CLASS METHODS
    //============================================================================

    //=============================================================
    // mMatrix::set
    void mMatrix::set(const mMatrix& src)
    {
      for (int i = 0; i < 15;)
      {
        m[i] = src.m[i]; i++;
        m[i] = src.m[i]; i++;
        m[i] = src.m[i]; i++;
        m[i] = src.m[i]; i++;
      }
    }

    //=============================================================
    // mMatrix::makeIdentity
    void mMatrix::makeIdentity()
    {
      m[0] = 1.0f; m[4] = 0.0f; m[8]  = 0.0f; m[12] = 0.0f;
      m[1] = 0.0f; m[5] = 1.0f; m[9]  = 0.0f; m[13] = 0.0f;
      m[2] = 0.0f; m[6] = 0.0f; m[10] = 1.0f; m[14] = 0.0f;
      m[3] = 0.0f; m[7] = 0.0f; m[11] = 0.0f; m[15] = 1.0f;
    }

    //=============================================================
    // mMatrix::mult
    void mMatrix::mult(const mMatrix& a, const mMatrix& b)
    {
      mMatrix m;

      m[0]=a[0]*b[0] + a[4]*b[1] + a[8 ]*b[2] + a[12]*b[3];
      m[1]=a[1]*b[0] + a[5]*b[1] + a[9 ]*b[2] + a[13]*b[3];
      m[2]=a[2]*b[0] + a[6]*b[1] + a[10]*b[2] + a[14]*b[3];
      m[3]=a[3]*b[0] + a[7]*b[1] + a[11]*b[2] + a[15]*b[3];

      m[4]=a[0]*b[4] + a[4]*b[5] + a[8 ]*b[6] + a[12]*b[7];
      m[5]=a[1]*b[4] + a[5]*b[5] + a[9 ]*b[6] + a[13]*b[7];
      m[6]=a[2]*b[4] + a[6]*b[5] + a[10]*b[6] + a[14]*b[7];
      m[7]=a[3]*b[4] + a[7]*b[5] + a[11]*b[6] + a[15]*b[7];

      m[8 ]=a[0]*b[8] + a[4]*b[9] + a[8 ]*b[10] + a[12]*b[11];
      m[9 ]=a[1]*b[8] + a[5]*b[9] + a[9 ]*b[10] + a[13]*b[11];
      m[10]=a[2]*b[8] + a[6]*b[9] + a[10]*b[10] + a[14]*b[11];
      m[11]=a[3]*b[8] + a[7]*b[9] + a[11]*b[10] + a[15]*b[11];

      m[12]=a[0]*b[12] + a[4]*b[13] + a[8 ]*b[14] + a[12]*b[15];
      m[13]=a[1]*b[12] + a[5]*b[13] + a[9 ]*b[14] + a[13]*b[15];
      m[14]=a[2]*b[12] + a[6]*b[13] + a[10]*b[14] + a[14]*b[15];
      m[15]=a[3]*b[12] + a[7]*b[13] + a[11]*b[14] + a[15]*b[15];

      set(m);
    }

    //****************************************************************************
    //**    END MODULE mMatrix.cpp
    //****************************************************************************

Currently browsing [mmath.zip] (283,561 bytes) - [src/mMath/mOCS.cpp] - (8,480 bytes)

    //****************************************************************************
    //**
    //**    mOCS.cpp
    //**    Implementation for mOCS.
    //**    (C) 2000 - Douglas H. Cox
    //**
    //****************************************************************************
    //============================================================================
    //    HEADERS
    //============================================================================
    #include "mOCS.h"

    #include "mMatrix.h"

    //============================================================================
    //    PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
    //============================================================================

    //============================================================================
    //    PRIVATE STRUCTURES / UTILITY CLASSES
    //============================================================================

    //============================================================================
    //    PRIVATE DATA
    //============================================================================

    //============================================================================
    //    PRIVATE FUNCTIONS
    //============================================================================

    //============================================================================
    //    FUNCTIONS
    //============================================================================

    //============================================================================
    //    CLASS METHODS
    //============================================================================

    //=============================================================
    // mOCS::mOCS
    mOCS::mOCS(const mOCS& src) : o(src.o),
                                  f(src.f),
                                  s(src.s),
                                  type(src.type)
    {
    }

    //=============================================================
    // mOCS::mOCS
    mOCS::mOCS(const mVec3& origin,
               const mFrame& frame,
               const mVec3& scale,
               unsigned type)
    {
      (type & ORIGIN) ? o.set(origin) : o.set(0.0f, 0.0f, 0.0f);
      (type & FRAME)  ? f.set(frame)  : f.makeIdentity();
      (type & SCALE)  ? s.set(scale)  : s.set(1.0f, 1.0f, 1.0f);

      this->type = type;
    }

    //=============================================================
    // mOCS::makeIdentity
    void mOCS::makeIdentity()
    {
      if (type == IDENTITY) return;

      o.set(0.0f, 0.0f, 0.0f);
      if (type & FRAME)
        f.makeIdentity();
      s.set(1.0f, 1.0f, 1.0f);
      type = IDENTITY;
    }

    //=============================================================
    // mOCS::makeOrigin
    void mOCS::makeOrigin(float x, float y, float z)
    {
      o.set(x, y, z);
      if (type & FRAME)
        f.makeIdentity();
      s.set(1.0f, 1.0f, 1.0f);
      type = ORIGIN;
    }

    //=============================================================
    // mOCS::makeFrame
    void mOCS::makeFrame(const mFrame& frame)
    {
      o.set(0.0f, 0.0f, 0.0f);
      f.set(frame);
      s.set(1.0f, 1.0f, 1.0f);
      type = FRAME;
    }

    //=============================================================
    // mOCS::makeScale
    void mOCS::makeScale(float x, float y, float z)
    {
      o.set(0.0f, 0.0f, 0.0f);
      if (type & FRAME)
        f.makeIdentity();
      s.set(x, y, z);
      type = SCALE;
    }

    //=============================================================
    // mOCS::set
    void mOCS::set(const mOCS& src)
    {
      o.set(src.o);
      f.set(src.f);
      s.set(src.s);
      type = src.type;
    }

    //=============================================================
    // mOCS::set
    void mOCS::set(const mVec3& origin,
                   const mFrame& frame,
                   const mVec3& scale,
                   unsigned type)
    {
      (type & ORIGIN) ? o.set(origin) : o.set(0.0f, 0.0f, 0.0f);
      (type & FRAME)  ? f.set(frame)  : f.makeIdentity();
      (type & SCALE)  ? s.set(scale)  : s.set(1.0f, 1.0f, 1.0f);

      this->type = type;
    }

    //=============================================================
    // mOCS::get
    void mOCS::get(mVec3& origin, mFrame& frame, mVec3& scale) const
    {
      origin.set(o);
      frame.set(f);
      scale.set(s);
    }

    // ============================================================
    // mOCS::operator ==
    bool mOCS::operator == (const mOCS& ocs) const
    {
      return ( o == ocs.o &&
               s == ocs.s &&
               f == ocs.f );
    }

    //=============================================================
    // mOCS::approxEqual
    bool mOCS::approxEqual(const mOCS& ocs, float tol) const
    {
      return ( o.approxEqual(ocs.o, mZeroTol) &&
               s.approxEqual(ocs.s, mZeroTol) &&
               f.approxEqual(ocs.f, mZeroTol) );
    }

    //=============================================================
    // mOCS::inverse
    void mOCS::inverse(const mOCS &ocs)
    {
      if (ocs.type & ORIGIN)
        o.xformTo(mVec3(0.0f, 0.0f, 0.0f), ocs);
      else
        o.set(0.0f, 0.0f, 0.0f);

      if (ocs.type & FRAME)
        f.inverse(ocs.f);
      else if (type & FRAME)
        f.makeIdentity();

      if (ocs.type & SCALE)
        s.compDiv(mVec3(1.0f, 1.0f, 1.0f), ocs.s);
      else
        s.set(1.0f, 1.0f, 1.0f);

      type = ocs.type;
    }

    //=============================================================
    // mOCS::xformTo
    void mOCS::xformTo(const mOCS& ocs, const mOCS& to)
    {
      mVec3 no;
      no.xformTo(ocs.o, to);

      mFrame nf;
      if (to.type & FRAME)
        nf.xformTo(ocs.f, to.f);
      else
        nf.set(ocs.f);

      mVec3 ns;
      if (to.type & SCALE)
        ns.compDiv(ocs.s, to.s);
      else
        ns.set(ocs.s);

      set(no, nf, ns, ocs.type | to.type);
    }

    //=============================================================
    // mOCS::xformFrom
    void mOCS::xformFrom(const mOCS& ocs, const mOCS& from)
    {
      mVec3 no;
      no.xformFrom(ocs.o, from);

      mFrame nf;
      if (from.type & FRAME)
        nf.xformFrom(ocs.f, from.f);
      else
        nf.set(ocs.f);

      mVec3 ns;
      if (from.type & SCALE)
        ns.compMult(ocs.s, from.s);
      else
        ns.set(ocs.s);

      set(no, nf, ns, ocs.type | from.type);
    }

    //=============================================================
    // mOCS::getToMatrix
    void mOCS::getToMatrix(mMatrix& matrix) const
    {
      float *m = matrix.m;

      m[3] = 0.0f; m[7] = 0.0f; m[11] = 0.0f; m[15] = 1.0f;

      if (type & FRAME)
      {
        m[0] = f.a[0].v[0]; m[4] = f.a[0].v[1]; m[8 ] = f.a[0].v[2];
        m[1] = f.a[1].v[0]; m[5] = f.a[1].v[1]; m[9 ] = f.a[1].v[2];
        m[2] = f.a[2].v[0]; m[6] = f.a[2].v[1]; m[10] = f.a[2].v[2];

        if (type & SCALE)
        {
          mVec3 ns(1.0f, 1.0f, 1.0f);
          ns.compDiv(s);
          m[0] *= ns.v[0]; m[4] *= ns.v[1]; m[8 ] *= ns.v[2];
          m[1] *= ns.v[0]; m[5] *= ns.v[1]; m[9 ] *= ns.v[2];
          m[2] *= ns.v[0]; m[6] *= ns.v[1]; m[10] *= ns.v[2];
        }
      }
      else
      {
        if (type & SCALE)
        {
          m[0] = 1.0f / s.v[0]; m[5] = 1.0f / s.v[1]; m[10] = 1.0f /s.v[2];
        }
        else
        {
          m[0] = m[5] = m[10] = 1.0f;
        }
                     m[4] = 0.0f; m[8 ] = 0.0f;
        m[1] = 0.0f;              m[9 ] = 0.0f;
        m[2] = 0.0f; m[6] = 0.0f;
      }

      if (type & ORIGIN)
      {
        mVec3 no;
        no.xformTo(o, *this);
        m[12] = o.v[0]; m[13] = o.v[1]; m[14] = o.v[2];
      }
      else
      {
        m[12] = o.v[0]; m[13] = o.v[1]; m[14] = o.v[2];
      }
    }

    //=============================================================
    // mOCS::getFromMatrix
    void mOCS::getFromMatrix(mMatrix& matrix) const
    {
      float *m = matrix.m;

      m[3] = 0.0f; m[7] = 0.0f; m[11] = 0.0f; m[15] = 1.0f;

      if (type & FRAME)
      {
        m[0] = f.a[0].v[0]; m[4] = f.a[1].v[0]; m[8 ] = f.a[2].v[0];
        m[1] = f.a[0].v[1]; m[5] = f.a[1].v[1]; m[9 ] = f.a[2].v[1];
        m[2] = f.a[0].v[2]; m[6] = f.a[1].v[2]; m[10] = f.a[2].v[2];

        if (type & SCALE)
        {
          m[0] *= s.v[0]; m[4] *= s.v[1]; m[8 ] *= s.v[2];
          m[1] *= s.v[0]; m[5] *= s.v[1]; m[9 ] *= s.v[2];
          m[2] *= s.v[0]; m[6] *= s.v[1]; m[10] *= s.v[2];
        }
      }
      else
      {
        if (type & SCALE)
        {
          m[0] = s.v[0]; m[5] = s.v[1]; m[10] = s.v[2];
        }
        else
        {
          m[0] = m[5] = m[10] = 1.0f;
        }
                     m[4] = 0.0f; m[8 ] = 0.0f;
        m[1] = 0.0f;              m[9 ] = 0.0f;
        m[2] = 0.0f; m[6] = 0.0f;
      }

      m[12] = o.v[0]; m[13] = o.v[1]; m[14] = o.v[2];
    }

    //****************************************************************************
    //**    END MODULE mOCS.cpp
    //****************************************************************************

Currently browsing [mmath.zip] (283,561 bytes) - [src/mMath/mQuat.cpp] - (5,462 bytes)

    //****************************************************************************
    //**
    //**    mQuat.cpp
    //**    Implementation for mQuat.
    //**    (C) 2000 - Douglas H. Cox
    //**
    //****************************************************************************
    //============================================================================
    //    HEADERS
    //============================================================================
    #include "mQuat.h"
    #include "mVec3.h"

    //============================================================================
    //    PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
    //============================================================================

    //============================================================================
    //    PRIVATE STRUCTURES / UTILITY CLASSES
    //============================================================================

    //============================================================================
    //    PRIVATE DATA
    //============================================================================

    //============================================================================
    //    PRIVATE FUNCTIONS
    //============================================================================

    //============================================================================
    //    FUNCTIONS
    //============================================================================

    //============================================================================
    //    CLASS METHODS
    //============================================================================

    //=============================================================
    // mQuat::inverse
    void mQuat::inverse()
    {
      // q.scale(1.0f/length2())
      // q.conjugate()
      scale(-1.0f / length2());
      v[3] = -v[3];
    }

    //=============================================================
    // mQuat::inverse
    void mQuat::inverse(const mQuat& q)
    {
      // q.scale(1.0f/length2())
      // q.conjugate()
      scale(q, -1.0f / q.length2());
      v[3] = -v[3];
    }

    // ============================================================
    // mQuat::mult
    void mQuat::mult(const mQuat& q1, const mQuat& q2)
    {
      mQuat tmp;
      tmp[0] = q1[3] * q2[0] + q1[0] * q2[3] +
               q1[1] * q2[2] - q1[2] * q2[1];
      tmp[1] = q1[3] * q2[1] + q1[1] * q2[3] +
               q1[2] * q2[0] - q1[0] * q2[2];
      tmp[2] = q1[3] * q2[2] + q1[2] * q2[3] +
               q1[0] * q2[1] - q1[1] * q2[0];
      tmp[3] = q1[3] * q2[3] - q1[0] * q2[0] -
               q1[1] * q2[1] - q1[2] * q2[2];
      set(tmp);
    }

    //=============================================================
    // mQuat::setAxisAngle
    void mQuat::setAxisAngle(const mVec3& n, float a)
    {
      float s, c;
      mSinCos(a * 0.5f, s, c);

      v[0] = n[0] * s;
      v[1] = n[1] * s;
      v[2] = n[2] * s;
      v[3] = c;
    }

    //=============================================================
    // mQuat::getAxisAngle
    void mQuat::getAxisAngle(mVec3& n, float& a) const
    {
      float s = 1.0f / mSqrt( 1.0f - v[3]*v[3] );

      a = mACos(v[3]) * 2.0f;
      n[0] = v[0] * s;
      n[1] = v[1] * s;
      n[2] = v[2] * s;
    }

    // ============================================================
    // mQuat::setHP
    void mQuat::setHP(float h, float p)
    {
      // TODO: check h/p > 180.0f etc.

      h *= 0.5f;
      p *= 0.5f;

      float cH, sH;
      float cP, sP;

      mSinCos(h, sH, cH);
      mSinCos(p, sP, cP);

      v[0] = -(sP * cH);
      v[1] = -(sP * sH);
      v[2] = -(cP * sH);
      v[3] =  (cP * cH);
    }

    //=============================================================
    // mQuat::getHP
    void mQuat::getHP(float &h, float &p) const
    {
      h = 2.0f * mATan2(-v[2], v[3]);
      p = 2.0f * mATan2(-v[0], v[3]);
    }

    // ============================================================
    // mQuat::setHPR
    void mQuat::setHPR(float h, float p, float r)
    {
      h *= 0.5f;
      p *= 0.5f;
      r *= 0.5f;

      float cH, sH;
      float cP, sP;
      float cR, sR;

      mSinCos(h, sH, cH);
      mSinCos(p, sP, cP);
      mSinCos(r, sR, cR);

      float cPcH = cP * cH;
      float cPsH = cP * sH;
      float sPcH = sP * cH;
      float sPsH = sP * sH;

      v[0] = -(sPcH * cR) + (cPsH * sR);
      v[1] = -(cPcH * sR) - (sPsH * cR);
      v[2] = -(cPsH * cR) - (sPcH * sR);
      v[3] =  (cPcH * cR) - (sPsH * sR);
    }

    //=============================================================
    // mQuat::getHPR
    void mQuat::getHPR(mVec3& hpr) const
    {
      assert(false); // TODO: implement
    }

    //=============================================================
    // mQuat::slerp
    void mQuat::slerp(const mQuat& q1, const mQuat& q2, float t)
    {
      float cosom = q1.dot(q2);
      float s1, s2;

      if ( (1.0f + cosom) > mZeroTol)
      {
        if ( (1.0f - cosom) > mZeroTol)
        {
          double omega, isinom;
          omega = acos(cosom);
          isinom = 1.0f / sin(omega);
          s1 = float(sin((1.0f - t) * omega) * isinom);
          s2 = float(sin(t * omega) * isinom);
        }
        else
        {
          s1 = 1.0f - t;
          s2 = t;
        }
        addScaled(q1, s1, q2, s2);
      }
      else
      {
        mQuat pq;
        pq.v[0] = -q2.v[1];
        pq.v[1] = q2.v[0];
        pq.v[2] = -q2.v[3];
        pq.v[3] = q2.v[2];

        s1 = float(sin((1.0f - t) * mHalfPI));
        s2 = float(sin(t * mHalfPI));
        addScaled(q1, s1, pq, s2);
      }
    }

    //****************************************************************************
    //**    END MODULE mQuat.cpp
    //****************************************************************************

Currently browsing [mmath.zip] (283,561 bytes) - [src/mMath/mRay.cpp] - (3,311 bytes)

    //****************************************************************************
    //**
    //**    mRay.cpp
    //**    Ray class.
    //**    (C) 2000 - Douglas H. Cox
    //**
    //****************************************************************************
    //============================================================================
    //    HEADERS
    //============================================================================
    #include "mRay.h"

    #include "mOCS.h"

    //============================================================================
    //    PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
    //============================================================================

    //============================================================================
    //    PRIVATE STRUCTURES / UTILITY CLASSES
    //============================================================================

    //============================================================================
    //    PRIVATE DATA
    //============================================================================

    //============================================================================
    //    PRIVATE FUNCTIONS
    //============================================================================

    //============================================================================
    //    FUNCTIONS
    //============================================================================

    //============================================================================
    //    CLASS METHODS
    //============================================================================

    // ============================================================
    // mRay::set
    void mRay::set(const mVec3& startPoint, const mVec3& endPoint)
    {
      pos.set(startPoint);
      dir.sub(endPoint, startPoint);
      len = dir.normalize();
    }

    // ============================================================
    // mRay::operator ==
    bool mRay::operator == (const mRay& ray) const
    {
      return (len == ray.len &&
              pos == ray.pos &&
              dir == ray.dir);
    }

    // ============================================================
    // mRay::getEndPoint
    void mRay::getEndPoint(mVec3& end) const
    {
      (len >= 0.0f) ? end.addScaled(pos, dir, len) :
                      end.addScaled(pos, dir, mFloatMax);
    }

    // ============================================================
    // mRay::xformTo
    void mRay::xformTo(const mRay& ray, const mOCS& ocs)
    {
      pos.xformTo(ray.pos, ocs);
      dir.xformVecTo(ray.dir, ocs);

      if (len < 0.0f)
      {
        if (ocs.type & mOCS::SCALE)
          dir.normalize();
      }
      else
      {
        if (ocs.type & mOCS::SCALE)
        {
          len *= dir.normalize();
        }
      }
    }

    // ============================================================
    // mRay::xformFrom
    void mRay::xformFrom(const mRay& ray, const mOCS& ocs)
    {
      pos.xformFrom(ray.pos, ocs);
      dir.xformVecFrom(ray.dir, ocs);

      if (len < 0.0f)
      {
        if (ocs.type & mOCS::SCALE)
          dir.normalize();
      }
      else
      {
        if (ocs.type & mOCS::SCALE)
        {
          len *= dir.normalize();
        }
      }
    }

    //****************************************************************************
    //**    END MODULE mRay.cpp
    //****************************************************************************

Currently browsing [mmath.zip] (283,561 bytes) - [src/mMath/mVec.cpp] - (4,647 bytes)

    //****************************************************************************
    //**
    //**    mVec.cpp
    //**    Implementation for various mVec* functions.
    //**    (C) 2000 - Douglas H. Cox
    //**
    //****************************************************************************
    //============================================================================
    //    HEADERS
    //============================================================================
    #include "mVec3.h"
    #include "mFrame.h"
    #include "mOCS.h"

    //============================================================================
    //    PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
    //============================================================================

    //============================================================================
    //    PRIVATE STRUCTURES / UTILITY CLASSES
    //============================================================================

    //============================================================================
    //    PRIVATE DATA
    //============================================================================

    //============================================================================
    //    PRIVATE FUNCTIONS
    //============================================================================

    //============================================================================
    //    FUNCTIONS
    //============================================================================

    //============================================================================
    //    CLASS METHODS
    //============================================================================

    //=============================================================
    // mVec3::setHP
    void mVec3::setHP(float heading, float pitch)
    {
      mSinCos(heading, v[0], v[1]);
      v[0] = -v[0];
      v[2] = mSin(pitch);
      normalize();
    }

    //=============================================================
    // mVec3::getHP
    void mVec3::getHP(float& heading, float& pitch) const
    {
      heading = mATan2(-v[0], v[1]);
      pitch = mASin(v[2] / mSqrt(v[0]*v[0] + v[1]*v[1]));
    }

    // ============================================================
    // mVec3::makeNormal
    void mVec3::makeNormal(const mVec3& a, const mVec3& b, const mVec3& c)
    {
      cross(b - a, c - b);
      normalize();
    }

    //=============================================================
    // mVec3::xformTo
    void mVec3::xformTo(const mVec3& vec, const mFrame& f)
    {
      mVec3 nv(vec.dot(f.a[0]),
               vec.dot(f.a[1]),
               vec.dot(f.a[2]));
      set(nv);
    }

    //=============================================================
    // mVec3::xformFrom
    void mVec3::xformFrom(const mVec3& vec, const mFrame& f)
    {
      mVec3 nv(vec.v[0] * f.a[0].v[0] +
               vec.v[1] * f.a[1].v[0] +
               vec.v[2] * f.a[2].v[0],
               vec.v[0] * f.a[0].v[1] +
               vec.v[1] * f.a[1].v[1] +
               vec.v[2] * f.a[2].v[1],
               vec.v[0] * f.a[0].v[2] +
               vec.v[1] * f.a[1].v[2] +
               vec.v[2] * f.a[2].v[2]);

      set(nv);
    }

    //=============================================================
    // mVec3::xformTo
    void mVec3::xformTo(const mVec3& vec, const mOCS& ocs)
    {
      assert(&vec != &ocs.o);
      set(vec);

      if (ocs.type & mOCS::ORIGIN)
        sub(ocs.o);

      if (ocs.type & mOCS::FRAME)
        xformTo(*this, ocs.f);

      if (ocs.type & mOCS::SCALE)
        compDiv(ocs.s);
    }

    //=============================================================
    // mVec3::xformVecTo
    void mVec3::xformVecTo(const mVec3& vec, const mOCS& ocs)
    {
      assert(&vec != &ocs.o);
      set(vec);

      if (ocs.type & mOCS::FRAME)
        xformTo(*this, ocs.f);

      if (ocs.type & mOCS::SCALE)
        compDiv(ocs.s);
    }

    //=============================================================
    // mVec3::xformFrom
    void mVec3::xformFrom(const mVec3& vec, const mOCS& ocs)
    {
      assert(&vec != &ocs.o);
      set(vec);

      if (ocs.type & mOCS::SCALE)
        compMult(ocs.s);

      if (ocs.type & mOCS::FRAME)
        xformFrom(*this, ocs.f);

      if (ocs.type & mOCS::ORIGIN)
        add(ocs.o);
    }

    //=============================================================
    // mVec3::xformVecFrom
    void mVec3::xformVecFrom(const mVec3& vec, const mOCS& ocs)
    {
      assert(&vec != &ocs.o);
      set(vec);

      if (ocs.type & mOCS::SCALE)
        compMult(ocs.s);

      if (ocs.type & mOCS::FRAME)
        xformFrom(*this, ocs.f);
    }

    //****************************************************************************
    //**    END MODULE mVec.cpp
    //****************************************************************************

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.