/*
 	File:		QD3DMath.h
 
 	Contains:	Math & matrix routines and definitions.							
 
 	Version:	Technology:	Quickdraw 3D 1.6
 				Release:	QuickTime 4.1
 
 	Copyright:	(c) 1995-1999 by Apple Computer, Inc., all rights reserved.
 
 	Bugs?:		For bug reports, consult the following page on
 				the World Wide Web:
 
 					http://developer.apple.com/bugreporter/
 
*/
#ifndef __QD3DMATH__
#define __QD3DMATH__

#ifndef __QD3D__
	#include <QD3D.h>
#endif


#include <float.h>


#if PRAGMA_ONCE
#pragma once
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if PRAGMA_IMPORT
#pragma import on
#endif

#if PRAGMA_STRUCT_ALIGN
	#pragma options align=power
#elif PRAGMA_STRUCT_PACKPUSH
	#pragma pack(push, 2)
#elif PRAGMA_STRUCT_PACK
	#pragma pack(2)
#endif

#if PRAGMA_ENUM_ALWAYSINT
	#pragma enumsalwaysint on
#elif PRAGMA_ENUM_OPTIONS
	#pragma option enum=int
#elif PRAGMA_ENUM_PACK
	#if __option(pack_enums)
		#define PRAGMA_ENUM_PACK__QD3DMATH__
	#endif
	#pragma options(!pack_enums)
#endif

/******************************************************************************
 **																			 **
 **							Constant Definitions							 **
 **																			 **
 *****************************************************************************/
/*
 *  Real zero definition
 */

#ifdef FLT_EPSILON
	#define kQ3RealZero			(FLT_EPSILON)
#else
	#define kQ3RealZero			((float)1.19209290e-07)
#endif

#ifdef FLT_MAX
	#define kQ3MaxFloat			(FLT_MAX)
#else
	#define kQ3MaxFloat			((float)3.40282347e+38)
#endif

/*
 *  Values of PI
 */
#define kQ3Pi 					((float)3.1415926535898)
#define kQ32Pi 					((float)(2.0 * 3.1415926535898))
#define kQ3PiOver2				((float)(3.1415926535898 / 2.0))
#define kQ33PiOver2				((float)(3.0 * 3.1415926535898 / 2.0))


/******************************************************************************
 **																			 **
 **							Miscellaneous Functions							 **
 **																			 **
 *****************************************************************************/
#define Q3Math_DegreesToRadians(x)	((float)((x) *  kQ3Pi / 180.0f))
#define Q3Math_RadiansToDegrees(x)	((float)((x) * 180.0f / kQ3Pi))
#define Q3Math_Min(x,y)				((x) <= (y) ? (x) : (y))
#define Q3Math_Max(x,y)				((x) >= (y) ? (x) : (y))

