mirror of
				https://github.com/halpz/re3.git
				synced 2025-11-04 15:35:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			647 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			647 lines
		
	
	
		
			32 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Data structures for Quaternions
 | 
						|
 * See http://www-groups.dcs.st-and.ac.uk/~history/Mathematicians/Hamilton.html
 | 
						|
 *
 | 
						|
 * Copyright (c) Criterion Software Limited
 | 
						|
 */
 | 
						|
 | 
						|
#ifndef RTQUAT_H
 | 
						|
#define RTQUAT_H
 | 
						|
 | 
						|
/**
 | 
						|
 * \defgroup rtquat RtQuat
 | 
						|
 * \ingroup rttool
 | 
						|
 *
 | 
						|
 * Quaternion Toolkit for RenderWare.
 | 
						|
 *
 | 
						|
 * See also http://www.gamasutra.com/features/19980703/quaternions_01.htm
 | 
						|
 */
 | 
						|
 | 
						|
/*
 | 
						|
 * See http://www-groups.dcs.st-and.ac.uk/~history/Mathematicians/Hamilton.html
 | 
						|
 * On 16 October 1843 (a Monday) Hamilton was walking in along the Royal
 | 
						|
 * Canal with his wife to preside at a Council meeting of the Royal Irish
 | 
						|
 * Academy.
 | 
						|
 * 
 | 
						|
 * Although his wife talked to him now and again Hamilton hardly
 | 
						|
 * heard, for the discovery of the quaternions, the first noncommutative
 | 
						|
 * algebra to be studied, was taking shape in his mind:-
 | 
						|
 * 
 | 
						|
 *    "And here there dawned on me the notion that we must admit, in
 | 
						|
 *     some sense, a fourth dimension of space for the purpose of calculating
 | 
						|
 *     with triples ...  An electric circuit seemed to close, and a spark
 | 
						|
 *     flashed forth."
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 Includes
 | 
						|
 */
 | 
						|
 | 
						|
#include <math.h>
 | 
						|
/* renderware */
 | 
						|
#include "rwcore.h"
 | 
						|
 | 
						|
#include "rtquat.rpe"          /* automatically generated header file */
 | 
						|
 | 
						|
#define RW_TOL_ORTHONORMAL  ((RwReal)0.01)
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 Global Types
 | 
						|
 */
 | 
						|
 | 
						|
 | 
						|
typedef struct RtQuat RtQuat;
 | 
						|
/**
 | 
						|
 * \ingroup rtquat
 | 
						|
 * \struct RtQuat 
 | 
						|
 * A structure describing a Quaternion
 | 
						|
 *
 | 
						|
*/ 
 | 
						|
