1 /*! @header QuesaMath.h
2         Declares the Quesa math utilities.
3  */
4 /*  NAME:
5         QuesaMath.h
6 
7     DESCRIPTION:
8         Quesa public header.
9 
10     COPYRIGHT:
11         Copyright (c) 1999-2004, Quesa Developers. All rights reserved.
12 
13         For the current release of Quesa, please see:
14 
15             <http://www.quesa.org/>
16 
17         Redistribution and use in source and binary forms, with or without
18         modification, are permitted provided that the following conditions
19         are met:
20 
21             o Redistributions of source code must retain the above copyright
22               notice, this list of conditions and the following disclaimer.
23 
24             o Redistributions in binary form must reproduce the above
25               copyright notice, this list of conditions and the following
26               disclaimer in the documentation and/or other materials provided
27               with the distribution.
28 
29             o Neither the name of Quesa nor the names of its contributors
30               may be used to endorse or promote products derived from this
31               software without specific prior written permission.
32 
33         THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34         "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35         LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
36         A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37         OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38         SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
39         TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
40         PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
41         LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42         NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43         SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44     ___________________________________________________________________________
45 */
46 #ifndef QUESA_MATH_HDR
47 #define QUESA_MATH_HDR
48 //=============================================================================
49 //      Include files
50 //-----------------------------------------------------------------------------
51 #include "Quesa.h"
52 
53 // Disable QD3D header
54 #ifdef __QD3DMATH__
55 #error
56 #endif
57 
58 #define __QD3DMATH__
59 
60 #include <math.h>
61 #include <float.h>
62 
63 
64 
65 
66 
67 //=============================================================================
68 //      C++ preamble
69 //-----------------------------------------------------------------------------
70 #ifdef __cplusplus
71 extern "C" {
72 #endif
73 
74 
75 
76 
77 
78 //=============================================================================
79 //      Constants
80 //-----------------------------------------------------------------------------
81 #ifdef FLT_EPSILON
82     #define kQ3RealZero                         (FLT_EPSILON)
83 #else
84     #define kQ3RealZero                         ((TQ3Float32) 1.19209290e-07)
85 #endif
86 
87 #ifdef FLT_MAX
88     #define kQ3MaxFloat                         (FLT_MAX)
89 #else
90     #define kQ3MaxFloat                         ((TQ3Float32) 3.40282347e+38)
91 #endif
92 
93 #ifdef FLT_MIN
94     #define kQ3MinFloat                         (FLT_MIN)
95 #else
96     #define kQ3MinFloat                         ((TQ3Float32) 1.17549e-38)
97 #endif
98 
99 #define kQ3Pi                                   ((TQ3Float32) 3.1415926535898)
100 #define kQ32Pi                                  ((TQ3Float32) (2.0 * 3.1415926535898))
101 #define kQ3PiOver2                              ((TQ3Float32) (3.1415926535898 / 2.0))
102 #define kQ33PiOver2                             ((TQ3Float32) (3.0 * 3.1415926535898 / 2.0))
103 
104 
105 
106 
107 
108 //=============================================================================
109 //      Macros
110 //-----------------------------------------------------------------------------
111 #define Q3Math_DegreesToRadians(_x)             ((TQ3Float32) ((_x) *  kQ3Pi / 180.0f))
112 #define Q3Math_RadiansToDegrees(_x)             ((TQ3Float32) ((_x) * 180.0f / kQ3Pi))
113 #define Q3Math_Min(_x,_y)                       ((_x) <= (_y) ? (_x) : (_y))
114 #define Q3Math_Max(_x,_y)                       ((_x) >= (_y) ? (_x) : (_y))
115 
116 
117 #ifndef	QUESA_LONGLONG64_SUPPORT
118 	#if defined(__MWERKS__) || defined(__GNUC__)
119 		#define	QUESA_LONGLONG64_SUPPORT	1
120 	#else
121 		#define	QUESA_LONGLONG64_SUPPORT	0
122 	#endif
123 #endif
124 
125 
126 
127 
128 
129 //=============================================================================
130 //      Function prototypes
131 //-----------------------------------------------------------------------------
132 //      Point and Vector creation
133 //-----------------------------------------------------------------------------
134 /*!
135  *  @function
136  *      Q3Vector2D_Set
137  *  @discussion
138  *      Set a 2D vector.
139  *
140  *      Available in inline form as Q3FastVector2D_Set.
141  *
142  *  @param vector2D         Address of vector to set (may be NULL).
143  *  @param x                X coordinate to set into vector2D.
144  *  @param y                Y coordinate to set into vector2D.
145  *  @result                 Convenience copy of vector2D parameter.
146  */
147 Q3_EXTERN_API_C ( TQ3Vector2D * )
148 Q3Vector2D_Set (
149     TQ3Vector2D                   *vector2D,
150     float                         x,
151     float                         y
152 );
153 
154 
155 
156 /*!
157  *  @function
158  *      Q3Vector3D_Set
159  *  @discussion
160  *      Set a 3D vector.
161  *
162  *      Available in inline form as Q3FastVector3D_Set.
163  *
164  *  @param vector3D         Address of vector to set (may be NULL).
165  *  @param x                X coordinate to set into vector3D.
166  *  @param y                Y coordinate to set into vector3D.
167  *  @param z                Z coordinate to set into vector3D.
168  *  @result                 Convenience copy of vector3D parameter.
169  */
170 Q3_EXTERN_API_C ( TQ3Vector3D * )
171 Q3Vector3D_Set (
172     TQ3Vector3D                   *vector3D,
173     float                         x,
174     float                         y,
175     float                         z
176 );
177 
178 
179 
180 /*!
181  *  @function
182  *      Q3Point2D_Set
183  *  @discussion
184  *      Set a 2D point.
185  *
186  *      Available in inline form as Q3FastPoint2D_Set.
187  *
188  *  @param point2D          Address of point to set (may be NULL).
189  *  @param x                X coordinate to set into vector2D.
190  *  @param y                Y coordinate to set into vector2D.
191  *  @result                 Convenience copy of point2D parameter.
192  */
193 Q3_EXTERN_API_C ( TQ3Point2D * )
194 Q3Point2D_Set (
195     TQ3Point2D                    *point2D,
196     float                         x,
197     float                         y
198 );
199 
200 
201 
202 /*!
203  *  @function
204  *      Q3Param2D_Set
205  *  @discussion
206  *      Set a 2D parameterization value (i.e., a UV coordinate).
207  *
208  *      Available in inline form as Q3FastParam2D_Set.
209  *
210  *  @param param2D          Address of param2D to set (may be NULL).
211  *  @param u                U coordinate to set into param2D.
212  *  @param v                V coordinate to set into param2D.
213  *  @result                 Convenience copy of param2D parameter.
214  */
215 Q3_EXTERN_API_C ( TQ3Param2D * )
216 Q3Param2D_Set (
217     TQ3Param2D                    *param2D,
218     float                         u,
219     float                         v
220 );
221 
222 
223 
224 /*!
225  *  @function
226  *      Q3RationalPoint3D_Set
227  *  @discussion
228  *      Set a 3D rational point (x,y,w).
229  *
230  *      Available in inline form as Q3FastRationalPoint3D_Set.
231  *
232  *  @param rationalPoint3D  Address of rational point to set (may be NULL).
233  *  @param x                X coordinate to set into rationalPoint3D.
234  *  @param y                Y coordinate to set into rationalPoint3D.
235  *  @param w                W coordinate to set into rationalPoint3D.
236  *  @result                 Convenience copy of rationalPoint3D parameter.
237  */
238 Q3_EXTERN_API_C ( TQ3RationalPoint3D * )
239 Q3RationalPoint3D_Set (
240     TQ3RationalPoint3D            *rationalPoint3D,
241     float                         x,
242     float                         y,
243     float                         w
244 );
245 
246 
247 
248 /*!
249  *  @function
250  *      Q3Point3D_Set
251  *  @discussion
252  *      Set a 3D point.
253  *
254  *      Available in inline form as Q3FastPoint3D_Set.
255  *
256  *  @param point3D          Address of point to set (may be NULL).
257  *  @param x                X coordinate to set into point3D.
258  *  @param y                Y coordinate to set into point3D.
259  *  @param z                Z coordinate to set into point3D.
260  *  @result                 Convenience copy of point3D parameter.
261  */
262 Q3_EXTERN_API_C ( TQ3Point3D * )
263 Q3Point3D_Set (
264     TQ3Point3D                    *point3D,
265     float                         x,
266     float                         y,
267     float                         z
268 );
269 
270 
271 
272 /*!
273  *  @function
274  *      Q3RationalPoint4D_Set
275  *  @discussion
276  *      Set a 4D rational point (x,y,z,w).
277  *
278  *      Available in inline form as Q3FastRationalPoint4D_Set.
279  *
280  *  @param rationalPoint4D  Address of rational point to set.
281  *  @param x                X coordinate to set into rationalPoint4D.
282  *  @param y                Y coordinate to set into rationalPoint4D.
283  *  @param z                Z coordinate to set into rationalPoint4D.
284  *  @result                 Convenience copy of rationalPoint4D parameter.
285  */
286 Q3_EXTERN_API_C ( TQ3RationalPoint4D * )
287 Q3RationalPoint4D_Set (
288     TQ3RationalPoint4D            *rationalPoint4D,
289     float                         x,
290     float                         y,
291     float                         z,
292     float                         w
293 );
294 
295 
296 
297 /*!
298  *  @function
299  *      Q3PolarPoint_Set
300  *  @discussion
301  *      Set a 2D polar-coordinates point.
302  *
303  *      Available in inline form as Q3FastPolarPoint_Set.
304  *
305  *  @param polarPoint       Address of point to set (may be NULL).
306  *  @param r                Radius coordinate to set into polarPoint.
307  *  @param theta            Angle coordinate (in radians) to set into polarPoint.
308  *  @result                 Convenience copy of polarPoint parameter.
309  */
310 Q3_EXTERN_API_C ( TQ3PolarPoint * )
311 Q3PolarPoint_Set (
312     TQ3PolarPoint                 *polarPoint,
313     float                         r,
314     float                         theta
315 );
316 
317 
318 
319 /*!
320  *  @function
321  *      Q3SphericalPoint_Set
322  *  @discussion
323  *      Set a 3D spherical-coordinates point.
324  *
325  *      Available in inline form as Q3FastSphericalPoint_Set.
326  *
327  *  @param sphericalPoint   Address of point to set (may be NULL).
328  *  @param rho              Rho coordinate to set into sphericalPoint.
329  *  @param theta            Theta coordinate to set into sphericalPoint.
330  *  @param phi              Phi coordinate to set into sphericalPoint.
331  *  @result                 Convenience copy of polarPoint parameter.
332  */
333 Q3_EXTERN_API_C ( TQ3SphericalPoint * )
334 Q3SphericalPoint_Set (
335     TQ3SphericalPoint             *sphericalPoint,
336     float                         rho,
337     float                         theta,
338     float                         phi
339 );
340 
341 
342 
343 
344 
345 //=============================================================================
346 //      Point and Vector dimension conversion
347 //-----------------------------------------------------------------------------
348 /*!
349  *  @function
350  *      Q3Vector2D_To3D
351  *  @discussion
352  *      Convert 2D vector to 3D, by setting z to 1.
353  *
354  *		Note: this operation makes no sense mathematically, but is included
355  *		for backward-compatibility with QD3D.  Perhaps the QD3D
356  *		implementation was really intended to convert a 2D vector into a 3D
357  *		rational point -- see QDPoint2D_To3D, which does exactly that.
358  *
359  *      Available in inline form as Q3FastVector2D_To3D.
360  *
361  *  @param vector2D         Address of 2D vector to convert.
362  *  @param result           Address of 3D vector to set.
363  *  @result                 Convenience copy of result parameter.
364  */
365 Q3_EXTERN_API_C ( TQ3Vector3D * )
366 Q3Vector2D_To3D (
367     const TQ3Vector2D             *vector2D,
368     TQ3Vector3D                   *result
369 );
370 
371 
372 
373 /*!
374  *  @function
375  *      Q3Vector2D_ToRationalPoint3D
376  *  @discussion
377  *		Convert 2D vector to 3D rational point, setting w to 0.
378  *
379  *      Available in inline form as Q3FastVector2D_ToRationalPoint3D.
380  *
381  *      <em>This function is not available in QD3D.</em>
382  *
383  *  @param vector2D         Address of 2D vector to convert.
384  *  @param result           Address of 3D rational point to set.
385  *  @result                 Convenience copy of result parameter.
386  */
387 #if QUESA_ALLOW_QD3D_EXTENSIONS
388 
389 Q3_EXTERN_API_C ( TQ3RationalPoint3D * )
390 Q3Vector2D_ToRationalPoint3D (
391     const TQ3Vector2D             *vector2D,
392     TQ3RationalPoint3D            *result
393 );
394 
395 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
396 
397 
398 
399 /*!
400  *  @function
401  *      Q3Vector3D_To2D
402  *  @discussion
403  *      Convert 3D vector to 2D, dividing by z.
404  *
405  *		Note: this operation makes no sense mathematically, but is included
406  *		for backward-compatibility with QD3D.  It's possible that the QD3D
407  *		function was really intended to convert a 3D rational point to a
408  *		2D vector -- see E3RationalPoint3D_To2D, which does the same thing
409  *		for a 2D point.
410  *
411  *      Available in inline form as Q3FastVector3D_To2D.
412  *
413  *  @param vector3D         Address of 3D vector to convert.
414  *  @param result           Address of 2D vector to set.
415  *  @result                 Convenience copy of result parameter.
416  */
417 Q3_EXTERN_API_C ( TQ3Vector2D * )
418 Q3Vector3D_To2D (
419     const TQ3Vector3D             *vector3D,
420     TQ3Vector2D                   *result
421 );
422 
423 
424 
425 /*!
426  *  @function
427  *      Q3RationalPoint3D_ToVector2D
428  *  @discussion
429  *		Convert 3D rational point to 2D vector, discarding w.
430  *
431  *      Available in inline form as Q3FastRationalPoint3D_ToVector2D.
432  *
433  *      <em>This function is not available in QD3D.</em>
434  *
435  *  @param rationalPoint3D  Address of 3D rational point to convert.
436  *  @param result           Address of 2D vector to set.
437  *  @result                 Convenience copy of result parameter.
438  */
439 #if QUESA_ALLOW_QD3D_EXTENSIONS
440 
441 Q3_EXTERN_API_C ( TQ3Vector2D * )
442 Q3RationalPoint3D_ToVector2D (
443     const TQ3RationalPoint3D      *rationalPoint3D,
444     TQ3Vector2D                   *result
445 );
446 
447 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
448 
449 
450 
451 /*!
452  *  @function
453  *      Q3Vector3D_ToRationalPoint4D
454  *  @discussion
455  *		Convert 3D vector to 4D rational point, setting w to 0.
456  *
457  *      Available in inline form as Q3FastVector3D_ToRationalPoint4D.
458  *
459  *      <em>This function is not available in QD3D.</em>
460  *
461  *  @param vector3D         Address of 3D vector to convert.
462  *  @param result           Address of 4D rational point to set.
463  *  @result                 Convenience copy of result parameter.
464  */
465 #if QUESA_ALLOW_QD3D_EXTENSIONS
466 
467 Q3_EXTERN_API_C ( TQ3RationalPoint4D * )
468 Q3Vector3D_ToRationalPoint4D (
469     const TQ3Vector3D             *vector3D,
470     TQ3RationalPoint4D            *result
471 );
472 
473 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
474 
475 
476 
477 /*!
478  *  @function
479  *      Q3RationalPoint4D_ToVector3D
480  *  @discussion
481  *		Convert 4D rational point to 3D vector, discarding w.
482  *
483  *      Available in inline form as Q3FastRationalPoint4D_ToVector3D.
484  *
485  *      <em>This function is not available in QD3D.</em>
486  *
487  *  @param rationalPoint4D  Address of 4D rational point to convert.
488  *  @param result           Address of 3D vector to set.
489  *  @result                 Convenience copy of result parameter.
490  */
491 #if QUESA_ALLOW_QD3D_EXTENSIONS
492 
493 Q3_EXTERN_API_C ( TQ3Vector3D * )
494 Q3RationalPoint4D_ToVector3D (
495     const TQ3RationalPoint4D      *rationalPoint4D,
496     TQ3Vector3D                   *result
497 );
498 
499 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
500 
501 
502 
503 /*!
504  *  @function
505  *      Q3Point2D_To3D
506  *  @discussion
507  *      Convert 2D point to rational 3D, setting w to 1.
508  *
509  *      The Apple version incorrectly declares the type of 'result' to
510  *      be TQ3Point3D rather than TQ3RationalPoint3D. At a binary level
511  *      there is no difference, but at the source code level the Apple
512  *      version forces the use of the incorrect type or type casting.
513  *
514  *      Available in inline form as Q3FastPoint2D_To3D.
515  *
516  *  @param point2D          Address of 2D point to convert.
517  *  @param result           Address of 3D rational point to set.
518  *  @result                 Convenience copy of result parameter.
519  */
520 Q3_EXTERN_API_C ( TQ3RationalPoint3D * )
521 Q3Point2D_To3D (
522     const TQ3Point2D              *point2D,
523     TQ3RationalPoint3D            *result
524 );
525 
526 
527 
528 /*!
529  *  @function
530  *      Q3RationalPoint3D_To2D
531  *  @discussion
532  *      Convert rational 3D point to 2D, dividing by w.
533  *
534  *      Available in inline form as Q3FastRationalPoint3D_To2D.
535  *
536  *  @param rationalPoint3D  Address of rational 3D point to convert.
537  *  @param result           Address of 2D point to set.
538  *  @result                 Convenience copy of result parameter.
539  */
540 Q3_EXTERN_API_C ( TQ3Point2D * )
541 Q3RationalPoint3D_To2D (
542     const TQ3RationalPoint3D      *rationalPoint3D,
543     TQ3Point2D                    *result
544 );
545 
546 
547 
548 /*!
549  *  @function
550  *      Q3Point3D_To4D
551  *  @discussion
552  *      Convert 3D point to rational 4D, setting w to 1.
553  *
554  *      Available in inline form as Q3FastPoint3D_To4D.
555  *
556  *  @param point3D          Address of 3D point to convert.
557  *  @param result           Address of rational 4D point to set.
558  *  @result                 Convenience copy of result parameter.
559  */
560 Q3_EXTERN_API_C ( TQ3RationalPoint4D * )
561 Q3Point3D_To4D (
562     const TQ3Point3D              *point3D,
563     TQ3RationalPoint4D            *result
564 );
565 
566 
567 
568 /*!
569  *  @function
570  *      Q3RationalPoint4D_To3D
571  *  @discussion
572  *      Convert rational 4D point to 3D, dividing by w.
573  *
574  *      Available in inline form as Q3FastRationalPoint4D_To3D.
575  *
576  *  @param rationalPoint4D  Address of rational 4D point to convert.
577  *  @param result           Address of 3D point to set.
578  *  @result                 Convenience copy of result parameter.
579  */
580 Q3_EXTERN_API_C ( TQ3Point3D * )
581 Q3RationalPoint4D_To3D (
582     const TQ3RationalPoint4D      *rationalPoint4D,
583     TQ3Point3D                    *result
584 );
585 
586 
587 
588 
589 
590 //=============================================================================
591 //      Point conversion from cartesian to polar/spherical
592 //-----------------------------------------------------------------------------
593 /*!
594  *  @function
595  *      Q3Point2D_ToPolar
596  *  @discussion
597  *      Convert 2D cartesian point to polar coordinates.
598  *
599  *      The angle (theta) here is measured counter-clockwise from the +x axis.
600  *
601  *  @param point2D          Address of 2D point to convert.
602  *  @param result           Address of polar point to set.
603  *  @result                 Convenience copy of result parameter.
604  */
605 Q3_EXTERN_API_C ( TQ3PolarPoint * )
606 Q3Point2D_ToPolar (
607     const TQ3Point2D              *point2D,
608     TQ3PolarPoint                 *result
609 );
610 
611 
612 
613 /*!
614  *  @function
615  *      Q3PolarPoint_ToPoint2D
616  *  @discussion
617  *      Convert 2D polar point to cartesian coordinates.
618  *
619  *      The angle (theta) here is measured counter-clockwise from the +x axis.
620  *
621  *      Available in inline form as Q3FastPolarPoint_ToPoint2D.
622  *
623  *  @param polarPoint       Address of polar point to convert.
624  *  @param result           Address of 2D cartesian point to set.
625  *  @result                 Convenience copy of result parameter.
626  */
627 Q3_EXTERN_API_C ( TQ3Point2D * )
628 Q3PolarPoint_ToPoint2D (
629     const TQ3PolarPoint           *polarPoint,
630     TQ3Point2D                    *result
631 );
632 
633 
634 
635 /*!
636  *  @function
637  *      Q3Point3D_ToSpherical
638  *  @discussion
639  *      Convert 3D cartesian point to spherical coordinates.
640  *
641  *  @param point3D          Address of 3D cartesian point to convert.
642  *  @param result           Address of spherical-coordinates point to set.
643  *  @result                 Convenience copy of result parameter.
644  */
645 Q3_EXTERN_API_C ( TQ3SphericalPoint * )
646 Q3Point3D_ToSpherical (
647     const TQ3Point3D              *point3D,
648     TQ3SphericalPoint             *result
649 );
650 
651 
652 
653 /*!
654  *  @function
655  *      Q3SphericalPoint_ToPoint3D
656  *  @discussion
657  *      Convert 3D spherical point to cartesian coordinates.
658  *
659  *  @param sphericalPoint   Address of spherical-coordinates point to convert.
660  *  @param result           Address of 3D cartesian point to set.
661  *  @result                 Convenience copy of result parameter.
662  */
663 Q3_EXTERN_API_C ( TQ3Point3D * )
664 Q3SphericalPoint_ToPoint3D (
665     const TQ3SphericalPoint       *sphericalPoint,
666     TQ3Point3D                    *result
667 );
668 
669 
670 
671 
672 
673 //=============================================================================
674 //      Dot product
675 //-----------------------------------------------------------------------------
676 /*!
677  *  @function
678  *      Q3Vector2D_Dot
679  *  @discussion
680  *      Return the dot product of two 2D vectors.
681  *
682  *      Available in inline form as Q3FastVector2D_Dot.
683  *
684  *  @param v1               Address of first vector.
685  *  @param v2               Address of second vector.
686  *  @result                 Dot product of the two vectors.
687  */
688 Q3_EXTERN_API_C ( float  )
689 Q3Vector2D_Dot (
690     const TQ3Vector2D             *v1,
691     const TQ3Vector2D             *v2
692 );
693 
694 
695 
696 /*!
697  *  @function
698  *      Q3Vector3D_Dot
699  *  @discussion
700  *      Return the dot product of two 3D vectors.
701  *
702  *      Available in inline form as Q3FastVector3D_Dot.
703  *
704  *  @param v1               Address of first vector.
705  *  @param v2               Address of second vector.
706  *  @result                 Dot product of the two vectors.
707  */
708 Q3_EXTERN_API_C ( float  )
709 Q3Vector3D_Dot (
710     const TQ3Vector3D             *v1,
711     const TQ3Vector3D             *v2
712 );
713 
714 
715 
716 /*!
717  *  @function
718  *      Q3Vector3D_DotArray
719  *  @discussion
720  *      Calculate an array of dot products.
721  *
722  *      Given two arrays of vectors, an array of dot products is returned along
723  *      with an array of TQ3Booleans indicating which dot products are less than
724  *      zero.
725  *
726  *      At least one of dotProducts or dotLessThanZero must be non-NULL, however
727  *      one parameter may be set to NULL if that information is not required.
728  *
729  *      <em>This function is not available in QD3D.</em>
730  *
731  *  @param inFirstVectors3D             First array of 3D vectors to dot.
732  *  @param inSecondVectors3D            Second array of 3D vectors to dot.
733  *  @param outDotProducts               Array of scalars to receive the dot products.
734  *  @param outDotLessThanZeros          Array of booleans to receive the "< 0.0" status of the dot products.
735  *  @param numVectors                   How many elements are in each array.
736  *  @param inStructSize                 Size of one element of input arrays, typically sizeof(TQ3Vector3D).
737  *  @param outDotProductStructSize      Size of one element of the outDotProducts array, typically sizeof(float).
738  *  @param outDotLessThanZeroStructSize Size of one element of the outDotLessThanZeros array, typically sizeof(TQ3Boolean).
739  *  @result                             kQ3Success or some error code.
740  */
741 #if QUESA_ALLOW_QD3D_EXTENSIONS
742 
743 Q3_EXTERN_API_C ( TQ3Status  )
744 Q3Vector3D_DotArray(
745     const TQ3Vector3D             *inFirstVectors3D,
746     const TQ3Vector3D             *inSecondVectors3D,
747     float                         *outDotProducts,
748     TQ3Boolean                    *outDotLessThanZeros,
749     TQ3Uns32                      numVectors,
750     TQ3Uns32                      inStructSize,
751     TQ3Uns32                      outDotProductStructSize,
752     TQ3Uns32                      outDotLessThanZeroStructSize
753 );
754 
755 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
756 
757 
758 
759 
760 
761 //=============================================================================
762 //      Cross product
763 //-----------------------------------------------------------------------------
764 /*!
765  *  @function
766  *      Q3Vector2D_Cross
767  *  @discussion
768  *      Return the length of the cross product of two 2D vectors.
769  *
770  *		Equivalently, we assume that the 2D vectors are really 3D vectors with
771  *		z=0, then return the z coordinate of the cross product (0,0,z).
772  *
773  *      Available in inline form as Q3FastVector2D_Cross.
774  *
775  *  @param v1               Address of first vector.
776  *  @param v2               Address of second vector.
777  *  @result                 Length of the 2D cross product.
778  */
779 Q3_EXTERN_API_C ( float  )
780 Q3Vector2D_Cross (
781     const TQ3Vector2D             *v1,
782     const TQ3Vector2D             *v2
783 );
784 
785 
786 
787 /*!
788  *  @function
789  *      Q3Point2D_CrossProductTri
790  *  @discussion
791  *		Return the length of the cross product of a triangle specified by
792  *		three 2D points, that is, of the vectors p2-p1 and p3-p2.
793  *
794  *      <em>This function is not available in QD3D.</em>
795  *
796  *      Available in inline form as Q3FastPoint2D_CrossProductTri.
797  *
798  *  @param p1               Address of one point in the triangle.
799  *  @param p2               Address of a second point in the triangle.
800  *  @param p3               Address of a third point in the triangle.
801  *  @result                 Length of (p2-p1) x (p3-p2).
802  */
803 #if QUESA_ALLOW_QD3D_EXTENSIONS
804 
805 Q3_EXTERN_API_C ( float )
806 Q3Point2D_CrossProductTri (
807     const TQ3Point2D              *p1,
808     const TQ3Point2D              *p2,
809     const TQ3Point2D              *p3
810 );
811 
812 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
813 
814 
815 
816 /*!
817  *  @function
818  *      Q3Vector3D_Cross
819  *  @discussion
820  *      Return 3D cross product of two 3D vectors.
821  *
822  *      Available in inline form as Q3FastVector3D_Cross.
823  *
824  *  @param v1               Address of first vector.
825  *  @param v2               Address of second vector.
826  *  @param result           Address of vector to set with the result;
827  *							may be the same address as v1 and/or v2.
828  *  @result                 Convenience copy of result parameter.
829  */
830 Q3_EXTERN_API_C ( TQ3Vector3D * )
831 Q3Vector3D_Cross (
832     const TQ3Vector3D             *v1,
833     const TQ3Vector3D             *v2,
834     TQ3Vector3D                   *result
835 );
836 
837 
838 
839 /*!
840  *  @function
841  *      Q3Point3D_CrossProductTri
842  *  @discussion
843  *      Return the cross product of triangle triangle defined by three
844  *		3D points, that is, of the vectors p2-p1 and p3-p2.
845  *
846  *      Available in inline form as Q3FastPoint3D_CrossProductTri.
847  *
848  *  @param p1               Address of one point in the triangle.
849  *  @param p2               Address of a second point in the triangle.
850  *  @param p3               Address of a third point in the triangle.
851  *  @param result           Address of vector to set with cross product (p2-p1) x (p3-p2).
852  *  @result                 Convenience copy of result parameter.
853  */
854 Q3_EXTERN_API_C ( TQ3Vector3D * )
855 Q3Point3D_CrossProductTri (
856     const TQ3Point3D              *p1,
857     const TQ3Point3D              *p2,
858     const TQ3Point3D              *p3,
859     TQ3Vector3D                   *result
860 );
861 
862 
863 
864 /*!
865  *  @function
866  *      Q3Triangle_CrossProductArray
867  *  @discussion
868  *      Calculate an array of triangle normals.
869  *
870  *      Triangles are specified as a contiguous array of triangle indices,
871  *      and a contiguous array of points. The result is a contiguous array
872  *      of triangle normals.
873  *
874  *      Triangles may be omitted from processing with the usageFlags parameter,
875  *      which should point to an array of TQ3Uns8 flags. If usageFlags is not
876  *      NULL, only triangles whose corresponding entry in this array is 0 will
877  *      be processed.
878  *
879  *      The returning vectors are normalized.
880  *
881  *      <em>This function is not available in QD3D.</em>
882  *
883  *  @param numTriangles     The number of triangles to process.
884  *  @param usageFlags       The optional usage flags, indicating the triangles to process.
885  *  @param theIndices       The triangle indices.
886  *  @param thePoints        The triangle points.
887  *  @param theNormals       Receives the triangle normals.
888  *  @result                 Success or failure of the operation.
889  */
890 #if QUESA_ALLOW_QD3D_EXTENSIONS
891 
892 Q3_EXTERN_API_C ( TQ3Status  )
893 Q3Triangle_CrossProductArray(
894     TQ3Uns32                    numTriangles,
895     const TQ3Uns8               *usageFlags,
896     const TQ3Uns32              *theIndices,
897     const TQ3Point3D            *thePoints,
898     TQ3Vector3D                 *theNormals
899 );
900 
901 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
902 
903 
904 
905 
906 
907 //=============================================================================
908 //      Vector length
909 //-----------------------------------------------------------------------------
910 /*!
911  *  @function
912  *      Q3Vector2D_Length
913  *  @discussion
914  *      Return length of 2D vector.
915  *
916  *      Available in inline form as Q3FastVector2D_Length.
917  *
918  *  @param vector2D         Address of vector to get length of.
919  *  @result                 Length of the given vector.
920  */
921 Q3_EXTERN_API_C ( float  )
922 Q3Vector2D_Length (
923     const TQ3Vector2D             *vector2D
924 );
925 
926 
927 
928 /*!
929  *  @function
930  *      Q3Vector2D_LengthSquared
931  *  @discussion
932  *		Return squared length of 2D vector.
933  *
934  *		For many operations, knowing the squared length of a vector is just
935  *		as good as knowing the actual length (e.g., when sorting a set of
936  *		vectors by length, or comparing a vector to a cut-off length).  But
937  *		finding the squared length is much faster, since it avoids a costly
938  *		square root computation.
939  *
940  *      Available in inline form as Q3FastVector2D_LengthSquared.
941  *
942  *      <em>This function is not available in QD3D.</em>
943  *
944  *  @param vector2D         Address of vector to get length of.
945  *  @result                 Squared length of the given vector.
946  */
947 #if QUESA_ALLOW_QD3D_EXTENSIONS
948 
949 Q3_EXTERN_API_C ( float  )
950 Q3Vector2D_LengthSquared (
951     const TQ3Vector2D             *vector2D
952 );
953 
954 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
955 
956 
957 
958 /*!
959  *  @function
960  *      Q3Vector3D_Length
961  *  @discussion
962  *      Return length of 2D vector.
963  *
964  *      Available in inline form as Q3FastVector3D_Length.
965  *
966  *  @param vector3D         Address of vector to get length of.
967  *  @result                 Length of the given vector.
968  */
969 Q3_EXTERN_API_C ( float  )
970 Q3Vector3D_Length (
971     const TQ3Vector3D             *vector3D
972 );
973 
974 
975 
976 /*!
977  *  @function
978  *      Q3Vector3D_LengthSquared
979  *  @discussion
980  *		Return squared length of 2D vector.
981  *
982  *		For many operations, knowing the squared length of a vector is just
983  *		as good as knowing the actual length (e.g., when sorting a set of
984  *		vectors by length, or comparing a vector to a cut-off length).  But
985  *		finding the squared length is much faster, since it avoids a costly
986  *		square root computation.
987  *
988  *      Available in inline form as Q3FastVector3D_LengthSquared.
989  *
990  *      <em>This function is not available in QD3D.</em>
991  *
992  *  @param vector3D         Address of vector to get length of.
993  *  @result                 Squared length of the given vector.
994  */
995 #if QUESA_ALLOW_QD3D_EXTENSIONS
996 
997 Q3_EXTERN_API_C ( float  )
998 Q3Vector3D_LengthSquared (
999     const TQ3Vector3D             *vector3D
1000 );
1001 
1002 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
1003 
1004 
1005 
1006 
1007 
1008 //=============================================================================
1009 //      Point distance
1010 //-----------------------------------------------------------------------------
1011 /*!
1012  *  @function
1013  *      Q3Point2D_Distance
1014  *  @discussion
1015  *      Return Euclidean distance between two 2D points.
1016  *
1017  *      Available in inline form as Q3FastPoint2D_Distance.
1018  *
1019  *  @param p1               Address of first point of interest.
1020  *  @param p2               Address of second point of interest.
1021  *  @result                 Distance between the given points.
1022  */
1023 Q3_EXTERN_API_C ( float  )
1024 Q3Point2D_Distance (
1025     const TQ3Point2D              *p1,
1026     const TQ3Point2D              *p2
1027 );
1028 
1029 
1030 
1031 /*!
1032  *  @function
1033  *      Q3Point2D_DistanceSquared
1034  *  @discussion
1035  *      Return the squared Euclidean distance between two 2D points.
1036  *
1037  *      Available in inline form as Q3FastPoint2D_DistanceSquared.
1038  *
1039  *  @param p1               Address of first point of interest.
1040  *  @param p2               Address of second point of interest.
1041  *  @result                 Square of the distance between the given points.
1042  */
1043 Q3_EXTERN_API_C ( float  )
1044 Q3Point2D_DistanceSquared (
1045     const TQ3Point2D              *p1,
1046     const TQ3Point2D              *p2
1047 );
1048 
1049 
1050 
1051 /*!
1052  *  @function
1053  *      Q3Param2D_Distance
1054  *  @discussion
1055  *      Return Euclidean distance between two UV parameter points.
1056  *
1057  *      Available in inline form as Q3FastParam2D_Distance.
1058  *
1059  *  @param p1               Address of first point of interest.
1060  *  @param p2               Address of second point of interest.
1061  *  @result                 Distance between the given points.
1062  */
1063 Q3_EXTERN_API_C ( float  )
1064 Q3Param2D_Distance (
1065     const TQ3Param2D              *p1,
1066     const TQ3Param2D              *p2
1067 );
1068 
1069 
1070 
1071 /*!
1072  *  @function
1073  *      Q3Param2D_DistanceSquared
1074  *  @discussion
1075  *      Return the squared Euclidean distance between two UV parameter points.
1076  *
1077  *      Available in inline form as Q3FastParam2D_DistanceSquared.
1078  *
1079  *  @param p1               Address of first point of interest.
1080  *  @param p2               Address of second point of interest.
1081  *  @result                 Square of the distance between the given points.
1082  */
1083 Q3_EXTERN_API_C ( float  )
1084 Q3Param2D_DistanceSquared (
1085     const TQ3Param2D              *p1,
1086     const TQ3Param2D              *p2
1087 );
1088 
1089 
1090 
1091 /*!
1092  *  @function
1093  *      Q3RationalPoint3D_Distance
1094  *  @discussion
1095  *		Returns the Euclidian distance between two rational 3D points.
1096  *
1097  *      This operation makes no sense mathematically, but is included
1098  *		for backwards compatibility with QD3D.
1099  *
1100  *      Available in inline form as Q3FastRationalPoint3D_Distance.
1101  *
1102  *  @param p1               Address of first point of interest.
1103  *  @param p2               Address of second point of interest.
1104  *  @result                 Distance between the given points, treating
1105  *							w as a spatial coordinate.
1106  */
1107 Q3_EXTERN_API_C ( float  )
1108 Q3RationalPoint3D_Distance (
1109     const TQ3RationalPoint3D      *p1,
1110     const TQ3RationalPoint3D      *p2
1111 );
1112 
1113 
1114 
1115 /*!
1116  *  @function
1117  *      Q3RationalPoint3D_DistanceSquared
1118  *  @discussion
1119  *		Returns the squared Euclidian distance between two rational 3D points.
1120  *
1121  *      This operation makes no sense mathematically, but is included
1122  *		for backwards compatibility with QD3D.
1123  *
1124  *      Available in inline form as Q3FastRationalPoint3D_DistanceSquared.
1125  *
1126  *  @param p1               Address of first point of interest.
1127  *  @param p2               Address of second point of interest.
1128  *  @result                 Square of the distance between the given points,
1129  *							treating w as a spatial coordinate.
1130  */
1131 Q3_EXTERN_API_C ( float  )
1132 Q3RationalPoint3D_DistanceSquared (
1133     const TQ3RationalPoint3D      *p1,
1134     const TQ3RationalPoint3D      *p2
1135 );
1136 
1137 
1138 
1139 /*!
1140  *  @function
1141  *      Q3Point3D_Distance
1142  *  @discussion
1143  *      Return Euclidean distance between two 3D points.
1144  *
1145  *      Available in inline form as Q3FastPoint3D_Distance.
1146  *
1147  *  @param p1               Address of first point of interest.
1148  *  @param p2               Address of second point of interest.
1149  *  @result                 Distance between the given points.
1150  */
1151 Q3_EXTERN_API_C ( float  )
1152 Q3Point3D_Distance (
1153     const TQ3Point3D              *p1,
1154     const TQ3Point3D              *p2
1155 );
1156 
1157 
1158 
1159 /*!
1160  *  @function
1161  *      Q3Point3D_DistanceSquared
1162  *  @discussion
1163  *      Return the squared Euclidean distance between two 3D points.
1164  *
1165  *      Available in inline form as Q3FastPoint3D_DistanceSquared.
1166  *
1167  *  @param p1               Address of first point of interest.
1168  *  @param p2               Address of second point of interest.
1169  *  @result                 Square of the distance between the given points.
1170  */
1171 Q3_EXTERN_API_C ( float  )
1172 Q3Point3D_DistanceSquared (
1173     const TQ3Point3D              *p1,
1174     const TQ3Point3D              *p2
1175 );
1176 
1177 
1178 
1179 /*!
1180  *  @function
1181  *      Q3RationalPoint4D_Distance
1182  *  @discussion
1183  *		Returns the Euclidian distance between two rational 4D points.
1184  *
1185  *      This operation makes no sense mathematically, but is included
1186  *		for backwards compatibility with QD3D.
1187  *
1188  *      Available in inline form as Q3FastRationalPoint4D_Distance.
1189  *
1190  *  @param p1               Address of first point of interest.
1191  *  @param p2               Address of second point of interest.
1192  *  @result                 Distance between the given points, treating
1193  *							w as a spatial coordinate.
1194  */
1195 Q3_EXTERN_API_C ( float  )
1196 Q3RationalPoint4D_Distance (
1197     const TQ3RationalPoint4D      *p1,
1198     const TQ3RationalPoint4D      *p2
1199 );
1200 
1201 
1202 
1203 /*!
1204  *  @function
1205  *      Q3RationalPoint4D_DistanceSquared
1206  *  @discussion
1207  *		Returns the squared Euclidian distance between two rational 4D points.
1208  *
1209  *      This operation makes no sense mathematically, but is included
1210  *		for backwards compatibility with QD3D.
1211  *
1212  *      Available in inline form as Q3FastRationalPoint4D_DistanceSquared.
1213  *
1214  *  @param p1               Address of first point of interest.
1215  *  @param p2               Address of second point of interest.
1216  *  @result                 Square of the distance between the given points,
1217  *							treating w as a spatial coordinate.
1218  */
1219 Q3_EXTERN_API_C ( float  )
1220 Q3RationalPoint4D_DistanceSquared (
1221     const TQ3RationalPoint4D      *p1,
1222     const TQ3RationalPoint4D      *p2
1223 );
1224 
1225 
1226 
1227 
1228 
1229 //=============================================================================
1230 //      Vector negation
1231 //-----------------------------------------------------------------------------
1232 /*!
1233  *  @function
1234  *      Q3Vector2D_Negate
1235  *  @discussion
1236  *      Scale a 2D vector by a factor of -1.
1237  *
1238  *      Available in inline form as Q3FastVector2D_Negate.
1239  *
1240  *  @param vector2D         Address of vector to negate.
1241  *  @param result           Address of vector to set (may be the same as vector2D).
1242  *  @result                 Convenience copy of result parameter.
1243  */
1244 Q3_EXTERN_API_C ( TQ3Vector2D * )
1245 Q3Vector2D_Negate (
1246     const TQ3Vector2D             *vector2D,
1247     TQ3Vector2D                   *result
1248 );
1249 
1250 
1251 
1252 /*!
1253  *  @function
1254  *      Q3Vector3D_Negate
1255  *  @discussion
1256  *      Scale a 3D vector by a factor of -1.
1257  *
1258  *      Available in inline form as Q3FastVector3D_Negate.
1259  *
1260  *  @param vector3D         Address of vector to negate.
1261  *  @param result           Address of vector to set (may be the same as vector3D).
1262  *  @result                 Convenience copy of result parameter.
1263  */
1264 Q3_EXTERN_API_C ( TQ3Vector3D * )
1265 Q3Vector3D_Negate (
1266     const TQ3Vector3D             *vector3D,
1267     TQ3Vector3D                   *result
1268 );
1269 
1270 
1271 
1272 
1273 
1274 //=============================================================================
1275 //      Vector scale
1276 //-----------------------------------------------------------------------------
1277 /*!
1278  *  @function
1279  *      Q3Vector2D_Scale
1280  *  @discussion
1281  *      Scale a 2D vector by the given factor.
1282  *
1283  *      Available in inline form as Q3FastVector2D_Scale.
1284  *
1285  *  @param vector2D         Address of vector to scale.
1286  *  @param scalar           Scaling factor.
1287  *  @param result           Address of vector to set (may be the same as vector2D).
1288  *  @result                 Convenience copy of result parameter.
1289  */
1290 Q3_EXTERN_API_C ( TQ3Vector2D * )
1291 Q3Vector2D_Scale (
1292     const TQ3Vector2D             *vector2D,
1293     float                         scalar,
1294     TQ3Vector2D                   *result
1295 );
1296 
1297 
1298 
1299 /*!
1300  *  @function
1301  *      Q3Vector3D_Scale
1302  *  @discussion
1303  *      Scale a 3D vector by the given factor.
1304  *
1305  *      Available in inline form as Q3FastVector3D_Scale.
1306  *
1307  *  @param vector3D         Address of vector to scale.
1308  *  @param scalar           Scaling factor.
1309  *  @param result           Address of vector to set (may be the same as vector3D).
1310  *  @result                 Convenience copy of result parameter.
1311  */
1312 Q3_EXTERN_API_C ( TQ3Vector3D * )
1313 Q3Vector3D_Scale (
1314     const TQ3Vector3D             *vector3D,
1315     float                         scalar,
1316     TQ3Vector3D                   *result
1317 );
1318 
1319 
1320 
1321 
1322 
1323 //=============================================================================
1324 //      Vector normalize
1325 //-----------------------------------------------------------------------------
1326 /*!
1327  *  @function
1328  *      Q3Vector2D_Normalize
1329  *  @discussion
1330  *      Scale a 2D vector to length 1.
1331  *
1332  *      To obtain valid results, the length of vector2D must not be 0.
1333  *
1334  *      Available in inline form as Q3FastVector2D_Normalize.
1335  *
1336  *  @param vector2D         Address of vector to normalize.
1337  *  @param result           Address of vector to set (may be the same as vector2D).
1338  *  @result                 Convenience copy of result parameter.
1339  */
1340 Q3_EXTERN_API_C ( TQ3Vector2D * )
1341 Q3Vector2D_Normalize (
1342     const TQ3Vector2D             *vector2D,
1343     TQ3Vector2D                   *result
1344 );
1345 
1346 
1347 
1348 /*!
1349  *  @function
1350  *      Q3Vector3D_Normalize
1351  *  @discussion
1352  *      Scale a 3D vector to length 1.
1353  *
1354  *      To obtain valid results, the length of vector3D must not be 0.
1355  *
1356  *      Available in inline form as Q3FastVector3D_Normalize.
1357  *
1358  *  @param vector3D         Address of vector to normalize.
1359  *  @param result           Address of vector to set (may be the same as vector3D).
1360  *  @result                 Convenience copy of result parameter.
1361  */
1362 Q3_EXTERN_API_C ( TQ3Vector3D * )
1363 Q3Vector3D_Normalize (
1364     const TQ3Vector3D             *vector3D,
1365     TQ3Vector3D                   *result
1366 );
1367 
1368 
1369 
1370 
1371 
1372 //=============================================================================
1373 //      Vector-vector addition/subtraction
1374 //-----------------------------------------------------------------------------
1375 /*!
1376  *  @function
1377  *      Q3Vector2D_Add
1378  *  @discussion
1379  *      Add two 2D vectors.
1380  *
1381  *      Available in inline form as Q3FastVector2D_Add.
1382  *
1383  *  @param v1               Address of first vector to add.
1384  *  @param v2               Address of second vector to add.
1385  *  @param result           Address of vector to set (may be the same as v1 and/or v2).
1386  *  @result                 Convenience copy of result parameter.
1387  */
1388 Q3_EXTERN_API_C ( TQ3Vector2D * )
1389 Q3Vector2D_Add (
1390     const TQ3Vector2D             *v1,
1391     const TQ3Vector2D             *v2,
1392     TQ3Vector2D                   *result
1393 );
1394 
1395 
1396 
1397 /*!
1398  *  @function
1399  *      Q3Vector3D_Add
1400  *  @discussion
1401  *      Add two 3D vectors.
1402  *
1403  *      Available in inline form as Q3FastVector3D_Add.
1404  *
1405  *  @param v1               Address of first vector to add.
1406  *  @param v2               Address of second vector to add.
1407  *  @param result           Address of vector to set (may be the same as v1 and/or v2).
1408  *  @result                 Convenience copy of result parameter.
1409  */
1410 Q3_EXTERN_API_C ( TQ3Vector3D * )
1411 Q3Vector3D_Add (
1412     const TQ3Vector3D             *v1,
1413     const TQ3Vector3D             *v2,
1414     TQ3Vector3D                   *result
1415 );
1416 
1417 
1418 
1419 /*!
1420  *  @function
1421  *      Q3Vector2D_Subtract
1422  *  @discussion
1423  *      Subtract 2D vector v2 from v1.
1424  *
1425  *      Available in inline form as Q3FastVector2D_Subtract.
1426  *
1427  *  @param v1               Address of first vector.
1428  *  @param v2               Address of vector to subtract from v1.
1429  *  @param result           Address of vector to set (may be the same as v1 and/or v2).
1430  *  @result                 Convenience copy of result parameter.
1431  */
1432 Q3_EXTERN_API_C ( TQ3Vector2D * )
1433 Q3Vector2D_Subtract (
1434     const TQ3Vector2D             *v1,
1435     const TQ3Vector2D             *v2,
1436     TQ3Vector2D                   *result
1437 );
1438 
1439 
1440 
1441 /*!
1442  *  @function
1443  *      Q3Vector3D_Subtract
1444  *  @discussion
1445  *      Subtract 3D vector v2 from v1.
1446  *
1447  *      Available in inline form as Q3FastVector3D_Subtract.
1448  *
1449  *  @param v1               Address of first vector.
1450  *  @param v2               Address of vector to subtract from v1.
1451  *  @param result           Address of vector to set (may be the same as v1 and/or v2).
1452  *  @result                 Convenience copy of result parameter.
1453  */
1454 Q3_EXTERN_API_C ( TQ3Vector3D * )
1455 Q3Vector3D_Subtract (
1456     const TQ3Vector3D             *v1,
1457     const TQ3Vector3D             *v2,
1458     TQ3Vector3D                   *result
1459 );
1460 
1461 
1462 
1463 
1464 
1465 //=============================================================================
1466 //      Point and Vector addition/subtraction
1467 //-----------------------------------------------------------------------------
1468 /*!
1469  *  @function
1470  *      Q3Point2D_Vector2D_Add
1471  *  @discussion
1472  *      Add a 2D vector to a point.
1473  *
1474  *      Available in inline form as Q3FastPoint2D_Vector2D_Add.
1475  *
1476  *  @param point2D          Address of a point.
1477  *  @param vector2D         Address of a vector to add.
1478  *  @param result           Address of point to set (may be the same as point2D).
1479  *  @result                 Convenience copy of result parameter.
1480  */
1481 Q3_EXTERN_API_C ( TQ3Point2D * )
1482 Q3Point2D_Vector2D_Add (
1483     const TQ3Point2D              *point2D,
1484     const TQ3Vector2D             *vector2D,
1485     TQ3Point2D                    *result
1486 );
1487 
1488 
1489 
1490 /*!
1491  *  @function
1492  *      Q3Param2D_Vector2D_Add
1493  *  @discussion
1494  *      Add a 2D vector to a parametric (UV) point.
1495  *
1496  *      Available in inline form as Q3FastParam2D_Vector2D_Add.
1497  *
1498  *  @param param2D          Address of a 2D parametric point.
1499  *  @param vector2D         Address of a vector to add.
1500  *  @param result           Address of point to set (may be the same as param2D).
1501  *  @result                 Convenience copy of result parameter.
1502  */
1503 Q3_EXTERN_API_C ( TQ3Param2D * )
1504 Q3Param2D_Vector2D_Add (
1505     const TQ3Param2D              *param2D,
1506     const TQ3Vector2D             *vector2D,
1507     TQ3Param2D                    *result
1508 );
1509 
1510 
1511 
1512 /*!
1513  *  @function
1514  *      Q3Point3D_Vector3D_Add
1515  *  @discussion
1516  *      Add a 3D vector to a point.
1517  *
1518  *      Available in inline form as Q3FastPoint3D_Vector3D_Add.
1519  *
1520  *  @param point3D          Address of a point.
1521  *  @param vector3D         Address of a vector to add.
1522  *  @param result           Address of point to set (may be the same as point3D).
1523  *  @result                 Convenience copy of result parameter.
1524  */
1525 Q3_EXTERN_API_C ( TQ3Point3D * )
1526 Q3Point3D_Vector3D_Add (
1527     const TQ3Point3D              *point3D,
1528     const TQ3Vector3D             *vector3D,
1529     TQ3Point3D                    *result
1530 );
1531 
1532 
1533 
1534 /*!
1535  *  @function
1536  *      Q3Point2D_Vector2D_Subtract
1537  *  @discussion
1538  *      Subtract a 2D vector from a point.
1539  *
1540  *      Available in inline form as Q3FastPoint2D_Vector2D_Subtract.
1541  *
1542  *  @param point2D          Address of a point.
1543  *  @param vector2D         Address of a vector to subtract.
1544  *  @param result           Address of point to set (may be the same as point2D).
1545  *  @result                 Convenience copy of result parameter.
1546  */
1547 Q3_EXTERN_API_C ( TQ3Point2D * )
1548 Q3Point2D_Vector2D_Subtract (
1549     const TQ3Point2D              *point2D,
1550     const TQ3Vector2D             *vector2D,
1551     TQ3Point2D                    *result
1552 );
1553 
1554 
1555 
1556 /*!
1557  *  @function
1558  *      Q3Param2D_Vector2D_Subtract
1559  *  @discussion
1560  *      Subtract a 2D vector from a parametric (UV) point.
1561  *
1562  *      Available in inline form as Q3FastParam2D_Vector2D_Subtract.
1563  *
1564  *  @param param2D          Address of a 2D parametric point.
1565  *  @param vector2D         Address of a vector to subtract.
1566  *  @param result           Address of point to set (may be the same as param2D).
1567  *  @result                 Convenience copy of result parameter.
1568  */
1569 Q3_EXTERN_API_C ( TQ3Param2D * )
1570 Q3Param2D_Vector2D_Subtract (
1571     const TQ3Param2D              *param2D,
1572     const TQ3Vector2D             *vector2D,
1573     TQ3Param2D                    *result
1574 );
1575 
1576 
1577 
1578 /*!
1579  *  @function
1580  *      Q3Point3D_Vector3D_Subtract
1581  *  @discussion
1582  *      Subtract 3D vector from point.
1583  *
1584  *      Available in inline form as Q3FastPoint3D_Vector3D_Subtract.
1585  *
1586  *  @param point3D          Address of a point.
1587  *  @param vector3D         Address of a vector to subtract.
1588  *  @param result           Address of point to set (may be the same as point3D).
1589  *  @result                 Convenience copy of result parameter.
1590  */
1591 Q3_EXTERN_API_C ( TQ3Point3D * )
1592 Q3Point3D_Vector3D_Subtract (
1593     const TQ3Point3D              *point3D,
1594     const TQ3Vector3D             *vector3D,
1595     TQ3Point3D                    *result
1596 );
1597 
1598 
1599 
1600 
1601 
1602 //=============================================================================
1603 //      Point subtraction
1604 //-----------------------------------------------------------------------------
1605 /*!
1606  *  @function
1607  *      Q3Point2D_Subtract
1608  *  @discussion
1609  *      Subtract the 2D point p2 from p1.
1610  *
1611  *      Available in inline form as Q3FastPoint2D_Subtract.
1612  *
1613  *  @param p1               Address of a point.
1614  *  @param p2               Address of point to subtract.
1615  *  @param result           Address of a vector to set with (p1-p2).
1616  *  @result                 Convenience copy of result parameter.
1617  */
1618 Q3_EXTERN_API_C ( TQ3Vector2D * )
1619 Q3Point2D_Subtract (
1620     const TQ3Point2D              *p1,
1621     const TQ3Point2D              *p2,
1622     TQ3Vector2D                   *result
1623 );
1624 
1625 
1626 
1627 /*!
1628  *  @function
1629  *      Q3Param2D_Subtract
1630  *  @discussion
1631  *      Subtract 2D parametric point p2 from p1.
1632  *
1633  *      Available in inline form as Q3FastParam2D_Subtract.
1634  *
1635  *  @param p1               Address of a point.
1636  *  @param p2               Address of point to subtract.
1637  *  @param result           Address of a vector to set with (p1-p2).
1638  *  @result                 Convenience copy of result parameter.
1639  */
1640 Q3_EXTERN_API_C ( TQ3Vector2D * )
1641 Q3Param2D_Subtract (
1642     const TQ3Param2D              *p1,
1643     const TQ3Param2D              *p2,
1644     TQ3Vector2D                   *result
1645 );
1646 
1647 
1648 
1649 /*!
1650  *  @function
1651  *      Q3Point3D_Subtract
1652  *  @discussion
1653  *      Subtract 3D point p2 from p1.
1654  *
1655  *      Available in inline form as Q3FastPoint3D_Subtract.
1656  *
1657  *  @param p1               Address of a point.
1658  *  @param p2               Address of a point to subtract.
1659  *  @param result           Address of point to set (may be the same as p1 and/or p2).
1660  *  @result                 Convenience copy of result parameter.
1661  */
1662 Q3_EXTERN_API_C ( TQ3Vector3D * )
1663 Q3Point3D_Subtract (
1664     const TQ3Point3D              *p1,
1665     const TQ3Point3D              *p2,
1666     TQ3Vector3D                   *result
1667 );
1668 
1669 
1670 
1671 
1672 
1673 //=============================================================================
1674 //      Point relative ratio
1675 //-----------------------------------------------------------------------------
1676 /*!
1677  *  @function
1678  *      Q3Point2D_RRatio
1679  *  @discussion
1680  *      Return the point at ratio r2/(r1+r2) along the line segment from p1 to p2.
1681  *
1682  *		Put another way, this function gives you the weighted average of points
1683  *		p1 and p2, with the weights given by r1 and r2.  (Note that r1+r2 must
1684  *		be nonzero.)
1685  *
1686  *      NOTE: The QD3D docs claim that the ratio used is r1/(r1+r2), but
1687  *		it was found by direct experimentation that the QD3D library (1.6)
1688  *		in fact uses r2/(r1+r2) instead.  This is as it should be, if r1 is
1689  *		the weight of p1, and r2 is the weight of p2.
1690  *
1691  *		As usual, we do as QD3D does, not as the docs say.
1692  *
1693  *      Available in inline form as Q3FastPoint2D_RRatio.
1694  *
1695  *  @param p1               Address of one end of a line segment.
1696  *  @param p2               Address of the other end of a line segment.
1697  *  @param r1               Weight given to point p1.
1698  *  @param r2               Weight given to point p2.
1699  *  @param result           Address of point to set (may be the same as p1 and/or p2).
1700  *  @result                 Convenience copy of result parameter.
1701  */
1702 Q3_EXTERN_API_C ( TQ3Point2D * )
1703 Q3Point2D_RRatio (
1704     const TQ3Point2D              *p1,
1705     const TQ3Point2D              *p2,
1706     float                         r1,
1707     float                         r2,
1708     TQ3Point2D                    *result
1709 );
1710 
1711 
1712 
1713 /*!
1714  *  @function
1715  *      Q3Param2D_RRatio
1716  *  @discussion
1717  *      Return the point at ratio r2/(r1+r2) along the line segment is
1718  *		parameter (UV) space from p1 to p2.
1719  *
1720  *		Put another way, this function gives you the weighted average of points
1721  *		p1 and p2, with the weights given by r1 and r2.  (Note that r1+r2 must
1722  *		be nonzero.)
1723  *
1724  *      Available in inline form as Q3FastParam2D_RRatio.
1725  *
1726  *  @param p1               Address of one end of a line segment.
1727  *  @param p2               Address of the other end of a line segment.
1728  *  @param r1               Weight given to point p1.
1729  *  @param r2               Weight given to point p2.
1730  *  @param result           Address of point to set (may be the same as p1 and/or p2).
1731  *  @result                 Convenience copy of result parameter.
1732  */
1733 Q3_EXTERN_API_C ( TQ3Param2D * )
1734 Q3Param2D_RRatio (
1735     const TQ3Param2D              *p1,
1736     const TQ3Param2D              *p2,
1737     float                         r1,
1738     float                         r2,
1739     TQ3Param2D                    *result
1740 );
1741 
1742 
1743 
1744 /*!
1745  *  @function
1746  *      Q3Point3D_RRatio
1747  *  @discussion
1748  *      Return the point at ratio r2/(r1+r2) along the line segment from p1 to p2.
1749  *
1750  *		Put another way, this function gives you the weighted average of points
1751  *		p1 and p2, with the weights given by r1 and r2.  (Note that r1+r2 must
1752  *		be nonzero.)
1753  *
1754  *      NOTE: The QD3D docs claim that the ratio used is r1/(r1+r2), but
1755  *		it was found by direct experimentation that the QD3D library (1.6)
1756  *		in fact uses r2/(r1+r2) instead.  This is as it should be, if r1 is
1757  *		the weight of p1, and r2 is the weight of p2.
1758  *
1759  *		As usual, we do as QD3D does, not as the docs say.
1760  *
1761  *      Available in inline form as Q3FastPoint3D_RRatio.
1762  *
1763  *  @param p1               Address of one end of a line segment.
1764  *  @param p2               Address of the other end of a line segment.
1765  *  @param r1               Weight given to point p1.
1766  *  @param r2               Weight given to point p2.
1767  *  @param result           Address of point to set (may be the same as p1 and/or p2).
1768  *  @result                 Convenience copy of result parameter.
1769  */
1770 Q3_EXTERN_API_C ( TQ3Point3D * )
1771 Q3Point3D_RRatio (
1772     const TQ3Point3D              *p1,
1773     const TQ3Point3D              *p2,
1774     float                         r1,
1775     float                         r2,
1776     TQ3Point3D                    *result
1777 );
1778 
1779 
1780 
1781 /*!
1782  *  @function
1783  *      Q3RationalPoint4D_RRatio
1784  *  @discussion
1785  *      Return the point at ratio r2/(r1+r2) along the line segment from p1 to p2.
1786  *
1787  *		Put another way, this function gives you the weighted average of points
1788  *		p1 and p2, with the weights given by r1 and r2.  (Note that r1+r2 must
1789  *		be nonzero.)
1790  *
1791  *      NOTE: The QD3D docs claim that the ratio used is r1/(r1+r2), but
1792  *		it was found by direct experimentation that the QD3D library (1.6)
1793  *		in fact uses r2/(r1+r2) instead.  This is as it should be, if r1 is
1794  *		the weight of p1, and r2 is the weight of p2.
1795  *
1796  *		As usual, we do as QD3D does, not as the docs say.
1797  *
1798  *      Available in inline form as Q3FastRationalPoint4D_RRatio.
1799  *
1800  *  @param p1               Address of one end of a line segment.
1801  *  @param p2               Address of the other end of a line segment.
1802  *  @param r1               Weight given to point p1.
1803  *  @param r2               Weight given to point p2.
1804  *  @param result           Address of point to set (may be the same as p1 and/or p2).
1805  *  @result                 Convenience copy of result parameter.
1806  */
1807 Q3_EXTERN_API_C ( TQ3RationalPoint4D * )
1808 Q3RationalPoint4D_RRatio (
1809     const TQ3RationalPoint4D      *p1,
1810     const TQ3RationalPoint4D      *p2,
1811     float                         r1,
1812     float                         r2,
1813     TQ3RationalPoint4D            *result
1814 );
1815 
1816 
1817 
1818 
1819 
1820 //=============================================================================
1821 //      Point affine combinations
1822 //-----------------------------------------------------------------------------
1823 /*!
1824  *  @function
1825  *      Q3Point2D_AffineComb
1826  *  @discussion
1827  *      Return weighted combination of several 2D points.
1828  *
1829  *		Provide an array of points and a parallel array of weights, and
1830  *		this function will compute the weighted combination.
1831  *
1832  *		Although the mathematical definition of an affine combination requires
1833  *		that the weights sum to 1, this function does not.  It divides by the
1834  *		sum of the weights, so it only requires that the sum is nonzero.
1835  *
1836  *		If you have only two points, use Q3Point2D_RRatio instead.
1837  *
1838  *  @param points2D         Array of 2D points.
1839  *  @param weights          Array of weights.
1840  *  @param numPoints        How many elements there are in each array.
1841  *  @param result           Address of point to set with the weighted combination.
1842  *  @result                 Convenience copy of result parameter.
1843  */
1844 Q3_EXTERN_API_C ( TQ3Point2D * )
1845 Q3Point2D_AffineComb (
1846     const TQ3Point2D              *points2D,
1847     const float                   *weights,
1848     TQ3Uns32                      numPoints,
1849     TQ3Point2D                    *result
1850 );
1851 
1852 
1853 
1854 /*!
1855  *  @function
1856  *      Q3Param2D_AffineComb
1857  *  @discussion
1858  *      Return weighted combination of several 2D parameter points.
1859  *
1860  *		Provide an array of points and a parallel array of weights, and
1861  *		this function will compute the weighted combination.
1862  *
1863  *		Although the mathematical definition of an affine combination requires
1864  *		that the weights sum to 1, this function does not.  It divides by the
1865  *		sum of the weights, so it only requires that the sum is nonzero.
1866  *
1867  *		If you have only two points, use Q3Param2D_RRatio instead.
1868  *
1869  *  @param params2D         Array of 2D parameter points.
1870  *  @param weights          Array of weights.
1871  *  @param numPoints        How many elements there are in each array.
1872  *  @param result           Address of point to set with the weighted combination.
1873  *  @result                 Convenience copy of result parameter.
1874  */
1875 Q3_EXTERN_API_C ( TQ3Param2D * )
1876 Q3Param2D_AffineComb (
1877     const TQ3Param2D              *params2D,
1878     const float                   *weights,
1879     TQ3Uns32                      numPoints,
1880     TQ3Param2D                    *result
1881 );
1882 
1883 
1884 
1885 /*!
1886  *  @function
1887  *      Q3RationalPoint3D_AffineComb
1888  *  @discussion
1889  *		Compute the weighted combination of several 3D rational points.
1890  *
1891  *		Although the mathematical definition of an affine combination requires
1892  *		that the weights sum to 1, this function does not.  It divides by the
1893  *		sum of the weights, so it only requires that the sum is nonzero.
1894  *
1895  *  @param rationalPoints3D Array of 3D rational points.
1896  *  @param weights          Array of weights.
1897  *  @param numPoints        How many elements there are in each array.
1898  *  @param result           Address of point to set with the weighted combination.
1899  *  @result                 Convenience copy of result parameter.
1900  */
1901 Q3_EXTERN_API_C ( TQ3RationalPoint3D * )
1902 Q3RationalPoint3D_AffineComb (
1903     const TQ3RationalPoint3D      *rationalPoints3D,
1904     const float                   *weights,
1905     TQ3Uns32                      numPoints,
1906     TQ3RationalPoint3D            *result
1907 );
1908 
1909 
1910 
1911 /*!
1912  *  @function
1913  *      Q3Point3D_AffineComb
1914  *  @discussion
1915  *      Return weighted combination of several 3D points.
1916  *
1917  *		Provide an array of points and a parallel array of weights, and
1918  *		this function will compute the weighted combination.
1919  *
1920  *		Although the mathematical definition of an affine combination requires
1921  *		that the weights sum to 1, this function does not.  It divides by the
1922  *		sum of the weights, so it only requires that the sum is nonzero.
1923  *
1924  *		If you have only two points, use Q3Point3D_RRatio instead.
1925  *
1926  *  @param points3D         Array of 3D points.
1927  *  @param weights          Array of weights.
1928  *  @param numPoints        How many elements there are in each array.
1929  *  @param result           Address of point to set with the weighted combination.
1930  *  @result                 Convenience copy of result parameter.
1931  */
1932 Q3_EXTERN_API_C ( TQ3Point3D * )
1933 Q3Point3D_AffineComb (
1934     const TQ3Point3D              *points3D,
1935     const float                   *weights,
1936     TQ3Uns32                      numPoints,
1937     TQ3Point3D                    *result
1938 );
1939 
1940 
1941 
1942 /*!
1943  *  @function
1944  *      Q3RationalPoint4D_AffineComb
1945  *  @discussion
1946  *		Compute the weighted combination of several 4D rational points.
1947  *
1948  *		Although the mathematical definition of an affine combination requires
1949  *		that the weights sum to 1, this function does not.  It divides by the
1950  *		sum of the weights, so it only requires that the sum is nonzero.
1951  *
1952  *  @param rationalPoints4D Array of 4D rational points.
1953  *  @param weights          Array of weights.
1954  *  @param numPoints        How many elements there are in each array.
1955  *  @param result           Address of point to set with the weighted combination.
1956  *  @result                 Convenience copy of result parameter.
1957  */
1958 Q3_EXTERN_API_C ( TQ3RationalPoint4D * )
1959 Q3RationalPoint4D_AffineComb (
1960     const TQ3RationalPoint4D      *rationalPoints4D,
1961     const float                   *weights,
1962     TQ3Uns32                      numPoints,
1963     TQ3RationalPoint4D            *result
1964 );
1965 
1966 
1967 
1968 
1969 
1970 //=============================================================================
1971 //      Point and vector transformation
1972 //-----------------------------------------------------------------------------
1973 /*!
1974  *  @function
1975  *      Q3Vector2D_Transform
1976  *  @discussion
1977  *      Transform a 2D vector by a 3x3 matrix.
1978  *
1979  *		Note that the translation and perspective components of the
1980  *		matrix is ignored (as if it were really a 2x2 matrix).
1981  *
1982  *		Contrast with Q3Point2D_Transform, which does the full 3x3
1983  *		transformation.
1984  *
1985  *  @param vector2D         Address of a vector to transform.
1986  *  @param matrix3x3        Address of a 3x3 transformation matrix.
1987  *  @param result           Address of vector to set (may be the same as vector2D).
1988  *  @result                 Convenience copy of result parameter.
1989  */
1990 Q3_EXTERN_API_C ( TQ3Vector2D * )
1991 Q3Vector2D_Transform (
1992     const TQ3Vector2D             *vector2D,
1993     const TQ3Matrix3x3            *matrix3x3,
1994     TQ3Vector2D                   *result
1995 );
1996 
1997 
1998 
1999 /*!
2000  *  @function
2001  *      Q3Vector3D_Transform
2002  *  @discussion
2003  *      Transform a 3D vector by a 4x4 matrix.
2004  *
2005  *		Note that the translation and perspective components of the
2006  *		matrix is ignored (as if it were really a 3x3 matrix).
2007  *
2008  *		Contrast with Q3Point3D_Transform, which does the full 4x4
2009  *		transformation.
2010  *
2011  *  @param vector3D         Address of a vector to transform.
2012  *  @param matrix4x4        Address of a 4x4 transformation matrix.
2013  *  @param result           Address of vector to set (may be the same as vector3D).
2014  *  @result                 Convenience copy of result parameter.
2015  */
2016 Q3_EXTERN_API_C ( TQ3Vector3D * )
2017 Q3Vector3D_Transform (
2018     const TQ3Vector3D             *vector3D,
2019     const TQ3Matrix4x4            *matrix4x4,
2020     TQ3Vector3D                   *result
2021 );
2022 
2023 
2024 
2025 /*!
2026  *  @function
2027  *      Q3Point2D_Transform
2028  *  @discussion
2029  *      Transform a 2D point by a 3x3 matrix.
2030  *
2031  *  @param point2D          Address of a point to transform.
2032  *  @param matrix3x3        Address of a 3x3 transformation matrix.
2033  *  @param result           Address of point to set (may be the same as point2D).
2034  *  @result                 Convenience copy of result parameter.
2035  */
2036 Q3_EXTERN_API_C ( TQ3Point2D * )
2037 Q3Point2D_Transform (
2038     const TQ3Point2D              *point2D,
2039     const TQ3Matrix3x3            *matrix3x3,
2040     TQ3Point2D                    *result
2041 );
2042 
2043 
2044 
2045 /*!
2046  *  @function
2047  *      Q3Param2D_Transform
2048  *  @discussion
2049  *      Transform a 2D parametric point by a 3x3 matrix.
2050  *
2051  *  @param point2D          Address of a point to transform.
2052  *  @param matrix3x3        Address of a 3x3 transformation matrix.
2053  *  @param result           Address of point to set (may be the same as point2D).
2054  *  @result                 Convenience copy of result parameter.
2055  */
2056 Q3_EXTERN_API_C ( TQ3Param2D * )
2057 Q3Param2D_Transform (
2058     const TQ3Param2D              *param2D,
2059     const TQ3Matrix3x3            *matrix3x3,
2060     TQ3Param2D                    *result
2061 );
2062 
2063 
2064 
2065 /*!
2066  *  @function
2067  *      Q3RationalPoint3D_Transform
2068  *  @discussion
2069  *		Transform a 3D rational point by 3x3 matrix.
2070  *
2071  *      <em>This function is not available in QD3D.</em>
2072  *
2073  *  @param rationalPoint3D  Address of a point to transform.
2074  *  @param matrix3x3        Address of a 3x3 transformation matrix.
2075  *  @param result           Address of point to set (may be the same as rationalPoint3D).
2076  *  @result                 Convenience copy of result parameter.
2077  */
2078 #if QUESA_ALLOW_QD3D_EXTENSIONS
2079 
2080 Q3_EXTERN_API_C ( TQ3RationalPoint3D * )
2081 Q3RationalPoint3D_Transform (
2082     const TQ3RationalPoint3D      *rationalPoint3D,
2083     const TQ3Matrix3x3            *matri3x3,
2084     TQ3RationalPoint3D            *result
2085 );
2086 
2087 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
2088 
2089 
2090 
2091 /*!
2092  *  @function
2093  *      Q3Point3D_Transform
2094  *  @discussion
2095  *      Transform a 3D point by a 4x4 matrix.
2096  *
2097  *  @param point3D          Address of a point to transform.
2098  *  @param matrix4x4        Address of a 4x4 transformation matrix.
2099  *  @param result           Address of point to set (may be the same as point3D).
2100  *  @result                 Convenience copy of result parameter.
2101  */
2102 Q3_EXTERN_API_C ( TQ3Point3D * )
2103 Q3Point3D_Transform (
2104     const TQ3Point3D              *point3D,
2105     const TQ3Matrix4x4            *matrix4x4,
2106     TQ3Point3D                    *result
2107 );
2108 
2109 
2110 
2111 /*!
2112  *  @function
2113  *      Q3RationalPoint4D_Transform
2114  *  @discussion
2115  *      Transform a 4D rational point by a 4x4 matrix.
2116  *
2117  *  @param rationalPoint4D  Address of a point to transform.
2118  *  @param matrix4x4        Address of a 4x4 transformation matrix.
2119  *  @param result           Address of point to set (may be the same as rationalPoint4D).
2120  *  @result                 Convenience copy of result parameter.
2121  */
2122 Q3_EXTERN_API_C ( TQ3RationalPoint4D * )
2123 Q3RationalPoint4D_Transform (
2124     const TQ3RationalPoint4D      *rationalPoint4D,
2125     const TQ3Matrix4x4            *matrix4x4,
2126     TQ3RationalPoint4D            *result
2127 );
2128 
2129 
2130 
2131 /*!
2132  *  @function
2133  *      Q3Vector2D_To2DTransformArray
2134  *  @discussion
2135  *		Transform an array of 2D vectors by a 3x3 matrix.
2136  *
2137  *		When you have many vectors to transform, this is a more efficient
2138  *		alternative to calling Q3Vector2D_Transform repeatedly.
2139  *
2140  *      <em>This function is not available in QD3D.</em>
2141  *
2142  *  @param inVectors2D      Array of 2D vectors to transform.
2143  *  @param matrix3x3        Transformation matrix.
2144  *  @param outVectors2D     Array of vectors to receive output (may be the same as inVectors2D).
2145  *  @param numVectors       How many vectors are in each array.
2146  *  @param inStructSize     Size of one element of the input array, typically sizeof(TQ3Vector2D).
2147  *  @param outStructSize    Size of one element of the output array, typically sizeof(TQ3Vector2D).
2148  *  @result                 kQ3Success or some error code.
2149  */
2150 #if QUESA_ALLOW_QD3D_EXTENSIONS
2151 
2152 Q3_EXTERN_API_C ( TQ3Status  )
2153 Q3Vector2D_To2DTransformArray (
2154     const TQ3Vector2D             *inVectors2D,
2155     const TQ3Matrix3x3            *matrix3x3,
2156     TQ3Vector2D                   *outVectors2D,
2157     TQ3Uns32                      numVectors,
2158     TQ3Uns32                      inStructSize,
2159     TQ3Uns32                      outStructSize
2160 );
2161 
2162 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
2163 
2164 
2165 
2166 /*!
2167  *  @function
2168  *      Q3Vector3D_To3DTransformArray
2169  *  @discussion
2170  *		Transform an array of 3D vectors by a 4x4 matrix.
2171  *
2172  *		When you have many vectors to transform, this is a more efficient
2173  *		alternative to calling Q3Vector3D_Transform repeatedly.
2174  *
2175  *      <em>This function is not available in QD3D.</em>
2176  *
2177  *  @param inVectors3D      Array of 3D vectors to transform.
2178  *  @param matrix4x4        Transformation matrix.
2179  *  @param outVectors3D     Array of vectors to receive output (may be the same as inVectors3D).
2180  *  @param numVectors       How many vectors are in each array.
2181  *  @param inStructSize     Size of one element of the input array, typically sizeof(TQ3Vector3D).
2182  *  @param outStructSize    Size of one element of the output array, typically sizeof(TQ3Vector3D).
2183  *  @result                 kQ3Success or some error code.
2184  */
2185 #if QUESA_ALLOW_QD3D_EXTENSIONS
2186 
2187 Q3_EXTERN_API_C ( TQ3Status  )
2188 Q3Vector3D_To3DTransformArray (
2189     const TQ3Vector3D             *inVectors3D,
2190     const TQ3Matrix4x4            *matrix4x4,
2191     TQ3Vector3D                   *outVectors3D,
2192     TQ3Uns32                      numVectors,
2193     TQ3Uns32                      inStructSize,
2194     TQ3Uns32                      outStructSize
2195 );
2196 
2197 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
2198 
2199 
2200 
2201 /*!
2202  *  @function
2203  *      Q3Point2D_To2DTransformArray
2204  *  @discussion
2205  *		Transform an array of 2D points by a 3x3 matrix.
2206  *
2207  *		When you have many points to transform, this is a more efficient
2208  *		alternative to calling Q3Point2D_Transform repeatedly.
2209  *
2210  *      <em>This function is not available in QD3D.</em>
2211  *
2212  *  @param inPoints2D       Array of 2D points to transform.
2213  *  @param matrix3x3        Transformation matrix.
2214  *  @param outPoints2D      Array of points to receive output (may be the same as inPoints2D).
2215  *  @param numPoints        How many points are in each array.
2216  *  @param inStructSize     Size of one element of the input array, typically sizeof(TQ3Point2D).
2217  *  @param outStructSize    Size of one element of the output array, typically sizeof(TQ3Point2D).
2218  *  @result                 kQ3Success or some error code.
2219  */
2220 #if QUESA_ALLOW_QD3D_EXTENSIONS
2221 
2222 Q3_EXTERN_API_C ( TQ3Status  )
2223 Q3Point2D_To2DTransformArray (
2224     const TQ3Point2D              *inPoints2D,
2225     const TQ3Matrix3x3            *matrix3x3,
2226     TQ3Point2D                    *outPoints2D,
2227     TQ3Uns32                      numPoints,
2228     TQ3Uns32                      inStructSize,
2229     TQ3Uns32                      outStructSize
2230 );
2231 
2232 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
2233 
2234 
2235 
2236 /*!
2237  *  @function
2238  *      Q3Point2D_To3DTransformArray
2239  *  @discussion
2240  *      Transform an array of 2D points by a 3x3 matrix into 3D rational points.
2241  *
2242  *		When you have many vectors to transform, this is a more efficient
2243  *		alternative to calling Q3Point2D_To3D and Q3RationalPoint3D_Transform repeatedly.
2244  *
2245  *      <em>This function is not available in QD3D.</em>
2246  *
2247  *  @param inPoints2D       Array of 2D points to transform.
2248  *  @param matrix3x3        Transformation matrix.
2249  *  @param outRationalPoints3D Array of points to receive output.
2250  *  @param numPoints        How many points are in each array.
2251  *  @param inStructSize     Size of one element of the input array, typically sizeof(TQ3Point2D).
2252  *  @param outStructSize    Size of one element of the output array, typically sizeof(TQ3RationalPoint3D).
2253  *  @result                 kQ3Success or some error code.
2254  */
2255 #if QUESA_ALLOW_QD3D_EXTENSIONS
2256 
2257 Q3_EXTERN_API_C ( TQ3Status  )
2258 Q3Point2D_To3DTransformArray (
2259     const TQ3Point2D              *inPoints2D,
2260     const TQ3Matrix3x3            *matrix3x3,
2261     TQ3RationalPoint3D            *outRationalPoints3D,
2262     TQ3Uns32                      numPoints,
2263     TQ3Uns32                      inStructSize,
2264     TQ3Uns32                      outStructSize
2265 );
2266 
2267 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
2268 
2269 
2270 
2271 /*!
2272  *  @function
2273  *      Q3RationalPoint3D_To3DTransformArray
2274  *  @discussion
2275  *		Transform an array of 3D rational points by a 3x3 matrix.
2276  *
2277  *		When you have many points to transform, this is a more efficient
2278  *		alternative to calling Q3RationalPoint3D_Transform repeatedly.
2279  *
2280  *      <em>This function is not available in QD3D.</em>
2281  *
2282  *  @param inRationalPoints3D Array of 3D rational points to transform.
2283  *  @param matrix3x3        Transformation matrix.
2284  *  @param outRationalPoints3D Array of points to receive output (may be the same as inRationalPoints3D).
2285  *  @param numPoints        How many points are in each array.
2286  *  @param inStructSize     Size of one element of the input array, typically sizeof(TQ3RationalPoint3D).
2287  *  @param outStructSize    Size of one element of the output array, typically sizeof(TQ3RationalPoint3D).
2288  *  @result                 kQ3Success or some error code.
2289  */
2290 #if QUESA_ALLOW_QD3D_EXTENSIONS
2291 
2292 Q3_EXTERN_API_C ( TQ3Status  )
2293 Q3RationalPoint3D_To3DTransformArray (
2294     const TQ3RationalPoint3D      *inRationalPoints3D,
2295     const TQ3Matrix3x3            *matrix3x3,
2296     TQ3RationalPoint3D            *outRationalPoints3D,
2297     TQ3Uns32                      numPoints,
2298     TQ3Uns32                      inStructSize,
2299     TQ3Uns32                      outStructSize
2300 );
2301 
2302 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
2303 
2304 
2305 
2306 /*!
2307  *  @function
2308  *      Q3Point3D_To3DTransformArray
2309  *  @discussion
2310  *		Transform an array of 3D points by a 4x4 matrix.
2311  *
2312  *		When you have many points to transform, this is a more efficient
2313  *		alternative to calling Q3Point3D_Transform repeatedly.
2314  *
2315  *  @param inPoints3D       Array of 3D points to transform.
2316  *  @param matrix4x4        Transformation matrix.
2317  *  @param outPoints3D      Array of points to receive output (may be the same as inPoints3D).
2318  *  @param numPoints        How many points are in each array.
2319  *  @param inStructSize     Size of one element of the input array, typically sizeof(TQ3Point3D).
2320  *  @param outStructSize    Size of one element of the output array, typically sizeof(TQ3Point3D).
2321  *  @result                 kQ3Success or some error code.
2322  */
2323 Q3_EXTERN_API_C ( TQ3Status  )
2324 Q3Point3D_To3DTransformArray (
2325     const TQ3Point3D              *inPoints3D,
2326     const TQ3Matrix4x4            *matrix4x4,
2327     TQ3Point3D                    *outPoints3D,
2328     TQ3Uns32                      numPoints,
2329     TQ3Uns32                      inStructSize,
2330     TQ3Uns32                      outStructSize
2331 );
2332 
2333 
2334 
2335 /*!
2336  *  @function
2337  *      Q3Point3D_To4DTransformArray
2338  *  @discussion
2339  *      Transform an array of 3D points by a 4x4 matrix into 4D rational points.
2340  *
2341  *		When you have many vectors to transform, this is a more efficient
2342  *		alternative to calling Q3Point3D_To4D and Q3RationalPoint4D_Transform repeatedly.
2343  *
2344  *  @param inPoints3D       Array of 3D points to transform.
2345  *  @param matrix4x4        Transformation matrix.
2346  *  @param outRationalPoints4D Array of points to receive output.
2347  *  @param numPoints        How many points are in each array.
2348  *  @param inStructSize     Size of one element of the input array, typically sizeof(TQ3Point3D).
2349  *  @param outStructSize    Size of one element of the output array, typically sizeof(TQ3RationalPoint4D).
2350  *  @result                 kQ3Success or some error code.
2351  */
2352 Q3_EXTERN_API_C ( TQ3Status  )
2353 Q3Point3D_To4DTransformArray (
2354     const TQ3Point3D              *inPoints3D,
2355     const TQ3Matrix4x4            *matrix4x4,
2356     TQ3RationalPoint4D            *outRationalPoints4D,
2357     TQ3Uns32                      numPoints,
2358     TQ3Uns32                      inStructSize,
2359     TQ3Uns32                      outStructSize
2360 );
2361 
2362 
2363 
2364 /*!
2365  *  @function
2366  *      Q3RationalPoint4D_To4DTransformArray
2367  *  @discussion
2368  *		Transform an array of 4D points by a 4x4 matrix.
2369  *
2370  *		When you have many points to transform, this is a more efficient
2371  *		alternative to calling Q3RationalPoint4D_Transform repeatedly.
2372  *
2373  *  @param inRationalPoints4D Array of 4D points to transform.
2374  *  @param matrix4x4        Transformation matrix.
2375  *  @param outRationalPoints4D Array of points to receive output (may be the same as inRationalPoints4D).
2376  *  @param numPoints        How many points are in each array.
2377  *  @param inStructSize     Size of one element of the input array, typically sizeof(TQ3RationalPoint4D).
2378  *  @param outStructSize    Size of one element of the output array, typically sizeof(TQ3RationalPoint4D).
2379  *  @result                 kQ3Success or some error code.
2380  */
2381 Q3_EXTERN_API_C ( TQ3Status  )
2382 Q3RationalPoint4D_To4DTransformArray (
2383     const TQ3RationalPoint4D      *inRationalPoints4D,
2384     const TQ3Matrix4x4            *matrix4x4,
2385     TQ3RationalPoint4D            *outRationalPoints4D,
2386     TQ3Uns32                      numPoints,
2387     TQ3Uns32                      inStructSize,
2388     TQ3Uns32                      outStructSize
2389 );
2390 
2391 
2392 
2393 
2394 
2395 //=============================================================================
2396 //      Matrix functions
2397 //-----------------------------------------------------------------------------
2398 /*!
2399  *  @function
2400  *      Q3Matrix3x3_SetIdentity
2401  *  @discussion
2402  *      Set a 3x3 matrix to the identity matrix.
2403  *
2404  *  @param matrix3x3        Address of matrix to set.
2405  *  @result                 Convenience copy of matrix3x3 parameter.
2406  */
2407 Q3_EXTERN_API_C ( TQ3Matrix3x3 * )
2408 Q3Matrix3x3_SetIdentity (
2409     TQ3Matrix3x3                  *matrix3x3
2410 );
2411 
2412 
2413 
2414 /*!
2415  *  @function
2416  *      Q3Matrix4x4_SetIdentity
2417  *  @discussion
2418  *      Set a 4x4 matrix to the identity matrix.
2419  *
2420  *  @param matrix4x4        Address of matrix to set.
2421  *  @result                 Convenience copy of matrix4x4 parameter.
2422  */
2423 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2424 Q3Matrix4x4_SetIdentity (
2425     TQ3Matrix4x4                  *matrix4x4
2426 );
2427 
2428 
2429 
2430 /*!
2431  *  @function
2432  *      Q3Matrix3x3_SetTranslate
2433  *  @discussion
2434  *      Set a 3x3 matrix to translate in x, y.
2435  *
2436  *  @param matrix3x3        Address of matrix to set.
2437  *  @param xTrans           Amount to translate in x.
2438  *  @param yTrans           Amount to translate in y.
2439  *  @result                 Convenience copy of matrix3x3 parameter.
2440  */
2441 Q3_EXTERN_API_C ( TQ3Matrix3x3 * )
2442 Q3Matrix3x3_SetTranslate (
2443     TQ3Matrix3x3                  *matrix3x3,
2444     float                         xTrans,
2445     float                         yTrans
2446 );
2447 
2448 
2449 
2450 /*!
2451  *  @function
2452  *      Q3Matrix4x4_SetTranslate
2453  *  @discussion
2454  *      Set a 4x4 matrix to translate in x, y, z.
2455  *
2456  *  @param matrix4x4        Address of matrix to set.
2457  *  @param xTrans           Amount to translate in x.
2458  *  @param yTrans           Amount to translate in y.
2459  *  @param zTrans           Amount to translate in z.
2460  *  @result                 Convenience copy of matrix4x4 parameter.
2461  */
2462 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2463 Q3Matrix4x4_SetTranslate (
2464     TQ3Matrix4x4                  *matrix4x4,
2465     float                         xTrans,
2466     float                         yTrans,
2467     float                         zTrans
2468 );
2469 
2470 
2471 
2472 /*!
2473  *  @function
2474  *      Q3Matrix3x3_SetScale
2475  *  @discussion
2476  *      Set 3x3 matrix to scale in x, y.
2477  *
2478  *  @param matrix3x3        Address of matrix to set.
2479  *  @param xScale           Amount to scale in x.
2480  *  @param yScale           Amount to scale in y.
2481  *  @result                 Convenience copy of matrix3x3 parameter.
2482  */
2483 Q3_EXTERN_API_C ( TQ3Matrix3x3 * )
2484 Q3Matrix3x3_SetScale (
2485     TQ3Matrix3x3                  *matrix3x3,
2486     float                         xScale,
2487     float                         yScale
2488 );
2489 
2490 
2491 
2492 /*!
2493  *  @function
2494  *      Q3Matrix4x4_SetScale
2495  *  @discussion
2496  *      Set a 4x4 matrix to scale in x, y, z.
2497  *
2498  *  @param matrix4x4        Address of matrix to set.
2499  *  @param xScale           Amount to scale in x.
2500  *  @param yScale           Amount to scale in y.
2501  *  @param zScale           Amount to scale in z.
2502  *  @result                 Convenience copy of matrix4x4 parameter.
2503  */
2504 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2505 Q3Matrix4x4_SetScale (
2506     TQ3Matrix4x4                  *matrix4x4,
2507     float                         xScale,
2508     float                         yScale,
2509     float                         zScale
2510 );
2511 
2512 
2513 
2514 /*!
2515  *  @function
2516  *      Q3Matrix3x3_SetRotate
2517  *  @discussion
2518  *		Set a 3x3 matrix to rotate about the origin.
2519  *
2520  *      <em>This function is not available in QD3D.</em>
2521  *
2522  *  @param matrix3x3        Address of matrix to set.
2523  *  @param angle            Angle to rotate (in radians).
2524  *  @result                 Convenience copy of matrix3x3 parameter.
2525  */
2526 #if QUESA_ALLOW_QD3D_EXTENSIONS
2527 
2528 Q3_EXTERN_API_C ( TQ3Matrix3x3 * )
2529 Q3Matrix3x3_SetRotate (
2530     TQ3Matrix3x3                  *matrix3x3,
2531     float                         angle
2532 );
2533 
2534 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
2535 
2536 
2537 
2538 /*!
2539  *  @function
2540  *      Q3Matrix4x4_SetRotate_X
2541  *  @discussion
2542  *      Set a 4x4 matrix to rotate about the X axis.
2543  *
2544  *  @param matrix4x4        Address of matrix to set.
2545  *  @param angle            Angle to rotate (in radians).
2546  *  @result                 Convenience copy of matrix4x4 parameter.
2547  */
2548 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2549 Q3Matrix4x4_SetRotate_X (
2550     TQ3Matrix4x4                  *matrix4x4,
2551     float                         angle
2552 );
2553 
2554 
2555 
2556 /*!
2557  *  @function
2558  *      Q3Matrix4x4_SetRotate_Y
2559  *  @discussion
2560  *      Set a 4x4 matrix to rotate about the Y axis.
2561  *
2562  *  @param matrix4x4        Address of matrix to set.
2563  *  @param angle            Angle to rotate (in radians).
2564  *  @result                 Convenience copy of matrix4x4 parameter.
2565  */
2566 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2567 Q3Matrix4x4_SetRotate_Y (
2568     TQ3Matrix4x4                  *matrix4x4,
2569     float                         angle
2570 );
2571 
2572 
2573 
2574 /*!
2575  *  @function
2576  *      Q3Matrix4x4_SetRotate_Z
2577  *  @discussion
2578  *      Set a 4x4 matrix to rotate about the Z axis.
2579  *
2580  *  @param matrix4x4        Address of matrix to set.
2581  *  @param angle            Angle to rotate (in radians).
2582  *  @result                 Convenience copy of matrix4x4 parameter.
2583  */
2584 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2585 Q3Matrix4x4_SetRotate_Z (
2586     TQ3Matrix4x4                  *matrix4x4,
2587     float                         angle
2588 );
2589 
2590 
2591 
2592 /*!
2593  *  @function
2594  *      Q3Matrix4x4_SetRotate_XYZ
2595  *  @discussion
2596  *      Set a 4x4 matrix to rotate about the X, Y, Z axes (in that order).
2597  *
2598  *		This order of rotations is rarely useful, but it's kept for backwards
2599  *		compatibility with QD3D.
2600  *
2601  *  @param matrix4x4        Address of matrix to set.
2602  *  @param xAngle           Angle to rotate about the X axis (in radians).
2603  *  @param yAngle           Angle to rotate about the Y axis (in radians).
2604  *  @param zAngle           Angle to rotate about the Z axis (in radians).
2605  *  @result                 Convenience copy of matrix4x4 parameter.
2606  */
2607 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2608 Q3Matrix4x4_SetRotate_XYZ (
2609     TQ3Matrix4x4                  *matrix4x4,
2610     float                         xAngle,
2611     float                         yAngle,
2612     float                         zAngle
2613 );
2614 
2615 
2616 
2617 /*!
2618  *  @function
2619  *      Q3Matrix3x3_SetRotateAboutPoint
2620  *  @discussion
2621  *      Set a 3x3 matrix to rotate about a point.
2622  *
2623  *		This is equivalent to translating the point to the origin,
2624  *		doing a rotation about the origin, and translating back.
2625  *
2626  *  @param matrix3x3        Address of matrix to set.
2627  *  @param origin           Address of a 2D point about which to rotate.
2628  *  @param angle            Angle to rotate (in radians).
2629  *  @result                 Convenience copy of matrix3x3 parameter.
2630  */
2631 Q3_EXTERN_API_C ( TQ3Matrix3x3 * )
2632 Q3Matrix3x3_SetRotateAboutPoint (
2633     TQ3Matrix3x3                  *matrix3x3,
2634     const TQ3Point2D              *origin,
2635     float                         angle
2636 );
2637 
2638 
2639 
2640 /*!
2641  *  @function
2642  *      Q3Matrix4x4_SetRotateAboutPoint
2643  *  @discussion
2644  *      Set a 4x4 matrix to rotate about axes through a point and
2645  *		parallel to the X, Y, and Z axes (in that order).
2646  *
2647  *		This order of rotations is rarely useful, but it's kept for backwards
2648  *		compatibility with QD3D.
2649  *
2650  *  @param matrix4x4        Address of matrix to set.
2651  *  @param origin           Address of a 3D point about which to rotate.
2652  *  @param xAngle           Angle to rotate about the translated X axis (in radians).
2653  *  @param yAngle           Angle to rotate about the translated Y axis (in radians).
2654  *  @param zAngle           Angle to rotate about the translated Z axis (in radians).
2655  *  @result                 Convenience copy of matrix4x4 parameter.
2656  */
2657 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2658 Q3Matrix4x4_SetRotateAboutPoint (
2659     TQ3Matrix4x4                  *matrix4x4,
2660     const TQ3Point3D              *origin,
2661     float                         xAngle,
2662     float                         yAngle,
2663     float                         zAngle
2664 );
2665 
2666 
2667 
2668 /*!
2669  *  @function
2670  *      Q3Matrix4x4_SetRotateAboutAxis
2671  *  @discussion
2672  *      Set 4x4 matrix to rotate about an arbitrary origin and axis.
2673  *
2674  *		Note that for correct results, the axis should be normalized
2675  *		(i.e. have length = 1).
2676  *
2677  *  @param matrix4x4        Address of matrix to set.
2678  *  @param origin           Address of a 2D point about which to rotate.
2679  *  @param axis             Address of a 3D vector to use as the rotation axis.
2680  *  @param angle            Angle to rotate (in radians).
2681  *  @result                 Convenience copy of matrix4x4 parameter.
2682  */
2683 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2684 Q3Matrix4x4_SetRotateAboutAxis (
2685     TQ3Matrix4x4                  *matrix4x4,
2686     const TQ3Point3D              *origin,
2687     const TQ3Vector3D             *axis,
2688     float                         angle
2689 );
2690 
2691 
2692 
2693 /*!
2694  *  @function
2695  *      Q3Matrix4x4_SetRotateVectorToVector
2696  *  @discussion
2697  *      Set a 4x4 matrix to rotate vector 'v1' to 'v2'.
2698  *
2699  *		Note that for correct results, both vectors should be normalized
2700  *		(i.e. have length = 1).
2701  *
2702  *  @param matrix4x4        Address of matrix to set.
2703  *  @param v1               Address of "starting" vector.
2704  *  @param v2               Address of "ending" vector.
2705  *  @result                 Convenience copy of matrix4x4 parameter.
2706  */
2707 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2708 Q3Matrix4x4_SetRotateVectorToVector (
2709     TQ3Matrix4x4                  *matrix4x4,
2710     const TQ3Vector3D             *v1,
2711     const TQ3Vector3D             *v2
2712 );
2713 
2714 
2715 
2716 /*!
2717  *  @function
2718  *      Q3Matrix4x4_SetQuaternion
2719  *  @discussion
2720  *      Set a 4x4 matrix from to the rotation represented by a quaternion.
2721  *
2722  *  @param matrix4x4        Address of matrix to set.
2723  *  @param quaternion       Address of the quaternion to imitate.
2724  *  @result                 Convenience copy of matrix4x4 parameter.
2725  */
2726 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2727 Q3Matrix4x4_SetQuaternion (
2728     TQ3Matrix4x4                  *matrix4x4,
2729     const TQ3Quaternion           *quaternion
2730 );
2731 
2732 
2733 
2734 /*!
2735  *  @function
2736  *      Q3Matrix3x3_Copy
2737  *  @discussion
2738  *      Copy a 3x3 matrix.
2739  *
2740  *  @param matrix3x3        Address of source matrix.
2741  *  @param result           Address of destination matrix (may be the same as matrix3x3).
2742  *  @result                 Convenience copy of result parameter.
2743  */
2744 Q3_EXTERN_API_C ( TQ3Matrix3x3 * )
2745 Q3Matrix3x3_Copy (
2746     const TQ3Matrix3x3            *matrix3x3,
2747     TQ3Matrix3x3                  *result
2748 );
2749 
2750 
2751 
2752 /*!
2753  *  @function
2754  *      Q3Matrix4x4_Copy
2755  *  @discussion
2756  *      Copy a 4x4 matrix.
2757  *
2758  *  @param matrix4x4        Address of source matrix.
2759  *  @param result           Address of destination matrix (may be the same as matrix4x4).
2760  *  @result                 Convenience copy of result parameter.
2761  */
2762 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2763 Q3Matrix4x4_Copy (
2764     const TQ3Matrix4x4            *matrix4x4,
2765     TQ3Matrix4x4                  *result
2766 );
2767 
2768 
2769 
2770 /*!
2771  *  @function
2772  *      Q3Matrix3x3_Transpose
2773  *  @discussion
2774  *      Transpose a 3x3 matrix.
2775  *
2776  *  @param matrix3x3        Address of a matrix to transpose.
2777  *  @param result           Address of matrix to set (may be the same as matrix3x3).
2778  *  @result                 Convenience copy of result parameter.
2779  */
2780 Q3_EXTERN_API_C ( TQ3Matrix3x3 * )
2781 Q3Matrix3x3_Transpose (
2782     const TQ3Matrix3x3            *matrix3x3,
2783     TQ3Matrix3x3                  *result
2784 );
2785 
2786 
2787 
2788 /*!
2789  *  @function
2790  *      Q3Matrix4x4_Transpose
2791  *  @discussion
2792  *      Transpose a 4x4 matrix.
2793  *
2794  *  @param matrix4x4        Address of a matrix to transpose.
2795  *  @param result           Address of matrix to set (may be the same as matrix4x4).
2796  *  @result                 Convenience copy of result parameter.
2797  */
2798 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2799 Q3Matrix4x4_Transpose (
2800     const TQ3Matrix4x4            *matrix4x4,
2801     TQ3Matrix4x4                  *result
2802 );
2803 
2804 
2805 
2806 /*!
2807  *  @function
2808  *      Q3Matrix3x3_Determinant
2809  *  @discussion
2810  *      Return the determinant of 3x3 matrix.
2811  *
2812  *  @param matrix3x3        Address of a matrix.
2813  *  @result                 Determinant of that matrix.
2814  */
2815 Q3_EXTERN_API_C ( float  )
2816 Q3Matrix3x3_Determinant (
2817     const TQ3Matrix3x3            *matrix3x3
2818 );
2819 
2820 
2821 
2822 /*!
2823  *  @function
2824  *      Q3Matrix4x4_Determinant
2825  *  @discussion
2826  *      Return the determinant of 4x4 matrix.
2827  *
2828  *  @param matrix4x4        Address of a matrix.
2829  *  @result                 Determinant of that matrix.
2830  */
2831 Q3_EXTERN_API_C ( float  )
2832 Q3Matrix4x4_Determinant (
2833     const TQ3Matrix4x4            *matrix4x4
2834 );
2835 
2836 
2837 
2838 /*!
2839  *  @function
2840  *      Q3Matrix3x3_Adjoint
2841  *  @discussion
2842  *      Calculate adjoint of 3x3 matrix.
2843  *
2844  *		The adjoint of a matrix is a scalar multiple of the inverse of
2845  *		the matrix. For some applications, the adjoint can be used in
2846  *		place of the inverse. In particular:
2847  *
2848  *			adjoint(A) = determinant(A) * inverse(A)
2849  *
2850  *  @param matrix3x3        Address of a matrix to calculate the adjoint of.
2851  *  @param result           Address of matrix to set (may be the same as matrix3x3).
2852  *  @result                 Convenience copy of result parameter.
2853  */
2854 Q3_EXTERN_API_C ( TQ3Matrix3x3 * )
2855 Q3Matrix3x3_Adjoint (
2856     const TQ3Matrix3x3            *matrix3x3,
2857     TQ3Matrix3x3                  *result
2858 );
2859 
2860 
2861 
2862 /*!
2863  *  @function
2864  *      Q3Matrix3x3_Invert
2865  *  @discussion
2866  *      Calculate the inverse of a 3x3 non-singular matrix.
2867  *
2868  *  @param matrix3x3        Address of non-singular matrix to invert.
2869  *  @param result           Address of matrix to set (may be the same as matrix3x3).
2870  *  @result                 Convenience copy of result parameter.
2871  */
2872 Q3_EXTERN_API_C ( TQ3Matrix3x3 * )
2873 Q3Matrix3x3_Invert (
2874     const TQ3Matrix3x3            *matrix3x3,
2875     TQ3Matrix3x3                  *result
2876 );
2877 
2878 
2879 
2880 /*!
2881  *  @function
2882  *      Q3Matrix4x4_Invert
2883  *  @discussion
2884  *      Calculate the inverse of a 4x4 non-singular matrix.
2885  *
2886  *  @param matrix4x4        Address of non-singular matrix to invert.
2887  *  @param result           Address of matrix to set (may be the same as matrix4x4).
2888  *  @result                 Convenience copy of result parameter.
2889  */
2890 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2891 Q3Matrix4x4_Invert (
2892     const TQ3Matrix4x4            *matrix4x4,
2893     TQ3Matrix4x4                  *result
2894 );
2895 
2896 
2897 
2898 /*!
2899  *  @function
2900  *      Q3Matrix3x3_Multiply
2901  *  @discussion
2902  *      Multiply two 3x3 matrices.
2903  *
2904  *  @param m1               Address of first matrix.
2905  *  @param m2               Address of second matrix.
2906  *  @param result           Address of matrix to set with m1*m2 (may be the same as m1 and/or m2).
2907  *  @result                 Convenience copy of result parameter.
2908  */
2909 Q3_EXTERN_API_C ( TQ3Matrix3x3 * )
2910 Q3Matrix3x3_Multiply (
2911     const TQ3Matrix3x3            *m1,
2912     const TQ3Matrix3x3            *m2,
2913     TQ3Matrix3x3                  *result
2914 );
2915 
2916 
2917 
2918 /*!
2919  *  @function
2920  *      Q3Matrix4x4_Multiply
2921  *  @discussion
2922  *      Multiply two 4x4 matrices.
2923  *
2924  *  @param m1               Address of first matrix.
2925  *  @param m2               Address of second matrix.
2926  *  @param result           Address of matrix to set with m1*m2 (may be the same as m1 and/or m2).
2927  *  @result                 Convenience copy of result parameter.
2928  */
2929 Q3_EXTERN_API_C ( TQ3Matrix4x4 * )
2930 Q3Matrix4x4_Multiply (
2931     const TQ3Matrix4x4            *m1,
2932     const TQ3Matrix4x4            *m2,
2933     TQ3Matrix4x4                  *result
2934 );
2935 
2936 
2937 
2938 
2939 
2940 //=============================================================================
2941 //      Quaternion functions
2942 //-----------------------------------------------------------------------------
2943 /*!
2944  *  @function
2945  *      Q3Quaternion_Set
2946  *  @discussion
2947  *      Set a quaternion with its individual w, x, y, and z components.
2948  *
2949  *      Available in inline form as Q3FastQuaternion_Set.
2950  *
2951  *  @param quaternion       Address of a quaternion to set.
2952  *  @param w                Value for w component.
2953  *  @param x                Value for x component.
2954  *  @param y                Value for y component.
2955  *  @param z                Value for z component.
2956  *  @result                 Convenience copy of quaternion parameter.
2957  */
2958 Q3_EXTERN_API_C ( TQ3Quaternion * )
2959 Q3Quaternion_Set (
2960     TQ3Quaternion                 *quaternion,
2961     float                         w,
2962     float                         x,
2963     float                         y,
2964     float                         z
2965 );
2966 
2967 
2968 
2969 /*!
2970  *  @function
2971  *      Q3Quaternion_SetIdentity
2972  *  @discussion
2973  *      Set a quaternion to the identity value (1,0,0,0).
2974  *
2975  *      Available in inline form as Q3FastQuaternion_SetIdentity.
2976  *
2977  *  @param quaternion       Address of a quaternion to set.
2978  *  @result                 Convenience copy of result parameter.
2979  */
2980 Q3_EXTERN_API_C ( TQ3Quaternion * )
2981 Q3Quaternion_SetIdentity (
2982     TQ3Quaternion                 *quaternion
2983 );
2984 
2985 
2986 
2987 /*!
2988  *  @function
2989  *      Q3Quaternion_SetRotate_X
2990  *  @discussion
2991  *      Set a quaternion to rotate about the X axis.
2992  *
2993  *  @param quaternion       Address of a quaternion to set.
2994  *  @param angle            Angle to rotate (in radians).
2995  *  @result                 Convenience copy of result parameter.
2996  */
2997 Q3_EXTERN_API_C ( TQ3Quaternion * )
2998 Q3Quaternion_SetRotate_X (
2999     TQ3Quaternion                 *quaternion,
3000     float                         angle
3001 );
3002 
3003 
3004 
3005 /*!
3006  *  @function
3007  *      Q3Quaternion_SetRotate_Y
3008  *  @discussion
3009  *      Set a quaternion to rotate about the Y axis.
3010  *
3011  *  @param quaternion       Address of a quaternion to set.
3012  *  @param angle            Angle to rotate (in radians).
3013  *  @result                 Convenience copy of quaternion parameter.
3014  */
3015 Q3_EXTERN_API_C ( TQ3Quaternion * )
3016 Q3Quaternion_SetRotate_Y (
3017     TQ3Quaternion                 *quaternion,
3018     float                         angle
3019 );
3020 
3021 
3022 
3023 /*!
3024  *  @function
3025  *      Q3Quaternion_SetRotate_Z
3026  *  @discussion
3027  *      Set a quaternion to rotate about the Z axis.
3028  *
3029  *  @param quaternion       Address of a quaternion to set.
3030  *  @param angle            Angle to rotate (in radians).
3031  *  @result                 Convenience copy of quaternion parameter.
3032  */
3033 Q3_EXTERN_API_C ( TQ3Quaternion * )
3034 Q3Quaternion_SetRotate_Z (
3035     TQ3Quaternion                 *quaternion,
3036     float                         angle
3037 );
3038 
3039 
3040 
3041 /*!
3042  *  @function
3043  *      Q3Quaternion_SetRotate_XYZ
3044  *  @discussion
3045  *      Set a quaternion to rotate about the X, Y, and Z axes (in that order).
3046  *
3047  *		This order of rotations is rarely useful, but it's kept for backwards
3048  *		compatibility with QD3D.
3049  *
3050  *  @param quaternion       Address of a quaternion to set.
3051  *  @param xAngle           Angle to rotate about the X axis (in radians).
3052  *  @param yAngle           Angle to rotate about the Y axis (in radians).
3053  *  @param zAngle           Angle to rotate about the Z axis (in radians).
3054  *  @result                 Convenience copy of quaternion parameter.
3055  */
3056 Q3_EXTERN_API_C ( TQ3Quaternion * )
3057 Q3Quaternion_SetRotate_XYZ (
3058     TQ3Quaternion                 *quaternion,
3059     float                         xAngle,
3060     float                         yAngle,
3061     float                         zAngle
3062 );
3063 
3064 
3065 
3066 /*!
3067  *  @function
3068  *      Q3Quaternion_SetRotateAboutAxis
3069  *  @discussion
3070  *      Set quaternion to rotate about arbitrary axis.
3071  *
3072  *		Note that for correct results, the axis should be normalized
3073  *		(i.e. have length = 1).
3074  *
3075  *  @param quaternion       Address of a quaternion to set.
3076  *  @param axis             Address of a 3D vector to use as the rotation axis.
3077  *  @param angle            Angle to rotate (in radians).
3078  *  @result                 Convenience copy of quaternion parameter.
3079  */
3080 Q3_EXTERN_API_C ( TQ3Quaternion * )
3081 Q3Quaternion_SetRotateAboutAxis (
3082     TQ3Quaternion                 *quaternion,
3083     const TQ3Vector3D             *axis,
3084     float                         angle
3085 );
3086 
3087 
3088 
3089 /*!
3090  *  @function
3091  *      Q3Quaternion_SetRotateVectorToVector
3092  *  @discussion
3093  *      Set a quaternion to rotate vector 'v1' to 'v2'.
3094  *
3095  *		Note that for correct results, both vectors should be normalized
3096  *		(i.e. have length = 1).
3097  *
3098  *  @param quaternion       Address of a quaternion to set.
3099  *  @param v1               Address of "starting" vector.
3100  *  @param v2               Address of "ending" vector.
3101  *  @result                 Convenience copy of quaternion parameter.
3102  */
3103 Q3_EXTERN_API_C ( TQ3Quaternion * )
3104 Q3Quaternion_SetRotateVectorToVector (
3105     TQ3Quaternion                 *quaternion,
3106     const TQ3Vector3D             *v1,
3107     const TQ3Vector3D             *v2
3108 );
3109 
3110 
3111 
3112 /*!
3113  *  @function
3114  *      Q3Quaternion_SetMatrix
3115  *  @discussion
3116  *      Set a quaternion from a 4x4 rotation matrix.
3117  *
3118  *		Note: The QD3D implementation of this function appears to be buggy.
3119  *		This can be demonstrated by starting with an arbitrary
3120  *		quaternion, converting to a matrix, then converting back (with
3121  *		this function).
3122  *
3123  *		QD3D's result is something ridiculous; in Quesa, this function
3124  *		returns the original quaternion (or something equivalent).
3125  *
3126  *  @param quaternion       Address of a quaternion to set.
3127  *  @param matrix4x4        Address of a rotation matrix to imitate.
3128  *  @result                 Convenience copy of quaternion parameter.
3129  */
3130 Q3_EXTERN_API_C ( TQ3Quaternion * )
3131 Q3Quaternion_SetMatrix (
3132     TQ3Quaternion                 *quaternion,
3133     const TQ3Matrix4x4            *matrix4x4
3134 );
3135 
3136 
3137 
3138 /*!
3139  *  @function
3140  *      Q3Quaternion_Copy
3141  *  @discussion
3142  *      Copy a quaternion.
3143  *
3144  *      Available in inline form as Q3FastQuaternion_Copy.
3145  *
3146  *  @param quaternion       Address of source quaternion.
3147  *  @param result           Address of destination quaternion (may be the same as the first parameter).
3148  *  @result                 Convenience copy of result parameter.
3149  */
3150 Q3_EXTERN_API_C ( TQ3Quaternion * )
3151 Q3Quaternion_Copy (
3152     const TQ3Quaternion           *quaternion,
3153     TQ3Quaternion                 *result
3154 );
3155 
3156 
3157 
3158 /*!
3159  *  @function
3160  *      Q3Quaternion_IsIdentity
3161  *  @discussion
3162  *      Return whether a quaternion is (roughly) the identity,
3163  *		i.e., (1,0,0,0).
3164  *
3165  *		Values for x, y, and z are considered close enough to 0
3166  *		if they are within FLT_EPSILON (a small number).
3167  *
3168  *		For correct results, the quaternion should first be normalized.
3169  *
3170  *  @param quaternion       Address of quaternion to test.
3171  *  @result                 True if quaternion is the identity.
3172  */
3173 Q3_EXTERN_API_C ( TQ3Boolean  )
3174 Q3Quaternion_IsIdentity (
3175     const TQ3Quaternion           *quaternion
3176 );
3177 
3178 
3179 
3180 /*!
3181  *  @function
3182  *      Q3Quaternion_Dot
3183  *  @discussion
3184  *      Return the dot product of q1 and q2.
3185  *
3186  *      Available in inline form as Q3FastQuaternion_Dot.
3187  *
3188  *  @param q1               Address of one quaternion.
3189  *  @param q2               Address of another quaternion (may be the same as q1).
3190  *  @result                 Dot product of q1 and q2.
3191  */
3192 Q3_EXTERN_API_C ( float  )
3193 Q3Quaternion_Dot (
3194     const TQ3Quaternion           *q1,
3195     const TQ3Quaternion           *q2
3196 );
3197 
3198 
3199 
3200 /*!
3201  *  @function
3202  *      Q3Quaternion_Normalize
3203  *  @discussion
3204  *      Scale a quaternion to length 1.
3205  *
3206  *		This is often needed when combining or interpolating between
3207  *		quaternions, to keep accumulated error from causing your
3208  *		quaternion values to "blow up".
3209  *
3210  *      Available in inline form as Q3FastQuaternion_Normalize.
3211  *
3212  *  @param quaternion       Address of a quaternion to normalize.
3213  *  @param result           Address of quaternion to set (may be the same as the first parameter).
3214  *  @result                 Convenience copy of result parameter.
3215  */
3216 Q3_EXTERN_API_C ( TQ3Quaternion * )
3217 Q3Quaternion_Normalize (
3218     const TQ3Quaternion           *quaternion,
3219     TQ3Quaternion                 *result
3220 );
3221 
3222 
3223 
3224 /*!
3225  *  @function
3226  *      Q3Quaternion_Invert
3227  *  @discussion
3228  *      Invert a quaternion.
3229  *
3230  *		For correct results, the quaternion should be normalized
3231  *		before inverting.
3232  *
3233  *      Available in inline form as Q3FastQuaternion_Invert.
3234  *
3235  *  @param quaternion       Address of a quaternion to invert.
3236  *  @param result           Address of quaternion to set (may be the same as the first parameter).
3237  *  @result                 Convenience copy of result parameter.
3238  */
3239 Q3_EXTERN_API_C ( TQ3Quaternion * )
3240 Q3Quaternion_Invert (
3241     const TQ3Quaternion           *quaternion,
3242     TQ3Quaternion                 *result
3243 );
3244 
3245 
3246 
3247 /*!
3248  *  @function
3249  *      Q3Quaternion_Multiply
3250  *  @discussion
3251  *      Compute the product of two quaternions.
3252  *
3253  *		This is a very useful operation, since the rotation represented
3254  *		by q1*q2 is exactly the same as rotating by q1 and then by q2.
3255  *
3256  *  @param q1               Address of first quaternion.
3257  *  @param q2               Address of second quaternion.
3258  *  @param result           Address of quaternion to set (may be the same as q1 and/or q2).
3259  *  @result                 Convenience copy of result parameter.
3260  */
3261 Q3_EXTERN_API_C ( TQ3Quaternion * )
3262 Q3Quaternion_Multiply (
3263     const TQ3Quaternion           *q1,
3264     const TQ3Quaternion           *q2,
3265     TQ3Quaternion                 *result
3266 );
3267 
3268 
3269 
3270 /*!
3271  *  @function
3272  *      Q3Quaternion_MatchReflection
3273  *  @discussion
3274  *      Set result to either q1 or -q1, whichever produces a positive dot
3275  *		product with q2 (i.e., whichever is "closer" to q2 in orientation).
3276  *
3277  *  @param q1               Address of source quaternion.
3278  *  @param q2               Address of quaternion to match.
3279  *  @param result           Address of quaternion to set (may be the same as q1 and/or q2).
3280  *  @result                 Convenience copy of result parameter.
3281  */
3282 Q3_EXTERN_API_C ( TQ3Quaternion * )
3283 Q3Quaternion_MatchReflection (
3284     const TQ3Quaternion           *q1,
3285     const TQ3Quaternion           *q2,
3286     TQ3Quaternion                 *result
3287 );
3288 
3289 
3290 
3291 /*!
3292  *  @function
3293  *      Q3Quaternion_InterpolateFast
3294  *  @discussion
3295  *      Compute a straight linear interpolation between two quaternions.
3296  *
3297  *		This does a true linear, not spherical, interpolation between
3298  *		q1 and q2.  It's fast, but not very proper for most uses.
3299  *
3300  *		The result is automatically normalized, so there is no need to
3301  *		do so yourself.
3302  *
3303  *  @param q1               Address of first quaternion.
3304  *  @param q2               Address of second quaternion.
3305  *  @param t                Fraction (0-1) of the way from q1 to q2.
3306  *  @param result           Address of quaternion to set (may be the same as q1 and/or q2).
3307  *  @result                 Convenience copy of result parameter.
3308  */
3309 Q3_EXTERN_API_C ( TQ3Quaternion * )
3310 Q3Quaternion_InterpolateFast (
3311     const TQ3Quaternion           *q1,
3312     const TQ3Quaternion           *q2,
3313     float                         t,
3314     TQ3Quaternion                 *result
3315 );
3316 
3317 
3318 
3319 /*!
3320  *  @function
3321  *      Q3Quaternion_InterpolateLinear
3322  *  @discussion
3323  *      Compute a spherical linear interpolation between two quaternions.
3324  *
3325  *		Despite the name, this function does a SLERP (spherical linear
3326  *		interpolation) from q1 to q2.
3327  *		It falls back on a straight linear interpolation only when the
3328  *		cosine of the angle between them is less than 0.01.
3329  *
3330  *		The cut-off point was chosen arbitrarily, and may not match
3331  *		that of QD3D.
3332  *
3333  *  @param q1               Address of first quaternion.
3334  *  @param q2               Address of second quaternion.
3335  *  @param t                Fraction (0-1) of the way from q1 to q2.
3336  *  @param result           Address of quaternion to set (may be the same as q1 and/or q2).
3337  *  @result                 Convenience copy of result parameter.
3338  */
3339 Q3_EXTERN_API_C ( TQ3Quaternion * )
3340 Q3Quaternion_InterpolateLinear (
3341     const TQ3Quaternion           *q1,
3342     const TQ3Quaternion           *q2,
3343     float                         t,
3344     TQ3Quaternion                 *result
3345 );
3346 
3347 
3348 
3349 /*!
3350  *  @function
3351  *      Q3Quaternion_GetAxisAndAngle
3352  *  @discussion
3353  *      Get the rotation axis and/or angle represented by a quaternion.
3354  *
3355  *      Note that for correct results, the quaternion should be normalized.
3356  *
3357  *		If the quaternion represents a null rotation, then outAngle will be
3358  *		set to 0.0 and outAxis will be set to <0, 1, 0> (since in this case
3359  *		the rotation axis is undefined, but we want to always give you a
3360  *		valid axis).
3361  *
3362  *		The returned angle in radians will be in the range [0, 2*pi].
3363  *
3364  *		Either outAxis or outAngle may be null if you are not interested in
3365  *		that result.  (You could even pass null for both, but that would be
3366  *		rather pointless.)
3367  *
3368  *      <em>This function is not available in QD3D.</em>
3369  *
3370  *  @param quaternion       Address of a quaternion to inspect.
3371  *  @param outAxis          Address of a vector to set to the rotation axis (may be null).
3372  *  @param outAngle         Address of a float to set to the rotation angle (may be null).
3373  *  @result                 Convenience copy of outAxis parameter.
3374  */
3375 #if QUESA_ALLOW_QD3D_EXTENSIONS
3376 
3377 Q3_EXTERN_API_C ( TQ3Vector3D * )
3378 Q3Quaternion_GetAxisAndAngle (
3379 	const TQ3Quaternion           *quaternion,
3380 	TQ3Vector3D                   *outAxis,
3381 	float                         *outAngle
3382 );
3383 
3384 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
3385 
3386 
3387 
3388 /*!
3389  *  @function
3390  *      Q3Vector3D_TransformQuaternion
3391  *  @discussion
3392  *      Transform a 3D vector by a quaternion.
3393  *
3394  *      Note that for correct results, the quaternion should be normalized.
3395  *
3396  *  @param vector3D         Address of a vector to transform.
3397  *  @param quaternion       Address of a quaternion to transform by.
3398  *  @param result           Address of a vector to set (may be the same as vector3D).
3399  *  @result                 Convenience copy of result parameter.
3400  */
3401 Q3_EXTERN_API_C ( TQ3Vector3D * )
3402 Q3Vector3D_TransformQuaternion (
3403     const TQ3Vector3D             *vector3D,
3404     const TQ3Quaternion           *quaternion,
3405     TQ3Vector3D                   *result
3406 );
3407 
3408 
3409 
3410 /*!
3411  *  @function
3412  *      Q3Point3D_TransformQuaternion
3413  *  @discussion
3414  *      Transform a 3D point by a quaternion.
3415  *
3416  *      Note that for correct results, the quaternion should be normalized.
3417  *
3418  *  @param point3D          Address of a point to transform.
3419  *  @param quaternion       Address of a quaternion to transform by.
3420  *  @param result           Address of a point to set (may be the same as point3D).
3421  *  @result                 Convenience copy of result parameter.
3422  */
3423 Q3_EXTERN_API_C ( TQ3Point3D * )
3424 Q3Point3D_TransformQuaternion (
3425     const TQ3Point3D              *point3D,
3426     const TQ3Quaternion           *quaternion,
3427     TQ3Point3D                    *result
3428 );
3429 
3430 
3431 
3432 
3433 
3434 //=============================================================================
3435 //      Bounding box functions
3436 //-----------------------------------------------------------------------------
3437 /*!
3438  *  @function
3439  *      Q3BoundingBox_Reset
3440  *  @discussion
3441  *      Reset (set to empty) a bounding box.
3442  *
3443  *      Available in inline form as Q3FastBoundingBox_Reset.
3444  *
3445  *      <em>This function is not available in QD3D.</em>
3446  *
3447  *  @param bBox             Address of bounding box to reset.
3448  *  @result                 Convenience copy of bBox parameter.
3449  */
3450 #if QUESA_ALLOW_QD3D_EXTENSIONS
3451 
3452 Q3_EXTERN_API_C ( TQ3BoundingBox * )
3453 Q3BoundingBox_Reset (
3454     TQ3BoundingBox                *bBox
3455 );
3456 
3457 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
3458 
3459 
3460 
3461 /*!
3462  *  @function
3463  *      Q3BoundingBox_Set
3464  *  @discussion
3465  *      Set a bounding box.
3466  *
3467  *      Available in inline form as Q3FastBoundingBox_Set.
3468  *
3469  *  @param bBox             Address of bounding box to set.
3470  *  @param min              Address of point indicating minimum X, Y, and Z.
3471  *  @param max              Address of point indicating maximum X, Y, and Z.
3472  *  @param isEmpty          True if the bounding box is empty, false otherwise.
3473  *  @result                 Convenience copy of bBox parameter.
3474  */
3475 Q3_EXTERN_API_C ( TQ3BoundingBox * )
3476 Q3BoundingBox_Set (
3477     TQ3BoundingBox                *bBox,
3478     const TQ3Point3D              *min,
3479     const TQ3Point3D              *max,
3480     TQ3Boolean                    isEmpty
3481 );
3482 
3483 
3484 
3485 /*!
3486  *  @function
3487  *      Q3BoundingBox_SetFromPoints3D
3488  *  @discussion
3489  *      Set a bounding box to just enclose a set of 3D points.
3490  *
3491  *  @param bBox             Address of bounding box to set.
3492  *  @param points3D         Array of 3D points.
3493  *  @param numPoints        How many points are in the array.
3494  *  @param structSize       Size of each array element, typically sizeof(TQ3Point3D).
3495  *  @result                 Convenience copy of bBox parameter.
3496  */
3497 Q3_EXTERN_API_C ( TQ3BoundingBox * )
3498 Q3BoundingBox_SetFromPoints3D (
3499     TQ3BoundingBox                *bBox,
3500     const TQ3Point3D              *points3D,
3501     TQ3Uns32                      numPoints,
3502     TQ3Uns32                      structSize
3503 );
3504 
3505 
3506 
3507 /*!
3508  *  @function
3509  *      Q3BoundingBox_SetFromRationalPoints4D
3510  *  @discussion
3511  *      Set a bounding box to just enclose a set of 4D rational points.
3512  *
3513  *  @param bBox             Address of bounding box to set.
3514  *  @param rationalPoints4D Array of 4D rational points.
3515  *  @param numPoints        How many points are in the array.
3516  *  @param structSize       Size of each array element, typically sizeof(TQ3RationalPoint4D).
3517  *  @result                 Convenience copy of bBox parameter.
3518  */
3519 Q3_EXTERN_API_C ( TQ3BoundingBox * )
3520 Q3BoundingBox_SetFromRationalPoints4D (
3521     TQ3BoundingBox                *bBox,
3522     const TQ3RationalPoint4D      *rationalPoints4D,
3523     TQ3Uns32                      numPoints,
3524     TQ3Uns32                      structSize
3525 );
3526 
3527 
3528 
3529 /*!
3530  *  @function
3531  *      Q3BoundingBox_Copy
3532  *  @discussion
3533  *      Copy a bounding box.
3534  *
3535  *      Available in inline form as Q3BFastoundingBox_Copy.
3536  *
3537  *  @param bBox             Address of source bounding box.
3538  *  @param result           Address of bounding box to set (may be the same as bBox).
3539  *  @result                 Convenience copy of result parameter.
3540  */
3541 Q3_EXTERN_API_C ( TQ3BoundingBox * )
3542 Q3BoundingBox_Copy (
3543     const TQ3BoundingBox          *bBox,
3544     TQ3BoundingBox                *result
3545 );
3546 
3547 
3548 
3549 /*!
3550  *  @function
3551  *      Q3BoundingBox_Union
3552  *  @discussion
3553  *      Compute the minimum bounding box that encloses both 'b1' and 'b2'.
3554  *
3555  *  @param b1               Address of one bounding box.
3556  *  @param b2               Address of another bounding box.
3557  *  @param result           Address of bounding box to set (may be the same as b1 and/or b2).
3558  *  @result                 Convenience copy of result parameter.
3559  */
3560 Q3_EXTERN_API_C ( TQ3BoundingBox * )
3561 Q3BoundingBox_Union (
3562     const TQ3BoundingBox          *b1,
3563     const TQ3BoundingBox          *b2,
3564     TQ3BoundingBox                *result
3565 );
3566 
3567 
3568 
3569 /*!
3570  *  @function
3571  *      Q3BoundingBox_UnionPoint3D
3572  *  @discussion
3573  *      Return the minimum bounding box that encloses both 'bBox' and 'point3D'.
3574  *
3575  *  @param bBox             Address of initial bounding box.
3576  *  @param point3D          Address of a point to enclose.
3577  *  @param result           Address of bounding box to set (may be the same as bBox).
3578  *  @result                 Convenience copy of result parameter.
3579  */
3580 Q3_EXTERN_API_C ( TQ3BoundingBox * )
3581 Q3BoundingBox_UnionPoint3D (
3582     const TQ3BoundingBox          *bBox,
3583     const TQ3Point3D              *point3D,
3584     TQ3BoundingBox                *result
3585 );
3586 
3587 
3588 
3589 /*!
3590  *  @function
3591  *      Q3BoundingBox_UnionRationalPoint4D
3592  *  @discussion
3593  *      Return the minimum bounding box that encloses both 'bBox' and 'rationalPoint4D'.
3594  *
3595  *  @param bBox             Address of initial bounding box.
3596  *  @param rationalPoint4D  Address of a point to enclose.
3597  *  @param result           Address of bounding box to set (may be the same as bBox).
3598  *  @result                 Convenience copy of result parameter.
3599  */
3600 Q3_EXTERN_API_C ( TQ3BoundingBox * )
3601 Q3BoundingBox_UnionRationalPoint4D (
3602     const TQ3BoundingBox          *bBox,
3603     const TQ3RationalPoint4D      *rationalPoint4D,
3604     TQ3BoundingBox                *result
3605 );
3606 
3607 
3608 
3609 
3610 
3611 //=============================================================================
3612 //      Bounding sphere functions
3613 //-----------------------------------------------------------------------------
3614 /*!
3615  *  @function
3616  *      Q3BoundingSphere_Reset
3617  *  @discussion
3618  *      Reset (set to empty) a bounding sphere.
3619  *
3620  *      Available in inline form as Q3FastBoundingSphere_Reset.
3621  *
3622  *      <em>This function is not available in QD3D.</em>
3623  *
3624  *  @param bSphere          Address of bounding sphere to reset.
3625  *  @result                 Convenience copy of bSphere parameter.
3626  */
3627 #if QUESA_ALLOW_QD3D_EXTENSIONS
3628 
3629 Q3_EXTERN_API_C ( TQ3BoundingSphere * )
3630 Q3BoundingSphere_Reset (
3631     TQ3BoundingSphere             *bSphere
3632 );
3633 
3634 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
3635 
3636 
3637 
3638 /*!
3639  *  @function
3640  *      Q3BoundingSphere_Set
3641  *  @discussion
3642  *      Set a bounding sphere.
3643  *
3644  *      Available in inline form as Q3FastBoundingSphere_Set.
3645  *
3646  *  @param bSphere          Address of bounding sphere to set.
3647  *  @param origin           Address of point indicating sphere origin.
3648  *  @param radius           Sphere radius.
3649  *  @param isEmpty          True if the bounding sphere is empty, false otherwise.
3650  *  @result                 Convenience copy of bSphere parameter.
3651  */
3652 Q3_EXTERN_API_C ( TQ3BoundingSphere * )
3653 Q3BoundingSphere_Set (
3654     TQ3BoundingSphere             *bSphere,
3655     const TQ3Point3D              *origin,
3656     float                         radius,
3657     TQ3Boolean                    isEmpty
3658 );
3659 
3660 
3661 
3662 /*!
3663  *  @function
3664  *      Q3BoundingSphere_SetFromPoints3D
3665  *  @discussion
3666  *      Set a bounding sphere to just enclose a set of 3D points.
3667  *
3668  *  @param bSphere          The bounding sphere to update.
3669  *  @param points3D         Array of 3D points.
3670  *  @param numPoints        How many points are in the array.
3671  *  @param structSize       Size of each array element, typically sizeof(TQ3Point3D).
3672  *  @result                 Convenience copy of bSphere parameter.
3673  */
3674 Q3_EXTERN_API_C ( TQ3BoundingSphere * )
3675 Q3BoundingSphere_SetFromPoints3D (
3676     TQ3BoundingSphere             *bSphere,
3677     const TQ3Point3D              *points3D,
3678     TQ3Uns32                      numPoints,
3679     TQ3Uns32                      structSize
3680 );
3681 
3682 
3683 
3684 /*!
3685  *  @function
3686  *      Q3BoundingSphere_SetFromRationalPoints4D
3687  *  @discussion
3688  *      Set a bounding sphere to just enclose a set of 4D rational points.
3689  *
3690  *  @param bSphere          Address of bounding sphere to set.
3691  *  @param rationalPoints4D Array of 4D rational points.
3692  *  @param numPoints        How many points are in the array.
3693  *  @param structSize       Size of each array element, typically sizeof(TQ3RationalPoint4D).
3694  *  @result                 Convenience copy of bSphere parameter.
3695  */
3696 Q3_EXTERN_API_C ( TQ3BoundingSphere * )
3697 Q3BoundingSphere_SetFromRationalPoints4D (
3698     TQ3BoundingSphere             *bSphere,
3699     const TQ3RationalPoint4D      *rationalPoints4D,
3700     TQ3Uns32                      numPoints,
3701     TQ3Uns32                      structSize
3702 );
3703 
3704 
3705 
3706 /*!
3707  *  @function
3708  *      Q3BoundingSphere_Copy
3709  *  @discussion
3710  *      Copy a bounding sphere.
3711  *
3712  *      Available in inline form as Q3FastBoundingSphere_Copy.
3713  *
3714  *  @param bSphere          Address of source bounding sphere.
3715  *  @param result           Address of bounding sphere to set (may be the same as bSphere).
3716  *  @result                 Convenience copy of result parameter.
3717  */
3718 Q3_EXTERN_API_C ( TQ3BoundingSphere * )
3719 Q3BoundingSphere_Copy (
3720     const TQ3BoundingSphere       *bSphere,
3721     TQ3BoundingSphere             *result
3722 );
3723 
3724 
3725 
3726 /*!
3727  *  @function
3728  *      Q3BoundingSphere_Union
3729  *  @discussion
3730  *      Compute the minimum bounding sphere that encloses both 's1' and 's2'.
3731  *
3732  *  @param s1               Address of one bounding sphere.
3733  *  @param s2               Address of another bounding sphere.
3734  *  @param result           Address of bounding sphere to set (may be the same as s1 and/or s2).
3735  *  @result                 Convenience copy of result parameter.
3736  */
3737 Q3_EXTERN_API_C ( TQ3BoundingSphere * )
3738 Q3BoundingSphere_Union (
3739     const TQ3BoundingSphere       *s1,
3740     const TQ3BoundingSphere       *s2,
3741     TQ3BoundingSphere             *result
3742 );
3743 
3744 
3745 
3746 /*!
3747  *  @function
3748  *      Q3BoundingSphere_UnionPoint3D
3749  *  @discussion
3750  *      Return the minimum bounding sphere that encloses both 'bSphere' and 'point3D'.
3751  *
3752  *  @param bSphere          Address of initial bounding sphere.
3753  *  @param point3D          Address of a point to enclose.
3754  *  @param result           Address of bounding sphere to set (may be the same as bSphere).
3755  *  @result                 Convenience copy of result parameter.
3756  */
3757 Q3_EXTERN_API_C ( TQ3BoundingSphere * )
3758 Q3BoundingSphere_UnionPoint3D (
3759     const TQ3BoundingSphere       *bSphere,
3760     const TQ3Point3D              *point3D,
3761     TQ3BoundingSphere             *result
3762 );
3763 
3764 
3765 
3766 /*!
3767  *  @function
3768  *      Q3BoundingSphere_UnionRationalPoint4D
3769  *  @discussion
3770  *      Return the minimum bounding sphere that encloses both 'bSphere' and 'rationalPoint4D'.
3771  *
3772  *  @param bSphere          Address of initial bounding sphere.
3773  *  @param rationalPoint4D  Address of a point to enclose.
3774  *  @param result           Address of bounding sphere to set (may be the same as bSphere).
3775  *  @result                 Convenience copy of result parameter.
3776  */
3777 Q3_EXTERN_API_C ( TQ3BoundingSphere * )
3778 Q3BoundingSphere_UnionRationalPoint4D (
3779     const TQ3BoundingSphere       *bSphere,
3780     const TQ3RationalPoint4D      *rationalPoint4D,
3781     TQ3BoundingSphere             *result
3782 );
3783 
3784 
3785 
3786 
3787 
3788 //=============================================================================
3789 //      Intersection functions
3790 //-----------------------------------------------------------------------------
3791 /*!
3792  *  @function
3793  *      Q3Ray3D_IntersectSphere
3794  *  @discussion
3795  *      Test a ray for intersection against a sphere, and return the point
3796  *		of intersection if found.
3797  *
3798  *      The direction vector of the ray must be normalised.
3799  *
3800  *      <em>This function is not available in QD3D.</em>
3801  *
3802  *  @param theRay           The ray to test.
3803  *  @param theSphere        The sphere to test against.
3804  *  @param hitPoint         Receives the intersection point, if found.
3805  *  @result                 Indicates if the ray intersects the sphere.
3806  */
3807 #if QUESA_ALLOW_QD3D_EXTENSIONS
3808 
3809 Q3_EXTERN_API_C ( TQ3Boolean  )
3810 Q3Ray3D_IntersectSphere (
3811     const TQ3Ray3D                *theRay,
3812     const TQ3Sphere               *theSphere,
3813     TQ3Point3D                    *hitPoint
3814 );
3815 
3816 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
3817 
3818 
3819 
3820 /*!
3821  *  @function
3822  *      Q3Ray3D_IntersectBoundingBox
3823  *  @discussion
3824  *      Test a ray for intersection against a bounding box. If an
3825  *      intersection occurs, the point of intersection is returned.
3826  *
3827  *      The direction vector of the ray must be normalised.
3828  *
3829  *      <em>This function is not available in QD3D.</em>
3830  *
3831  *  @param theRay           The ray to test.
3832  *  @param theBounds        The bounding box to test against.
3833  *  @param hitPoint         Receives the intersection point, if found.
3834  *  @result                 Indicates if the ray intersects the bounding box.
3835  */
3836 #if QUESA_ALLOW_QD3D_EXTENSIONS
3837 
3838 Q3_EXTERN_API_C ( TQ3Boolean  )
3839 Q3Ray3D_IntersectBoundingBox (
3840     const TQ3Ray3D                *theRay,
3841     const TQ3BoundingBox          *theBounds,
3842     TQ3Point3D                    *hitPoint
3843 );
3844 
3845 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
3846 
3847 
3848 
3849 /*!
3850  *  @function
3851  *      Q3Ray3D_IntersectTriangle
3852  *  @discussion
3853  *      Test a ray for intersection against a triangle formed by three
3854  *      points. If an intersection occurs, returns the barycentric
3855  *      coordinates of the point of intersection and the distance along
3856  *      the ray.
3857  *
3858  *      Triangles may optionally be subject to backface culling, in
3859  *      which case a hit on the reverse side of the triangle will fail
3860  *      to result in an intersection.
3861  *
3862  *      Barycentric coordinates can be used to interpolate the triangle
3863  *      vertices to obtain the exact point of intersection, like so:
3864  *
3865  *        t = (1.0f - hitPoint.u - hitPoint.v);
3866  *        x = (point1.x * t) + (point2.x * hitPoint.u) + (point3.x * hitPoint.v);
3867  *        y = (point1.y * t) + (point2.y * hitPoint.u) + (point3.y * hitPoint.v);
3868  *        z = (point1.z * t) + (point2.z * hitPoint.u) + (point3.z * hitPoint.v);
3869  *
3870  *      Similar calculations can be made for vertex normals, UVs, or any
3871  *      other vertex attribute. The w component of hitPoint is set to the
3872  *      distance along the ray at which the intersection occurs.
3873  *
3874  *      <em>This function is not available in QD3D.</em>
3875  *
3876  *  @param theRay           The ray to test.
3877  *  @param point1           The first triangle vertex.
3878  *  @param point2           The second triangle vertex.
3879  *  @param point3           The third triangle vertex.
3880  *  @param cullBackfacing   Controls if back-facing triangles should be skipped.
3881  *  @param hitPoint         Receives the barycentric coordinates of the intersection, and the distance along the ray.
3882  *  @result                 Indicates if the ray intersects the triangle.
3883  */
3884 #if QUESA_ALLOW_QD3D_EXTENSIONS
3885 
3886 Q3_EXTERN_API_C ( TQ3Boolean  )
3887 Q3Ray3D_IntersectTriangle (
3888     const TQ3Ray3D                *theRay,
3889     const TQ3Point3D              *point1,
3890     const TQ3Point3D              *point2,
3891     const TQ3Point3D              *point3,
3892     TQ3Boolean                    cullBackfacing,
3893     TQ3Param3D                    *hitPoint
3894 );
3895 
3896 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
3897 
3898 
3899 
3900 
3901 
3902 //=============================================================================
3903 //      General math functions
3904 //-----------------------------------------------------------------------------
3905 /*!
3906  *  @function
3907  *      Q3Math_SquareRoot
3908  *  @discussion
3909  *      Obtain a fast, but possibly inaccurate, square root.
3910  *
3911  *      The available precision depends on the current architecture, but will
3912  *      suffice for most non-accumulating 3D operations. If a reliable degree
3913  *      of precision is required, sqrt() should be used instead.
3914  *
3915  *      <em>This function is not available in QD3D.</em>
3916  *
3917  *  @param x                The number whose square root should be returned.
3918  *  @result                 Approximate square root of x.
3919  */
3920 #if QUESA_ALLOW_QD3D_EXTENSIONS
3921 
3922 Q3_EXTERN_API_C ( float  )
3923 Q3Math_SquareRoot (
3924     float                         x
3925 );
3926 
3927 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
3928 
3929 
3930 
3931 /*!
3932  *  @function
3933  *      Q3Math_InvSquareRoot
3934  *  @discussion
3935  *      Obtain a fast, but possibly inaccurate, inverse square root.
3936  *
3937  *      The available precision depends on the current architecture, but will
3938  *      suffice for most non-accumulating 3D operations. If a reliable degree
3939  *      of precision is required, 1.0/sqrt() should be used instead.
3940  *
3941  *      <em>This function is not available in QD3D.</em>
3942  *
3943  *  @param x                The number whose inverse square root should be returned.
3944  *  @result                 Approximate inverse square root of x.
3945  */
3946 #if QUESA_ALLOW_QD3D_EXTENSIONS
3947 
3948 Q3_EXTERN_API_C ( float  )
3949 Q3Math_InvSquareRoot (
3950     float                         x
3951 );
3952 
3953 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
3954 
3955 
3956 
3957 
3958 
3959 //=============================================================================
3960 //      Inline APIs
3961 //-----------------------------------------------------------------------------
3962 //		Note : Preserve the order of functions when adding new inline APIs.
3963 //-----------------------------------------------------------------------------
3964 #if QUESA_ALLOW_QD3D_EXTENSIONS
3965 
3966 // Implementation
3967     #if _MSC_VER
3968      // Disable conditional expression is constant warning for VC++
3969        #pragma warning(disable:4127)
3970     #endif
3971 
3972 
3973 #define __Q3FastVector2D_Set(_v, _x, _y)									\
3974 	do																		\
3975 		{																	\
3976 		(_v)->x = (_x);														\
3977 		(_v)->y = (_y);														\
3978 		}																	\
3979 	while (0)
3980 
3981 #define __Q3FastVector3D_Set(_v, _x, _y, _z)								\
3982 	do																		\
3983 		{																	\
3984 		(_v)->x = (_x);														\
3985 		(_v)->y = (_y);														\
3986 		(_v)->z = (_z);														\
3987 		}																	\
3988 	while (0)
3989 
3990 #define __Q3FastPoint2D_Set(_p, _x, _y)										\
3991 	do																		\
3992 		{																	\
3993 		(_p)->x = (_x);														\
3994 		(_p)->y = (_y);														\
3995 		}																	\
3996 	while (0)
3997 
3998 #define __Q3FastParam2D_Set(_p, _u, _v)										\
3999 	do																		\
4000 		{																	\
4001 		(_p)->u = (_u);														\
4002 		(_p)->v = (_v);														\
4003 		}																	\
4004 	while (0)
4005 
4006 #define __Q3FastRationalPoint3D_Set(_p, _x, _y, _w)							\
4007 	do																		\
4008 		{																	\
4009 		(_p)->x = (_x);														\
4010 		(_p)->y = (_y);														\
4011 		(_p)->w = (_w);														\
4012 		}																	\
4013 	while (0)
4014 
4015 #define __Q3FastPoint3D_Set(_p, _x, _y, _z)									\
4016 	do																		\
4017 		{																	\
4018 		(_p)->x = (_x);														\
4019 		(_p)->y = (_y);														\
4020 		(_p)->z = (_z);														\
4021 		}																	\
4022 	while (0)
4023 
4024 #define __Q3FastRationalPoint4D_Set(_p, _x, _y, _z, _w)						\
4025 	do																		\
4026 		{																	\
4027 		(_p)->x = (_x);														\
4028 		(_p)->y = (_y);														\
4029 		(_p)->z = (_z);														\
4030 		(_p)->w = (_w);														\
4031 		}																	\
4032 	while (0)
4033 
4034 #define __Q3FastPolarPoint_Set(_p, _r, _theta)								\
4035 	do																		\
4036 		{																	\
4037 		(_p)->r     = (_r);													\
4038 		(_p)->theta = (_theta);												\
4039 		}																	\
4040 	while (0)
4041 
4042 #define __Q3FastSphericalPoint_Set(_p, _rho, _theta, _phi)					\
4043 	do																		\
4044 		{																	\
4045 		(_p)->rho   = (_rho);												\
4046 		(_p)->theta = (_theta);												\
4047 		(_p)->phi   = (_phi);												\
4048 		}																	\
4049 	while (0)
4050 
4051 #define __Q3FastVector2D_To3D(_v1, _v2)										\
4052 	do																		\
4053 		{																	\
4054 		(_v2)->x = (_v1)->x;												\
4055 		(_v2)->y = (_v1)->y;												\
4056 		(_v2)->z = 1.0f;													\
4057 		}																	\
4058 	while (0)
4059 
4060 
4061 #define __Q3FastVector2D_ToRationalPoint3D(_v, _p)							\
4062 	do																		\
4063 		{																	\
4064 		(_p)->x = (_v)->x;													\
4065 		(_p)->y = (_v)->y;													\
4066 		(_p)->w = 0.0f;														\
4067 		}																	\
4068 	while (0)
4069 
4070 #define __Q3FastVector3D_To2D(_v1, _v2)										\
4071 	do																		\
4072 		{																	\
4073 		float invZ = 1.0f / (_v1)->z;										\
4074 		(_v2)->x = (_v1)->x * invZ;											\
4075 		(_v2)->y = (_v1)->y * invZ;											\
4076 		}																	\
4077 	while (0)
4078 
4079 #define __Q3FastRationalPoint3D_ToVector2D(_p, _v)							\
4080 	do																		\
4081 		{																	\
4082 		(_v)->x = (_p)->x;													\
4083 		(_v)->y = (_p)->y;													\
4084 		}																	\
4085 	while (0)
4086 
4087 #define __Q3FastVector3D_ToRationalPoint4D(_v, _p)							\
4088 	do																		\
4089 		{																	\
4090 		(_p)->x = (_v)->x;													\
4091 		(_p)->y = (_v)->y;													\
4092 		(_p)->z = (_v)->z;													\
4093 		(_p)->w = 0.0f;														\
4094 		}																	\
4095 	while (0)
4096 
4097 #define __Q3FastRationalPoint4D_ToVector3D(_p, _v)							\
4098 	do																		\
4099 		{																	\
4100 		(_v)->x = (_p)->x;													\
4101 		(_v)->y = (_p)->y;													\
4102 		(_v)->z = (_p)->z;													\
4103 		}																	\
4104 	while (0)
4105 
4106 #define __Q3FastPoint2D_To3D(_p1, _p2)										\
4107 	do																		\
4108 		{																	\
4109 		(_p2)->x = (_p1)->x;												\
4110 		(_p2)->y = (_p1)->y;												\
4111 		(_p2)->w = 1.0f;													\
4112 		}																	\
4113 	while (0)
4114 
4115 #define __Q3FastRationalPoint3D_To2D(_p1, _p2)								\
4116 	do																		\
4117 		{																	\
4118 		float invW = 1.0f / (_p1)->w;										\
4119 		(_p2)->x = (_p1)->x * invW;											\
4120 		(_p2)->y = (_p1)->y * invW;											\
4121 		}																	\
4122 	while (0)
4123 
4124 #define __Q3FastPoint3D_To4D(_p1, _p2)										\
4125 	do																		\
4126 		{																	\
4127 		(_p2)->x = (_p1)->x;												\
4128 		(_p2)->y = (_p1)->y;												\
4129 		(_p2)->z = (_p1)->z;												\
4130 		(_p2)->w = 1.0f;													\
4131 		}																	\
4132 	while (0)
4133 
4134 #define __Q3FastRationalPoint4D_To3D(_p1, _p2)								\
4135 	do																		\
4136 		{																	\
4137 		float invW = 1.0f / (_p1)->w;										\
4138 		(_p2)->x = (_p1)->x * invW;											\
4139 		(_p2)->y = (_p1)->y * invW;											\
4140 		(_p2)->z = (_p1)->z * invW;											\
4141 		}																	\
4142 	while (0)
4143 
4144 #define __Q3FastPolarPoint_ToPoint2D(_p1, _p2)								\
4145 	do																		\
4146 		{																	\
4147 		(_p2)->x = (_p1)->r * ((float) cos((_p1)->theta));					\
4148 		(_p2)->y = (_p1)->r * ((float) sin((_p1)->theta));					\
4149 		}																	\
4150 	while (0)
4151 
4152 #define __Q3FastVector2D_Dot(_v1, _v2)										\
4153 	(																		\
4154 		((_v1)->x * (_v2)->x) +												\
4155 		((_v1)->y * (_v2)->y)												\
4156 	)																		\
4157 
4158 #define __Q3FastVector3D_Dot(_v1, _v2)										\
4159 	(																		\
4160 		((_v1)->x * (_v2)->x) +												\
4161 		((_v1)->y * (_v2)->y) +												\
4162 		((_v1)->z * (_v2)->z)												\
4163 	)																		\
4164 
4165 #define __Q3FastVector2D_Cross(_v1, _v2)									\
4166 	(																		\
4167 		((_v1)->x * (_v2)->y) -												\
4168 		((_v1)->y * (_v2)->x)												\
4169 	)																		\
4170 
4171 #define __Q3FastPoint2D_CrossProductTri(_p1, _p2, _p3)						\
4172 	(																		\
4173 		(((_p2)->x - (_p1)->x) * ((_p3)->x - (_p2)->x)) -					\
4174 		(((_p2)->y - (_p1)->y) * ((_p3)->y - (_p2)->y))						\
4175 	)																		\
4176 
4177 #define __Q3FastVector3D_Cross(_v1, _v2, _r)								\
4178 	do																		\
4179 		{																	\
4180 		float rx = ((_v1)->y * (_v2)->z) - ((_v1)->z * (_v2)->y);			\
4181         float ry = ((_v1)->z * (_v2)->x) - ((_v1)->x * (_v2)->z);			\
4182         float rz = ((_v1)->x * (_v2)->y) - ((_v1)->y * (_v2)->x);			\
4183         																	\
4184         (_r)->x = rx;														\
4185         (_r)->y = ry;														\
4186         (_r)->z = rz;														\
4187 		}																	\
4188 	while (0)
4189 
4190 #define __Q3FastPoint3D_CrossProductTri(_p1, _p2, _p3, _r)					\
4191 	do																		\
4192 		{																	\
4193 		float _v1_x = (_p2)->x - (_p1)->x;									\
4194 		float _v1_y = (_p2)->y - (_p1)->y;									\
4195 		float _v1_z = (_p2)->z - (_p1)->z;									\
4196 																			\
4197 		float _v2_x = (_p3)->x - (_p2)->x;									\
4198 		float _v2_y = (_p3)->y - (_p2)->y;									\
4199 		float _v2_z = (_p3)->z - (_p2)->z;									\
4200 																			\
4201 		(_r)->x = (_v1_y * _v2_z) - (_v1_z * _v2_y);						\
4202         (_r)->y = (_v1_z * _v2_x) - (_v1_x * _v2_z);						\
4203         (_r)->z = (_v1_x * _v2_y) - (_v1_y * _v2_x);						\
4204 		}																	\
4205 	while (0)
4206 
4207 #define __Q3FastVector2D_Length(_v)											\
4208 	(																		\
4209 		(float) sqrt(__Q3FastVector2D_LengthSquared(_v))					\
4210 	)																		\
4211 
4212 #define __Q3FastVector2D_LengthSquared(_v)									\
4213 	(																		\
4214 		((_v)->x * (_v)->x) +												\
4215 		((_v)->y * (_v)->y)													\
4216 	)																		\
4217 
4218 #define __Q3FastVector3D_Length(_v)											\
4219 	(																		\
4220 		(float) sqrt(__Q3FastVector3D_LengthSquared(_v))					\
4221 	)																		\
4222 
4223 #define __Q3FastVector3D_LengthSquared(_v)									\
4224 	(																		\
4225 		((_v)->x * (_v)->x) +												\
4226 		((_v)->y * (_v)->y)	+												\
4227 		((_v)->z * (_v)->z)													\
4228 	)																		\
4229 
4230 #define __Q3FastPoint2D_Distance(_p1, _p2)									\
4231 	(																		\
4232 		(float) sqrt(__Q3FastPoint2D_DistanceSquared(_p1, _p2))				\
4233 	)																		\
4234 
4235 #define __Q3FastPoint2D_DistanceSquared(_p1, _p2)							\
4236 	(																		\
4237 		(((_p1)->x - (_p2)->x) * ((_p1)->x - (_p2)->x))	+					\
4238 		(((_p1)->y - (_p2)->y) * ((_p1)->y - (_p2)->y))						\
4239 	)																		\
4240 
4241 #define __Q3FastParam2D_Distance(_p1, _p2)									\
4242 	(																		\
4243 		__Q3FastPoint2D_Distance((const TQ3Point2D*) _p1,					\
4244 							     (const TQ3Point2D*) _p2)					\
4245 	)																		\
4246 
4247 #define __Q3FastParam2D_DistanceSquared(_p1, _p2)							\
4248 	(																		\
4249 		__Q3FastPoint2D_DistanceSquared((const TQ3Point2D*) _p1,			\
4250 									    (const TQ3Point2D*) _p2)			\
4251 	)																		\
4252 
4253 #define __Q3FastRationalPoint3D_Distance(_p1, _p2)							\
4254 	(																		\
4255 		(float) sqrt(__Q3FastRationalPoint3D_DistanceSquared(_p1, _p2))		\
4256 	)																		\
4257 
4258 #define __Q3FastRationalPoint3D_DistanceSquared(_p1, _p2)					\
4259 	(																		\
4260 		(((_p1)->x/(_p1)->w - (_p2)->x/(_p2)->w) * ((_p1)->x/(_p1)->w - (_p2)->x/(_p2)->w))	+	\
4261 		(((_p1)->y/(_p1)->w - (_p2)->y/(_p2)->w) * ((_p1)->y/(_p1)->w - (_p2)->y/(_p2)->w))		\
4262 	)																		\
4263 
4264 #define __Q3FastPoint3D_Distance(_p1, _p2)									\
4265 	(																		\
4266 		(float) sqrt(__Q3FastPoint3D_DistanceSquared(_p1, _p2))				\
4267 	)																		\
4268 
4269 #define __Q3FastPoint3D_DistanceSquared(_p1, _p2)							\
4270 	(																		\
4271 		(((_p1)->x - (_p2)->x) * ((_p1)->x - (_p2)->x))	+					\
4272 		(((_p1)->y - (_p2)->y) * ((_p1)->y - (_p2)->y))	+					\
4273 		(((_p1)->z - (_p2)->z) * ((_p1)->z - (_p2)->z))						\
4274 	)																		\
4275 
4276 #define __Q3FastRationalPoint4D_Distance(_p1, _p2)							\
4277 	(																		\
4278 		(float) sqrt(__Q3FastRationalPoint4D_DistanceSquared(_p1, _p2))		\
4279 	)																		\
4280 
4281 #define __Q3FastRationalPoint4D_DistanceSquared(_p1, _p2)					\
4282 	(																		\
4283 		(((_p1)->x/(_p1)->w - (_p2)->x/(_p2)->w) * ((_p1)->x/(_p1)->w - (_p2)->x/(_p2)->w))	+	\
4284 		(((_p1)->y/(_p1)->w - (_p2)->y/(_p2)->w) * ((_p1)->y/(_p1)->w - (_p2)->y/(_p2)->w))	+	\
4285 		(((_p1)->z/(_p1)->w - (_p2)->z/(_p2)->w) * ((_p1)->z/(_p1)->w - (_p2)->z/(_p2)->w))		\
4286 	)																		\
4287 
4288 #define __Q3FastVector2D_Negate(_v1, _v2)									\
4289 	do																		\
4290 		{																	\
4291 		(_v2)->x = -(_v1)->x;												\
4292 		(_v2)->y = -(_v1)->y;												\
4293 		}																	\
4294 	while (0)
4295 
4296 #define __Q3FastVector3D_Negate(_v1, _v2)									\
4297 	do																		\
4298 		{																	\
4299 		(_v2)->x = -(_v1)->x;												\
4300 		(_v2)->y = -(_v1)->y;												\
4301 		(_v2)->z = -(_v1)->z;												\
4302 		}																	\
4303 	while (0)
4304 
4305 #define __Q3FastVector2D_Scale(_v1, _s, _v2)								\
4306 	do																		\
4307 		{																	\
4308 		(_v2)->x = (_v1)->x * (_s);											\
4309 		(_v2)->y = (_v1)->y * (_s);											\
4310 		}																	\
4311 	while (0)
4312 
4313 #define __Q3FastVector3D_Scale(_v1, _s, _v2)								\
4314 	do																		\
4315 		{																	\
4316 		(_v2)->x = (_v1)->x * (_s);											\
4317 		(_v2)->y = (_v1)->y * (_s);											\
4318 		(_v2)->z = (_v1)->z * (_s);											\
4319 		}																	\
4320 	while (0)
4321 
4322 #define __Q3FastVector2D_Normalize(_v1, _v2)								\
4323 	do																		\
4324 		{																	\
4325 		float invLength = 1.0f / __Q3FastVector2D_Length(_v1);				\
4326 		__Q3FastVector2D_Scale(_v1, invLength, _v2);						\
4327 		}																	\
4328 	while (0)
4329 
4330 #define __Q3FastVector3D_Normalize(_v1, _v2)								\
4331 	do																		\
4332 		{																	\
4333 		float invLength = 1.0f / __Q3FastVector3D_Length(_v1);				\
4334 		__Q3FastVector3D_Scale(_v1, invLength, _v2);						\
4335 		}																	\
4336 	while (0)
4337 
4338 
4339 #define __Q3FastVector2D_Add(_v1, _v2, _r)									\
4340 	do																		\
4341 		{																	\
4342 		(_r)->x = (_v1)->x + (_v2)->x;										\
4343 		(_r)->y = (_v1)->y + (_v2)->y;										\
4344 		}																	\
4345 	while (0)
4346 
4347 #define __Q3FastVector3D_Add(_v1, _v2, _r)									\
4348 	do																		\
4349 		{																	\
4350 		(_r)->x = (_v1)->x + (_v2)->x;										\
4351 		(_r)->y = (_v1)->y + (_v2)->y;										\
4352 		(_r)->z = (_v1)->z + (_v2)->z;										\
4353 		}																	\
4354 	while (0)
4355 
4356 #define __Q3FastVector2D_Subtract(_v1, _v2, _r)								\
4357 	do																		\
4358 		{																	\
4359 		(_r)->x = (_v1)->x - (_v2)->x;										\
4360 		(_r)->y = (_v1)->y - (_v2)->y;										\
4361 		}																	\
4362 	while (0)
4363 
4364 #define __Q3FastVector3D_Subtract(_v1, _v2, _r)								\
4365 	do																		\
4366 		{																	\
4367 		(_r)->x = (_v1)->x - (_v2)->x;										\
4368 		(_r)->y = (_v1)->y - (_v2)->y;										\
4369 		(_r)->z = (_v1)->z - (_v2)->z;										\
4370 		}																	\
4371 	while (0)
4372 
4373 #define __Q3FastPoint2D_Vector2D_Add(_p, _v, _r)							\
4374 	do																		\
4375 		{																	\
4376 		(_r)->x = (_p)->x + (_v)->x;										\
4377 		(_r)->y = (_p)->y + (_v)->y;										\
4378 		}																	\
4379 	while (0)
4380 
4381 #define __Q3FastParam2D_Vector2D_Add(_p, _v, _r)							\
4382 	do																		\
4383 		{																	\
4384 		(_r)->u = (_p)->u + (_v)->x;										\
4385 		(_r)->v = (_p)->v + (_v)->y;										\
4386 		}																	\
4387 	while (0)
4388 
4389 #define __Q3FastPoint3D_Vector3D_Add(_p, _v, _r)							\
4390 	do																		\
4391 		{																	\
4392 		(_r)->x = (_p)->x + (_v)->x;										\
4393 		(_r)->y = (_p)->y + (_v)->y;										\
4394 		(_r)->z = (_p)->z + (_v)->z;										\
4395 		}																	\
4396 	while (0)
4397 
4398 #define __Q3FastPoint2D_Vector2D_Subtract(_p, _v, _r)						\
4399 	do																		\
4400 		{																	\
4401 		(_r)->x = (_p)->x - (_v)->x;										\
4402 		(_r)->y = (_p)->y - (_v)->y;										\
4403 		}																	\
4404 	while (0)
4405 
4406 #define __Q3FastParam2D_Vector2D_Subtract(_p, _v, _r)						\
4407 	do																		\
4408 		{																	\
4409 		(_r)->u = (_p)->u - (_v)->x;										\
4410 		(_r)->v = (_p)->v - (_v)->y;										\
4411 		}																	\
4412 	while (0)
4413 
4414 #define __Q3FastPoint3D_Vector3D_Subtract(_p, _v, _r)						\
4415 	do																		\
4416 		{																	\
4417 		(_r)->x = (_p)->x - (_v)->x;										\
4418 		(_r)->y = (_p)->y - (_v)->y;										\
4419 		(_r)->z = (_p)->z - (_v)->z;										\
4420 		}																	\
4421 	while (0)
4422 
4423 #define __Q3FastPoint2D_Subtract(_p1, _p2, _r)								\
4424 	do																		\
4425 		{																	\
4426 		(_r)->x = (_p1)->x - (_p2)->x;										\
4427 		(_r)->y = (_p1)->y - (_p2)->y;										\
4428 		}																	\
4429 	while (0)
4430 
4431 #define __Q3FastParam2D_Subtract(_p1, _p2, _r)								\
4432 	do																		\
4433 		{																	\
4434 		(_r)->x = (_p1)->u - (_p2)->u;										\
4435 		(_r)->y = (_p1)->v - (_p2)->v;										\
4436 		}																	\
4437 	while (0)
4438 
4439 #define __Q3FastPoint3D_Subtract(_p1, _p2, _r)								\
4440 	do																		\
4441 		{																	\
4442 		(_r)->x = (_p1)->x - (_p2)->x;										\
4443 		(_r)->y = (_p1)->y - (_p2)->y;										\
4444 		(_r)->z = (_p1)->z - (_p2)->z;										\
4445 		}																	\
4446 	while (0)
4447 
4448 #define __Q3FastPoint2D_RRatio(_p1, _p2, _r1, _r2, _result)					\
4449 	do																		\
4450 		{																	\
4451 		float frac   = (_r2) / ((_r1) + (_r2));								\
4452 		(_result)->x = (_p1)->x + (frac * ((_p2)->x - (_p1)->x));			\
4453 		(_result)->y = (_p1)->y + (frac * ((_p2)->y - (_p1)->y));			\
4454 		}																	\
4455 	while (0)
4456 
4457 #define __Q3FastParam2D_RRatio(_p1, _p2, _r1, _r2, _result)					\
4458 	do																		\
4459 		{																	\
4460 		float frac   = (_r2) / ((_r1) + (_r2));								\
4461 		(_result)->u = (_p1)->u + (frac * ((_p2)->u - (_p1)->u));			\
4462 		(_result)->v = (_p1)->v + (frac * ((_p2)->v - (_p1)->v));			\
4463 		}																	\
4464 	while (0)
4465 
4466 #define __Q3FastPoint3D_RRatio(_p1, _p2, _r1, _r2, _result)					\
4467 	do																		\
4468 		{																	\
4469 		float frac   = (_r2) / ((_r1) + (_r2));								\
4470 		(_result)->x = (_p1)->x + (frac * ((_p2)->x - (_p1)->x));			\
4471 		(_result)->y = (_p1)->y + (frac * ((_p2)->y - (_p1)->y));			\
4472 		(_result)->z = (_p1)->z + (frac * ((_p2)->z - (_p1)->z));			\
4473 		}																	\
4474 	while (0)
4475 
4476 #define __Q3FastRationalPoint4D_RRatio(_p1, _p2, _r1, _r2, _result)			\
4477 	do																		\
4478 		{																	\
4479 		TQ3Point3D	_pt1, _pt2;												\
4480 		__Q3FastRationalPoint4D_To3D( _p1, &_pt1 );							\
4481 		__Q3FastRationalPoint4D_To3D( _p2, &_pt2 );							\
4482 		__Q3FastPoint3D_RRatio( &_pt1, &_pt2, _r1, _r2, _result );			\
4483 		(_result)->w = 1;													\
4484 		}																	\
4485 	while (0)
4486 
4487 #define __Q3FastQuaternion_Set(_q, _w, _x, _y, _z)							\
4488 	do																		\
4489 		{																	\
4490 		(_q)->w = (_w);														\
4491 		(_q)->x = (_x);														\
4492 		(_q)->y = (_y);														\
4493 		(_q)->z = (_z);														\
4494 		}																	\
4495 	while (0)
4496 
4497 #define __Q3FastQuaternion_SetIdentity(_q)									\
4498 	do																		\
4499 		{																	\
4500 		(_q)->w = 1.0f;														\
4501 		(_q)->x = 0.0f;														\
4502 		(_q)->y = 0.0f;														\
4503 		(_q)->z = 0.0f;														\
4504 		}																	\
4505 	while (0)
4506 
4507 #define __Q3FastQuaternion_Copy(_q1, _q2)									\
4508 	do																		\
4509 		{																	\
4510 		*(_q2) = *(_q1);													\
4511 		}																	\
4512 	while (0)
4513 
4514 #define __Q3FastQuaternion_Dot(_q1, _q2)									\
4515 	(																		\
4516 		((_q1)->w * (_q2)->w) +												\
4517 		((_q1)->x * (_q2)->x) +												\
4518 		((_q1)->y * (_q2)->y) +												\
4519 		((_q1)->z * (_q2)->z)												\
4520 	)																		\
4521 
4522 #define __Q3FastQuaternion_Normalize(_q1, _q2)								\
4523 	do																		\
4524 		{																	\
4525 		float qDot    = __Q3FastQuaternion_Dot(_q1, _q1);					\
4526 		float qFactor = 1.0f / (float) sqrt(qDot);							\
4527 																			\
4528 		(_q2)->w = (_q1)->w * qFactor;										\
4529 		(_q2)->x = (_q1)->x * qFactor;										\
4530 		(_q2)->y = (_q1)->y * qFactor;										\
4531 		(_q2)->z = (_q1)->z * qFactor;										\
4532 		}																	\
4533 	while (0)
4534 
4535 #define __Q3FastQuaternion_Invert(_q1, _q2)									\
4536 	do																		\
4537 		{																	\
4538 		(_q2)->w =  (_q1)->w;												\
4539 		(_q2)->x = -(_q1)->x;												\
4540 		(_q2)->y = -(_q1)->y;												\
4541 		(_q2)->z = -(_q1)->z;												\
4542 		}																	\
4543 	while (0)
4544 
4545 #define __Q3FastBoundingBox_Reset(_b)										\
4546 	do																		\
4547 		{																	\
4548 		(_b)->min.x =														\
4549 		(_b)->min.y =														\
4550 		(_b)->min.z =														\
4551 		(_b)->max.x =														\
4552 		(_b)->max.y =														\
4553 		(_b)->max.z = 0.0f;													\
4554 		(_b)->isEmpty = kQ3True;											\
4555 		}																	\
4556 	while (0)
4557 
4558 #define __Q3FastBoundingBox_Set(_b, _min, _max, _isEmpty)					\
4559 	do																		\
4560 		{																	\
4561 		(_b)->min     = *(_min);											\
4562 		(_b)->max     = *(_max);											\
4563 		(_b)->isEmpty =  (_isEmpty);										\
4564 		}																	\
4565 	while (0)
4566 
4567 #define __Q3FastBoundingBox_Copy(_b1, _b2)									\
4568 	do																		\
4569 		{																	\
4570 		*(_b2) = *(_b1);													\
4571 		}																	\
4572 	while (0)
4573 
4574 #define __Q3FastBoundingSphere_Reset(_s)									\
4575 	do																		\
4576 		{																	\
4577 		(_s)->origin.x =													\
4578 		(_s)->origin.y =													\
4579 		(_s)->origin.z =													\
4580 		(_s)->radius   = 0.0f;												\
4581 		(_s)->isEmpty = kQ3True;											\
4582 		}																	\
4583 	while (0)
4584 
4585 #define __Q3FastBoundingSphere_Set(_s, _origin, _radius, _isEmpty)			\
4586 	do																		\
4587 		{																	\
4588 		(_s)->origin  = *(_origin);											\
4589 		(_s)->radius  =  (_radius);											\
4590 		(_s)->isEmpty =  (_isEmpty);										\
4591 		}																	\
4592 	while (0)
4593 
4594 #define __Q3FastBoundingSphere_Copy(_s1, _s2)								\
4595 	do																		\
4596 		{																	\
4597 		*(_s2) = *(_s1);													\
4598 		}																	\
4599 	while (0)
4600 
4601 #if QUESA_LONGLONG64_SUPPORT
4602 	#define 	Q3Int64_ToLongLong( _n )	((((long long)_n.hi) << 32) | _n.lo)
4603 	#define		Q3LongLong_ToInt64( _longlong, _n )							\
4604 	do {																	\
4605 		_n.hi = _longlong >> 32;											\
4606 		_n.lo = _longlong & 0xFFFFFFFFULL;									\
4607 	} while (0)
4608 #endif
4609 
4610 #if QUESA_LONGLONG64_SUPPORT
4611 #define __Q3Int64_Add( _n1, _n2, _result )									\
4612 	do {																	\
4613 		long long num1 = Q3Int64_ToLongLong( _n1 );							\
4614 		long long num2 = Q3Int64_ToLongLong( _n2 );							\
4615 		num1 += num2;														\
4616 		Q3LongLong_ToInt64( num1, _result );								\
4617 	} while (0)
4618 #else
4619 #define __Q3Int64_Add( _n1, _n2, _result )									\
4620 	do {																	\
4621 		int	highBit1 = (_n1.lo & 0x80000000L) != 0;							\
4622 		int	highBit2 = (_n2.lo & 0x80000000L) != 0;							\
4623 		_result.lo = _n1.lo + _n2.lo;										\
4624 		int	highBit_sum = (_result.lo & 0x80000000L) != 0;					\
4625 		int	carry = ((highBit1 == 1) && (highBit2 == 1)) ||					\
4626 			((highBit1 != highBit2) && (highBit_sum == 0));					\
4627 		_result.hi = _n1.hi + _n2.hi + carry;								\
4628 	} while (0)
4629 #endif
4630 
4631 #define	__Q3Int64_Uns32_Add( _n1, _n2, _result )							\
4632 	do {																	\
4633 		TQ3Int64	n2;														\
4634 		n2.hi = 0;															\
4635 		n2.lo = _n2;														\
4636 		__Q3Int64_Add( _n1, n2, _result );									\
4637 	} while (0)
4638 
4639 #if QUESA_LONGLONG64_SUPPORT
4640 #define __Q3Int64_Subtract( _n1, _n2, _result )								\
4641 	do {																	\
4642 		long long num1 = Q3Int64_ToLongLong( _n1 );							\
4643 		long long num2 = Q3Int64_ToLongLong( _n2 );							\
4644 		num1 -= num2;														\
4645 		Q3LongLong_ToInt64( num1, _result );								\
4646 	} while (0)
4647 #else
4648 #define __Q3Int64_Subtract( _n1, _n2, _result )								\
4649 	do {																	\
4650 		TQ3Int64	neg_n2, one;											\
4651 		neg_n2.hi = ~_n2.hi;												\
4652 		neg_n2.lo = ~_n2.lo;												\
4653 		one.hi = 0;															\
4654 		one.lo = 1;															\
4655 		__Q3Int64_Add( neg_n2, one, neg_n2 );								\
4656 		__Q3Int64_Add( _n1, neg_n2, _result );								\
4657 	} while (0)
4658 #endif
4659 
4660 #define	__Q3Int64_Uns32_Subtract( _n1, _n2, _result )						\
4661 	do {																	\
4662 		TQ3Int64	n2;														\
4663 		n2.hi = 0;															\
4664 		n2.lo = _n2;														\
4665 		__Q3Int64_Subtract( _n1, n2, _result );								\
4666 	} while (0)
4667 
4668 
4669 
4670 // Wrappers
4671 #ifdef __cplusplus
4672 
Q3FastVector2D_Set(TQ3Vector2D * vector2D,float x,float y)4673 	inline TQ3Vector2D *Q3FastVector2D_Set(TQ3Vector2D *vector2D, float x, float y)
4674 	{
4675 		__Q3FastVector2D_Set(vector2D, x, y);
4676 		return(vector2D);
4677 	}
4678 
Q3FastVector3D_Set(TQ3Vector3D * vector3D,float x,float y,float z)4679 	inline TQ3Vector3D *Q3FastVector3D_Set(TQ3Vector3D *vector3D, float x, float y, float z)
4680 	{
4681 		__Q3FastVector3D_Set(vector3D, x, y, z);
4682 		return(vector3D);
4683 	}
4684 
Q3FastPoint2D_Set(TQ3Point2D * point2D,float x,float y)4685 	inline TQ3Point2D * Q3FastPoint2D_Set(TQ3Point2D *point2D, float x, float y)
4686 	{
4687 		__Q3FastPoint2D_Set(point2D, x, y);
4688 		return(point2D);
4689 	}
4690 
Q3FastParam2D_Set(TQ3Param2D * param2D,float u,float v)4691 	inline TQ3Param2D * Q3FastParam2D_Set(TQ3Param2D *param2D, float u, float v)
4692 	{
4693 		__Q3FastParam2D_Set(param2D, u, v);
4694 		return(param2D);
4695 	}
4696 
Q3FastRationalPoint3D_Set(TQ3RationalPoint3D * rationalPoint3D,float x,float y,float w)4697 	inline TQ3RationalPoint3D * Q3FastRationalPoint3D_Set(TQ3RationalPoint3D *rationalPoint3D, float x, float y, float w)
4698 	{
4699 		__Q3FastRationalPoint3D_Set(rationalPoint3D, x, y, w);
4700 		return(rationalPoint3D);
4701 	}
4702 
Q3FastPoint3D_Set(TQ3Point3D * point3D,float x,float y,float z)4703 	inline TQ3Point3D * Q3FastPoint3D_Set(TQ3Point3D *point3D, float x, float y, float z)
4704 	{
4705 		__Q3FastPoint3D_Set(point3D, x, y, z);
4706 		return(point3D);
4707 	}
4708 
Q3FastRationalPoint4D_Set(TQ3RationalPoint4D * rationalPoint4D,float x,float y,float z,float w)4709 	inline TQ3RationalPoint4D * Q3FastRationalPoint4D_Set(TQ3RationalPoint4D *rationalPoint4D, float x, float y, float z, float w)
4710 	{
4711 		__Q3FastRationalPoint4D_Set(rationalPoint4D, x, y, z, w);
4712 		return(rationalPoint4D);
4713 	}
4714 
Q3FastPolarPoint_Set(TQ3PolarPoint * polarPoint,float r,float theta)4715 	inline TQ3PolarPoint * Q3FastPolarPoint_Set(TQ3PolarPoint *polarPoint, float r, float theta)
4716 	{
4717 		__Q3FastPolarPoint_Set(polarPoint, r, theta);
4718 		return(polarPoint);
4719 	}
4720 
Q3FastSphericalPoint_Set(TQ3SphericalPoint * sphericalPoint,float rho,float theta,float phi)4721 	inline TQ3SphericalPoint * Q3FastSphericalPoint_Set(TQ3SphericalPoint *sphericalPoint, float rho, float theta, float phi)
4722 	{
4723 		__Q3FastSphericalPoint_Set(sphericalPoint, rho, theta, phi);
4724 		return(sphericalPoint);
4725 	}
4726 
Q3FastVector2D_To3D(const TQ3Vector2D * vector2D,TQ3Vector3D * result)4727 	inline TQ3Vector3D * Q3FastVector2D_To3D(const TQ3Vector2D *vector2D, TQ3Vector3D *result)
4728 	{
4729 		__Q3FastVector2D_To3D(vector2D, result);
4730 		return(result);
4731 	}
4732 
Q3FastVector2D_ToRationalPoint3D(const TQ3Vector2D * vector2D,TQ3RationalPoint3D * result)4733 	inline TQ3RationalPoint3D * Q3FastVector2D_ToRationalPoint3D(const TQ3Vector2D *vector2D, TQ3RationalPoint3D *result)
4734 	{
4735 		__Q3FastVector2D_ToRationalPoint3D(vector2D, result);
4736 		return(result);
4737 	}
4738 
Q3FastVector3D_To2D(const TQ3Vector3D * vector3D,TQ3Vector2D * result)4739 	inline TQ3Vector2D * Q3FastVector3D_To2D(const TQ3Vector3D *vector3D, TQ3Vector2D *result)
4740 	{
4741 		__Q3FastVector3D_To2D(vector3D, result);
4742 		return(result);
4743 	}
4744 
Q3FastRationalPoint3D_ToVector2D(const TQ3RationalPoint3D * rationalPoint3D,TQ3Vector2D * result)4745 	inline TQ3Vector2D * Q3FastRationalPoint3D_ToVector2D(const TQ3RationalPoint3D *rationalPoint3D, TQ3Vector2D *result)
4746 	{
4747 		__Q3FastRationalPoint3D_ToVector2D(rationalPoint3D, result);
4748 		return(result);
4749 	}
4750 
Q3FastVector3D_ToRationalPoint4D(const TQ3Vector3D * vector3D,TQ3RationalPoint4D * result)4751 	inline TQ3RationalPoint4D * Q3FastVector3D_ToRationalPoint4D(const TQ3Vector3D *vector3D, TQ3RationalPoint4D *result)
4752 	{
4753 		__Q3FastVector3D_ToRationalPoint4D(vector3D, result);
4754 		return(result);
4755 	}
4756 
Q3FastRationalPoint4D_ToVector3D(const TQ3RationalPoint4D * rationalPoint4D,TQ3Vector3D * result)4757 	inline TQ3Vector3D * Q3FastRationalPoint4D_ToVector3D(const TQ3RationalPoint4D *rationalPoint4D, TQ3Vector3D *result)
4758 	{
4759 		__Q3FastRationalPoint4D_ToVector3D(rationalPoint4D, result);
4760 		return(result);
4761 	}
4762 
Q3FastPoint2D_To3D(const TQ3Point2D * point2D,TQ3RationalPoint3D * result)4763 	inline TQ3RationalPoint3D * Q3FastPoint2D_To3D(const TQ3Point2D *point2D, TQ3RationalPoint3D *result)
4764 	{
4765 		__Q3FastPoint2D_To3D(point2D, result);
4766 		return(result);
4767 	}
4768 
Q3FastRationalPoint3D_To2D(const TQ3RationalPoint3D * rationalPoint3D,TQ3Point2D * result)4769 	inline TQ3Point2D * Q3FastRationalPoint3D_To2D(const TQ3RationalPoint3D *rationalPoint3D, TQ3Point2D *result)
4770 	{
4771 		__Q3FastRationalPoint3D_To2D(rationalPoint3D, result);
4772 		return(result);
4773 	}
4774 
Q3FastPoint3D_To4D(const TQ3Point3D * point3D,TQ3RationalPoint4D * result)4775 	inline TQ3RationalPoint4D * Q3FastPoint3D_To4D(const TQ3Point3D *point3D, TQ3RationalPoint4D *result)
4776 	{
4777 		__Q3FastPoint3D_To4D(point3D, result);
4778 		return(result);
4779 	}
4780 
Q3FastRationalPoint4D_To3D(const TQ3RationalPoint4D * rationalPoint4D,TQ3Point3D * result)4781 	inline TQ3Point3D * Q3FastRationalPoint4D_To3D(const TQ3RationalPoint4D *rationalPoint4D, TQ3Point3D *result)
4782 	{
4783 		__Q3FastRationalPoint4D_To3D(rationalPoint4D, result);
4784 		return(result);
4785 	}
4786 
Q3FastPolarPoint_ToPoint2D(const TQ3PolarPoint * polarPoint,TQ3Point2D * result)4787 	inline TQ3Point2D *Q3FastPolarPoint_ToPoint2D(const TQ3PolarPoint *polarPoint, TQ3Point2D *result)
4788 	{
4789 		__Q3FastPolarPoint_ToPoint2D(polarPoint, result);
4790 		return(result);
4791 	}
4792 
Q3FastVector2D_Dot(const TQ3Vector2D * v1,const TQ3Vector2D * v2)4793 	inline float Q3FastVector2D_Dot(const TQ3Vector2D *v1, const TQ3Vector2D *v2)
4794 	{
4795 		return(__Q3FastVector2D_Dot(v1, v2));
4796 	}
4797 
Q3FastVector3D_Dot(const TQ3Vector3D * v1,const TQ3Vector3D * v2)4798 	inline float Q3FastVector3D_Dot(const TQ3Vector3D *v1, const TQ3Vector3D *v2)
4799 	{
4800 		return(__Q3FastVector3D_Dot(v1, v2));
4801 	}
4802 
Q3FastVector2D_Cross(const TQ3Vector2D * v1,const TQ3Vector2D * v2)4803 	inline float Q3FastVector2D_Cross(const TQ3Vector2D *v1, const TQ3Vector2D *v2)
4804 	{
4805 		return(__Q3FastVector2D_Cross(v1, v2));
4806 	}
4807 
Q3FastPoint2D_CrossProductTri(const TQ3Point2D * p1,const TQ3Point2D * p2,const TQ3Point2D * p3)4808 	inline float Q3FastPoint2D_CrossProductTri(const TQ3Point2D *p1, const TQ3Point2D *p2, const TQ3Point2D *p3)
4809 	{
4810 		return(__Q3FastPoint2D_CrossProductTri(p1, p2, p3));
4811 	}
4812 
Q3FastVector3D_Cross(const TQ3Vector3D * v1,const TQ3Vector3D * v2,TQ3Vector3D * result)4813 	inline TQ3Vector3D *Q3FastVector3D_Cross(const TQ3Vector3D *v1, const TQ3Vector3D *v2, TQ3Vector3D *result)
4814 	{
4815 		__Q3FastVector3D_Cross(v1, v2, result);
4816 		return(result);
4817 	}
4818 
Q3FastPoint3D_CrossProductTri(const TQ3Point3D * p1,const TQ3Point3D * p2,const TQ3Point3D * p3,TQ3Vector3D * result)4819 	inline TQ3Vector3D *Q3FastPoint3D_CrossProductTri(const TQ3Point3D *p1, const TQ3Point3D *p2, const TQ3Point3D *p3, TQ3Vector3D *result)
4820 	{
4821 		__Q3FastPoint3D_CrossProductTri(p1, p2, p3, result);
4822 		return(result);
4823 	}
4824 
Q3FastVector2D_Length(const TQ3Vector2D * vector2D)4825 	inline float Q3FastVector2D_Length(const TQ3Vector2D *vector2D)
4826 	{
4827 		return(__Q3FastVector2D_Length(vector2D));
4828 	}
4829 
Q3FastVector2D_LengthSquared(const TQ3Vector2D * vector2D)4830 	inline float Q3FastVector2D_LengthSquared(const TQ3Vector2D *vector2D)
4831 	{
4832 		return(__Q3FastVector2D_LengthSquared(vector2D));
4833 	}
4834 
Q3FastVector3D_Length(const TQ3Vector3D * vector3D)4835 	inline float Q3FastVector3D_Length(const TQ3Vector3D *vector3D)
4836 	{
4837 		return(__Q3FastVector3D_Length(vector3D));
4838 	}
4839 
Q3FastVector3D_LengthSquared(const TQ3Vector3D * vector3D)4840 	inline float Q3FastVector3D_LengthSquared(const TQ3Vector3D *vector3D)
4841 	{
4842 		return(__Q3FastVector3D_LengthSquared(vector3D));
4843 	}
4844 
Q3FastPoint2D_Distance(const TQ3Point2D * p1,const TQ3Point2D * p2)4845 	inline float Q3FastPoint2D_Distance(const TQ3Point2D *p1, const TQ3Point2D *p2)
4846 	{
4847 		return(__Q3FastPoint2D_Distance(p1, p2));
4848 	}
4849 
Q3FastPoint2D_DistanceSquared(const TQ3Point2D * p1,const TQ3Point2D * p2)4850 	inline float Q3FastPoint2D_DistanceSquared(const TQ3Point2D *p1, const TQ3Point2D *p2)
4851 	{
4852 		return(__Q3FastPoint2D_DistanceSquared(p1, p2));
4853 	}
4854 
Q3FastParam2D_Distance(const TQ3Param2D * p1,const TQ3Param2D * p2)4855 	inline float Q3FastParam2D_Distance(const TQ3Param2D *p1, const TQ3Param2D *p2)
4856 	{
4857 		return(__Q3FastParam2D_Distance(p1, p2));
4858 	}
4859 
Q3FastParam2D_DistanceSquared(const TQ3Param2D * p1,const TQ3Param2D * p2)4860 	inline float Q3FastParam2D_DistanceSquared(const TQ3Param2D *p1, const TQ3Param2D *p2)
4861 	{
4862 		return(__Q3FastParam2D_DistanceSquared(p1, p2));
4863 	}
4864 
Q3FastRationalPoint3D_Distance(const TQ3RationalPoint3D * p1,const TQ3RationalPoint3D * p2)4865 	inline float Q3FastRationalPoint3D_Distance(const TQ3RationalPoint3D *p1, const TQ3RationalPoint3D *p2)
4866 	{
4867 		return(__Q3FastRationalPoint3D_Distance(p1, p2));
4868 	}
4869 
Q3FastRationalPoint3D_DistanceSquared(const TQ3RationalPoint3D * p1,const TQ3RationalPoint3D * p2)4870 	inline float Q3FastRationalPoint3D_DistanceSquared(const TQ3RationalPoint3D *p1, const TQ3RationalPoint3D *p2)
4871 	{
4872 		return(__Q3FastRationalPoint3D_DistanceSquared(p1, p2));
4873 	}
4874 
Q3FastPoint3D_Distance(const TQ3Point3D * p1,const TQ3Point3D * p2)4875 	inline float Q3FastPoint3D_Distance(const TQ3Point3D *p1, const TQ3Point3D *p2)
4876 	{
4877 		return(__Q3FastPoint3D_Distance(p1, p2));
4878 	}
4879 
Q3FastPoint3D_DistanceSquared(const TQ3Point3D * p1,const TQ3Point3D * p2)4880 	inline float Q3FastPoint3D_DistanceSquared(const TQ3Point3D *p1, const TQ3Point3D *p2)
4881 	{
4882 		return(__Q3FastPoint3D_DistanceSquared(p1, p2));
4883 	}
4884 
Q3FastRationalPoint4D_Distance(const TQ3RationalPoint4D * p1,const TQ3RationalPoint4D * p2)4885 	inline float Q3FastRationalPoint4D_Distance(const TQ3RationalPoint4D *p1, const TQ3RationalPoint4D *p2)
4886 	{
4887 		return(__Q3FastRationalPoint4D_Distance(p1, p2));
4888 	}
4889 
Q3FastRationalPoint4D_DistanceSquared(const TQ3RationalPoint4D * p1,const TQ3RationalPoint4D * p2)4890 	inline float Q3FastRationalPoint4D_DistanceSquared(const TQ3RationalPoint4D *p1, const TQ3RationalPoint4D *p2)
4891 	{
4892 		return(__Q3FastRationalPoint4D_DistanceSquared(p1, p2));
4893 	}
4894 
Q3FastVector2D_Negate(const TQ3Vector2D * vector2D,TQ3Vector2D * result)4895 	inline TQ3Vector2D *Q3FastVector2D_Negate(const TQ3Vector2D *vector2D, TQ3Vector2D *result)
4896 	{
4897 		__Q3FastVector2D_Negate(vector2D, result);
4898 		return(result);
4899 	}
4900 
Q3FastVector3D_Negate(const TQ3Vector3D * vector3D,TQ3Vector3D * result)4901 	inline TQ3Vector3D *Q3FastVector3D_Negate(const TQ3Vector3D *vector3D, TQ3Vector3D *result)
4902 	{
4903 		__Q3FastVector3D_Negate(vector3D, result);
4904 		return(result);
4905 	}
4906 
Q3FastVector2D_Scale(const TQ3Vector2D * vector2D,float scalar,TQ3Vector2D * result)4907 	inline TQ3Vector2D *Q3FastVector2D_Scale(const TQ3Vector2D *vector2D, float scalar, TQ3Vector2D *result)
4908 	{
4909 		__Q3FastVector2D_Scale(vector2D, scalar, result);
4910 		return(result);
4911 	}
4912 
Q3FastVector3D_Scale(const TQ3Vector3D * vector3D,float scalar,TQ3Vector3D * result)4913 	inline TQ3Vector3D *Q3FastVector3D_Scale(const TQ3Vector3D *vector3D, float scalar, TQ3Vector3D *result)
4914 	{
4915 		__Q3FastVector3D_Scale(vector3D, scalar, result);
4916 		return(result);
4917 	}
4918 
Q3FastVector2D_Normalize(const TQ3Vector2D * vector2D,TQ3Vector2D * result)4919 	inline TQ3Vector2D *Q3FastVector2D_Normalize(const TQ3Vector2D *vector2D, TQ3Vector2D *result)
4920 	{
4921 		__Q3FastVector2D_Normalize(vector2D, result);
4922 		return(result);
4923 	}
4924 
Q3FastVector3D_Normalize(const TQ3Vector3D * vector3D,TQ3Vector3D * result)4925 	inline TQ3Vector3D *Q3FastVector3D_Normalize(const TQ3Vector3D *vector3D, TQ3Vector3D *result)
4926 	{
4927 		__Q3FastVector3D_Normalize(vector3D, result);
4928 		return(result);
4929 	}
4930 
Q3FastVector2D_Add(const TQ3Vector2D * v1,const TQ3Vector2D * v2,TQ3Vector2D * result)4931 	inline TQ3Vector2D *Q3FastVector2D_Add(const TQ3Vector2D *v1, const TQ3Vector2D *v2, TQ3Vector2D *result)
4932 	{
4933 		__Q3FastVector2D_Add(v1, v2, result);
4934 		return(result);
4935 	}
4936 
Q3FastVector3D_Add(const TQ3Vector3D * v1,const TQ3Vector3D * v2,TQ3Vector3D * result)4937 	inline TQ3Vector3D *Q3FastVector3D_Add(const TQ3Vector3D *v1, const TQ3Vector3D *v2, TQ3Vector3D *result)
4938 	{
4939 		__Q3FastVector3D_Add(v1, v2, result);
4940 		return(result);
4941 	}
4942 
Q3FastVector2D_Subtract(const TQ3Vector2D * v1,const TQ3Vector2D * v2,TQ3Vector2D * result)4943 	inline TQ3Vector2D *Q3FastVector2D_Subtract(const TQ3Vector2D *v1, const TQ3Vector2D *v2, TQ3Vector2D *result)
4944 	{
4945 		__Q3FastVector2D_Subtract(v1, v2, result);
4946 		return(result);
4947 	}
4948 
Q3FastVector3D_Subtract(const TQ3Vector3D * v1,const TQ3Vector3D * v2,TQ3Vector3D * result)4949 	inline TQ3Vector3D *Q3FastVector3D_Subtract(const TQ3Vector3D *v1, const TQ3Vector3D *v2, TQ3Vector3D *result)
4950 	{
4951 		__Q3FastVector3D_Subtract(v1, v2, result);
4952 		return(result);
4953 	}
4954 
Q3FastPoint2D_Vector2D_Add(const TQ3Point2D * point2D,const TQ3Vector2D * vector2D,TQ3Point2D * result)4955 	inline TQ3Point2D *Q3FastPoint2D_Vector2D_Add(const TQ3Point2D *point2D, const TQ3Vector2D *vector2D, TQ3Point2D *result)
4956 	{
4957 		__Q3FastPoint2D_Vector2D_Add(point2D, vector2D, result);
4958 		return(result);
4959 	}
4960 
Q3FastParam2D_Vector2D_Add(const TQ3Param2D * param2D,const TQ3Vector2D * vector2D,TQ3Param2D * result)4961 	inline TQ3Param2D *Q3FastParam2D_Vector2D_Add(const TQ3Param2D *param2D, const TQ3Vector2D *vector2D, TQ3Param2D *result)
4962 	{
4963 		__Q3FastParam2D_Vector2D_Add(param2D, vector2D, result);
4964 		return(result);
4965 	}
4966 
Q3FastPoint3D_Vector3D_Add(const TQ3Point3D * point3D,const TQ3Vector3D * vector3D,TQ3Point3D * result)4967 	inline TQ3Point3D *Q3FastPoint3D_Vector3D_Add(const TQ3Point3D *point3D, const TQ3Vector3D *vector3D, TQ3Point3D *result)
4968 	{
4969 		__Q3FastPoint3D_Vector3D_Add(point3D, vector3D, result);
4970 		return(result);
4971 	}
4972 
Q3FastPoint2D_Vector2D_Subtract(const TQ3Point2D * point2D,const TQ3Vector2D * vector2D,TQ3Point2D * result)4973 	inline TQ3Point2D *Q3FastPoint2D_Vector2D_Subtract(const TQ3Point2D *point2D, const TQ3Vector2D *vector2D, TQ3Point2D *result)
4974 	{
4975 		__Q3FastPoint2D_Vector2D_Subtract(point2D, vector2D, result);
4976 		return(result);
4977 	}
4978 
Q3FastParam2D_Vector2D_Subtract(const TQ3Param2D * param2D,const TQ3Vector2D * vector2D,TQ3Param2D * result)4979 	inline TQ3Param2D *Q3FastParam2D_Vector2D_Subtract(const TQ3Param2D *param2D, const TQ3Vector2D *vector2D, TQ3Param2D *result)
4980 	{
4981 		__Q3FastParam2D_Vector2D_Subtract(param2D, vector2D, result);
4982 		return(result);
4983 	}
4984 
Q3FastPoint3D_Vector3D_Subtract(const TQ3Point3D * point3D,const TQ3Vector3D * vector3D,TQ3Point3D * result)4985 	inline TQ3Point3D *Q3FastPoint3D_Vector3D_Subtract(const TQ3Point3D *point3D, const TQ3Vector3D *vector3D, TQ3Point3D *result)
4986 	{
4987 		__Q3FastPoint3D_Vector3D_Subtract(point3D, vector3D, result);
4988 		return(result);
4989 	}
4990 
Q3FastPoint2D_Subtract(const TQ3Point2D * p1,const TQ3Point2D * p2,TQ3Vector2D * result)4991 	inline TQ3Vector2D *Q3FastPoint2D_Subtract(const TQ3Point2D *p1, const TQ3Point2D *p2, TQ3Vector2D *result)
4992 	{
4993 		__Q3FastPoint2D_Subtract(p1, p2, result);
4994 		return(result);
4995 	}
4996 
Q3FastParam2D_Subtract(const TQ3Param2D * p1,const TQ3Param2D * p2,TQ3Vector2D * result)4997 	inline TQ3Vector2D *Q3FastParam2D_Subtract(const TQ3Param2D *p1, const TQ3Param2D *p2, TQ3Vector2D *result)
4998 	{
4999 		__Q3FastParam2D_Subtract(p1, p2, result);
5000 		return(result);
5001 	}
5002 
Q3FastPoint3D_Subtract(const TQ3Point3D * p1,const TQ3Point3D * p2,TQ3Vector3D * result)5003 	inline TQ3Vector3D *Q3FastPoint3D_Subtract(const TQ3Point3D *p1, const TQ3Point3D *p2, TQ3Vector3D *result)
5004 	{
5005 		__Q3FastPoint3D_Subtract(p1, p2, result);
5006 		return(result);
5007 	}
5008 
Q3FastPoint2D_RRatio(const TQ3Point2D * p1,const TQ3Point2D * p2,float r1,float r2,TQ3Point2D * result)5009 	inline TQ3Point2D *Q3FastPoint2D_RRatio(const TQ3Point2D *p1, const TQ3Point2D *p2, float r1, float r2, TQ3Point2D *result)
5010 	{
5011 		__Q3FastPoint2D_RRatio(p1, p2, r1, r2, result);
5012 		return(result);
5013 	}
5014 
Q3FastParam2D_RRatio(const TQ3Param2D * p1,const TQ3Param2D * p2,float r1,float r2,TQ3Param2D * result)5015 	inline TQ3Param2D *Q3FastParam2D_RRatio(const TQ3Param2D *p1, const TQ3Param2D *p2, float r1, float r2, TQ3Param2D *result)
5016 	{
5017 		__Q3FastParam2D_RRatio(p1, p2, r1, r2, result);
5018 		return(result);
5019 	}
5020 
Q3FastPoint3D_RRatio(const TQ3Point3D * p1,const TQ3Point3D * p2,float r1,float r2,TQ3Point3D * result)5021 	inline TQ3Point3D *Q3FastPoint3D_RRatio(const TQ3Point3D *p1, const TQ3Point3D *p2, float r1, float r2, TQ3Point3D *result)
5022 	{
5023 		__Q3FastPoint3D_RRatio(p1, p2, r1, r2, result);
5024 		return(result);
5025 	}
5026 
Q3FastRationalPoint4D_RRatio(const TQ3RationalPoint4D * p1,const TQ3RationalPoint4D * p2,float r1,float r2,TQ3RationalPoint4D * result)5027 	inline TQ3RationalPoint4D *Q3FastRationalPoint4D_RRatio(const TQ3RationalPoint4D *p1, const TQ3RationalPoint4D *p2, float r1, float r2, TQ3RationalPoint4D *result)
5028 	{
5029 		__Q3FastRationalPoint4D_RRatio(p1, p2, r1, r2, result);
5030 		return(result);
5031 	}
5032 
Q3FastQuaternion_Set(TQ3Quaternion * quaternion,float w,float x,float y,float z)5033 	inline TQ3Quaternion *Q3FastQuaternion_Set(TQ3Quaternion *quaternion, float w, float x, float y, float z)
5034 	{
5035 		__Q3FastQuaternion_Set(quaternion, w, x, y, z);
5036 		return(quaternion);
5037 	}
5038 
Q3FastQuaternion_SetIdentity(TQ3Quaternion * quaternion)5039 	inline TQ3Quaternion *Q3FastQuaternion_SetIdentity(TQ3Quaternion *quaternion)
5040 	{
5041 		__Q3FastQuaternion_SetIdentity(quaternion);
5042 		return(quaternion);
5043 	}
5044 
Q3FastQuaternion_Copy(const TQ3Quaternion * quaternion,TQ3Quaternion * result)5045 	inline TQ3Quaternion *Q3FastQuaternion_Copy(const TQ3Quaternion *quaternion, TQ3Quaternion *result)
5046 	{
5047 		__Q3FastQuaternion_Copy(quaternion, result);
5048 		return(result);
5049 	}
5050 
Q3FastQuaternion_Dot(const TQ3Quaternion * q1,const TQ3Quaternion * q2)5051 	inline float Q3FastQuaternion_Dot(const TQ3Quaternion *q1, const TQ3Quaternion *q2)
5052 	{
5053 		return(__Q3FastQuaternion_Dot(q1, q2));
5054 	}
5055 
Q3FastQuaternion_Normalize(const TQ3Quaternion * quaternion,TQ3Quaternion * result)5056 	inline TQ3Quaternion *Q3FastQuaternion_Normalize(const TQ3Quaternion *quaternion, TQ3Quaternion *result)
5057 	{
5058 		__Q3FastQuaternion_Normalize(quaternion, result);
5059 		return(result);
5060 	}
5061 
Q3FastQuaternion_Invert(const TQ3Quaternion * quaternion,TQ3Quaternion * result)5062 	inline TQ3Quaternion *Q3FastQuaternion_Invert(const TQ3Quaternion *quaternion, TQ3Quaternion *result)
5063 	{
5064 		__Q3FastQuaternion_Invert(quaternion, result);
5065 		return(result);
5066 	}
5067 
Q3FastBoundingBox_Reset(TQ3BoundingBox * bBox)5068 	inline TQ3BoundingBox *Q3FastBoundingBox_Reset(TQ3BoundingBox *bBox)
5069 	{
5070 		__Q3FastBoundingBox_Reset(bBox);
5071 		return(bBox);
5072 	}
5073 
Q3FastBoundingBox_Set(TQ3BoundingBox * bBox,const TQ3Point3D * min,const TQ3Point3D * max,TQ3Boolean isEmpty)5074 	inline TQ3BoundingBox *Q3FastBoundingBox_Set(TQ3BoundingBox *bBox, const TQ3Point3D *min, const TQ3Point3D *max, TQ3Boolean isEmpty)
5075 	{
5076 		__Q3FastBoundingBox_Set(bBox, min, max, isEmpty);
5077 		return(bBox);
5078 	}
5079 
Q3FastBoundingBox_Copy(const TQ3BoundingBox * bBox,TQ3BoundingBox * result)5080 	inline TQ3BoundingBox *Q3FastBoundingBox_Copy(const TQ3BoundingBox *bBox, TQ3BoundingBox *result)
5081 	{
5082 		__Q3FastBoundingBox_Copy(bBox, result);
5083 		return(result);
5084 	}
5085 
Q3FastBoundingSphere_Reset(TQ3BoundingSphere * bSphere)5086 	inline TQ3BoundingSphere *Q3FastBoundingSphere_Reset(TQ3BoundingSphere *bSphere)
5087 	{
5088 		__Q3FastBoundingSphere_Reset(bSphere);
5089 		return(bSphere);
5090 	}
5091 
Q3FastBoundingSphere_Set(TQ3BoundingSphere * bSphere,const TQ3Point3D * origin,float radius,TQ3Boolean isEmpty)5092 	inline TQ3BoundingSphere *Q3FastBoundingSphere_Set(TQ3BoundingSphere *bSphere, const TQ3Point3D *origin, float radius, TQ3Boolean isEmpty)
5093 	{
5094 		__Q3FastBoundingSphere_Set(bSphere, origin, radius, isEmpty);
5095 		return(bSphere);
5096 	}
5097 
Q3FastBoundingSphere_Copy(const TQ3BoundingSphere * bSphere,TQ3BoundingSphere * result)5098 	inline TQ3BoundingSphere *Q3FastBoundingSphere_Copy(const TQ3BoundingSphere *bSphere, TQ3BoundingSphere *result)
5099 	{
5100 		__Q3FastBoundingSphere_Copy(bSphere, result);
5101 		return(result);
5102 	}
5103 
Q3Int64_Add(const TQ3Int64 & a,const TQ3Int64 & b,TQ3Int64 & c)5104 	inline void Q3Int64_Add( const TQ3Int64& a, const TQ3Int64& b, TQ3Int64& c )
5105 	{
5106 		__Q3Int64_Add( a, b, c );
5107 	}
5108 
Q3Int64_Subtract(const TQ3Int64 & a,const TQ3Int64 & b,TQ3Int64 & c)5109 	inline void Q3Int64_Subtract( const TQ3Int64& a, const TQ3Int64& b, TQ3Int64& c )
5110 	{
5111 		__Q3Int64_Subtract( a, b, c );
5112 	}
5113 
Q3Int64_Uns32_Add(const TQ3Int64 & a,TQ3Uns32 b,TQ3Int64 & c)5114 	inline void Q3Int64_Uns32_Add( const TQ3Int64& a, TQ3Uns32 b, TQ3Int64& c )
5115 	{
5116 		__Q3Int64_Uns32_Add( a, b, c );
5117 	}
5118 
Q3Int64_Uns32_Subtract(const TQ3Int64 & a,TQ3Uns32 b,TQ3Int64 & c)5119 	inline void Q3Int64_Uns32_Subtract( const TQ3Int64& a, TQ3Uns32 b, TQ3Int64& c )
5120 	{
5121 		__Q3Int64_Uns32_Subtract( a, b, c );
5122 	}
5123 
5124 #else
5125 	#define Q3FastVector2D_Set							__Q3FastVector2D_Set
5126 	#define Q3FastVector3D_Set							__Q3FastVector3D_Set
5127 	#define Q3FastPoint2D_Set							__Q3FastPoint2D_Set
5128 	#define Q3FastParam2D_Set							__Q3FastParam2D_Set
5129 	#define Q3FastRationalPoint3D_Set					__Q3FastRationalPoint3D_Set
5130 	#define Q3FastPoint3D_Set							__Q3FastPoint3D_Set
5131 	#define Q3FastRationalPoint4D_Set					__Q3FastRationalPoint4D_Set
5132 	#define Q3FastPolarPoint_Set						__Q3FastPolarPoint_Set
5133 	#define Q3FastSphericalPoint_Set					__Q3FastSphericalPoint_Set
5134 	#define Q3FastVector2D_To3D							__Q3FastVector2D_To3D
5135 	#define Q3FastVector2D_ToRationalPoint3D			__Q3FastVector2D_ToRationalPoint3D
5136 	#define Q3FastVector3D_To2D							__Q3FastVector3D_To2D
5137 	#define Q3FastRationalPoint3D_ToVector2D			__Q3FastRationalPoint3D_ToVector2D
5138 	#define Q3FastVector3D_ToRationalPoint4D			__Q3FastVector3D_ToRationalPoint4D
5139 	#define Q3FastRationalPoint4D_ToVector3D			__Q3FastRationalPoint4D_ToVector3D
5140 	#define Q3FastPoint2D_To3D							__Q3FastPoint2D_To3D
5141 	#define Q3FastRationalPoint3D_To2D					__Q3FastRationalPoint3D_To2D
5142 	#define Q3FastPoint3D_To4D							__Q3FastPoint3D_To4D
5143 	#define Q3FastRationalPoint4D_To3D					__Q3FastRationalPoint4D_To3D
5144 	#define Q3FastPolarPoint_ToPoint2D					__Q3FastPolarPoint_ToPoint2D
5145 	#define Q3FastVector2D_Dot							__Q3FastVector2D_Dot
5146 	#define Q3FastVector3D_Dot							__Q3FastVector3D_Dot
5147 	#define Q3FastVector2D_Cross						__Q3FastVector2D_Cross
5148 	#define Q3FastPoint2D_CrossProductTri				__Q3FastPoint2D_CrossProductTri
5149 	#define Q3FastVector3D_Cross						__Q3FastVector3D_Cross
5150 	#define Q3FastPoint3D_CrossProductTri				__Q3FastPoint3D_CrossProductTri
5151 	#define Q3FastVector2D_Length						__Q3FastVector2D_Length
5152 	#define Q3FastVector2D_LengthSquared				__Q3FastVector2D_LengthSquared
5153 	#define Q3FastVector3D_Length						__Q3FastVector3D_Length
5154 	#define Q3FastVector3D_LengthSquared				__Q3FastVector3D_LengthSquared
5155 	#define Q3FastPoint2D_Distance						__Q3FastPoint2D_Distance
5156 	#define Q3FastPoint2D_DistanceSquared				__Q3FastPoint2D_DistanceSquared
5157 	#define Q3FastParam2D_Distance						__Q3FastParam2D_Distance
5158 	#define Q3FastParam2D_DistanceSquared				__Q3FastParam2D_DistanceSquared
5159 	#define Q3FastRationalPoint3D_Distance				__Q3FastRationalPoint3D_Distance
5160 	#define Q3FastRationalPoint3D_DistanceSquared		__Q3FastRationalPoint3D_DistanceSquared
5161 	#define Q3FastPoint3D_Distance						__Q3FastPoint3D_Distance
5162 	#define Q3FastPoint3D_DistanceSquared				__Q3FastPoint3D_DistanceSquared
5163 	#define Q3FastRationalPoint4D_Distance				__Q3FastRationalPoint4D_Distance
5164 	#define Q3FastRationalPoint4D_DistanceSquared		__Q3FastRationalPoint4D_DistanceSquared
5165 	#define Q3FastVector2D_Negate						__Q3FastVector2D_Negate
5166 	#define Q3FastVector3D_Negate						__Q3FastVector3D_Negate
5167 	#define Q3FastVector2D_Scale						__Q3FastVector2D_Scale
5168 	#define Q3FastVector3D_Scale						__Q3FastVector3D_Scale
5169 	#define Q3FastVector2D_Normalize					__Q3FastVector2D_Normalize
5170 	#define Q3FastVector3D_Normalize					__Q3FastVector3D_Normalize
5171 	#define Q3FastVector2D_Add							__Q3FastVector2D_Add
5172 	#define Q3FastVector3D_Add							__Q3FastVector3D_Add
5173 	#define Q3FastVector2D_Subtract						__Q3FastVector2D_Subtract
5174 	#define Q3FastVector3D_Subtract						__Q3FastVector3D_Subtract
5175 	#define Q3FastPoint2D_Vector2D_Add					__Q3FastPoint2D_Vector2D_Add
5176 	#define Q3FastParam2D_Vector2D_Add					__Q3FastParam2D_Vector2D_Add
5177 	#define Q3FastPoint3D_Vector3D_Add					__Q3FastPoint3D_Vector3D_Add
5178 	#define Q3FastPoint2D_Vector2D_Subtract				__Q3FastPoint2D_Vector2D_Subtract
5179 	#define Q3FastParam2D_Vector2D_Subtract				__Q3FastParam2D_Vector2D_Subtract
5180 	#define Q3FastPoint3D_Vector3D_Subtract				__Q3FastPoint3D_Vector3D_Subtract
5181 	#define Q3FastPoint2D_Subtract						__Q3FastPoint2D_Subtract
5182 	#define Q3FastParam2D_Subtract						__Q3FastParam2D_Subtract
5183 	#define Q3FastPoint3D_Subtract						__Q3FastPoint3D_Subtract
5184 	#define Q3FastPoint2D_RRatio						__Q3FastPoint2D_RRatio
5185 	#define Q3FastParam2D_RRatio						__Q3FastParam2D_RRatio
5186 	#define Q3FastPoint3D_RRatio						__Q3FastPoint3D_RRatio
5187 	#define Q3FastRationalPoint4D_RRatio				__Q3FastRationalPoint4D_RRatio
5188 	#define Q3FastQuaternion_Set						__Q3FastQuaternion_Set
5189 	#define Q3FastQuaternion_SetIdentity				__Q3FastQuaternion_SetIdentity
5190 	#define Q3FastQuaternion_Copy						__Q3FastQuaternion_Copy
5191 	#define Q3FastQuaternion_Dot						__Q3FastQuaternion_Dot
5192 	#define Q3FastQuaternion_Normalize					__Q3FastQuaternion_Normalize
5193 	#define Q3FastQuaternion_Invert						__Q3FastQuaternion_Invert
5194 	#define Q3FastBoundingBox_Reset						__Q3FastBoundingBox_Reset
5195 	#define Q3FastBoundingBox_Set						__Q3FastBoundingBox_Set
5196 	#define Q3FastBoundingBox_Copy						__Q3FastBoundingBox_Copy
5197 	#define Q3FastBoundingSphere_Reset					__Q3FastBoundingSphere_Reset
5198 	#define Q3FastBoundingSphere_Set					__Q3FastBoundingSphere_Set
5199 	#define Q3FastBoundingSphere_Copy					__Q3FastBoundingSphere_Copy
5200 	#define	Q3Int64_Add									__Q3Int64_Add
5201 	#define	Q3Int64_Subtract							__Q3Int64_Subtract
5202 	#define	Q3Int64_Uns32_Add							__Q3Int64_Uns32_Add
5203 	#define Q3Int64_Uns32_Subtract						__Q3Int64_Uns32_Subtract
5204 #endif
5205 
5206 
5207 
5208 // Redirection
5209 #if QUESA_ALLOW_INLINE_APIS
5210 	#define Q3Vector2D_Set								Q3FastVector2D_Set
5211 	#define Q3Vector3D_Set								Q3FastVector3D_Set
5212 	#define Q3Point2D_Set								Q3FastPoint2D_Set
5213 	#define Q3Param2D_Set								Q3FastParam2D_Set
5214 	#define Q3RationalPoint3D_Set						Q3FastRationalPoint3D_Set
5215 	#define Q3Point3D_Set								Q3FastPoint3D_Set
5216 	#define Q3RationalPoint4D_Set						Q3FastRationalPoint4D_Set
5217 	#define Q3PolarPoint_Set							Q3FastPolarPoint_Set
5218 	#define Q3SphericalPoint_Set						Q3FastSphericalPoint_Set
5219 	#define Q3Vector2D_To3D								Q3FastVector2D_To3D
5220 	#define Q3Vector2D_ToRationalPoint3D				Q3FastVector2D_ToRationalPoint3D
5221 	#define Q3Vector3D_To2D								Q3FastVector3D_To2D
5222 	#define Q3RationalPoint3D_ToVector2D				Q3FastRationalPoint3D_ToVector2D
5223 	#define Q3Vector3D_ToRationalPoint4D				Q3FastVector3D_ToRationalPoint4D
5224 	#define Q3RationalPoint4D_ToVector3D				Q3FastRationalPoint4D_ToVector3D
5225 	#define Q3Point2D_To3D								Q3FastPoint2D_To3D
5226 	#define Q3RationalPoint3D_To2D						Q3FastRationalPoint3D_To2D
5227 	#define Q3Point3D_To4D								Q3FastPoint3D_To4D
5228 	#define Q3RationalPoint4D_To3D						Q3FastRationalPoint4D_To3D
5229 	#define Q3PolarPoint_ToPoint2D						Q3FastPolarPoint_ToPoint2D
5230 	#define Q3Vector2D_Dot								Q3FastVector2D_Dot
5231 	#define Q3Vector3D_Dot								Q3FastVector3D_Dot
5232 	#define Q3Vector2D_Cross							Q3FastVector2D_Cross
5233 	#define Q3Point2D_CrossProductTri					Q3FastPoint2D_CrossProductTri
5234 	#define Q3Vector3D_Cross							Q3FastVector3D_Cross
5235 	#define Q3Point3D_CrossProductTri					Q3FastPoint3D_CrossProductTri
5236 	#define Q3Vector2D_Length							Q3FastVector2D_Length
5237 	#define Q3Vector2D_LengthSquared					Q3FastVector2D_LengthSquared
5238 	#define Q3Vector3D_Length							Q3FastVector3D_Length
5239 	#define Q3Vector3D_LengthSquared					Q3FastVector3D_LengthSquared
5240 	#define Q3Point2D_Distance							Q3FastPoint2D_Distance
5241 	#define Q3Point2D_DistanceSquared					Q3FastPoint2D_DistanceSquared
5242 	#define Q3Param2D_Distance							Q3FastParam2D_Distance
5243 	#define Q3Param2D_DistanceSquared					Q3FastParam2D_DistanceSquared
5244 	#define Q3RationalPoint3D_Distance					Q3FastRationalPoint3D_Distance
5245 	#define Q3RationalPoint3D_DistanceSquared			Q3FastRationalPoint3D_DistanceSquared
5246 	#define Q3Point3D_Distance							Q3FastPoint3D_Distance
5247 	#define Q3Point3D_DistanceSquared					Q3FastPoint3D_DistanceSquared
5248 	#define Q3RationalPoint4D_Distance					Q3FastRationalPoint4D_Distance
5249 	#define Q3RationalPoint4D_DistanceSquared			Q3FastRationalPoint4D_DistanceSquared
5250 	#define Q3Vector2D_Negate							Q3FastVector2D_Negate
5251 	#define Q3Vector3D_Negate							Q3FastVector3D_Negate
5252 	#define Q3Vector2D_Scale							Q3FastVector2D_Scale
5253 	#define Q3Vector3D_Scale							Q3FastVector3D_Scale
5254 	#define Q3Vector2D_Normalize						Q3FastVector2D_Normalize
5255 	#define Q3Vector3D_Normalize						Q3FastVector3D_Normalize
5256 	#define Q3Vector2D_Add								Q3FastVector2D_Add
5257 	#define Q3Vector3D_Add								Q3FastVector3D_Add
5258 	#define Q3Vector2D_Subtract							Q3FastVector2D_Subtract
5259 	#define Q3Vector3D_Subtract							Q3FastVector3D_Subtract
5260 	#define Q3Point2D_Vector2D_Add						Q3FastPoint2D_Vector2D_Add
5261 	#define Q3Param2D_Vector2D_Add						Q3FastParam2D_Vector2D_Add
5262 	#define Q3Point3D_Vector3D_Add						Q3FastPoint3D_Vector3D_Add
5263 	#define Q3Point2D_Vector2D_Subtract					Q3FastPoint2D_Vector2D_Subtract
5264 	#define Q3Param2D_Vector2D_Subtract					Q3FastParam2D_Vector2D_Subtract
5265 	#define Q3Point3D_Vector3D_Subtract					Q3FastPoint3D_Vector3D_Subtract
5266 	#define Q3Point2D_Subtract							Q3FastPoint2D_Subtract
5267 	#define Q3Param2D_Subtract							Q3FastParam2D_Subtract
5268 	#define Q3Point3D_Subtract							Q3FastPoint3D_Subtract
5269 	#define Q3Point2D_RRatio							Q3FastPoint2D_RRatio
5270 	#define Q3Param2D_RRatio							Q3FastParam2D_RRatio
5271 	#define Q3Point3D_RRatio							Q3FastPoint3D_RRatio
5272 	#define Q3RationalPoint4D_RRatio					Q3FastRationalPoint4D_RRatio
5273 	#define Q3Quaternion_Set							Q3FastQuaternion_Set
5274 	#define Q3Quaternion_SetIdentity					Q3FastQuaternion_SetIdentity
5275 	#define Q3Quaternion_Copy							Q3FastQuaternion_Copy
5276 	#define Q3Quaternion_Dot							Q3FastQuaternion_Dot
5277 	#define Q3Quaternion_Normalize						Q3FastQuaternion_Normalize
5278 	#define Q3Quaternion_Invert							Q3FastQuaternion_Invert
5279 	#define Q3BoundingBox_Reset							Q3FastBoundingBox_Reset
5280 	#define Q3BoundingBox_Set							Q3FastBoundingBox_Set
5281 	#define Q3BoundingBox_Copy							Q3FastBoundingBox_Copy
5282 	#define Q3BoundingSphere_Reset						Q3FastBoundingSphere_Reset
5283 	#define Q3BoundingSphere_Set						Q3FastBoundingSphere_Set
5284 	#define Q3BoundingSphere_Copy						Q3FastBoundingSphere_Copy
5285 #endif
5286 
5287 #endif // QUESA_ALLOW_QD3D_EXTENSIONS
5288 
5289 
5290 
5291 
5292 
5293 //=============================================================================
5294 //      C++ postamble
5295 //-----------------------------------------------------------------------------
5296 #ifdef __cplusplus
5297 }
5298 #endif
5299 
5300 #endif
5301 
5302 
5303