Namespaces | Classes | Typedefs | Enumerations | Functions | Variables

gmtl Namespace Reference

Meta programming classes. More...

Namespaces

namespace  helpers
namespace  Math
namespace  meta
namespace  output

Classes

class  AABox
 Describes an axially aligned box in 3D space. More...
class  AxisAngle
 AxisAngle: Represents a "twist about an axis" AxisAngle is used to specify a rotation in 3-space. More...
struct  CompareIndexPointProjections
class  Coord
 coord is a position/rotation pair. More...
class  EulerAngle
 EulerAngle: Represents a group of euler angles. More...
class  Frustum
 This class defines a View Frustum Volume as a set of 6 planes. More...
class  LineSeg
 Describes a line segment. More...
struct  RotationOrderBase
 Base class for Rotation orders. More...
struct  XYZ
 XYZ Rotation order. More...
struct  ZYX
 ZYX Rotation order. More...
struct  ZXY
 ZXY Rotation order. More...
class  Matrix
 State tracked NxM dimensional Matrix (ordered in memory by Column). More...
class  Eigen
class  OOBox
class  ParametricCurve
 A base representation of a parametric curve with SIZE component using DATA_TYPE as the data type, ORDER as the order for each component. More...
class  LinearCurve
 A representation of a line with order set to 2. More...
class  QuadraticCurve
 A representation of a quadratic curve with order set to 3. More...
class  CubicCurve
 A representation of a cubic curve with order set to 4. More...
class  Plane
 Plane: Defines a geometrical plane. More...
class  Point
 Point Use points when you need to represent a position. More...
class  Quat
 Quat: Class to encapsulate quaternion behaviors. More...
class  Ray
 Describes a ray. More...
class  Sphere
 Describes a sphere in 3D space by its center point and its radius. More...
class  Tri
 This class defines a triangle as a set of 3 points order in CCW fashion. More...
struct  Type2Type
 A lightweight identifier you can pass to overloaded functions to typefy them. More...
struct  CompileTimeError< true >
class  Vec
 A representation of a vector with SIZE components using DATA_TYPE as the data type for each component. More...
class  VecBase
 Base type for vector-like objects including Points and Vectors. More...
class  VecBase< DATA_TYPE, SIZE, meta::DefaultVecTag >
 Specialized version of VecBase that is actually used for all user interaction with a traditional vector. More...

Typedefs

typedef AABox< float > AABoxf
typedef AABox< double > AABoxd
typedef AxisAngle< float > AxisAnglef
typedef AxisAngle< double > AxisAngled
typedef Coord< Vec3d,
EulerAngleXYZd
CoordVec3EulerAngleXYZd
typedef Coord< Vec3f,
EulerAngleXYZf
CoordVec3EulerAngleXYZf
typedef Coord< Vec4d,
EulerAngleXYZd
CoordVec4EulerAngleXYZd
typedef Coord< Vec4f,
EulerAngleXYZf
CoordVec4EulerAngleXYZf
typedef Coord< Vec3d,
EulerAngleZYXd
CoordVec3EulerAngleZYXd
typedef Coord< Vec3f,
EulerAngleZYXf
CoordVec3EulerAngleZYXf
typedef Coord< Vec4d,
EulerAngleZYXd
CoordVec4EulerAngleZYXd
typedef Coord< Vec4f,
EulerAngleZYXf
CoordVec4EulerAngleZYXf
typedef Coord< Vec3d,
EulerAngleZXYd
CoordVec3EulerAngleZXYd
typedef Coord< Vec3f,
EulerAngleZXYf
CoordVec3EulerAngleZXYf
typedef Coord< Vec4d,
EulerAngleZXYd
CoordVec4EulerAngleZXYd
typedef Coord< Vec4f,
EulerAngleZXYf
CoordVec4EulerAngleZXYf
typedef Coord< Vec3d, AxisAngledCoordVec3AxisAngled
typedef Coord< Vec3f, AxisAnglefCoordVec3AxisAnglef
typedef Coord< Vec4d, AxisAngledCoordVec4AxisAngled
typedef Coord< Vec4f, AxisAnglefCoordVec4AxisAnglef
typedef Coord< Vec3f,
EulerAngleXYZf
Coord3fXYZ
 3 elt types
typedef Coord< Vec3f,
EulerAngleZYXf
Coord3fZYX
typedef Coord< Vec3f,
EulerAngleZXYf
Coord3fZXY
typedef Coord< Vec3d,
EulerAngleXYZd
Coord3dXYZ
typedef Coord< Vec3d,
EulerAngleZYXd
Coord3dZYX
typedef Coord< Vec3d,
EulerAngleZXYd
Coord3dZXY
typedef Coord< Vec4f,
EulerAngleXYZf
Coord4fXYZ
 4 elt types
typedef Coord< Vec4f,
EulerAngleZYXf
Coord4fZYX
typedef Coord< Vec4f,
EulerAngleZXYf
Coord4fZXY
typedef Coord< Vec4d,
EulerAngleXYZd
Coord4dXYZ
typedef Coord< Vec4d,
EulerAngleZYXd
Coord4dZYX
typedef Coord< Vec4d,
EulerAngleZXYd
Coord4dZXY
typedef Coord< Vec3f, QuatfCoord3fQuat
 3 elt types
typedef Coord< Vec3d, QuatdCoord3dQuat
typedef Coord< Vec4f, QuatfCoord4fQuat
 4 elt types
typedef Coord< Vec4d, QuatdCoord4dQuat
typedef Coord< Vec3f, AxisAnglefCoord3fAxisAngle
 3 elt types
typedef Coord< Vec3d, AxisAngledCoord3dAxisAngle
typedef Coord< Vec4f, AxisAnglefCoord4fAxisAngle
 4 elt types
typedef Coord< Vec4d, AxisAngledCoord4dAxisAngle
typedef EulerAngle< float, XYZEulerAngleXYZf
typedef EulerAngle< double, XYZEulerAngleXYZd
typedef EulerAngle< float, ZYXEulerAngleZYXf
typedef EulerAngle< double, ZYXEulerAngleZYXd
typedef EulerAngle< float, ZXYEulerAngleZXYf
typedef EulerAngle< double, ZXYEulerAngleZXYd
typedef Frustum< float > Frustumf
typedef Frustum< double > Frustumd
typedef LineSeg< float > LineSegf
typedef LineSeg< double > LineSegd
typedef Matrix< float, 2, 2 > Matrix22f
typedef Matrix< double, 2, 2 > Matrix22d
typedef Matrix< float, 2, 3 > Matrix23f
typedef Matrix< double, 2, 3 > Matrix23d
typedef Matrix< float, 3, 3 > Matrix33f
typedef Matrix< double, 3, 3 > Matrix33d
typedef Matrix< float, 3, 4 > Matrix34f
typedef Matrix< double, 3, 4 > Matrix34d
typedef Matrix< float, 4, 4 > Matrix44f
typedef Matrix< double, 4, 4 > Matrix44d
typedef LinearCurve< float, 1 > LinearCurve1f
typedef LinearCurve< float, 2 > LinearCurve2f
typedef LinearCurve< float, 3 > LinearCurve3f
typedef LinearCurve< double, 1 > LinearCurve1d
typedef LinearCurve< double, 2 > LinearCurve2d
typedef LinearCurve< double, 3 > LinearCurve3d
typedef QuadraticCurve< float, 1 > QuadraticCurve1f
typedef QuadraticCurve< float, 2 > QuadraticCurve2f
typedef QuadraticCurve< float, 3 > QuadraticCurve3f
typedef QuadraticCurve< double, 1 > QuadraticCurve1d
typedef QuadraticCurve< double, 2 > QuadraticCurve2d
typedef QuadraticCurve< double, 3 > QuadraticCurve3d
typedef CubicCurve< float, 1 > CubicCurve1f
typedef CubicCurve< float, 2 > CubicCurve2f
typedef CubicCurve< float, 3 > CubicCurve3f
typedef CubicCurve< double, 1 > CubicCurve1d
typedef CubicCurve< double, 2 > CubicCurve2d
typedef CubicCurve< double, 3 > CubicCurve3d
typedef Plane< float > Planef
typedef Plane< double > Planed
typedef Point< int, 2 > Point2i
typedef Point< float, 2 > Point2f
typedef Point< double, 2 > Point2d
typedef Point< int, 3 > Point3i
typedef Point< float, 3 > Point3f
typedef Point< double, 3 > Point3d
typedef Point< int, 4 > Point4i
typedef Point< float, 4 > Point4f
typedef Point< double, 4 > Point4d
typedef Quat< float > Quatf
typedef Quat< double > Quatd
typedef Ray< float > Rayf
typedef Ray< double > Rayd
typedef Sphere< float > Spheref
typedef Sphere< double > Sphered
typedef Tri< float > Trif
typedef Tri< double > Trid
typedef Tri< int > Trii
typedef Vec< int, 2 > Vec2i
typedef Vec< float, 2 > Vec2f
typedef Vec< double, 2 > Vec2d
typedef Vec< int, 3 > Vec3i
typedef Vec< float, 3 > Vec3f
typedef Vec< double, 3 > Vec3d
typedef Vec< int, 4 > Vec4i
typedef Vec< float, 4 > Vec4f
typedef Vec< double, 4 > Vec4d

Enumerations

enum  VectorIndex { Xelt = 0, Yelt = 1, Zelt = 2, Welt = 3 }
 

use the values in this enum to index vector data types (such as Vec, Point, Quat).

More...
enum  PlaneSide { ON_PLANE, POS_SIDE, NEG_SIDE }
 

Used to describe where a point lies in relationship to a plane.

More...

Functions

const AxisAngle< float > AXISANGLE_IDENTITYF (0.0f, 1.0f, 0.0f, 0.0f)
const AxisAngle< double > AXISANGLE_IDENTITYD (0.0, 1.0, 0.0, 0.0)
template<class DATA_TYPE >
bool isInVolume (const Sphere< DATA_TYPE > &container, const Point< DATA_TYPE, 3 > &pt)
 Tests if the given point is inside or on the surface of the given spherical volume.
template<class DATA_TYPE >
bool isInVolume (const Sphere< DATA_TYPE > &container, const Sphere< DATA_TYPE > &sphere)
 Tests if the given sphere is completely inside or on the surface of the given spherical volume.
template<class DATA_TYPE >
void extendVolume (Sphere< DATA_TYPE > &container, const Point< DATA_TYPE, 3 > &pt)
 Modifies the existing sphere to tightly enclose itself and the given point.
template<class DATA_TYPE >
void extendVolume (Sphere< DATA_TYPE > &container, const Sphere< DATA_TYPE > &sphere)
 Modifies the container to tightly enclose itself and the given sphere.
template<class DATA_TYPE >
void makeVolume (Sphere< DATA_TYPE > &container, const std::vector< Point< DATA_TYPE, 3 > > &pts)
 Modifies the given sphere to tightly enclose all points in the given std::vector.
template<class DATA_TYPE >
bool isOnVolume (const Sphere< DATA_TYPE > &container, const Point< DATA_TYPE, 3 > &pt)
 Modifies the given sphere to tightly enclose all spheres in the given std::vector.
template<class DATA_TYPE >
bool isOnVolume (const Sphere< DATA_TYPE > &container, const Point< DATA_TYPE, 3 > &pt, const DATA_TYPE &tol)
 Tests of the given point is on the surface of the container with the given tolerance.
template<class DATA_TYPE >
bool isInVolume (const AABox< DATA_TYPE > &container, const Point< DATA_TYPE, 3 > &pt)
 Tests if the given point is inside (or on) the surface of the given AABox volume.
template<class DATA_TYPE >
bool isInVolumeExclusive (const AABox< DATA_TYPE > &container, const Point< DATA_TYPE, 3 > &pt)
 Tests if the given point is inside (not on) the surface of the given AABox volume.
template<class DATA_TYPE >
bool isInVolume (const AABox< DATA_TYPE > &container, const AABox< DATA_TYPE > &box)
 Tests if the given AABox is completely inside or on the surface of the given AABox container.
template<class DATA_TYPE >
void extendVolume (AABox< DATA_TYPE > &container, const Point< DATA_TYPE, 3 > &pt)
 Modifies the existing AABox to tightly enclose itself and the given point.
template<class DATA_TYPE >
void extendVolume (AABox< DATA_TYPE > &container, const AABox< DATA_TYPE > &box)
 Modifies the container to tightly enclose itself and the given AABox.
template<class DATA_TYPE >
void makeVolume (AABox< DATA_TYPE > &box, const Sphere< DATA_TYPE > &sph)
 Creates an AABox that tightly encloses the given Sphere.
template<typename T >
bool isInVolume (const Frustum< T > &f, const Point< T, 3 > &p, unsigned int &idx)
template<typename T >
bool isInVolume (const Frustum< T > &f, const Sphere< T > &s)
template<typename T >
bool isInVolume (const Frustum< T > &f, const AABox< T > &box)
template<typename T >
bool isInVolume (const Frustum< T > &f, const Tri< T > &tri)
const EulerAngle< float, XYZEULERANGLE_IDENTITY_XYZF (0.0f, 0.0f, 0.0f)
const EulerAngle< double, XYZEULERANGLE_IDENTITY_XYZD (0.0, 0.0, 0.0)
const EulerAngle< float, ZYXEULERANGLE_IDENTITY_ZYXF (0.0f, 0.0f, 0.0f)
const EulerAngle< double, ZYXEULERANGLE_IDENTITY_ZYXD (0.0, 0.0, 0.0)
const EulerAngle< float, ZXYEULERANGLE_IDENTITY_ZXYF (0.0f, 0.0f, 0.0f)
const EulerAngle< double, ZXYEULERANGLE_IDENTITY_ZXYD (0.0, 0.0, 0.0)
Matrix44fset (Matrix44f &mat, const OSG::Matrix &osgMat)
 Converts an OpenSG matrix to a gmtl::Matrix.
OSG::Matrix & set (OSG::Matrix &osgMat, const Matrix44f &mat)
 Converts a GMTL matrix to an OpenSG matrix.
void GaussPointsFit (int iQuantity, const Point3 *akPoint, Point3 &rkCenter, Vec3 akAxis[3], float afExtent[3])
bool GaussPointsFit (int iQuantity, const Vec3 *akPoint, const bool *abValid, Vec3 &rkCenter, Vec3 akAxis[3], float afExtent[3])
template<class DATA_TYPE >
void normalize (Frustum< DATA_TYPE > &f)
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
void setRow (Vec< DATA_TYPE, COLS > &dest, const Matrix< DATA_TYPE, ROWS, COLS > &src, unsigned row)
 Accesses a particular row in the matrix by copying the values in the row into the given vector.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Vec< DATA_TYPE, COLS > makeRow (const Matrix< DATA_TYPE, ROWS, COLS > &src, unsigned row)
 Accesses a particular row in the matrix by creating a new vector containing the values in the given matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
void setColumn (Vec< DATA_TYPE, ROWS > &dest, const Matrix< DATA_TYPE, ROWS, COLS > &src, unsigned col)
 Accesses a particular column in the matrix by copying the values in the column into the given vector.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Vec< DATA_TYPE, ROWS > makeColumn (const Matrix< DATA_TYPE, ROWS, COLS > &src, unsigned col)
 Accesses a particular column in the matrix by creating a new vector containing the values in the given matrix.
template<class DATA_TYPE >
bool intersect (const AABox< DATA_TYPE > &box1, const AABox< DATA_TYPE > &box2)
 Tests if the given AABoxes intersect with each other.
template<class DATA_TYPE >
bool intersect (const AABox< DATA_TYPE > &box, const Point< DATA_TYPE, 3 > &point)
 Tests if the given AABox and point intersect with each other.
template<class DATA_TYPE >
bool intersect (const AABox< DATA_TYPE > &box1, const Vec< DATA_TYPE, 3 > &path1, const AABox< DATA_TYPE > &box2, const Vec< DATA_TYPE, 3 > &path2, DATA_TYPE &firstContact, DATA_TYPE &secondContact)
 Tests if the given AABoxes intersect if moved along the given paths.
template<class DATA_TYPE >
bool intersectAABoxRay (const AABox< DATA_TYPE > &box, const Ray< DATA_TYPE > &ray, DATA_TYPE &tIn, DATA_TYPE &tOut)
 Given an axis-aligned bounding box and a ray (or subclass thereof), returns whether the ray intersects the box, and if so, tIn and tOut are set to the parametric terms on the ray where the segment enters and exits the box respectively.
template<class DATA_TYPE >
bool intersect (const AABox< DATA_TYPE > &box, const LineSeg< DATA_TYPE > &seg, unsigned int &numHits, DATA_TYPE &tIn, DATA_TYPE &tOut)
 Given a line segment and an axis-aligned bounding box, returns whether the line intersects the box, and if so, tIn and tOut are set to the parametric terms on the line segment where the segment enters and exits the box respectively.
template<class DATA_TYPE >
bool intersect (const LineSeg< DATA_TYPE > &seg, const AABox< DATA_TYPE > &box, unsigned int &numHits, DATA_TYPE &tIn, DATA_TYPE &tOut)
 Given a line segment and an axis-aligned bounding box, returns whether the line intersects the box, and if so, tIn and tOut are set to the parametric terms on the line segment where the segment enters and exits the box respectively.
template<class DATA_TYPE >
bool intersect (const AABox< DATA_TYPE > &box, const Ray< DATA_TYPE > &ray, unsigned int &numHits, DATA_TYPE &tIn, DATA_TYPE &tOut)
 Given a ray and an axis-aligned bounding box, returns whether the ray intersects the box, and if so, tIn and tOut are set to the parametric terms on the ray where it enters and exits the box respectively.
template<class DATA_TYPE >
bool intersect (const Ray< DATA_TYPE > &ray, const AABox< DATA_TYPE > &box, unsigned int &numHits, DATA_TYPE &tIn, DATA_TYPE &tOut)
 Given a ray and an axis-aligned bounding box, returns whether the ray intersects the box, and if so, tIn and tOut are set to the parametric terms on the ray where it enters and exits the box respectively.
template<class DATA_TYPE >
bool intersect (const Sphere< DATA_TYPE > &sph1, const Vec< DATA_TYPE, 3 > &path1, const Sphere< DATA_TYPE > &sph2, const Vec< DATA_TYPE, 3 > &path2, DATA_TYPE &firstContact, DATA_TYPE &secondContact)
 Tests if the given Spheres intersect if moved along the given paths.
template<class DATA_TYPE >
bool intersect (const AABox< DATA_TYPE > &box, const Sphere< DATA_TYPE > &sph)
 Tests if the given AABox and Sphere intersect with each other.
template<class DATA_TYPE >
bool intersect (const Sphere< DATA_TYPE > &sph, const AABox< DATA_TYPE > &box)
 Tests if the given AABox and Sphere intersect with each other.
template<class DATA_TYPE >
bool intersect (const Sphere< DATA_TYPE > &sphere, const Point< DATA_TYPE, 3 > &point)
 intersect point/sphere.
template<typename T >
bool intersect (const Sphere< T > &sphere, const Ray< T > &ray, int &numhits, T &t0, T &t1)
 intersect ray/sphere-shell (not volume).
template<typename T >
bool intersect (const Sphere< T > &sphere, const LineSeg< T > &lineseg, int &numhits, T &t0, T &t1)
 intersect LineSeg/Sphere-shell (not volume).
template<typename T >
bool intersectVolume (const Sphere< T > &sphere, const LineSeg< T > &ray, int &numhits, T &t0, T &t1)
 intersect lineseg/sphere-volume.
template<typename T >
bool intersectVolume (const Sphere< T > &sphere, const Ray< T > &ray, int &numhits, T &t0, T &t1)
 intersect ray/sphere-volume.
template<class DATA_TYPE >
bool intersect (const Plane< DATA_TYPE > &plane, const Ray< DATA_TYPE > &ray, DATA_TYPE &t)
 Tests if the given plane and ray intersect with each other.
template<class DATA_TYPE >
bool intersect (const Plane< DATA_TYPE > &plane, const LineSeg< DATA_TYPE > &seg, DATA_TYPE &t)
 Tests if the given plane and lineseg intersect with each other.
template<class DATA_TYPE >
bool intersect (const Tri< DATA_TYPE > &tri, const Ray< DATA_TYPE > &ray, float &u, float &v, float &t)
 Tests if the given triangle and ray intersect with each other.
template<class DATA_TYPE >
bool intersectDoubleSided (const Tri< DATA_TYPE > &tri, const Ray< DATA_TYPE > &ray, DATA_TYPE &u, DATA_TYPE &v, DATA_TYPE &t)
 Tests if the given triangle intersects with the given ray, from both sides.
template<class DATA_TYPE >
bool intersect (const Tri< DATA_TYPE > &tri, const LineSeg< DATA_TYPE > &lineseg, DATA_TYPE &u, DATA_TYPE &v, DATA_TYPE &t)
 Tests if the given triangle and line segment intersect with each other.
template<class DATA_TYPE >
Point< DATA_TYPE, 3 > findNearestPt (const LineSeg< DATA_TYPE > &lineseg, const Point< DATA_TYPE, 3 > &pt)
 Finds the closest point on the line segment to a given point.
template<class DATA_TYPE >
DATA_TYPE distance (const LineSeg< DATA_TYPE > &lineseg, const Point< DATA_TYPE, 3 > &pt)
 Computes the shortest distance from the line segment to the given point.
template<class DATA_TYPE >
DATA_TYPE distanceSquared (const LineSeg< DATA_TYPE > &lineseg, const Point< DATA_TYPE, 3 > &pt)
 Computes the shortest distance from the line segment to the given point.
int combineMatrixStates (int state1, int state2)
 utility function for use by matrix operations.
template<typename DATA_TYPE_OUT , typename DATA_TYPE_IN , unsigned ROWS, unsigned COLS>
gmtl::Matrix< DATA_TYPE_OUT,
ROWS, COLS > 
convertTo (const gmtl::Matrix< DATA_TYPE_IN, ROWS, COLS > &in)
 Converts a matrix of one data type to another, such as gmtl::Matrix44f to gmtl::Matrix44d.
const Quat< float > QUAT_MULT_IDENTITYF (0.0f, 0.0f, 0.0f, 1.0f)
const Quat< float > QUAT_ADD_IDENTITYF (0.0f, 0.0f, 0.0f, 0.0f)
const Quat< float > QUAT_IDENTITYF (QUAT_MULT_IDENTITYF)
const Quat< double > QUAT_MULT_IDENTITYD (0.0, 0.0, 0.0, 1.0)
const Quat< double > QUAT_ADD_IDENTITYD (0.0, 0.0, 0.0, 0.0)
const Quat< double > QUAT_IDENTITYD (QUAT_MULT_IDENTITYD)
template<class DATA_TYPE >
bool operator== (const Ray< DATA_TYPE > &ls1, const Ray< DATA_TYPE > &ls2)
 Compare two line segments to see if they are EXACTLY the same.
template<class DATA_TYPE >
bool operator!= (const Ray< DATA_TYPE > &ls1, const Ray< DATA_TYPE > &ls2)
 Compare two line segments to see if they are not EXACTLY the same.
template<class DATA_TYPE >
bool isEqual (const Ray< DATA_TYPE > &ls1, const Ray< DATA_TYPE > &ls2, const DATA_TYPE &eps)
 Compare two line segments to see if the are the same within the given tolerance.
const char * getVersion ()
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Ray< DATA_TYPE > & xform (Ray< DATA_TYPE > &result, const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const Ray< DATA_TYPE > &ray)
 transform ray by a matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Ray< DATA_TYPE > operator* (const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const Ray< DATA_TYPE > &ray)
 ray * a matrix multiplication of [m x k] matrix by a ray.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Ray< DATA_TYPE > & operator*= (Ray< DATA_TYPE > &ray, const Matrix< DATA_TYPE, ROWS, COLS > &matrix)
 ray *= a matrix multiplication of [m x k] matrix by a ray.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
LineSeg< DATA_TYPE > & xform (LineSeg< DATA_TYPE > &result, const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const LineSeg< DATA_TYPE > &seg)
 transform seg by a matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
LineSeg< DATA_TYPE > operator* (const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const LineSeg< DATA_TYPE > &seg)
 seg * a matrix multiplication of [m x k] matrix by a seg.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
LineSeg< DATA_TYPE > & operator*= (LineSeg< DATA_TYPE > &seg, const Matrix< DATA_TYPE, ROWS, COLS > &matrix)
 seg *= a matrix multiplication of [m x k] matrix by a seg.
AABox Comparitors

template<class DATA_TYPE >
bool operator== (const AABox< DATA_TYPE > &b1, const AABox< DATA_TYPE > &b2)
 Compare two AABoxes to see if they are EXACTLY the same.
template<class DATA_TYPE >
bool operator!= (const AABox< DATA_TYPE > &b1, const AABox< DATA_TYPE > &b2)
 Compare two AABoxes to see if they are not EXACTLY the same.
template<class DATA_TYPE >
bool isEqual (const AABox< DATA_TYPE > &b1, const AABox< DATA_TYPE > &b2, const DATA_TYPE &eps)
 Compare two AABoxes to see if they are the same within the given tolerance.
AxisAngle Comparitors

template<class DATA_TYPE >
bool operator== (const AxisAngle< DATA_TYPE > &a1, const AxisAngle< DATA_TYPE > &a2)
 Compares 2 AxisAngles to see if they are exactly the same.
template<class DATA_TYPE >
bool operator!= (const AxisAngle< DATA_TYPE > &a1, const AxisAngle< DATA_TYPE > &a2)
 Compares 2 AxisAngles to see if they are NOT exactly the same.
template<class DATA_TYPE >
bool isEqual (const AxisAngle< DATA_TYPE > &a1, const AxisAngle< DATA_TYPE > &a2, const DATA_TYPE eps=0)
 Compares a1 and a2 to see if they are the same within the given epsilon tolerance.
Coord Comparitors

template<typename POS_TYPE , typename ROT_TYPE >
bool operator== (const Coord< POS_TYPE, ROT_TYPE > &c1, const Coord< POS_TYPE, ROT_TYPE > &c2)
 Compare two coordinate frames for equality.
template<typename POS_TYPE , typename ROT_TYPE >
bool operator!= (const Coord< POS_TYPE, ROT_TYPE > &c1, const Coord< POS_TYPE, ROT_TYPE > &c2)
 Compare two coordinate frames for not-equality.
template<typename POS_TYPE , typename ROT_TYPE >
bool isEqual (const Coord< POS_TYPE, ROT_TYPE > &c1, const Coord< POS_TYPE, ROT_TYPE > &c2, typename Coord< POS_TYPE, ROT_TYPE >::DataType tol=0)
 Compare two coordinate frames for equality with a given tolerance.
EulerAngle Comparitors

template<class DATA_TYPE , typename ROT_ORDER >
bool operator== (const EulerAngle< DATA_TYPE, ROT_ORDER > &e1, const EulerAngle< DATA_TYPE, ROT_ORDER > &e2)
 Compares 2 EulerAngles (component-wise) to see if they are exactly the same.
template<class DATA_TYPE , typename ROT_ORDER >
bool operator!= (const EulerAngle< DATA_TYPE, ROT_ORDER > &e1, const EulerAngle< DATA_TYPE, ROT_ORDER > &e2)
 Compares e1 and e2 (component-wise) to see if they are NOT exactly the same.
template<class DATA_TYPE , typename ROT_ORDER >
bool isEqual (const EulerAngle< DATA_TYPE, ROT_ORDER > &e1, const EulerAngle< DATA_TYPE, ROT_ORDER > &e2, const DATA_TYPE eps=0)
 Compares e1 and e2 (component-wise) to see if they are the same within a given tolerance.
Vec Generators

template<typename DATA_TYPE >
Vec< DATA_TYPE, 3 > makeVec (const Quat< DATA_TYPE > &quat)
 create a vector from the vector component of a quaternion
template<typename DATA_TYPE , unsigned SIZE>
Vec< DATA_TYPE, SIZE > makeNormal (Vec< DATA_TYPE, SIZE > vec)
 create a normalized vector from the given vector.
template<class DATA_TYPE >
Vec< DATA_TYPE, 3 > makeCross (const Vec< DATA_TYPE, 3 > &v1, const Vec< DATA_TYPE, 3 > &v2)
 Computes the cross product between v1 and v2 and returns the result.
template<typename VEC_TYPE , typename DATA_TYPE , unsigned ROWS, unsigned COLS>
VEC_TYPE & setTrans (VEC_TYPE &result, const Matrix< DATA_TYPE, ROWS, COLS > &arg)
 Set vector using translation portion of the matrix.
Quat Generators

template<typename DATA_TYPE >
Quat< DATA_TYPE > & setPure (Quat< DATA_TYPE > &quat, const Vec< DATA_TYPE, 3 > &vec)
 Set pure quaternion.
template<typename DATA_TYPE >
Quat< DATA_TYPE > makePure (const Vec< DATA_TYPE, 3 > &vec)
 create a pure quaternion
template<typename DATA_TYPE >
Quat< DATA_TYPE > makeNormal (const Quat< DATA_TYPE > &quat)
 Normalize a quaternion.
template<typename DATA_TYPE >
Quat< DATA_TYPE > makeConj (const Quat< DATA_TYPE > &quat)
 quaternion complex conjugate.
template<typename DATA_TYPE >
Quat< DATA_TYPE > makeInvert (const Quat< DATA_TYPE > &quat)
 create quaternion from the inverse of another quaternion.
template<typename DATA_TYPE >
Quat< DATA_TYPE > & set (Quat< DATA_TYPE > &result, const AxisAngle< DATA_TYPE > &axisAngle)
 Convert an AxisAngle to a Quat.
template<typename DATA_TYPE >
Quat< DATA_TYPE > & setRot (Quat< DATA_TYPE > &result, const AxisAngle< DATA_TYPE > &axisAngle)
 Redundant duplication of the set(quat,axisangle) function, this is provided only for template compatibility.
template<typename DATA_TYPE , typename ROT_ORDER >
Quat< DATA_TYPE > & set (Quat< DATA_TYPE > &result, const EulerAngle< DATA_TYPE, ROT_ORDER > &euler)
 Convert an EulerAngle rotation to a Quaternion rotation.
template<typename DATA_TYPE , typename ROT_ORDER >
Quat< DATA_TYPE > & setRot (Quat< DATA_TYPE > &result, const EulerAngle< DATA_TYPE, ROT_ORDER > &euler)
 Redundant duplication of the set(quat,eulerangle) function, this is provided only for template compatibility.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Quat< DATA_TYPE > & set (Quat< DATA_TYPE > &quat, const Matrix< DATA_TYPE, ROWS, COLS > &mat)
 Convert a Matrix to a Quat.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Quat< DATA_TYPE > & setRot (Quat< DATA_TYPE > &result, const Matrix< DATA_TYPE, ROWS, COLS > &mat)
 Redundant duplication of the set(quat,mat) function, this is provided only for template compatibility.
AxisAngle Generators

template<typename DATA_TYPE >
AxisAngle< DATA_TYPE > & set (AxisAngle< DATA_TYPE > &axisAngle, Quat< DATA_TYPE > quat)
 Convert a rotation quaternion to an AxisAngle.
template<typename DATA_TYPE >
AxisAngle< DATA_TYPE > & setRot (AxisAngle< DATA_TYPE > &result, Quat< DATA_TYPE > quat)
 Redundant duplication of the set(axisangle,quat) function, this is provided only for template compatibility.
template<typename DATA_TYPE >
AxisAngle< DATA_TYPE > makeNormal (const AxisAngle< DATA_TYPE > &a)
 make the axis of an AxisAngle normalized
EulerAngle Generators

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, typename ROT_ORDER >
EulerAngle< DATA_TYPE,
ROT_ORDER > & 
set (EulerAngle< DATA_TYPE, ROT_ORDER > &euler, const Matrix< DATA_TYPE, ROWS, COLS > &mat)
 Convert Matrix to EulerAngle.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, typename ROT_ORDER >
EulerAngle< DATA_TYPE,
ROT_ORDER > & 
setRot (EulerAngle< DATA_TYPE, ROT_ORDER > &result, const Matrix< DATA_TYPE, ROWS, COLS > &mat)
 Redundant duplication of the set(eulerangle,quat) function, this is provided only for template compatibility.
Matrix Generators

template<typename T >
Matrix< T, 4, 4 > & setFrustum (Matrix< T, 4, 4 > &result, T left, T top, T right, T bottom, T nr, T fr)
 Set an arbitrary projection matrix.
template<typename T >
Matrix< T, 4, 4 > & setOrtho (Matrix< T, 4, 4 > &result, T left, T top, T right, T bottom, T nr, T fr)
 Set an orthographic projection matrix creates a transformation that produces a parallel projection matrix.
template<typename T >
Matrix< T, 4, 4 > & setPerspective (Matrix< T, 4, 4 > &result, T fovy, T aspect, T nr, T fr)
 Set a symmetric perspective projection matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned SIZE, typename REP >
Matrix< DATA_TYPE, ROWS, COLS > & setTrans (Matrix< DATA_TYPE, ROWS, COLS > &result, const VecBase< DATA_TYPE, SIZE, REP > &trans)
 Set matrix translation from vec.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned SIZE>
Matrix< DATA_TYPE, ROWS, COLS > & setScale (Matrix< DATA_TYPE, ROWS, COLS > &result, const Vec< DATA_TYPE, SIZE > &scale)
 Set the scale part of a matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & setScale (Matrix< DATA_TYPE, ROWS, COLS > &result, const DATA_TYPE scale)
 Sets the scale part of a matrix.
template<typename MATRIX_TYPE , typename INPUT_TYPE >
MATRIX_TYPE makeScale (const INPUT_TYPE &scale, Type2Type< MATRIX_TYPE > t=Type2Type< MATRIX_TYPE >())
 Create a scale matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & setRot (Matrix< DATA_TYPE, ROWS, COLS > &result, const AxisAngle< DATA_TYPE > &axisAngle)
 Set the rotation portion of a rotation matrix using an axis and an angle (in radians).
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, typename ROT_ORDER >
Matrix< DATA_TYPE, ROWS, COLS > & setRot (Matrix< DATA_TYPE, ROWS, COLS > &result, const EulerAngle< DATA_TYPE, ROT_ORDER > &euler)
 Set (only) the rotation part of a matrix using an EulerAngle (angles are in radians).
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & set (Matrix< DATA_TYPE, ROWS, COLS > &result, const AxisAngle< DATA_TYPE > &axisAngle)
 Convert an AxisAngle to a rotation matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, typename ROT_ORDER >
Matrix< DATA_TYPE, ROWS, COLS > & set (Matrix< DATA_TYPE, ROWS, COLS > &result, const EulerAngle< DATA_TYPE, ROT_ORDER > &euler)
 Convert an EulerAngle to a rotation matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
DATA_TYPE makeYRot (const Matrix< DATA_TYPE, ROWS, COLS > &mat)
 Extracts the Y axis rotation information from the matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
DATA_TYPE makeXRot (const Matrix< DATA_TYPE, ROWS, COLS > &mat)
 Extracts the X-axis rotation information from the matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
DATA_TYPE makeZRot (const Matrix< DATA_TYPE, ROWS, COLS > &mat)
 Extracts the Z-axis rotation information from the matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & setDirCos (Matrix< DATA_TYPE, ROWS, COLS > &result, const Vec< DATA_TYPE, 3 > &xDestAxis, const Vec< DATA_TYPE, 3 > &yDestAxis, const Vec< DATA_TYPE, 3 > &zDestAxis, const Vec< DATA_TYPE, 3 > &xSrcAxis=Vec< DATA_TYPE, 3 >(1, 0, 0), const Vec< DATA_TYPE, 3 > &ySrcAxis=Vec< DATA_TYPE, 3 >(0, 1, 0), const Vec< DATA_TYPE, 3 > &zSrcAxis=Vec< DATA_TYPE, 3 >(0, 0, 1))
 create a rotation matrix that will rotate from SrcAxis to DestAxis.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & setAxes (Matrix< DATA_TYPE, ROWS, COLS > &result, const Vec< DATA_TYPE, 3 > &xAxis, const Vec< DATA_TYPE, 3 > &yAxis, const Vec< DATA_TYPE, 3 > &zAxis)
 set the matrix given the raw coordinate axes.
template<typename ROTATION_TYPE >
ROTATION_TYPE makeAxes (const Vec< typename ROTATION_TYPE::DataType, 3 > &xAxis, const Vec< typename ROTATION_TYPE::DataType, 3 > &yAxis, const Vec< typename ROTATION_TYPE::DataType, 3 > &zAxis, Type2Type< ROTATION_TYPE > t=Type2Type< ROTATION_TYPE >())
 set the matrix given the raw coordinate axes.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > makeTranspose (const Matrix< DATA_TYPE, ROWS, COLS > &m)
 create a matrix transposed from the source.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > makeInvert (const Matrix< DATA_TYPE, ROWS, COLS > &src)
 Creates a matrix that is the inverse of the given source matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & setRot (Matrix< DATA_TYPE, ROWS, COLS > &mat, const Quat< DATA_TYPE > &q)
 Set the rotation portion of a matrix (3x3) from a rotation quaternion.
template<typename DATATYPE , typename POS_TYPE , typename ROT_TYPE , unsigned MATCOLS, unsigned MATROWS>
Matrix< DATATYPE, MATROWS,
MATCOLS > & 
set (Matrix< DATATYPE, MATROWS, MATCOLS > &mat, const Coord< POS_TYPE, ROT_TYPE > &coord)
 Convert a Coord to a Matrix Note: It is set directly, but this is equivalent to T*R where T is the translation matrix and R is the rotation matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & set (Matrix< DATA_TYPE, ROWS, COLS > &mat, const Quat< DATA_TYPE > &q)
 Convert a Quat to a rotation Matrix.
Coord Generators

template<typename DATATYPE , typename POS_TYPE , typename ROT_TYPE , unsigned MATCOLS, unsigned MATROWS>
Coord< POS_TYPE, ROT_TYPE > & set (Coord< POS_TYPE, ROT_TYPE > &eulercoord, const Matrix< DATATYPE, MATROWS, MATCOLS > &mat)
 convert Matrix to Coord
template<typename DATATYPE , typename POS_TYPE , typename ROT_TYPE , unsigned MATCOLS, unsigned MATROWS>
Coord< POS_TYPE, ROT_TYPE > & setRot (Coord< POS_TYPE, ROT_TYPE > &result, const Matrix< DATATYPE, MATROWS, MATCOLS > &mat)
 Redundant duplication of the set(coord,mat) function, this is provided only for template compatibility.