/******************************************************************************
 **																			 **
 **							Point and Vector Creation						 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Point2D *)
Q3Point2D_Set					(TQ3Point2D *			point2D,
								 float 					x,
								 float 					y);

EXTERN_API_C( TQ3Param2D *)
Q3Param2D_Set					(TQ3Param2D *			param2D,
								 float 					u,
								 float 					v);

EXTERN_API_C( TQ3Point3D *)
Q3Point3D_Set					(TQ3Point3D *			point3D,
								 float 					x,
								 float 					y,
								 float 					z);

EXTERN_API_C( TQ3RationalPoint3D *)
Q3RationalPoint3D_Set			(TQ3RationalPoint3D *	point3D,
								 float 					x,
								 float 					y,
								 float 					w);

EXTERN_API_C( TQ3RationalPoint4D *)
Q3RationalPoint4D_Set			(TQ3RationalPoint4D *	point4D,
								 float 					x,
								 float 					y,
								 float 					z,
								 float 					w);

EXTERN_API_C( TQ3Vector2D *)
Q3Vector2D_Set					(TQ3Vector2D *			vector2D,
								 float 					x,
								 float 					y);

EXTERN_API_C( TQ3Vector3D *)
Q3Vector3D_Set					(TQ3Vector3D *			vector3D,
								 float 					x,
								 float 					y,
								 float 					z);

EXTERN_API_C( TQ3PolarPoint *)
Q3PolarPoint_Set				(TQ3PolarPoint *		polarPoint,
								 float 					r,
								 float 					theta);

EXTERN_API_C( TQ3SphericalPoint *)
Q3SphericalPoint_Set			(TQ3SphericalPoint *	sphericalPoint,
								 float 					rho,
								 float 					theta,
								 float 					phi);


/******************************************************************************
 **																			 **
 **					Point and Vector Dimension Conversion					 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Point3D *)
Q3Point2D_To3D					(const TQ3Point2D *		point2D,
								 TQ3Point3D *			result);

EXTERN_API_C( TQ3Point2D *)
Q3RationalPoint3D_To2D			(const TQ3RationalPoint3D * point3D,
								 TQ3Point2D *			result);

EXTERN_API_C( TQ3RationalPoint4D *)
Q3Point3D_To4D					(const TQ3Point3D *		point3D,
								 TQ3RationalPoint4D *	result);

EXTERN_API_C( TQ3Point3D *)
Q3RationalPoint4D_To3D			(const TQ3RationalPoint4D * point4D,
								 TQ3Point3D *			result);

EXTERN_API_C( TQ3Vector3D *)
Q3Vector2D_To3D					(const TQ3Vector2D *	vector2D,
								 TQ3Vector3D *			result);

EXTERN_API_C( TQ3Vector2D *)
Q3Vector3D_To2D					(const TQ3Vector3D *	vector3D,
								 TQ3Vector2D *			result);


/******************************************************************************
 **																			 **
 **							Point Subtraction								 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Vector2D *)
Q3Point2D_Subtract				(const TQ3Point2D *		p1,
								 const TQ3Point2D *		p2,
								 TQ3Vector2D *			result);

EXTERN_API_C( TQ3Vector2D *)
Q3Param2D_Subtract				(const TQ3Param2D *		p1,
								 const TQ3Param2D *		p2,
								 TQ3Vector2D *			result);

EXTERN_API_C( TQ3Vector3D *)
Q3Point3D_Subtract				(const TQ3Point3D *		p1,
								 const TQ3Point3D *		p2,
								 TQ3Vector3D *			result);


/******************************************************************************
 **																			 **
 **							Point Distance									 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( float )
Q3Point2D_Distance				(const TQ3Point2D *		p1,
								 const TQ3Point2D *		p2);

EXTERN_API_C( float )
Q3Point2D_DistanceSquared		(const TQ3Point2D *		p1,
								 const TQ3Point2D *		p2);


EXTERN_API_C( float )
Q3Param2D_Distance				(const TQ3Param2D *		p1,
								 const TQ3Param2D *		p2);

EXTERN_API_C( float )
Q3Param2D_DistanceSquared		(const TQ3Param2D *		p1,
								 const TQ3Param2D *		p2);


EXTERN_API_C( float )
Q3RationalPoint3D_Distance		(const TQ3RationalPoint3D * p1,
								 const TQ3RationalPoint3D * p2);

EXTERN_API_C( float )
Q3RationalPoint3D_DistanceSquared (const TQ3RationalPoint3D * p1,
								 const TQ3RationalPoint3D * p2);


EXTERN_API_C( float )
Q3Point3D_Distance				(const TQ3Point3D *		p1,
								 const TQ3Point3D *		p2);

EXTERN_API_C( float )
Q3Point3D_DistanceSquared		(const TQ3Point3D *		p1,
								 const TQ3Point3D *		p2);


EXTERN_API_C( float )
Q3RationalPoint4D_Distance		(const TQ3RationalPoint4D * p1,
								 const TQ3RationalPoint4D * p2);

EXTERN_API_C( float )
Q3RationalPoint4D_DistanceSquared (const TQ3RationalPoint4D * p1,
								 const TQ3RationalPoint4D * p2);


/******************************************************************************
 **																			 **
 **							Point Relative Ratio							 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Point2D *)
Q3Point2D_RRatio				(const TQ3Point2D *		p1,
								 const TQ3Point2D *		p2,
								 float 					r1,
								 float 					r2,
								 TQ3Point2D *			result);

EXTERN_API_C( TQ3Param2D *)
Q3Param2D_RRatio				(const TQ3Param2D *		p1,
								 const TQ3Param2D *		p2,
								 float 					r1,
								 float 					r2,
								 TQ3Param2D *			result);

EXTERN_API_C( TQ3Point3D *)
Q3Point3D_RRatio				(const TQ3Point3D *		p1,
								 const TQ3Point3D *		p2,
								 float 					r1,
								 float 					r2,
								 TQ3Point3D *			result);

EXTERN_API_C( TQ3RationalPoint4D *)
Q3RationalPoint4D_RRatio		(const TQ3RationalPoint4D * p1,
								 const TQ3RationalPoint4D * p2,
								 float 					r1,
								 float 					r2,
								 TQ3RationalPoint4D *	result);


/******************************************************************************
 **																			 **
 **					Point / Vector Addition	& Subtraction					 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Point2D *)
Q3Point2D_Vector2D_Add			(const TQ3Point2D *		point2D,
								 const TQ3Vector2D *	vector2D,
								 TQ3Point2D *			result);

EXTERN_API_C( TQ3Param2D *)
Q3Param2D_Vector2D_Add			(const TQ3Param2D *		param2D,
								 const TQ3Vector2D *	vector2D,
								 TQ3Param2D *			result);

EXTERN_API_C( TQ3Point3D *)
Q3Point3D_Vector3D_Add			(const TQ3Point3D *		point3D,
								 const TQ3Vector3D *	vector3D,
								 TQ3Point3D *			result);

EXTERN_API_C( TQ3Point2D *)
Q3Point2D_Vector2D_Subtract		(const TQ3Point2D *		point2D,
								 const TQ3Vector2D *	vector2D,
								 TQ3Point2D *			result);

EXTERN_API_C( TQ3Param2D *)
Q3Param2D_Vector2D_Subtract		(const TQ3Param2D *		param2D,
								 const TQ3Vector2D *	vector2D,
								 TQ3Param2D *			result);

EXTERN_API_C( TQ3Point3D *)
Q3Point3D_Vector3D_Subtract		(const TQ3Point3D *		point3D,
								 const TQ3Vector3D *	vector3D,
								 TQ3Point3D *			result);


/******************************************************************************
 **																			 **
 **								Vector Scale								 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Vector2D *)
Q3Vector2D_Scale				(const TQ3Vector2D *	vector2D,
								 float 					scalar,
								 TQ3Vector2D *			result);

EXTERN_API_C( TQ3Vector3D *)
Q3Vector3D_Scale				(const TQ3Vector3D *	vector3D,
								 float 					scalar,
								 TQ3Vector3D *			result);


/******************************************************************************
 **																			 **
 **								Vector Length								 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( float )
Q3Vector2D_Length				(const TQ3Vector2D *	vector2D);

EXTERN_API_C( float )
Q3Vector3D_Length				(const TQ3Vector3D *	vector3D);


/******************************************************************************
 **																			 **
 **								Vector Normalize							 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Vector2D *)
Q3Vector2D_Normalize			(const TQ3Vector2D *	vector2D,
								 TQ3Vector2D *			result);

EXTERN_API_C( TQ3Vector3D *)
Q3Vector3D_Normalize			(const TQ3Vector3D *	vector3D,
								 TQ3Vector3D *			result);


/******************************************************************************
 **																			 **
 **					Vector/Vector Addition and Subtraction					 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Vector2D *)
Q3Vector2D_Add					(const TQ3Vector2D *	v1,
								 const TQ3Vector2D *	v2,
								 TQ3Vector2D *			result);

EXTERN_API_C( TQ3Vector3D *)
Q3Vector3D_Add					(const TQ3Vector3D *	v1,
								 const TQ3Vector3D *	v2,
								 TQ3Vector3D *			result);


EXTERN_API_C( TQ3Vector2D *)
Q3Vector2D_Subtract				(const TQ3Vector2D *	v1,
								 const TQ3Vector2D *	v2,
								 TQ3Vector2D *			result);

EXTERN_API_C( TQ3Vector3D *)
Q3Vector3D_Subtract				(const TQ3Vector3D *	v1,
								 const TQ3Vector3D *	v2,
								 TQ3Vector3D *			result);


/******************************************************************************
 **																			 **
 **								Cross Product								 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( float )
Q3Vector2D_Cross				(const TQ3Vector2D *	v1,
								 const TQ3Vector2D *	v2);

EXTERN_API_C( TQ3Vector3D *)
Q3Vector3D_Cross				(const TQ3Vector3D *	v1,
								 const TQ3Vector3D *	v2,
								 TQ3Vector3D *			result);

EXTERN_API_C( TQ3Vector3D *)
Q3Point3D_CrossProductTri		(const TQ3Point3D *		point1,
								 const TQ3Point3D *		point2,
								 const TQ3Point3D *		point3,
								 TQ3Vector3D *			crossVector);


/******************************************************************************
 **																			 **
 **								Dot Product									 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( float )
Q3Vector2D_Dot					(const TQ3Vector2D *	v1,
								 const TQ3Vector2D *	v2);

EXTERN_API_C( float )
Q3Vector3D_Dot					(const TQ3Vector3D *	v1,
								 const TQ3Vector3D *	v2);


/******************************************************************************
 **																			 **
 **						Point and Vector Transformation						 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Vector2D *)
Q3Vector2D_Transform			(const TQ3Vector2D *	vector2D,
								 const TQ3Matrix3x3 *	matrix3x3,
								 TQ3Vector2D *			result);

EXTERN_API_C( TQ3Vector3D *)
Q3Vector3D_Transform			(const TQ3Vector3D *	vector3D,
								 const TQ3Matrix4x4 *	matrix4x4,
								 TQ3Vector3D *			result);

EXTERN_API_C( TQ3Point2D *)
Q3Point2D_Transform				(const TQ3Point2D *		point2D,
								 const TQ3Matrix3x3 *	matrix3x3,
								 TQ3Point2D *			result);

EXTERN_API_C( TQ3Param2D *)
Q3Param2D_Transform				(const TQ3Param2D *		param2D,
								 const TQ3Matrix3x3 *	matrix3x3,
								 TQ3Param2D *			result);

EXTERN_API_C( TQ3Point3D *)
Q3Point3D_Transform				(const TQ3Point3D *		point3D,
								 const TQ3Matrix4x4 *	matrix4x4,
								 TQ3Point3D *			result);

EXTERN_API_C( TQ3RationalPoint4D *)
Q3RationalPoint4D_Transform		(const TQ3RationalPoint4D * point4D,
								 const TQ3Matrix4x4 *	matrix4x4,
								 TQ3RationalPoint4D *	result);

EXTERN_API_C( TQ3Status )
Q3Point3D_To3DTransformArray	(const TQ3Point3D *		inPoint3D,
								 const TQ3Matrix4x4 *	matrix,
								 TQ3Point3D *			outPoint3D,
								 long 					numPoints,
								 unsigned long 			inStructSize,
								 unsigned long 			outStructSize);

EXTERN_API_C( TQ3Status )
Q3Point3D_To4DTransformArray	(const TQ3Point3D *		inPoint3D,
								 const TQ3Matrix4x4 *	matrix,
								 TQ3RationalPoint4D *	outPoint4D,
								 long 					numPoints,
								 unsigned long 			inStructSize,
								 unsigned long 			outStructSize);

EXTERN_API_C( TQ3Status )
Q3RationalPoint4D_To4DTransformArray (const TQ3RationalPoint4D * inPoint4D,
								 const TQ3Matrix4x4 *	matrix,
								 TQ3RationalPoint4D *	outPoint4D,
								 long 					numPoints,
								 unsigned long 			inStructSize,
								 unsigned long 			outStructSize);


/******************************************************************************
 **																			 **
 **								Vector Negation								 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Vector2D *)
Q3Vector2D_Negate				(const TQ3Vector2D *	vector2D,
								 TQ3Vector2D *			result);

EXTERN_API_C( TQ3Vector3D *)
Q3Vector3D_Negate				(const TQ3Vector3D *	vector3D,
								 TQ3Vector3D *			result);


/******************************************************************************
 **																			 **
 **					Point conversion from cartesian to polar				 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3PolarPoint *)
Q3Point2D_ToPolar				(const TQ3Point2D *		point2D,
								 TQ3PolarPoint *		result);

EXTERN_API_C( TQ3Point2D *)
Q3PolarPoint_ToPoint2D			(const TQ3PolarPoint *	polarPoint,
								 TQ3Point2D *			result);

EXTERN_API_C( TQ3SphericalPoint *)
Q3Point3D_ToSpherical			(const TQ3Point3D *		point3D,
								 TQ3SphericalPoint *	result);

EXTERN_API_C( TQ3Point3D *)
Q3SphericalPoint_ToPoint3D		(const TQ3SphericalPoint * sphericalPoint,
								 TQ3Point3D *			result);


/******************************************************************************
 **																			 **
 **							Point Affine Combinations						 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Point2D *)
Q3Point2D_AffineComb			(const TQ3Point2D *		points2D,
								 const float *			weights,
								 unsigned long 			nPoints,
								 TQ3Point2D *			result);

EXTERN_API_C( TQ3Param2D *)
Q3Param2D_AffineComb			(const TQ3Param2D *		params2D,
								 const float *			weights,
								 unsigned long 			nPoints,
								 TQ3Param2D *			result);

EXTERN_API_C( TQ3RationalPoint3D *)
Q3RationalPoint3D_AffineComb	(const TQ3RationalPoint3D * points3D,
								 const float *			weights,
								 unsigned long 			numPoints,
								 TQ3RationalPoint3D *	result);

EXTERN_API_C( TQ3Point3D *)
Q3Point3D_AffineComb			(const TQ3Point3D *		points3D,
								 const float *			weights,
								 unsigned long 			numPoints,
								 TQ3Point3D *			result);

EXTERN_API_C( TQ3RationalPoint4D *)
Q3RationalPoint4D_AffineComb	(const TQ3RationalPoint4D * points4D,
								 const float *			weights,
								 unsigned long 			numPoints,
								 TQ3RationalPoint4D *	result);


/******************************************************************************
 **																			 **
 **								Matrix Functions							 **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Matrix3x3 *)
Q3Matrix3x3_Copy				(const TQ3Matrix3x3 *	matrix3x3,
								 TQ3Matrix3x3 *			result);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_Copy				(const TQ3Matrix4x4 *	matrix4x4,
								 TQ3Matrix4x4 *			result);


EXTERN_API_C( TQ3Matrix3x3 *)
Q3Matrix3x3_SetIdentity			(TQ3Matrix3x3 *			matrix3x3);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetIdentity			(TQ3Matrix4x4 *			matrix4x4);


EXTERN_API_C( TQ3Matrix3x3 *)
Q3Matrix3x3_Transpose			(const TQ3Matrix3x3 *	matrix3x3,
								 TQ3Matrix3x3 *			result);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_Transpose			(const TQ3Matrix4x4 *	matrix4x4,
								 TQ3Matrix4x4 *			result);


EXTERN_API_C( TQ3Matrix3x3 *)
Q3Matrix3x3_Invert				(const TQ3Matrix3x3 *	matrix3x3,
								 TQ3Matrix3x3 *			result);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_Invert				(const TQ3Matrix4x4 *	matrix4x4,
								 TQ3Matrix4x4 *			result);


EXTERN_API_C( TQ3Matrix3x3 *)
Q3Matrix3x3_Adjoint				(const TQ3Matrix3x3 *	matrix3x3,
								 TQ3Matrix3x3 *			result);


EXTERN_API_C( TQ3Matrix3x3 *)
Q3Matrix3x3_Multiply			(const TQ3Matrix3x3 *	matrixA,
								 const TQ3Matrix3x3 *	matrixB,
								 TQ3Matrix3x3 *			result);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_Multiply			(const TQ3Matrix4x4 *	matrixA,
								 const TQ3Matrix4x4 *	matrixB,
								 TQ3Matrix4x4 *			result);


EXTERN_API_C( TQ3Matrix3x3 *)
Q3Matrix3x3_SetTranslate		(TQ3Matrix3x3 *			matrix3x3,
								 float 					xTrans,
								 float 					yTrans);

EXTERN_API_C( TQ3Matrix3x3 *)
Q3Matrix3x3_SetScale			(TQ3Matrix3x3 *			matrix3x3,
								 float 					xScale,
								 float 					yScale);


EXTERN_API_C( TQ3Matrix3x3 *)
Q3Matrix3x3_SetRotateAboutPoint	(TQ3Matrix3x3 *			matrix3x3,
								 const TQ3Point2D *		origin,
								 float 					angle);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetTranslate		(TQ3Matrix4x4 *			matrix4x4,
								 float 					xTrans,
								 float 					yTrans,
								 float 					zTrans);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetScale			(TQ3Matrix4x4 *			matrix4x4,
								 float 					xScale,
								 float 					yScale,
								 float 					zScale);


EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetRotateAboutPoint	(TQ3Matrix4x4 *			matrix4x4,
								 const TQ3Point3D *		origin,
								 float 					xAngle,
								 float 					yAngle,
								 float 					zAngle);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetRotateAboutAxis	(TQ3Matrix4x4 *			matrix4x4,
								 const TQ3Point3D *		origin,
								 const TQ3Vector3D *	orientation,
								 float 					angle);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetRotate_X			(TQ3Matrix4x4 *			matrix4x4,
								 float 					angle);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetRotate_Y			(TQ3Matrix4x4 *			matrix4x4,
								 float 					angle);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetRotate_Z			(TQ3Matrix4x4 *			matrix4x4,
								 float 					angle);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetRotate_XYZ		(TQ3Matrix4x4 *			matrix4x4,
								 float 					xAngle,
								 float 					yAngle,
								 float 					zAngle);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetRotateVectorToVector (TQ3Matrix4x4 *		matrix4x4,
								 const TQ3Vector3D *	v1,
								 const TQ3Vector3D *	v2);

EXTERN_API_C( TQ3Matrix4x4 *)
Q3Matrix4x4_SetQuaternion		(TQ3Matrix4x4 *			matrix,
								 const TQ3Quaternion *	quaternion);

EXTERN_API_C( float )
Q3Matrix3x3_Determinant			(const TQ3Matrix3x3 *	matrix3x3);

EXTERN_API_C( float )
Q3Matrix4x4_Determinant			(const TQ3Matrix4x4 *	matrix4x4);


/******************************************************************************
 **																			 **
 **								Quaternion Routines						     **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_Set				(TQ3Quaternion *		quaternion,
								 float 					w,
								 float 					x,
								 float 					y,
								 float 					z);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_SetIdentity		(TQ3Quaternion *		quaternion);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_Copy				(const TQ3Quaternion *	quaternion,
								 TQ3Quaternion *		result);

EXTERN_API_C( TQ3Boolean )
Q3Quaternion_IsIdentity			(const TQ3Quaternion *	quaternion);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_Invert				(const TQ3Quaternion *	quaternion,
								 TQ3Quaternion *		result);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_Normalize			(const TQ3Quaternion *	quaternion,
								 TQ3Quaternion *		result);

EXTERN_API_C( float )
Q3Quaternion_Dot				(const TQ3Quaternion *	q1,
								 const TQ3Quaternion *	q2);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_Multiply			(const TQ3Quaternion *	q1,
								 const TQ3Quaternion *	q2,
								 TQ3Quaternion *		result);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_SetRotateAboutAxis	(TQ3Quaternion *		quaternion,
								 const TQ3Vector3D *	axis,
								 float 					angle);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_SetRotate_XYZ		(TQ3Quaternion *		quaternion,
								 float 					xAngle,
								 float 					yAngle,
								 float 					zAngle);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_SetRotate_X		(TQ3Quaternion *		quaternion,
								 float 					angle);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_SetRotate_Y		(TQ3Quaternion *		quaternion,
								 float 					angle);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_SetRotate_Z		(TQ3Quaternion *		quaternion,
								 float 					angle);


EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_SetMatrix			(TQ3Quaternion *		quaternion,
								 const TQ3Matrix4x4 *	matrix);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_SetRotateVectorToVector (TQ3Quaternion *	quaternion,
								 const TQ3Vector3D *	v1,
								 const TQ3Vector3D *	v2);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_MatchReflection	(const TQ3Quaternion *	q1,
								 const TQ3Quaternion *	q2,
								 TQ3Quaternion *		result);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_InterpolateFast	(const TQ3Quaternion *	q1,
								 const TQ3Quaternion *	q2,
								 float 					t,
								 TQ3Quaternion *		result);

EXTERN_API_C( TQ3Quaternion *)
Q3Quaternion_InterpolateLinear	(const TQ3Quaternion *	q1,
								 const TQ3Quaternion *	q2,
								 float 					t,
								 TQ3Quaternion *		result);

EXTERN_API_C( TQ3Vector3D *)
Q3Vector3D_TransformQuaternion	(const TQ3Vector3D *	vector3D,
								 const TQ3Quaternion *	quaternion,
								 TQ3Vector3D *			result);

EXTERN_API_C( TQ3Point3D *)
Q3Point3D_TransformQuaternion	(const TQ3Point3D *		point3D,
								 const TQ3Quaternion *	quaternion,
								 TQ3Point3D *			result);


/******************************************************************************
 **																			 **
 **								Volume Routines							     **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3BoundingBox *)
Q3BoundingBox_Copy				(const TQ3BoundingBox *	src,
								 TQ3BoundingBox *		dest);

EXTERN_API_C( TQ3BoundingBox *)
Q3BoundingBox_Union				(const TQ3BoundingBox *	v1,
								 const TQ3BoundingBox *	v2,
								 TQ3BoundingBox *		result);

EXTERN_API_C( TQ3BoundingBox *)
Q3BoundingBox_Set				(TQ3BoundingBox *		bBox,
								 const TQ3Point3D *		min,
								 const TQ3Point3D *		max,
								 TQ3Boolean 			isEmpty);

EXTERN_API_C( TQ3BoundingBox *)
Q3BoundingBox_UnionPoint3D		(const TQ3BoundingBox *	bBox,
								 const TQ3Point3D *		point3D,
								 TQ3BoundingBox *		result);

EXTERN_API_C( TQ3BoundingBox *)
Q3BoundingBox_UnionRationalPoint4D (const TQ3BoundingBox * bBox,
								 const TQ3RationalPoint4D * point4D,
								 TQ3BoundingBox *		result);

EXTERN_API_C( TQ3BoundingBox *)
Q3BoundingBox_SetFromPoints3D	(TQ3BoundingBox *		bBox,
								 const TQ3Point3D *		points3D,
								 unsigned long 			numPoints,
								 unsigned long 			structSize);

EXTERN_API_C( TQ3BoundingBox *)
Q3BoundingBox_SetFromRationalPoints4D (TQ3BoundingBox *	bBox,
								 const TQ3RationalPoint4D * points4D,
								 unsigned long 			numPoints,
								 unsigned long 			structSize);


/******************************************************************************
 **																			 **
 **								Sphere Routines							     **
 **																			 **
 *****************************************************************************/
