root/trunk/orca/math3d.c

Revision 94, 7.1 kB (checked in by krobillard, 2 years ago)

All natives now use the OR_NATIVE macro.

Line 
1 /*============================================================================
2     ORCA Interpreter
3     Copyright (C) 2005-2006  Karl Robillard
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Lesser General Public
7     License as published by the Free Software Foundation; either
8     version 2.1 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Lesser General Public License for more details.
14
15     You should have received a copy of the GNU Lesser General Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 ===========================================================================*/
19
20 #ifdef OR_CONFIG_MATH3D
21
22
23 #include "ovalue.h"
24 #include "math3d.h"
25 #include "os.h"
26 #include "os_math.h"
27
28
29 enum eMatrixIndex
30 {
31     k00 = 0,
32     k01,
33     k02,
34     k03,
35     k10,
36     k11,
37     k12,
38     k13,
39     k20,
40     k21,
41     k22,
42     k23,
43     k30,
44     k31,
45     k32,
46     k33,
47
48     kX = 12,
49     kY,
50     kZ
51 };
52
53
54 static float _identity[16] =
55 {
56     1.0f, 0.0f, 0.0f, 0.0f,
57     0.0f, 1.0f, 0.0f, 0.0f,
58     0.0f, 0.0f, 1.0f, 0.0f,
59     0.0f, 0.0f, 0.0f, 1.0f
60 };
61
62
63 void orLoadIdentity( float* mat )
64 {
65     memCpy( mat, _identity, 16 * sizeof(float) );
66 }
67
68
69 void orLoadRotation( float* mat, const float* axis, float radians )
70 {
71     float x, y, z;
72     float c, s, t;
73
74     x = axis[0];
75     y = axis[1];
76     z = axis[2];
77
78     c = mathCosineF( radians );
79     s = mathSineF( radians );
80     t = 1.0f - c;
81
82     mat[ 0 ] = t*x*x + c;
83     mat[ 1 ] = t*x*y + s*z;
84     mat[ 2 ] = t*x*z - s*y;
85     mat[ 3 ] = 0.0f;
86
87     mat[ 4 ] = t*x*y - s*z;
88     mat[ 5 ] = t*y*y + c;
89     mat[ 6 ] = t*y*z + s*x;
90     mat[ 7 ] = 0.0f;
91
92     mat[  8 ] = t*x*z + s*y;
93     mat[  9 ] = t*y*z - s*x;
94     mat[ 10 ] = t*z*z + c;
95     mat[ 11 ] = 0.0f;
96
97     mat[ 12 ] = 0.0f;
98     mat[ 13 ] = 0.0f;
99     mat[ 14 ] = 0.0f;
100     mat[ 15 ] = 1.0f;
101 }
102
103
104 /*
105   Result can be the same matrix as A, but not B.
106 */
107 void orMatrixMult( const float* a, const float* b, float* result )
108 {
109 #define A(col,row)  a[(col<<2)+row]
110 #define R(col,row)  result[(col<<2)+row]
111
112     int i;
113     for( i = 0; i < 4; i++ )
114     {
115         float ai0=A(0,i), ai1=A(1,i), ai2=A(2,i), ai3=A(3,i);
116         R(0,i) = ai0 * b[k00] + ai1 * b[k01] + ai2 * b[k02] + ai3 * b[k03];
117         R(1,i) = ai0 * b[k10] + ai1 * b[k11] + ai2 * b[k12] + ai3 * b[k13];
118         R(2,i) = ai0 * b[k20] + ai1 * b[k21] + ai2 * b[k22] + ai3 * b[k23];
119         R(3,i) = ai0 * b[k30] + ai1 * b[k31] + ai2 * b[k32] + ai3 * b[k33];
120     }
121 }
122
123
124 void orTransLocal( float* mat, float x, float y, float z )
125 {
126     if( x )
127     {
128         mat[ kX ] += mat[ k00 ] * x;
129         mat[ kY ] += mat[ k01 ] * x;
130         mat[ kZ ] += mat[ k02 ] * x;
131     }
132     if( y )
133     {
134         mat[ kX ] += mat[ k10 ] * y;
135         mat[ kY ] += mat[ k11 ] * y;
136         mat[ kZ ] += mat[ k12 ] * y;
137     }
138     if( z )
139     {
140         mat[ kX ] += mat[ k20 ] * z;
141         mat[ kY ] += mat[ k21 ] * z;
142         mat[ kZ ] += mat[ k22 ] * z;
143     }
144 }
145
146
147 /**
148   Transpose 3x3 submatrix to negate rotation.
149 */
150 void orMatrixTranspose( float* mat, const float* a )
151 {
152     mat[ k00 ] = a[ k00 ];
153     mat[ k01 ] = a[ k10 ];
154     mat[ k02 ] = a[ k20 ];
155     mat[ k03 ] = a[ k03 ];
156
157     mat[ k10 ] = a[ k01 ];
158     mat[ k11 ] = a[ k11 ];
159     mat[ k12 ] = a[ k21 ];
160     mat[ k13 ] = a[ k13 ];
161
162     mat[ k20 ] = a[ k02 ];
163     mat[ k21 ] = a[ k12 ];
164     mat[ k22 ] = a[ k22 ];
165     mat[ k23 ] = a[ k23 ];
166 }
167
168
169 /**
170   Negates rotation and translation.
171 */
172 void orMatrixInverse( float* mat, const float* a )
173 {
174     orMatrixTranspose( mat, a );
175
176     // Negate translation.
177
178     mat[ kX ] = - (a[kX] * a[k00]) - (a[kY] * a[k01]) - (a[kZ] * a[k02]);
179     mat[ kY ] = - (a[kX] * a[k10]) - (a[kY] * a[k11]) - (a[kZ] * a[k12]);
180     mat[ kZ ] = - (a[kX] * a[k20]) - (a[kY] * a[k21]) - (a[kZ] * a[k22]);
181     mat[ k33 ] = a[ k33 ];
182 }
183
184
185 /*--------------------------------------------------------------------------*/
186
187
188 /**
189   Returns the distance from vecA to vecB.
190 */
191 float orDistance( const float* vecA, const float* vecB )
192 {
193     float dx, dy, dz;
194
195     dx = vecB[0] - vecA[0];
196     dy = vecB[1] - vecA[1];
197     dz = vecB[2] - vecA[2];
198
199     return mathSqrtF( dx * dx + dy * dy + dz * dz );
200 }
201
202
203 /**
204   Applies the entire matrix to this point.
205 */
206 void orTransform( float* pnt, const float* mat )
207 {
208     float ox, oy, oz;
209
210     ox = pnt[0];
211     oy = pnt[1];
212     oz = pnt[2];
213
214     pnt[0] = mat[ k00 ] * ox + mat[ k10 ] * oy + mat[ k20 ] * oz + mat[ k30 ];
215     pnt[1] = mat[ k01 ] * ox + mat[ k11 ] * oy + mat[ k21 ] * oz + mat[ k31 ];
216     pnt[2] = mat[ k02 ] * ox + mat[ k12 ] * oy + mat[ k22 ] * oz + mat[ k32 ];
217 }
218
219
220 /**
221   Applies the upper 3x3 portion of the matrix to this point.
222 */
223 void orTransform3x3( float* pnt, const float* mat )
224 {
225     float ox, oy, oz;
226
227     ox = pnt[0];
228     oy = pnt[1];
229     oz = pnt[2];
230
231     pnt[0] = mat[ k00 ] * ox + mat[ k10 ] * oy + mat[ k20 ] * oz;
232     pnt[1] = mat[ k01 ] * ox + mat[ k11 ] * oy + mat[ k21 ] * oz;
233     pnt[2] = mat[ k02 ] * ox + mat[ k12 ] * oy + mat[ k22 ] * oz;
234 }
235
236
237 /**
238   Result can be the same as either a or b.
239 */
240 void orReflect( const float* a, const float* b, float* result )
241 {
242     float dot2 = orDot(a, b) * 2.0f;
243
244     result[0] = a[0] - (b[0] * dot2);
245     result[1] = a[1] - (b[1] * dot2);
246     result[2] = a[2] - (b[2] * dot2);
247 }
248
249
250 void orNormalize( float* vec )
251 {
252     float x, y, z;
253     float len;
254
255     x = vec[0];
256     y = vec[1];
257     z = vec[2];
258
259     len = mathSqrtF( x * x + y * y + z * z );
260     if( len )
261     {
262         len = 1.0f / len;
263         vec[0] = x * len;
264         vec[1] = y * len;
265         vec[2] = z * len;
266     }
267 }
268
269
270 /*--------------------------------------------------------------------------*/
271
272
273 /**
274   Returns zero if invalid values were found.
275 */
276 int orLoadVectorBlock( float* vec, int count, OValue* blkV )
277 {
278 #define VEND    if(vec == vend) break
279
280     OBlock* blk = orBLOCK(blkV);
281     OValue* it  = blk->values + blkV->series.it;
282     OValue* end = blk->values + blk->used;
283     float* vend = vec + count;
284     int ok = 1;
285
286     while( it != end )
287     {
288         if( it->type == OT_INTEGER )
289         {
290             *vec++ = (float) orInt(it);
291             VEND;
292         }
293         else if( it->type == OT_DECIMAL )
294         {
295             *vec++ = (float) orDecimal(it);
296             VEND;
297         }
298 #if 0
299         else if( it->type == OT_VEC3 )
300         {
301             *vec++ = it->vec3.x;
302             VEND;
303             *vec++ = it->vec3.y;
304             VEND;
305             *vec++ = it->vec3.z;
306             VEND;
307         }
308 #endif
309         else
310         {
311             ok = 0;
312         }
313
314         ++it;
315     }
316
317     return ok;
318 }
319
320
321 OR_NATIVE_PUB( orDotNative )
322 {
323     float* a = &a1->vec3.x;
324     float* b = &(a1 + 1)->vec3.x;
325
326     orSetTF( a1, OT_DECIMAL );
327     orDecimal(a1) = (double) orDot(a, b);
328 }
329
330
331 OR_NATIVE_PUB( orCrossNative )
332 {
333     float* a = &a1->vec3.x;
334     float* b = &(a1 + 1)->vec3.x;
335     float res[3];
336
337     orCross( a, b, res );
338     memCpy( &a1->vec3, res, 3 * sizeof(float) );
339 }
340
341
342 OR_NATIVE_PUB( orNormalizeNative )
343 {
344     orNormalize( &a1->vec3.x );
345 }
346
347
348 #endif
349
350 /* EOF */
Note: See TracBrowser for help on using the browser.