Generic Generators (any type)

template<typename TARGET_TYPE , typename SOURCE_TYPE >
TARGET_TYPE make (const SOURCE_TYPE &src, Type2Type< TARGET_TYPE > t=Type2Type< TARGET_TYPE >())
 Construct an object from another object of a different type.
template<typename ROTATION_TYPE , typename SOURCE_TYPE >
ROTATION_TYPE makeRot (const SOURCE_TYPE &coord, Type2Type< ROTATION_TYPE > t=Type2Type< ROTATION_TYPE >())
 Create a rotation datatype from another rotation datatype.
template<typename ROTATION_TYPE >
ROTATION_TYPE makeDirCos (const Vec< typename ROTATION_TYPE::DataType, 3 > &xDestAxis, const Vec< typename ROTATION_TYPE::DataType, 3 > &yDestAxis, const Vec< typename ROTATION_TYPE::DataType, 3 > &zDestAxis, const Vec< typename ROTATION_TYPE::DataType, 3 > &xSrcAxis=Vec< typename ROTATION_TYPE::DataType, 3 >(1, 0, 0), const Vec< typename ROTATION_TYPE::DataType, 3 > &ySrcAxis=Vec< typename ROTATION_TYPE::DataType, 3 >(0, 1, 0), const Vec< typename ROTATION_TYPE::DataType, 3 > &zSrcAxis=Vec< typename ROTATION_TYPE::DataType, 3 >(0, 0, 1), Type2Type< ROTATION_TYPE > t=Type2Type< ROTATION_TYPE >())
 Create a rotation matrix or quaternion (or any other rotation data type) using direction cosines.
template<typename TRANS_TYPE , typename SRC_TYPE >
TRANS_TYPE makeTrans (const SRC_TYPE &arg, Type2Type< TRANS_TYPE > t=Type2Type< TRANS_TYPE >())
 Make a translation datatype from another translation datatype.
template<typename ROTATION_TYPE >
ROTATION_TYPE makeRot (const Vec< typename ROTATION_TYPE::DataType, 3 > &from, const Vec< typename ROTATION_TYPE::DataType, 3 > &to)
 Create a rotation datatype that will xform first vector to the second.
template<typename DEST_TYPE , typename DATA_TYPE >
DEST_TYPE & setRot (DEST_TYPE &result, const Vec< DATA_TYPE, 3 > &from, const Vec< DATA_TYPE, 3 > &to)
 set a rotation datatype that will xform first vector to the second.
Matrix Operations

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & identity (Matrix< DATA_TYPE, ROWS, COLS > &result)
 Make identity matrix out the matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & zero (Matrix< DATA_TYPE, ROWS, COLS > &result)
 zero out the matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned INTERNAL, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & mult (Matrix< DATA_TYPE, ROWS, COLS > &result, const Matrix< DATA_TYPE, ROWS, INTERNAL > &lhs, const Matrix< DATA_TYPE, INTERNAL, COLS > &rhs)
 matrix multiply.
template<typename DATA_TYPE , unsigned ROWS, unsigned INTERNAL, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > operator* (const Matrix< DATA_TYPE, ROWS, INTERNAL > &lhs, const Matrix< DATA_TYPE, INTERNAL, COLS > &rhs)
 matrix * matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & sub (Matrix< DATA_TYPE, ROWS, COLS > &result, const Matrix< DATA_TYPE, ROWS, COLS > &lhs, const Matrix< DATA_TYPE, ROWS, COLS > &rhs)
 matrix subtraction (algebraic operation for matrix).
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & add (Matrix< DATA_TYPE, ROWS, COLS > &result, const Matrix< DATA_TYPE, ROWS, COLS > &lhs, const Matrix< DATA_TYPE, ROWS, COLS > &rhs)
 matrix addition (algebraic operation for matrix).
template<typename DATA_TYPE , unsigned SIZE>
Matrix< DATA_TYPE, SIZE, SIZE > & postMult (Matrix< DATA_TYPE, SIZE, SIZE > &result, const Matrix< DATA_TYPE, SIZE, SIZE > &operand)
 matrix postmultiply.
template<typename DATA_TYPE , unsigned SIZE>
Matrix< DATA_TYPE, SIZE, SIZE > & preMult (Matrix< DATA_TYPE, SIZE, SIZE > &result, const Matrix< DATA_TYPE, SIZE, SIZE > &operand)
 matrix preMultiply.
template<typename DATA_TYPE , unsigned SIZE>
Matrix< DATA_TYPE, SIZE, SIZE > & operator*= (Matrix< DATA_TYPE, SIZE, SIZE > &result, const Matrix< DATA_TYPE, SIZE, SIZE > &operand)
 matrix postmult (operator*=).
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & mult (Matrix< DATA_TYPE, ROWS, COLS > &result, const Matrix< DATA_TYPE, ROWS, COLS > &mat, const DATA_TYPE &scalar)
 matrix scalar mult.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & mult (Matrix< DATA_TYPE, ROWS, COLS > &result, DATA_TYPE scalar)
 matrix scalar mult.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & operator*= (Matrix< DATA_TYPE, ROWS, COLS > &result, const DATA_TYPE &scalar)
 matrix scalar mult (operator*=).