EXTERN_API_C( TQ3BoundingSphere *)
Q3BoundingSphere_Copy			(const TQ3BoundingSphere * src,
								 TQ3BoundingSphere *	dest);

EXTERN_API_C( TQ3BoundingSphere *)
Q3BoundingSphere_Union			(const TQ3BoundingSphere * s1,
								 const TQ3BoundingSphere * s2,
								 TQ3BoundingSphere *	result);

EXTERN_API_C( TQ3BoundingSphere *)
Q3BoundingSphere_Set			(TQ3BoundingSphere *	bSphere,
								 const TQ3Point3D *		origin,
								 float 					radius,
								 TQ3Boolean 			isEmpty);

EXTERN_API_C( TQ3BoundingSphere *)
Q3BoundingSphere_UnionPoint3D	(const TQ3BoundingSphere * bSphere,
								 const TQ3Point3D *		point3D,
								 TQ3BoundingSphere *	result);

EXTERN_API_C( TQ3BoundingSphere *)
Q3BoundingSphere_UnionRationalPoint4D (const TQ3BoundingSphere * bSphere,
								 const TQ3RationalPoint4D * point4D,
								 TQ3BoundingSphere *	result);


EXTERN_API_C( TQ3BoundingSphere *)
Q3BoundingSphere_SetFromPoints3D (TQ3BoundingSphere *	bSphere,
								 const TQ3Point3D *		points3D,
								 unsigned long 			numPoints,
								 unsigned long 			structSize);

EXTERN_API_C( TQ3BoundingSphere *)
Q3BoundingSphere_SetFromRationalPoints4D (TQ3BoundingSphere * bSphere,
								 const TQ3RationalPoint4D * points4D,
								 unsigned long 			numPoints,
								 unsigned long 			structSize);





#if PRAGMA_ENUM_ALWAYSINT
	#pragma enumsalwaysint reset
#elif PRAGMA_ENUM_OPTIONS
	#pragma option enum=reset
#elif defined(PRAGMA_ENUM_PACK__QD3DMATH__)
	#pragma options(pack_enums)
#endif

#if PRAGMA_STRUCT_ALIGN
	#pragma options align=reset
#elif PRAGMA_STRUCT_PACKPUSH
	#pragma pack(pop)
#elif PRAGMA_STRUCT_PACK
	#pragma pack()
#endif

#ifdef PRAGMA_IMPORT_OFF
#pragma import off
#elif PRAGMA_IMPORT
#pragma import reset
#endif

#ifdef __cplusplus
}
#endif

#endif /* __QD3DMATH__ */

