rmath3d 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ChangeLog +73 -0
- data/LICENSE.txt +21 -0
- data/README.txt +154 -0
- data/Rakefile +42 -0
- data/ext/rmath3d/RMath3D.h +35 -0
- data/ext/rmath3d/RMtx3.c +370 -0
- data/ext/rmath3d/RMtx3.h +95 -0
- data/ext/rmath3d/RMtx4.c +572 -0
- data/ext/rmath3d/RMtx4.h +110 -0
- data/ext/rmath3d/RQuat.c +367 -0
- data/ext/rmath3d/RQuat.h +92 -0
- data/ext/rmath3d/RType.h +76 -0
- data/ext/rmath3d/RVec3.c +285 -0
- data/ext/rmath3d/RVec3.h +89 -0
- data/ext/rmath3d/RVec4.c +215 -0
- data/ext/rmath3d/RVec4.h +86 -0
- data/ext/rmath3d/extconf.rb +9 -0
- data/ext/rmath3d/rmath3d.c +5999 -0
- data/lib/rmath3d/rmath3d_plain.rb +3311 -0
- data/sample/opengl-bindings/load_matrix.rb +174 -0
- data/sample/opengl2/load_matrix.rb +118 -0
- data/sample/simple/transform.rb +11 -0
- data/test/test.rb +15 -0
- data/test/test_RMtx3.rb +517 -0
- data/test/test_RMtx4.rb +735 -0
- data/test/test_RQuat.rb +381 -0
- data/test/test_RVec3.rb +308 -0
- data/test/test_RVec4.rb +287 -0
- metadata +74 -0
data/ext/rmath3d/RMtx3.h
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
/* -*- C -*- */
|
2
|
+
#ifndef RMATHMTX3_H_INCLUDED
|
3
|
+
#define RMATHMTX3_H_INCLUDED
|
4
|
+
|
5
|
+
#include "RType.h"
|
6
|
+
|
7
|
+
struct RVec3;
|
8
|
+
struct RQuat;
|
9
|
+
|
10
|
+
typedef struct RMtx3
|
11
|
+
{
|
12
|
+
union
|
13
|
+
{
|
14
|
+
/* NOTE : column-major */
|
15
|
+
struct
|
16
|
+
{
|
17
|
+
rmReal e00, e10, e20;
|
18
|
+
rmReal e01, e11, e21;
|
19
|
+
rmReal e02, e12, e22;
|
20
|
+
};
|
21
|
+
rmReal e[9];
|
22
|
+
};
|
23
|
+
} RMtx3;
|
24
|
+
|
25
|
+
#ifdef __cplusplus
|
26
|
+
extern "C" {
|
27
|
+
#endif
|
28
|
+
|
29
|
+
void RMtx3SetElements( RMtx3* out,
|
30
|
+
rmReal e00, rmReal e01, rmReal e02,
|
31
|
+
rmReal e10, rmReal e11, rmReal e12,
|
32
|
+
rmReal e20, rmReal e21, rmReal e22
|
33
|
+
);
|
34
|
+
|
35
|
+
void RMtx3SetElement( RMtx3* out, int row, int col, rmReal e );
|
36
|
+
rmReal RMtx3GetElement( const RMtx3* in, int row, int col );
|
37
|
+
|
38
|
+
void RMtx3GetRow( struct RVec3* out, const RMtx3* in, int row );
|
39
|
+
void RMtx3GetColumn( struct RVec3* out, const RMtx3* in, int col );
|
40
|
+
|
41
|
+
void RMtx3SetRow( struct RMtx3* out, const RVec3* in, int row );
|
42
|
+
void RMtx3SetColumn( struct RMtx3* out, const RVec3* in, int col );
|
43
|
+
|
44
|
+
void RMtx3Copy( RMtx3* out, const RMtx3* in );
|
45
|
+
|
46
|
+
void RMtx3Zero( RMtx3* out );
|
47
|
+
void RMtx3Identity( RMtx3* out );
|
48
|
+
rmReal RMtx3Determinant( const RMtx3* in );
|
49
|
+
void RMtx3Transpose( RMtx3* out, const RMtx3* in );
|
50
|
+
rmReal RMtx3Inverse( RMtx3* out, const RMtx3* in );
|
51
|
+
|
52
|
+
void RMtx3RotationX( RMtx3* out, rmReal radian );
|
53
|
+
void RMtx3RotationY( RMtx3* out, rmReal radian );
|
54
|
+
void RMtx3RotationZ( RMtx3* out, rmReal radian );
|
55
|
+
void RMtx3RotationAxis( RMtx3* out, const struct RVec3* axis, rmReal radian );
|
56
|
+
void RMtx3RotationQuaternion( RMtx3* out, const struct RQuat* q );
|
57
|
+
void RMtx3Scaling( RMtx3* out, rmReal sx, rmReal sy, rmReal sz );
|
58
|
+
|
59
|
+
int RMtx3Equal( const RMtx3* m1, const RMtx3* m2 );
|
60
|
+
|
61
|
+
void RMtx3Add( RMtx3* out, const RMtx3* m1, const RMtx3* m2 );
|
62
|
+
void RMtx3Sub( RMtx3* out, const RMtx3* m1, const RMtx3* m2 );
|
63
|
+
void RMtx3Mul( RMtx3* out, const RMtx3* m1, const RMtx3* m2 );
|
64
|
+
void RMtx3Scale( RMtx3* out, const RMtx3* m, rmReal f );
|
65
|
+
|
66
|
+
#ifdef __cplusplus
|
67
|
+
}
|
68
|
+
#endif
|
69
|
+
|
70
|
+
|
71
|
+
#endif
|
72
|
+
|
73
|
+
/*
|
74
|
+
RMath : Ruby math module for 3D Applications
|
75
|
+
Copyright (c) 2008- vaiorabbit <http://twitter.com/vaiorabbit>
|
76
|
+
|
77
|
+
This software is provided 'as-is', without any express or implied
|
78
|
+
warranty. In no event will the authors be held liable for any damages
|
79
|
+
arising from the use of this software.
|
80
|
+
|
81
|
+
Permission is granted to anyone to use this software for any purpose,
|
82
|
+
including commercial applications, and to alter it and redistribute it
|
83
|
+
freely, subject to the following restrictions:
|
84
|
+
|
85
|
+
1. The origin of this software must not be misrepresented; you must not
|
86
|
+
claim that you wrote the original software. If you use this software
|
87
|
+
in a product, an acknowledgment in the product documentation would be
|
88
|
+
appreciated but is not required.
|
89
|
+
|
90
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
91
|
+
misrepresented as being the original software.
|
92
|
+
|
93
|
+
3. This notice may not be removed or altered from any source
|
94
|
+
distribution.
|
95
|
+
*/
|
data/ext/rmath3d/RMtx4.c
ADDED
@@ -0,0 +1,572 @@
|
|
1
|
+
#include <math.h>
|
2
|
+
#include <string.h>
|
3
|
+
|
4
|
+
#include "RVec3.h"
|
5
|
+
#include "RVec4.h"
|
6
|
+
#include "RQuat.h"
|
7
|
+
#include "RMtx3.h"
|
8
|
+
#include "RMtx4.h"
|
9
|
+
|
10
|
+
/* NOTE : column-major */
|
11
|
+
#define SET_ELEMENT(out, row, col, val) (out)->e[(col)*4+(row)] = (val)
|
12
|
+
#define GET_ELEMENT(in, row, col) ((in)->e[(col)*4+(row)])
|
13
|
+
|
14
|
+
void
|
15
|
+
RMtx4SetElement( RMtx4* out, int row, int col, rmReal e )
|
16
|
+
{
|
17
|
+
SET_ELEMENT( out, row, col, e );
|
18
|
+
}
|
19
|
+
|
20
|
+
rmReal
|
21
|
+
RMtx4GetElement( const RMtx4* in, int row, int col )
|
22
|
+
{
|
23
|
+
return GET_ELEMENT( in, row, col );
|
24
|
+
}
|
25
|
+
|
26
|
+
void
|
27
|
+
RMtx4GetRow( RVec4* out, const RMtx4* in, int row )
|
28
|
+
{
|
29
|
+
RVec4SetX( out, GET_ELEMENT( in, row, 0 ) );
|
30
|
+
RVec4SetY( out, GET_ELEMENT( in, row, 1 ) );
|
31
|
+
RVec4SetZ( out, GET_ELEMENT( in, row, 2 ) );
|
32
|
+
RVec4SetW( out, GET_ELEMENT( in, row, 3 ) );
|
33
|
+
}
|
34
|
+
|
35
|
+
void
|
36
|
+
RMtx4GetColumn( RVec4* out, const RMtx4* in, int col )
|
37
|
+
{
|
38
|
+
RVec4SetX( out, GET_ELEMENT( in, 0, col ) );
|
39
|
+
RVec4SetY( out, GET_ELEMENT( in, 1, col ) );
|
40
|
+
RVec4SetZ( out, GET_ELEMENT( in, 2, col ) );
|
41
|
+
RVec4SetW( out, GET_ELEMENT( in, 3, col ) );
|
42
|
+
}
|
43
|
+
|
44
|
+
void
|
45
|
+
RMtx4SetRow( RMtx4* out, const RVec4* in, int row )
|
46
|
+
{
|
47
|
+
SET_ELEMENT( out, row, 0, RVec4GetElement( in, 0 ) );
|
48
|
+
SET_ELEMENT( out, row, 1, RVec4GetElement( in, 1 ) );
|
49
|
+
SET_ELEMENT( out, row, 2, RVec4GetElement( in, 2 ) );
|
50
|
+
SET_ELEMENT( out, row, 3, RVec4GetElement( in, 3 ) );
|
51
|
+
}
|
52
|
+
|
53
|
+
void
|
54
|
+
RMtx4SetColumn( RMtx4* out, const RVec4* in, int col )
|
55
|
+
{
|
56
|
+
SET_ELEMENT( out, 0, col, RVec4GetElement( in, 0 ) );
|
57
|
+
SET_ELEMENT( out, 1, col, RVec4GetElement( in, 1 ) );
|
58
|
+
SET_ELEMENT( out, 2, col, RVec4GetElement( in, 2 ) );
|
59
|
+
SET_ELEMENT( out, 3, col, RVec4GetElement( in, 3 ) );
|
60
|
+
}
|
61
|
+
|
62
|
+
void
|
63
|
+
RMtx4GetUpper3x3( RMtx3* out, const RMtx4* in )
|
64
|
+
{
|
65
|
+
RMtx3SetElements( out,
|
66
|
+
GET_ELEMENT(in,0,0), GET_ELEMENT(in,0,1), GET_ELEMENT(in,0,2),
|
67
|
+
GET_ELEMENT(in,1,0), GET_ELEMENT(in,1,1), GET_ELEMENT(in,1,2),
|
68
|
+
GET_ELEMENT(in,2,0), GET_ELEMENT(in,2,1), GET_ELEMENT(in,2,2) );
|
69
|
+
}
|
70
|
+
|
71
|
+
void
|
72
|
+
RMtx4SetUpper3x3( RMtx4* out, const RMtx3* in )
|
73
|
+
{
|
74
|
+
SET_ELEMENT( out, 0, 0, RMtx3GetElement( in, 0, 0 ) );
|
75
|
+
SET_ELEMENT( out, 0, 1, RMtx3GetElement( in, 0, 1 ) );
|
76
|
+
SET_ELEMENT( out, 0, 2, RMtx3GetElement( in, 0, 2 ) );
|
77
|
+
SET_ELEMENT( out, 1, 0, RMtx3GetElement( in, 1, 0 ) );
|
78
|
+
SET_ELEMENT( out, 1, 1, RMtx3GetElement( in, 1, 1 ) );
|
79
|
+
SET_ELEMENT( out, 1, 2, RMtx3GetElement( in, 1, 2 ) );
|
80
|
+
SET_ELEMENT( out, 2, 0, RMtx3GetElement( in, 2, 0 ) );
|
81
|
+
SET_ELEMENT( out, 2, 1, RMtx3GetElement( in, 2, 1 ) );
|
82
|
+
SET_ELEMENT( out, 2, 2, RMtx3GetElement( in, 2, 2 ) );
|
83
|
+
}
|
84
|
+
|
85
|
+
void
|
86
|
+
RMtx4Copy( RMtx4* out, const RMtx4* in )
|
87
|
+
{
|
88
|
+
memmove( out, in, sizeof(RMtx4) );
|
89
|
+
}
|
90
|
+
|
91
|
+
void
|
92
|
+
RMtx4SetElements( RMtx4* out,
|
93
|
+
rmReal e00, rmReal e01, rmReal e02, rmReal e03,
|
94
|
+
rmReal e10, rmReal e11, rmReal e12, rmReal e13,
|
95
|
+
rmReal e20, rmReal e21, rmReal e22, rmReal e23,
|
96
|
+
rmReal e30, rmReal e31, rmReal e32, rmReal e33
|
97
|
+
)
|
98
|
+
{
|
99
|
+
SET_ELEMENT( out, 0, 0, e00 );
|
100
|
+
SET_ELEMENT( out, 0, 1, e01 );
|
101
|
+
SET_ELEMENT( out, 0, 2, e02 );
|
102
|
+
SET_ELEMENT( out, 0, 3, e03 );
|
103
|
+
|
104
|
+
SET_ELEMENT( out, 1, 0, e10 );
|
105
|
+
SET_ELEMENT( out, 1, 1, e11 );
|
106
|
+
SET_ELEMENT( out, 1, 2, e12 );
|
107
|
+
SET_ELEMENT( out, 1, 3, e13 );
|
108
|
+
|
109
|
+
SET_ELEMENT( out, 2, 0, e20 );
|
110
|
+
SET_ELEMENT( out, 2, 1, e21 );
|
111
|
+
SET_ELEMENT( out, 2, 2, e22 );
|
112
|
+
SET_ELEMENT( out, 2, 3, e23 );
|
113
|
+
|
114
|
+
SET_ELEMENT( out, 3, 0, e30 );
|
115
|
+
SET_ELEMENT( out, 3, 1, e31 );
|
116
|
+
SET_ELEMENT( out, 3, 2, e32 );
|
117
|
+
SET_ELEMENT( out, 3, 3, e33 );
|
118
|
+
}
|
119
|
+
|
120
|
+
void
|
121
|
+
RMtx4Zero( RMtx4* out )
|
122
|
+
{
|
123
|
+
int row, col;
|
124
|
+
for ( row = 0; row < 4; ++row )
|
125
|
+
for ( col = 0; col < 4; ++col )
|
126
|
+
SET_ELEMENT( out, row, col, 0.0f );
|
127
|
+
}
|
128
|
+
|
129
|
+
void
|
130
|
+
RMtx4Identity( RMtx4* out )
|
131
|
+
{
|
132
|
+
int row, col;
|
133
|
+
for ( row = 0; row < 4; ++row )
|
134
|
+
for ( col = 0; col < 4; ++col )
|
135
|
+
SET_ELEMENT( out, row, col, (row==col) ? 1.0f : 0.0f );
|
136
|
+
}
|
137
|
+
|
138
|
+
rmReal
|
139
|
+
RMtx4Determinant( const RMtx4* in )
|
140
|
+
{
|
141
|
+
#define I( r, c ) GET_ELEMENT( in, (r), (c) )
|
142
|
+
#define D( e00,e01,e02, e10,e11,e12, e20,e21,e22 ) \
|
143
|
+
( (e00)*((e11)*(e22)-(e12)*(e21)) \
|
144
|
+
- (e01)*((e10)*(e22)-(e12)*(e20)) \
|
145
|
+
+ (e02)*((e10)*(e21)-(e11)*(e20)) )
|
146
|
+
|
147
|
+
return
|
148
|
+
I(0,0) * D( I(1,1),I(1,2),I(1,3), I(2,1),I(2,2),I(2,3), I(3,1),I(3,2),I(3,3) ) -
|
149
|
+
I(0,1) * D( I(1,0),I(1,2),I(1,3), I(2,0),I(2,2),I(2,3), I(3,0),I(3,2),I(3,3) ) +
|
150
|
+
I(0,2) * D( I(1,0),I(1,1),I(1,3), I(2,0),I(2,1),I(2,3), I(3,0),I(3,1),I(3,3) ) -
|
151
|
+
I(0,3) * D( I(1,0),I(1,1),I(1,2), I(2,0),I(2,1),I(2,2), I(3,0),I(3,1),I(3,2) ) ;
|
152
|
+
|
153
|
+
#undef I
|
154
|
+
#undef D
|
155
|
+
}
|
156
|
+
|
157
|
+
void
|
158
|
+
RMtx4Transpose( RMtx4* out, const RMtx4* in )
|
159
|
+
{
|
160
|
+
int row, col;
|
161
|
+
RMtx4 tmp;
|
162
|
+
for ( row = 0; row < 4; ++row )
|
163
|
+
for ( col = 0; col < 4; ++col )
|
164
|
+
SET_ELEMENT( &tmp, row, col, GET_ELEMENT( in, col, row ) );
|
165
|
+
|
166
|
+
RMtx4Copy( out, &tmp );
|
167
|
+
}
|
168
|
+
|
169
|
+
rmReal
|
170
|
+
RMtx4Inverse( RMtx4* out, const RMtx4* in )
|
171
|
+
{
|
172
|
+
#define I( r, c ) GET_ELEMENT( in, (r), (c) )
|
173
|
+
#define R( r, c ) GET_ELEMENT( &result, (r), (c) )
|
174
|
+
#define D( e00,e01,e02, e10,e11,e12, e20,e21,e22 ) \
|
175
|
+
( (e00)*((e11)*(e22)-(e12)*(e21)) \
|
176
|
+
- (e01)*((e10)*(e22)-(e12)*(e20)) \
|
177
|
+
+ (e02)*((e10)*(e21)-(e11)*(e20)) )
|
178
|
+
|
179
|
+
RMtx4 result;
|
180
|
+
rmReal det;
|
181
|
+
|
182
|
+
SET_ELEMENT( &result, 0, 0,
|
183
|
+
D( I(1,1),I(1,2),I(1,3), I(2,1),I(2,2),I(2,3), I(3,1),I(3,2),I(3,3) ) );
|
184
|
+
|
185
|
+
SET_ELEMENT( &result, 0, 1,
|
186
|
+
-D( I(0,1),I(0,2),I(0,3), I(2,1),I(2,2),I(2,3), I(3,1),I(3,2),I(3,3) ) );
|
187
|
+
|
188
|
+
SET_ELEMENT( &result, 0, 2,
|
189
|
+
D( I(0,1),I(0,2),I(0,3), I(1,1),I(1,2),I(1,3), I(3,1),I(3,2),I(3,3) ) );
|
190
|
+
|
191
|
+
SET_ELEMENT( &result, 0, 3,
|
192
|
+
-D( I(0,1),I(0,2),I(0,3), I(1,1),I(1,2),I(1,3), I(2,1),I(2,2),I(2,3) ) );
|
193
|
+
|
194
|
+
SET_ELEMENT( &result, 1, 0,
|
195
|
+
-D( I(1,0),I(1,2),I(1,3), I(2,0),I(2,2),I(2,3), I(3,0),I(3,2),I(3,3) ) );
|
196
|
+
|
197
|
+
SET_ELEMENT( &result, 1, 1,
|
198
|
+
D( I(0,0),I(0,2),I(0,3), I(2,0),I(2,2),I(2,3), I(3,0),I(3,2),I(3,3) ) );
|
199
|
+
|
200
|
+
SET_ELEMENT( &result, 1, 2,
|
201
|
+
-D( I(0,0),I(0,2),I(0,3), I(1,0),I(1,2),I(1,3), I(3,0),I(3,2),I(3,3) ) );
|
202
|
+
|
203
|
+
SET_ELEMENT( &result, 1, 3,
|
204
|
+
D( I(0,0),I(0,2),I(0,3), I(1,0),I(1,2),I(1,3), I(2,0),I(2,2),I(2,3) ) );
|
205
|
+
|
206
|
+
SET_ELEMENT( &result, 2, 0,
|
207
|
+
D( I(1,0),I(1,1),I(1,3), I(2,0),I(2,1),I(2,3), I(3,0),I(3,1),I(3,3) ) );
|
208
|
+
|
209
|
+
SET_ELEMENT( &result, 2, 1,
|
210
|
+
-D( I(0,0),I(0,1),I(0,3), I(2,0),I(2,1),I(2,3), I(3,0),I(3,1),I(3,3) ) );
|
211
|
+
|
212
|
+
SET_ELEMENT( &result, 2, 2,
|
213
|
+
D( I(0,0),I(0,1),I(0,3), I(1,0),I(1,1),I(1,3), I(3,0),I(3,1),I(3,3) ) );
|
214
|
+
|
215
|
+
SET_ELEMENT( &result, 2, 3,
|
216
|
+
-D( I(0,0),I(0,1),I(0,3), I(1,0),I(1,1),I(1,3), I(2,0),I(2,1),I(2,3) ) );
|
217
|
+
|
218
|
+
SET_ELEMENT( &result, 3, 0,
|
219
|
+
-D( I(1,0),I(1,1),I(1,2), I(2,0),I(2,1),I(2,2), I(3,0),I(3,1),I(3,2) ) );
|
220
|
+
|
221
|
+
SET_ELEMENT( &result, 3, 1,
|
222
|
+
D( I(0,0),I(0,1),I(0,2), I(2,0),I(2,1),I(2,2), I(3,0),I(3,1),I(3,2) ) );
|
223
|
+
|
224
|
+
SET_ELEMENT( &result, 3, 2,
|
225
|
+
-D( I(0,0),I(0,1),I(0,2), I(1,0),I(1,1),I(1,2), I(3,0),I(3,1),I(3,2) ) );
|
226
|
+
|
227
|
+
SET_ELEMENT( &result, 3, 3,
|
228
|
+
D( I(0,0),I(0,1),I(0,2), I(1,0),I(1,1),I(1,2), I(2,0),I(2,1),I(2,2) ) );
|
229
|
+
|
230
|
+
det = I(0,0) * R(0,0) + I(0,1) * R(1,0) + I(0,2) * R(2,0) + I(0,3) * R(3,0);
|
231
|
+
|
232
|
+
if ( rmFabs(det) < RMATH_TOLERANCE )
|
233
|
+
return det;
|
234
|
+
|
235
|
+
RMtx4Scale( out, &result, 1.0f / det );
|
236
|
+
|
237
|
+
return det;
|
238
|
+
|
239
|
+
#undef I
|
240
|
+
#undef R
|
241
|
+
#undef D
|
242
|
+
}
|
243
|
+
|
244
|
+
|
245
|
+
void
|
246
|
+
RMtx4Translation( RMtx4* out, rmReal tx, rmReal ty, rmReal tz )
|
247
|
+
{
|
248
|
+
RMtx4Identity( out );
|
249
|
+
SET_ELEMENT( out, 0, 3, tx );
|
250
|
+
SET_ELEMENT( out, 1, 3, ty );
|
251
|
+
SET_ELEMENT( out, 2, 3, tz );
|
252
|
+
}
|
253
|
+
|
254
|
+
/* http://en.wikipedia.org/wiki/Rotation_representation_%28mathematics%29
|
255
|
+
http://en.wikipedia.org/wiki/Rotation_matrix
|
256
|
+
*/
|
257
|
+
void
|
258
|
+
RMtx4RotationX( RMtx4* out, rmReal radian )
|
259
|
+
{
|
260
|
+
rmReal s = rmSin( radian );
|
261
|
+
rmReal c = rmCos( radian );
|
262
|
+
|
263
|
+
RMtx4Identity( out );
|
264
|
+
SET_ELEMENT( out, 1, 1, c );
|
265
|
+
SET_ELEMENT( out, 1, 2, -s );
|
266
|
+
SET_ELEMENT( out, 2, 1, s );
|
267
|
+
SET_ELEMENT( out, 2, 2, c );
|
268
|
+
}
|
269
|
+
|
270
|
+
/* http://en.wikipedia.org/wiki/Rotation_representation_%28mathematics%29
|
271
|
+
http://en.wikipedia.org/wiki/Rotation_matrix
|
272
|
+
*/
|
273
|
+
void
|
274
|
+
RMtx4RotationY( RMtx4* out, rmReal radian )
|
275
|
+
{
|
276
|
+
rmReal s = rmSin( radian );
|
277
|
+
rmReal c = rmCos( radian );
|
278
|
+
|
279
|
+
RMtx4Identity( out );
|
280
|
+
SET_ELEMENT( out, 0, 0, c );
|
281
|
+
SET_ELEMENT( out, 0, 2, s );
|
282
|
+
SET_ELEMENT( out, 2, 0, -s );
|
283
|
+
SET_ELEMENT( out, 2, 2, c );
|
284
|
+
}
|
285
|
+
|
286
|
+
/* http://en.wikipedia.org/wiki/Rotation_representation_%28mathematics%29
|
287
|
+
http://en.wikipedia.org/wiki/Rotation_matrix
|
288
|
+
*/
|
289
|
+
void
|
290
|
+
RMtx4RotationZ( RMtx4* out, rmReal radian )
|
291
|
+
{
|
292
|
+
rmReal s = rmSin( radian );
|
293
|
+
rmReal c = rmCos( radian );
|
294
|
+
|
295
|
+
RMtx4Identity( out );
|
296
|
+
SET_ELEMENT( out, 0, 0, c );
|
297
|
+
SET_ELEMENT( out, 0, 1, -s );
|
298
|
+
SET_ELEMENT( out, 1, 0, s );
|
299
|
+
SET_ELEMENT( out, 1, 1, c );
|
300
|
+
}
|
301
|
+
|
302
|
+
/* http://en.wikipedia.org/wiki/Rotation_matrix
|
303
|
+
*/
|
304
|
+
void
|
305
|
+
RMtx4RotationAxis( RMtx4* out, const RVec3* axis, rmReal radian )
|
306
|
+
{
|
307
|
+
rmReal s = rmSin( radian );
|
308
|
+
rmReal c = rmCos( radian );
|
309
|
+
rmReal C = 1.0f - c;
|
310
|
+
rmReal x = RVec3GetX( axis );
|
311
|
+
rmReal y = RVec3GetY( axis );
|
312
|
+
rmReal z = RVec3GetZ( axis );
|
313
|
+
|
314
|
+
RMtx4Identity( out );
|
315
|
+
SET_ELEMENT( out, 0, 0, x*x*C + c );
|
316
|
+
SET_ELEMENT( out, 0, 1, x*y*C - z*s );
|
317
|
+
SET_ELEMENT( out, 0, 2, z*x*C + y*s );
|
318
|
+
SET_ELEMENT( out, 1, 0, x*y*C + z*s );
|
319
|
+
SET_ELEMENT( out, 1, 1, y*y*C + c );
|
320
|
+
SET_ELEMENT( out, 1, 2, y*z*C - x*s );
|
321
|
+
SET_ELEMENT( out, 2, 0, z*x*C - y*s );
|
322
|
+
SET_ELEMENT( out, 2, 1, y*z*C + x*s );
|
323
|
+
SET_ELEMENT( out, 2, 2, z*z*C + c );
|
324
|
+
}
|
325
|
+
|
326
|
+
/* From Quaternion to Matrix and Back
|
327
|
+
http://www.intel.com/cd/ids/developer/asmo-na/eng/293748.htm
|
328
|
+
*/
|
329
|
+
void
|
330
|
+
RMtx4RotationQuaternion( RMtx4* out, const struct RQuat* q )
|
331
|
+
{
|
332
|
+
rmReal x = RQuatGetX( q );
|
333
|
+
rmReal y = RQuatGetY( q );
|
334
|
+
rmReal z = RQuatGetZ( q );
|
335
|
+
rmReal w = RQuatGetW( q );
|
336
|
+
|
337
|
+
rmReal x2 = 2.0f * x;
|
338
|
+
rmReal y2 = 2.0f * y;
|
339
|
+
rmReal z2 = 2.0f * z;
|
340
|
+
|
341
|
+
rmReal xx2 = x * x2;
|
342
|
+
rmReal yy2 = y * y2;
|
343
|
+
rmReal zz2 = z * z2;
|
344
|
+
|
345
|
+
rmReal yz2 = y * z2;
|
346
|
+
rmReal wx2 = w * x2;
|
347
|
+
rmReal xy2 = x * y2;
|
348
|
+
rmReal wz2 = w * z2;
|
349
|
+
rmReal xz2 = x * z2;
|
350
|
+
rmReal wy2 = w * y2;
|
351
|
+
|
352
|
+
RMtx4Identity( out );
|
353
|
+
SET_ELEMENT( out, 0, 0, 1.0f - yy2 - zz2 );
|
354
|
+
SET_ELEMENT( out, 1, 0, xy2 + wz2 );
|
355
|
+
SET_ELEMENT( out, 2, 0, xz2 - wy2 );
|
356
|
+
SET_ELEMENT( out, 0, 1, xy2 - wz2 );
|
357
|
+
SET_ELEMENT( out, 1, 1, 1.0f - xx2 - zz2 );
|
358
|
+
SET_ELEMENT( out, 2, 1, yz2 + wx2 );
|
359
|
+
SET_ELEMENT( out, 0, 2, xz2 + wy2 );
|
360
|
+
SET_ELEMENT( out, 1, 2, yz2 - wx2 );
|
361
|
+
SET_ELEMENT( out, 2, 2, 1.0f - xx2 - yy2 );
|
362
|
+
}
|
363
|
+
|
364
|
+
void
|
365
|
+
RMtx4Scaling( RMtx4* out, rmReal sx, rmReal sy, rmReal sz )
|
366
|
+
{
|
367
|
+
RMtx4Identity( out );
|
368
|
+
SET_ELEMENT( out, 0, 0, sx );
|
369
|
+
SET_ELEMENT( out, 1, 1, sy );
|
370
|
+
SET_ELEMENT( out, 2, 2, sz );
|
371
|
+
}
|
372
|
+
|
373
|
+
|
374
|
+
int
|
375
|
+
RMtx4Equal( const RMtx4* m1, const RMtx4* m2 )
|
376
|
+
{
|
377
|
+
if ( 0 == memcmp( m1, m2, sizeof(RMtx4) ) )
|
378
|
+
return !0;
|
379
|
+
else
|
380
|
+
return 0;
|
381
|
+
}
|
382
|
+
|
383
|
+
|
384
|
+
void
|
385
|
+
RMtx4Add( RMtx4* out, const RMtx4* m1, const RMtx4* m2 )
|
386
|
+
{
|
387
|
+
int row, col;
|
388
|
+
RMtx4 tmp;
|
389
|
+
for ( row = 0; row < 4; ++row )
|
390
|
+
for ( col = 0; col < 4; ++col )
|
391
|
+
SET_ELEMENT( &tmp, row, col,
|
392
|
+
GET_ELEMENT( m1, row, col ) + GET_ELEMENT( m2, row, col ) );
|
393
|
+
|
394
|
+
RMtx4Copy( out, &tmp );
|
395
|
+
}
|
396
|
+
|
397
|
+
void
|
398
|
+
RMtx4Sub( RMtx4* out, const RMtx4* m1, const RMtx4* m2 )
|
399
|
+
{
|
400
|
+
int row, col;
|
401
|
+
for ( row = 0; row < 4; ++row )
|
402
|
+
for ( col = 0; col < 4; ++col )
|
403
|
+
SET_ELEMENT( out, row, col,
|
404
|
+
GET_ELEMENT( m1, row, col ) - GET_ELEMENT( m2, row, col ) );
|
405
|
+
}
|
406
|
+
|
407
|
+
void
|
408
|
+
RMtx4Mul( RMtx4* out, const RMtx4* m1, const RMtx4* m2 )
|
409
|
+
{
|
410
|
+
int row, col;
|
411
|
+
RMtx4 tmp;
|
412
|
+
for ( row = 0; row < 4; ++row )
|
413
|
+
{
|
414
|
+
for ( col = 0; col < 4; ++col )
|
415
|
+
{
|
416
|
+
int i;
|
417
|
+
rmReal sum = 0.0f;
|
418
|
+
for ( i = 0; i < 4; ++i )
|
419
|
+
{
|
420
|
+
sum += GET_ELEMENT( m1, row, i ) * GET_ELEMENT( m2, i, col );
|
421
|
+
}
|
422
|
+
SET_ELEMENT( &tmp, row, col, sum );
|
423
|
+
}
|
424
|
+
}
|
425
|
+
|
426
|
+
RMtx4Copy( out, &tmp );
|
427
|
+
}
|
428
|
+
|
429
|
+
void
|
430
|
+
RMtx4Scale( RMtx4* out, const RMtx4* m, rmReal f )
|
431
|
+
{
|
432
|
+
int row, col;
|
433
|
+
for ( row = 0; row < 4; ++row )
|
434
|
+
for ( col = 0; col < 4; ++col )
|
435
|
+
SET_ELEMENT( out, row, col,
|
436
|
+
GET_ELEMENT( m, row, col ) * f );
|
437
|
+
}
|
438
|
+
|
439
|
+
/* http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/glu/lookat.html
|
440
|
+
http://msdn.microsoft.com/en-us/library/bb205343.aspx
|
441
|
+
*/
|
442
|
+
void
|
443
|
+
RMtx4LookAtRH( RMtx4* out, const RVec3* eye, const RVec3* at, const RVec3* up )
|
444
|
+
{
|
445
|
+
#define AX(i) RVec3GetElement( &axis_x, i )
|
446
|
+
#define AY(i) RVec3GetElement( &axis_y, i )
|
447
|
+
#define AZ(i) RVec3GetElement( &axis_z, i )
|
448
|
+
|
449
|
+
RVec3 axis_x, axis_y, axis_z;
|
450
|
+
|
451
|
+
RMtx4Identity( out );
|
452
|
+
|
453
|
+
RVec3Sub( &axis_z, eye, at );
|
454
|
+
RVec3Normalize( &axis_z, &axis_z );
|
455
|
+
|
456
|
+
RVec3Cross( &axis_x, up, &axis_z );
|
457
|
+
RVec3Normalize( &axis_x, &axis_x );
|
458
|
+
|
459
|
+
RVec3Cross( &axis_y, &axis_z, &axis_x );
|
460
|
+
|
461
|
+
SET_ELEMENT( out, 0, 0, AX(0) );
|
462
|
+
SET_ELEMENT( out, 0, 1, AX(1) );
|
463
|
+
SET_ELEMENT( out, 0, 2, AX(2) );
|
464
|
+
SET_ELEMENT( out, 0, 3, -RVec3Dot(&axis_x, eye) );
|
465
|
+
|
466
|
+
SET_ELEMENT( out, 1, 0, AY(0) );
|
467
|
+
SET_ELEMENT( out, 1, 1, AY(1) );
|
468
|
+
SET_ELEMENT( out, 1, 2, AY(2) );
|
469
|
+
SET_ELEMENT( out, 1, 3, -RVec3Dot(&axis_y, eye) );
|
470
|
+
|
471
|
+
SET_ELEMENT( out, 2, 0, AZ(0) );
|
472
|
+
SET_ELEMENT( out, 2, 1, AZ(1) );
|
473
|
+
SET_ELEMENT( out, 2, 2, AZ(2) );
|
474
|
+
SET_ELEMENT( out, 2, 3, -RVec3Dot(&axis_z, eye) );
|
475
|
+
|
476
|
+
#undef AX
|
477
|
+
#undef AY
|
478
|
+
#undef AZ
|
479
|
+
}
|
480
|
+
|
481
|
+
void
|
482
|
+
RMtx4PerspectiveRH( RMtx4* out, rmReal width, rmReal height, rmReal znear, rmReal zfar )
|
483
|
+
{
|
484
|
+
RMtx4PerspectiveOffCenterRH( out, -width/2.0f, width/2.0f, -height/2.0f, height/2.0f, znear, zfar );
|
485
|
+
}
|
486
|
+
|
487
|
+
/* http://pyopengl.sourceforge.net/documentation/manual/gluPerspective.3G.html
|
488
|
+
*/
|
489
|
+
void
|
490
|
+
RMtx4PerspectiveFovRH( RMtx4* out, rmReal fovy_radian, rmReal aspect, rmReal znear, rmReal zfar )
|
491
|
+
{
|
492
|
+
rmReal f = rmTan( fovy_radian / 2.0f );
|
493
|
+
f = 1.0f / f;
|
494
|
+
|
495
|
+
RMtx4Identity( out );
|
496
|
+
SET_ELEMENT( out, 0, 0, f / aspect );
|
497
|
+
SET_ELEMENT( out, 1, 1, f );
|
498
|
+
SET_ELEMENT( out, 2, 2, (zfar+znear)/(znear-zfar) );
|
499
|
+
SET_ELEMENT( out, 2, 3, 2*zfar*znear/(znear-zfar) );
|
500
|
+
SET_ELEMENT( out, 3, 2, -1.0f );
|
501
|
+
SET_ELEMENT( out, 3, 3, 0.0f );
|
502
|
+
}
|
503
|
+
|
504
|
+
/* http://pyopengl.sourceforge.net/documentation/manual/glFrustum.3G.html
|
505
|
+
*/
|
506
|
+
void
|
507
|
+
RMtx4PerspectiveOffCenterRH( RMtx4* out, rmReal left, rmReal right, rmReal bottom, rmReal top, rmReal znear, rmReal zfar )
|
508
|
+
{
|
509
|
+
rmReal A = (right+left) / (right-left);
|
510
|
+
rmReal B = (top+bottom) / (top-bottom);
|
511
|
+
rmReal C = -(zfar+znear) / (zfar-znear);
|
512
|
+
rmReal D = -(2*znear*zfar) / (zfar-znear);
|
513
|
+
|
514
|
+
RMtx4Identity( out );
|
515
|
+
SET_ELEMENT( out, 0, 0, 2*znear/(right-left) );
|
516
|
+
SET_ELEMENT( out, 0, 2, A );
|
517
|
+
SET_ELEMENT( out, 1, 1, 2*znear/(top-bottom) );
|
518
|
+
SET_ELEMENT( out, 1, 2, B );
|
519
|
+
SET_ELEMENT( out, 2, 2, C );
|
520
|
+
SET_ELEMENT( out, 2, 3, D );
|
521
|
+
SET_ELEMENT( out, 3, 2, -1.0f );
|
522
|
+
SET_ELEMENT( out, 3, 3, 0.0f );
|
523
|
+
}
|
524
|
+
|
525
|
+
void
|
526
|
+
RMtx4OrthoRH( RMtx4* out, rmReal width, rmReal height, rmReal znear, rmReal zfar )
|
527
|
+
{
|
528
|
+
RMtx4OrthoOffCenterRH( out, -width/2.0f, width/2.0f, -height/2.0f, height/2.0f, znear, zfar );
|
529
|
+
}
|
530
|
+
|
531
|
+
/* http://pyopengl.sourceforge.net/documentation/manual/glOrtho.3G.html
|
532
|
+
*/
|
533
|
+
void
|
534
|
+
RMtx4OrthoOffCenterRH( RMtx4* out, rmReal left, rmReal right, rmReal bottom, rmReal top, rmReal znear, rmReal zfar )
|
535
|
+
{
|
536
|
+
rmReal tx = (right+left) / (right-left);
|
537
|
+
rmReal ty = (top+bottom) / (top-bottom);
|
538
|
+
rmReal tz = (zfar+znear) / (zfar-znear);
|
539
|
+
|
540
|
+
RMtx4Identity( out );
|
541
|
+
SET_ELEMENT( out, 0, 0, 2.0f/(right-left) );
|
542
|
+
SET_ELEMENT( out, 0, 3, tx );
|
543
|
+
SET_ELEMENT( out, 1, 1, 2.0f/(top-bottom) );
|
544
|
+
SET_ELEMENT( out, 1, 3, ty );
|
545
|
+
SET_ELEMENT( out, 2, 2, -2.0f/(zfar-znear) );
|
546
|
+
SET_ELEMENT( out, 2, 3, tz );
|
547
|
+
}
|
548
|
+
|
549
|
+
|
550
|
+
/*
|
551
|
+
RMath : Ruby math module for 3D Applications
|
552
|
+
Copyright (c) 2008- vaiorabbit <http://twitter.com/vaiorabbit>
|
553
|
+
|
554
|
+
This software is provided 'as-is', without any express or implied
|
555
|
+
warranty. In no event will the authors be held liable for any damages
|
556
|
+
arising from the use of this software.
|
557
|
+
|
558
|
+
Permission is granted to anyone to use this software for any purpose,
|
559
|
+
including commercial applications, and to alter it and redistribute it
|
560
|
+
freely, subject to the following restrictions:
|
561
|
+
|
562
|
+
1. The origin of this software must not be misrepresented; you must not
|
563
|
+
claim that you wrote the original software. If you use this software
|
564
|
+
in a product, an acknowledgment in the product documentation would be
|
565
|
+
appreciated but is not required.
|
566
|
+
|
567
|
+
2. Altered source versions must be plainly marked as such, and must not be
|
568
|
+
misrepresented as being the original software.
|
569
|
+
|
570
|
+
3. This notice may not be removed or altered from any source
|
571
|
+
distribution.
|
572
|
+
*/
|