template<typename DATA_TYPE , unsigned SIZE>
Matrix< DATA_TYPE, SIZE, SIZE > & transpose (Matrix< DATA_TYPE, SIZE, SIZE > &result)
 matrix transpose in place.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & transpose (Matrix< DATA_TYPE, ROWS, COLS > &result, const Matrix< DATA_TYPE, COLS, ROWS > &source)
 matrix transpose from one type to another (i.e.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & invertTrans (Matrix< DATA_TYPE, ROWS, COLS > &result, const Matrix< DATA_TYPE, ROWS, COLS > &src)
 translational matrix inversion.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & invertOrthogonal (Matrix< DATA_TYPE, ROWS, COLS > &result, const Matrix< DATA_TYPE, ROWS, COLS > &src)
 orthogonal matrix inversion.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & invertAffine (Matrix< DATA_TYPE, ROWS, COLS > &result, const Matrix< DATA_TYPE, ROWS, COLS > &source)
 affine matrix inversion.
template<typename DATA_TYPE , unsigned SIZE>
Matrix< DATA_TYPE, SIZE, SIZE > & invertFull_GJ (Matrix< DATA_TYPE, SIZE, SIZE > &result, const Matrix< DATA_TYPE, SIZE, SIZE > &src)
 Full matrix inversion using Gauss-Jordan elimination.
template<typename DATA_TYPE , unsigned SIZE>
Matrix< DATA_TYPE, SIZE, SIZE > & invertFull_orig (Matrix< DATA_TYPE, SIZE, SIZE > &result, const Matrix< DATA_TYPE, SIZE, SIZE > &src)
 full matrix inversion.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & invertFull (Matrix< DATA_TYPE, ROWS, COLS > &result, const Matrix< DATA_TYPE, ROWS, COLS > &src)
 Invert method.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & invert (Matrix< DATA_TYPE, ROWS, COLS > &result, const Matrix< DATA_TYPE, ROWS, COLS > &src)
 smart matrix inversion.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix< DATA_TYPE, ROWS, COLS > & invert (Matrix< DATA_TYPE, ROWS, COLS > &result)
 smart matrix inversion (in place) Does matrix inversion by intelligently selecting what type of inversion to use depending on the types of operations your Matrix has been through.
Matrix Comparitors

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
bool operator== (const Matrix< DATA_TYPE, ROWS, COLS > &lhs, const Matrix< DATA_TYPE, ROWS, COLS > &rhs)
 Tests 2 matrices for equality.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
bool operator!= (const Matrix< DATA_TYPE, ROWS, COLS > &lhs, const Matrix< DATA_TYPE, ROWS, COLS > &rhs)
 Tests 2 matrices for inequality.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
bool isEqual (const Matrix< DATA_TYPE, ROWS, COLS > &lhs, const Matrix< DATA_TYPE, ROWS, COLS > &rhs, const DATA_TYPE eps=0)
 Tests 2 matrices for equality within a tolerance.
Output Stream Operators

template<typename DATA_TYPE , unsigned SIZE, typename REP >
std::ostream & operator<< (std::ostream &out, const VecBase< DATA_TYPE, SIZE, REP > &v)
 Outputs a string representation of the given VecBase type to the given output stream.
template<class DATA_TYPE , typename ROTATION_ORDER >
std::ostream & operator<< (std::ostream &out, const EulerAngle< DATA_TYPE, ROTATION_ORDER > &e)
 Outputs a string representation of the given EulerAngle type to the given output stream.
template<class DATA_TYPE , unsigned ROWS, unsigned COLS>
std::ostream & operator<< (std::ostream &out, const Matrix< DATA_TYPE, ROWS, COLS > &m)
 Outputs a string representation of the given Matrix to the given output stream.
template<typename DATA_TYPE >
std::ostream & operator<< (std::ostream &out, const Quat< DATA_TYPE > &q)
 Outputs a string representation of the given Matrix to the given output stream.
template<typename DATA_TYPE >
std::ostream & operator<< (std::ostream &out, const Tri< DATA_TYPE > &t)
 Outputs a string representation of the given Tri to the given output stream.
template<typename DATA_TYPE >
std::ostream & operator<< (std::ostream &out, const Plane< DATA_TYPE > &p)
 Outputs a string representation of the given Plane to the given output stream.
template<typename DATA_TYPE >
std::ostream & operator<< (std::ostream &out, const Sphere< DATA_TYPE > &s)
 Outputs a string representation of the given Sphere to the given output stream.
template<typename DATA_TYPE >
std::ostream & operator<< (std::ostream &out, const AABox< DATA_TYPE > &b)
 Outputs a string representation of the given AABox to the given output stream.
template<typename DATA_TYPE >
std::ostream & operator<< (std::ostream &out, const Ray< DATA_TYPE > &b)
 Outputs a string representation of the given Ray to the given output stream.
template<typename DATA_TYPE >
std::ostream & operator<< (std::ostream &out, const LineSeg< DATA_TYPE > &b)
 Outputs a string representation of the given LineSeg to the given output stream.
template<typename POS_TYPE , typename ROT_TYPE >
std::ostream & operator<< (std::ostream &out, const Coord< POS_TYPE, ROT_TYPE > &c)
Plane Operations

template<class DATA_TYPE >
DATA_TYPE distance (const Plane< DATA_TYPE > &plane, const Point< DATA_TYPE, 3 > &pt)
 Computes the distance from the plane to the point.
template<class DATA_TYPE >
PlaneSide whichSide (const Plane< DATA_TYPE > &plane, const Point< DATA_TYPE, 3 > &pt)
 Determines which side of the plane the given point lies.
template<class DATA_TYPE >
PlaneSide whichSide (const Plane< DATA_TYPE > &plane, const Point< DATA_TYPE, 3 > &pt, const DATA_TYPE &eps)
 Determines which side of the plane the given point lies with the given epsilon tolerance.
template<class DATA_TYPE >
DATA_TYPE findNearestPt (const Plane< DATA_TYPE > &plane, const Point< DATA_TYPE, 3 > &pt, Point< DATA_TYPE, 3 > &result)
 Finds the point on the plane that is nearest to the given point.
template<class DATA_TYPE , unsigned SIZE>
void reflect (Point< DATA_TYPE, SIZE > &result, const Plane< DATA_TYPE > &plane, const Point< DATA_TYPE, SIZE > &point)
 Mirror the point by the plane.
Plane Comparitors

template<class DATA_TYPE >
bool operator== (const Plane< DATA_TYPE > &p1, const Plane< DATA_TYPE > &p2)
 Compare two planes to see if they are EXACTLY the same.
template<class DATA_TYPE >
bool operator!= (const Plane< DATA_TYPE > &p1, const Plane< DATA_TYPE > &p2)
 Compare two planes to see if they are not EXACTLY the same.
template<class DATA_TYPE >
bool isEqual (const Plane< DATA_TYPE > &p1, const Plane< DATA_TYPE > &p2, const DATA_TYPE &eps)
 Compare two planes to see if they are the same within the given tolerance.
Quat Operations

template<typename DATA_TYPE >
Quat< DATA_TYPE > & mult (Quat< DATA_TYPE > &result, const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 product of two quaternions (quaternion product) multiplication of quats is much like multiplication of typical complex numbers.
template<typename DATA_TYPE >
Quat< DATA_TYPE > operator* (const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 product of two quaternions (quaternion product) Does quaternion multiplication.
template<typename DATA_TYPE >
Quat< DATA_TYPE > & operator*= (Quat< DATA_TYPE > &result, const Quat< DATA_TYPE > &q2)
 quaternion postmult
template<typename DATA_TYPE >
Quat< DATA_TYPE > & negate (Quat< DATA_TYPE > &result)
 Vector negation - negate each element in the quaternion vector.
template<typename DATA_TYPE >
Quat< DATA_TYPE > operator- (const Quat< DATA_TYPE > &quat)
 Vector negation - (operator-) return a temporary that is the negative of the given quat.
template<typename DATA_TYPE >
Quat< DATA_TYPE > & mult (Quat< DATA_TYPE > &result, const Quat< DATA_TYPE > &q, DATA_TYPE s)
 vector scalar multiplication
template<typename DATA_TYPE >
Quat< DATA_TYPE > operator* (const Quat< DATA_TYPE > &q, DATA_TYPE s)
 vector scalar multiplication
template<typename DATA_TYPE >
Quat< DATA_TYPE > & operator*= (Quat< DATA_TYPE > &q, DATA_TYPE s)
 vector scalar multiplication
template<typename DATA_TYPE >
Quat< DATA_TYPE > & div (Quat< DATA_TYPE > &result, const Quat< DATA_TYPE > &q1, Quat< DATA_TYPE > q2)
 quotient of two quaternions
template<typename DATA_TYPE >
Quat< DATA_TYPE > operator/ (const Quat< DATA_TYPE > &q1, Quat< DATA_TYPE > q2)
 quotient of two quaternions
template<typename DATA_TYPE >
Quat< DATA_TYPE > & operator/= (Quat< DATA_TYPE > &result, const Quat< DATA_TYPE > &q2)
 quotient of two quaternions
template<typename DATA_TYPE >
Quat< DATA_TYPE > & div (Quat< DATA_TYPE > &result, const Quat< DATA_TYPE > &q, DATA_TYPE s)
 quaternion vector scale
template<typename DATA_TYPE >
Quat< DATA_TYPE > operator/ (const Quat< DATA_TYPE > &q, DATA_TYPE s)
 vector scalar division
template<typename DATA_TYPE >
Quat< DATA_TYPE > & operator/= (const Quat< DATA_TYPE > &q, DATA_TYPE s)
 vector scalar division
template<typename DATA_TYPE >
Quat< DATA_TYPE > & add (Quat< DATA_TYPE > &result, const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 vector addition
template<typename DATA_TYPE >
Quat< DATA_TYPE > operator+ (const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 vector addition
template<typename DATA_TYPE >
Quat< DATA_TYPE > & operator+= (Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 vector addition
template<typename DATA_TYPE >
Quat< DATA_TYPE > & sub (Quat< DATA_TYPE > &result, const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 vector subtraction
template<typename DATA_TYPE >
Quat< DATA_TYPE > operator- (const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 vector subtraction
template<typename DATA_TYPE >
Quat< DATA_TYPE > & operator-= (Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 vector subtraction
template<typename DATA_TYPE >
DATA_TYPE dot (const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 vector dot product between two quaternions.
template<typename DATA_TYPE >
DATA_TYPE lengthSquared (const Quat< DATA_TYPE > &q)
 quaternion "norm" (also known as vector length squared) using this can be faster than using length for some operations...
template<typename DATA_TYPE >
DATA_TYPE length (const Quat< DATA_TYPE > &q)
 quaternion "absolute" (also known as vector length or magnitude) using this can be faster than using length for some operations...
template<typename DATA_TYPE >
Quat< DATA_TYPE > & normalize (Quat< DATA_TYPE > &result)
 set self to the normalized quaternion of self.
template<typename DATA_TYPE >
bool isNormalized (const Quat< DATA_TYPE > &q1, const DATA_TYPE eps=0.0001f)
 Determines if the given quaternion is normalized within the given tolerance.
template<typename DATA_TYPE >
Quat< DATA_TYPE > & conj (Quat< DATA_TYPE > &result)
 quaternion complex conjugate.
template<typename DATA_TYPE >
Quat< DATA_TYPE > & invert (Quat< DATA_TYPE > &result)
 quaternion multiplicative inverse.
template<typename DATA_TYPE >
Quat< DATA_TYPE > & exp (Quat< DATA_TYPE > &result)
 complex exponentiation.
template<typename DATA_TYPE >
Quat< DATA_TYPE > & log (Quat< DATA_TYPE > &result)
 complex logarithm
template<typename DATA_TYPE >
void squad (Quat< DATA_TYPE > &result, DATA_TYPE t, const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2, const Quat< DATA_TYPE > &a, const Quat< DATA_TYPE > &b)
 WARNING: not implemented (do not use).
template<typename DATA_TYPE >
void meanTangent (Quat< DATA_TYPE > &result, const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2, const Quat< DATA_TYPE > &q3)
 WARNING: not implemented (do not use).
Quaternion Interpolation

template<typename DATA_TYPE >
Quat< DATA_TYPE > & slerp (Quat< DATA_TYPE > &result, const DATA_TYPE t, const Quat< DATA_TYPE > &from, const Quat< DATA_TYPE > &to, bool adjustSign=true)
 spherical linear interpolation between two rotation quaternions.
template<typename DATA_TYPE >
Quat< DATA_TYPE > & lerp (Quat< DATA_TYPE > &result, const DATA_TYPE t, const Quat< DATA_TYPE > &from, const Quat< DATA_TYPE > &to)
 linear interpolation between two quaternions.
Quat Comparisons

template<typename DATA_TYPE >
bool operator== (const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 Compare two quaternions for equality.
template<typename DATA_TYPE >
bool operator!= (const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2)
 Compare two quaternions for not-equality.
template<typename DATA_TYPE >
bool isEqual (const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2, DATA_TYPE tol=0.0)
 Compare two quaternions for equality with tolerance.
template<typename DATA_TYPE >
bool isEquiv (const Quat< DATA_TYPE > &q1, const Quat< DATA_TYPE > &q2, DATA_TYPE tol=0.0)
 Compare two quaternions for geometric equivelence (with tolerance).
Sphere Comparitors

template<class DATA_TYPE >
bool operator== (const Sphere< DATA_TYPE > &s1, const Sphere< DATA_TYPE > &s2)
 Compare two spheres to see if they are EXACTLY the same.
template<class DATA_TYPE >
bool operator!= (const Sphere< DATA_TYPE > &s1, const Sphere< DATA_TYPE > &s2)
 Compare two spheres to see if they are not EXACTLY the same.
template<class DATA_TYPE >
bool isEqual (const Sphere< DATA_TYPE > &s1, const Sphere< DATA_TYPE > &s2, const DATA_TYPE &eps)
 Compare two spheres to see if they are the same within the given tolerance.
Triangle Operations

template<class DATA_TYPE >
Point< DATA_TYPE, 3 > center (const Tri< DATA_TYPE > &tri)
 Computes the point at the center of the given triangle.
template<class DATA_TYPE >
Vec< DATA_TYPE, 3 > normal (const Tri< DATA_TYPE > &tri)
 Computes the normal for this triangle.
Triangle Comparitors

template<class DATA_TYPE >
bool operator== (const Tri< DATA_TYPE > &tri1, const Tri< DATA_TYPE > &tri2)
 Compare two triangles to see if they are EXACTLY the same.
template<class DATA_TYPE >
bool operator!= (const Tri< DATA_TYPE > &tri1, const Tri< DATA_TYPE > &tri2)
 Compare two triangle to see if they are not EXACTLY the same.
template<class DATA_TYPE >
bool isEqual (const Tri< DATA_TYPE > &tri1, const Tri< DATA_TYPE > &tri2, const DATA_TYPE &eps)
 Compare two triangles to see if they are the same within the given tolerance.

template<class T >
void ignore_unused_variable_warning (const T &)
Vector/Point Operations

template<typename T , unsigned SIZE, typename R1 >
VecBase< T, SIZE,
meta::VecUnaryExpr< VecBase< T,
SIZE, R1 >, meta::VecNegUnary > > 
operator- (const VecBase< T, SIZE, R1 > &v1)
 Negates v1.
template<class DATA_TYPE , unsigned SIZE, typename REP2 >
VecBase< DATA_TYPE, SIZE > & operator+= (VecBase< DATA_TYPE, SIZE > &v1, const VecBase< DATA_TYPE, SIZE, REP2 > &v2)
 Adds v2 to v1 and stores the result in v1.
template<typename T , unsigned SIZE, typename R1 , typename R2 >
VecBase< T, SIZE,
meta::VecBinaryExpr< VecBase
< T, SIZE, R1 >, VecBase< T,
SIZE, R2 >
, meta::VecPlusBinary > > 
operator+ (const VecBase< T, SIZE, R1 > &v1, const VecBase< T, SIZE, R2 > &v2)
 Adds v2 to v1 and returns the result.
template<class DATA_TYPE , unsigned SIZE, typename REP2 >
VecBase< DATA_TYPE, SIZE > & operator-= (VecBase< DATA_TYPE, SIZE > &v1, const VecBase< DATA_TYPE, SIZE, REP2 > &v2)
 Subtracts v2 from v1 and stores the result in v1.
template<typename T , unsigned SIZE, typename R1 , typename R2 >
VecBase< T, SIZE,
meta::VecBinaryExpr< VecBase
< T, SIZE, R1 >, VecBase< T,
SIZE, R2 >
, meta::VecMinusBinary > > 
operator- (const VecBase< T, SIZE, R1 > &v1, const VecBase< T, SIZE, R2 > &v2)
 Subtracts v2 from v1 and returns the result.
template<class DATA_TYPE , unsigned SIZE, class SCALAR_TYPE >
VecBase< DATA_TYPE, SIZE > & operator*= (VecBase< DATA_TYPE, SIZE > &v1, const SCALAR_TYPE &scalar)
 Multiplies v1 by a scalar value and stores the result in v1.
template<typename T , unsigned SIZE, typename R1 >
VecBase< T, SIZE,
meta::VecBinaryExpr< VecBase
< T, SIZE, R1 >, VecBase< T,
SIZE, meta::ScalarArg< T >
>, meta::VecMultBinary > > 
operator* (const VecBase< T, SIZE, R1 > &v1, const T scalar)
 Multiplies v1 by a scalar value and returns the result.
template<typename T , unsigned SIZE, typename R1 >
VecBase< T, SIZE,
meta::VecBinaryExpr< VecBase
< T, SIZE, meta::ScalarArg< T >
>, VecBase< T, SIZE, R1 >
, meta::VecMultBinary > > 
operator* (const T scalar, const VecBase< T, SIZE, R1 > &v1)
template<class DATA_TYPE , unsigned SIZE, class SCALAR_TYPE >
VecBase< DATA_TYPE, SIZE > & operator/= (VecBase< DATA_TYPE, SIZE > &v1, const SCALAR_TYPE &scalar)
 Multiplies v1 by a scalar value and returns the result.
template<typename T , unsigned SIZE, typename R1 >
VecBase< T, SIZE,
meta::VecBinaryExpr< VecBase
< T, SIZE, R1 >, VecBase< T,
SIZE, meta::ScalarArg< T >
>, meta::VecDivBinary > > 
operator/ (const VecBase< T, SIZE, R1 > &v1, const T scalar)
 Divides v1 by a scalar value and returns the result.
Vector Operations

template<class DATA_TYPE , unsigned SIZE, typename REP1 , typename REP2 >
DATA_TYPE dot (const VecBase< DATA_TYPE, SIZE, REP1 > &v1, const VecBase< DATA_TYPE, SIZE, REP2 > &v2)
 Computes dot product of v1 and v2 and returns the result.
template<class DATA_TYPE , unsigned SIZE>
DATA_TYPE length (const Vec< DATA_TYPE, SIZE > &v1)
 Computes the length of the given vector.
template<class DATA_TYPE , unsigned SIZE>
DATA_TYPE lengthSquared (const Vec< DATA_TYPE, SIZE > &v1)
 Computes the square of the length of the given vector.
template<class DATA_TYPE , unsigned SIZE>
DATA_TYPE normalize (Vec< DATA_TYPE, SIZE > &v1)
 Normalizes the given vector in place causing it to be of unit length.
template<class DATA_TYPE , unsigned SIZE>
bool isNormalized (const Vec< DATA_TYPE, SIZE > &v1, const DATA_TYPE eps=(DATA_TYPE) 0.0001f)
 Determines if the given vector is normalized within the given tolerance.
template<class DATA_TYPE >
Vec< DATA_TYPE, 3 > & cross (Vec< DATA_TYPE, 3 > &result, const Vec< DATA_TYPE, 3 > &v1, const Vec< DATA_TYPE, 3 > &v2)
 Computes the cross product between v1 and v2 and stores the result in result.
template<class DATA_TYPE , unsigned SIZE>
VecBase< DATA_TYPE, SIZE > & reflect (VecBase< DATA_TYPE, SIZE > &result, const VecBase< DATA_TYPE, SIZE > &vec, const Vec< DATA_TYPE, SIZE > &normal)
 Reflect a vector about a normal.
Vector Interpolation

template<typename DATA_TYPE , unsigned SIZE>
VecBase< DATA_TYPE, SIZE > & lerp (VecBase< DATA_TYPE, SIZE > &result, const DATA_TYPE &lerpVal, const VecBase< DATA_TYPE, SIZE > &from, const VecBase< DATA_TYPE, SIZE > &to)
 Linearly interpolates between to vectors.
Vector Comparitors

template<class DATA_TYPE , unsigned SIZE>
bool operator== (const VecBase< DATA_TYPE, SIZE > &v1, const VecBase< DATA_TYPE, SIZE > &v2)
 Compares v1 and v2 to see if they are exactly the same.
template<class DATA_TYPE , unsigned SIZE>
bool operator!= (const VecBase< DATA_TYPE, SIZE > &v1, const VecBase< DATA_TYPE, SIZE > &v2)
 Compares v1 and v2 to see if they are NOT exactly the same with zero tolerance.
template<class DATA_TYPE , unsigned SIZE>
bool isEqual (const VecBase< DATA_TYPE, SIZE > &v1, const VecBase< DATA_TYPE, SIZE > &v2, const DATA_TYPE eps)
 Compares v1 and v2 to see if they are the same within the given epsilon tolerance.
Vector Transform (Quaternion)

template<typename DATA_TYPE >
VecBase< DATA_TYPE, 3 > & xform (VecBase< DATA_TYPE, 3 > &result, const Quat< DATA_TYPE > &rot, const VecBase< DATA_TYPE, 3 > &vector)
 transform a vector by a rotation quaternion.
template<typename DATA_TYPE >
VecBase< DATA_TYPE, 3 > operator* (const Quat< DATA_TYPE > &rot, const VecBase< DATA_TYPE, 3 > &vector)
 transform a vector by a rotation quaternion.
template<typename DATA_TYPE >
VecBase< DATA_TYPE, 3 > operator*= (VecBase< DATA_TYPE, 3 > &vector, const Quat< DATA_TYPE > &rot)
 transform a vector by a rotation quaternion.
Vector Transform (Matrix)

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Vec< DATA_TYPE, COLS > & xform (Vec< DATA_TYPE, COLS > &result, const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const Vec< DATA_TYPE, COLS > &vector)
 xform a vector by a matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Vec< DATA_TYPE, COLS > operator* (const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const Vec< DATA_TYPE, COLS > &vector)
 matrix * vector xform.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned VEC_SIZE>
Vec< DATA_TYPE, VEC_SIZE > & xform (Vec< DATA_TYPE, VEC_SIZE > &result, const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const Vec< DATA_TYPE, VEC_SIZE > &vector)
 partially transform a partially specified vector by a matrix, assumes last elt of vector is 0 (the 0 makes it only partially transformed).
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
Vec< DATA_TYPE, COLS_MINUS_ONE > operator* (const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const Vec< DATA_TYPE, COLS_MINUS_ONE > &vector)
 matrix * partial vector, assumes last elt of vector is 0 (partial transform).
Point Transform (Matrix)

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Point< DATA_TYPE, COLS > & xform (Point< DATA_TYPE, COLS > &result, const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const Point< DATA_TYPE, COLS > &point)
 transform point by a matrix.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Point< DATA_TYPE, COLS > operator* (const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const Point< DATA_TYPE, COLS > &point)
 matrix * point.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned PNT_SIZE>
Point< DATA_TYPE, PNT_SIZE > & xform (Point< DATA_TYPE, PNT_SIZE > &result, const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const Point< DATA_TYPE, PNT_SIZE > &point)
 transform a partially specified point by a matrix, assumes last elt of point is 1.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
Point< DATA_TYPE, COLS_MINUS_ONE > operator* (const Matrix< DATA_TYPE, ROWS, COLS > &matrix, const Point< DATA_TYPE, COLS_MINUS_ONE > &point)
 matrix * partially specified point.
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Point< DATA_TYPE, COLS > operator* (const Point< DATA_TYPE, COLS > &point, const Matrix< DATA_TYPE, ROWS, COLS > &matrix)
 point * a matrix multiplication of [m x k] matrix by a [k x 1] matrix (also known as a Point [with w == 1 for points by definition] ).
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Point< DATA_TYPE, COLS > operator*= (Point< DATA_TYPE, COLS > &point, const Matrix< DATA_TYPE, ROWS, COLS > &matrix)
 point *= a matrix multiplication of [m x k] matrix by a [k x 1] matrix (also known as a Point [with w == 1 for points by definition] ).
template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
Point< DATA_TYPE,
COLS_MINUS_ONE > & 
operator*= (Point< DATA_TYPE, COLS_MINUS_ONE > &point, const Matrix< DATA_TYPE, ROWS, COLS > &matrix)
 partial point *= a matrix multiplication of [m x k] matrix by a [k-1 x 1] matrix (also known as a Point [with w == 1 for points by definition] ).

Variables

const unsigned int IN_FRONT_OF_ALL_PLANES = 6
const Matrix22f MAT_IDENTITY22F = Matrix22f()
 32bit floating point 2x2 identity matrix
const Matrix22d MAT_IDENTITY22D = Matrix22d()
 64bit floating point 2x2 identity matrix
const Matrix23f MAT_IDENTITY23F = Matrix23f()
 32bit floating point 2x2 identity matrix
const Matrix23d MAT_IDENTITY23D = Matrix23d()
 64bit floating point 2x2 identity matrix
const Matrix33f MAT_IDENTITY33F = Matrix33f()
 32bit floating point 3x3 identity matrix
const Matrix33d MAT_IDENTITY33D = Matrix33d()
 64bit floating point 3x3 identity matrix
const Matrix34f MAT_IDENTITY34F = Matrix34f()
 32bit floating point 3x4 identity matrix
const Matrix34d MAT_IDENTITY34D = Matrix34d()
 64bit floating point 3x4 identity matrix
const Matrix44f MAT_IDENTITY44F = Matrix44f()
 32bit floating point 4x4 identity matrix
const Matrix44d MAT_IDENTITY44D = Matrix44d()
 64bit floating point 4x4 identity matrix
Constants

const float GMTL_EPSILON = 1.0e-6f
const float GMTL_MAT_EQUAL_EPSILON = 0.001f
const float GMTL_VEC_EQUAL_EPSILON = 0.0001f

Detailed Description

Meta programming classes.

Meta programming classes for vec operations.

Expression template classes for vec operations.

Static assertion macros Borrowed from boost and Loki.


Typedef Documentation

typedef AABox<double> gmtl::AABoxd

Definition at line 144 of file AABox.h.

typedef AABox<float> gmtl::AABoxf

Definition at line 143 of file AABox.h.

typedef AxisAngle<double> gmtl::AxisAngled

Definition at line 121 of file AxisAngle.h.

typedef AxisAngle<float> gmtl::AxisAnglef

Definition at line 120 of file AxisAngle.h.

Definition at line 189 of file Coord.h.

Definition at line 180 of file Coord.h.

Definition at line 166 of file Coord.h.

Definition at line 168 of file Coord.h.

Definition at line 167 of file Coord.h.

3 elt types

Definition at line 188 of file Coord.h.

3 elt types

Definition at line 179 of file Coord.h.

3 elt types

Definition at line 163 of file Coord.h.

Definition at line 165 of file Coord.h.

Definition at line 164 of file Coord.h.

Definition at line 193 of file Coord.h.

Definition at line 184 of file Coord.h.

Definition at line 174 of file Coord.h.

Definition at line 176 of file Coord.h.

Definition at line 175 of file Coord.h.

4 elt types

Definition at line 192 of file Coord.h.

4 elt types

Definition at line 183 of file Coord.h.

4 elt types

Definition at line 171 of file Coord.h.

Definition at line 173 of file Coord.h.

Definition at line 172 of file Coord.h.

Definition at line 155 of file Coord.h.

Definition at line 156 of file Coord.h.

Definition at line 140 of file Coord.h.

Definition at line 141 of file Coord.h.

Definition at line 150 of file Coord.h.

Definition at line 151 of file Coord.h.

Definition at line 145 of file Coord.h.

Definition at line 146 of file Coord.h.

Definition at line 157 of file Coord.h.

Definition at line 158 of file Coord.h.

Definition at line 142 of file Coord.h.

Definition at line 143 of file Coord.h.

Definition at line 152 of file Coord.h.

Definition at line 153 of file Coord.h.

Definition at line 147 of file Coord.h.

Definition at line 148 of file Coord.h.

typedef CubicCurve<double, 1> gmtl::CubicCurve1d

Definition at line 402 of file ParametricCurve.h.

typedef CubicCurve<float, 1> gmtl::CubicCurve1f

Definition at line 399 of file ParametricCurve.h.

typedef CubicCurve<double, 2> gmtl::CubicCurve2d

Definition at line 403 of file ParametricCurve.h.

typedef CubicCurve<float, 2> gmtl::CubicCurve2f

Definition at line 400 of file ParametricCurve.h.

typedef CubicCurve<double, 3> gmtl::CubicCurve3d

Definition at line 404 of file ParametricCurve.h.

typedef CubicCurve<float, 3> gmtl::CubicCurve3f

Definition at line 401 of file ParametricCurve.h.

Definition at line 123 of file EulerAngle.h.

Definition at line 122 of file EulerAngle.h.

Definition at line 127 of file EulerAngle.h.

Definition at line 126 of file EulerAngle.h.

Definition at line 125 of file EulerAngle.h.

Definition at line 124 of file EulerAngle.h.

typedef Frustum<double> gmtl::Frustumd

Definition at line 150 of file Frustum.h.

typedef Frustum<float> gmtl::Frustumf

Definition at line 149 of file Frustum.h.

typedef LinearCurve<double, 1> gmtl::LinearCurve1d

Definition at line 390 of file ParametricCurve.h.

typedef LinearCurve<float, 1> gmtl::LinearCurve1f

Definition at line 387 of file ParametricCurve.h.

typedef LinearCurve<double, 2> gmtl::LinearCurve2d

Definition at line 391 of file ParametricCurve.h.

typedef LinearCurve<float, 2> gmtl::LinearCurve2f

Definition at line 388 of file ParametricCurve.h.

typedef LinearCurve<double, 3> gmtl::LinearCurve3d

Definition at line 392 of file ParametricCurve.h.

typedef LinearCurve<float, 3> gmtl::LinearCurve3f

Definition at line 389 of file ParametricCurve.h.

typedef LineSeg<double> gmtl::LineSegd

Definition at line 83 of file LineSeg.h.

typedef LineSeg<float> gmtl::LineSegf

Definition at line 82 of file LineSeg.h.

typedef Matrix<double, 2, 2> gmtl::Matrix22d

Definition at line 492 of file Matrix.h.

typedef Matrix<float, 2, 2> gmtl::Matrix22f

Definition at line 491 of file Matrix.h.

typedef Matrix<double, 2, 3> gmtl::Matrix23d

Definition at line 494 of file Matrix.h.

typedef Matrix<float, 2, 3> gmtl::Matrix23f

Definition at line 493 of file Matrix.h.

typedef Matrix<double, 3, 3> gmtl::Matrix33d

Definition at line 496 of file Matrix.h.

typedef Matrix<float, 3, 3> gmtl::Matrix33f

Definition at line 495 of file Matrix.h.

typedef Matrix<double, 3, 4> gmtl::Matrix34d

Definition at line 498 of file Matrix.h.

typedef Matrix<float, 3, 4> gmtl::Matrix34f

Definition at line 497 of file Matrix.h.

typedef Matrix<double, 4, 4> gmtl::Matrix44d

Definition at line 500 of file Matrix.h.

typedef Matrix<float, 4, 4> gmtl::Matrix44f

Definition at line 499 of file Matrix.h.

typedef Plane<double> gmtl::Planed

Definition at line 157 of file Plane.h.

typedef Plane<float> gmtl::Planef

Definition at line 156 of file Plane.h.

typedef Point<double,2> gmtl::Point2d

Definition at line 123 of file Point.h.

typedef Point<float,2> gmtl::Point2f

Definition at line 122 of file Point.h.

typedef Point<int,2> gmtl::Point2i

Definition at line 121 of file Point.h.

typedef Point<double,3> gmtl::Point3d

Definition at line 126 of file Point.h.

typedef Point<float,3> gmtl::Point3f

Definition at line 125 of file Point.h.

typedef Point<int, 3> gmtl::Point3i

Definition at line 124 of file Point.h.

typedef Point<double,4> gmtl::Point4d

Definition at line 129 of file Point.h.

typedef Point<float,4> gmtl::Point4f

Definition at line 128 of file Point.h.

typedef Point<int, 4> gmtl::Point4i

Definition at line 127 of file Point.h.

Definition at line 396 of file ParametricCurve.h.

Definition at line 393 of file ParametricCurve.h.

Definition at line 397 of file ParametricCurve.h.

Definition at line 394 of file ParametricCurve.h.

Definition at line 398 of file ParametricCurve.h.

Definition at line 395 of file ParametricCurve.h.

typedef Quat<double> gmtl::Quatd

Definition at line 156 of file Quat.h.

typedef Quat<float> gmtl::Quatf

Definition at line 155 of file Quat.h.

typedef Ray<double> gmtl::Rayd

Definition at line 114 of file Ray.h.

typedef Ray<float> gmtl::Rayf

Definition at line 113 of file Ray.h.

typedef Sphere<double> gmtl::Sphered

Definition at line 107 of file Sphere.h.

typedef Sphere<float> gmtl::Spheref

Definition at line 106 of file Sphere.h.

typedef Tri<double> gmtl::Trid

Definition at line 142 of file Tri.h.

typedef Tri<float> gmtl::Trif

Definition at line 141 of file Tri.h.

typedef Tri<int> gmtl::Trii

Definition at line 143 of file Tri.h.

typedef Vec<double,2> gmtl::Vec2d

Definition at line 125 of file Vec.h.

typedef Vec<float,2> gmtl::Vec2f

Definition at line 124 of file Vec.h.

typedef Vec<int, 2> gmtl::Vec2i

Definition at line 123 of file Vec.h.

typedef Vec<double,3> gmtl::Vec3d

Definition at line 128 of file Vec.h.

typedef Vec<float,3> gmtl::Vec3f

Definition at line 127 of file Vec.h.

typedef Vec<int, 3> gmtl::Vec3i

Definition at line 126 of file Vec.h.

typedef Vec<double,4> gmtl::Vec4d

Definition at line 131 of file Vec.h.

typedef Vec<float,4> gmtl::Vec4f

Definition at line 130 of file Vec.h.

typedef Vec<int, 4> gmtl::Vec4i

Definition at line 129 of file Vec.h.


Function Documentation

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::add ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  lhs,
const Matrix< DATA_TYPE, ROWS, COLS > &  rhs 
) [inline]

matrix addition (algebraic operation for matrix).

: if lhs is m x n, and rhs is m x n, then result is m x n (mult func undefined otherwise) : returns a m x n matrix TODO: enforce the sizes with templates...

Definition at line 141 of file MatrixOps.h.

   {
      // p. 150 Numerical Analysis (second ed.)
      // if A is m x n, and B is m x n, then AB is m x n
      // (A - B)ij  = (a)ij + (b)ij     (where:  1 <= i <= m, 1 <= j <= n)
      for (unsigned int i = 0; i < ROWS; ++i)           // 1 <= i <= m
      for (unsigned int j = 0; j < COLS; ++j)           // 1 <= j <= n
         result( i, j ) = lhs( i, j ) + rhs( i, j );

      // track state
      result.mState = combineMatrixStates( lhs.mState, rhs.mState );
      return result;
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::add ( Quat< DATA_TYPE > &  result,
const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
)

vector addition

See also:
Quat

Definition at line 227 of file QuatOps.h.

   {
      result[0] = q1[0] + q2[0];
      result[1] = q1[1] + q2[1];
      result[2] = q1[2] + q2[2];
      result[3] = q1[3] + q2[3];
      return result;
   }

const AxisAngle<double> gmtl::AXISANGLE_IDENTITYD ( 0.  0,
1.  0,
0.  0,
0.  0 
)
const AxisAngle<float> gmtl::AXISANGLE_IDENTITYF ( 0.  0f,
1.  0f,
0.  0f,
0.  0f 
)
template<class DATA_TYPE >
Point<DATA_TYPE, 3> gmtl::center ( const Tri< DATA_TYPE > &  tri  ) 

Computes the point at the center of the given triangle.

Parameters:
tri the triangle to find the center of
Returns:
the point at the center of the triangle

Definition at line 28 of file TriOps.h.

{
   const float one_third = (1.0f/3.0f);
   return (tri[0] + tri[1] + tri[2]) * DATA_TYPE(one_third);
}

int gmtl::combineMatrixStates ( int  state1,
int  state2 
) [inline]

utility function for use by matrix operations.

given two matrices, when combined with set(..) or xform(..) types of operations, compute what matrixstate will the resulting matrix have?

Definition at line 536 of file Matrix.h.

{
   switch (state1)
   {
   case Matrix44f::IDENTITY:
      switch (state2)
      {
      case Matrix44f::XFORM_ERROR: return state2;
      case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
      default: return state2;
      }
   case Matrix44f::TRANS:
      switch (state2)
      {
      case Matrix44f::IDENTITY: return state1;
      case Matrix44f::ORTHOGONAL: return Matrix44f::AFFINE;
      case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
      default: return state2;
      }
   case Matrix44f::ORTHOGONAL:
      switch (state2)
      {
      case Matrix44f::IDENTITY: return state1;
      case Matrix44f::TRANS: return Matrix44f::AFFINE;
      case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
      default: return state2;
      }
   case Matrix44f::AFFINE:
      switch (state2)
      {
      case Matrix44f::IDENTITY:
      case Matrix44f::TRANS:
      case Matrix44f::ORTHOGONAL:  return state1;
      case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
      case Matrix44f::AFFINE | Matrix44f::NON_UNISCALE:
      default: return state2;
      }
   case Matrix44f::AFFINE | Matrix44f::NON_UNISCALE:
      switch (state2)
      {
      case Matrix44f::IDENTITY:
      case Matrix44f::TRANS:
      case Matrix44f::ORTHOGONAL:
      case Matrix44f::AFFINE:  return state1;
      case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
      default: return state2;
      }
   case Matrix44f::FULL:
      switch (state2)
      {
      case Matrix44f::XFORM_ERROR: return state2;
      case Matrix44f::NON_UNISCALE: return Matrix44f::XFORM_ERROR;
      default: return state1;
      }
      break;
   default:
      return Matrix44f::XFORM_ERROR;
   }
}

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::conj ( Quat< DATA_TYPE > &  result  ) 

quaternion complex conjugate.

Postcondition:
set result to the complex conjugate of result.
q* = [s,-v]
result'[x,y,z,w] == result[-x,-y,-z,w]
See also:
Quat

Definition at line 376 of file QuatOps.h.

   {
      result[Xelt] = -result[Xelt];
      result[Yelt] = -result[Yelt];
      result[Zelt] = -result[Zelt];
      return result;
   }

template<typename DATA_TYPE_OUT , typename DATA_TYPE_IN , unsigned ROWS, unsigned COLS>
gmtl::Matrix<DATA_TYPE_OUT, ROWS, COLS> gmtl::convertTo ( const gmtl::Matrix< DATA_TYPE_IN, ROWS, COLS > &  in  )  [inline]

Converts a matrix of one data type to another, such as gmtl::Matrix44f to gmtl::Matrix44d.

Internally, this uses loop unrolling to optimize performance.

 const gmtl::Matrix44f m_float = getMatrix();
 gmtl::Matrix44d m_double = gmtl::convertTo<double>(m_float);
Precondition:
The input matrix and output matrix must have matching dimensions.
Note:
The compiler will enforce the pre-condition about the matrix dimensions, but the error message may not always be clear. Use of a static assertion may help with that.
Since:
0.5.1

Definition at line 38 of file MatrixConvert.h.

{
   using namespace boost::lambda;

   gmtl::Matrix<DATA_TYPE_OUT, ROWS, COLS> out;

   // Accessing in.mData and out.mData in this way allows for use of
   // Boost.Lambda so that a separate helper function is not required to do
   // the assignment.
   const DATA_TYPE_IN* in_data(in.mData);
   DATA_TYPE_OUT* out_data(out.mData);

   // This relies on implicit casting between data types.
   boost::mpl::for_each< boost::mpl::range_c<unsigned int, 0, ROWS * COLS> >(
      *(out_data + boost::lambda::_1) = *(in_data + boost::lambda::_1)
   );

   return out;
}

template<class DATA_TYPE >
Vec<DATA_TYPE,3>& gmtl::cross ( Vec< DATA_TYPE, 3 > &  result,
const Vec< DATA_TYPE, 3 > &  v1,
const Vec< DATA_TYPE, 3 > &  v2 
)

Computes the cross product between v1 and v2 and stores the result in result.

The result is also returned by reference. Use this when you want to reuse an existing Vec to store the result. Note that this only applies to 3-dimensional vectors.

Precondition:
v1 and v2 are 3-D vectors
Postcondition:
result = v1 x v2
Parameters:
result filled with the result of the cross product between v1 and v2
v1 the first vector
v2 the second vector
Returns:
a reference to result for convenience

Definition at line 460 of file VecOps.h.

{
   result.set( (v1[Yelt]*v2[Zelt]) - (v1[Zelt]*v2[Yelt]),
               (v1[Zelt]*v2[Xelt]) - (v1[Xelt]*v2[Zelt]),
               (v1[Xelt]*v2[Yelt]) - (v1[Yelt]*v2[Xelt]) );
   return result;
}

template<class DATA_TYPE >
DATA_TYPE gmtl::distance ( const Plane< DATA_TYPE > &  plane,
const Point< DATA_TYPE, 3 > &  pt 
)

Computes the distance from the plane to the point.

Parameters:
plane the plane to compare the point to it
pt a point in space
Returns:
the distance from the point to the plane

Definition at line 30 of file PlaneOps.h.

{
   return ( dot(plane.mNorm, static_cast< Vec<DATA_TYPE, 3> >(pt)) - plane.mOffset );
}

template<class DATA_TYPE >
DATA_TYPE gmtl::distance ( const LineSeg< DATA_TYPE > &  lineseg,
const Point< DATA_TYPE, 3 > &  pt 
) [inline]

Computes the shortest distance from the line segment to the given point.

Parameters:
lineseg the line segment to test
pt the point which to test against lineseg
Returns:
the shortest distance from pt to lineseg

Definition at line 40 of file LineSegOps.h.

{
   return gmtl::length(gmtl::Vec<DATA_TYPE, 3>(pt - findNearestPt(lineseg, pt)));
}

template<class DATA_TYPE >
DATA_TYPE gmtl::distanceSquared ( const LineSeg< DATA_TYPE > &  lineseg,
const Point< DATA_TYPE, 3 > &  pt 
) [inline]

Computes the shortest distance from the line segment to the given point.

Parameters:
lineseg the line segment to test
pt the point which to test against lineseg
Returns:
the squared shortest distance from pt to lineseg (value is squared, this func is slightly faster since it doesn't involve a sqrt)

Definition at line 55 of file LineSegOps.h.

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::div ( Quat< DATA_TYPE > &  result,
const Quat< DATA_TYPE > &  q1,
Quat< DATA_TYPE >  q2 
)

quotient of two quaternions

Postcondition:
result = q1 * (1/q2) (where 1/q2 is applied first to any xform'd geometry)
See also:
Quat

Definition at line 162 of file QuatOps.h.

   {
      // multiply q1 by the multiplicative inverse of the quaternion
      return mult( result, q1, invert( q2 ) );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::div ( Quat< DATA_TYPE > &  result,
const Quat< DATA_TYPE > &  q,
DATA_TYPE  s 
)

quaternion vector scale

Postcondition:
result = q / s
See also:
Quat

Definition at line 193 of file QuatOps.h.

   {
      result[0] = q[0] / s;
      result[1] = q[1] / s;
      result[2] = q[2] / s;
      result[3] = q[3] / s;
      return result;
   }

template<typename DATA_TYPE >
DATA_TYPE gmtl::dot ( const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
)

vector dot product between two quaternions.

get the lengthSquared between two quat vectors...

Postcondition:
N(q) = x1*x2 + y1*y2 + z1*z2 + w1*w2
Returns:
dot product of q1 and q2
See also:
Quat

Definition at line 298 of file QuatOps.h.

   {
      return DATA_TYPE( (q1[0] * q2[0]) +
                        (q1[1] * q2[1]) +
                        (q1[2] * q2[2]) +
                        (q1[3] * q2[3])  );
   }

template<class DATA_TYPE , unsigned SIZE, typename REP1 , typename REP2 >
DATA_TYPE gmtl::dot ( const VecBase< DATA_TYPE, SIZE, REP1 > &  v1,
const VecBase< DATA_TYPE, SIZE, REP2 > &  v2 
)

Computes dot product of v1 and v2 and returns the result.

Parameters:
v1 the first vector
v2 the second vector
Returns:
the dotproduct of v1 and v2

Definition at line 351 of file VecOps.h.

{
   return gmtl::meta::DotVecUnrolled<SIZE-1,
                                     VecBase<DATA_TYPE,SIZE,REP1>,
                                     VecBase<DATA_TYPE,SIZE,REP2> >::func(v1,v2);
}

const EulerAngle<double, XYZ> gmtl::EULERANGLE_IDENTITY_XYZD ( 0.  0,
0.  0,
0.  0 
)
const EulerAngle<float, XYZ> gmtl::EULERANGLE_IDENTITY_XYZF ( 0.  0f,
0.  0f,
0.  0f 
)
const EulerAngle<double, ZXY> gmtl::EULERANGLE_IDENTITY_ZXYD ( 0.  0,
0.  0,
0.  0 
)
const EulerAngle<float, ZXY> gmtl::EULERANGLE_IDENTITY_ZXYF ( 0.  0f,
0.  0f,
0.  0f 
)
const EulerAngle<double, ZYX> gmtl::EULERANGLE_IDENTITY_ZYXD ( 0.  0,
0.  0,
0.  0 
)
const EulerAngle<float, ZYX> gmtl::EULERANGLE_IDENTITY_ZYXF ( 0.  0f,
0.  0f,
0.  0f 
)
template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::exp ( Quat< DATA_TYPE > &  result  ) 

complex exponentiation.

Precondition:
safe to pass self as argument
Postcondition:
sets self to the exponentiation of quat
See also:
Quat

Definition at line 415 of file QuatOps.h.

   {
      DATA_TYPE len1, len2;

      len1 = Math::sqrt( result[Xelt] * result[Xelt] +
                         result[Yelt] * result[Yelt] +
                         result[Zelt] * result[Zelt] );
      if (len1 > (DATA_TYPE)0.0)
         len2 = Math::sin( len1 ) / len1;
      else
         len2 = (DATA_TYPE)1.0;

      result[Xelt] = result[Xelt] * len2;
      result[Yelt] = result[Yelt] * len2;
      result[Zelt] = result[Zelt] * len2;
      result[Welt] = Math::cos( len1 );

      return result;
   }

template<class DATA_TYPE >
void gmtl::extendVolume ( AABox< DATA_TYPE > &  container,
const Point< DATA_TYPE, 3 > &  pt 
)

Modifies the existing AABox to tightly enclose itself and the given point.

Parameters:
container [in,out] the AABox that will be extended
pt [in] the point which the AABox should contain

Definition at line 393 of file Containment.h.

{
   if (! container.isEmpty())
   {
      // X coord
      if (pt[0] > container.mMax[0])
      {
         container.mMax[0] = pt[0];
      }
      else if (pt[0] < container.mMin[0])
      {
         container.mMin[0] = pt[0];
      }

      // Y coord
      if (pt[1] > container.mMax[1])
      {
         container.mMax[1] = pt[1];
      }
      else if (pt[1] < container.mMin[1])
      {
         container.mMin[1] = pt[1];
      }

      // Z coord
      if (pt[2] > container.mMax[2])
      {
         container.mMax[2] = pt[2];
      }
      else if (pt[2] < container.mMin[2])
      {
         container.mMin[2] = pt[2];
      }
   }
   else
   {
      // Make a box with essentially zero volume at the point
      container.setMin(pt);
      container.setMax(pt);
      container.setEmpty(false);
   }
}

template<class DATA_TYPE >
void gmtl::extendVolume ( AABox< DATA_TYPE > &  container,
const AABox< DATA_TYPE > &  box 
)

Modifies the container to tightly enclose itself and the given AABox.

Parameters:
container [in,out] the AABox that will be extended
box [in] the AABox which container should contain

Definition at line 444 of file Containment.h.

{
   // Can't extend by an empty box
   if (box.isEmpty())
   {
      return;
   }

   // An empty container is extended to be the box
   if (container.isEmpty())
   {
      container = box;
   }

   // Just extend by the corners of the box
   extendVolume(container, box.getMin());
   extendVolume(container, box.getMax());
}

template<class DATA_TYPE >
void gmtl::extendVolume ( Sphere< DATA_TYPE > &  container,
const Point< DATA_TYPE, 3 > &  pt 
)

Modifies the existing sphere to tightly enclose itself and the given point.

Parameters:
container [in,out] the sphere that will be extended
pt [in] the point which the sphere should contain

Definition at line 79 of file Containment.h.

{
   // check if we already contain the point
   if ( isInVolume( container, pt ) )
   {
      return;
   }

   // make a vector pointing from the center of the sphere to pt. this is the
   // direction in which we need to move the sphere's center
   Vec<DATA_TYPE, 3> dir = pt - container.mCenter;
   DATA_TYPE len = normalize( dir );

   // compute what the new radius should be
   DATA_TYPE newRadius = (len + container.mRadius) * static_cast<DATA_TYPE>(0.5);

   // compute the new center for the sphere
   Point<DATA_TYPE, 3> newCenter = container.mCenter +
                                   (dir * (newRadius - container.mRadius));

   // modify container to its new values
   container.mCenter = newCenter;
   container.mRadius = newRadius;
}

template<class DATA_TYPE >
void gmtl::extendVolume ( Sphere< DATA_TYPE > &  container,
const Sphere< DATA_TYPE > &  sphere 
)

Modifies the container to tightly enclose itself and the given sphere.

Parameters:
container [in,out] the sphere that will be extended
sphere [in] the sphere which container should contain

Definition at line 112 of file Containment.h.

{
   // check if we already contain the sphere
   if ( isInVolume( container, sphere ) )
   {
      return;
   }

   // make a vector pointing from the center of container to sphere. this is the
   // direction in which we need to move container's center
   Vec<DATA_TYPE, 3> dir = sphere.mCenter - container.mCenter;
   DATA_TYPE len = normalize( dir );

   // compute what the new radius should be
   DATA_TYPE newRadius = (len + sphere.mRadius + container.mRadius) *
                         static_cast<DATA_TYPE>(0.5);

   // compute the new center for container
   Point<DATA_TYPE, 3> newCenter = container.mCenter +
                                   (dir * (newRadius - container.mRadius));

   // modify container to its new values
   container.mCenter = newCenter;
   container.mRadius = newRadius;
}

template<class DATA_TYPE >
DATA_TYPE gmtl::findNearestPt ( const Plane< DATA_TYPE > &  plane,
const Point< DATA_TYPE, 3 > &  pt,
Point< DATA_TYPE, 3 > &  result 
)

Finds the point on the plane that is nearest to the given point.

As a convenience, the distance between pt and result is returned.

Parameters:
plane [in] the plane to compare the point to
pt [in] the point to test
result [out] the point on plane closest to pt
Returns:
the distance between pt and result

Definition at line 96 of file PlaneOps.h.

{
   // GGI:  p297
   // GGII: p223
   gmtlASSERT( isNormalized(plane.mNorm) );   // Assert: Normalized
   DATA_TYPE dist_to_plane(0);
   dist_to_plane = plane.mOffset + dot( plane.mNorm, static_cast< Vec<DATA_TYPE, 3> >(pt) );
   result = pt - (plane.mNorm * dist_to_plane);
   return dist_to_plane;
}

template<class DATA_TYPE >
Point<DATA_TYPE, 3> gmtl::findNearestPt ( const LineSeg< DATA_TYPE > &  lineseg,
const Point< DATA_TYPE, 3 > &  pt 
)

Finds the closest point on the line segment to a given point.

Parameters:
lineseg the line segment to test
pt the point which to test against lineseg
Returns:
the point on the line segment closest to pt

Definition at line 23 of file LineSegOps.h.

{
   // result = origin + dir * dot((pt-origin), dir)
   return ( lineseg.mOrigin + lineseg.mDir *
            dot(pt - lineseg.mOrigin, lineseg.mDir) / lengthSquared(lineseg.mDir) );
}

void gmtl::GaussPointsFit ( int  iQuantity,
const Point3 *  akPoint,
Point3 &  rkCenter,
Vec3  akAxis[3],
float  afExtent[3] 
)

Definition at line 47 of file GaussPointsFit.h.

{
    // compute mean of points
    rkCenter = akPoint[0];
    unsigned i;
    for (i = 1; i < iQuantity; i++)
        rkCenter += akPoint[i];
    float fInvQuantity = 1.0f/iQuantity;
    rkCenter *= fInvQuantity;

    // compute covariances of points
    float fSumXX = 0.0, fSumXY = 0.0, fSumXZ = 0.0;
    float fSumYY = 0.0, fSumYZ = 0.0, fSumZZ = 0.0;
    for (i = 0; i < iQuantity; i++)
    {
        Vec3 kDiff = akPoint[i] - rkCenter;
        fSumXX += kDiff[Xelt]*kDiff[Xelt];
        fSumXY += kDiff[Xelt]*kDiff[Yelt];
        fSumXZ += kDiff[Xelt]*kDiff[Zelt];
        fSumYY += kDiff[Yelt]*kDiff[Yelt];
        fSumYZ += kDiff[Yelt]*kDiff[Zelt];
        fSumZZ += kDiff[Zelt]*kDiff[Zelt];
    }
    fSumXX *= fInvQuantity;
    fSumXY *= fInvQuantity;
    fSumXZ *= fInvQuantity;
    fSumYY *= fInvQuantity;
    fSumYZ *= fInvQuantity;
    fSumZZ *= fInvQuantity;

    // compute eigenvectors for covariance matrix
    gmtl::Eigen kES(3);
    kES.Matrix(0,0) = fSumXX;
    kES.Matrix(0,1) = fSumXY;
    kES.Matrix(0,2) = fSumXZ;
    kES.Matrix(1,0) = fSumXY;
    kES.Matrix(1,1) = fSumYY;
    kES.Matrix(1,2) = fSumYZ;
    kES.Matrix(2,0) = fSumXZ;
    kES.Matrix(2,1) = fSumYZ;
    kES.Matrix(2,2) = fSumZZ;
    kES.IncrSortEigenStuff3();

    akAxis[0][Xelt] = kES.GetEigenvector(0,0);
    akAxis[0][Yelt] = kES.GetEigenvector(1,0);
    akAxis[0][Zelt] = kES.GetEigenvector(2,0);

    akAxis[1][Xelt] = kES.GetEigenvector(0,1);
    akAxis[1][Yelt] = kES.GetEigenvector(1,1);
    akAxis[1][Zelt] = kES.GetEigenvector(2,1);

    akAxis[2][Xelt] = kES.GetEigenvector(0,2);
    akAxis[2][Yelt] = kES.GetEigenvector(1,2);
    akAxis[2][Zelt] = kES.GetEigenvector(2,2);

    afExtent[0] = kES.GetEigenvalue(0);
    afExtent[1] = kES.GetEigenvalue(1);
    afExtent[2] = kES.GetEigenvalue(2);
}

bool gmtl::GaussPointsFit ( int  iQuantity,
const Vec3 *  akPoint,
const bool *  abValid,
Vec3 &  rkCenter,
Vec3  akAxis[3],
float  afExtent[3] 
)

Definition at line 110 of file GaussPointsFit.h.

{
    // compute mean of points
    rkCenter = ZeroVec3;
    int i, iValidQuantity = 0;
    for (i = 0; i < iQuantity; i++)
    {
        if ( abValid[i] )
        {
            rkCenter += akPoint[i];
            iValidQuantity++;
        }
    }
    if ( iValidQuantity == 0 )
        return false;

    float fInvQuantity = 1.0/iValidQuantity;
    rkCenter *= fInvQuantity;

    // compute covariances of points
    float fSumXX = 0.0, fSumXY = 0.0, fSumXZ = 0.0;
    float fSumYY = 0.0, fSumYZ = 0.0, fSumZZ = 0.0;
    for (i = 0; i < iQuantity; i++)
    {
        if ( abValid[i] )
        {
            Vec3 kDiff = akPoint[i] - rkCenter;
            fSumXX += kDiff[Xelt]*kDiff[Xelt];
            fSumXY += kDiff[Xelt]*kDiff[Yelt];
            fSumXZ += kDiff[Xelt]*kDiff[Zelt];
            fSumYY += kDiff[Yelt]*kDiff[Yelt];
            fSumYZ += kDiff[Yelt]*kDiff[Zelt];
            fSumZZ += kDiff[Zelt]*kDiff[Zelt];
        }
    }
    fSumXX *= fInvQuantity;
    fSumXY *= fInvQuantity;
    fSumXZ *= fInvQuantity;
    fSumYY *= fInvQuantity;
    fSumYZ *= fInvQuantity;
    fSumZZ *= fInvQuantity;

    // compute eigenvectors for covariance matrix
    Eigen kES(3);
    kES.Matrix(0,0) = fSumXX;
    kES.Matrix(0,1) = fSumXY;
    kES.Matrix(0,2) = fSumXZ;
    kES.Matrix(1,0) = fSumXY;
    kES.Matrix(1,1) = fSumYY;
    kES.Matrix(1,2) = fSumYZ;
    kES.Matrix(2,0) = fSumXZ;
    kES.Matrix(2,1) = fSumYZ;
    kES.Matrix(2,2) = fSumZZ;
    kES.IncrSortEigenStuff3();

    akAxis[0][Xelt] = kES.GetEigenvector(0,0);
    akAxis[0][Yelt] = kES.GetEigenvector(1,0);
    akAxis[0][Zelt] = kES.GetEigenvector(2,0);

    akAxis[1][Xelt] = kES.GetEigenvector(0,1);
    akAxis[1][Yelt] = kES.GetEigenvector(1,1);
    akAxis[1][Zelt] = kES.GetEigenvector(2,1);

    akAxis[2][Xelt] = kES.GetEigenvector(0,2);
    akAxis[2][Yelt] = kES.GetEigenvector(1,2);
    akAxis[2][Zelt] = kES.GetEigenvector(2,2);

    afExtent[0] = kES.GetEigenvalue(0);
    afExtent[1] = kES.GetEigenvalue(1);
    afExtent[2] = kES.GetEigenvalue(2);

    return true;
}

const char* gmtl::getVersion (  )  [inline]

Definition at line 111 of file Version.h.

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::identity ( Matrix< DATA_TYPE, ROWS, COLS > &  result  )  [inline]

Make identity matrix out the matrix.

Postcondition:
Every element is 0 except the matrix's diagonal, whose elements are 1.

Definition at line 28 of file MatrixOps.h.

   {
      if(result.mState != Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY)   // if not already ident
      {
         // TODO: mp
         for (unsigned int r = 0; r < ROWS; ++r)
         for (unsigned int c = 0; c < COLS; ++c)
            result( r, c ) = (DATA_TYPE)0.0;

         // TODO: mp
         for (unsigned int x = 0; x < Math::Min( COLS, ROWS ); ++x)
            result( x, x ) = (DATA_TYPE)1.0;

         result.mState = Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY;
//         result.mState = Matrix<DATA_TYPE, ROWS, COLS>::FULL;
      }

      return result;
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const AABox< DATA_TYPE > &  box1,
const AABox< DATA_TYPE > &  box2 
)

Tests if the given AABoxes intersect with each other.

Sharing an edge IS considered intersection by this algorithm.

Parameters:
box1 the first AA box to test
box2 the second AA box to test
Returns:
true if the boxes intersect; false otherwise

Definition at line 35 of file Intersection.h.

   {
      // Look for a separating axis on each box for each axis
      if (box1.getMin()[0] > box2.getMax()[0])  return false;
      if (box1.getMin()[1] > box2.getMax()[1])  return false;
      if (box1.getMin()[2] > box2.getMax()[2])  return false;

      if (box2.getMin()[0] > box1.getMax()[0])  return false;
      if (box2.getMin()[1] > box1.getMax()[1])  return false;
      if (box2.getMin()[2] > box1.getMax()[2])  return false;

      // No separating axis ... they must intersect
      return true;
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const AABox< DATA_TYPE > &  box1,
const Vec< DATA_TYPE, 3 > &  path1,
const AABox< DATA_TYPE > &  box2,
const Vec< DATA_TYPE, 3 > &  path2,
DATA_TYPE &  firstContact,
DATA_TYPE &  secondContact 
)

Tests if the given AABoxes intersect if moved along the given paths.

Using the AABox sweep test, the normalized time of the first and last points of contact are found.

Parameters:
box1 the first box to test
path1 the path the first box should travel along
box2 the second box to test
path2 the path the second box should travel along
firstContact set to the normalized time of the first point of contact
secondContact set to the normalized time of the second point of contact
Returns:
true if the boxes intersect at any time; false otherwise

Definition at line 90 of file Intersection.h.

   {
      // Algorithm taken from Gamasutra's article, "Simple Intersection Test for
      // Games" - http://www.gamasutra.com/features/19991018/Gomez_3.htm
      //
      // This algorithm is solved from the frame of reference of box1

      // Get the relative path (in normalized time)
      Vec<DATA_TYPE, 3> path = path2 - path1;

      // The first time of overlap along each axis
      Vec<DATA_TYPE, 3> overlap1(DATA_TYPE(0), DATA_TYPE(0), DATA_TYPE(0));

      // The second time of overlap along each axis
      Vec<DATA_TYPE, 3> overlap2(DATA_TYPE(1), DATA_TYPE(1), DATA_TYPE(1));

      // Check if the boxes already overlap
      if (gmtl::intersect(box1, box2))
      {
         firstContact = secondContact = DATA_TYPE(0);
         return true;
      }

      // Find the possible first and last times of overlap along each axis
      for (int i=0; i<3; ++i)
      {
         if ((box1.getMax()[i] < box2.getMin()[i]) && (path[i] < DATA_TYPE(0)))
         {
            overlap1[i] = (box1.getMax()[i] - box2.getMin()[i]) / path[i];
         }
         else if ((box2.getMax()[i] < box1.getMin()[i]) && (path[i] > DATA_TYPE(0)))
         {
            overlap1[i] = (box1.getMin()[i] - box2.getMax()[i]) / path[i];
         }

         if ((box2.getMax()[i] > box1.getMin()[i]) && (path[i] < DATA_TYPE(0)))
         {
            overlap2[i] = (box1.getMin()[i] - box2.getMax()[i]) / path[i];
         }
         else if ((box1.getMax()[i] > box2.getMin()[i]) && (path[i] > DATA_TYPE(0)))
         {
            overlap2[i] = (box1.getMax()[i] - box2.getMin()[i]) / path[i];
         }
      }

      // Calculate the first time of overlap
      firstContact = Math::Max(overlap1[0], overlap1[1], overlap1[2]);

      // Calculate the second time of overlap
      secondContact = Math::Min(overlap2[0], overlap2[1], overlap2[2]);

      // There could only have been a collision if the first overlap time
      // occurred before the second overlap time
      return firstContact <= secondContact;
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const AABox< DATA_TYPE > &  box,
const Point< DATA_TYPE, 3 > &  point 
)

Tests if the given AABox and point intersect with each other.

On an edge IS considered intersection by this algorithm.

Parameters:
box the box to test
point the point to test
Returns:
true if the point is within the box's bounds; false otherwise

Definition at line 60 of file Intersection.h.

   {
      // Look for a separating axis on each box for each axis
      if (box.getMin()[0] > point[0])  return false;
      if (box.getMin()[1] > point[1])  return false;
      if (box.getMin()[2] > point[2])  return false;

      if (point[0] > box.getMax()[0])  return false;
      if (point[1] > box.getMax()[1])  return false;
      if (point[2] > box.getMax()[2])  return false;

      // they must intersect
      return true;
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const AABox< DATA_TYPE > &  box,
const LineSeg< DATA_TYPE > &  seg,
unsigned int &  numHits,
DATA_TYPE &  tIn,
DATA_TYPE &  tOut 
)

Given a line segment and an axis-aligned bounding box, returns whether the line intersects the box, and if so, tIn and tOut are set to the parametric terms on the line segment where the segment enters and exits the box respectively.

Since:
0.4.11

Definition at line 284 of file Intersection.h.

   {
      numHits = 0;
      bool result = intersectAABoxRay(box, seg, tIn, tOut);
      if (tIn < 0.0 && tOut > 1.0)
      {
     return false;
      }
      if ( result )
      {
         // If tIn is less than 0, then the origin of the line segment is
         // inside the bounding box (not on an edge)but the endpoint is
         // outside.
         if ( tIn < DATA_TYPE(0) )
         {
            numHits = 1;
            tIn = tOut;
         }
         // If tIn is less than 0, then the origin of the line segment is
         // outside the bounding box but the endpoint is inside (not on an
         // edge).
         else if ( tOut > DATA_TYPE(1) )
         {
            numHits = 1;
            tOut = tIn;
         }
         // Otherwise, the line segement intersects the bounding box in two
         // places. tIn and tOut reflect those points of intersection.
         else
         {
            numHits = 2;
         }
      }

      return result;
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const LineSeg< DATA_TYPE > &  seg,
const AABox< DATA_TYPE > &  box,
unsigned int &  numHits,
DATA_TYPE &  tIn,
DATA_TYPE &  tOut 
)

Given a line segment and an axis-aligned bounding box, returns whether the line intersects the box, and if so, tIn and tOut are set to the parametric terms on the line segment where the segment enters and exits the box respectively.

Since:
0.4.11

Definition at line 331 of file Intersection.h.

   {
      return intersect(box, seg, numHits, tIn, tOut);
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const AABox< DATA_TYPE > &  box,
const Ray< DATA_TYPE > &  ray,
unsigned int &  numHits,
DATA_TYPE &  tIn,
DATA_TYPE &  tOut 
)

Given a ray and an axis-aligned bounding box, returns whether the ray intersects the box, and if so, tIn and tOut are set to the parametric terms on the ray where it enters and exits the box respectively.

Since:
0.4.11

Definition at line 346 of file Intersection.h.

   {
      numHits = 0;

      bool result = intersectAABoxRay(box, ray, tIn, tOut);

      if ( result )
      {
         // Ray is inside the box.
         if ( tIn < DATA_TYPE(0) )
         {
            tIn = tOut;
            numHits = 1;
         }
         else
         {
            numHits = 2;
         }
      }

      return result;
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const Sphere< DATA_TYPE > &  sph1,
const Vec< DATA_TYPE, 3 > &  path1,
const Sphere< DATA_TYPE > &  sph2,
const Vec< DATA_TYPE, 3 > &  path2,
DATA_TYPE &  firstContact,
DATA_TYPE &  secondContact 
)

Tests if the given Spheres intersect if moved along the given paths.

Using the Sphere sweep test, the normalized time of the first and last points of contact are found.

Parameters:
sph1 the first sphere to test
path1 the path the first sphere should travel along
sph2 the second sphere to test
path2 the path the second sphere should travel along
firstContact set to the normalized time of the first point of contact
secondContact set to the normalized time of the second point of contact
Returns:
true if the spheres intersect; false otherwise

Definition at line 400 of file Intersection.h.

   {
      // Algorithm taken from Gamasutra's article, "Simple Intersection Test for
      // Games" - http://www.gamasutra.com/features/19991018/Gomez_2.htm
      //
      // This algorithm is solved from the frame of reference of sph1

      // Get the relative path (in normalized time)
      const Vec<DATA_TYPE, 3> path = path2 - path1;

      // Get the vector from sph1's starting point to sph2's starting point
      const Vec<DATA_TYPE, 3> start_offset = sph2.getCenter() - sph1.getCenter();

      // Compute the sum of the radii
      const DATA_TYPE radius_sum = sph1.getRadius() + sph2.getRadius();

      // u*u coefficient
      const DATA_TYPE a = dot(path, path);

      // u coefficient
      const DATA_TYPE b = DATA_TYPE(2) * dot(path, start_offset);

      // constant term
      const DATA_TYPE c = dot(start_offset, start_offset) - radius_sum * radius_sum;

      // Check if they're already overlapping
      if (dot(start_offset, start_offset) <= radius_sum * radius_sum)
      {
         firstContact = secondContact = DATA_TYPE(0);
         return true;
      }

      // Find the first and last points of intersection
      if (Math::quadraticFormula(firstContact, secondContact, a, b, c))
      {
         // Swap first and second contacts if necessary
         if (firstContact > secondContact)
         {
            std::swap(firstContact, secondContact);
            return true;
         }
      }

      return false;
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const AABox< DATA_TYPE > &  box,
const Sphere< DATA_TYPE > &  sph 
)

Tests if the given AABox and Sphere intersect with each other.

On an edge IS considered intersection by this algorithm.

Parameters:
box the box to test
sph the sphere to test
Returns:
true if the items intersect; false otherwise

Definition at line 458 of file Intersection.h.

   {
      DATA_TYPE dist_sqr = DATA_TYPE(0);

      // Compute the square of the distance from the sphere to the box
      for (int i=0; i<3; ++i)
      {
         if (sph.getCenter()[i] < box.getMin()[i])
         {
            DATA_TYPE s = sph.getCenter()[i] - box.getMin()[i];
            dist_sqr += s*s;
         }
         else if (sph.getCenter()[i] > box.getMax()[i])
         {
            DATA_TYPE s = sph.getCenter()[i] - box.getMax()[i];
            dist_sqr += s*s;
         }
      }

      return dist_sqr <= (sph.getRadius()*sph.getRadius());
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const Sphere< DATA_TYPE > &  sph,
const AABox< DATA_TYPE > &  box 
)

Tests if the given AABox and Sphere intersect with each other.

On an edge IS considered intersection by this algorithm.

Parameters:
sph the sphere to test
box the box to test
Returns:
true if the items intersect; false otherwise

Definition at line 490 of file Intersection.h.

   {
      return gmtl::intersect(box, sph);
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const Sphere< DATA_TYPE > &  sphere,
const Point< DATA_TYPE, 3 > &  point 
)

intersect point/sphere.

Parameters:
point the point to test
sphere the sphere to test
Returns:
true if point is in or on sphere

Definition at line 502 of file Intersection.h.

   {
      gmtl::Vec<DATA_TYPE, 3> offset = point - sphere.getCenter();
      DATA_TYPE dist = lengthSquared( offset ) - sphere.getRadius() * sphere.getRadius();

      // point is inside the sphere when true
      return  dist <= 0;
   }

template<typename T >
bool gmtl::intersect ( const Sphere< T > &  sphere,
const Ray< T > &  ray,
int &  numhits,
T &  t0,
T &  t1 
) [inline]

intersect ray/sphere-shell (not volume).

only register hits with the surface of the sphere. note: after calling this, you can find the intersection point with: ray.getOrigin() + ray.getDir() * t

Parameters:
ray the ray to test
sphere the sphere to test
Returns:
returns intersection point in t, and the number of hits
numhits, t0, t1 are undefined if return value is false

Definition at line 522 of file Intersection.h.

   {
      numhits = -1;

      // set up quadratic Q(t) = a*t^2 + 2*b*t + c
      const Vec<T, 3> offset = ray.getOrigin() - sphere.getCenter();
      const T a = lengthSquared( ray.getDir() );
      const T b = dot( offset, ray.getDir() );
      const T c = lengthSquared( offset ) - sphere.getRadius() * sphere.getRadius();



      // no intersection if Q(t) has no real roots
      const T discriminant = b * b - a * c;
      if (discriminant < 0.0f)
      {
         numhits = 0;
         return false;
      }
      else if (discriminant > 0.0f)
      {
         T root = Math::sqrt( discriminant );
         T invA = T(1) / a;
         t0 = (-b - root) * invA;
         t1 = (-b + root) * invA;

         // assert: t0 < t1 since A > 0

         if (t0 >= T(0))
         {
            numhits = 2;
            return true;
         }
         else if (t1 >= T(0))
         {
            numhits = 1;
            t0 = t1;
            return true;
         }
         else
         {
            numhits = 0;
            return false;
         }
      }
      else
      {
         t0 = -b / a;
         if (t0 >= T(0))
         {
            numhits = 1;
            return true;
         }
         else
         {
            numhits = 0;
            return false;
         }
      }
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const Ray< DATA_TYPE > &  ray,
const AABox< DATA_TYPE > &  box,
unsigned int &  numHits,
DATA_TYPE &  tIn,
DATA_TYPE &  tOut 
)

Given a ray and an axis-aligned bounding box, returns whether the ray intersects the box, and if so, tIn and tOut are set to the parametric terms on the ray where it enters and exits the box respectively.

Since:
0.4.11

Definition at line 379 of file Intersection.h.

   {
      return intersect(box, ray, numHits, tIn, tOut);
   }

template<typename T >
bool gmtl::intersect ( const Sphere< T > &  sphere,
const LineSeg< T > &  lineseg,
int &  numhits,
T &  t0,
T &  t1 
) [inline]

intersect LineSeg/Sphere-shell (not volume).

does intersection on sphere surface, point inside sphere doesn't count as an intersection returns intersection point(s) in t find intersection point(s) with: ray.getOrigin() + ray.getDir() * t numhits, t0, t1 are undefined if return value is false

Definition at line 590 of file Intersection.h.

   {
      if (intersect( sphere, Ray<T>( lineseg ), numhits, t0, t1 ))
      {
         // throw out hits that are past 1 in segspace (off the end of the lineseg)
         while (0 < numhits && 1.0f < t0)
         {
            --numhits;
            t0 = t1;
         }
         if (2 == numhits && 1.0f < t1)
         {
            --numhits;
         }
         return 0 < numhits;
      }
      else
      {
         return false;
      }
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const Plane< DATA_TYPE > &  plane,
const LineSeg< DATA_TYPE > &  seg,
DATA_TYPE &  t 
)

Tests if the given plane and lineseg intersect with each other.

Parameters:
ray - the lineseg
plane - the Plane
t - t gives you the intersection point: isect_point = lineseg.origin + lineseg.dir * t
Returns:
true if the lineseg intersects the plane.

Definition at line 750 of file Intersection.h.

   {
      bool res(intersect(plane, static_cast<Ray<DATA_TYPE> >(seg), t));
      return res && t <= (DATA_TYPE)1.0;
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const Tri< DATA_TYPE > &  tri,
const Ray< DATA_TYPE > &  ray,
float &  u,
float &  v,
float &  t 
)

Tests if the given triangle and ray intersect with each other.

Parameters:
tri - the triangle (ccw ordering)
ray - the ray
u,v - tangent space u/v coordinates of the intersection
t - an indicator of the intersection location
Postcondition:
t gives you the intersection point: isect = ray.dir * t + ray.origin
Returns:
true if the ray intersects the triangle.
See also:
from http://www.acm.org/jgt/papers/MollerTrumbore97/code.html

Definition at line 769 of file Intersection.h.

   {
      const float EPSILON = (DATA_TYPE)0.00001f;
      Vec<DATA_TYPE, 3> edge1, edge2, tvec, pvec, qvec;
      float det,inv_det;

      /* find vectors for two edges sharing vert0 */
      edge1 = tri[1] - tri[0];
      edge2 = tri[2] - tri[0];

      /* begin calculating determinant - also used to calculate U parameter */
      gmtl::cross( pvec, ray.getDir(), edge2 );

      /* if determinant is near zero, ray lies in plane of triangle */
      det = gmtl::dot( edge1, pvec );

      if (det < EPSILON)
         return false;

      /* calculate distance from vert0 to ray origin */
      tvec = ray.getOrigin() - tri[0];

      /* calculate U parameter and test bounds */
      u = gmtl::dot( tvec, pvec );
      if (u < 0.0 || u > det)
         return false;

      /* prepare to test V parameter */
      gmtl::cross( qvec, tvec, edge1 );

      /* calculate V parameter and test bounds */
      v = gmtl::dot( ray.getDir(), qvec );
      if (v < 0.0 || u + v > det)
         return false;

      /* calculate t, scale parameters, ray intersects triangle */
      t = gmtl::dot( edge2, qvec );
      inv_det = ((DATA_TYPE)1.0) / det;
      t *= inv_det;
      u *= inv_det;
      v *= inv_det;

      // test if t is within the ray boundary (when t >= 0)
      return t >= (DATA_TYPE)0;
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const Plane< DATA_TYPE > &  plane,
const Ray< DATA_TYPE > &  ray,
DATA_TYPE &  t 
)

Tests if the given plane and ray intersect with each other.

Parameters:
ray - the Ray
plane - the Plane
t - t gives you the intersection point: isect_point = ray.origin + ray.dir * t
Returns:
true if the ray intersects the plane.
Note:
If ray is parallel to plane: t=0, ret:true -> on plane, ret:false -> No hit

Definition at line 719 of file Intersection.h.

   {
      const DATA_TYPE eps(0.00001f);

      // t = -(nĚP + d)
      Vec<DATA_TYPE, 3> N( plane.getNormal() );
      DATA_TYPE denom( dot(N,ray.getDir()) );
      if(gmtl::Math::abs(denom) < eps)    // Ray parallel to plane
      {
         t = 0;
         if(distance(plane, ray.mOrigin) < eps)     // Test for ray on plane
         { return true; }
         else
         { return false; }
      }
      t = dot( N, Vec<DATA_TYPE,3>(N * plane.getOffset() - ray.getOrigin()) ) / denom;

      return (DATA_TYPE)0 <= t;
   }

template<class DATA_TYPE >
bool gmtl::intersect ( const Tri< DATA_TYPE > &  tri,
const LineSeg< DATA_TYPE > &  lineseg,
DATA_TYPE &  u,
DATA_TYPE &  v,
DATA_TYPE &  t 
)

Tests if the given triangle and line segment intersect with each other.

Parameters:
tri - the triangle (ccw ordering)
lineseg - the line segment
u,v - tangent space u/v coordinates of the intersection
t - an indicator of the intersection point
Postcondition:
t gives you the intersection point: isect = lineseg.getDir() * t + lineseg.getOrigin()
Returns:
true if the line segment intersects the triangle.

Definition at line 898 of file Intersection.h.

   {
      const DATA_TYPE eps = (DATA_TYPE)0.0001010101;
      DATA_TYPE l = length( lineseg.getDir() );
      if (eps < l)
      {
         Ray<DATA_TYPE> temp( lineseg.getOrigin(), lineseg.getDir() );
         bool result = intersect( tri, temp, u, v, t );
         return result && t <= (DATA_TYPE)1.0;
      }
      else
      {  return false; }
   }

template<class DATA_TYPE >
bool gmtl::intersectAABoxRay ( const AABox< DATA_TYPE > &  box,
const Ray< DATA_TYPE > &  ray,
DATA_TYPE &  tIn,
DATA_TYPE &  tOut 
)

Given an axis-aligned bounding box and a ray (or subclass thereof), returns whether the ray intersects the box, and if so, tIn and tOut are set to the parametric terms on the ray where the segment enters and exits the box respectively.

The implementation of this function comes from the book Geometric Tools for Computer Graphics, pages 626-630.

Note:
Internal function for performing an intersection test between an axis-aligned bounding box and a ray. User code should not call this function directly. It is used to capture the common code between the gmtl::Ray<T> and gmtl::LineSeg<T> overloads of gmtl::intersect() when intersecting with a gmtl::AABox<T>.

Definition at line 164 of file Intersection.h.

   {
      tIn  = -(std::numeric_limits<DATA_TYPE>::max)();
      tOut = (std::numeric_limits<DATA_TYPE>::max)();
      DATA_TYPE t0, t1;
      const DATA_TYPE epsilon(0.0000001);

      // YZ plane.
      if ( gmtl::Math::abs(ray.mDir[0]) < epsilon )
      {
         // Ray parallel to plane.
         if ( ray.mOrigin[0] < box.mMin[0] || ray.mOrigin[0] > box.mMax[0] )
         {
            return false;
         }
      }

      // XZ plane.
      if ( gmtl::Math::abs(ray.mDir[1]) < epsilon )
      {
         // Ray parallel to plane.
         if ( ray.mOrigin[1] < box.mMin[1] || ray.mOrigin[1] > box.mMax[1] )
         {
            return false;
         }
      }

      // XY plane.
      if ( gmtl::Math::abs(ray.mDir[2]) < epsilon )
      {
         // Ray parallel to plane.
         if ( ray.mOrigin[2] < box.mMin[2] || ray.mOrigin[2] > box.mMax[2] )
         {
            return false;
         }
      }

      // YZ plane.
      t0 = (box.mMin[0] - ray.mOrigin[0]) / ray.mDir[0];
      t1 = (box.mMax[0] - ray.mOrigin[0]) / ray.mDir[0];

      if ( t0 > t1 )
      {
         std::swap(t0, t1);
      }

      if ( t0 > tIn )
      {
         tIn = t0;
      }
      if ( t1 < tOut )
      {
         tOut = t1;
      }

      if ( tIn > tOut || tOut < DATA_TYPE(0) )
      {
         return false;
      }

      // XZ plane.
      t0 = (box.mMin[1] - ray.mOrigin[1]) / ray.mDir[1];
      t1 = (box.mMax[1] - ray.mOrigin[1]) / ray.mDir[1];

      if ( t0 > t1 )
      {
         std::swap(t0, t1);
      }

      if ( t0 > tIn )
      {
         tIn = t0;
      }
      if ( t1 < tOut )
      {
         tOut = t1;
      }

      if ( tIn > tOut || tOut < DATA_TYPE(0) )
      {
         return false;
      }

      // XY plane.
      t0 = (box.mMin[2] - ray.mOrigin[2]) / ray.mDir[2];
      t1 = (box.mMax[2] - ray.mOrigin[2]) / ray.mDir[2];

      if ( t0 > t1 )
      {
         std::swap(t0, t1);
      }

      if ( t0 > tIn )
      {
         tIn = t0;
      }
      if ( t1 < tOut )
      {
         tOut = t1;
      }

      if ( tIn > tOut || tOut < DATA_TYPE(0) )
      {
         return false;
      }

      return true;
   }

template<class DATA_TYPE >
bool gmtl::intersectDoubleSided ( const Tri< DATA_TYPE > &  tri,
const Ray< DATA_TYPE > &  ray,
DATA_TYPE &  u,
DATA_TYPE &  v,
DATA_TYPE &  t 
)

Tests if the given triangle intersects with the given ray, from both sides.

Parameters:
tri The triangle (ccw ordering).
ray The ray.
u Tangent space u-coordinate of the intersection.
v Tangent space v-coordinate of the intersection.
t An indicator of the intersection location.
Postcondition:
t gives you the intersection point:
 isect = ray.dir * t + ray.origin 
Returns:
true if the ray intersects the triangle.
See also:
from http://www.acm.org/jgt/papers/MollerTrumbore97/code.html

Definition at line 833 of file Intersection.h.

   {
      const DATA_TYPE EPSILON = (DATA_TYPE)0.00001f;
      Vec<DATA_TYPE, 3> edge1, edge2, tvec, pvec, qvec;
      DATA_TYPE det, inv_det;

      // Find vectors for two edges sharing vert0.
      edge1 = tri[1] - tri[0];
      edge2 = tri[2] - tri[0];

      // Begin calculating determinant - also used to calculate U parameter.
      gmtl::cross(pvec, ray.getDir(), edge2);

      // If determinant is near zero, ray lies in plane of triangle.
      det = gmtl::dot( edge1, pvec );

      if ( det < EPSILON && det > -EPSILON )
      {
         return false;
      }

      // calculate distance from vert0 to ray origin>
      tvec = ray.getOrigin() - tri[0];

      // Calc inverse deteriminant.
      inv_det = ((DATA_TYPE)1.0) / det; 

      // Calculate U parameter and test bounds.
      u =  inv_det * gmtl::dot(tvec, pvec);
      if ( u < 0.0 || u > 1.0 )
      {
         return false;
      }

      // Prepare to test V parameter.
      gmtl::cross(qvec, tvec, edge1);

      // Calculate V parameter and test bounds.
      v = inv_det * gmtl::dot(ray.getDir(), qvec);
      if (v < 0.0 || u + v > 1.0)
      {
         return false;
      }

      // Calculate t, scale parameters, ray intersects triangle.
      t = inv_det * gmtl::dot(edge2, qvec);

      // Test if t is within the ray boundary (when t >= 0).
      return t >= (DATA_TYPE)0;
   }

template<typename T >
bool gmtl::intersectVolume ( const Sphere< T > &  sphere,
const LineSeg< T > &  ray,
int &  numhits,
T &  t0,
T &  t1 
) [inline]

intersect lineseg/sphere-volume.

register hits with both the surface and when end points land on the interior of the sphere. note: after calling this, you can find the intersection point with: ray.getOrigin() + ray.getDir() * t

Parameters:
ray the lineseg to test
sphere the sphere to test
Returns:
returns intersection point in t, and the number of hits
numhits, t0, t1 are undefined if return value is false

Definition at line 623 of file Intersection.h.

   {
      bool result = intersect( sphere, ray, numhits, t0, t1 );
      if (result && numhits == 2)
      {
         return true;
      }
      // todo: make this faster (find an early out) since 1 or 0 hits is the common case.
      // volume test has some additional checks before we can throw it out because
      // one of both points may be inside the volume, so we want to return hits for those as well...
      else // 1 or 0 hits.
      {
         const T rsq = sphere.getRadius() * sphere.getRadius();
         const Vec<T, 3> dist = ray.getOrigin() - sphere.getCenter();
         const T a = lengthSquared( dist ) - rsq;
         const T b = lengthSquared( gmtl::Vec<T,3>(dist + ray.getDir()) ) - rsq;

         bool inside1 = a <= T( 0 );
         bool inside2 = b <= T( 0 );

         // one point is inside
         if (numhits == 1 && inside1 && !inside2)
         {
            t1 = t0;
            t0 = T(0);
            numhits = 2;
            return true;
         }
         else if (numhits == 1 && !inside1 && inside2)
         {
            t1 = T(1);
            numhits = 2;
            return true;
         }
         // maybe both points are inside?
         else if (inside1 && inside2) // 0 hits.
         {
            t0 = T(0);
            t1 = T(1);
            numhits = 2;
            return true;
         }
      }
      return result;
   }

template<typename T >
bool gmtl::intersectVolume ( const Sphere< T > &  sphere,
const Ray< T > &  ray,
int &  numhits,
T &  t0,
T &  t1 
) [inline]

intersect ray/sphere-volume.

register hits with both the surface and when the origin lands in the interior of the sphere. note: after calling this, you can find the intersection point with: ray.getOrigin() + ray.getDir() * t

Parameters:
ray the ray to test
sphere the sphere to test
Returns:
returns intersection point in t, and the number of hits
numhits, t0, t1 are undefined if return value is false

Definition at line 680 of file Intersection.h.

   {
      bool result = intersect( sphere, ray, numhits, t0, t1 );
      if (result && numhits == 2)
      {
         return true;
      }
      else
      {
         const T rsq = sphere.getRadius() * sphere.getRadius();
         const Vec<T, 3> dist = ray.getOrigin() - sphere.getCenter();
         const T a = lengthSquared( dist ) - rsq;

         bool inside = a <= T( 0 );

         // start point is inside
         if (inside)
         {
            t1 = t0;
            t0 = T(0);
            numhits = 2;
            return true;
         }
      }
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::invert ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  src 
) [inline]

smart matrix inversion.

Does matrix inversion by intelligently selecting what type of inversion to use depending on the types of operations your Matrix has been through.

5 types of inversion: FULL, AFFINE, ORTHONORMAL, ORTHOGONAL, IDENTITY.

Check for error with Matrix::isError(). : result' = inv( result ) : If inversion failed, then error bit is set within the Matrix.

Definition at line 642 of file MatrixOps.h.

   {
      if (src.mState == Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY )
         return result = src;
      else if (src.mState == Matrix<DATA_TYPE, ROWS, COLS>::TRANS)
         return invertTrans( result, src );
      else if (src.mState == Matrix<DATA_TYPE, ROWS, COLS>::ORTHOGONAL)
         return invertOrthogonal( result, src );
      else if (src.mState == Matrix<DATA_TYPE, ROWS, COLS>::AFFINE ||
               src.mState == (Matrix<DATA_TYPE, ROWS, COLS>::AFFINE | Matrix<DATA_TYPE, ROWS, COLS>::NON_UNISCALE))
         return invertAffine( result, src );
      else
         return invertFull_orig( result, src );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::invert ( Matrix< DATA_TYPE, ROWS, COLS > &  result  )  [inline]

smart matrix inversion (in place) Does matrix inversion by intelligently selecting what type of inversion to use depending on the types of operations your Matrix has been through.

5 types of inversion: FULL, AFFINE, ORTHONORMAL, ORTHOGONAL, IDENTITY.

Check for error with Matrix::isError(). : result' = inv( result ) : If inversion failed, then error bit is set within the Matrix.

Definition at line 668 of file MatrixOps.h.

   {
      return invert( result, result );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::invert ( Quat< DATA_TYPE > &  result  ) 

quaternion multiplicative inverse.

Postcondition:
self becomes the multiplicative inverse of self
1/q = q* / N(q)
See also:
Quat

Definition at line 390 of file QuatOps.h.

   {
      // from game programming gems p198
      // do result = conj( q ) / norm( q )
      conj( result );

      // return if norm() is near 0 (divide by 0 would result in NaN)
      DATA_TYPE l = lengthSquared( result );
      if (l < (DATA_TYPE)0.0001)
         return result;

      DATA_TYPE l_inv = ((DATA_TYPE)1.0) / l;
      result[Xelt] *= l_inv;
      result[Yelt] *= l_inv;
      result[Zelt] *= l_inv;
      result[Welt] *= l_inv;
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::invertAffine ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  source 
) [inline]

affine matrix inversion.

Matrix inversion that acts on a 4x3 affine matrix (matrix with only trans, rot, uniform scale) Check for error with Matrix::isError().

Precondition:
: 3x3, 4x3, 4x4 matrices only : result' = inv( result ) : If inversion failed, then error bit is set within the Matrix.

Definition at line 322 of file MatrixOps.h.

   {
      static const float eps = 0.00000001f;

      // in case &result is == &source... :(
      Matrix<DATA_TYPE, ROWS, COLS> src = source;

      // The rotational part of the matrix is simply the transpose of the
      // original matrix.
      for (int x = 0; x < 3; ++x)
      for (int y = 0; y < 3; ++y)
      {
         result[x][y] = src[y][x];
      }

      // do non-uniform scale inversion
      if (src.mState & Matrix<DATA_TYPE, ROWS, COLS>::NON_UNISCALE)
      {
         DATA_TYPE l0 = gmtl::lengthSquared( gmtl::Vec<DATA_TYPE, 3>( result[0][0], result[0][1], result[0][2] ) );
         DATA_TYPE l1 = gmtl::lengthSquared( gmtl::Vec<DATA_TYPE, 3>( result[1][0], result[1][1], result[1][2] ) );
         DATA_TYPE l2 = gmtl::lengthSquared( gmtl::Vec<DATA_TYPE, 3>( result[2][0], result[2][1], result[2][2] ) );
         if (gmtl::Math::abs( l0 ) > eps) l0 = 1.0f / l0;
         if (gmtl::Math::abs( l1 ) > eps) l1 = 1.0f / l1;
         if (gmtl::Math::abs( l2 ) > eps) l2 = 1.0f / l2;
         // apply the inverse scale to the 3x3
         // for each axis: normalize it (1/length), and then mult by inverse scale (1/length)
         result[0][0] *= l0;
         result[0][1] *= l0;
         result[0][2] *= l0;
         result[1][0] *= l1;
         result[1][1] *= l1;
         result[1][2] *= l1;
         result[2][0] *= l2;
         result[2][1] *= l2;
         result[2][2] *= l2;
      }

      // handle matrices with translation
      if (COLS == 4)
      {
         // The right column vector of the matrix should always be [ 0 0 0 s ]
         // this represents some shear values
         result[3][0] = result[3][1] = result[3][2] = 0;

         // The translation components of the original matrix.
         const DATA_TYPE& tx = src[0][3];
         const DATA_TYPE& ty = src[1][3];
         const DATA_TYPE& tz = src[2][3];


         // Rresult = -(Tm * Rm) to get the translation part of the inverse
         if (ROWS == 4)
         {
            // invert scale.
            const DATA_TYPE tw = (gmtl::Math::abs( src[3][3] ) > eps) ? 1.0f / src[3][3] : 0.0f;

            // handle uniform scale in Nx4 matrices
            result[0][3] = -( result[0][0] * tx + result[0][1] * ty + result[0][2] * tz ) * tw;
            result[1][3] = -( result[1][0] * tx + result[1][1] * ty + result[1][2] * tz ) * tw;
            result[2][3] = -( result[2][0] * tx + result[2][1] * ty + result[2][2] * tz ) * tw;
            result[3][3] = tw;
         }
         else if (ROWS == 3)
         {
            result[0][3] = -( result[0][0] * tx + result[0][1] * ty + result[0][2] * tz );
            result[1][3] = -( result[1][0] * tx + result[1][1] * ty + result[1][2] * tz );
            result[2][3] = -( result[2][0] * tx + result[2][1] * ty + result[2][2] * tz );
         }
      }



      result.mState = src.mState;

      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::invertFull ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  src 
) [inline]

Invert method.

Calls invertFull_orig to do the work.

Definition at line 626 of file MatrixOps.h.

   {
      return invertFull_orig(result,src);
   }

template<typename DATA_TYPE , unsigned SIZE>
Matrix<DATA_TYPE, SIZE, SIZE>& gmtl::invertFull_GJ ( Matrix< DATA_TYPE, SIZE, SIZE > &  result,
const Matrix< DATA_TYPE, SIZE, SIZE > &  src 
) [inline]

Full matrix inversion using Gauss-Jordan elimination.

Check for error with Matrix::isError(). : result' = inv( result ) : If inversion failed, then error bit is set within the Matrix.

Definition at line 406 of file MatrixOps.h.

   {
      //gmtlASSERT( ROWS == COLS && "invertFull only works with nxn matrices" );

      const DATA_TYPE pivot_eps(1e-20);         // Epsilon for the pivot value test (delta with test against zero)

      // Computer inverse of matrix using a Gaussian-Jordan elimination.
      // Uses max pivot at each point
      // See: "Essential Mathmatics for Games" for description

      // Do this invert in place
      result = src;
      unsigned swapped[SIZE];       // Track swaps. swapped[3] = 2 means that row 3 was swapped with row 2

      unsigned pivot;

      // --- Gaussian elimination step --- //
      // For each column and row
      for(pivot=0; pivot<SIZE;++pivot)
      {
         unsigned    pivot_row(pivot);
         DATA_TYPE   pivot_value(gmtl::Math::abs(result(pivot_row, pivot)));    // Initialize to beginning of current row

         // find pivot row - (max pivot element)
         for(unsigned pr=pivot+1;pr<SIZE;++pr)
         {
            const DATA_TYPE cur_val(gmtl::Math::abs(result(pr,pivot)));   // get value at current point
            if (cur_val > pivot_value)
            {
               pivot_row = pr;
               pivot_value = cur_val;
            }
         }

         if(gmtl::Math::isEqual(DATA_TYPE(0),pivot_value,pivot_eps))
         {
            std::cerr << "*** pivot = " << pivot_value << " in mat_inv. ***\n";
            result.setError();
            return result;
         }

         // Check for swap of pivot rows
         swapped[pivot] = pivot_row;
         if(pivot_row != pivot)
         {
            for(unsigned c=0;c<SIZE;++c)
            {  std::swap(result(pivot,c), result(pivot_row,c)); }
         }
         // ASSERT: row to use in now in "row" (check that row starts with max pivot value found)
         gmtlASSERT(gmtl::Math::isEqual(pivot_value,gmtl::Math::abs(result(pivot,pivot)),DATA_TYPE(0.00001)));

         // Compute pivot factor
         const DATA_TYPE mult_factor(1.0f/pivot_value);

         // Set pivot row values
         for(unsigned c=0;c<SIZE;++c)
         {  result(pivot,c) *= mult_factor; }
         result(pivot,pivot) = mult_factor;    // Copy the 1/pivot since we are inverting in place

         // Clear pivot column in other rows (since we are in place)
         // - Subtract current row times result(r,col) so that column element becomes 0
         for(unsigned row=0;row<SIZE;++row)
         {
            if(row==pivot)     // Don't subtract from our row
            { continue; }

            const DATA_TYPE sub_mult_factor(result(row,pivot));

            // Clear the pivot column's element (for invers in place)
            // ends up being set to -sub_mult_factor*pivotInverse
            result(row,pivot) = 0;

            // subtract the pivot row from this row
            for(unsigned col=0;col<SIZE;++col)
            {   result(row,col) -= (sub_mult_factor*result(pivot,col)); }
         }
      } // end: gaussian substitution


      // Now undo the swaps in column direction in reverse order
      unsigned p(SIZE);
      do
      {
         --p;
         gmtlASSERT(p<SIZE);

         // If row was swapped
         if(swapped[p] != p)
         {
            // Swap the column with same index
            for(unsigned r=0; r<SIZE; ++r)
            { std::swap(result(r, p), result(r, swapped[p])); }
         }
      }
      while(p>0);

      return result;
   }

template<typename DATA_TYPE , unsigned SIZE>
Matrix<DATA_TYPE, SIZE, SIZE>& gmtl::invertFull_orig ( Matrix< DATA_TYPE, SIZE, SIZE > &  result,
const Matrix< DATA_TYPE, SIZE, SIZE > &  src 
) [inline]

full matrix inversion.

Check for error with Matrix::isError(). : result' = inv( result ) : If inversion failed, then error bit is set within the Matrix.

Definition at line 512 of file MatrixOps.h.

   {
      /*---------------------------------------------------------------------------*
       | mat_inv: Compute the inverse of a n x n matrix, using the maximum pivot   |
       |          strategy.  n <= MAX1.                                            |
       *---------------------------------------------------------------------------*

         Parameters:
             a        a n x n square matrix
             b        inverse of input a.
             n        dimenstion of matrix a.
      */

      const DATA_TYPE* a = src.getData();
      DATA_TYPE* b = result.mData;

      int   n(SIZE);
      int    i, j, k;
      int    r[SIZE], c[SIZE], row[SIZE], col[SIZE];
      DATA_TYPE  m[SIZE][SIZE*2], pivot, max_m, tmp_m, fac;

      /* Initialization */
      for ( i = 0; i < n; i ++ )
      {
         r[ i] = c[ i] = 0;
         row[ i] = col[ i] = 0;
      }

      /* Set working matrix */
      for ( i = 0; i < n; i++ )
      {
         for ( j = 0; j < n; j++ )
         {
            m[ i][ j] = a[ i * n + j];
            m[ i][ j + n] = ( i == j ) ? (DATA_TYPE)1.0 : (DATA_TYPE)0.0 ;
         }
      }

      /* Begin of loop */
      for ( k = 0; k < n; k++ )
      {
         /* Choosing the pivot */
         for ( i = 0, max_m = 0; i < n; i++ )
         {
            if ( row[ i]  )
               continue;
            for ( j = 0; j < n; j++ )
            {
               if ( col[ j] )
                  continue;
               tmp_m = gmtl::Math::abs( m[ i][ j]);
               if ( tmp_m > max_m)
               {
                  max_m = tmp_m;
                  r[ k] = i;
                  c[ k] = j;
               }
            }
         }
         row[ r[k] ] = col[ c[k] ] = 1;
         pivot = m[ r[ k] ][ c[ k] ];


         if ( gmtl::Math::abs( pivot) <= 1e-20)
         {
            std::cerr << "*** pivot = " << pivot << " in mat_inv. ***\n";
            result.setError();
            return result;
         }

         /* Normalization */
         for ( j = 0; j < 2*n; j++ )
         {
            if ( j == c[ k] )
               m[ r[ k]][ j] = (DATA_TYPE)1.0;
            else
               m[ r[ k]][ j] /= pivot;
         }

         /* Reduction */
         for ( i = 0; i < n; i++ )
         {
            if ( i == r[ k] )
               continue;

            for ( j=0, fac = m[ i][ c[k]]; j < 2*n; j++ )
            {
               if ( j == c[ k] )
                  m[ i][ j] = (DATA_TYPE)0.0;
               else
                  m[ i][ j] -= fac * m[ r[k]][ j];
            }
         }
      }

      /* Assign inverse to a matrix */
      for ( i = 0; i < n; i++ )
         for ( j = 0; j < n; j++ )
            row[ i] = ( c[ j] == i ) ? r[ j] : row[ i];

      for ( i = 0; i < n; i++ )
         for ( j = 0; j < n; j++ )
            b[ i * n +  j] = m[ row[ i]][ j + n];

      // It worked
      result.mState = src.mState;
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::invertOrthogonal ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  src 
) [inline]

orthogonal matrix inversion.

Matrix inversion that acts on a affine matrix (matrix with only trans, rot, uniform scale) Check for error with Matrix::isError().

Precondition:
: any size matrix
Postcondition:
: result' = inv( result )
: If inversion failed, then error bit is set within the Matrix.

Definition at line 293 of file MatrixOps.h.

   {
      // in case result is == source... :(
      Matrix<DATA_TYPE, ROWS, COLS> temp = src;

      // if 3x4, 2x3, etc...  can't transpose the last column
      const unsigned int size = Math::Min( ROWS, COLS );

      // p. 149 Numerical Analysis (second ed.)
      for (unsigned i = 0; i < size; ++i)
      {
         for (unsigned j = 0; j < size; ++j)
         {
            result( i, j ) = temp( j, i );
         }
      }
      result.mState = temp.mState;
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::invertTrans ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  src 
) [inline]

translational matrix inversion.

Matrix inversion that acts on a translational matrix (matrix with only translation) Check for error with Matrix::isError().

Precondition:
: 4x3, 4x4 matrices only
Postcondition:
: result' = inv( result )
: If inversion failed, then error bit is set within the Matrix.

Definition at line 271 of file MatrixOps.h.

   {
      gmtlASSERT( ROWS == COLS || COLS == ROWS+1 && "invertTrans supports NxN or Nx(N-1) matrices only" );

      if (&result != &src)
         result = src; // could optimise this a little more (skip the trans copy), favor simplicity for now...
      for (unsigned x = 0; x < (ROWS-1+(COLS-ROWS)); ++x)
      {
         result[x][3] = -result[x][3];
      }
      return result;
   }

template<class DATA_TYPE >
bool gmtl::isEqual ( const AxisAngle< DATA_TYPE > &  a1,
const AxisAngle< DATA_TYPE > &  a2,
const DATA_TYPE  eps = 0 
) [inline]

Compares a1 and a2 to see if they are the same within the given epsilon tolerance.

Precondition:
eps must be >= 0
Parameters:
a1 the first vector
a2 the second vector
eps the epsilon tolerance value
Returns:
true if a1 equals a2 within tolerance; false if they differ

Definition at line 67 of file AxisAngleOps.h.

{
   gmtlASSERT( eps >= (DATA_TYPE)0 );
   
   // @todo metaprogramming.
   if (!Math::isEqual( a1[0], a2[0], eps )) return false;
   if (!Math::isEqual( a1[1], a2[1], eps )) return false;
   if (!Math::isEqual( a1[2], a2[2], eps )) return false;
   if (!Math::isEqual( a1[3], a2[3], eps )) return false;
   return true;
}

template<class DATA_TYPE , typename ROT_ORDER >
bool gmtl::isEqual ( const EulerAngle< DATA_TYPE, ROT_ORDER > &  e1,
const EulerAngle< DATA_TYPE, ROT_ORDER > &  e2,
const DATA_TYPE  eps = 0 
) [inline]

Compares e1 and e2 (component-wise) to see if they are the same within a given tolerance.

Precondition:
eps must be >= 0
Parameters:
e1 the first EulerAngle
e2 the second EulerAngle
eps the epsilon tolerance value, in radians
Returns:
true if e1 is within the tolerance of e2; false if not

Definition at line 66 of file EulerAngleOps.h.

{
   gmtlASSERT(eps >= (DATA_TYPE)0);
   
   // @todo metaprogramming.
   if (!Math::isEqual( e1[0], e2[0], eps )) return false;
   if (!Math::isEqual( e1[1], e2[1], eps )) return false;
   if (!Math::isEqual( e1[2], e2[2], eps )) return false;
   return true;
}

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
bool gmtl::isEqual ( const Matrix< DATA_TYPE, ROWS, COLS > &  lhs,
const Matrix< DATA_TYPE, ROWS, COLS > &  rhs,
const DATA_TYPE  eps = 0 
) [inline]

Tests 2 matrices for equality within a tolerance.

Parameters:
lhs The first matrix
rhs The second matrix
eps The tolerance value
Precondition:
Both matrices must be of the same size.
Returns:
true if the matrices' elements are within the tolerance value of each other; false otherwise

Definition at line 726 of file MatrixOps.h.

   {
      gmtlASSERT( eps >= (DATA_TYPE)0 );

      for (unsigned int i = 0; i < ROWS*COLS; ++i)
      {
         if (!Math::isEqual( lhs.mData[i], rhs.mData[i], eps ))
            return false;
      }
      return true;
   }

template<class DATA_TYPE >
bool gmtl::isEqual ( const Plane< DATA_TYPE > &  p1,
const Plane< DATA_TYPE > &  p2,
const DATA_TYPE &  eps 
) [inline]

Compare two planes to see if they are the same within the given tolerance.

Parameters:
p1 the first plane to compare
p2 the second plane to compare
eps the tolerance value to use
Precondition:
eps must be >= 0
Returns:
true if they are equal within a tolerance, false otherwise

Definition at line 171 of file PlaneOps.h.

{
   gmtlASSERT( eps >= 0 );
   return ( (isEqual(p1.mNorm, p2.mNorm, eps)) &&
            (Math::isEqual(p1.mOffset, p2.mOffset, eps)) );
}

template<class DATA_TYPE >
bool gmtl::isEqual ( const AABox< DATA_TYPE > &  b1,
const AABox< DATA_TYPE > &  b2,
const DATA_TYPE &  eps 
) [inline]

Compare two AABoxes to see if they are the same within the given tolerance.

Parameters:
b1 the first box to compare
b2 the second box to compare
eps the tolerance value to use
Precondition:
eps must be >= 0
Returns:
true if their points are within the given tolerance of each other, false otherwise

Definition at line 64 of file AABoxOps.h.

{
   gmtlASSERT( eps >= 0 );
   return (b1.isEmpty() == b2.isEmpty()) &&
          isEqual( b1.getMin(), b2.getMin(), eps ) &&
          isEqual( b1.getMax(), b2.getMax(), eps );
}

template<typename DATA_TYPE >
bool gmtl::isEqual ( const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2,
DATA_TYPE  tol = 0.0 
)

Compare two quaternions for equality with tolerance.

Definition at line 619 of file QuatOps.h.

   {
      return bool( Math::isEqual( q1[0], q2[0], tol ) &&
                   Math::isEqual( q1[1], q2[1], tol ) &&
                   Math::isEqual( q1[2], q2[2], tol ) &&
                   Math::isEqual( q1[3], q2[3], tol )    );
   }

template<class DATA_TYPE >
bool gmtl::isEqual ( const Ray< DATA_TYPE > &  ls1,
const Ray< DATA_TYPE > &  ls2,
const DATA_TYPE &  eps 
) [inline]

Compare two line segments to see if the are the same within the given tolerance.

Parameters:
ls1 the first Ray to compare
ls2 the second Ray to compare
eps the tolerance value to use
Precondition:
eps must be >= 0
Returns:
true if they are equal within the tolerance, false otherwise

Definition at line 56 of file RayOps.h.

{
   gmtlASSERT( eps >= 0 );
   return ( (isEqual(ls1.mOrigin, ls2.mOrigin, eps)) &&
            (isEqual(ls1.mDir, ls2.mDir, eps)) );
}

template<class DATA_TYPE >
bool gmtl::isEqual ( const Sphere< DATA_TYPE > &  s1,
const Sphere< DATA_TYPE > &  s2,
const DATA_TYPE &  eps 
) [inline]

Compare two spheres to see if they are the same within the given tolerance.

Parameters:
s1 the first sphere to compare
s2 the second sphere to compare
eps the tolerance value to use
Precondition:
eps must be >= 0
Returns:
true if they are equal within a tolerance, false otherwise

Definition at line 61 of file SphereOps.h.

{
   gmtlASSERT( eps >= 0 );
   return ( (isEqual(s1.mCenter, s2.mCenter, eps)) &&
            (Math::isEqual(s1.mRadius, s2.mRadius, eps)) );
}

template<class DATA_TYPE >
bool gmtl::isEqual ( const Tri< DATA_TYPE > &  tri1,
const Tri< DATA_TYPE > &  tri2,
const DATA_TYPE &  eps 
)

Compare two triangles to see if they are the same within the given tolerance.

Parameters:
tri1 the first triangle to compare
tri2 the second triangle to compare
eps the tolerance value to use
Precondition:
eps must be >= 0
Returns:
true if they are equal within the tolerance, false otherwise

Definition at line 97 of file TriOps.h.

{
   gmtlASSERT( eps >= 0 );
   return ( isEqual(tri1[0], tri2[0], eps) &&
            isEqual(tri1[1], tri2[1], eps) &&
            isEqual(tri1[2], tri2[2], eps) );
}

template<typename POS_TYPE , typename ROT_TYPE >
bool gmtl::isEqual ( const Coord< POS_TYPE, ROT_TYPE > &  c1,
const Coord< POS_TYPE, ROT_TYPE > &  c2,
typename Coord< POS_TYPE, ROT_TYPE >::DataType  tol = 0 
) [inline]

Compare two coordinate frames for equality with a given tolerance.

Parameters:
c1 the first Coord
c2 the second Coord
tol the tolerance coordinate frame of the same type as c1 and c2
Returns:
true if c1 is equal within a tolerance of c2, false otherwise

Definition at line 50 of file CoordOps.h.

   {
      return bool( isEqual( c1.getPos(), c2.getPos(), tol ) &&
                   isEqual( c1.getRot(), c2.getRot(), tol )     );
   }

template<class DATA_TYPE , unsigned SIZE>
bool gmtl::isEqual ( const VecBase< DATA_TYPE, SIZE > &  v1,
const VecBase< DATA_TYPE, SIZE > &  v2,
const DATA_TYPE  eps 
) [inline]

Compares v1 and v2 to see if they are the same within the given epsilon tolerance.

Precondition:
eps must be >= 0
Parameters:
v1 the first vector
v2 the second vector
eps the epsilon tolerance value
Returns:
true if v1 equals v2 within the tolerance; false if they differ

Definition at line 603 of file VecOps.h.

{
   gmtlASSERT(eps >= 0);

   for(unsigned i=0;i<SIZE;++i)
   {
      if ( gmtl::Math::abs(v1[i] - v2[i]) > eps )
      {
         return false;
      }
   }
   return true;
}

template<typename DATA_TYPE >
bool gmtl::isEquiv ( const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2,
DATA_TYPE  tol = 0.0 
)

Compare two quaternions for geometric equivelence (with tolerance).

there exist 2 quats for every possible rotation: the original, and its negative. the negative of a rotation quaternion is geometrically equivelent to the original.

Definition at line 633 of file QuatOps.h.

   {
      return bool( isEqual( q1, q2, tol ) || isEqual( q1, -q2, tol ) );
   }

template<class DATA_TYPE >
bool gmtl::isInVolume ( const AABox< DATA_TYPE > &  container,
const Point< DATA_TYPE, 3 > &  pt 
)

Tests if the given point is inside (or on) the surface of the given AABox volume.

Parameters:
container the AABox to test against
pt the point to test with
Returns:
true if pt is inside container, false otherwise

Definition at line 305 of file Containment.h.

{
   if (! container.isEmpty())
   {
      return ( pt[0] >= container.mMin[0] &&
               pt[1] >= container.mMin[1] &&
               pt[2] >= container.mMin[2] &&
               pt[0] <= container.mMax[0] &&
               pt[1] <= container.mMax[1] &&
               pt[2] <= container.mMax[2]);
   }
   else
   {
      return false;
   }
}

template<class DATA_TYPE >
bool gmtl::isInVolume ( const AABox< DATA_TYPE > &  container,
const AABox< DATA_TYPE > &  box 
)

Tests if the given AABox is completely inside or on the surface of the given AABox container.

Parameters:
container the AABox acting as the container
box the AABox that may be inside container
Returns:
true if AABox is inside container, false otherwise

Definition at line 365 of file Containment.h.

{
   // Empty boxes don't overlap
   if (container.isEmpty() || box.isEmpty())
   {
      return false;
   }
 
   if (container.mMin[0] <= box.mMin[0] && container.mMax[0] >= box.mMax[0] &&
       container.mMin[1] <= box.mMin[1] && container.mMax[1] >= box.mMax[1] &&
       container.mMin[2] <= box.mMin[2] && container.mMax[2] >= box.mMax[2])
   {
      return true;
   }
   else
   {
      return false;
   }
}

template<class DATA_TYPE >
bool gmtl::isInVolume ( const Sphere< DATA_TYPE > &  container,
const Point< DATA_TYPE, 3 > &  pt 
)

Tests if the given point is inside or on the surface of the given spherical volume.

Parameters:
container the sphere to test against
pt the point to test with
Returns:
true if pt is inside container, false otherwise

Definition at line 41 of file Containment.h.

{
   // The point is inside the sphere if the vector computed from the center of
   // the sphere to the point has a magnitude less than or equal to the radius
   // of the sphere.
   // |pt - center| <= radius
   return ( length(gmtl::Vec<DATA_TYPE,3>(pt - container.mCenter)) <= container.mRadius );
}

template<class DATA_TYPE >
bool gmtl::isInVolume ( const Sphere< DATA_TYPE > &  container,
const Sphere< DATA_TYPE > &  sphere 
)

Tests if the given sphere is completely inside or on the surface of the given spherical volume.

Parameters:
container the sphere acting as the container
sphere the sphere that may be inside container
Returns:
true if sphere is inside container, false otherwise

Definition at line 61 of file Containment.h.

{
   // the sphere is inside container if the distance between the centers of the
   // spheres plus the radius of the inner sphere is less than or equal to the
   // radius of the containing sphere.
   // |sphere.center - container.center| + sphere.radius <= container.radius
   return ( length(gmtl::Vec<DATA_TYPE,3>(sphere.mCenter - container.mCenter)) + sphere.mRadius
            <= container.mRadius );
}

template<typename T >
bool gmtl::isInVolume ( const Frustum< T > &  f,
const Point< T, 3 > &  p,
unsigned int &  idx 
) [inline]

Definition at line 495 of file Containment.h.

{
   for ( unsigned int i = 0; i < 6; ++i )
   {
      T dist = dot(f.mPlanes[i].mNorm, static_cast< Vec<T, 3> >(p)) + f.mPlanes[i].mOffset;
      if (dist < T(0.0) )
      {
         idx = i;
         return false;
      }
   }
     
   idx = IN_FRONT_OF_ALL_PLANES;
   return true;
}

template<typename T >
bool gmtl::isInVolume ( const Frustum< T > &  f,
const Sphere< T > &  s 
) [inline]

Definition at line 513 of file Containment.h.

{
   for ( unsigned int i = 0; i < 6; ++i )
   {
      T dist = dot(f.mPlanes[i].mNorm, static_cast< Vec<T, 3> >(s.getCenter())) + f.mPlanes[i].mOffset;
      if ( dist <= -T(s.getRadius()) )
      {
         return false;
      }
   }

   return true;
}

template<typename T >
bool gmtl::isInVolume ( const Frustum< T > &  f,
const Tri< T > &  tri 
) [inline]

Definition at line 565 of file Containment.h.

{
   unsigned int junk;

   if ( isInVolume(f, tri[0], junk) )
   {
      return true;
   }

   if ( isInVolume(f, tri[1], junk) )
   {
      return true;
   }

   if ( isInVolume(f, tri[2], junk) )
   {
      return true;
   }

   return false;
}

template<typename T >
bool gmtl::isInVolume ( const Frustum< T > &  f,
const AABox< T > &  box 
) [inline]

Definition at line 528 of file Containment.h.

{
   const Point<T, 3>& min = box.getMin();
   const Point<T, 3>& max = box.getMax();
   Point<T, 3> p[8];
   p[0] = min;
   p[1] = max;
   p[2] = Point<T, 3>(max[0], min[1], min[2]);
   p[3] = Point<T, 3>(min[0], max[1], min[2]);
   p[4] = Point<T, 3>(min[0], min[1], max[2]);
   p[5] = Point<T, 3>(max[0], max[1], min[2]);
   p[6] = Point<T, 3>(min[0], max[1], max[2]);
   p[7] = Point<T, 3>(max[0], min[1], max[2]);

   unsigned int idx = 6;

   if ( isInVolume(f, p[0], idx) )
   {
      return true;
   }

   // now we have the index of the seperating plane int idx, so check if all
   // other points lie on the backside of this plane too

   for ( unsigned int i = 1; i < 8; ++i )
   {
      T dist = dot(f.mPlanes[idx].mNorm, static_cast< Vec<T, 3> >(p[i])) + f.mPlanes[idx].mOffset;      
      if ( dist > T(0.0) )
      {
         return true;
      }
   }
      
   return false;
}

template<class DATA_TYPE >
bool gmtl::isInVolumeExclusive ( const AABox< DATA_TYPE > &  container,
const Point< DATA_TYPE, 3 > &  pt 
)

Tests if the given point is inside (not on) the surface of the given AABox volume.

This method is "exclusive" because it does not consider the surface to be a part of the space.

Parameters:
container the AABox to test against
pt the point to test with
Returns:
true if pt is inside container (but not on surface), false otherwise

Definition at line 334 of file Containment.h.

{
   if (! container.isEmpty())
   {
      return ( pt[0] > container.mMin[0] &&
               pt[1] > container.mMin[1] &&
               pt[2] > container.mMin[2] &&
               pt[0] < container.mMax[0] &&
               pt[1] < container.mMax[1] &&
               pt[2] < container.mMax[2]);
   }
   else
   {
      return false;
   }
}

template<typename DATA_TYPE >
bool gmtl::isNormalized ( const Quat< DATA_TYPE > &  q1,
const DATA_TYPE  eps = 0.0001f 
)

Determines if the given quaternion is normalized within the given tolerance.

The quaternion is normalized if its lengthSquared is 1.

Parameters:
q1 the quaternion to test
eps the epsilon tolerance
Returns:
true if the quaternion is normalized, false otherwise

Definition at line 364 of file QuatOps.h.

   {
      return Math::isEqual( lengthSquared( q1 ), DATA_TYPE(1), eps );
   }

template<class DATA_TYPE , unsigned SIZE>
bool gmtl::isNormalized ( const Vec< DATA_TYPE, SIZE > &  v1,
const DATA_TYPE  eps = (DATA_TYPE) 0.0001f 
)

Determines if the given vector is normalized within the given tolerance.

The vector is normalized if its lengthSquared is 1.

Parameters:
v1 the vector to test
eps the epsilon tolerance
Returns:
true if the vector is normalized, false otherwise

Definition at line 438 of file VecOps.h.

{
   return Math::isEqual( lengthSquared( v1 ), DATA_TYPE(1.0), eps );
}

template<class DATA_TYPE >
bool gmtl::isOnVolume ( const Sphere< DATA_TYPE > &  container,
const Point< DATA_TYPE, 3 > &  pt 
)

Modifies the given sphere to tightly enclose all spheres in the given std::vector.

This operation is O(n) and uses sqrt(..) liberally. :(

Parameters:
container [out] the sphere that will be modified to tightly enclose all the spheres in spheres
spheres [in] the list of spheres to contain
Precondition:
spheres must contain at least 2 points Tests if the given point is on the surface of the container with zero tolerance.
Parameters:
container the container to test against
pt the test point
Returns:
true if pt is on the surface of container, false otherwise

Definition at line 262 of file Containment.h.

{
   // |center - pt| - radius == 0
   return ( length(gmtl::Vec<DATA_TYPE,3>(container.mCenter - pt)) - container.mRadius == 0 );
}

template<class DATA_TYPE >
bool gmtl::isOnVolume ( const Sphere< DATA_TYPE > &  container,
const Point< DATA_TYPE, 3 > &  pt,
const DATA_TYPE &  tol 
)

Tests of the given point is on the surface of the container with the given tolerance.

Parameters:
container the container to test against
pt the test point
tol the epsilon tolerance
Returns:
true if pt is on the surface of container, false otherwise

Definition at line 280 of file Containment.h.

{
   gmtlASSERT( tol >= 0 && "tolerance must be positive" );

   // abs( |center-pt| - radius ) < tol
   return ( Math::abs( length( gmtl::Vec<DATA_TYPE,3>(container.mCenter - pt)) - container.mRadius )
            <= tol );
}

template<typename DATA_TYPE >
DATA_TYPE gmtl::length ( const Quat< DATA_TYPE > &  q  ) 

quaternion "absolute" (also known as vector length or magnitude) using this can be faster than using length for some operations...

Postcondition:
returns the magnitude of the 4D vector.
result = sqrt( lengthSquared( q ) )
See also:
Quat

Definition at line 326 of file QuatOps.h.

   {
      return Math::sqrt( lengthSquared( q ) );
   }

template<class DATA_TYPE , unsigned SIZE>
DATA_TYPE gmtl::length ( const Vec< DATA_TYPE, SIZE > &  v1  ) 

Computes the length of the given vector.

Parameters:
v1 the vector with which to compute the length
Returns:
the length of v1

Definition at line 367 of file VecOps.h.

{
   DATA_TYPE ret_val = lengthSquared(v1);
   if (ret_val == DATA_TYPE(0.0f))
      return DATA_TYPE(0.0f);
   else
      return Math::sqrt(ret_val);
}

template<class DATA_TYPE , unsigned SIZE>
DATA_TYPE gmtl::lengthSquared ( const Vec< DATA_TYPE, SIZE > &  v1  ) 

Computes the square of the length of the given vector.

This can be used in many calculations instead of length to increase speed by saving you an expensive sqrt call.

Parameters:
v1 the vector with which to compute the squared length
Returns:
the square of the length of v1

Definition at line 386 of file VecOps.h.

{
#ifdef GMTL_NO_METAPROG
   DATA_TYPE ret_val(0);
   for(unsigned i=0;i<SIZE;++i)
   {
      ret_val += (v1[i] * v1[i]);
   }

   return ret_val;
#else
   return gmtl::meta::LenSqrVecUnrolled<SIZE-1,Vec<DATA_TYPE,SIZE> >::func(v1);
#endif
}

template<typename DATA_TYPE >
DATA_TYPE gmtl::lengthSquared ( const Quat< DATA_TYPE > &  q  ) 

quaternion "norm" (also known as vector length squared) using this can be faster than using length for some operations...

Postcondition:
returns the vector length squared
N(q) = x^2 + y^2 + z^2 + w^2
result = x*x + y*y + z*z + w*w
See also:
Quat

Definition at line 314 of file QuatOps.h.

   {
      return dot( q, q );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::lerp ( Quat< DATA_TYPE > &  result,
const DATA_TYPE  t,
const Quat< DATA_TYPE > &  from,
const Quat< DATA_TYPE > &  to 
)

linear interpolation between two quaternions.

t is a value between 0 and 1 that interpolates between from and to.

Precondition:
no aliasing problems to worry about ("result" can be "from" or "to" param). References:
  • From Adv Anim and Rendering Tech. Pg 364
See also:
Quat

Definition at line 554 of file QuatOps.h.

   {
      // just an alias to match q
      const Quat<DATA_TYPE>& p = from;

      // calc cosine theta
      DATA_TYPE cosom = dot( from, to );

      // adjust signs (if necessary)
      Quat<DATA_TYPE> q;
      if (cosom < (DATA_TYPE)0.0)
      {
         q[0] = -to[0];   // Reverse all signs
         q[1] = -to[1];
         q[2] = -to[2];
         q[3] = -to[3];
      }
      else
      {
         q = to;
      }

      // do linear interp
      DATA_TYPE sclp, sclq;
      sclp = (DATA_TYPE)1.0 - t;
      sclq = t;

      result[Xelt] = sclp * p[Xelt] + sclq * q[Xelt];
      result[Yelt] = sclp * p[Yelt] + sclq * q[Yelt];
      result[Zelt] = sclp * p[Zelt] + sclq * q[Zelt];
      result[Welt] = sclp * p[Welt] + sclq * q[Welt];
      return result;
   }

template<typename DATA_TYPE , unsigned SIZE>
VecBase<DATA_TYPE, SIZE>& gmtl::lerp ( VecBase< DATA_TYPE, SIZE > &  result,
const DATA_TYPE &  lerpVal,
const VecBase< DATA_TYPE, SIZE > &  from,
const VecBase< DATA_TYPE, SIZE > &  to 
)

Linearly interpolates between to vectors.

Precondition:
lerpVal is a value between 0 and 1 that interpolates between from and to.
Postcondition:
undefined if lerpVal < 0 or lerpVal > 1
Parameters:
result the result of the linear interpolation
lerpVal the value to interpolate between from and to
from the vector at lerpVal 0
to the vector at lerpVal 1
Returns:
a reference to result for convenience

Todo:
metaprogramming...

Definition at line 520 of file VecOps.h.

{
   for (unsigned int x = 0; x < SIZE; ++x)
   {
      Math::lerp( result[x], lerpVal, from[x], to[x] );
   }
   return result;
}

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::log ( Quat< DATA_TYPE > &  result  ) 

complex logarithm

Postcondition:
sets self to the log of quat
See also:
Quat

Definition at line 440 of file QuatOps.h.

   {
      DATA_TYPE length;

      length = Math::sqrt( result[Xelt] * result[Xelt] +
                           result[Yelt] * result[Yelt] +
                           result[Zelt] * result[Zelt] );

      // avoid divide by 0
      if (Math::isEqual( result[Welt], (DATA_TYPE)0.0, (DATA_TYPE)0.00001 ) == false)
         length = Math::aTan( length / result[Welt] );
      else
         length = Math::PI_OVER_2;

      result[Welt] = (DATA_TYPE)0.0;
      result[Xelt] = result[Xelt] * length;
      result[Yelt] = result[Yelt] * length;
      result[Zelt] = result[Zelt] * length;
      return result;
   }

template<typename TARGET_TYPE , typename SOURCE_TYPE >
TARGET_TYPE gmtl::make ( const SOURCE_TYPE &  src,
Type2Type< TARGET_TYPE >  t = Type2Type< TARGET_TYPE >() 
) [inline]

Construct an object from another object of a different type.

This allows us to automatically convert from any type to any other type.

Precondition:
must have a set() function defined that converts between the two types.
Parameters:
src the object to use for creation
Returns:
a new object with values based on the src variable
See also:
OpenSGGenerate.h for an example

Definition at line 1276 of file Generate.h.

   {
      gmtl::ignore_unused_variable_warning(t);
      TARGET_TYPE target;
      return gmtl::set( target, src );
   }

template<typename ROTATION_TYPE >
ROTATION_TYPE gmtl::makeAxes ( const Vec< typename ROTATION_TYPE::DataType, 3 > &  xAxis,
const Vec< typename ROTATION_TYPE::DataType, 3 > &  yAxis,
const Vec< typename ROTATION_TYPE::DataType, 3 > &  zAxis,
Type2Type< ROTATION_TYPE >  t = Type2Type< ROTATION_TYPE >() 
) [inline]

set the matrix given the raw coordinate axes.

Postcondition:
this function only produces 3x3, 3x4, 4x3, and 4x4 matrices, and is undefined otherwise
these axes are copied direct to the 3x3 in the matrix

Definition at line 1105 of file Generate.h.

   {
      gmtl::ignore_unused_variable_warning(t);
      ROTATION_TYPE temporary;
      return setAxes( temporary, xAxis, yAxis, zAxis );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Vec<DATA_TYPE, ROWS> gmtl::makeColumn ( const Matrix< DATA_TYPE, ROWS, COLS > &  src,
unsigned  col 
)

Accesses a particular column in the matrix by creating a new vector containing the values in the given matrix.

Parameters:
src the matrix being accessed
col the column of the matrix to access
Returns:
a vector containing the values in the requested column

Definition at line 1462 of file Generate.h.

   {
      Vec<DATA_TYPE, ROWS> result;
      setColumn(result, src, col);
      return result;
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::makeConj ( const Quat< DATA_TYPE > &  quat  )  [inline]

quaternion complex conjugate.

Parameters:
quat any quaternion object
Postcondition:
set result to the complex conjugate of result.
result'[x,y,z,w] == result[-x,-y,-z,w]
See also:
Quat

Definition at line 161 of file Generate.h.

   {
      Quat<DATA_TYPE> temporary( quat );
      return conj( temporary );
   }

template<class DATA_TYPE >
Vec<DATA_TYPE,3> gmtl::makeCross ( const Vec< DATA_TYPE, 3 > &  v1,
const Vec< DATA_TYPE, 3 > &  v2 
)

Computes the cross product between v1 and v2 and returns the result.

Note that this only applies to 3-dimensional vectors.

Precondition:
v1 and v2 must be 3-D vectors
Postcondition:
result = v1 x v2
Parameters:
v1 the first vector
v2 the second vector
Returns:
the result of the cross product between v1 and v2

Definition at line 64 of file Generate.h.

   {
      return Vec<DATA_TYPE,3>( ((v1[Yelt]*v2[Zelt]) - (v1[Zelt]*v2[Yelt])),
                               ((v1[Zelt]*v2[Xelt]) - (v1[Xelt]*v2[Zelt])),
                               ((v1[Xelt]*v2[Yelt]) - (v1[Yelt]*v2[Xelt])) );
   }

template<typename ROTATION_TYPE >
ROTATION_TYPE gmtl::makeDirCos ( const Vec< typename ROTATION_TYPE::DataType, 3 > &  xDestAxis,
const Vec< typename ROTATION_TYPE::DataType, 3 > &  yDestAxis,
const Vec< typename ROTATION_TYPE::DataType, 3 > &  zDestAxis,
const Vec< typename ROTATION_TYPE::DataType, 3 > &  xSrcAxis = Vec<typename ROTATION_TYPE::DataType, 3>(1,0,0),
const Vec< typename ROTATION_TYPE::DataType, 3 > &  ySrcAxis = Vec<typename ROTATION_TYPE::DataType, 3>(0,1,0),
const Vec< typename ROTATION_TYPE::DataType, 3 > &  zSrcAxis = Vec<typename ROTATION_TYPE::DataType, 3>(0,0,1),
Type2Type< ROTATION_TYPE >  t = Type2Type< ROTATION_TYPE >() 
) [inline]

Create a rotation matrix or quaternion (or any other rotation data type) using direction cosines.

If the two coordinate frames are labeled: SRC and TARGET, the matrix produced is: src_M_target this means that it will transform a point in TARGET to SRC but moves the base frame from SRC to TARGET.

Parameters:
DestAxis required to specify
SrcAxis optional to specify
Precondition:
specify 1 axis (3 vectors), or 2 axes (6 vectors).
Postcondition:
Creates a rotation from SrcAxis to DestAxis
this function only produces 3x3, 3x4, 4x3, and 4x4 matrices, and is undefined otherwise

Definition at line 1309 of file Generate.h.

   {
      gmtl::ignore_unused_variable_warning(t);
      ROTATION_TYPE temporary;
      return setDirCos( temporary, xDestAxis, yDestAxis, zDestAxis, xSrcAxis, ySrcAxis, zSrcAxis );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS> gmtl::makeInvert ( const Matrix< DATA_TYPE, ROWS, COLS > &  src  )  [inline]

Creates a matrix that is the inverse of the given source matrix.

Parameters:
src the matrix to compute the inverse of
Returns:
the inverse of source

Definition at line 1134 of file Generate.h.

   {
      Matrix<DATA_TYPE, ROWS, COLS> result;
      return invert( result, src );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::makeInvert ( const Quat< DATA_TYPE > &  quat  )  [inline]

create quaternion from the inverse of another quaternion.

Parameters:
quat any quaternion object
Returns:
a quaternion that is the multiplicative inverse of quat
See also:
Quat

Definition at line 173 of file Generate.h.

   {
      Quat<DATA_TYPE> temporary( quat );
      return invert( temporary );
   }

template<typename DATA_TYPE , unsigned SIZE>
Vec<DATA_TYPE, SIZE> gmtl::makeNormal ( Vec< DATA_TYPE, SIZE >  vec  )  [inline]

create a normalized vector from the given vector.

Definition at line 45 of file Generate.h.

   {
      normalize( vec );
      return vec;
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::makeNormal ( const Quat< DATA_TYPE > &  quat  )  [inline]

Normalize a quaternion.

Parameters:
quat a quaternion
Postcondition:
quat is normalized

Definition at line 148 of file Generate.h.

   {
      Quat<DATA_TYPE> temporary( quat );
      return normalize( temporary );
   }

template<typename DATA_TYPE >
AxisAngle<DATA_TYPE> gmtl::makeNormal ( const AxisAngle< DATA_TYPE > &  a  ) 

make the axis of an AxisAngle normalized

Definition at line 415 of file Generate.h.

   {
      return AxisAngle<DATA_TYPE>( a.getAngle(), makeNormal( a.getAxis() ) );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::makePure ( const Vec< DATA_TYPE, 3 > &  vec  )  [inline]

create a pure quaternion

Precondition:
vec should be normalized
Parameters:
vec a normalized vector representing an axis
Returns:
a quaternion with vec as its axis, and no rotation
Postcondition:
quat = [v,0] = [v0,v1,v2,0]

Definition at line 138 of file Generate.h.

   {
      return Quat<DATA_TYPE>( vec[0], vec[1], vec[2], 0 );
   }

template<typename ROTATION_TYPE , typename SOURCE_TYPE >
ROTATION_TYPE gmtl::makeRot ( const SOURCE_TYPE &  coord,
Type2Type< ROTATION_TYPE >  t = Type2Type< ROTATION_TYPE >() 
) [inline]

Create a rotation datatype from another rotation datatype.

Postcondition:
converts the source rotation to a to another type (usually Matrix, Quat, Euler, AxisAngle),
returns a temporary object.

Definition at line 1289 of file Generate.h.

   {
      gmtl::ignore_unused_variable_warning(t);
      ROTATION_TYPE temporary;
      return gmtl::set( temporary, coord );
   }

template<typename ROTATION_TYPE >
ROTATION_TYPE gmtl::makeRot ( const Vec< typename ROTATION_TYPE::DataType, 3 > &  from,
const Vec< typename ROTATION_TYPE::DataType, 3 > &  to 
) [inline]

Create a rotation datatype that will xform first vector to the second.

Precondition:
each vec needs to be normalized.
Postcondition:
This function returns a temporary object.

Definition at line 1351 of file Generate.h.

   {
      ROTATION_TYPE temporary;
      return setRot( temporary, from, to );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Vec<DATA_TYPE, COLS> gmtl::makeRow ( const Matrix< DATA_TYPE, ROWS, COLS > &  src,
unsigned  row 
)

Accesses a particular row in the matrix by creating a new vector containing the values in the given matrix.

Parameters:
src the matrix being accessed
row the row of the matrix to access
Returns:
a vector containing the values in the requested row

Definition at line 1430 of file Generate.h.

   {
      Vec<DATA_TYPE, COLS> result;
      setRow(result, src, row);
      return result;
   }

template<typename MATRIX_TYPE , typename INPUT_TYPE >
MATRIX_TYPE gmtl::makeScale ( const INPUT_TYPE &  scale,
Type2Type< MATRIX_TYPE >  t = Type2Type< MATRIX_TYPE >() 
) [inline]

Create a scale matrix.

Parameters:
scale You'll typically pass in a Vec or a float here. setScale() for all possible argument types for this function.

Definition at line 803 of file Generate.h.

   {
      gmtl::ignore_unused_variable_warning(t);
      MATRIX_TYPE temporary;
      return setScale( temporary, scale );
   }

template<typename TRANS_TYPE , typename SRC_TYPE >
TRANS_TYPE gmtl::makeTrans ( const SRC_TYPE &  arg,
Type2Type< TRANS_TYPE >  t = Type2Type< TRANS_TYPE >() 
) [inline]

Make a translation datatype from another translation datatype.

Typically this is from Matrix to Vec or Vec to Matrix. This function reads only translation information from the src datatype.

Parameters:
arg the matrix to extract the translation from
Precondition:
if making an n x n matrix, then for
  • vector is homogeneous: SIZE of vector needs to equal number of Matrix ROWS - 1
  • vector has scale component: SIZE of vector needs to equal number of Matrix ROWS
    if making an n x n+1 matrix, then for
  • vector is homogeneous: SIZE of vector needs to equal number of Matrix ROWS
  • vector has scale component: SIZE of vector needs to equal number of Matrix ROWS + 1
Postcondition:
if preconditions are not met, then function is undefined (will not compile)

Definition at line 1338 of file Generate.h.

   {
      gmtl::ignore_unused_variable_warning(t);
      TRANS_TYPE temporary;
      return setTrans( temporary, arg );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS> gmtl::makeTranspose ( const Matrix< DATA_TYPE, ROWS, COLS > &  m  )  [inline]

create a matrix transposed from the source.

Postcondition:
returns the transpose of m
See also:
Quat

Definition at line 1120 of file Generate.h.

   {
      Matrix<DATA_TYPE, ROWS, COLS> temporary( m );
      return transpose( temporary );
   }

template<typename DATA_TYPE >
Vec<DATA_TYPE, 3> gmtl::makeVec ( const Quat< DATA_TYPE > &  quat  )  [inline]

create a vector from the vector component of a quaternion

Returns:
a vector of the quaternion's axis. quat = [v,0] = [v0,v1,v2,0]

Definition at line 37 of file Generate.h.

   {
      return Vec<DATA_TYPE, 3>( quat[Xelt], quat[Yelt], quat[Zelt] );
   }

template<class DATA_TYPE >
void gmtl::makeVolume ( AABox< DATA_TYPE > &  box,
const Sphere< DATA_TYPE > &  sph 
)

Creates an AABox that tightly encloses the given Sphere.

Parameters:
box set to the box

Definition at line 470 of file Containment.h.

{
   const gmtl::Point<DATA_TYPE, 3>& center = sph.getCenter();
   const DATA_TYPE& radius = sph.getRadius();

   // Calculate the min and max points for the box
   gmtl::Point<DATA_TYPE, 3> min_pt(center[0] - radius,
                                    center[1] - radius,
                                    center[2] - radius);
   gmtl::Point<DATA_TYPE, 3> max_pt(center[0] + radius,
                                    center[1] + radius,
                                    center[2] + radius);

   box.setMin(min_pt);
   box.setMax(max_pt);
   box.setEmpty(radius == DATA_TYPE(0));
}

template<class DATA_TYPE >
void gmtl::makeVolume ( Sphere< DATA_TYPE > &  container,
const std::vector< Point< DATA_TYPE, 3 > > &  pts 
)

Modifies the given sphere to tightly enclose all points in the given std::vector.

This operation is O(n) and uses sqrt(..) liberally. :(

Parameters:
container [out] the sphere that will be modified to tightly enclose all the points in pts
pts [in] the list of points to contain
Precondition:
pts must contain at least 2 points

Definition at line 150 of file Containment.h.

{
   gmtlASSERT( pts.size() > 0  && "pts must contain at least 1 point" );

   // Implementation based on the Sphere Centered at Average of Points algorithm
   // found in "3D Game Engine Design" by Devud G, Eberly (pg. 27)
   typename std::vector< Point<DATA_TYPE, 3> >::const_iterator itr = pts.begin();

   // compute the average of the points as the center
   Point<DATA_TYPE, 3> sum = *itr;
   ++itr;
   while ( itr != pts.end() )
   {
      sum += *itr;
      ++itr;
   }
   container.mCenter = sum / static_cast<DATA_TYPE>(pts.size());

   // compute the distance from the computed center to point furthest from that
   // center as the radius
   DATA_TYPE radiusSqr(0);
   for ( itr = pts.begin(); itr != pts.end(); ++itr )
   {
      DATA_TYPE len = lengthSquared( gmtl::Vec<DATA_TYPE,3>( (*itr) - container.mCenter) );
      if ( len > radiusSqr )
         radiusSqr = len;
   }

   container.mRadius = Math::sqrt( radiusSqr );
}

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
DATA_TYPE gmtl::makeXRot ( const Matrix< DATA_TYPE, ROWS, COLS > &  mat  )  [inline]

Extracts the X-axis rotation information from the matrix.

Postcondition:
Returned value is from -PI to PI, where 0 is no rotation.

Definition at line 961 of file Generate.h.

   {
      const gmtl::Vec<DATA_TYPE, 3> forward_point(0.0f, 0.0f, -1.0f);   // -Z
      const gmtl::Vec<DATA_TYPE, 3> origin_point(0.0f, 0.0f, 0.0f);
      gmtl::Vec<DATA_TYPE, 3> end_point, start_point;

      gmtl::xform(end_point, mat, forward_point);
      gmtl::xform(start_point, mat, origin_point);
      gmtl::Vec<DATA_TYPE, 3> direction_vector = end_point - start_point;

      // Constrain the direction to YZ-plane only.
      direction_vector[0] = 0.0f;                  // Eliminate X value
      gmtl::normalize(direction_vector);
      DATA_TYPE x_rot = gmtl::Math::aCos(gmtl::dot(direction_vector,
                                                   forward_point));

      gmtl::Vec<DATA_TYPE, 3> which_side = gmtl::makeCross(forward_point,
                                                           direction_vector);

      // If direction vector to "bottom" (negative) side of forward
      if ( which_side[0] < 0.0f )
      {
         x_rot = -x_rot;
      }

      return x_rot;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
DATA_TYPE gmtl::makeYRot ( const Matrix< DATA_TYPE, ROWS, COLS > &  mat  )  [inline]

Extracts the Y axis rotation information from the matrix.

Postcondition:
Returned value is from -PI to PI, where 0 is none.

Definition at line 928 of file Generate.h.

   {
      const gmtl::Vec<DATA_TYPE, 3> forward_point(0.0f, 0.0f, -1.0f);   // -Z
      const gmtl::Vec<DATA_TYPE, 3> origin_point(0.0f, 0.0f, 0.0f);
      gmtl::Vec<DATA_TYPE, 3> end_point, start_point;

      gmtl::xform(end_point, mat, forward_point);
      gmtl::xform(start_point, mat, origin_point);
      gmtl::Vec<DATA_TYPE, 3> direction_vector = end_point - start_point;

      // Constrain the direction to XZ-plane only.
      direction_vector[1] = 0.0f;                  // Eliminate Y value
      gmtl::normalize(direction_vector);
      DATA_TYPE y_rot = gmtl::Math::aCos(gmtl::dot(direction_vector,
                                                   forward_point));

      gmtl::Vec<DATA_TYPE, 3> which_side = gmtl::makeCross(forward_point,
                                                           direction_vector);

      // If direction vector to "right" (negative) side of forward
      if ( which_side[1] < 0.0f )
      {
         y_rot = -y_rot;
      }

      return y_rot;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
DATA_TYPE gmtl::makeZRot ( const Matrix< DATA_TYPE, ROWS, COLS > &  mat  )  [inline]

Extracts the Z-axis rotation information from the matrix.

Postcondition:
Returned value is from -PI to PI, where 0 is no rotation.

Definition at line 994 of file Generate.h.

   {
      const gmtl::Vec<DATA_TYPE, 3> forward_point(1.0f, 0.0f, 0.0f);   // +x
      const gmtl::Vec<DATA_TYPE, 3> origin_point(0.0f, 0.0f, 0.0f);
      gmtl::Vec<DATA_TYPE, 3> end_point, start_point;

      gmtl::xform(end_point, mat, forward_point);
      gmtl::xform(start_point, mat, origin_point);
      gmtl::Vec<DATA_TYPE, 3> direction_vector = end_point - start_point;

      // Constrain the direction to XY-plane only.
      direction_vector[2] = 0.0f;                  // Eliminate Z value
      gmtl::normalize(direction_vector);
      DATA_TYPE z_rot = gmtl::Math::aCos(gmtl::dot(direction_vector,
                                                   forward_point));

      gmtl::Vec<DATA_TYPE, 3> which_side = gmtl::makeCross(forward_point,
                                                           direction_vector);

      // If direction vector to "right" (negative) side of forward
      if ( which_side[2] < 0.0f )
      {
         z_rot = -z_rot;
      }

      return z_rot;
   }

template<typename DATA_TYPE >
void gmtl::meanTangent ( Quat< DATA_TYPE > &  result,
const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2,
const Quat< DATA_TYPE > &  q3 
)

WARNING: not implemented (do not use).

Definition at line 470 of file QuatOps.h.

   {
       gmtlASSERT( false );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::mult ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  mat,
const DATA_TYPE &  scalar 
) [inline]

matrix scalar mult.

mult each elt in a matrix by a scalar value. : result = mat * scalar

Definition at line 196 of file MatrixOps.h.

   {
      for (unsigned i = 0; i < ROWS * COLS; ++i)
         result.mData[i] = mat.mData[i] * scalar;
      result.mState = mat.mState;
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::mult ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
DATA_TYPE  scalar 
) [inline]

matrix scalar mult.

mult each elt in a matrix by a scalar value. : result *= scalar

Definition at line 209 of file MatrixOps.h.

   {
      for (unsigned i = 0; i < ROWS * COLS; ++i)
         result.mData[i] *= scalar;
      return result;
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::mult ( Quat< DATA_TYPE > &  result,
const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
)

product of two quaternions (quaternion product) multiplication of quats is much like multiplication of typical complex numbers.

Postcondition:
q1q2 = (s1 + v1)(s2 + v2)
result = q1 * q2 (where q2 would be applied first to any xformed geometry)
See also:
Quat

Definition at line 26 of file QuatOps.h.

   {
      // Here is the easy to understand equation: (grassman product)
      // scalar_component = q1.s * q2.s - dot(q1.v, q2.v)
      // vector_component = q2.v * q1.s + q1.v * q2.s + cross(q1.v, q2.v)

      // Here is another version (euclidean product, just FYI)...
      // scalar_component = q1.s * q2.s + dot(q1.v, q2.v)
      // vector_component = q2.v * q1.s - q1.v * q2.s - cross(q1.v, q2.v)

      // Here it is, using vector algebra (grassman product)
      /*
      const float& w1( q1[Welt] ), w2( q2[Welt] );
      Vec3 v1( q1[Xelt], q1[Yelt], q1[Zelt] ), v2( q2[Xelt], q2[Yelt], q2[Zelt] );

      float w = w1 * w2 - v1.dot( v2 );
      Vec3 v = (w1 * v2) + (w2 * v1) + v1.cross( v2 );

      vec[Welt] = w;
      vec[Xelt] = v[0];
      vec[Yelt] = v[1];
      vec[Zelt] = v[2];
      */

      // Here is the same, only expanded... (grassman product)
      Quat<DATA_TYPE> temporary; // avoid aliasing problems...
      temporary[Xelt] = q1[Welt]*q2[Xelt] + q1[Xelt]*q2[Welt] + q1[Yelt]*q2[Zelt] - q1[Zelt]*q2[Yelt];
      temporary[Yelt] = q1[Welt]*q2[Yelt] + q1[Yelt]*q2[Welt] + q1[Zelt]*q2[Xelt] - q1[Xelt]*q2[Zelt];
      temporary[Zelt] = q1[Welt]*q2[Zelt] + q1[Zelt]*q2[Welt] + q1[Xelt]*q2[Yelt] - q1[Yelt]*q2[Xelt];
      temporary[Welt] = q1[Welt]*q2[Welt] - q1[Xelt]*q2[Xelt] - q1[Yelt]*q2[Yelt] - q1[Zelt]*q2[Zelt];

      // use a temporary, in case q1 or q2 is the same as self.
      result[Xelt] = temporary[Xelt];
      result[Yelt] = temporary[Yelt];
      result[Zelt] = temporary[Zelt];
      result[Welt] = temporary[Welt];

      // don't normalize, because it might not be rotation arithmetic we're doing
      // (only rotation quats have unit length)
      return result;
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::mult ( Quat< DATA_TYPE > &  result,
const Quat< DATA_TYPE > &  q,
DATA_TYPE  s 
)

vector scalar multiplication

Postcondition:
result' = [qx*s, qy*s, qz*s, qw*s]
See also:
Quat

Definition at line 127 of file QuatOps.h.

   {
      result[0] = q[0] * s;
      result[1] = q[1] * s;
      result[2] = q[2] * s;
      result[3] = q[3] * s;
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned INTERNAL, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::mult ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, INTERNAL > &  lhs,
const Matrix< DATA_TYPE, INTERNAL, COLS > &  rhs 
) [inline]

matrix multiply.

: With regard to size (ROWS/COLS): if lhs is m x p, and rhs is p x n, then result is m x n (mult func undefined otherwise) : returns a m x n sized matrix

Postcondition:
: result = lhs * rhs (where rhs is applied first)

Definition at line 80 of file MatrixOps.h.

   {
      Matrix<DATA_TYPE, ROWS, COLS> ret_mat; // prevent aliasing
      zero( ret_mat );

      // p. 150 Numerical Analysis (second ed.)
      // if A is m x p, and B is p x n, then AB is m x n
      // (AB)ij  =  [k = 1 to p] (a)ik (b)kj     (where:  1 <= i <= m, 1 <= j <= n)
      for (unsigned int i = 0; i < ROWS; ++i)           // 1 <= i <= m
      for (unsigned int j = 0; j < COLS; ++j)           // 1 <= j <= n
      for (unsigned int k = 0; k < INTERNAL; ++k)       // [k = 1 to p]
         ret_mat( i, j ) += lhs( i, k ) * rhs( k, j );

      // track state
      ret_mat.mState = combineMatrixStates( lhs.mState, rhs.mState );
      return result = ret_mat;
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::negate ( Quat< DATA_TYPE > &  result  ) 

Vector negation - negate each element in the quaternion vector.

the negative of a rotation quaternion is geometrically equivelent to the original. there exist 2 quats for every possible rotation.

Returns:
returns the negation of the given quat.

Definition at line 102 of file QuatOps.h.

   {
      result[0] = -result[0];
      result[1] = -result[1];
      result[2] = -result[2];
      result[3] = -result[3];
      return result;
   }

template<class DATA_TYPE >
Vec<DATA_TYPE, 3> gmtl::normal ( const Tri< DATA_TYPE > &  tri  ) 

Computes the normal for this triangle.

Parameters:
tri the triangle for which to compute the normal
Returns:
the normal vector for tri

Definition at line 42 of file TriOps.h.

{
   Vec<DATA_TYPE, 3> normal = makeCross( gmtl::Vec<DATA_TYPE,3>(tri[1] - tri[0]), gmtl::Vec<DATA_TYPE,3>(tri[2] - tri[0]) );
   normalize( normal );
   return normal;
}

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::normalize ( Quat< DATA_TYPE > &  result  ) 

set self to the normalized quaternion of self.

Precondition:
magnitude should be > 0, otherwise no calculation is done.
Postcondition:
result' = normalize( result ), where normalize makes length( result ) == 1
See also:
Quat

Definition at line 337 of file QuatOps.h.

   {
      DATA_TYPE l = length( result );

      // return if no magnitude (already as normalized as possible)
      if (l < (DATA_TYPE)0.0001)
         return result;

      DATA_TYPE l_inv = ((DATA_TYPE)1.0) / l;
      result[Xelt] *= l_inv;
      result[Yelt] *= l_inv;
      result[Zelt] *= l_inv;
      result[Welt] *= l_inv;

      return result;
   }

template<class DATA_TYPE , unsigned SIZE>
DATA_TYPE gmtl::normalize ( Vec< DATA_TYPE, SIZE > &  v1  ) 

Normalizes the given vector in place causing it to be of unit length.

If the vector is already of length 1.0, nothing is done. For convenience, the original length of the vector is returned.

Postcondition:
length(v1) == 1.0 unless length(v1) is originally 0.0, in which case it is unchanged
Parameters:
v1 the vector to normalize
Returns:
the length of v1 before it was normalized

Definition at line 413 of file VecOps.h.

{
   DATA_TYPE len = length(v1);

   if(len != 0.0f)
   {
      for(unsigned i=0;i<SIZE;++i)
      {
         v1[i] /= len;
      }
   }

   return len;
}

template<class DATA_TYPE >
void gmtl::normalize ( Frustum< DATA_TYPE > &  f  ) 

Definition at line 18 of file FrustumOps.h.

{
   for ( unsigned int i = 0; i < 6; ++i )
   {
      Vec<DATA_TYPE, 3> n = f.mPlanes[i].getNormal();
      DATA_TYPE o = f.mPlanes[i].getOffset();
      DATA_TYPE len = Math::sqrt( n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
      n[0] /= len;
      n[1] /= len;
      n[2] /= len;
      o /= len;
      f.mPlanes[i].setNormal(n);
      f.mPlanes[i].setOffset(o);
   }
}

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
bool gmtl::operator!= ( const Matrix< DATA_TYPE, ROWS, COLS > &  lhs,
const Matrix< DATA_TYPE, ROWS, COLS > &  rhs 
) [inline]

Tests 2 matrices for inequality.

Parameters:
lhs The first matrix
rhs The second matrix
Precondition:
Both matrices must be of the same size.
Returns:
false if the matrices differ on any element value; true otherwise

Definition at line 713 of file MatrixOps.h.

   {
      return bool( !(lhs == rhs) );
   }

template<class DATA_TYPE , typename ROT_ORDER >
bool gmtl::operator!= ( const EulerAngle< DATA_TYPE, ROT_ORDER > &  e1,
const EulerAngle< DATA_TYPE, ROT_ORDER > &  e2 
) [inline]

Compares e1 and e2 (component-wise) to see if they are NOT exactly the same.

Parameters:
e1 the first EulerAngle
e2 the second EulerAngle
Returns:
true if e1 does not equal e2; false if they are equal

Definition at line 47 of file EulerAngleOps.h.

{
   return(! (e1 == e2));
}

template<class DATA_TYPE >
bool gmtl::operator!= ( const Plane< DATA_TYPE > &  p1,
const Plane< DATA_TYPE > &  p2 
) [inline]

Compare two planes to see if they are not EXACTLY the same.

In other words, this comparison is done with zero tolerance.

Parameters:
p1 the first plane to compare
p2 the second plane to compare
Returns:
true if they are not equal, false otherwise

Definition at line 154 of file PlaneOps.h.

{
   return (! (p1 == p2));
}

template<class DATA_TYPE , unsigned SIZE>
bool gmtl::operator!= ( const VecBase< DATA_TYPE, SIZE > &  v1,
const VecBase< DATA_TYPE, SIZE > &  v2 
) [inline]

Compares v1 and v2 to see if they are NOT exactly the same with zero tolerance.

Parameters:
v1 the first vector
v2 the second vector
Returns:
true if v1 does not equal v2; false if they are equal

Definition at line 584 of file VecOps.h.

{
   return(! (v1 == v2));
}

template<class DATA_TYPE >
bool gmtl::operator!= ( const Tri< DATA_TYPE > &  tri1,
const Tri< DATA_TYPE > &  tri2 
)

Compare two triangle to see if they are not EXACTLY the same.

Parameters:
tri1 the first triangle to compare
tri2 the second triangle to compare
Returns:
true if they are not equal, false otherwise

Definition at line 80 of file TriOps.h.

{
   return (! (tri1 == tri2));
}

template<typename DATA_TYPE >
bool gmtl::operator!= ( const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
) [inline]

Compare two quaternions for not-equality.

See also:
isEqual( Quat, Quat )

Definition at line 611 of file QuatOps.h.

   {
      return !operator==( q1, q2 );
   }

template<class DATA_TYPE >
bool gmtl::operator!= ( const AABox< DATA_TYPE > &  b1,
const AABox< DATA_TYPE > &  b2 
) [inline]

Compare two AABoxes to see if they are not EXACTLY the same.

In other words, this comparison is done with zero tolerance.

Parameters:
b1 the first box to compare
b2 the second box to compare
Returns:
true if they are not equal, false otherwise

Definition at line 47 of file AABoxOps.h.

{
   return (! (b1 == b2));
}

template<class DATA_TYPE >
bool gmtl::operator!= ( const Ray< DATA_TYPE > &  ls1,
const Ray< DATA_TYPE > &  ls2 
) [inline]

Compare two line segments to see if they are not EXACTLY the same.

Parameters:
ls1 the first Ray to compare
ls2 the second Ray to compare
Returns:
true if they are not equal, false otherwise

Definition at line 37 of file RayOps.h.

{
   return ( ! (ls1 == ls2) );
}

template<class DATA_TYPE >
bool gmtl::operator!= ( const Sphere< DATA_TYPE > &  s1,
const Sphere< DATA_TYPE > &  s2 
) [inline]

Compare two spheres to see if they are not EXACTLY the same.

Parameters:
s1 the first sphere to compare
s2 the second sphere to compare
Returns:
true if they are not equal, false otherwise

Definition at line 44 of file SphereOps.h.

{
   return (! (s1 == s2));
}

template<typename POS_TYPE , typename ROT_TYPE >
bool gmtl::operator!= ( const Coord< POS_TYPE, ROT_TYPE > &  c1,
const Coord< POS_TYPE, ROT_TYPE > &  c2 
) [inline]

Compare two coordinate frames for not-equality.

Parameters:
c1 the first Coord
c2 the second Coord
Returns:
true if c1 is different from c2, false otherwise

Definition at line 37 of file CoordOps.h.

   {
      return !operator==( c1, c2 );
   }

template<class DATA_TYPE >
bool gmtl::operator!= ( const AxisAngle< DATA_TYPE > &  a1,
const AxisAngle< DATA_TYPE > &  a2 
) [inline]

Compares 2 AxisAngles to see if they are NOT exactly the same.

Parameters:
a1 the first AxisAngle
a2 the second AxisAngle
Returns:
true if a1 does not equal a2; false if they are equal

Definition at line 48 of file AxisAngleOps.h.

{
   return !(a1 == a2);
}

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Ray<DATA_TYPE> gmtl::operator* ( const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const Ray< DATA_TYPE > &  ray 
) [inline]

ray * a matrix multiplication of [m x k] matrix by a ray.

Parameters:
matrix the transform matrix
ray the original ray
Returns:
the ray transformed by the matrix
Postcondition:
This results in a full matrix xform of the ray.

Definition at line 384 of file Xforms.h.

   {
      Ray<DATA_TYPE> temporary;
      return xform( temporary, matrix, ray );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
LineSeg<DATA_TYPE> gmtl::operator* ( const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const LineSeg< DATA_TYPE > &  seg 
) [inline]

seg * a matrix multiplication of [m x k] matrix by a seg.

Parameters:
matrix the transform matrix
seg the original ray
Returns:
the seg transformed by the matrix
Postcondition:
This results in a full matrix xform of the seg.

Definition at line 431 of file Xforms.h.

   {
      LineSeg<DATA_TYPE> temporary;
      return xform( temporary, matrix, seg );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::operator* ( const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
)

product of two quaternions (quaternion product) Does quaternion multiplication.

Postcondition:
temp' = q1 * q2 (where q2 would be applied first to any xformed geometry)
See also:
Quat
Todo:
metaprogramming on quat operator*()

Definition at line 75 of file QuatOps.h.

   {
      // (grassman product - see mult() for discussion)
      // don't normalize, because it might not be rotation arithmetic we're doing
      // (only rotation quats have unit length)
      return Quat<DATA_TYPE>( q1[Welt]*q2[Xelt] + q1[Xelt]*q2[Welt] + q1[Yelt]*q2[Zelt] - q1[Zelt]*q2[Yelt],
                              q1[Welt]*q2[Yelt] + q1[Yelt]*q2[Welt] + q1[Zelt]*q2[Xelt] - q1[Xelt]*q2[Zelt],
                              q1[Welt]*q2[Zelt] + q1[Zelt]*q2[Welt] + q1[Xelt]*q2[Yelt] - q1[Yelt]*q2[Xelt],
                              q1[Welt]*q2[Welt] - q1[Xelt]*q2[Xelt] - q1[Yelt]*q2[Yelt] - q1[Zelt]*q2[Zelt] );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Point<DATA_TYPE, COLS> gmtl::operator* ( const Point< DATA_TYPE, COLS > &  point,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix 
) [inline]

point * a matrix multiplication of [m x k] matrix by a [k x 1] matrix (also known as a Point [with w == 1 for points by definition] ).

Parameters:
matrix the transform matrix
point the original point
Returns:
the point transformed by the matrix
Postcondition:
This results in a full matrix xform of the point.

Definition at line 319 of file Xforms.h.

   {
      Point<DATA_TYPE, COLS> temporary;
      return xform( temporary, matrix, point );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
Point<DATA_TYPE, COLS_MINUS_ONE> gmtl::operator* ( const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const Point< DATA_TYPE, COLS_MINUS_ONE > &  point 
) [inline]

matrix * partially specified point.

multiplication of [m x k] matrix by a [k-1 x 1] matrix (also known as a Point [with w == 1 for points by definition] ).

Parameters:
matrix the transform matrix
point the original point
Returns:
the point transformed by the matrix
Postcondition:
the [k-1 x 1] vector you pass in is treated as a [point, 1.0]
This results in a full matrix xform of the point.

Definition at line 305 of file Xforms.h.

   {
      Point<DATA_TYPE, COLS_MINUS_ONE> temporary;
      return xform( temporary, matrix, point );
   }

template<typename T , unsigned SIZE, typename R1 >
VecBase<T,SIZE, meta::VecBinaryExpr<VecBase<T,SIZE,R1>, VecBase<T,SIZE, meta::ScalarArg<T> >, meta::VecMultBinary> > gmtl::operator* ( const VecBase< T, SIZE, R1 > &  v1,
const T  scalar 
) [inline]

Multiplies v1 by a scalar value and returns the result.

Thus result = v1 * scalar.

Parameters:
v1 the vector to scale
scalar the amount by which to scale v1
Returns:
the result of multiplying v1 by scalar

Definition at line 216 of file VecOps.h.

{
   return VecBase<T,SIZE,
             meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
                                 VecBase<T,SIZE, meta::ScalarArg<T> >,
                                 meta::VecMultBinary> >(
                                       meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
                                                           VecBase<T,SIZE, meta::ScalarArg<T> >,
                                                           meta::VecMultBinary>(v1,
                                                                                meta::ScalarArg<T>(scalar)) );
}

template<typename T , unsigned SIZE, typename R1 >
VecBase<T,SIZE, meta::VecBinaryExpr< VecBase<T,SIZE, meta::ScalarArg<T> >, VecBase<T,SIZE,R1>, meta::VecMultBinary> > gmtl::operator* ( const T  scalar,
const VecBase< T, SIZE, R1 > &  v1 
) [inline]

Definition at line 232 of file VecOps.h.

{
   return VecBase<T,SIZE,
             meta::VecBinaryExpr<VecBase<T,SIZE, meta::ScalarArg<T> >,
                                 VecBase<T,SIZE,R1>,
                                 meta::VecMultBinary> >(
                                       meta::VecBinaryExpr<VecBase<T,SIZE, meta::ScalarArg<T> >,
                                                           VecBase<T,SIZE,R1>,
                                                           meta::VecMultBinary>(meta::ScalarArg<T>(scalar), v1 ) );
}

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
Vec<DATA_TYPE, COLS_MINUS_ONE> gmtl::operator* ( const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const Vec< DATA_TYPE, COLS_MINUS_ONE > &  vector 
) [inline]

matrix * partial vector, assumes last elt of vector is 0 (partial transform).

Parameters:
matrix the transform matrix
vector the original vector
Returns:
the vector transformed by the matrix multiplication of [m x k] matrix by a [k-1 x 1] matrix (also known as a Vector [with w == 0 for vectors by definition] ).
Postcondition:
the [k-1 x 1] vector you pass in is treated as a [vector, 0.0]
This ends up being a partial xform using only the rotation from the matrix (vector xformed result is untranslated).

Definition at line 199 of file Xforms.h.

   {
      Vec<DATA_TYPE, COLS_MINUS_ONE> temporary;
      return xform( temporary, matrix, vector );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::operator* ( const Quat< DATA_TYPE > &  q,
DATA_TYPE  s 
)

vector scalar multiplication

Postcondition:
result' = [qx*s, qy*s, qz*s, qw*s]
See also:
Quat

Definition at line 141 of file QuatOps.h.

   {
      Quat<DATA_TYPE> temporary;
      return mult( temporary, q, s );
   }

template<typename DATA_TYPE >
VecBase<DATA_TYPE, 3> gmtl::operator* ( const Quat< DATA_TYPE > &  rot,
const VecBase< DATA_TYPE, 3 > &  vector 
) [inline]

transform a vector by a rotation quaternion.

Precondition:
give a vector, and a rotation quaternion (by definition, a rotation quaternion is normalized).
Parameters:
rot The quaternion
vector The original vector to transform
Returns:
the resulting vector transformed by the quaternion
Postcondition:
v' = q P(v) q* (where result is v', rot is q, and vector is v. q* is conj(q), and P(v) is pure quaternion made from v)

Definition at line 74 of file Xforms.h.

   {
      VecBase<DATA_TYPE, 3> temporary;
      return xform( temporary, rot, vector );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Vec<DATA_TYPE, COLS> gmtl::operator* ( const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const Vec< DATA_TYPE, COLS > &  vector 
) [inline]

matrix * vector xform.

multiplication of [m x k] matrix by a [k x 1] matrix (also known as a Vector...).

Parameters:
matrix the transform matrix
vector the original vector
Returns:
the vector transformed by the matrix
Postcondition:
This results in a full matrix xform of the vector (assumes you know what you are doing - i.e. that you know that the last component of a vector by definition is 0.0, and changing this might make the xform different that what you may expect).
returns a vec same size as the matrix rows... (v[r][1] = m[r][k] * v[k][1])

Definition at line 139 of file Xforms.h.

   {
      // do a standard [m x k] by [k x n] matrix multiplication (where n == 0).
      Vec<DATA_TYPE, COLS> temporary;
      return xform( temporary, matrix, vector );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned INTERNAL, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS> gmtl::operator* ( const Matrix< DATA_TYPE, ROWS, INTERNAL > &  lhs,
const Matrix< DATA_TYPE, INTERNAL, COLS > &  rhs 
) [inline]

matrix * matrix.

: With regard to size (ROWS/COLS): if lhs is m x p, and rhs is p x n, then result is m x n (mult func undefined otherwise) : returns a m x n sized matrix == lhs * rhs (where rhs is applied first) returns a temporary, is slower.

Definition at line 106 of file MatrixOps.h.

   {
      Matrix<DATA_TYPE, ROWS, COLS> temporary;
      return mult( temporary, lhs, rhs );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Point<DATA_TYPE, COLS> gmtl::operator* ( const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const Point< DATA_TYPE, COLS > &  point 
) [inline]

matrix * point.

multiplication of [m x k] matrix by a [k x 1] matrix (also known as a Point...).

Parameters:
matrix the transform matrix
point the original point
Returns:
the point transformed by the matrix
Postcondition:
This results in a full matrix xform of the point.
returns a point same size as the matrix rows... (p[r][1] = m[r][k] * p[k][1])

Definition at line 245 of file Xforms.h.

   {
      Point<DATA_TYPE, COLS> temporary;
      return xform( temporary, matrix, point );
   }

template<typename DATA_TYPE , unsigned SIZE>
Matrix<DATA_TYPE, SIZE, SIZE>& gmtl::operator*= ( Matrix< DATA_TYPE, SIZE, SIZE > &  result,
const Matrix< DATA_TYPE, SIZE, SIZE > &  operand 
) [inline]

matrix postmult (operator*=).

does a postmult on the matrix. : args must both be n x n sized (this function is undefined otherwise) : result' = result * operand (where operand is applied first)

Definition at line 185 of file MatrixOps.h.

   {
      return postMult( result, operand );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned COLS_MINUS_ONE>
Point<DATA_TYPE, COLS_MINUS_ONE>& gmtl::operator*= ( Point< DATA_TYPE, COLS_MINUS_ONE > &  point,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix 
) [inline]

partial point *= a matrix multiplication of [m x k] matrix by a [k-1 x 1] matrix (also known as a Point [with w == 1 for points by definition] ).

Parameters:
matrix the transform matrix
point the original point
Returns:
the point transformed by the matrix
Postcondition:
the [k-1 x 1] vector you pass in is treated as a [point, 1.0]
This results in a full matrix xform of the point.

Definition at line 349 of file Xforms.h.

   {
      Point<DATA_TYPE, COLS_MINUS_ONE> temporary = point;
      return xform( point, matrix, temporary);
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Point<DATA_TYPE, COLS> gmtl::operator*= ( Point< DATA_TYPE, COLS > &  point,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix 
) [inline]

point *= a matrix multiplication of [m x k] matrix by a [k x 1] matrix (also known as a Point [with w == 1 for points by definition] ).

Parameters:
matrix the transform matrix
point the original point
Returns:
the point transformed by the matrix
Postcondition:
This results in a full matrix xform of the point.

Definition at line 334 of file Xforms.h.

   {
      Point<DATA_TYPE, COLS> temporary = point;
      return xform( point, matrix, temporary);
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Ray<DATA_TYPE>& gmtl::operator*= ( Ray< DATA_TYPE > &  ray,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix 
) [inline]

ray *= a matrix multiplication of [m x k] matrix by a ray.

Parameters:
matrix the transform matrix
ray the original ray
Returns:
the ray transformed by the matrix
Postcondition:
This results in a full matrix xform of the ray.

Definition at line 399 of file Xforms.h.

   {
      Ray<DATA_TYPE> temporary = ray;
      return xform( ray, matrix, temporary);
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::operator*= ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const DATA_TYPE &  scalar 
) [inline]

matrix scalar mult (operator*=).

multiply matrix elements by a scalar : result *= scalar

Definition at line 221 of file MatrixOps.h.

   {
      return mult( result, scalar );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::operator*= ( Quat< DATA_TYPE > &  q,
DATA_TYPE  s 
)

vector scalar multiplication

Postcondition:
result' = [resultx*s, resulty*s, resultz*s, resultw*s]
See also:
Quat

Definition at line 152 of file QuatOps.h.

   {
      return mult( q, q, s );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
LineSeg<DATA_TYPE>& gmtl::operator*= ( LineSeg< DATA_TYPE > &  seg,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix 
) [inline]

seg *= a matrix multiplication of [m x k] matrix by a seg.

Parameters:
matrix the transform matrix
seg the original point
Returns:
the point transformed by the matrix
Postcondition:
This results in a full matrix xform of the point.

Definition at line 446 of file Xforms.h.

   {
      LineSeg<DATA_TYPE> temporary = seg;
      return xform( seg, matrix, temporary);
   }

template<class DATA_TYPE , unsigned SIZE, class SCALAR_TYPE >
VecBase<DATA_TYPE, SIZE>& gmtl::operator*= ( VecBase< DATA_TYPE, SIZE > &  v1,
const SCALAR_TYPE &  scalar 
)

Multiplies v1 by a scalar value and stores the result in v1.

This is equivalent to the expression v1 = v1 * scalar.

Parameters:
v1 the vector to scale
scalar the amount by which to scale v1
Returns:
v1 after it has been mutiplied by scalar

Definition at line 182 of file VecOps.h.

{
   for(unsigned i=0;i<SIZE;++i)
   {
      v1[i] *= (DATA_TYPE)scalar;
   }

   return v1;
}

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::operator*= ( Quat< DATA_TYPE > &  result,
const Quat< DATA_TYPE > &  q2 
)

quaternion postmult

Postcondition:
result' = result * q2 (where q2 is applied first to any xformed geometry)
See also:
Quat

Definition at line 91 of file QuatOps.h.

   {
      return mult( result, result, q2 );
   }

template<typename DATA_TYPE >
VecBase<DATA_TYPE, 3> gmtl::operator*= ( VecBase< DATA_TYPE, 3 > &  vector,
const Quat< DATA_TYPE > &  rot 
) [inline]

transform a vector by a rotation quaternion.

Precondition:
give a vector, and a rotation quaternion (by definition, a rotation quaternion is normalized).
Parameters:
rot The quaternion
vector The original vector to transform
Postcondition:
v' = q P(v) q* (where result is v', rot is q, and vector is v. q* is conj(q), and P(v) is pure quaternion made from v)

Definition at line 88 of file Xforms.h.

   {
      VecBase<DATA_TYPE, 3> temporary = vector;
      return xform( vector, rot, temporary);
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::operator+ ( const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
)

vector addition

Postcondition:
result' = [qx+s, qy+s, qz+s, qw+s]
See also:
Quat

Definition at line 241 of file QuatOps.h.

   {
      Quat<DATA_TYPE> temporary;
      return add( temporary, q1, q2 );
   }

template<typename T , unsigned SIZE, typename R1 , typename R2 >
VecBase<T,SIZE, meta::VecBinaryExpr<VecBase<T,SIZE,R1>, VecBase<T,SIZE,R2>, meta::VecPlusBinary> > gmtl::operator+ ( const VecBase< T, SIZE, R1 > &  v1,
const VecBase< T, SIZE, R2 > &  v2 
) [inline]

Adds v2 to v1 and returns the result.

Thus result = v1 + v2.

Parameters:
v1 the first vector
v2 the second vector
Returns:
the result of adding v2 to v1

Definition at line 103 of file VecOps.h.

{
   return VecBase<T,SIZE,
               meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
                                   VecBase<T,SIZE,R2>,
                                   meta::VecPlusBinary> >( meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
                                                                               VecBase<T,SIZE,R2>,
                                                                               meta::VecPlusBinary>(v1,v2) );
}

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::operator+= ( Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
)

vector addition

Postcondition:
result' = [resultx+s, resulty+s, resultz+s, resultw+s]
See also:
Quat

Definition at line 252 of file QuatOps.h.

   {
      return add( q1, q1, q2 );
   }

template<class DATA_TYPE , unsigned SIZE, typename REP2 >
VecBase<DATA_TYPE, SIZE>& gmtl::operator+= ( VecBase< DATA_TYPE, SIZE > &  v1,
const VecBase< DATA_TYPE, SIZE, REP2 > &  v2 
)

Adds v2 to v1 and stores the result in v1.

This is equivalent to the expression v1 = v1 + v2.

Parameters:
v1 the first vector
v2 the second vector
Returns:
v1 after v2 has been added to it

Definition at line 71 of file VecOps.h.

{
   for(unsigned i=0;i<SIZE;++i)
   {
      v1[i] += v2[i];
   }

   return v1;
}

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::operator- ( const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
)

vector subtraction

Postcondition:
result' = [qx-s, qy-s, qz-s, qw-s]
See also:
Quat

Definition at line 275 of file QuatOps.h.

   {
      Quat<DATA_TYPE> temporary;
      return sub( temporary, q1, q2 );
   }

template<typename T , unsigned SIZE, typename R1 , typename R2 >
VecBase<T,SIZE, meta::VecBinaryExpr<VecBase<T,SIZE,R1>, VecBase<T,SIZE,R2>, meta::VecMinusBinary> > gmtl::operator- ( const VecBase< T, SIZE, R1 > &  v1,
const VecBase< T, SIZE, R2 > &  v2 
) [inline]

Subtracts v2 from v1 and returns the result.

Thus result = v1 - v2.

Parameters:
v1 the first vector
v2 the second vector
Returns:
the result of subtracting v2 from v1

Definition at line 161 of file VecOps.h.

{
   return VecBase<T,SIZE,
               meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
                                   VecBase<T,SIZE,R2>,
                                   meta::VecMinusBinary> >( meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
                                                                               VecBase<T,SIZE,R2>,
                                                                               meta::VecMinusBinary>(v1,v2) );
}

template<typename T , unsigned SIZE, typename R1 >
VecBase<T,SIZE, meta::VecUnaryExpr<VecBase<T,SIZE,R1>, meta::VecNegUnary> > gmtl::operator- ( const VecBase< T, SIZE, R1 > &  v1  )  [inline]

Negates v1.

The result = -v1.

Parameters:
v1 the vector.
Returns:
the result of negating v1.

Definition at line 48 of file VecOps.h.

{
   return VecBase<T,SIZE,
                  meta::VecUnaryExpr<VecBase<T,SIZE,R1>, meta::VecNegUnary> >
                        ( meta::VecUnaryExpr<VecBase<T,SIZE,R1>, meta::VecNegUnary>(v1) );
}

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::operator- ( const Quat< DATA_TYPE > &  quat  ) 

Vector negation - (operator-) return a temporary that is the negative of the given quat.

the negative of a rotation quaternion is geometrically equivelent to the original. there exist 2 quats for every possible rotation.

Returns:
returns the negation of the given quat

Definition at line 117 of file QuatOps.h.

   {
      return Quat<DATA_TYPE>( -quat[0], -quat[1], -quat[2], -quat[3] );
   }

template<class DATA_TYPE , unsigned SIZE, typename REP2 >
VecBase<DATA_TYPE, SIZE>& gmtl::operator-= ( VecBase< DATA_TYPE, SIZE > &  v1,
const VecBase< DATA_TYPE, SIZE, REP2 > &  v2 
)

Subtracts v2 from v1 and stores the result in v1.

This is equivalent to the expression v1 = v1 - v2.

Parameters:
v1 the first vector
v2 the second vector
Returns:
v1 after v2 has been subtracted from it

Definition at line 129 of file VecOps.h.

{
   for(unsigned i=0;i<SIZE;++i)
   {
      v1[i] -= v2[i];
   }

   return v1;
}

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::operator-= ( Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
)

vector subtraction

Postcondition:
result' = [resultx-s, resulty-s, resultz-s, resultw-s]
See also:
Quat

Definition at line 286 of file QuatOps.h.

   {
      return sub( q1, q1, q2 );
   }

template<typename T , unsigned SIZE, typename R1 >
VecBase<T,SIZE, meta::VecBinaryExpr<VecBase<T,SIZE,R1>, VecBase<T,SIZE, meta::ScalarArg<T> >, meta::VecDivBinary> > gmtl::operator/ ( const VecBase< T, SIZE, R1 > &  v1,
const T  scalar 
) [inline]

Divides v1 by a scalar value and returns the result.

Thus result = v1 / scalar.

Parameters:
v1 the vector to scale
scalar the amount by which to scale v1
Returns:
the result of dividing v1 by scalar

Definition at line 309 of file VecOps.h.

{
   return VecBase<T,SIZE,
             meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
                                 VecBase<T,SIZE, meta::ScalarArg<T> >,
                                 meta::VecDivBinary> >(
                                       meta::VecBinaryExpr<VecBase<T,SIZE,R1>,
                                                           VecBase<T,SIZE, meta::ScalarArg<T> >,
                                                           meta::VecDivBinary>(v1,
                                                                               meta::ScalarArg<T>(scalar)) );
}

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::operator/ ( const Quat< DATA_TYPE > &  q1,
Quat< DATA_TYPE >  q2 
)

quotient of two quaternions

Postcondition:
result = q1 * (1/q2) (where 1/q2 is applied first to any xform'd geometry)
See also:
Quat

Definition at line 173 of file QuatOps.h.

   {
      return q1 * invert( q2 );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE> gmtl::operator/ ( const Quat< DATA_TYPE > &  q,
DATA_TYPE  s 
)

vector scalar division

Postcondition:
result' = [qx/s, qy/s, qz/s, qw/s]
See also:
Quat

Definition at line 207 of file QuatOps.h.

   {
      Quat<DATA_TYPE> temporary;
      return div( temporary, q, s );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::operator/= ( Quat< DATA_TYPE > &  result,
const Quat< DATA_TYPE > &  q2 
)

quotient of two quaternions

Postcondition:
result = result * (1/q2) (where 1/q2 is applied first to any xform'd geometry)
See also:
Quat

Definition at line 183 of file QuatOps.h.

   {
      return div( result, result, q2 );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::operator/= ( const Quat< DATA_TYPE > &  q,
DATA_TYPE  s 
)

vector scalar division

Postcondition:
result' = [resultx/s, resulty/s, resultz/s, resultw/s]
See also:
Quat

Definition at line 218 of file QuatOps.h.

   {
      return div( q, q, s );
   }

template<class DATA_TYPE , unsigned SIZE, class SCALAR_TYPE >
VecBase<DATA_TYPE, SIZE>& gmtl::operator/= ( VecBase< DATA_TYPE, SIZE > &  v1,
const SCALAR_TYPE &  scalar 
)

Multiplies v1 by a scalar value and returns the result.

Thus result = scalar * v1. This is equivalent to result = v1 * scalar.

Parameters:
scalar the amount by which to scale v1
v1 the vector to scale
Returns:
the result of multiplying v1 by scalar Divides v1 by a scalar value and stores the result in v1. This is equivalent to the expression v1 = v1 / scalar.
Parameters:
v1 the vector to scale
scalar the amount by which to scale v1
Returns:
v1 after it has been divided by scalar

Definition at line 276 of file VecOps.h.

{
   for(unsigned i=0;i<SIZE;++i)
   {
      v1[i] /= scalar;
   }

   return v1;
}

template<typename DATA_TYPE , unsigned SIZE, typename REP >
std::ostream& gmtl::operator<< ( std::ostream &  out,
const VecBase< DATA_TYPE, SIZE, REP > &  v 
)

Outputs a string representation of the given VecBase type to the given output stream.

This works for both Point and Vec types. The output is formatted such that Vec<int, 4>(1,2,3,4) will appear as "(1, 2, 3, 4)".

Parameters:
out the stream to write to
v the VecBase type to output
Returns:
out after it has been written to

Definition at line 93 of file Output.h.

   {
      return output::VecOutputter<DATA_TYPE,SIZE,REP>::outStream(out,v);
   }

template<class DATA_TYPE , unsigned ROWS, unsigned COLS>
std::ostream& gmtl::operator<< ( std::ostream &  out,
const Matrix< DATA_TYPE, ROWS, COLS > &  m 
)

Outputs a string representation of the given Matrix to the given output stream.

The output is formatted along the lines of:

    | 1 2 3 4 |
    | 5 6 7 8 |
    | 9 10 11 12 |
 
Parameters:
out the stream to write to
m the Matrix to output
Returns:
out after it has been written to

Definition at line 132 of file Output.h.

   {
      for ( unsigned row=0; row<ROWS; ++row )
      {
         out << "|";
         for ( unsigned col=0; col<COLS; ++col )
         {
            out << " " << m(row, col);
         }
         out << " |" << std::endl;
      }
      return out;
   }

template<typename DATA_TYPE >
std::ostream& gmtl::operator<< ( std::ostream &  out,
const Tri< DATA_TYPE > &  t 
)

Outputs a string representation of the given Tri to the given output stream.

The output is formatted such that Tri<int>( Point<int, 3>(1,2,3), Point<int, 3>(4,5,6), Point<int, 3>(7,8,9) ) will appear as "(1, 2, 3), (4, 5, 6), (7, 8, 9)".

Parameters:
out the stream to write to
t the Tri to output
Returns:
out after it has been written to

Definition at line 180 of file Output.h.

   {
      out << t[0] << ", " << t[1] << ", " << t[2];
      return out;
   }

template<typename DATA_TYPE >
std::ostream& gmtl::operator<< ( std::ostream &  out,
const Plane< DATA_TYPE > &  p 
)

Outputs a string representation of the given Plane to the given output stream.

The output is formatted such that Plane<int>( Vec<int, 3>(1,2,3), 4 ) will appear as "(1, 2, 3), 4)".

Parameters:
out the stream to write to
p the Plane to output
Returns:
out after it has been written to

Definition at line 201 of file Output.h.

   {
      out << p.mNorm << ", " << p.mOffset;
      return out;
   }

template<typename DATA_TYPE >
std::ostream& gmtl::operator<< ( std::ostream &  out,
const Sphere< DATA_TYPE > &  s 
)

Outputs a string representation of the given Sphere to the given output stream.

The output is formatted such that Sphere<int>( Point<int, 3>(1,2,3), 4 ) will appear as "(1, 2, 3), 4)".

Parameters:
out the stream to write to
s the Sphere to output
Returns:
out after it has been written to

Definition at line 222 of file Output.h.

   {
      out << s.mCenter << ", " << s.mRadius;
      return out;
   }

template<class DATA_TYPE , typename ROTATION_ORDER >
std::ostream& gmtl::operator<< ( std::ostream &  out,
const EulerAngle< DATA_TYPE, ROTATION_ORDER > &  e 
)

Outputs a string representation of the given EulerAngle type to the given output stream.

Format is {ang1,ang2,ang3}

Parameters:
out the stream to write to
e the EulerAngle type to output
Returns:
out after it has been written to

Definition at line 109 of file Output.h.

   {
      const DATA_TYPE* angle_data(e.getData());
      out << "{" << angle_data[0] << ", " << angle_data[1] << ", " << angle_data[2] << "}";
      return out;
   }

template<typename DATA_TYPE >
std::ostream& gmtl::operator<< ( std::ostream &  out,
const Ray< DATA_TYPE > &  b 
)

Outputs a string representation of the given Ray to the given output stream.

The output is formatted such that Ray<int>( Point<int>(1,2,3), Vec<int>(4,5,6) ) will appear as "(1,2,3) (4,5,6)".

Parameters:
out the stream to write to
b the Ray to output
Returns:
out after it has been written to

Definition at line 265 of file Output.h.

   {
      out << b.getOrigin() << " " << b.getDir();
      return out;
   }

template<typename POS_TYPE , typename ROT_TYPE >
std::ostream& gmtl::operator<< ( std::ostream &  out,
const Coord< POS_TYPE, ROT_TYPE > &  c 
)

Definition at line 293 of file Output.h.

   {
      out << "p:" << c.getPos() << " r:" << c.getRot();
      return out;
   }

template<typename DATA_TYPE >
std::ostream& gmtl::operator<< ( std::ostream &  out,
const Quat< DATA_TYPE > &  q 
)

Outputs a string representation of the given Matrix to the given output stream.

The output is formatted such that Quat<int>(1,2,3,4) will appear as "(1, 2, 3, 4)".

Parameters:
out the stream to write to
q the Quat to output
Returns:
out after it has been written to

Definition at line 158 of file Output.h.

   {
      out << q.mData;
      return out;
   }

template<typename DATA_TYPE >
std::ostream& gmtl::operator<< ( std::ostream &  out,
const AABox< DATA_TYPE > &  b 
)

Outputs a string representation of the given AABox to the given output stream.

The output is formatted such that AABox<int>( Point<int, 3>(1,2,3), Point<int, 3>(4,5,6) ) will appear as "(1,2,3) (4,5,6) false".

Parameters:
out the stream to write to
b the AABox to output
Returns:
out after it has been written to

Definition at line 243 of file Output.h.

   {
      out << b.mMin << " " << b.mMax << " ";
      out << (b.mEmpty ? "true" : "false");
      return out;
   }

template<typename DATA_TYPE >
std::ostream& gmtl::operator<< ( std::ostream &  out,
const LineSeg< DATA_TYPE > &  b 
)

Outputs a string representation of the given LineSeg to the given output stream.

The output is formatted such that LineSeg<int>( Point<int>(1,2,3), Vec<int>(4,5,6) ) will appear as "(1,2,3) (4,5,6)".

Parameters:
out the stream to write to
b the LineSeg to output
Returns:
out after it has been written to

Definition at line 286 of file Output.h.

   {
      out << b.getOrigin() << " " << b.getDir();
      return out;
   }

template<typename DATA_TYPE >
bool gmtl::operator== ( const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
) [inline]

Compare two quaternions for equality.

See also:
isEqual( Quat, Quat )

Definition at line 599 of file QuatOps.h.

   {
      return bool( q1[0] == q2[0] &&
                   q1[1] == q2[1] &&
                   q1[2] == q2[2] &&
                   q1[3] == q2[3]  );
   }

template<class DATA_TYPE , typename ROT_ORDER >
bool gmtl::operator== ( const EulerAngle< DATA_TYPE, ROT_ORDER > &  e1,
const EulerAngle< DATA_TYPE, ROT_ORDER > &  e2 
) [inline]

Compares 2 EulerAngles (component-wise) to see if they are exactly the same.

Parameters:
e1 the first EulerAngle
e2 the second EulerAngle
Returns:
true if e1 equals e2; false if they differ

Definition at line 28 of file EulerAngleOps.h.

{
   // @todo metaprogramming.
   if (e1[0] != e2[0]) return false;
   if (e1[1] != e2[1]) return false;
   if (e1[2] != e2[2]) return false;
   return true;
}

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
bool gmtl::operator== ( const Matrix< DATA_TYPE, ROWS, COLS > &  lhs,
const Matrix< DATA_TYPE, ROWS, COLS > &  rhs 
) [inline]

Tests 2 matrices for equality.

Parameters:
lhs The first matrix
rhs The second matrix
Precondition:
Both matrices must be of the same size.
Returns:
true if the matrices have the same element values; false otherwise

Definition at line 687 of file MatrixOps.h.

   {
      for (unsigned int i = 0; i < ROWS*COLS; ++i)
      {
         if (lhs.mData[i] != rhs.mData[i])
         {
            return false;
         }
      }

      return true;

      /*  Would like this
      return( lhs[0] == rhs[0] &&
              lhs[1] == rhs[1] &&
              lhs[2] == rhs[2] );
      */
   }

template<class DATA_TYPE >
bool gmtl::operator== ( const Plane< DATA_TYPE > &  p1,
const Plane< DATA_TYPE > &  p2 
) [inline]

Compare two planes to see if they are EXACTLY the same.

In other words, this comparison is done with zero tolerance.

Parameters:
p1 the first plane to compare
p2 the second plane to compare
Returns:
true if they are equal, false otherwise

Definition at line 139 of file PlaneOps.h.

{
   return ( (p1.mNorm == p2.mNorm) && (p1.mOffset == p2.mOffset) );
}

template<class DATA_TYPE , unsigned SIZE>
bool gmtl::operator== ( const VecBase< DATA_TYPE, SIZE > &  v1,
const VecBase< DATA_TYPE, SIZE > &  v2 
) [inline]

Compares v1 and v2 to see if they are exactly the same.

Parameters:
v1 the first vector
v2 the second vector
Returns:
true if v1 equals v2; false if they differ

Definition at line 551 of file VecOps.h.

{
#ifdef GMTL_NO_METAPROG
   for(unsigned i=0;i<SIZE;++i)
   {
      if(v1[i] != v2[i])
      {
         return false;
      }
   }

   return true;
#else
   return gmtl::meta::EqualVecUnrolled<SIZE-1,Vec<DATA_TYPE,SIZE> >::func(v1,v2);
#endif
   /*  Would like this
   return(vec[0] == _v[0] &&
          vec[1] == _v[1] &&
          vec[2] == _v[2]);
          */
}

template<class DATA_TYPE >
bool gmtl::operator== ( const Ray< DATA_TYPE > &  ls1,
const Ray< DATA_TYPE > &  ls2 
) [inline]

Compare two line segments to see if they are EXACTLY the same.

Parameters:
ls1 the first Ray to compare
ls2 the second Ray to compare
Returns:
true if they are equal, false otherwise

Definition at line 23 of file RayOps.h.

{
   return ( (ls1.mOrigin == ls2.mOrigin) && (ls1.mDir == ls2.mDir) );
}

template<class DATA_TYPE >
bool gmtl::operator== ( const AABox< DATA_TYPE > &  b1,
const AABox< DATA_TYPE > &  b2 
) [inline]

Compare two AABoxes to see if they are EXACTLY the same.

In other words, this comparison is done with zero tolerance.

Parameters:
b1 the first box to compare
b2 the second box to compare
Returns:
true if they are equal, false otherwise

Definition at line 30 of file AABoxOps.h.

{
   return ( (b1.isEmpty() == b2.isEmpty()) &&
            (b1.getMin() == b2.getMin()) &&
            (b1.getMax() == b2.getMax()) );
}

template<class DATA_TYPE >
bool gmtl::operator== ( const Sphere< DATA_TYPE > &  s1,
const Sphere< DATA_TYPE > &  s2 
) [inline]

Compare two spheres to see if they are EXACTLY the same.

Parameters:
s1 the first sphere to compare
s2 the second sphere to compare
Returns:
true if they are equal, false otherwise

Definition at line 30 of file SphereOps.h.

{
   return ( (s1.mCenter == s2.mCenter) && (s1.mRadius == s2.mRadius) );
}

template<class DATA_TYPE >
bool gmtl::operator== ( const Tri< DATA_TYPE > &  tri1,
const Tri< DATA_TYPE > &  tri2 
)

Compare two triangles to see if they are EXACTLY the same.

Parameters:
tri1 the first triangle to compare
tri2 the second triangle to compare
Returns:
true if they are equal, false otherwise

Definition at line 64 of file TriOps.h.

{
   return ( (tri1[0] == tri2[0]) &&
            (tri1[1] == tri2[1]) &&
            (tri1[2] == tri2[2]) );
}

template<typename POS_TYPE , typename ROT_TYPE >
bool gmtl::operator== ( const Coord< POS_TYPE, ROT_TYPE > &  c1,
const Coord< POS_TYPE, ROT_TYPE > &  c2 
) [inline]

Compare two coordinate frames for equality.

Parameters:
c1 the first Coord
c2 the second Coord
Returns:
true if c1 is the same as c2, false otherwise

Definition at line 24 of file CoordOps.h.

   {
      return bool( c1.getPos() == c2.getPos() &&
                   c1.getRot() == c2.getRot() );
   }

template<class DATA_TYPE >
bool gmtl::operator== ( const AxisAngle< DATA_TYPE > &  a1,
const AxisAngle< DATA_TYPE > &  a2 
) [inline]

Compares 2 AxisAngles to see if they are exactly the same.

Parameters:
a1 the first AxisAngle
a2 the second AxisAngle
Returns:
true if a1 equals a2; false if they differ

Definition at line 28 of file AxisAngleOps.h.

{
   // @todo metaprogramming.
   if (a1[0] != a2[0]) return false;
   if (a1[1] != a2[1]) return false;
   if (a1[2] != a2[2]) return false;
   if (a1[3] != a2[3]) return false;
   return true;
}

template<typename DATA_TYPE , unsigned SIZE>
Matrix<DATA_TYPE, SIZE, SIZE>& gmtl::postMult ( Matrix< DATA_TYPE, SIZE, SIZE > &  result,
const Matrix< DATA_TYPE, SIZE, SIZE > &  operand 
) [inline]

matrix postmultiply.

: args must both be n x n (this function is undefined otherwise) : result' = result * operand

Definition at line 162 of file MatrixOps.h.

   {
      return mult( result, result, operand );
   }

template<typename DATA_TYPE , unsigned SIZE>
Matrix<DATA_TYPE, SIZE, SIZE>& gmtl::preMult ( Matrix< DATA_TYPE, SIZE, SIZE > &  result,
const Matrix< DATA_TYPE, SIZE, SIZE > &  operand 
) [inline]

matrix preMultiply.

: args must both be n x n (this function is undefined otherwise) : result' = operand * result

Definition at line 173 of file MatrixOps.h.

   {
      return mult( result, operand, result );
   }

const Quat<double> gmtl::QUAT_ADD_IDENTITYD ( 0.  0,
0.  0,
0.  0,
0.  0 
)
const Quat<float> gmtl::QUAT_ADD_IDENTITYF ( 0.  0f,
0.  0f,
0.  0f,
0.  0f 
)
const Quat<double> gmtl::QUAT_IDENTITYD ( QUAT_MULT_IDENTITYD   ) 
const Quat<float> gmtl::QUAT_IDENTITYF ( QUAT_MULT_IDENTITYF   ) 
const Quat<double> gmtl::QUAT_MULT_IDENTITYD ( 0.  0,
0.  0,
0.  0,
1.  0 
)
const Quat<float> gmtl::QUAT_MULT_IDENTITYF ( 0.  0f,
0.  0f,
0.  0f,
1.  0f 
)
template<class DATA_TYPE , unsigned SIZE>
void gmtl::reflect ( Point< DATA_TYPE, SIZE > &  result,
const Plane< DATA_TYPE > &  plane,
const Point< DATA_TYPE, SIZE > &  point 
)

Mirror the point by the plane.

Definition at line 113 of file PlaneOps.h.

{
   gmtl::Point<DATA_TYPE, SIZE> point_on_plane;
   findNearestPt( plane, point, point_on_plane );
   gmtl::Vec<DATA_TYPE, SIZE> dir = point_on_plane - point;
   result = point + (dir * DATA_TYPE(2.0f));
}

template<class DATA_TYPE , unsigned SIZE>
VecBase<DATA_TYPE, SIZE>& gmtl::reflect ( VecBase< DATA_TYPE, SIZE > &  result,
const VecBase< DATA_TYPE, SIZE > &  vec,
const Vec< DATA_TYPE, SIZE > &  normal 
)

Reflect a vector about a normal.

This method reflects the given vector around the normal vector given. It is similar to if the normal vector was for a plane that you wanted to reflect about. v going into the plane, n normal to the plane, and r coming back out of the plane. (see below)

| v | / |/ |------> n |\ | \ | r

Parameters:
result the vector to store the result i
vec the original vector that we want to reflect
normal the normal vector
Postcondition:
result contains the reflected vector

Definition at line 491 of file VecOps.h.

{
   result = vec - (DATA_TYPE( 2.0 ) * (dot( (Vec<DATA_TYPE, SIZE>)vec, normal ) * normal));
   return result;
}

template<typename DATA_TYPE , typename ROT_ORDER >
Quat<DATA_TYPE>& gmtl::set ( Quat< DATA_TYPE > &  result,
const EulerAngle< DATA_TYPE, ROT_ORDER > &  euler 
) [inline]

Convert an EulerAngle rotation to a Quaternion rotation.

Sets a rotation quaternion using euler angles (each angle in radians).

Precondition:
pass in your angles in the same order as the RotationOrder you specify

Definition at line 215 of file Generate.h.

   {
      // this might be faster if put into the switch statement... (testme)
      const int& order = ROT_ORDER::ID;
      const DATA_TYPE xRot = (order == XYZ::ID) ? euler[0] : ((order == ZXY::ID) ? euler[1] : euler[2]);
      const DATA_TYPE yRot = (order == XYZ::ID) ? euler[1] : ((order == ZXY::ID) ? euler[2] : euler[1]);
      const DATA_TYPE zRot = (order == XYZ::ID) ? euler[2] : ((order == ZXY::ID) ? euler[0] : euler[0]);

      // this could be written better for each rotation order, but this is really general...
      Quat<DATA_TYPE> qx, qy, qz;

      // precompute half angles
      DATA_TYPE xOver2 = xRot * (DATA_TYPE)0.5;
      DATA_TYPE yOver2 = yRot * (DATA_TYPE)0.5;
      DATA_TYPE zOver2 = zRot * (DATA_TYPE)0.5;

      // set the pitch quat
      qx[Xelt] = Math::sin( xOver2 );
      qx[Yelt] = (DATA_TYPE)0.0;
      qx[Zelt] = (DATA_TYPE)0.0;
      qx[Welt] = Math::cos( xOver2 );

      // set the yaw quat
      qy[Xelt] = (DATA_TYPE)0.0;
      qy[Yelt] = Math::sin( yOver2 );
      qy[Zelt] = (DATA_TYPE)0.0;
      qy[Welt] = Math::cos( yOver2 );

      // set the roll quat
      qz[Xelt] = (DATA_TYPE)0.0;
      qz[Yelt] = (DATA_TYPE)0.0;
      qz[Zelt] = Math::sin( zOver2 );
      qz[Welt] = Math::cos( zOver2 );

      // compose the three in pyr order...
      switch (order)
      {
      case XYZ::ID: result = qx * qy * qz; break;
      case ZYX::ID: result = qz * qy * qx; break;
      case ZXY::ID: result = qz * qx * qy; break;
      default:
         gmtlASSERT( false && "unknown rotation order passed to setRot" );
         break;
      }

      // ensure the quaternion is normalized
      normalize( result );
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::set ( Matrix< DATA_TYPE, ROWS, COLS > &  mat,
const Quat< DATA_TYPE > &  q 
)

Convert a Quat to a rotation Matrix.

Precondition:
only 3x3, 3x4, 4x3, or 4x4 matrices are allowed, function is undefined otherwise.
Postcondition:
Matrix is entirely overwritten.
Todo:
Implement using setRot

Definition at line 1209 of file Generate.h.

   {
      if (ROWS == 4)
      {
         mat( 3, 0 ) = DATA_TYPE(0.0);
         mat( 3, 1 ) = DATA_TYPE(0.0);
         mat( 3, 2 ) = DATA_TYPE(0.0);
      }

      if (COLS == 4)
      {
         mat( 0, 3 ) = DATA_TYPE(0.0);
         mat( 1, 3 ) = DATA_TYPE(0.0);
         mat( 2, 3 ) = DATA_TYPE(0.0);
      }

      if (ROWS == 4 && COLS == 4)
         mat( 3, 3 ) = DATA_TYPE(1.0);

      // track state
      mat.mState = Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY;

      return setRot( mat, q );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, typename ROT_ORDER >
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::set ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const EulerAngle< DATA_TYPE, ROT_ORDER > &  euler 
) [inline]

Convert an EulerAngle to a rotation matrix.

Postcondition:
this function only writes to 3x3, 3x4, 4x3, and 4x4 matrices, and is undefined otherwise

Definition at line 917 of file Generate.h.

   {
      gmtl::identity( result );
      return setRot( result, euler );
   }

Matrix44f& gmtl::set ( Matrix44f &  mat,
const OSG::Matrix &  osgMat 
) [inline]

Converts an OpenSG matrix to a gmtl::Matrix.

Parameters:
mat The matrix to write the OpenSG matrix data into.
osgMat The source OpenSG matrix.
Returns:
The equivalent GMTL matrix.

Definition at line 29 of file OpenSGConvert.h.

{
   mat.set(osgMat.getValues());
   return mat;
}

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::set ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const AxisAngle< DATA_TYPE > &  axisAngle 
) [inline]

Convert an AxisAngle to a rotation matrix.

Postcondition:
this function only writes to 3x3, 3x4, 4x3, and 4x4 matrices, and is undefined otherwise
Precondition:
AxisAngle must be normalized (the axis part), results are undefined if not.

Definition at line 907 of file Generate.h.

   {
      gmtl::identity( result );
      return setRot( result, axisAngle );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::set ( Quat< DATA_TYPE > &  result,
const AxisAngle< DATA_TYPE > &  axisAngle 
) [inline]

Convert an AxisAngle to a Quat.

sets a rotation quaternion from an angle and an axis.

Precondition:
AxisAngle::axis must be normalized to length == 1 prior to calling this.
Postcondition:
q = [ cos(rad/2), sin(rad/2) * [x,y,z] ]

Definition at line 184 of file Generate.h.

   {
      gmtlASSERT( (Math::isEqual( lengthSquared( axisAngle.getAxis() ), (DATA_TYPE)1.0, (DATA_TYPE)0.0001 )) &&
                   "you must pass in a normalized vector to setRot( quat, rad, vec )" );

      DATA_TYPE half_angle = axisAngle.getAngle() * (DATA_TYPE)0.5;
      DATA_TYPE sin_half_angle = Math::sin( half_angle );

      result[Welt] = Math::cos( half_angle );
      result[Xelt] = sin_half_angle * axisAngle.getAxis()[0];
      result[Yelt] = sin_half_angle * axisAngle.getAxis()[1];
      result[Zelt] = sin_half_angle * axisAngle.getAxis()[2];

      // should automagically be normalized (unit magnitude) now...
      return result;
   }

template<typename DATATYPE , typename POS_TYPE , typename ROT_TYPE , unsigned MATCOLS, unsigned MATROWS>
Coord<POS_TYPE, ROT_TYPE>& gmtl::set ( Coord< POS_TYPE, ROT_TYPE > &  eulercoord,
const Matrix< DATATYPE, MATROWS, MATCOLS > &  mat 
) [inline]

convert Matrix to Coord

Definition at line 1243 of file Generate.h.

   {
      gmtl::setTrans( eulercoord.pos(), mat );
      gmtl::set( eulercoord.rot(), mat );
      return eulercoord;
   }

template<typename DATA_TYPE >
AxisAngle<DATA_TYPE>& gmtl::set ( AxisAngle< DATA_TYPE > &  axisAngle,
Quat< DATA_TYPE >  quat 
) [inline]

Convert a rotation quaternion to an AxisAngle.

Postcondition:
returns an angle in radians, and a normalized axis equivilent to the quaternion's rotation.
returns rad and xyz such that
  • rad = acos( w ) * 2.0
  • vec = v / (asin( w ) * 2.0) [where v is the xyz or vector component of the quat]
axisAngle = quat;

Definition at line 363 of file Generate.h.

   {
      // set sure we don't get a NaN result from acos...
      if (Math::abs( quat[Welt] ) > (DATA_TYPE)1.0)
      {
         gmtl::normalize( quat );
      }
      gmtlASSERT( Math::abs( quat[Welt] ) <= (DATA_TYPE)1.0 && "acos returns NaN when quat[Welt] > 1, try normalizing your quat." );

      // [acos( w ) * 2.0, v / (asin( w ) * 2.0)]

      // set the angle - aCos is mathematically defined to be between 0 and PI
      DATA_TYPE rad = Math::aCos( quat[Welt] ) * (DATA_TYPE)2.0;
      axisAngle.setAngle( rad );

      // set the axis: (use sin(rad) instead of asin(w))
      DATA_TYPE sin_half_angle = Math::sin( rad * (DATA_TYPE)0.5 );
      if (sin_half_angle >= (DATA_TYPE)0.0001) // because (PI >= rad >= 0)
      {
         DATA_TYPE sin_half_angle_inv = DATA_TYPE(1.0) / sin_half_angle;
         Vec<DATA_TYPE, 3> axis( quat[Xelt] * sin_half_angle_inv,
                                 quat[Yelt] * sin_half_angle_inv,
                                 quat[Zelt] * sin_half_angle_inv );
         normalize( axis );
         axisAngle.setAxis( axis );
      }

      // avoid NAN
      else
      {
         // one of the terms should be a 1,
         // so we can maintain unit-ness
         // in case w is 0 (which here w is 0)
         axisAngle.setAxis( gmtl::Vec<DATA_TYPE, 3>(
                             DATA_TYPE( 1.0 ) /*- gmtl::Math::abs( quat[Welt] )*/,
                            (DATA_TYPE)0.0,
                            (DATA_TYPE)0.0 ) );
      }
      return axisAngle;
   }

template<typename DATATYPE , typename POS_TYPE , typename ROT_TYPE , unsigned MATCOLS, unsigned MATROWS>
Matrix<DATATYPE, MATROWS, MATCOLS>& gmtl::set ( Matrix< DATATYPE, MATROWS, MATCOLS > &  mat,
const Coord< POS_TYPE, ROT_TYPE > &  coord 
) [inline]

Convert a Coord to a Matrix Note: It is set directly, but this is equivalent to T*R where T is the translation matrix and R is the rotation matrix.

See also:
Coord
Matrix

Definition at line 1187 of file Generate.h.

   {
      // set to ident first...
      gmtl::identity( mat );

      // set translation
      // @todo metaprogram this out for 3x3 and 2x2 matrices
      if (MATCOLS == 4)
      {
         setTrans( mat, coord.getPos() );// filtered (only sets the trans part).
      }
      setRot( mat, coord.getRot() ); // filtered (only sets the rot part).
      return mat;
   }

OSG::Matrix& gmtl::set ( OSG::Matrix &  osgMat,
const Matrix44f &  mat 
) [inline]

Converts a GMTL matrix to an OpenSG matrix.

Parameters:
osgMat The matrix to write the GMTL matrix data into.
mat The source GMTL matrix.
Returns:
The equivalent OpenSG matrix.

Definition at line 43 of file OpenSGConvert.h.

{
   osgMat.setValue(mat.getData());
   return osgMat;
}

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Quat<DATA_TYPE>& gmtl::set ( Quat< DATA_TYPE > &  quat,
const Matrix< DATA_TYPE, ROWS, COLS > &  mat 
) [inline]

Convert a Matrix to a Quat.

Sets the rotation quaternion using the given matrix (3x3, 3x4, 4x3, or 4x4 are all valid sizes).

Definition at line 279 of file Generate.h.

   {
      gmtlASSERT( ((ROWS == 3 && COLS == 3) ||
               (ROWS == 3 && COLS == 4) ||
               (ROWS == 4 && COLS == 3) ||
               (ROWS == 4 && COLS == 4)) &&
               "pre conditions not met on set( quat, pos, mat ) which only sets a quaternion to the rotation part of a 3x3, 3x4, 4x3, or 4x4 matrix." );

      DATA_TYPE tr( mat( 0, 0 ) + mat( 1, 1 ) + mat( 2, 2 ) ), s( 0.0f );

      // If diagonal is positive
      if (tr > (DATA_TYPE)0.0)
      {
         s = Math::sqrt( tr + (DATA_TYPE)1.0 );
         quat[Welt] = s * (DATA_TYPE)0.5;
         s = DATA_TYPE(0.5) / s;

         quat[Xelt] = (mat( 2, 1 ) - mat( 1, 2 )) * s;
         quat[Yelt] = (mat( 0, 2 ) - mat( 2, 0 )) * s;
         quat[Zelt] = (mat( 1, 0 ) - mat( 0, 1 )) * s;
      }

      // when Diagonal is negative
      else
      {
         static const unsigned int nxt[3] = { 1, 2, 0 };
         unsigned int i( Xelt ), j, k;

         if (mat( 1, 1 ) > mat( 0, 0 ))
            i = 1;

         if (mat( 2, 2 ) > mat( i, i ))
            i = 2;

         j = nxt[i];
         k = nxt[j];

         s = Math::sqrt( (mat( i, i )-(mat( j, j )+mat( k, k ))) + (DATA_TYPE)1.0 );

         DATA_TYPE q[4];
         q[i] = s * (DATA_TYPE)0.5;

         if (s != (DATA_TYPE)0.0)
            s = DATA_TYPE(0.5) / s;

         q[3] = (mat( k, j ) - mat( j, k )) * s;
         q[j] = (mat( j, i ) + mat( i, j )) * s;
         q[k] = (mat( k, i ) + mat( i, k )) * s;

         quat[Xelt] = q[0];
         quat[Yelt] = q[1];
         quat[Zelt] = q[2];
         quat[Welt] = q[3];
      }

      return quat;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, typename ROT_ORDER >
EulerAngle<DATA_TYPE, ROT_ORDER>& gmtl::set ( EulerAngle< DATA_TYPE, ROT_ORDER > &  euler,
const Matrix< DATA_TYPE, ROWS, COLS > &  mat 
) [inline]

Convert Matrix to EulerAngle.

Set the Euler Angle from the given rotation portion (3x3) of the matrix.

Parameters:
input order, mat
output param0, param1, param2
Precondition:
pass in your args in the same order as the RotationOrder you specify
Postcondition:
this function only reads 3x3, 3x4, 4x3, and 4x4 matrices, and is undefined otherwise NOTE: Angles are returned in radians (this is always true in GMTL).

Definition at line 437 of file Generate.h.

   {
      // @todo set this a compile time assert...
      gmtlASSERT( ROWS >= 3 && COLS >= 3 && ROWS <= 4 && COLS <= 4 &&
            "this is undefined for Matrix smaller than 3x3 or bigger than 4x4" );

      // @todo metaprogram this!
      const int& order = ROT_ORDER::ID;
      switch (order)
      {
      case XYZ::ID:
         {
#if 0
            euler[2] = Math::aTan2( -mat(0,1), mat(0,0) );       // -(-cy*sz)/(cy*cz) - cy falls out
            euler[0] = Math::aTan2( -mat(1,2), mat(2,2) );       // -(sx*cy)/(cx*cy) - cy falls out
            DATA_TYPE cz = Math::cos( euler[2] );
            euler[1] = Math::aTan2( mat(0,2), mat(0,0) / cz );   // (sy)/((cy*cz)/cz)
#else
            DATA_TYPE x(0), y(0), z(0);
            y = Math::aSin( mat(0,2));
            if (y < gmtl::Math::PI_OVER_2)
            {
               if(y > -gmtl::Math::PI_OVER_2)
               {
                  x = Math::aTan2(-mat(1,2),mat(2,2));
                  z = Math::aTan2(-mat(0,1),mat(0,0));
               }
               else  // Non-unique (x - z constant)
               {
                  x = -Math::aTan2(mat(1,0), mat(1,1));
                  z = 0;
               }
            }
            else
            {
               // not unique (x + z constant)
               x = Math::aTan2(mat(1,0), mat(1,1));
               z = 0;
            }
            euler[0] = x;
            euler[1] = y;
            euler[2] = z;

#endif
         }
         break;
      case ZYX::ID:
         {
#if 0
            euler[0] = Math::aTan2( mat(1,0), mat(0,0) );        // (cy*sz)/(cy*cz) - cy falls out
            euler[2] = Math::aTan2( mat(2,1), mat(2,2) );        // (sx*cy)/(cx*cy) - cy falls out
            DATA_TYPE sx = Math::sin( euler[2] );
            euler[1] = Math::aTan2( -mat(2,0), mat(2,1) / sx );  // -(-sy)/((sx*cy)/sx)
#else
            DATA_TYPE x(0), y(0), z(0);

            y = Math::aSin(-mat(2,0));
            if(y < Math::PI_OVER_2)
            {
               if(y>-Math::PI_OVER_2)
               {
                  z = Math::aTan2(mat(1,0), mat(0,0));
                  x = Math::aTan2(mat(2,1), mat(2,2));
               }
               else  // not unique (x + z constant)
               {
                  z = Math::aTan2(-mat(0,1),-mat(0,2));
                  x = 0;
               }
            }
            else  // not unique (x - z constant)
            {
               z = -Math::aTan2(mat(0,1), mat(0,2));
               x = 0;
            }
            euler[0] = z;
            euler[1] = y;
            euler[2] = x;
#endif
         }
         break;
      case ZXY::ID:
         {
#if 0
         // Extract the rotation directly from the matrix
            DATA_TYPE x_angle;
            DATA_TYPE y_angle;
            DATA_TYPE z_angle;
            DATA_TYPE cos_y, sin_y;
            DATA_TYPE cos_x, sin_x;
            DATA_TYPE cos_z, sin_z;

            sin_x = mat(2,1);
            x_angle = Math::aSin( sin_x );     // Get x angle
            cos_x = Math::cos( x_angle );

            // Check if cos_x = Zero
            if (cos_x != 0.0f)     // ASSERT: cos_x != 0
            {
                  // Get y Angle
               cos_y = mat(2,2) / cos_x;
               sin_y = -mat(2,0) / cos_x;
               y_angle = Math::aTan2( cos_y, sin_y );

                  // Get z Angle
               cos_z = mat(1,1) / cos_x;
               sin_z = -mat(0,1) / cos_x;
               z_angle = Math::aTan2( cos_z, sin_z );
            }
            else
            {
               // Arbitrarily set z_angle = 0
               z_angle = 0;

                  // Get y Angle
               cos_y = mat(0,0);
               sin_y = mat(1,0);
               y_angle = Math::aTan2( cos_y, sin_y );
            }

            euler[1] = x_angle;
            euler[2] = y_angle;
            euler[0] = z_angle;
#else
            DATA_TYPE x,y,z;

            x = Math::aSin(mat(2,1));
            if(x < Math::PI_OVER_2)
            {
               if(x > -Math::PI_OVER_2)
               {
                  z = Math::aTan2(-mat(0,1), mat(1,1));
                  y = Math::aTan2(-mat(2,0), mat(2,2));
               }
               else  // not unique (y - z constant)
               {
                  z = -Math::aTan2(mat(0,2), mat(0,0));
                  y = 0;
               }
            }
            else  // not unique (y + z constant)
            {
               z = Math::aTan2(mat(0,2), mat(0,0));
               y = 0;
            }
            euler[0] = z;
            euler[1] = x;
            euler[2] = y;
#endif
         }
         break;
      default:
         gmtlASSERT( false && "unknown rotation order passed to setRot" );
         break;
      }
      return euler;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::setAxes ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Vec< DATA_TYPE, 3 > &  xAxis,
const Vec< DATA_TYPE, 3 > &  yAxis,
const Vec< DATA_TYPE, 3 > &  zAxis 
) [inline]

set the matrix given the raw coordinate axes.

Postcondition:
this function only produces 3x3, 3x4, 4x3, and 4x4 matrices, and is undefined otherwise
these axes are copied direct to the 3x3 in the matrix

Definition at line 1071 of file Generate.h.

   {
      // @todo set this a compile time assert...
      gmtlASSERT( ROWS >= 3 && COLS >= 3 && ROWS <= 4 && COLS <= 4 && "this is undefined for Matrix smaller than 3x3 or bigger than 4x4" );

      result( 0, 0 ) = xAxis[0];
      result( 1, 0 ) = xAxis[1];
      result( 2, 0 ) = xAxis[2];

      result( 0, 1 ) = yAxis[0];
      result( 1, 1 ) = yAxis[1];
      result( 2, 1 ) = yAxis[2];

      result( 0, 2 ) = zAxis[0];
      result( 1, 2 ) = zAxis[1];
      result( 2, 2 ) = zAxis[2];

      // track state
      switch (result.mState)
      {
      case Matrix<DATA_TYPE, ROWS, COLS>::TRANS:    result.mState = Matrix<DATA_TYPE, ROWS, COLS>::AFFINE; break;
      case Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY: result.mState = Matrix<DATA_TYPE, ROWS, COLS>::ORTHOGONAL; break;
      }
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
void gmtl::setColumn ( Vec< DATA_TYPE, ROWS > &  dest,
const Matrix< DATA_TYPE, ROWS, COLS > &  src,
unsigned  col 
)

Accesses a particular column in the matrix by copying the values in the column into the given vector.

Parameters:
dest the vector in which the values of the column will be placed
src the matrix being accessed
col the column of the matrix to access

Definition at line 1445 of file Generate.h.

   {
      for (unsigned i=0; i<ROWS; ++i)
      {
         dest[i] = src[i][col];
      }
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::setDirCos ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Vec< DATA_TYPE, 3 > &  xDestAxis,
const Vec< DATA_TYPE, 3 > &  yDestAxis,
const Vec< DATA_TYPE, 3 > &  zDestAxis,
const Vec< DATA_TYPE, 3 > &  xSrcAxis = Vec<DATA_TYPE, 3>(1,0,0),
const Vec< DATA_TYPE, 3 > &  ySrcAxis = Vec<DATA_TYPE, 3>(0,1,0),
const Vec< DATA_TYPE, 3 > &  zSrcAxis = Vec<DATA_TYPE, 3>(0,0,1) 
) [inline]

create a rotation matrix that will rotate from SrcAxis to DestAxis.

xSrcAxis, ySrcAxis, zSrcAxis is the base rotation to go from and defaults to xSrcAxis(1,0,0), ySrcAxis(0,1,0), zSrcAxis(0,0,1) if you only pass in 3 axes.

If the two coordinate frames are labeled: SRC and TARGET, the matrix produced is: src_M_target this means that it will transform a point in TARGET to SRC but moves the base frame from SRC to TARGET.

Precondition:
pass in 3 axes, and setDirCos will give you the rotation from MATRIX_IDENTITY to DestAxis
pass in 6 axes, and setDirCos will give you the rotation from your 3-axis rotation to your second 3-axis rotation
Postcondition:
this function only produces 3x3, 3x4, 4x3, and 4x4 matrices

Definition at line 1033 of file Generate.h.

   {
      // @todo set this a compile time assert...
      gmtlASSERT( ROWS >= 3 && COLS >= 3 && ROWS <= 4 && COLS <= 4 && "this is undefined for Matrix smaller than 3x3 or bigger than 4x4" );

      DATA_TYPE Xa, Xb, Xc;    // Direction cosines of the secondary x-axis
      DATA_TYPE Ya, Yb, Yc;    // Direction cosines of the secondary y-axis
      DATA_TYPE Za, Zb, Zc;    // Direction cosines of the secondary z-axis

      Xa = dot(xDestAxis, xSrcAxis);  Xb = dot(xDestAxis, ySrcAxis);  Xc = dot(xDestAxis, zSrcAxis);
      Ya = dot(yDestAxis, xSrcAxis);  Yb = dot(yDestAxis, ySrcAxis);  Yc = dot(yDestAxis, zSrcAxis);
      Za = dot(zDestAxis, xSrcAxis);  Zb = dot(zDestAxis, ySrcAxis);  Zc = dot(zDestAxis, zSrcAxis);

      // Set the matrix correctly
      result( 0, 0 ) = Xa; result( 0, 1 ) = Ya; result( 0, 2 ) = Za;
      result( 1, 0 ) = Xb; result( 1, 1 ) = Yb; result( 1, 2 ) = Zb;
      result( 2, 0 ) = Xc; result( 2, 1 ) = Yc; result( 2, 2 ) = Zc;

      // track state
      switch (result.mState)
      {
      case Matrix<DATA_TYPE, ROWS, COLS>::TRANS:    result.mState = Matrix<DATA_TYPE, ROWS, COLS>::AFFINE; break;
      case Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY: result.mState = Matrix<DATA_TYPE, ROWS, COLS>::ORTHOGONAL; break;
      }

      return result;
   }

template<typename T >
Matrix<T, 4,4>& gmtl::setFrustum ( Matrix< T, 4, 4 > &  result,
left,
top,
right,
bottom,
nr,
fr 
) [inline]

Set an arbitrary projection matrix.

Returns:
: set a projection matrix (similar to glFrustum).

Definition at line 615 of file Generate.h.

   {
      result.mData[0] = ( T( 2.0 ) * nr ) / ( right - left );
      result.mData[1] = T( 0.0 );
      result.mData[2] = T( 0.0 );
      result.mData[3] = T( 0.0 );

      result.mData[4] = T( 0.0 );
      result.mData[5] = ( T( 2.0 ) * nr ) / ( top - bottom );
      result.mData[6] = T( 0.0 );
      result.mData[7] = T( 0.0 );

      result.mData[8] = ( right + left ) / ( right - left );
      result.mData[9] = ( top + bottom ) / ( top - bottom );
      result.mData[10] = -( fr + nr ) / ( fr - nr );
      result.mData[11] = T( -1.0 );

      result.mData[12] = T( 0.0 );
      result.mData[13] = T( 0.0 );
      result.mData[14] = -( T( 2.0 ) * fr * nr ) / ( fr - nr );
      result.mData[15] = T( 0.0 );

      result.mState = Matrix<T, 4, 4>::FULL; // track state

      return result;
   }

template<typename T >
Matrix<T, 4,4>& gmtl::setOrtho ( Matrix< T, 4, 4 > &  result,
left,
top,
right,
bottom,
nr,
fr 
) [inline]

Set an orthographic projection matrix creates a transformation that produces a parallel projection matrix.

= -nr is the value of the near clipping plane (positive value for near is negative in the z direction) = -fr is the value of the far clipping plane (positive value for far is negative in the z direction)

Returns:
: set a orthographic matrix (similar to glOrtho).

Definition at line 651 of file Generate.h.

   {
      result.mData[1] = result.mData[2] = result.mData[3] =
      result.mData[4] = result.mData[6] = result.mData[7] =
      result.mData[8] = result.mData[9] = result.mData[11] = T(0);

      T rl_inv = T(1) / (right - left);
      T tb_inv = T(1) / (top - bottom);
      T nf_inv = T(1) / (fr - nr);

      result.mData[0] =  T(2) * rl_inv;
      result.mData[5] =  T(2) * tb_inv;
      result.mData[10] = -T(2) * nf_inv;

      result.mData[12] = -(right + left) * rl_inv;
      result.mData[13] = -(top + bottom) * tb_inv;
      result.mData[14] = -(fr + nr) * nf_inv;
      result.mData[15] = T(1);

      return result;
   }

template<typename T >
Matrix<T, 4,4>& gmtl::setPerspective ( Matrix< T, 4, 4 > &  result,
fovy,
aspect,
nr,
fr 
) [inline]

Set a symmetric perspective projection matrix.

Parameters:
fovy The field of view angle, in degrees, about the y-axis.
aspect The aspect ratio that determines the field of view about the x-axis. The aspect ratio is the ratio of x (width) to y (height).
zNear The distance from the viewer to the near clipping plane (always positive).
zFar The distance from the viewer to the far clipping plane (always positive).
Returns:
Set matrix to perspective transform

Definition at line 688 of file Generate.h.

   {
      gmtlASSERT( nr > 0 && fr > nr && "invalid near and far values" );
      T theta = Math::deg2Rad( fovy * T( 0.5 ) );
      T tangentTheta = Math::tan( theta );

      // tan(theta) = right / nr
      // top = tan(theta) * nr
      // right = tan(theta) * nr * aspect

      T top = tangentTheta * nr;
      T right = top * aspect; // aspect determines the fieald of view in the x-axis

      // TODO: args need to match...
      return setFrustum( result, -right, top, right, -top, nr, fr );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::setPure ( Quat< DATA_TYPE > &  quat,
const Vec< DATA_TYPE, 3 > &  vec 
) [inline]

Set pure quaternion.

Precondition:
vec should be normalized
Parameters:
quat any quaternion object
vec a normalized vector representing an axis
Postcondition:
quat will have vec as its axis, and no rotation

Definition at line 125 of file Generate.h.

   {
      quat.set( vec[0], vec[1], vec[2], 0 );
      return quat;
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::setRot ( Quat< DATA_TYPE > &  result,
const AxisAngle< DATA_TYPE > &  axisAngle 
) [inline]

Redundant duplication of the set(quat,axisangle) function, this is provided only for template compatibility.

unless you're writing template functions, you should use set(quat,axisangle).

Definition at line 205 of file Generate.h.

   {
      return gmtl::set( result, axisAngle );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::setRot ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const AxisAngle< DATA_TYPE > &  axisAngle 
) [inline]

Set the rotation portion of a rotation matrix using an axis and an angle (in radians).

Only writes to the rotation matrix (3x3) defined by the rotation part of M

Postcondition:
this function only writes to 3x3, 3x4, 4x3, and 4x4 matrices, and is undefined otherwise
Precondition:
you must pass a normalized vector in for the axis, results are undefined if not.

Definition at line 817 of file Generate.h.

   {
      /* @todo set this a compile time assert... */
      gmtlASSERT( ROWS >= 3 && COLS >= 3 && ROWS <= 4 && COLS <= 4 &&
                     "this func is undefined for Matrix smaller than 3x3 or bigger than 4x4" );
      gmtlASSERT( Math::isEqual( lengthSquared( axisAngle.getAxis() ), (DATA_TYPE)1.0, (DATA_TYPE)0.001 ) /* &&
                     "you must pass in a normalized vector to setRot( mat, rad, vec )" */ );

      // GGI: pg 466
      DATA_TYPE s = Math::sin( axisAngle.getAngle() );
      DATA_TYPE c = Math::cos( axisAngle.getAngle() );
      DATA_TYPE t = DATA_TYPE( 1.0 ) - c;
      DATA_TYPE x = axisAngle.getAxis()[0];
      DATA_TYPE y = axisAngle.getAxis()[1];
      DATA_TYPE z = axisAngle.getAxis()[2];

      /* From: Introduction to robotic.  Craig.  Pg. 52 */
      result( 0, 0 ) = (t*x*x)+c;     result( 0, 1 ) = (t*x*y)-(s*z); result( 0, 2 ) = (t*x*z)+(s*y);
      result( 1, 0 ) = (t*x*y)+(s*z); result( 1, 1 ) = (t*y*y)+c;     result( 1, 2 ) = (t*y*z)-(s*x);
      result( 2, 0 ) = (t*x*z)-(s*y); result( 2, 1 ) = (t*y*z)+(s*x); result( 2, 2 ) = (t*z*z)+c;

      // track state
      switch (result.mState)
      {
      case Matrix<DATA_TYPE, ROWS, COLS>::TRANS:    result.mState = Matrix<DATA_TYPE, ROWS, COLS>::AFFINE; break;
      case Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY: result.mState = Matrix<DATA_TYPE, ROWS, COLS>::ORTHOGONAL; break;
      }
      return result;
   }

template<typename DATA_TYPE >
AxisAngle<DATA_TYPE>& gmtl::setRot ( AxisAngle< DATA_TYPE > &  result,
Quat< DATA_TYPE >  quat 
) [inline]

Redundant duplication of the set(axisangle,quat) function, this is provided only for template compatibility.

unless you're writing template functions, you should use set(axisangle,quat) for clarity.

Definition at line 408 of file Generate.h.

   {
      return gmtl::set( result, quat );
   }

template<typename DATATYPE , typename POS_TYPE , typename ROT_TYPE , unsigned MATCOLS, unsigned MATROWS>
Coord<POS_TYPE, ROT_TYPE>& gmtl::setRot ( Coord< POS_TYPE, ROT_TYPE > &  result,
const Matrix< DATATYPE, MATROWS, MATCOLS > &  mat 
) [inline]

Redundant duplication of the set(coord,mat) function, this is provided only for template compatibility.

unless you're writing template functions, you should use set(coord,mat) for clarity.

Definition at line 1254 of file Generate.h.

   {
      return gmtl::set( result, mat );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, typename ROT_ORDER >
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::setRot ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const EulerAngle< DATA_TYPE, ROT_ORDER > &  euler 
) [inline]

Set (only) the rotation part of a matrix using an EulerAngle (angles are in radians).

Postcondition:
this function only produces 3x3, 3x4, 4x3, and 4x4 matrices, and is undefined otherwise
See also:
EulerAngle for angle ordering (usually ordered based on RotationOrder)

Definition at line 852 of file Generate.h.

   {
      // @todo set this a compile time assert...
      gmtlASSERT( ROWS >= 3 && COLS >= 3 && ROWS <= 4 && COLS <= 4 && "this is undefined for Matrix smaller than 3x3 or bigger than 4x4" );

      // this might be faster if put into the switch statement... (testme)
      const int& order = ROT_ORDER::ID;
      const DATA_TYPE xRot = (order == XYZ::ID) ? euler[0] : ((order == ZXY::ID) ? euler[1] : euler[2]);
      const DATA_TYPE yRot = (order == XYZ::ID) ? euler[1] : ((order == ZXY::ID) ? euler[2] : euler[1]);
      const DATA_TYPE zRot = (order == XYZ::ID) ? euler[2] : ((order == ZXY::ID) ? euler[0] : euler[0]);

      DATA_TYPE sx = Math::sin( xRot );  DATA_TYPE cx = Math::cos( xRot );
      DATA_TYPE sy = Math::sin( yRot );  DATA_TYPE cy = Math::cos( yRot );
      DATA_TYPE sz = Math::sin( zRot );  DATA_TYPE cz = Math::cos( zRot );

      // @todo metaprogram this!
      switch (order)
      {
      case XYZ::ID:
         // Derived by simply multiplying out the matrices by hand X * Y * Z
         result( 0, 0 ) = cy*cz;             result( 0, 1 ) = -cy*sz;            result( 0, 2 ) = sy;
         result( 1, 0 ) = sx*sy*cz + cx*sz;  result( 1, 1 ) = -sx*sy*sz + cx*cz; result( 1, 2 ) = -sx*cy;
         result( 2, 0 ) = -cx*sy*cz + sx*sz; result( 2, 1 ) = cx*sy*sz + sx*cz;  result( 2, 2 ) = cx*cy;
         break;
      case ZYX::ID:
         // Derived by simply multiplying out the matrices by hand Z * Y * Z
         result( 0, 0 ) = cy*cz; result( 0, 1 ) = -cx*sz + sx*sy*cz; result( 0, 2 ) = sx*sz + cx*sy*cz;
         result( 1, 0 ) = cy*sz; result( 1, 1 ) = cx*cz + sx*sy*sz;  result( 1, 2 ) = -sx*cz + cx*sy*sz;
         result( 2, 0 ) = -sy;   result( 2, 1 ) = sx*cy;             result( 2, 2 ) = cx*cy;
         break;
      case ZXY::ID:
         // Derived by simply multiplying out the matrices by hand Z * X * Y
         result( 0, 0 ) = cy*cz - sx*sy*sz; result( 0, 1 ) = -cx*sz; result( 0, 2 ) = sy*cz + sx*cy*sz;
         result( 1, 0 ) = cy*sz + sx*sy*cz; result( 1, 1 ) = cx*cz;  result( 1, 2 ) = sy*sz - sx*cy*cz;
         result( 2, 0 ) = -cx*sy;           result( 2, 1 ) = sx;     result( 2, 2 ) = cx*cy;
         break;
      default:
         gmtlASSERT( false && "unknown rotation order passed to setRot" );
         break;
      }

      // track state
      switch (result.mState)
      {
      case Matrix<DATA_TYPE, ROWS, COLS>::TRANS:    result.mState = Matrix<DATA_TYPE, ROWS, COLS>::AFFINE; break;
      case Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY: result.mState = Matrix<DATA_TYPE, ROWS, COLS>::ORTHOGONAL; break;
      }
      return result;
   }

template<typename DATA_TYPE , typename ROT_ORDER >
Quat<DATA_TYPE>& gmtl::setRot ( Quat< DATA_TYPE > &  result,
const EulerAngle< DATA_TYPE, ROT_ORDER > &  euler 
) [inline]

Redundant duplication of the set(quat,eulerangle) function, this is provided only for template compatibility.

unless you're writing template functions, you should use set(quat,eulerangle).

Definition at line 269 of file Generate.h.

   {
      return gmtl::set( result, euler );
   }

template<typename DEST_TYPE , typename DATA_TYPE >
DEST_TYPE& gmtl::setRot ( DEST_TYPE &  result,
const Vec< DATA_TYPE, 3 > &  from,
const Vec< DATA_TYPE, 3 > &  to 
) [inline]

set a rotation datatype that will xform first vector to the second.

Precondition:
each vec needs to be normalized.
Postcondition:
generate rotation datatype that is the rotation between the vectors.
Note:
: only sets the rotation component of result, if result is a matrix, only sets the 3x3.

Definition at line 1364 of file Generate.h.

   {
      // @todo should assert that DEST_TYPE::DataType == DATA_TYPE
      const DATA_TYPE epsilon = (DATA_TYPE)0.00001;

      gmtlASSERT( gmtl::Math::isEqual( gmtl::length( from ), (DATA_TYPE)1.0, epsilon ) &&
                  gmtl::Math::isEqual( gmtl::length( to ), (DATA_TYPE)1.0, epsilon ) /* &&
                  "input params not normalized" */);

      DATA_TYPE cosangle = dot( from, to );

      // if cosangle is close to 1, so the vectors are close to being coincident
      // Need to generate an angle of zero with any vector we like
      // We'll choose identity (no rotation)
      if ( Math::isEqual( cosangle, (DATA_TYPE)1.0, epsilon ) )
      {
         return result = DEST_TYPE();
      }

      // vectors are close to being opposite, so rotate one a little...
      else if ( Math::isEqual( cosangle, (DATA_TYPE)-1.0, epsilon ) )
      {
         Vec<DATA_TYPE, 3> to_rot( to[0] + (DATA_TYPE)0.3, to[1] - (DATA_TYPE)0.15, to[2] - (DATA_TYPE)0.15 ), axis;
         normalize( cross( axis, from, to_rot ) ); // setRot requires normalized vec
         DATA_TYPE angle = Math::aCos( cosangle );
         return setRot( result, gmtl::AxisAngle<DATA_TYPE>( angle, axis ) );
      }

      // This is the usual situation - take a cross-product of vec1 and vec2
      // and that is the axis around which to rotate.
      else
      {
         Vec<DATA_TYPE, 3> axis;
         normalize( cross( axis, from, to ) ); // setRot requires normalized vec
         DATA_TYPE angle = Math::aCos( cosangle );
         return setRot( result, gmtl::AxisAngle<DATA_TYPE>( angle, axis ) );
      }
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::setRot ( Matrix< DATA_TYPE, ROWS, COLS > &  mat,
const Quat< DATA_TYPE > &  q 
)

Set the rotation portion of a matrix (3x3) from a rotation quaternion.

Precondition:
only 3x3, 3x4, 4x3, or 4x4 matrices are allowed, function is undefined otherwise.

Definition at line 1144 of file Generate.h.

   {
      gmtlASSERT( ((ROWS == 3 && COLS == 3) ||
               (ROWS == 3 && COLS == 4) ||
               (ROWS == 4 && COLS == 3) ||
               (ROWS == 4 && COLS == 4)) &&
               "pre conditions not met on set( mat, quat ) which only sets a quaternion to the rotation part of a 3x3, 3x4, 4x3, or 4x4 matrix." );

      // From Watt & Watt
      DATA_TYPE wx, wy, wz, xx, yy, yz, xy, xz, zz, xs, ys, zs;

      xs = q[Xelt] + q[Xelt]; ys = q[Yelt] + q[Yelt]; zs = q[Zelt] + q[Zelt];
      xx = q[Xelt] * xs;      xy = q[Xelt] * ys;      xz = q[Xelt] * zs;
      yy = q[Yelt] * ys;      yz = q[Yelt] * zs;      zz = q[Zelt] * zs;
      wx = q[Welt] * xs;      wy = q[Welt] * ys;      wz = q[Welt] * zs;

      mat( 0, 0 ) = DATA_TYPE(1.0) - (yy + zz);
      mat( 1, 0 ) = xy + wz;
      mat( 2, 0 ) = xz - wy;

      mat( 0, 1 ) = xy - wz;
      mat( 1, 1 ) = DATA_TYPE(1.0) - (xx + zz);
      mat( 2, 1 ) = yz + wx;

      mat( 0, 2 ) = xz + wy;
      mat( 1, 2 ) = yz - wx;
      mat( 2, 2 ) = DATA_TYPE(1.0) - (xx + yy);

      // track state
      switch (mat.mState)
      {
      case Matrix<DATA_TYPE, ROWS, COLS>::TRANS:    mat.mState = Matrix<DATA_TYPE, ROWS, COLS>::AFFINE; break;
      case Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY: mat.mState = Matrix<DATA_TYPE, ROWS, COLS>::ORTHOGONAL; break;
      }
      return mat;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Quat<DATA_TYPE>& gmtl::setRot ( Quat< DATA_TYPE > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  mat 
) [inline]

Redundant duplication of the set(quat,mat) function, this is provided only for template compatibility.

unless you're writing template functions, you should use set(quat,mat).

Definition at line 341 of file Generate.h.

   {
      return gmtl::set( result, mat );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, typename ROT_ORDER >
EulerAngle<DATA_TYPE, ROT_ORDER>& gmtl::setRot ( EulerAngle< DATA_TYPE, ROT_ORDER > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  mat 
) [inline]

Redundant duplication of the set(eulerangle,quat) function, this is provided only for template compatibility.

unless you're writing template functions, you should use set(eulerangle,quat) for clarity.

Definition at line 600 of file Generate.h.

   {
      return gmtl::set( result, mat );
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
void gmtl::setRow ( Vec< DATA_TYPE, COLS > &  dest,
const Matrix< DATA_TYPE, ROWS, COLS > &  src,
unsigned  row 
)

Accesses a particular row in the matrix by copying the values in the row into the given vector.

Parameters:
dest the vector in which the values of the row will be placed
src the matrix being accessed
row the row of the matrix to access

Definition at line 1413 of file Generate.h.

   {
      for (unsigned i=0; i<COLS; ++i)
      {
         dest[i] = src[row][i];
      }
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned SIZE>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::setScale ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Vec< DATA_TYPE, SIZE > &  scale 
) [inline]

Set the scale part of a matrix.

Definition at line 770 of file Generate.h.

   {
      gmtlASSERT( ((SIZE == (ROWS-1) && SIZE == (COLS-1)) || (SIZE == (ROWS-1) && SIZE == COLS) || (SIZE == (COLS-1) && SIZE == ROWS)) && "the scale params must fit within the matrix, check your sizes." );
      for (unsigned x = 0; x < SIZE; ++x)
      {
         result( x, x ) = scale[x];
      }
      // track state: affine matrix with non-uniform scale now.
      result.mState = Matrix<DATA_TYPE, ROWS, COLS>::AFFINE;
      result.mState |= Matrix<DATA_TYPE, ROWS, COLS>::NON_UNISCALE;
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::setScale ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const DATA_TYPE  scale 
) [inline]

Sets the scale part of a matrix.

Definition at line 786 of file Generate.h.

   {
      for (unsigned x = 0; x < Math::Min( ROWS, COLS, Math::Max( ROWS, COLS ) - 1 ); ++x) // account for 2x4 or other weird sizes...
      {
         result( x, x ) = scale;
      }
      // track state: affine matrix with non-uniform scale now.
      result.mState = Matrix<DATA_TYPE, ROWS, COLS>::AFFINE;
      result.mState |= Matrix<DATA_TYPE, ROWS, COLS>::NON_UNISCALE;
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned SIZE, typename REP >
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::setTrans ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const VecBase< DATA_TYPE, SIZE, REP > &  trans 
) [inline]

Set matrix translation from vec.

Precondition:
if making an n x n matrix, then for
  • vector is homogeneous: SIZE of vector needs to equal number of Matrix ROWS - 1
  • vector has scale component: SIZE of vector needs to equal number of Matrix ROWS if making an n x n+1 matrix, then for
  • vector is homogeneous: SIZE of vector needs to equal number of Matrix ROWS
  • vector has scale component: SIZE of vector needs to equal number of Matrix ROWS + 1
Postcondition:
if preconditions are not met, then function is undefined (will not compile)

Definition at line 732 of file Generate.h.

   {
      /* @todo make this a compile time assert... */
      // if n x n   then (homogeneous case) vecsize == rows-1 or (scale component case) vecsize == rows
      // if n x n+1 then (homogeneous case) vecsize == rows   or (scale component case) vecsize == rows+1
      gmtlASSERT( ((ROWS == COLS && (SIZE == (ROWS-1) || SIZE == ROWS)) ||
               (COLS == (ROWS+1) && (SIZE == ROWS || SIZE == (ROWS+1)))) &&
              "preconditions not met for vector size in call to makeTrans.  Read your documentation." );

      // homogeneous case...
      if ((ROWS == COLS && SIZE == ROWS) /* Square matrix and vec so assume homogeneous vector. ex. 4x4 with vec 4 */
          || (COLS == (ROWS+1) && SIZE == (ROWS+1)))  /* ex: 3x4 with vec4 */
      {
         DATA_TYPE homog_val = trans[SIZE-1];
         for (unsigned x = 0; x < COLS - 1; ++x)
            result( x, COLS - 1 ) = trans[x] / homog_val;
      }

      // non-homogeneous case...
      else
      {
         for (unsigned x = 0; x < COLS - 1; ++x)
            result( x, COLS - 1 ) = trans[x];
      }
      // track state, only override identity
      switch (result.mState)
      {
      case Matrix<DATA_TYPE, ROWS, COLS>::ORTHOGONAL: result.mState = Matrix<DATA_TYPE, ROWS, COLS>::AFFINE; break;
      case Matrix<DATA_TYPE, ROWS, COLS>::IDENTITY:   result.mState = Matrix<DATA_TYPE, ROWS, COLS>::TRANS; break;
      }
      return result;
   }

template<typename VEC_TYPE , typename DATA_TYPE , unsigned ROWS, unsigned COLS>
VEC_TYPE& gmtl::setTrans ( VEC_TYPE &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  arg 
) [inline]

Set vector using translation portion of the matrix.

Precondition:
if making an n x n matrix, then for
  • vector is homogeneous: SIZE of vector needs to equal number of Matrix ROWS - 1
  • vector has scale component: SIZE of vector needs to equal number of Matrix ROWS if making an n x n+1 matrix, then for
  • vector is homogeneous: SIZE of vector needs to equal number of Matrix ROWS
  • vector has scale component: SIZE of vector needs to equal number of Matrix ROWS + 1
Postcondition:
if preconditions are not met, then function is undefined (will not compile)

Definition at line 82 of file Generate.h.

   {
      // ASSERT: There are as many

      // if n x n   then (homogeneous case) vecsize == rows-1 or (scale component case) vecsize == rows
      // if n x n+1 then (homogeneous case) vecsize == rows   or (scale component case) vecsize == rows+1
      gmtlASSERT( ((ROWS == COLS && ( VEC_TYPE::Size == (ROWS-1) ||  VEC_TYPE::Size == ROWS)) ||
               (COLS == (ROWS+1) && ( VEC_TYPE::Size == ROWS ||  VEC_TYPE::Size == (ROWS+1)))) &&
              "preconditions not met for vector size in call to makeTrans.  Read your documentation." );

      // homogeneous case...
      if ((ROWS == COLS &&  VEC_TYPE::Size == ROWS)              // Square matrix and vec so assume homogeneous vector. ex. 4x4 with vec 4
          || (COLS == (ROWS+1) &&  VEC_TYPE::Size == (ROWS+1)))  // ex: 3x4 with vec4
      {
         result[VEC_TYPE::Size-1] = 1.0f;
      }

      // non-homogeneous case... (SIZE == ROWS),
      //else
      //{}

      for (unsigned x = 0; x < COLS - 1; ++x)
      {
         result[x] = arg( x, COLS - 1 );
      }

      return result;
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::slerp ( Quat< DATA_TYPE > &  result,
const DATA_TYPE  t,
const Quat< DATA_TYPE > &  from,
const Quat< DATA_TYPE > &  to,
bool  adjustSign = true 
)

spherical linear interpolation between two rotation quaternions.

t is a value between 0 and 1 that interpolates between from and to.

Precondition:
no aliasing problems to worry about ("result" can be "from" or "to" param).
Parameters:
adjustSign - If true, then slerp will operate by adjusting the sign of the slerp to take shortest path

References:

  • From Adv Anim and Rendering Tech. Pg 364
See also:
Quat

Definition at line 497 of file QuatOps.h.

   {
      const Quat<DATA_TYPE>& p = from; // just an alias to match q

      // calc cosine theta
      DATA_TYPE cosom = dot( from, to );

      // adjust signs (if necessary)
      Quat<DATA_TYPE> q;
      if (adjustSign && (cosom < (DATA_TYPE)0.0))
      {
         cosom = -cosom;
         q[0] = -to[0];   // Reverse all signs
         q[1] = -to[1];
         q[2] = -to[2];
         q[3] = -to[3];
      }
      else
      {
         q = to;
      }

      // Calculate coefficients
      DATA_TYPE sclp, sclq;
      if (((DATA_TYPE)1.0 - cosom) > (DATA_TYPE)0.0001) // 0.0001 -> some epsillon
      {
         // Standard case (slerp)
         DATA_TYPE omega, sinom;
         omega = gmtl::Math::aCos( cosom ); // extract theta from dot product's cos theta
         sinom = gmtl::Math::sin( omega );
         sclp  = gmtl::Math::sin( ((DATA_TYPE)1.0 - t) * omega ) / sinom;
         sclq  = gmtl::Math::sin( t * omega ) / sinom;
      }
      else
      {
         // Very close, do linear interp (because it's faster)
         sclp = (DATA_TYPE)1.0 - t;
         sclq = t;
      }

      result[Xelt] = sclp * p[Xelt] + sclq * q[Xelt];
      result[Yelt] = sclp * p[Yelt] + sclq * q[Yelt];
      result[Zelt] = sclp * p[Zelt] + sclq * q[Zelt];
      result[Welt] = sclp * p[Welt] + sclq * q[Welt];
      return result;
   }

template<typename DATA_TYPE >
void gmtl::squad ( Quat< DATA_TYPE > &  result,
DATA_TYPE  t,
const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2,
const Quat< DATA_TYPE > &  a,
const Quat< DATA_TYPE > &  b 
)

WARNING: not implemented (do not use).

Definition at line 463 of file QuatOps.h.

   {
      gmtlASSERT( false );
   }

template<typename DATA_TYPE >
Quat<DATA_TYPE>& gmtl::sub ( Quat< DATA_TYPE > &  result,
const Quat< DATA_TYPE > &  q1,
const Quat< DATA_TYPE > &  q2 
)

vector subtraction

See also:
Quat

Definition at line 261 of file QuatOps.h.

   {
      result[0] = q1[0] - q2[0];
      result[1] = q1[1] - q2[1];
      result[2] = q1[2] - q2[2];
      result[3] = q1[3] - q2[3];
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::sub ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  lhs,
const Matrix< DATA_TYPE, ROWS, COLS > &  rhs 
) [inline]

matrix subtraction (algebraic operation for matrix).

: if lhs is m x n, and rhs is m x n, then result is m x n (mult func undefined otherwise) : returns a m x n matrix : enforce the sizes with templates...

Definition at line 119 of file MatrixOps.h.

   {
      // p. 150 Numerical Analysis (second ed.)
      // if A is m x n, and B is m x n, then AB is m x n
      // (A - B)ij  = (a)ij - (b)ij     (where:  1 <= i <= m, 1 <= j <= n)
      for (unsigned int i = 0; i < ROWS; ++i)           // 1 <= i <= m
      for (unsigned int j = 0; j < COLS; ++j)           // 1 <= j <= n
         result( i, j ) = lhs( i, j ) - rhs( i, j );

      // track state
      result.mState = combineMatrixStates( lhs.mState, rhs.mState );
      return result;
   }

template<typename DATA_TYPE , unsigned SIZE>
Matrix<DATA_TYPE, SIZE, SIZE>& gmtl::transpose ( Matrix< DATA_TYPE, SIZE, SIZE > &  result  ) 

matrix transpose in place.

: needs to be an N x N matrix : flip along diagonal

Definition at line 231 of file MatrixOps.h.

   {
      // p. 27 game programming gems #1
      for (unsigned c = 0; c < SIZE; ++c)
         for (unsigned r = c + 1; r < SIZE; ++r)
            std::swap( result( r, c ), result( c, r ) );

      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Matrix<DATA_TYPE, ROWS, COLS>& gmtl::transpose ( Matrix< DATA_TYPE, ROWS, COLS > &  result,
const Matrix< DATA_TYPE, COLS, ROWS > &  source 
)

matrix transpose from one type to another (i.e.

3x4 to 4x3) : source needs to be an M x N matrix, while dest needs to be N x M : flip along diagonal

Definition at line 246 of file MatrixOps.h.

   {
      // in case result is == source... :(
      Matrix<DATA_TYPE, COLS, ROWS> temp = source;

      // p. 149 Numerical Analysis (second ed.)
      for (unsigned i = 0; i < ROWS; ++i)
      {
         for (unsigned j = 0; j < COLS; ++j)
         {
            result( i, j ) = temp( j, i );
         }
      }
      result.mState = temp.mState;
      return result;
   }

template<class DATA_TYPE >
PlaneSide gmtl::whichSide ( const Plane< DATA_TYPE > &  plane,
const Point< DATA_TYPE, 3 > &  pt,
const DATA_TYPE &  eps 
)

Determines which side of the plane the given point lies with the given epsilon tolerance.

Parameters:
plane the plane to compare the point to
pt the point to test
eps the epsilon tolerance to use while testing
Returns:
the PlaneSide enum describing on which side of the plane the point lies

Definition at line 71 of file PlaneOps.h.

{
   DATA_TYPE dist = distance( plane, pt );

   if ( dist < eps )
      return NEG_SIDE;
   else if ( dist > eps )
      return POS_SIDE;
   else
      return ON_PLANE;
}

template<class DATA_TYPE >
PlaneSide gmtl::whichSide ( const Plane< DATA_TYPE > &  plane,
const Point< DATA_TYPE, 3 > &  pt 
)

Determines which side of the plane the given point lies.

This operation is done with ZERO tolerance.

Parameters:
plane the plane to compare the point to
pt the point to test
Returns:
the PlaneSide enum describing on which side of the plane the point lies

Definition at line 46 of file PlaneOps.h.

{
   DATA_TYPE dist = distance( plane, pt );

   if ( dist < DATA_TYPE(0) )
      return NEG_SIDE;
   else if ( dist > DATA_TYPE(0) )
      return POS_SIDE;
   else
      return ON_PLANE;
}

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Vec<DATA_TYPE, COLS>& gmtl::xform ( Vec< DATA_TYPE, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const Vec< DATA_TYPE, COLS > &  vector 
) [inline]

xform a vector by a matrix.

Transforms a vector with a matrix, uses multiplication of [m x k] matrix by a [k x 1] matrix (the later also known as a Vector...).

Parameters:
result the vector to write the result in
matrix the transform matrix
vector the original vector
Postcondition:
This results in a rotational xform of the vector (assumes you know what you are doing - i.e. that you know that the last component of a vector by definition is 0.0, and changing this might make the xform different than what you may expect).
returns a point same size as the matrix rows... (v[r][1] = m[r][k] * v[k][1])

Definition at line 113 of file Xforms.h.

   {
      // do a standard [m x k] by [k x n] matrix multiplication (where n == 0).

      // reset vec to zero...
      result = Vec<DATA_TYPE, COLS>();

      for (unsigned iRow = 0; iRow < ROWS; ++iRow)
      for (unsigned iCol = 0; iCol < COLS; ++iCol)
         result[iRow] += matrix( iRow, iCol ) * vector[iCol];

      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned PNT_SIZE>
Point<DATA_TYPE, PNT_SIZE>& gmtl::xform ( Point< DATA_TYPE, PNT_SIZE > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const Point< DATA_TYPE, PNT_SIZE > &  point 
) [inline]

transform a partially specified point by a matrix, assumes last elt of point is 1.

Transforms a point with a matrix, uses multiplication of [m x k] matrix by a [k-1 x 1] matrix (also known as a Point [with w == 1 for points by definition] ).

Parameters:
result the point to write the result in
matrix the transform matrix
point the original point
Postcondition:
the [k-1 x 1] point you pass in is treated as [point, 1.0]
This results in a full matrix xform of the point.
Todo:
we need a PointOps.h operator*=(scalar) function

Definition at line 264 of file Xforms.h.

   {
      //gmtlSERT( PNT_SIZE == COLS - 1 && "The precondition of this method is that the vector size must be one less than the number of columns in the matrix.  eg. if Mat<n,k>, then Vec<k-1>." );
      GMTL_STATIC_ASSERT( PNT_SIZE == COLS-1, Point_not_of_size_mat_col_minus_1_as_required_for_xform);

      // copy the point to the correct size.
      Point<DATA_TYPE, PNT_SIZE+1> temp_point, temp_result;
      for (unsigned x = 0; x < PNT_SIZE; ++x)
         temp_point[x] = point[x];
      temp_point[PNT_SIZE] = (DATA_TYPE)1.0; // by definition of a point, set the last unspecified elt to 1.0

      // transform it.
      xform<DATA_TYPE, ROWS, COLS>( temp_result, matrix, temp_point );

      // convert result back to pnt<DATA_TYPE, PNT_SIZE>
      // some matrices will make the W param large even if this is a true vector,
      // we'll need to redistribute it to the other elts if W param is non-zero
      if (Math::isEqual( temp_result[PNT_SIZE], (DATA_TYPE)0, (DATA_TYPE)0.0001 ) == false)
      {
         DATA_TYPE w_coord_div = DATA_TYPE( 1.0 ) / temp_result[PNT_SIZE];
         for (unsigned x = 0; x < PNT_SIZE; ++x)
            result[x] = temp_result[x] * w_coord_div;
      }
      else
      {
         for (unsigned x = 0; x < PNT_SIZE; ++x)
            result[x] = temp_result[x];
      }

      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Ray<DATA_TYPE>& gmtl::xform ( Ray< DATA_TYPE > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const Ray< DATA_TYPE > &  ray 
) [inline]

transform ray by a matrix.

multiplication of [m x k] matrix by two [k x 1] matrices (also known as a ray...).

Parameters:
result the ray to write the result in
matrix the transform matrix
ray the original ray
Postcondition:
This results in a full matrix xform of the ray.
returns a ray same size as the matrix rows... (p[r][1] = m[r][k] * p[k][1])

Definition at line 367 of file Xforms.h.

   {
      gmtl::Point<DATA_TYPE, 3> pos;
      gmtl::Vec<DATA_TYPE, 3> dir;
      result.setOrigin( xform( pos, matrix, ray.getOrigin() ) );
      result.setDir( xform( dir, matrix, ray.getDir() ) );
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS, unsigned VEC_SIZE>
Vec<DATA_TYPE, VEC_SIZE>& gmtl::xform ( Vec< DATA_TYPE, VEC_SIZE > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const Vec< DATA_TYPE, VEC_SIZE > &  vector 
) [inline]

partially transform a partially specified vector by a matrix, assumes last elt of vector is 0 (the 0 makes it only partially transformed).

Transforms a vector with a matrix, uses multiplication of [m x k] matrix by a [k-1 x 1] matrix (also known as a Vector [with w == 0 for vectors by definition] ).

Parameters:
result the vector to write the result in
matrix the transform matrix
vector the original vector
Postcondition:
the [k-1 x 1] vector you pass in is treated as a [vector, 0.0]
This ends up being a partial xform using only the rotation from the matrix (vector xformed result is untranslated).

Definition at line 158 of file Xforms.h.

   {
      GMTL_STATIC_ASSERT( VEC_SIZE == COLS - 1, Vec_of_wrong_size_for_xform );
      // do a standard [m x k] by [k x n] matrix multiplication (where n == 0).

      // copy the point to the correct size.
      Vec<DATA_TYPE, COLS> temp_vector, temp_result;
      for (unsigned x = 0; x < VEC_SIZE; ++x)
         temp_vector[x] = vector[x];
      temp_vector[COLS-1] = (DATA_TYPE)0.0; // by definition of a vector, set the last unspecified elt to 0.0

      // transform it.
      xform<DATA_TYPE, ROWS, COLS>( temp_result, matrix, temp_vector );

      // convert result back to vec<DATA_TYPE, VEC_SIZE>
      // some matrices will make the W param large even if this is a true vector,
      // we'll need to redistribute it to the other elts if W param is non-zero
      if (Math::isEqual( temp_result[VEC_SIZE], (DATA_TYPE)0, (DATA_TYPE)0.0001 ) == false)
      {
         DATA_TYPE w_coord_div = DATA_TYPE( 1.0 ) / temp_result[VEC_SIZE];
         for (unsigned x = 0; x < VEC_SIZE; ++x)
            result[x] = temp_result[x] * w_coord_div;
      }
      else
      {
         for (unsigned x = 0; x < VEC_SIZE; ++x)
            result[x] = temp_result[x];
      }

      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
Point<DATA_TYPE, COLS>& gmtl::xform ( Point< DATA_TYPE, COLS > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const Point< DATA_TYPE, COLS > &  point 
) [inline]

transform point by a matrix.

multiplication of [m x k] matrix by a [k x 1] matrix (also known as a Point...).

Parameters:
result the point to write the result in
matrix the transform matrix
point the original point
Postcondition:
This results in a full matrix xform of the point.
returns a point same size as the matrix rows... (p[r][1] = m[r][k] * p[k][1])

Definition at line 222 of file Xforms.h.

   {
      // do a standard [m x k] by [k x n] matrix multiplication (n == 1).

      // reset point to zero...
      result = Point<DATA_TYPE, COLS>();

      for (unsigned iRow = 0; iRow < ROWS; ++iRow)
      for (unsigned iCol = 0; iCol < COLS; ++iCol)
         result[iRow] += matrix( iRow, iCol ) * point[iCol];

      return result;
   }

template<typename DATA_TYPE >
VecBase<DATA_TYPE, 3>& gmtl::xform ( VecBase< DATA_TYPE, 3 > &  result,
const Quat< DATA_TYPE > &  rot,
const VecBase< DATA_TYPE, 3 > &  vector 
) [inline]

transform a vector by a rotation quaternion.

Precondition:
give a vector, and a rotation quaternion (by definition, a rotation quaternion is normalized).
Parameters:
result The vector to write the result into
rot The quaternion
vector The original vector to transform
Postcondition:
v' = q P(v) q* (where result is v', rot is q, and vector is v. q* is conj(q), and P(v) is pure quaternion made from v)
See also:
game programming gems #1 p199
shoemake siggraph notes for the implementation, inv and conj should both work for the "q*" in "Rv = q P(v) q*" but conj is actually faster so we usually choose that. also note, that if the input quat wasn't normalized (and thus isn't a rotation quat), then this might not give the correct result, since conj and invert is only equiv when normalized...

Definition at line 40 of file Xforms.h.

   {
      // check preconditions...
      gmtlASSERT( Math::isEqual( length( rot ), (DATA_TYPE)1.0, (DATA_TYPE)0.0001 ) && "must pass a rotation quaternion to xform(result,quat,vec) - by definition, a rotation quaternion is normalized).  if you need non-rotation quaternion support, let us know." );

      // easiest to write and understand (slowest too)
      //return result_vec = makeVec( rot * makePure( vector ) * makeConj( rot ) );

      // completely hand expanded
      // (faster by 28% in gcc 2.96 debug mode.)
      // (faster by 35% in gcc 2.96 opt3 mode (78% for doubles))
      Quat<DATA_TYPE> rot_conj( -rot[Xelt], -rot[Yelt], -rot[Zelt], rot[Welt] );
      Quat<DATA_TYPE> pure( vector[0], vector[1], vector[2], (DATA_TYPE)0.0 );
      Quat<DATA_TYPE> temp(
         pure[Welt]*rot_conj[Xelt] + pure[Xelt]*rot_conj[Welt] + pure[Yelt]*rot_conj[Zelt] - pure[Zelt]*rot_conj[Yelt],
         pure[Welt]*rot_conj[Yelt] + pure[Yelt]*rot_conj[Welt] + pure[Zelt]*rot_conj[Xelt] - pure[Xelt]*rot_conj[Zelt],
         pure[Welt]*rot_conj[Zelt] + pure[Zelt]*rot_conj[Welt] + pure[Xelt]*rot_conj[Yelt] - pure[Yelt]*rot_conj[Xelt],
         pure[Welt]*rot_conj[Welt] - pure[Xelt]*rot_conj[Xelt] - pure[Yelt]*rot_conj[Yelt] - pure[Zelt]*rot_conj[Zelt] );

      result.set(
         rot[Welt]*temp[Xelt] + rot[Xelt]*temp[Welt] + rot[Yelt]*temp[Zelt] - rot[Zelt]*temp[Yelt],
         rot[Welt]*temp[Yelt] + rot[Yelt]*temp[Welt] + rot[Zelt]*temp[Xelt] - rot[Xelt]*temp[Zelt],
         rot[Welt]*temp[Zelt] + rot[Zelt]*temp[Welt] + rot[Xelt]*temp[Yelt] - rot[Yelt]*temp[Xelt] );
      return result;
   }

template<typename DATA_TYPE , unsigned ROWS, unsigned COLS>
LineSeg<DATA_TYPE>& gmtl::xform ( LineSeg< DATA_TYPE > &  result,
const Matrix< DATA_TYPE, ROWS, COLS > &  matrix,
const LineSeg< DATA_TYPE > &  seg 
) [inline]

transform seg by a matrix.

multiplication of [m x k] matrix by two [k x 1] matrices (also known as a seg...).

Parameters:
result the seg to write the result in
matrix the transform matrix
seg the original seg
Postcondition:
This results in a full matrix xform of the seg.
returns a seg same size as the matrix rows... (p[r][1] = m[r][k] * p[k][1])

Definition at line 414 of file Xforms.