0
|
1 /* ============================================================================
|
|
2 * Freetype GL - A C OpenGL Freetype engine
|
|
3 * Platform: Any
|
|
4 * WWW: http://code.google.com/p/freetype-gl/
|
|
5 * ----------------------------------------------------------------------------
|
|
6 * Copyright 2011,2012 Nicolas P. Rougier. All rights reserved.
|
|
7 *
|
|
8 * Redistribution and use in source and binary forms, with or without
|
|
9 * modification, are permitted provided that the following conditions are met:
|
|
10 *
|
|
11 * 1. Redistributions of source code must retain the above copyright notice,
|
|
12 * this list of conditions and the following disclaimer.
|
|
13 *
|
|
14 * 2. Redistributions in binary form must reproduce the above copyright
|
|
15 * notice, this list of conditions and the following disclaimer in the
|
|
16 * documentation and/or other materials provided with the distribution.
|
|
17 *
|
|
18 * THIS SOFTWARE IS PROVIDED BY NICOLAS P. ROUGIER ''AS IS'' AND ANY EXPRESS OR
|
|
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
21 * EVENT SHALL NICOLAS P. ROUGIER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28 *
|
|
29 * The views and conclusions contained in the software and documentation are
|
|
30 * those of the authors and should not be interpreted as representing official
|
|
31 * policies, either expressed or implied, of Nicolas P. Rougier.
|
|
32 * ============================================================================
|
|
33 */
|
|
34 #include <assert.h>
|
|
35 #include <stdlib.h>
|
|
36 #include <string.h>
|
|
37 #include <math.h>
|
|
38 #include "mat4.h"
|
|
39
|
|
40 #ifndef M_PI
|
|
41 # define M_PI 3.14159265358979323846
|
|
42 #endif
|
|
43
|
|
44 mat4 *
|
|
45 mat4_new( void )
|
|
46 {
|
|
47 mat4 *self = (mat4 *) malloc( sizeof(mat4) );
|
|
48 return self;
|
|
49
|
|
50 }
|
|
51
|
|
52 void
|
|
53 mat4_set_zero( mat4 *self )
|
|
54 {
|
|
55 assert( self );
|
|
56
|
|
57 memset( self, 0, sizeof( mat4 ));
|
|
58 }
|
|
59
|
|
60 void
|
|
61 mat4_set_identity( mat4 *self )
|
|
62 {
|
|
63 assert( self );
|
|
64
|
|
65 memset( self, 0, sizeof( mat4 ));
|
|
66 self->m00 = 1.0;
|
|
67 self->m11 = 1.0;
|
|
68 self->m22 = 1.0;
|
|
69 self->m33 = 1.0;
|
|
70 }
|
|
71
|
|
72 void
|
|
73 mat4_multiply( mat4 *self, mat4 *other )
|
|
74 {
|
|
75 mat4 m;
|
|
76 size_t i;
|
|
77
|
|
78 assert( self );
|
|
79 assert( other );
|
|
80
|
|
81 for( i=0; i<4; ++i )
|
|
82 {
|
|
83 m.data[i*4+0] =
|
|
84 (self->data[i*4+0] * other->data[0*4+0]) +
|
|
85 (self->data[i*4+1] * other->data[1*4+0]) +
|
|
86 (self->data[i*4+2] * other->data[2*4+0]) +
|
|
87 (self->data[i*4+3] * other->data[3*4+0]) ;
|
|
88
|
|
89 m.data[i*4+1] =
|
|
90 (self->data[i*4+0] * other->data[0*4+1]) +
|
|
91 (self->data[i*4+1] * other->data[1*4+1]) +
|
|
92 (self->data[i*4+2] * other->data[2*4+1]) +
|
|
93 (self->data[i*4+3] * other->data[3*4+1]) ;
|
|
94
|
|
95 m.data[i*4+2] =
|
|
96 (self->data[i*4+0] * other->data[0*4+2]) +
|
|
97 (self->data[i*4+1] * other->data[1*4+2]) +
|
|
98 (self->data[i*4+2] * other->data[2*4+2]) +
|
|
99 (self->data[i*4+3] * other->data[3*4+2]) ;
|
|
100
|
|
101 m.data[i*4+3] =
|
|
102 (self->data[i*4+0] * other->data[0*4+3]) +
|
|
103 (self->data[i*4+1] * other->data[1*4+3]) +
|
|
104 (self->data[i*4+2] * other->data[2*4+3]) +
|
|
105 (self->data[i*4+3] * other->data[3*4+3]) ;
|
|
106 }
|
|
107 memcpy( self, &m, sizeof( mat4 ) );
|
|
108
|
|
109 }
|
|
110
|
|
111
|
|
112 void
|
|
113 mat4_set_orthographic( mat4 *self,
|
|
114 float left, float right,
|
|
115 float bottom, float top,
|
|
116 float znear, float zfar )
|
|
117 {
|
|
118 assert( self );
|
|
119 assert( right != left );
|
|
120 assert( bottom != top );
|
|
121 assert( znear != zfar );
|
|
122
|
|
123 mat4_set_zero( self );
|
|
124
|
|
125 self->m00 = +2.0/(right-left);
|
|
126 self->m30 = -(right+left)/(right-left);
|
|
127 self->m11 = +2.0/(top-bottom);
|
|
128 self->m31 = -(top+bottom)/(top-bottom);
|
|
129 self->m22 = -2.0/(zfar-znear);
|
|
130 self->m32 = -(zfar+znear)/(zfar-znear);
|
|
131 self->m33 = 1.0;
|
|
132 }
|
|
133
|
|
134 void
|
|
135 mat4_set_perspective( mat4 *self,
|
|
136 float fovy, float aspect,
|
|
137 float znear, float zfar)
|
|
138 {
|
|
139 float h, w;
|
|
140
|
|
141 assert( self );
|
|
142 assert( znear != zfar );
|
|
143
|
|
144 h = tan(fovy / 360.0 * M_PI) * znear;
|
|
145 w = h * aspect;
|
|
146
|
|
147 mat4_set_frustum( self, -w, w, -h, h, znear, zfar );
|
|
148 }
|
|
149
|
|
150 void
|
|
151 mat4_set_frustum( mat4 *self,
|
|
152 float left, float right,
|
|
153 float bottom, float top,
|
|
154 float znear, float zfar )
|
|
155 {
|
|
156
|
|
157 assert( self );
|
|
158 assert( right != left );
|
|
159 assert( bottom != top );
|
|
160 assert( znear != zfar );
|
|
161
|
|
162 mat4_set_zero( self );
|
|
163
|
|
164 self->m00 = +2.0*znear/(right-left);
|
|
165 self->m20 = (right+left)/(right-left);
|
|
166
|
|
167 self->m11 = +2.0*znear/(top-bottom);
|
|
168 self->m31 = (top+bottom)/(top-bottom);
|
|
169
|
|
170 self->m22 = -(zfar+znear)/(zfar-znear);
|
|
171 self->m32 = -2.0*znear/(zfar-znear);
|
|
172
|
|
173 self->m23 = -1.0;
|
|
174 }
|
|
175
|
|
176 void
|
|
177 mat4_set_rotation( mat4 *self,
|
|
178 float angle,
|
|
179 float x, float y, float z)
|
|
180 {
|
|
181 float c, s, norm;
|
|
182
|
|
183 assert( self );
|
|
184
|
|
185 c = cos( M_PI*angle/180.0 );
|
|
186 s = sin( M_PI*angle/180.0 );
|
|
187 norm = sqrt(x*x+y*y+z*z);
|
|
188
|
|
189 x /= norm; y /= norm; z /= norm;
|
|
190
|
|
191 mat4_set_identity( self );
|
|
192
|
|
193 self->m00 = x*x*(1-c)+c;
|
|
194 self->m10 = y*x*(1-c)-z*s;
|
|
195 self->m20 = z*x*(1-c)+y*s;
|
|
196
|
|
197 self->m01 = x*y*(1-c)+z*s;
|
|
198 self->m11 = y*y*(1-c)+c;
|
|
199 self->m21 = z*y*(1-c)-x*s;
|
|
200
|
|
201 self->m02 = x*z*(1-c)-y*s;
|
|
202 self->m12 = y*z*(1-c)+x*s;
|
|
203 self->m22 = z*z*(1-c)+c;
|
|
204 }
|
|
205
|
|
206 void
|
|
207 mat4_set_translation( mat4 *self,
|
|
208 float x, float y, float z)
|
|
209 {
|
|
210 assert( self );
|
|
211
|
|
212 mat4_set_identity( self );
|
|
213 self-> m30 = x;
|
|
214 self-> m31 = y;
|
|
215 self-> m32 = z;
|
|
216 }
|
|
217
|
|
218 void
|
|
219 mat4_set_scaling( mat4 *self,
|
|
220 float x, float y, float z)
|
|
221 {
|
|
222 assert( self );
|
|
223
|
|
224 mat4_set_identity( self );
|
|
225 self-> m00 = x;
|
|
226 self-> m11 = y;
|
|
227 self-> m22 = z;
|
|
228 }
|
|
229
|
|
230 void
|
|
231 mat4_rotate( mat4 *self,
|
|
232 float angle,
|
|
233 float x, float y, float z)
|
|
234 {
|
|
235 mat4 m;
|
|
236
|
|
237 assert( self );
|
|
238
|
|
239 mat4_set_rotation( &m, angle, x, y, z);
|
|
240 mat4_multiply( self, &m );
|
|
241 }
|
|
242
|
|
243 void
|
|
244 mat4_translate( mat4 *self,
|
|
245 float x, float y, float z)
|
|
246 {
|
|
247 mat4 m;
|
|
248 assert( self );
|
|
249
|
|
250 mat4_set_translation( &m, x, y, z);
|
|
251 mat4_multiply( self, &m );
|
|
252 }
|
|
253
|
|
254 void
|
|
255 mat4_scale( mat4 *self,
|
|
256 float x, float y, float z)
|
|
257 {
|
|
258 mat4 m;
|
|
259 assert( self );
|
|
260
|
|
261 mat4_set_scaling( &m, x, y, z);
|
|
262 mat4_multiply( self, &m );
|
|
263 }
|