rmath3d 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,110 @@
1
+ /* -*- C -*- */
2
+ #ifndef RMATHMTX4_H_INCLUDED
3
+ #define RMATHMTX4_H_INCLUDED
4
+
5
+ #include "RType.h"
6
+
7
+ struct RVec3;
8
+ struct RVec4;
9
+ struct RQuat;
10
+
11
+ typedef struct RMtx4
12
+ {
13
+ union
14
+ {
15
+ /* NOTE : column-major */
16
+ struct
17
+ {
18
+ rmReal e00, e10, e20, e30;
19
+ rmReal e01, e11, e21, e31;
20
+ rmReal e02, e12, e22, e32;
21
+ rmReal e03, e13, e23, e33;
22
+ };
23
+ rmReal e[16];
24
+ };
25
+ } RMtx4;
26
+
27
+ #ifdef __cplusplus
28
+ extern "C" {
29
+ #endif
30
+
31
+ void RMtx4SetElements( RMtx4* out,
32
+ rmReal e00, rmReal e01, rmReal e02, rmReal e03,
33
+ rmReal e10, rmReal e11, rmReal e12, rmReal e13,
34
+ rmReal e20, rmReal e21, rmReal e22, rmReal e23,
35
+ rmReal e30, rmReal e31, rmReal e32, rmReal e33
36
+ );
37
+
38
+ void RMtx4SetElement( RMtx4* out, int row, int col, rmReal e );
39
+ rmReal RMtx4GetElement( const RMtx4* in, int row, int col );
40
+
41
+ void RMtx4GetRow( struct RVec4* out, const RMtx4* in, int row );
42
+ void RMtx4GetColumn( struct RVec4* out, const RMtx4* in, int col );
43
+
44
+ void RMtx4SetRow( struct RMtx4* out, const struct RVec4* in, int row );
45
+ void RMtx4SetColumn( struct RMtx4* out, const struct RVec4* in, int col );
46
+
47
+ void RMtx4GetUpper3x3( struct RMtx3* out, const struct RMtx4* in );
48
+ void RMtx4SetUpper3x3( struct RMtx4* out, const struct RMtx3* in );
49
+
50
+ void RMtx4Copy( RMtx4* out, const RMtx4* in );
51
+
52
+ void RMtx4Zero( RMtx4* out );
53
+ void RMtx4Identity( RMtx4* out );
54
+ rmReal RMtx4Determinant( const RMtx4* in );
55
+ void RMtx4Transpose( RMtx4* out, const RMtx4* in );
56
+ rmReal RMtx4Inverse( RMtx4* out, const RMtx4* in );
57
+
58
+ void RMtx4Translation( RMtx4* out, rmReal tx, rmReal ty, rmReal tz );
59
+ void RMtx4RotationX( RMtx4* out, rmReal radian );
60
+ void RMtx4RotationY( RMtx4* out, rmReal radian );
61
+ void RMtx4RotationZ( RMtx4* out, rmReal radian );
62
+ void RMtx4RotationAxis( RMtx4* out, const struct RVec3* axis, rmReal radian );
63
+ void RMtx4RotationQuaternion( RMtx4* out, const struct RQuat* q );
64
+ void RMtx4Scaling( RMtx4* out, rmReal sx, rmReal sy, rmReal sz );
65
+
66
+ int RMtx4Equal( const RMtx4* m1, const RMtx4* m2 );
67
+
68
+ void RMtx4Add( RMtx4* out, const RMtx4* m1, const RMtx4* m2 );
69
+ void RMtx4Sub( RMtx4* out, const RMtx4* m1, const RMtx4* m2 );
70
+ void RMtx4Mul( RMtx4* out, const RMtx4* m1, const RMtx4* m2 );
71
+ void RMtx4Scale( RMtx4* out, const RMtx4* m, rmReal f );
72
+
73
+ void RMtx4LookAtRH( RMtx4* out, const struct RVec3* eye, const struct RVec3* at, const struct RVec3* up );
74
+ void RMtx4PerspectiveRH( RMtx4* out, rmReal width, rmReal height, rmReal znear, rmReal zfar );
75
+ void RMtx4PerspectiveFovRH( RMtx4* out, rmReal fovy_radian, rmReal aspect, rmReal znear, rmReal zfar );
76
+ void RMtx4PerspectiveOffCenterRH( RMtx4* out, rmReal left, rmReal right, rmReal bottom, rmReal top, rmReal znear, rmReal zfar );
77
+ void RMtx4OrthoRH( RMtx4* out, rmReal width, rmReal height, rmReal znear, rmReal zfar );
78
+ void RMtx4OrthoOffCenterRH( RMtx4* out, rmReal left, rmReal right, rmReal bottom, rmReal top, rmReal znear, rmReal zfar );
79
+
80
+ #ifdef __cplusplus
81
+ }
82
+ #endif
83
+
84
+
85
+ #endif
86
+
87
+
88
+ /*
89
+ RMath : Ruby math module for 3D Applications
90
+ Copyright (c) 2008- vaiorabbit <http://twitter.com/vaiorabbit>
91
+
92
+ This software is provided 'as-is', without any express or implied
93
+ warranty. In no event will the authors be held liable for any damages
94
+ arising from the use of this software.
95
+
96
+ Permission is granted to anyone to use this software for any purpose,
97
+ including commercial applications, and to alter it and redistribute it
98
+ freely, subject to the following restrictions:
99
+
100
+ 1. The origin of this software must not be misrepresented; you must not
101
+ claim that you wrote the original software. If you use this software
102
+ in a product, an acknowledgment in the product documentation would be
103
+ appreciated but is not required.
104
+
105
+ 2. Altered source versions must be plainly marked as such, and must not be
106
+ misrepresented as being the original software.
107
+
108
+ 3. This notice may not be removed or altered from any source
109
+ distribution.
110
+ */
@@ -0,0 +1,367 @@
1
+ #include <math.h>
2
+ #include <string.h>
3
+
4
+ #include "RVec3.h"
5
+ #include "RMtx4.h"
6
+ #include "RQuat.h"
7
+
8
+ void
9
+ RQuatSetElements( RQuat* out, rmReal x, rmReal y, rmReal z, rmReal w )
10
+ {
11
+ RQuatSetX( out, x );
12
+ RQuatSetY( out, y );
13
+ RQuatSetZ( out, z );
14
+ RQuatSetW( out, w );
15
+ }
16
+
17
+ void
18
+ RQuatSetElement( RQuat* out, int at, rmReal f )
19
+ {
20
+ out->e[at] = f;
21
+ }
22
+
23
+ void
24
+ RQuatSetX( RQuat* out, rmReal x )
25
+ {
26
+ out->x = x;
27
+ }
28
+
29
+ void
30
+ RQuatSetY( RQuat* out, rmReal y )
31
+ {
32
+ out->y = y;
33
+ }
34
+
35
+ void
36
+ RQuatSetZ( RQuat* out, rmReal z )
37
+ {
38
+ out->z = z;
39
+ }
40
+
41
+ void
42
+ RQuatSetW( RQuat* out, rmReal w )
43
+ {
44
+ out->w = w;
45
+ }
46
+
47
+ void
48
+ RQuatSetXYZ( RQuat* out, const struct RVec3* v )
49
+ {
50
+ out->x = RVec3GetX( v );
51
+ out->y = RVec3GetY( v );
52
+ out->z = RVec3GetZ( v );
53
+ }
54
+
55
+
56
+ rmReal
57
+ RQuatGetElement( const RQuat* in, int at )
58
+ {
59
+ return in->e[at];
60
+ }
61
+
62
+ rmReal
63
+ RQuatGetX( const RQuat* in )
64
+ {
65
+ return in->x;
66
+ }
67
+
68
+ rmReal
69
+ RQuatGetY( const RQuat* in )
70
+ {
71
+ return in->y;
72
+ }
73
+
74
+ rmReal
75
+ RQuatGetZ( const RQuat* in )
76
+ {
77
+ return in->z;
78
+ }
79
+
80
+ rmReal
81
+ RQuatGetW( const RQuat* in )
82
+ {
83
+ return in->w;
84
+ }
85
+
86
+ void
87
+ RQuatGetXYZ( struct RVec3* out, const RQuat* in )
88
+ {
89
+ RVec3SetX( out, in->x );
90
+ RVec3SetY( out, in->y );
91
+ RVec3SetZ( out, in->z );
92
+ }
93
+
94
+
95
+ int
96
+ RQuatEqual( const RQuat* q1, const RQuat* q2 )
97
+ {
98
+ if ( 0 == memcmp( q1, q2, sizeof(RQuat) ) )
99
+ return !0;
100
+ else
101
+ return 0;
102
+ }
103
+
104
+ rmReal
105
+ RQuatDot( const RQuat* q1, const RQuat* q2 )
106
+ {
107
+ return q1->x*q2->x + q1->y*q2->y + q1->z*q2->z + q1->w*q2->w;
108
+ }
109
+
110
+
111
+ void
112
+ RQuatIdentity( RQuat* out )
113
+ {
114
+ RQuatSetElements( out, 0.0f, 0.0f, 0.0f, 1.0f );
115
+ }
116
+
117
+ void
118
+ RQuatCopy( RQuat* out, const RQuat* in )
119
+ {
120
+ out->x = in->x;
121
+ out->y = in->y;
122
+ out->z = in->z;
123
+ out->w = in->w;
124
+ }
125
+
126
+ void
127
+ RQuatNormalize( RQuat* out, const RQuat* in )
128
+ {
129
+ rmReal length = RQuatLength( in );
130
+ RQuatScale( out, in, 1.0f/length );
131
+ }
132
+
133
+ void
134
+ RQuatConjugate( RQuat* out, const RQuat* in )
135
+ {
136
+ out->x = -in->x;
137
+ out->y = -in->y;
138
+ out->z = -in->z;
139
+ out->w = in->w;
140
+ }
141
+
142
+ void
143
+ RQuatInverse( RQuat* out, const RQuat* in )
144
+ {
145
+ rmReal length_sq = RQuatLengthSq( in );
146
+ RQuat qc;
147
+
148
+ RQuatConjugate( &qc, in );
149
+ RQuatScale( &qc, &qc, 1.0f/length_sq );
150
+ RQuatCopy( out, &qc );
151
+ }
152
+
153
+
154
+ void
155
+ RQuatAdd( RQuat* out, const RQuat* q1, const RQuat* q2 )
156
+ {
157
+ out->x = q1->x + q2->x;
158
+ out->y = q1->y + q2->y;
159
+ out->z = q1->z + q2->z;
160
+ out->w = q1->w + q2->w;
161
+ }
162
+
163
+ void
164
+ RQuatSub( RQuat* out, const RQuat* q1, const RQuat* q2 )
165
+ {
166
+ out->x = q1->x - q2->x;
167
+ out->y = q1->y - q2->y;
168
+ out->z = q1->z - q2->z;
169
+ out->w = q1->w - q2->w;
170
+ }
171
+
172
+ /* http://en.wikipedia.org/wiki/Quaternion
173
+ */
174
+ void
175
+ RQuatMul( RQuat* out, const RQuat* q1, const RQuat* q2 )
176
+ {
177
+ rmReal x, y, z, w;
178
+ rmReal q1x = q1->x;
179
+ rmReal q1y = q1->y;
180
+ rmReal q1z = q1->z;
181
+ rmReal q1w = q1->w;
182
+ rmReal q2x = q2->x;
183
+ rmReal q2y = q2->y;
184
+ rmReal q2z = q2->z;
185
+ rmReal q2w = q2->w;
186
+
187
+ x = q1w*q2x + q1x*q2w + q1y*q2z - q1z*q2y;
188
+ y = q1w*q2y - q1x*q2z + q1y*q2w + q1z*q2x;
189
+ z = q1w*q2z + q1x*q2y - q1y*q2x + q1z*q2w;
190
+ w = q1w*q2w - q1x*q2x - q1y*q2y - q1z*q2z;
191
+
192
+ RQuatSetElements( out, x, y, z, w );
193
+ }
194
+
195
+ void
196
+ RQuatScale( RQuat* out, const RQuat* in, rmReal f )
197
+ {
198
+ out->x = in->x * f;
199
+ out->y = in->y * f;
200
+ out->z = in->z * f;
201
+ out->w = in->w * f;
202
+ }
203
+
204
+
205
+ rmReal
206
+ RQuatLength( const RQuat* in )
207
+ {
208
+ return rmSqrt( in->x*in->x + in->y*in->y + in->z*in->z + in->w*in->w );
209
+ }
210
+
211
+ rmReal
212
+ RQuatLengthSq( const RQuat* in )
213
+ {
214
+ return in->x*in->x + in->y*in->y + in->z*in->z + in->w*in->w;
215
+ }
216
+
217
+
218
+ /* Quaternion Algebra and Calculus
219
+ http://www.geometrictools.com/Documentation/Quaternions.pdf
220
+ */
221
+ void
222
+ RQuatSlerp( RQuat* out, const RQuat* q1, const RQuat* q2, rmReal t )
223
+ {
224
+ rmReal s1, s2;
225
+ rmReal it = 1.0f - t;
226
+ rmReal cosine = RQuatDot( q1, q2 );
227
+ RQuat qn1, qn2, qResult;
228
+ RQuatCopy( &qn1, q1 );
229
+ RQuatCopy( &qn2, q2 );
230
+
231
+ if ( cosine < 0.0f )
232
+ {
233
+ cosine *= -1.0f;
234
+ RQuatScale( &qn1, &qn1, -1.0f );
235
+ }
236
+
237
+ if ( (1.0f - cosine) > RMATH_TOLERANCE )
238
+ {
239
+ rmReal theta = rmAcos( cosine );
240
+ rmReal sin_theta = rmSin( theta );
241
+
242
+ s1 = rmSin( it * theta ) / sin_theta;
243
+ s2 = rmSin( t * theta ) / sin_theta;
244
+ }
245
+ else
246
+ {
247
+ s1 = it;
248
+ s2 = t;
249
+ }
250
+
251
+ RQuatScale( &qn1, &qn1, s1 );
252
+ RQuatScale( &qn2, &qn2, s2 );
253
+ RQuatAdd( &qResult, &qn1, &qn2 );
254
+
255
+ RQuatCopy( out, &qResult );
256
+ }
257
+
258
+
259
+ /* From Quaternion to Matrix and Back
260
+ http://www.intel.com/cd/ids/developer/asmo-na/eng/293748.htm
261
+ */
262
+ void
263
+ RQuatRotationMatrix( RQuat* out, const struct RMtx4* mtx )
264
+ {
265
+ #define I( r, c ) RMtx4GetElement( mtx, (r), (c) )
266
+
267
+ /* assumes:
268
+ - mtx represents rotation (contains no scaling factor)
269
+ - I(3,3) == 1.0f
270
+ */
271
+ rmReal diag00 = I( 0, 0 );
272
+ rmReal diag11 = I( 1, 1 );
273
+ rmReal diag22 = I( 2, 2 );
274
+
275
+ if ( diag00 + diag11 + diag22 > 0.0f )
276
+ {
277
+ rmReal t = diag00 + diag11 + diag22 + 1.0f;
278
+ rmReal s = 1.0f / ( rmSqrt( t ) * 2.0f );
279
+ RQuatSetW( out, s * t );
280
+ RQuatSetZ( out, (I(1,0) - I(0,1)) * s );
281
+ RQuatSetY( out, (I(0,2) - I(2,0)) * s );
282
+ RQuatSetX( out, (I(2,1) - I(1,2)) * s );
283
+ }
284
+ else if ( diag00 > diag11 && diag00 > diag22 )
285
+ {
286
+ rmReal t = diag00 - diag11 - diag22 + 1.0f;
287
+ rmReal s = 1.0f / ( rmSqrt( t ) * 2.0f );
288
+ RQuatSetX( out, s * t );
289
+ RQuatSetY( out, (I(1,0) + I(0,1)) * s );
290
+ RQuatSetZ( out, (I(0,2) + I(2,0)) * s );
291
+ RQuatSetW( out, (I(2,1) - I(1,2)) * s );
292
+ }
293
+ else if ( diag11 > diag22 )
294
+ {
295
+ rmReal t = -diag00 + diag11 - diag22 + 1.0f;
296
+ rmReal s = 1.0f / ( rmSqrt( t ) * 2.0f );
297
+ RQuatSetY( out, s * t );
298
+ RQuatSetX( out, (I(1,0) + I(0,1)) * s );
299
+ RQuatSetW( out, (I(0,2) - I(2,0)) * s );
300
+ RQuatSetZ( out, (I(2,1) + I(1,2)) * s );
301
+ }
302
+ else
303
+ {
304
+ rmReal t = -diag00 - diag11 + diag22 + 1.0f;
305
+ rmReal s = 1.0f / ( rmSqrt( t ) * 2.0f );
306
+ RQuatSetZ( out, s * t );
307
+ RQuatSetW( out, (I(1,0) - I(0,1)) * s );
308
+ RQuatSetX( out, (I(0,2) + I(2,0)) * s );
309
+ RQuatSetY( out, (I(2,1) + I(1,2)) * s );
310
+ }
311
+
312
+ #undef I
313
+ }
314
+
315
+ void
316
+ RQuatRotationAxis( RQuat* out, const struct RVec3* axis, rmReal radian )
317
+ {
318
+ rmReal s = rmSin( radian / 2.0f );
319
+ rmReal x, y, z, w;
320
+
321
+ x = s * RVec3GetX( axis );
322
+ y = s * RVec3GetY( axis );
323
+ z = s * RVec3GetZ( axis );
324
+ w = rmCos( radian / 2.0f );
325
+
326
+ RQuatSetElements( out, x, y, z, w );
327
+ }
328
+
329
+ void
330
+ RQuatToAxisAngle( const RQuat* in, struct RVec3* axis, rmReal* radian )
331
+ {
332
+ if ( axis )
333
+ {
334
+ RVec3 a;
335
+ RVec3SetElements( &a, in->x, in->y, in->z );
336
+ RVec3Normalize( axis, &a );
337
+ }
338
+
339
+ if ( radian )
340
+ {
341
+ *radian = 2.0f * rmAcos( in->w );
342
+ }
343
+ }
344
+
345
+ /*
346
+ RMath : Ruby math module for 3D Applications
347
+ Copyright (c) 2008- vaiorabbit <http://twitter.com/vaiorabbit>
348
+
349
+ This software is provided 'as-is', without any express or implied
350
+ warranty. In no event will the authors be held liable for any damages
351
+ arising from the use of this software.
352
+
353
+ Permission is granted to anyone to use this software for any purpose,
354
+ including commercial applications, and to alter it and redistribute it
355
+ freely, subject to the following restrictions:
356
+
357
+ 1. The origin of this software must not be misrepresented; you must not
358
+ claim that you wrote the original software. If you use this software
359
+ in a product, an acknowledgment in the product documentation would be
360
+ appreciated but is not required.
361
+
362
+ 2. Altered source versions must be plainly marked as such, and must not be
363
+ misrepresented as being the original software.
364
+
365
+ 3. This notice may not be removed or altered from any source
366
+ distribution.
367
+ */