1 //-----------------------------------------------------------------------------
2 // Fonctions math�matiques
3 //-----------------------------------------------------------------------------
4 
5 #ifndef __MATH_H__
6 #define __MATH_H__
7 
8 #include "types.h"
9 #include <math.h>
10 #include <stdlib.h>   // for rand
11 
12 // Enable assembly code for win32 compiler
13 #ifdef WIN32
14   #define ASM 1
15 #else
16   #define ASM 0
17 #endif
18 
19 #ifndef M_PI      // may already been defined
20   #define M_PI  3.1415926535897932384626433832795f    // matches value in gcc v2 math.h
21 #endif
22 #define M_TWO_PI  6.283185307179586476925286766559f
23 #define M_180_PI  57.295779513082320876798154814105f
24 #define M_PI_180  0.017453292519943295769236907684886f
25 
26 #define DEG2RAD(a) (a*M_PI_180)
27 #define RAD2DEG(a) (a*M_180_PI)
28 
29 #define MAKERGB(v,r,g,b) (v[0]=r;v[1]=g;v[2]=b)
30 #define MAKERGBA(v,r,g,b,a) (v[0]=r;v[1]=g;v[2]=b;v[3]=a)
31 
32 // Integer Math
33 /**
34  * Find the closest power of 2 that is >= N.
35  */
36 DWORD NextPowerOfTwo(DWORD N);
37 DWORD Log2(DWORD val);
38 
39 // vector encoding and decoding
40 //#define NUMVERTEXNORMALS  216
41 //extern  vec3_t  bytedirs[NUMVERTEXNORMALS];
42 //int DirToByte( vec3_t dir );
43 //void ByteToDir( int b, vec3_t dir );
44 
45 // Floating Point Math
46 #define FastTan(a) (FastSin(a)/FastCos(a))
47 #ifdef WIN32
48   float __fastcall FastAbs(float a);
49   float __fastcall FastSin(float a);
50   float __fastcall FastCos(float a);
51   float __fastcall InverseSqrt(float a);
52 #else
53   float FastAbs(float a);
54   float FastSin(float a);
55   float FastCos(float a);
56   float InverseSqrt(float a);
57 #endif
58 
59 #ifndef min
60   #define min(a,b) (a<b?a:b)
61 #endif
62 
63 #ifndef max
64   #define max(a,b) (a>b?a:b)
65 #endif
66 
67 #define bound(a,b,c) ((a) >= (c) ? (a) : (b) < (a) ? (a) : (b) > (c) ? (c) : (b))
68 
69 // clamps a (must be lvalue) to [b..c] range
70 #define clamp(a,b,c) ((b) >= (c) ? (a)=(b) : (a) < (b) ? (a)=(b) : (a) > (c) ? (a)=(c) : (a))
71 
72 // Reciprocal square root
73 float rSqrt(float number);
74 
75 // Aproximations:
76 #define Sqrt(n)   (n*rSqrt(n))
77 #ifdef WIN32
78   float __fastcall FastSqrt(float a);
79 #else
80   float FastSqrt(float a);
81 #endif
82 
83 #define rnd(a,b) ((b-(a))*((long double) rand()/32767)+(a))
84 #define random()  ((rand () & 0x7fff) / ((float)0x7fff))
85 #define crandom() (2.0 * (random() - 0.5))
86 
87 // Vector Math
88 
89 //  3d Vector macros:
90 #define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
91 
92 #define DotProduct(x,y)     ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
93 #define CrossProduct(v1,v2,cross) ((cross)[0]=(v1)[1]*(v2)[2]-(v1)[2]*(v2)[1],(cross)[1]=(v1)[2]*(v2)[0]-(v1)[0]*(v2)[2],(cross)[2]=(v1)[0]*(v2)[1]-(v1)[1]*(v2)[0])
94 
95 #define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
96 
97 #define VectorDot(x,y)        ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
98 #define VectorMult(a,b,c)     ((c)[0]=(a)[2]*(b)[3]-(a)[3]*(b)[2],(c)[1]=(a)[3]*(b)[1]-(a)[1]*(b)[3],(c)[2]=(a)[1]*(b)[2]-(a)[2]*(b)[1])
99 #define VectorSub(a,b,c)      ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2])
100 #define VectorAdd(a,b,c)      ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2])
101 #define VectorCopy(a,b)       ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2])
102 #define VectorScale(v, s, o)    ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s))
103 #define VectorMA(v, s, b, o)    ((o)[0]=(v)[0]+(b)[0]*(s),(o)[1]=(v)[1]+(b)[1]*(s),(o)[2]=(v)[2]+(b)[2]*(s))
104 #define VectorAvrg(a,b,c)     ((c)[0]=((a)[0]+(b)[0])/2,(c)[1]=((a)[1]+(b)[1])/2,(c)[2]=((a)[2]+(b)[2])/2)
105 #define VectorFakeMod(v)      (v[0]*v[0]+v[1]*v[1]+v[2]*v[2])
106 #define VectorMDot(a, b, c)     (a[0]*(b[0]-c[0])+a[1]*(b[1]-c[1])+a[2]*(b[2]-c[2]))
107 #define VectorClear(a)        ((a)[0]=(a)[1]=(a)[2]=0)
108 #define VectorNegate(a,b)     ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2])
109 #define VectorSet(v, x, y, z)   ((v)[0]=(x), (v)[1]=(y), (v)[2]=(z))
110 #define VectorCompare(v1,v2)    ((v1)[0]==(v2)[0] && (v1)[1]==(v2)[1] && (v1)[2]==(v2)[2])
111 #define VectorLength(v)       (sqrtf(DotProduct((v),(v))))
112 #define VectorInverse(v)      ((v)[0]=-(v)[0],(v)[1]=-(v)[1],(v)[2]=-(v)[2])
113 #define Vector4Set(v, a, b, c, d) ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3]=(d))
114 #define Vector4Copy(a,b)      ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
115 #define Vector4Scale(v,s,o)     ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s),(o)[3]=(v)[3]*(s))
116 #define Vector4Add(a,b,c)     ((c)[0]=(((a[0])+(b[0]))),(c)[1]=(((a[1])+(b[1]))),(c)[2]=(((a[2])+(b[2]))),(c)[3]=(((a[3])+(b[3]))))
117 #define Vector4Avg(a,b,c)     ((c)[0]=(((a[0])+(b[0]))*0.5f),(c)[1]=(((a[1])+(b[1]))*0.5f),(c)[2]=(((a[2])+(b[2]))*0.5f),(c)[3]=(((a[3])+(b[3]))*0.5f))
118 #define Vector4Clear(a)       ((a)[0]=(a)[1]=(a)[2]=(a)[3]=0)
119 
120 #define Vector2Set(v, x, y)     ((v)[0]=(x),(v)[1]=(y))
121 #define Vector2Clear(a)       ((a)[0]=(a)[1]=0)
122 #define Vector2Copy(a,b)      ((b)[0]=(a)[0],(b)[1]=(a)[1])
123 #define Vector2Avg(a,b,c)     ((c)[0]=(((a[0])+(b[0]))*0.5f),(c)[1]=(((a[1])+(b[1]))*0.5f))
124 #define SnapVector(v)       {v[0]=(int)v[0];v[1]=(int)v[1];v[2]=(int)v[2];}
125 
126 //  2d Vector macros:
127 #define TexcoordAdd(a,b,c)      ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1])
128 #define TexcoordScale(v, s, o)    ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s))
129 #define TexcoordCopy(a,b)     ((b)[0]=(a)[0],(b)[1]=(a)[1])
130 #define TexcoordClear(a)      ((a)[0]=(a)[1]=0)
131 #define TexcoordSet(v, x, y)    ((v)[0]=(x),(v)[1]=(y))
132 
133 //  4d Vector macros:
134 #define ColorAdd(a,b,c)       ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2],(c)[3]=(a)[3]+(b)[3])
135 #define ColorScale(v, s, o)     ((o)[0]=(v)[0]*(s),(o)[1]=(v)[1]*(s),(o)[2]=(v)[2]*(s),(o)[3]=(v)[3]*(s))
136 #define ColorCopy(a,c)        ((c)[0]=(a)[0],(c)[1]=(a)[1],(c)[2]=(a)[2],(c)[3]=(a)[3])
137 #define ColorSet(v, a, b, c, d)   ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3]=(d))
138 #define ColorClear(a)       ((a)[0]=(a)[1]=(a)[2]=(a)[3]=0)
139 
140 // BBox macros:
141 #define BoxCopy(a,b)        ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3],(b)[4]=(a)[4],(b)[5]=(a)[5])
142 
143 #define min3(a,b,c)         (min(min(a,b),c))
144 #define max3(a,b,c)         (max(max(a,b),c))
145 
146 // optimized dot product
147 #if 0
148 #ifndef DotProduct
149   #if ASM
150     #pragma warning (disable: 4035)
151     //__declspec( naked )
152     float __cdecl DotProduct(const vec3_t v1, const vec3_t v2);
153     #pragma warning( default: 4035 )
154   #else
155     #ifdef WIN32
156       float __cdecl DotProduct(const vec3_t v1, const vec3_t v2);
157     #else
158       float DotProduct(const vec3_t v1, const vec3_t v2);
159     #endif
160   #endif
161 #endif
162 #endif
163 
164 // Matrix initialisation
165 void InitMat3x3(float *A);
166 void InitMat4x4(float *A);
167 
168 // Matrix multiplication
169 void MultMat3x3(float *A, float *B, float *C);
170 void MultMat4x4(float *A, float *B, float *C);
171 
172 // Vector and matrix multiplication
173 void MultVect3x3(float *A, float *v, float *dest);
174 void MultVect4x4(float *A, float *v, float *dest);
175 
176 /**
177  * Fast normalization of 3 component vector (does not test if the vector has 0 length)
178  */
179 void FastNormVect3(float *v);
180 
181 /**
182  * Fast normalization of 2 component vector (does not test if the vector has 0 length)
183  */
184 void FastNormVect2(float *v);
185 
186 /**
187  * Slow normalization that returns the norm
188  */
189 vec_t VectorNormalize(vec3_t v);
190 vec_t VectorNormalize2(vec3_t v, vec3_t out);
191 void VectorNormalizeFast(vec3_t v);
192 float ColorNormalize(vec3_t in, vec3_t out);
193 
194 /**
195  * Cross Product
196  */
197 #ifndef CrossProduct
198 void CrossProduct(const vec3_t v1, const vec3_t v2, vec3_t cross);
199 #endif
200 
201 //-----------------------------------------------------------------------------
202 // Bezier curves (bugged?) functions
203 //-----------------------------------------------------------------------------
204 
205 // Three control point Bezier interpolation
206 // mu ranges from 0 to 1, start to end of the curve
207 void BezierCurve3(vec3_t p1, vec3_t p2, vec3_t p3, float mu, vec3_t dest);
208 // Four control point Bezier interpolation
209 // mu ranges from 0 to 1, start to end of curve
210 void BezierCurve4(vec3_t p1, vec3_t p2, vec3_t p3, vec3_t p4, float mu, vec3_t dest);
211 
212 // General Bezier curve
213 // Number of control points is n
214 // 0 <= mu < 1    IMPORTANT, the last point is not computed
215 void BezierCurveN(vec3_t *p, int n, float mu, vec3_t dest);
216 
217 //-----------------------------------------------------------------------------
218 // Bounding box related functions
219 //-----------------------------------------------------------------------------
220 
221 /**
222  * Calculate the bounding box of a mesh surface
223  * @param surf the concerned mesh surface
224  */
225 void CalcFaceBounds(Surface *surf);
226 
227 /**
228  * Redefine a bounding box with a new vertex.
229  * The bounding box is only updated if the vertex is out of the box.
230  * @param v The vertex to check with bounding box
231  * @param bbox The bounding box that will be updated if needed.
232  */
233 void AddPointToBounds(vec3_t v, bboxf_t bbox);
234 void AddPointToBounds(vec3_t v, vec3_t mins, vec3_t maxs);
235 
236 /**
237  * Clears the values of a bounding box.
238  * Note: After having been cleared, a bounding box can't be used for frustum
239  * test.
240  * @param bbox The bounding box to clear.
241  */
242 void ClearBounds(bboxf_t bbox);
243 void ClearBounds(vec3_t mins, vec3_t maxs);
244 bool BoundsIntersect(bboxf_t bbox, vec3_t mins2, vec3_t maxs2);
245 bool BoundsIntersect(vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2);
246 bool BoundsAndSphereIntersect(bboxf_t bbox, vec3_t centre, float radius);
247 bool BoundsAndSphereIntersect(vec3_t mins, vec3_t maxs, vec3_t centre, float radius);
248 bool PointInBounds(vec3_t point, bboxf_t bbox);
249 bool GetIntersection(bboxf_t bbox1, bboxf_t bbox2, bboxf_t dest);
250 
251 //-----------------------------------------------------------------------------
252 // Plane operations
253 //-----------------------------------------------------------------------------
254 
255 /**
256  * Generate a plane given 3 points.
257  * The normal will point out of the clock for clockwise ordered points.
258  * @return false if the triangle is degenrate
259  */
260 bool PlaneFromPoints(vec4_t plane, const vec3_t a, const vec3_t b, const vec3_t c);
261 void PlaneFromPoints(vertex_t verts[3], cplane_t *plane);
262 void PlaneFromPoints(vec3_t verts[3], cplane_t *plane);
263 
264 void CategorizePlane(cplane_t *plane);
265 
266 // returns the side of the plane in wich the box is
267 #if !ASM
268   int BoxOnPlaneSide(vec3_t emins, vec3_t emaxs, struct cplane_s *p);
269 #else
270   #pragma warning( disable: 4035 )
271   int BoxOnPlaneSide(vec3_t emins, vec3_t emaxs, struct cplane_s *p);
272   #pragma warning( default: 4035 )
273 #endif
274 #define BOX_ON_PLANE_SIDE(emins, emaxs, p)  \
275   (((p)->type < 3)?           \
276   (                   \
277     ((p)->dist <= (emins)[(p)->type])?  \
278       1               \
279     :                 \
280     (                 \
281       ((p)->dist >= (emaxs)[(p)->type])?\
282         2             \
283       :               \
284         3             \
285     )                 \
286   )                   \
287   :                   \
288     BoxOnPlaneSide((emins), (emaxs), (p)))
289 
290 /**
291  * Get the distance between a point and a plane along the plane normal.
292  * @param v The point vector.
293  * @param p The concerned plane.
294  * @return The distance between point and plane along the plane normal.
295  */
296 float PointDistance(vec3_t v, cplane_t* p);
297 
298 // matrix classes
299 
300 /**
301  * 3x2 matrix in homogeneus coordinates.
302  * Used for texture transformations.
303  */
304 class Mat3x2
305 {
306   public:
307 
Mat3x2(void)308     Mat3x2(void)
309     {
310     }
311 
Mat3x2(float * p)312     Mat3x2(float *p)
313     {
314       data[0][0] = p[0];
315       data[0][1] = p[1];
316       data[1][0] = p[2];
317       data[1][1] = p[3];
318       data[2][0] = p[4];
319       data[2][1] = p[5];
320     }
321 
Mat3x2(const Mat3x2 & src)322     Mat3x2(const Mat3x2& src)
323     {
324       data[0][0] = src.data[0][0];
325       data[0][1] = src.data[0][1];
326       data[1][0] = src.data[1][0];
327       data[1][1] = src.data[1][1];
328       data[2][0] = src.data[2][0];
329       data[2][1] = src.data[2][1];
330     }
331 
~Mat3x2(void)332     ~Mat3x2(void)
333     {
334     }
335 
336     const Mat3x2 &operator=(const Mat3x2 &src)
337     {
338       Copy(src);
339       return *this;
340     }
341 
GetData(void)342     const float *GetData(void) const
343     {
344       return &data[0][0];
345     }
346 
GetData(void)347     float *GetData(void)
348     {
349       return &data[0][0];
350     }
351 
Set(int i1,int i2,float f)352     void Set(int i1, int i2, float f)
353     {
354       data[i1][i2] = f;
355     }
356 
Get(int i1,int i2)357     float Get(int i1, int i2) const
358     {
359       return data[i1][i2];
360     }
361 
Copy(const Mat3x2 & src)362     void Copy (const Mat3x2 &src)
363     {
364       data[0][0] = src.data[0][0];
365       data[0][1] = src.data[0][1];
366       data[1][0] = src.data[1][0];
367       data[1][1] = src.data[1][1];
368       data[2][0] = src.data[2][0];
369       data[2][1] = src.data[2][1];
370     }
371 
Copy(const float * p)372     void Copy (const float *p)
373     {
374       data[0][0] = p[0];
375       data[0][1] = p[1];
376       data[1][0] = p[2];
377       data[1][1] = p[3];
378       data[2][0] = p[4];
379       data[2][1] = p[5];
380     }
381 
Identity(void)382     void Identity(void)
383     {
384       data[0][0] = 1.0f;
385       data[0][1] = 0.0f;
386       data[1][0] = 0.0f;
387       data[1][1] = 1.0f;
388       data[2][0] = 0.0f;
389       data[2][1] = 0.0f;
390     }
391 
Zero(void)392     void Zero(void)
393     {
394       data[0][0] = 0.0f;
395       data[0][1] = 0.0f;
396       data[1][0] = 0.0f;
397       data[1][1] = 0.0f;
398       data[2][0] = 0.0f;
399       data[2][1] = 0.0f;
400     }
401 
Add(const Mat3x2 & a,const Mat3x2 & b)402     void Add(const Mat3x2 &a, const Mat3x2 &b)
403     {
404       data[0][0] = a.data[0][0] + b.data[0][0];
405       data[0][1] = a.data[0][1] + b.data[0][1];
406       data[1][0] = a.data[1][0] + b.data[1][0];
407       data[1][1] = a.data[1][1] + b.data[1][1];
408       data[2][0] = a.data[2][0] + b.data[2][0];
409       data[2][1] = a.data[2][1] + b.data[2][1];
410     }
411 
Sub(const Mat3x2 & a,const Mat3x2 & b)412     void Sub(const Mat3x2 &a, const Mat3x2 &b)
413     {
414       data[0][0] = a.data[0][0] - b.data[0][0];
415       data[0][1] = a.data[0][1] - b.data[0][1];
416       data[1][0] = a.data[1][0] - b.data[1][0];
417       data[1][1] = a.data[1][1] - b.data[1][1];
418       data[2][0] = a.data[2][0] - b.data[2][0];
419       data[2][1] = a.data[2][1] - b.data[2][1];
420     }
421 
ScaleMatrix(const vec2_t v)422     void ScaleMatrix(const vec2_t v)
423     {
424       data[0][0] = v[0];
425       data[0][1] = 0.0f;
426       data[1][0] = 0.0f;
427       data[1][1] = v[1];
428       data[2][0] = 0.0f;
429       data[2][1] = 0.0f;
430     }
431 
ScaleMatrix(float f)432     void ScaleMatrix(float f)
433     {
434       data[0][0] = f;
435       data[0][1] = 0.0f;
436       data[1][0] = 0.0f;
437       data[1][1] = f;
438       data[2][0] = 0.0f;
439       data[2][1] = 0.0f;
440     }
441 
TranslationMatrix(const vec2_t v)442     void TranslationMatrix(const vec2_t v)
443     {
444       data[0][0] = 1.0f;
445       data[0][1] = 0.0f;
446       data[1][0] = 0.0f;
447       data[1][1] = 1.0f;
448       data[2][0] = v[0];
449       data[2][1] = v[1];
450     }
451 
RotationMatrix(float theta)452     void RotationMatrix(float theta)
453     {
454       float cost, sint;
455 
456       cost = FastCos(theta);
457       sint = FastSin(theta);
458 
459       data[0][0] = cost;
460       data[0][1] = -sint;
461       data[1][0] = sint;
462       data[1][1] = cost;
463       data[2][0] = 0.0f;
464       data[2][1] = 0.0f;
465     }
466 
Multiply(const Mat3x2 & a,const Mat3x2 & b)467     void Multiply(const Mat3x2 &a, const Mat3x2 &b)
468     {
469       data[0][0] = a.data[0][0] * b.data[0][0] + a.data[0][1] * b.data[1][0];
470       data[0][1] = a.data[0][0] * b.data[0][1] + a.data[0][1] * b.data[1][1];
471 
472       data[1][0] = a.data[1][0] * b.data[0][0] + a.data[1][1] * b.data[1][0];
473       data[1][1] = a.data[1][0] * b.data[0][1] + a.data[1][1] * b.data[1][1];
474 
475       data[2][0] = a.data[2][0] + b.data[2][0];
476       data[2][1] = a.data[2][1] + b.data[2][1];
477     }
478 
479     // transform 2d point
TransformPoint(const vec2_t v,vec2_t dest)480     void TransformPoint(const vec2_t v, vec2_t dest)
481     {
482       #ifndef WIN32
483         dest[0] = v[0]*data[0][0] + v[1]*data[1][0] + data[2][0];
484         dest[1] = v[0]*data[0][1] + v[1]*data[1][1] + data[2][1];
485       #else
486         __asm{
487           mov eax, DWORD PTR this
488           mov ebx, DWORD PTR v
489           mov ecx, DWORD PTR dest
490 
491           fld   DWORD PTR [ebx]
492           fmul  DWORD PTR [eax+4]     // v[0] * data[0][1]
493           fld   DWORD PTR [ebx]
494           fmul  DWORD PTR [eax]     // v[0] * data[0][0]
495           fld   DWORD PTR [ebx+4]
496           fmul  DWORD PTR [eax+12]    // v[1] * data[1][1]
497           fld   DWORD PTR [ebx+4]
498           fmul  DWORD PTR [eax+8]     // v[1] * data[1][0]
499           faddp ST(2), ST         // v[0] * data[1][0] + v[1] * data[0][0]
500           faddp ST(2), ST         // v[0] * data[1][1] + v[1] * data[0][1]
501           fadd  DWORD PTR [eax+16]
502           fstp  DWORD PTR [ecx]     // dest[0] = v[0]*data[0][0] + v[1]*data[1][0] + data[2][0];
503           fadd  DWORD PTR [eax+20]
504           fstp  DWORD PTR [ecx+4]     // dest[0] = v[0]*data[0][0] + v[1]*data[1][0] + data[2][0];
505         }
506       #endif
507     }
508 
509     // transform 2d point with turbulences
TransformPointX(const vec3_t v,vec2_t dest)510     void TransformPointX(const vec3_t v, vec2_t dest)
511     {
512       #ifndef WIN32
513         dest[0] = v[0]*data[0][0] + v[1]*data[1][0] + FastSin(v[0])*data[2][0];
514         dest[1] = v[0]*data[0][1] + v[1]*data[1][1] + FastSin(v[1])*data[2][1];
515       #else
516         __asm
517         {
518           mov eax, DWORD PTR this
519           mov ebx, DWORD PTR v
520           mov ecx, DWORD PTR dest
521 
522           //fld   DWORD PTR [ebx]       // x
523           //fld   DWORD PTR [ebx+4]     // x y
524           //fld   st(0)           // x y y
525           //fxch  st(2)           // y y x
526           //fld   st(0)           // y y x x
527 
528           fld   DWORD PTR [ebx]
529           fmul  DWORD PTR [eax]     // v[0] * data[0][0]
530 
531           fld   DWORD PTR [ebx]
532           fmul  DWORD PTR [eax+4]     // v[0] * data[0][1]
533 
534           fld   DWORD PTR [ebx+4]
535           fmul  DWORD PTR [eax+8]     // v[1] * data[1][0]
536 
537           fld   DWORD PTR [ebx+4]
538           fmul  DWORD PTR [eax+12]    // v[1] * data[1][1]
539 
540           fld   DWORD PTR [ebx]
541           fsin
542           fmul  DWORD PTR [eax+16]    // sin(v[0]) * data[2][0]
543 
544           fld   DWORD PTR [ebx+4]
545           fsin
546           fmul  DWORD PTR [eax+20]    // sin(v[0]) * data[2][1]
547 
548           faddp ST(2), ST
549           faddp ST(2), ST
550           faddp ST(2), ST
551           faddp ST(2), ST
552           fxch  ST(1)
553 
554           fstp  DWORD PTR [ecx]     // dest[0] = v[0]*data[0][0] + v[1]*data[1][0] + data[2][0];
555           fstp  DWORD PTR [ecx+4]     // dest[0] = v[0]*data[0][0] + v[1]*data[1][0] + data[2][0];
556         }
557       #endif
558     }
559 
560   protected:
561     float data[3][2];
562 };
563 
564 /**
565  * 3x3 matrix class.
566  */
567 class Mat3x3
568 {
569   public:
570 
571     Mat3x3(void);
572     Mat3x3(float*);
573     Mat3x3(const Mat3x3& rhs);
574     ~Mat3x3(void);
575     const Mat3x3 &operator=(const Mat3x3 &src);
576 
GetData(void)577     const float *GetData(void) const
578     {
579       return &data[0][0];
580     }
581 
GetData(void)582     float *GetData(void)
583     {
584       return &data[0][0];
585     }
586 
587     void  Set(int i1, int i2, float);
588     float Get(int i1, int i2) const;
589 
590 
591   protected:
592     float data[3][3];
593 };
594 
595 /**
596  * 4x4 matrix class.
597  */
598 class Mat4x4
599 {
600   public:
601 
602     Mat4x4(void);
603     Mat4x4(float*);
604     Mat4x4(const Mat4x4& rhs);
605     ~Mat4x4(void);
606     const Mat4x4 &operator=(const Mat4x4 &src);
607 
GetData(void)608     const float *GetData(void) const
609     {
610       return &data[0][0];
611     }
612 
GetData(void)613     float *GetData(void)
614     {
615       return &data[0][0];
616     }
617 
618     void  Set(int i1, int i2, float);
619     float Get(int i1, int i2) const;
620 
621 
622   protected:
623     float data[4][4];
624 };
625 
626 #endif  /* __MATH_H__ */
627