struct RtQuat
 | 
						|
{
 | 
						|
    RwV3d               imag;   /**< The imaginary part(s) */
 | 
						|
    RwReal              real;   /**< The real part */
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 Defines
 | 
						|
 */
 | 
						|
 | 
						|
#define RtQuatInitMacro( result, _x, _y, _z, _w)                           \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    (result)->real = (_w);                                                 \
 | 
						|
    (result)->imag.x = (_x);                                               \
 | 
						|
    (result)->imag.y = (_y);                                               \
 | 
						|
    (result)->imag.z = (_z);                                               \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#if (!defined(RtQuatAssignMacro))
 | 
						|
#define RtQuatAssignMacro(_target, _source)            \
 | 
						|
    ( *(_target) = *(_source) )
 | 
						|
#endif /* (!defined(RtQuatAssignMacro)) */
 | 
						|
 | 
						|
#define RtQuatAddMacro( result, q1, q2 )                                   \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    (result)->real = (q1)->real + (q2)->real;                              \
 | 
						|
    RwV3dAddMacro(&(result)->imag, &(q1)->imag, &(q2)->imag);              \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatIncrementRealPartMacro(result, s, q)                         \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    (result)->real = (q)->real + s;                                        \
 | 
						|
    (result)->imag.x = (q)->imag.x;                                        \
 | 
						|
    (result)->imag.y = (q)->imag.y;                                        \
 | 
						|
    (result)->imag.z = (q)->imag.z;                                        \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatDecrementRealPartMacro(result, s, q)                         \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    (result)->real = (q)->real - s;                                        \
 | 
						|
    (result)->imag.x = (q)->imag.x;                                        \
 | 
						|
    (result)->imag.y = (q)->imag.y;                                        \
 | 
						|
    (result)->imag.z = (q)->imag.z;                                        \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatIncrementMacro( result, dq )                                 \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    (result)->real = (result)->real + (dq)->real;                          \
 | 
						|
    RwV3dAddMacro(&(result)->imag, &(result)->imag, &(dq)->imag);          \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatSubMacro( result, q1, q2 )                                   \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    (result)->real = (q1)->real - (q2)->real;                              \
 | 
						|
    RwV3dSubMacro(&(result)->imag, &(q1)->imag, &(q2)->imag);              \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatNegateMacro( result, q )                                     \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    (result)->real = -(q)->real;                                           \
 | 
						|
    (result)->imag.x = -(q)->imag.x;                                       \
 | 
						|
    (result)->imag.y = -(q)->imag.y;                                       \
 | 
						|
    (result)->imag.z = -(q)->imag.z;                                       \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatConjugateMacro( result, q)                                   \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    (result)->real = (q)->real;                                            \
 | 
						|
    (result)->imag.x = -(q)->imag.x;                                       \
 | 
						|
    (result)->imag.y = -(q)->imag.y;                                       \
 | 
						|
    (result)->imag.z = -(q)->imag.z;                                       \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatScaleMacro(result, q, scale )                                \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    (result)->real = (q)->real * scale;                                    \
 | 
						|
    RwV3dScaleMacro(&(result)->imag, &(q)->imag, scale);                   \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatModulusSquaredMacro( q )                                     \
 | 
						|
    ((q)->real * (q)->real +                                               \
 | 
						|
     RwV3dDotProductMacro(&(q)->imag, &(q)->imag))
 | 
						|
 | 
						|
#define RtQuatModulusMacro( result, q )         \
 | 
						|
MACRO_START                                     \
 | 
						|
{                                               \
 | 
						|
    (result) = RtQuatModulusSquaredMacro(q);    \
 | 
						|
    rwSqrtMacro(&result, result);               \
 | 
						|
}                                               \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatMultiplyMacro( result, q1, q2)                               \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    /*                                                                     \
 | 
						|
     * Assumes q1 != result != q2                                          \
 | 
						|
     */                                                                    \
 | 
						|
    (result)->real =                                                       \
 | 
						|
        (q1)->real * (q2)->real -                                          \
 | 
						|
        RwV3dDotProductMacro(&(q1)->imag,&(q2)->imag);                     \
 | 
						|
    RwV3dCrossProductMacro(&(result)->imag, &(q1)->imag, &(q2)->imag);     \
 | 
						|
    RwV3dIncrementScaledMacro(&(result)->imag, &(q2)->imag, (q1)->real);   \
 | 
						|
    RwV3dIncrementScaledMacro(&(result)->imag, &(q1)->imag, (q2)->real);   \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatReciprocalMacro( result, q)                                  \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    /*                                                                     \
 | 
						|
     * Assumes result != q                                                 \
 | 
						|
     */                                                                    \
 | 
						|
    RwReal              val = RtQuatModulusSquaredMacro(q);                \
 | 
						|
                                                                           \
 | 
						|
    if (val > (RwReal) 0)                                                  \
 | 
						|
    {                                                                      \
 | 
						|
        val = ((RwReal)1) / val;                                           \
 | 
						|
        (result)->real = (q)->real * val;                                  \
 | 
						|
        val = -val;                                                        \
 | 
						|
        RwV3dScaleMacro(&(result)->imag, &(q)->imag, val);                 \
 | 
						|
    }                                                                      \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatSquareMacro( result, q )                                     \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    /*                                                                     \
 | 
						|
     * Assumes result != q                                                 \
 | 
						|
     */                                                                    \
 | 
						|
    RwReal val = ((RwReal)2) * (q)->real ;                                 \
 | 
						|
                                                                           \
 | 
						|
    (result)->real =                                                       \
 | 
						|
        (q)->real * (q)->real -                                            \
 | 
						|
         RwV3dDotProductMacro(&(q)->imag, &(q)->imag);                     \
 | 
						|
    RwV3dScaleMacro(&(result)->imag, &(q)->imag, val);                     \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatSquareRootMacro( result, q )                                 \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    /*                                                                     \
 | 
						|
     * Assumes result != q                                                 \
 | 
						|
     * other root is of course -result                                     \
 | 
						|
     */                                                                    \
 | 
						|
    RwReal              val;                                               \
 | 
						|
                                                                           \
 | 
						|
    RtQuatModulusMacro(val,q);                                             \
 | 
						|
    val = ((q)->real + val) * ((RwReal) 0.5);                              \
 | 
						|
                                                                           \
 | 
						|
    if (val > ((RwReal)0))                                                 \
 | 
						|
    {                                                                      \
 | 
						|
        rwSqrtMacro(&val, val);                                            \
 | 
						|
        (result)->real = val;                                              \
 | 
						|
        val = ((RwReal)0.5) / val;                                         \
 | 
						|
        RwV3dScale(&(result)->imag, &(q)->imag, val);                      \
 | 
						|
    }                                                                      \
 | 
						|
    else                                                                   \
 | 
						|
    {                                                                      \
 | 
						|
        result->imag.x = -(q)->real;                                       \
 | 
						|
        rwSqrtMacro(&(result->imag.x), result->imag.x);                    \
 | 
						|
        result->imag.y = ((RwReal)0);                                      \
 | 
						|
        result->imag.x = ((RwReal)0);                                      \
 | 
						|
        result->real   = ((RwReal)0);                                      \
 | 
						|
    }                                                                      \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatLogMacro(result, q)                                          \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    /*                                                                     \
 | 
						|
     * Assumes result != q                                                 \
 | 
						|
     */                                                                    \
 | 
						|
    const RwReal        mod2 = RtQuatModulusSquaredMacro(q);               \
 | 
						|
    RwReal              sin_b;                                             \
 | 
						|
    RwReal              radians;                                           \
 | 
						|
    RwReal              factor;                                            \
 | 
						|
                                                                           \
 | 
						|
    sin_b = RwV3dDotProduct(&(q)->imag, &(q)->imag);                       \
 | 
						|
    rwSqrtMacro(&sin_b, sin_b);                                            \
 | 
						|
    radians = (RwReal) RwATan2(sin_b, (q)->real);                          \
 | 
						|
    factor = (sin_b > (RwReal) 0) ? (((RwReal)radians) / sin_b) : 0 ;      \
 | 
						|
                                                                           \
 | 
						|
    RwV3dScaleMacro(&(result)->imag, &(q)->imag, factor);                  \
 | 
						|
    (result)->real = ((RwReal) RwLog(mod2)) * ((RwReal) 0.5);              \
 | 
						|
                                                                           \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatExpMacro(result, q)                                          \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    /*                                                                     \
 | 
						|
     * Assumes result != q                                                 \
 | 
						|
     */                                                                    \
 | 
						|
    const RwReal        exp_a = (RwReal)RwExp((q)->real);                  \
 | 
						|
    RwReal              mod_b;                                             \
 | 
						|
    RwReal              factor;                                            \
 | 
						|
                                                                           \
 | 
						|
    mod_b = RwV3dDotProduct(&(q)->imag, &(q)->imag);                       \
 | 
						|
    rwSqrtMacro(&mod_b, mod_b);                                            \
 | 
						|
    factor = ( (mod_b > (RwReal) 0) ?                                      \
 | 
						|
               (exp_a * ((RwReal)RwSin(mod_b)) / mod_b) :                  \
 | 
						|
               0 ) ;                                                       \
 | 
						|
                                                                           \
 | 
						|
    RwV3dScaleMacro(&(result)->imag, &(q)->imag, factor);                  \
 | 
						|
    (result)->real = exp_a * (RwReal)RwCos(mod_b);                         \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatPowMacro( result, q, e)                                      \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    RtQuat qLog;                                                           \
 | 
						|
                                                                           \
 | 
						|
    RtQuatLogMacro(&qLog, q);                                              \
 | 
						|
    RtQuatScaleMacro(&qLog, &qLog, e);                                     \
 | 
						|
    RtQuatExpMacro(result, &qLog);                                         \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatUnitLogMacro(result, q)                                     \
 | 
						|
MACRO_START                                                               \
 | 
						|
{                                                                         \
 | 
						|
    /*                                                                    \
 | 
						|
     * Assumes result != q                                                \
 | 
						|
     */                                                                   \
 | 
						|
    RwReal              sin_b ;                                           \
 | 
						|
    RwReal              radians ;                                         \
 | 
						|
    RwReal              factor ;                                          \
 | 
						|
                                                                          \
 | 
						|
    sin_b =  RwV3dDotProduct(&(q)->imag, &(q)->imag);                     \
 | 
						|
    rwSqrtMacro(&sin_b, sin_b);                                           \
 | 
						|
    radians = (RwReal)RwATan2(sin_b, (q)->real);                          \
 | 
						|
    factor = (sin_b > (RwReal) 0) ? (((RwReal)radians) / sin_b) : 0 ;     \
 | 
						|
                                                                          \
 | 
						|
    RwV3dScaleMacro(&(result)->imag, &(q)->imag, factor);                 \
 | 
						|
    (result)->real = (RwReal)0;                                           \
 | 
						|
                                                                          \
 | 
						|
}                                                                         \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatUnitExpMacro(result, q)                                      \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    /*                                                                     \
 | 
						|
     * Assumes result != q                                                 \
 | 
						|
     */                                                                    \
 | 
						|
    RwReal              mod_b;                                             \
 | 
						|
    RwReal             factor;                                             \
 | 
						|
                                                                           \
 | 
						|
    mod_b =  RwV3dDotProduct(&(q)->imag, &(q)->imag);                      \
 | 
						|
    rwSqrtMacro(&mod_b, mod_b);                                            \
 | 
						|
    factor = (mod_b > (RwReal) 0) ? (((RwReal)RwSin(mod_b)) / mod_b) : 0 ; \
 | 
						|
                                                                           \
 | 
						|
    RwV3dScaleMacro(&(result)->imag, &(q)->imag, factor);                  \
 | 
						|
    (result)->real = (RwReal)RwCos(mod_b);                                 \
 | 
						|
                                                                           \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatUnitPowMacro( result, q, e)                                  \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    RtQuat qLog;                                                           \
 | 
						|
                                                                           \
 | 
						|
    RtQuatUnitLogMacro(&qLog, q);                                          \
 | 
						|
    RwV3dScaleMacro(&qLog.imag, &qLog.imag, e);                            \
 | 
						|
    RtQuatUnitExpMacro(result, &qLog);                                     \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatConvertToMatrixMacro(qpQuat, mpMatrix)                       \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    RwReal              rS;                                                \
 | 
						|
    RwV3d               rV;                                                \
 | 
						|
    RwV3d               rW;                                                \
 | 
						|
    RwV3d               square;                                            \
 | 
						|
    RwV3d               cross;                                             \
 | 
						|
                                                                           \
 | 
						|
    rS = ((RwReal) 2) / RtQuatModulusSquaredMacro((qpQuat));               \
 | 
						|
                                                                           \
 | 
						|
    RwV3dScale(&rV, &(qpQuat)->imag, rS);                                  \
 | 
						|
    RwV3dScale(&rW, &rV, (qpQuat)->real);                                  \
 | 
						|
                                                                           \
 | 
						|
    square.x = (qpQuat)->imag.x * rV.x;                                    \
 | 
						|
    square.y = (qpQuat)->imag.y * rV.y;                                    \
 | 
						|
    square.z = (qpQuat)->imag.z * rV.z;                                    \
 | 
						|
                                                                           \
 | 
						|
    cross.x = (qpQuat)->imag.y * rV.z;                                     \
 | 
						|
    cross.y = (qpQuat)->imag.z * rV.x;                                     \
 | 
						|
    cross.z = (qpQuat)->imag.x * rV.y;                                     \
 | 
						|
                                                                           \
 | 
						|
    (mpMatrix)->right.x = ((RwReal) 1) - (square.y + square.z);            \
 | 
						|
    (mpMatrix)->right.y = cross.z + rW.z;                                  \
 | 
						|
    (mpMatrix)->right.z = cross.y - rW.y;                                  \
 | 
						|
                                                                           \
 | 
						|
    (mpMatrix)->up.x = cross.z - rW.z;                                     \
 | 
						|
    (mpMatrix)->up.y = ((RwReal) 1) - (square.z + square.x);               \
 | 
						|
    (mpMatrix)->up.z = cross.x + rW.x;                                     \
 | 
						|
                                                                           \
 | 
						|
    (mpMatrix)->at.x = cross.y + rW.y;                                     \
 | 
						|
    (mpMatrix)->at.y = cross.x - rW.x;                                     \
 | 
						|
    (mpMatrix)->at.z = ((RwReal) 1) - (square.x + square.y);               \
 | 
						|
                                                                           \
 | 
						|
    /* Set position */                                                     \
 | 
						|
    (mpMatrix)->pos.x = ((RwReal) 0);                                      \
 | 
						|
    (mpMatrix)->pos.y = ((RwReal) 0);                                      \
 | 
						|
    (mpMatrix)->pos.z = ((RwReal) 0);                                      \
 | 
						|
                                                                           \
 | 
						|
    /* Matrix is orthogonal */                                             \
 | 
						|
    rwMatrixSetFlags((mpMatrix),                                           \
 | 
						|
                      (rwMATRIXTYPEORTHOGANAL  &                           \
 | 
						|
                       ~rwMATRIXINTERNALIDENTITY) );                       \
 | 
						|
                                                                           \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#define RtQuatUnitConvertToMatrixMacro(qpQuat, mpMatrix)                   \
 | 
						|
MACRO_START                                                                \
 | 
						|
{                                                                          \
 | 
						|
    const RwReal        x = (qpQuat)->imag.x;                              \
 | 
						|
    const RwReal        y = (qpQuat)->imag.y;                              \
 | 
						|
    const RwReal        z = (qpQuat)->imag.z;                              \
 | 
						|
    const RwReal        w = (qpQuat)->real;                                \
 | 
						|
    RwV3d               square;                                            \
 | 
						|
    RwV3d               cross;                                             \
 | 
						|
    RwV3d               wimag;                                             \
 | 
						|
                                                                           \
 | 
						|
    square.x = x * x;                                                      \
 | 
						|
    square.y = y * y;                                                      \
 | 
						|
    square.z = z * z;                                                      \
 | 
						|
                                                                           \
 | 
						|
    cross.x = y * z;                                                       \
 | 
						|
    cross.y = z * x;                                                       \
 | 
						|
    cross.z = x * y;                                                       \
 | 
						|
                                                                           \
 | 
						|
    wimag.x = w * x;                                                       \
 | 
						|
    wimag.y = w * y;                                                       \
 | 
						|
    wimag.z = w * z;                                                       \
 | 
						|
                                                                           \
 | 
						|
    (mpMatrix)->right.x = 1 - 2 * (square.y + square.z);                   \
 | 
						|
    (mpMatrix)->right.y = 2 * (cross.z + wimag.z);                         \
 | 
						|
    (mpMatrix)->right.z = 2 * (cross.y - wimag.y);                         \
 | 
						|
                                                                           \
 | 
						|
    (mpMatrix)->up.x = 2 * (cross.z - wimag.z);                            \
 | 
						|
    (mpMatrix)->up.y = 1 - 2 * (square.x + square.z);                      \
 | 
						|
    (mpMatrix)->up.z = 2 * (cross.x + wimag.x);                            \
 | 
						|
                                                                           \
 | 
						|
    (mpMatrix)->at.x = 2 * (cross.y + wimag.y);                            \
 | 
						|
    (mpMatrix)->at.y = 2 * (cross.x - wimag.x);                            \
 | 
						|
    (mpMatrix)->at.z = (1 - 2 * (square.x + square.y));                    \
 | 
						|
                                                                           \
 | 
						|
    /* Set position */                                                     \
 | 
						|
    (mpMatrix)->pos.x = ((RwReal) 0);                                      \
 | 
						|
    (mpMatrix)->pos.y = ((RwReal) 0);                                      \
 | 
						|
    (mpMatrix)->pos.z = ((RwReal) 0);                                      \
 | 
						|
                                                                           \
 | 
						|
    /* Matrix is orthonormal */                                            \
 | 
						|
    rwMatrixSetFlags((mpMatrix),                                           \
 | 
						|
                      (rwMATRIXTYPEORTHONORMAL  &                          \
 | 
						|
                       ~rwMATRIXINTERNALIDENTITY) );                       \
 | 
						|
}                                                                          \
 | 
						|
MACRO_STOP
 | 
						|
 | 
						|
#if (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ))
 | 
						|
 | 
						|
#define RtQuatInit( result, _x, _y, _z, _w)                                \
 | 
						|
    RtQuatInitMacro( result, _x, _y, _z, _w)
 | 
						|
 | 
						|
#define RtQuatAssign( to, from )                                           \
 | 
						|
    RtQuatAssignMacro( to, from )
 | 
						|
 | 
						|
#define RtQuatAdd( result, q1, q2 )                                        \
 | 
						|
    RtQuatAddMacro( result, q1, q2 )
 | 
						|
 | 
						|
#define RtQuatIncrementRealPart(result, s, q)                              \
 | 
						|
    RtQuatIncrementRealPartMacro(result, s, q)
 | 
						|
 | 
						|
#define RtQuatDecrementRealPart(result, s, q)                              \
 | 
						|
    RtQuatDecrementRealPartMacro(result, s, q)
 | 
						|
 | 
						|
#define RtQuatIncrement( result, dq )                                      \
 | 
						|
    RtQuatIncrementMacro( result, dq )
 | 
						|
 | 
						|
#define RtQuatSub( result, q1, q2 )                                        \
 | 
						|
    RtQuatSubMacro( result, q1, q2 )
 | 
						|
 | 
						|
#define RtQuatNegate( result, q )                                          \
 | 
						|
    RtQuatNegateMacro( result, q )
 | 
						|
 | 
						|
#define RtQuatConjugate( result, q)                                        \
 | 
						|
    RtQuatConjugateMacro( result, q)
 | 
						|
 | 
						|
#define RtQuatScale(result, q, scale )                                     \
 | 
						|
    RtQuatScaleMacro(result, q, scale )
 | 
						|
 | 
						|
#define RtQuatModulusSquared( q )                                          \
 | 
						|
    RtQuatModulusSquaredMacro( q )
 | 
						|
 | 
						|
#define RtQuatMultiply( result, q1, q2)                                    \
 | 
						|
    RtQuatMultiplyMacro( result, q1, q2)
 | 
						|
 | 
						|
#define RtQuatReciprocal( result, q)                                       \
 | 
						|
    RtQuatReciprocalMacro( result, q)
 | 
						|
 | 
						|
#define RtQuatSquare( result, q )                                          \
 | 
						|
    RtQuatSquareMacro( result, q )
 | 
						|
 | 
						|
#define RtQuatSquareRoot( result, q )                                      \
 | 
						|
    RtQuatSquareRootMacro( result, q )
 | 
						|
 | 
						|
#define RtQuatLog( result, q )                                             \
 | 
						|
    RtQuatLogMacro( result, q )
 | 
						|
 | 
						|
#define RtQuatExp( result, q )                                             \
 | 
						|
    RtQuatExpMacro( result, q )
 | 
						|
 | 
						|
#define RtQuatPow( result, q, e )                                          \
 | 
						|
    RtQuatPowMacro( result, q, e )
 | 
						|
 | 
						|
#define RtQuatUnitLog( result, q )                                         \
 | 
						|
    RtQuatUnitLogMacro( result, q )
 | 
						|
 | 
						|
#define RtQuatUnitExp( result, q )                                         \
 | 
						|
    RtQuatUnitExpMacro( result, q )
 | 
						|
 | 
						|
#define RtQuatUnitPow( result, q, e )                                      \
 | 
						|
    RtQuatUnitPowMacro( result, q, e )
 | 
						|
 | 
						|
#define RtQuatConvertToMatrix(qpQuat, mpMatrix)                            \
 | 
						|
    RtQuatConvertToMatrixMacro(qpQuat, mpMatrix)    
 | 
						|
 | 
						|
#define RtQuatUnitConvertToMatrix(qpQuat, mpMatrix)                        \
 | 
						|
    RtQuatUnitConvertToMatrixMacro(qpQuat, mpMatrix)    
 | 
						|
 | 
						|
#endif /* (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )) */
 | 
						|
 | 
						|
/****************************************************************************
 | 
						|
 Function prototypes
 | 
						|
 */
 | 
						|
#ifdef    __cplusplus
 | 
						|
extern              "C"
 | 
						|
{
 | 
						|
#endif                          /* __cplusplus */
 | 
						|
 | 
						|
extern RwBool
 | 
						|
RtQuatConvertFromMatrix(RtQuat * const qpQuat,
 | 
						|
                        const RwMatrix * const mpMatrix);
 | 
						|
 | 
						|
extern RtQuat             *
 | 
						|
RtQuatRotate(RtQuat * quat,
 | 
						|
             const RwV3d * axis, 
 | 
						|
             RwReal angle, 
 | 
						|
             RwOpCombineType combineOp);
 | 
						|
 | 
						|
extern const RtQuat     *
 | 
						|
RtQuatQueryRotate(const RtQuat *quat, 
 | 
						|
                  RwV3d * unitAxis, 
 | 
						|
                  RwReal * angle);
 | 
						|
 | 
						|
extern RwV3d *
 | 
						|
RtQuatTransformVectors(RwV3d * vectorsOut,
 | 
						|
                       const RwV3d * vectorsIn,
 | 
						|
                       const RwInt32 numPoints,
 | 
						|
                       const RtQuat *quat);
 | 
						|
 | 
						|
extern RwReal
 | 
						|
RtQuatModulus(RtQuat * q);
 | 
						|
 | 
						|
#if ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) )
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatInit(RtQuat * result, RwReal x, RwReal y, RwReal z, RwReal w);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatAssign(RtQuat * to, RtQuat * from);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatAdd(RtQuat * result, RtQuat * q1, RtQuat * q2);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatIncrementRealPart(RtQuat * result, RwReal s, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatDecrementRealPart(RtQuat * result, RwReal s, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatIncrement(RtQuat * result, RtQuat * dq);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatSub(RtQuat * result, RtQuat * q1, RtQuat * q2);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatNegate(RtQuat * result, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatConjugate(RtQuat * result, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatScale(RtQuat * result, RtQuat * q, RwReal scale);
 | 
						|
 | 
						|
extern RwReal
 | 
						|
RtQuatModulusSquared(RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatMultiply(RtQuat * result, RtQuat * q1, RtQuat * q2);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatReciprocal(RtQuat * result, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatSquare(RtQuat * result, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatSquareRoot(RtQuat * result, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatLog(RtQuat * result, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatExp(RtQuat * result, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatPow(RtQuat * result, RtQuat * q, RwReal e);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatUnitLog(RtQuat * result, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatUnitExp(RtQuat * result, RtQuat * q);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatUnitPow(RtQuat * result, RtQuat * q, RwReal e);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatConvertToMatrix(const RtQuat * const qpQuat,
 | 
						|
                      RwMatrix * const mpMatrix);
 | 
						|
 | 
						|
extern void
 | 
						|
RtQuatUnitConvertToMatrix(const RtQuat * const qpQuat,
 | 
						|
                          RwMatrix * const mpMatrix);
 | 
						|
 | 
						|
#endif /* ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ) */
 | 
						|
 | 
						|
#ifdef    __cplusplus
 | 
						|
}
 | 
						|
#endif                          /* __cplusplus */
 | 
						|
 | 
						|
/*
 | 
						|
 * Backwards compatibility code
 | 
						|
 */
 | 
						|
 | 
						|
typedef RtQuat RpQuat;
 | 
						|
 | 
						|
#define RpAnimQuatConvertFromMatrix(qpQuat, mpMatrix)                      \
 | 
						|
    RtQuatConvertFromMatrix(qpQuat, mpMatrix)
 | 
						|
 | 
						|
#define RpAnimQuatConvertToMatrix(qpQuat,mpMatrix)                         \
 | 
						|
    RtQuatUnitConvertToMatrix(qpQuat,mpMatrix)
 | 
						|
 | 
						|
 | 
						|
#endif                          /* RTQUAT_H */
 | 
						|
 |