ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/util.C
Revision: 1.34
Committed: Sun Oct 17 14:03:52 2004 UTC (19 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.33: +14 -8 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 /*
2 * math support
3 * most of the more complicated code is taken from mesa.
4 */
5
6 #include <cstdio> // ugly
7 #include <cstring>
8 #include <cmath>
9
10 #include <sys/time.h>
11 #include <time.h>
12
13 #include "opengl.h"
14
15 #include "util.h"
16 #include "entity.h"
17
18 #define DEG2RAD (M_PI / 180.)
19
20 void renormalize (sector &s, point &p)
21 {
22 float i;
23
24 p.x = modff (p.x, &i); s.x += (soffs)i;
25 p.y = modff (p.y, &i); s.y += (soffs)i;
26 p.z = modff (p.z, &i); s.z += (soffs)i;
27 }
28
29 /////////////////////////////////////////////////////////////////////////////
30
31 const vec3 normalize (const vec3 &v)
32 {
33 GLfloat s = norm (v);
34
35 if (!s)
36 return v;
37
38 s = 1. / s;
39 return vec3 (v.x * s, v.y * s, v.z * s);
40 }
41
42 const vec3 cross (const vec3 &a, const vec3 &b)
43 {
44 return vec3 (
45 a.y * b.z - a.z * b.y,
46 a.z * b.x - a.x * b.z,
47 a.x * b.y - a.y * b.x
48 );
49 }
50
51 /////////////////////////////////////////////////////////////////////////////
52
53 plane::plane (GLfloat a, GLfloat b, GLfloat c, GLfloat d)
54 : n (vec3 (a,b,c))
55 {
56 GLfloat s = 1. / norm (n);
57
58 n = n * s;
59 this->d = d * s;
60 }
61
62 /////////////////////////////////////////////////////////////////////////////
63
64 void box::add (const box &o)
65 {
66 a.x = min (a.x, o.a.x);
67 a.y = min (a.y, o.a.y);
68 a.z = min (a.z, o.a.z);
69 b.x = max (b.x, o.b.x);
70 b.y = max (b.y, o.b.y);
71 b.z = max (b.z, o.b.z);
72 }
73
74 void box::add (const point &p)
75 {
76 a.x = min (a.x, p.x);
77 a.y = min (a.y, p.y);
78 a.z = min (a.z, p.z);
79 b.x = max (b.x, p.x);
80 b.y = max (b.y, p.y);
81 b.z = max (b.z, p.z);
82 }
83
84 /////////////////////////////////////////////////////////////////////////////
85
86 struct timer timer;
87 static double base;
88 double timer::now = 0.;
89 double timer::diff;
90 double timer::fps = 60.;
91 //double min_frame = 1. / 60.;
92 double min_frame = 1. / 1000.;
93
94 void timer::frame ()
95 {
96 struct timeval tv;
97 double next;
98
99 gettimeofday (&tv, 0);
100
101 next = tv.tv_sec - base + tv.tv_usec / 1.e6;
102 diff = next - now;
103
104 fps = fps * 0.99 + (1. / diff) * 0.01;
105
106 if (diff < min_frame)
107 {
108 SDL_Delay ((unsigned int)((min_frame - diff) * 1000.));
109
110 gettimeofday (&tv, 0);
111
112 next = tv.tv_sec - base + tv.tv_usec / 1.e6;
113 diff = next - now;
114 }
115
116 now = next;
117 }
118
119 timer::timer ()
120 {
121 struct timeval tv;
122 gettimeofday (&tv, 0);
123 base = tv.tv_sec + tv.tv_usec / 1.e6;
124 }
125
126 void render_text (GLint x, GLint y, const char *str)
127 {
128 glRasterPos2i (x, y);
129
130 #if 0
131 while (!*str)
132 glutBitmapCharacter (GLUT_BITMAP_HELVETICA_18, *str++);
133 #endif
134 }
135
136 namespace gl {
137
138 void matrix::diagonal (GLfloat v)
139 {
140 for (int i = 4; i--; )
141 for (int j = 4; j--; )
142 data[i][j] = i == j ? v : 0.;
143 }
144
145 const matrix operator *(const matrix &a, const matrix &b)
146 {
147 matrix r;
148
149 // taken from mesa
150 for (int i = 0; i < 4; i++)
151 {
152 const GLfloat ai0=a(i,0), ai1=a(i,1), ai2=a(i,2), ai3=a(i,3);
153
154 r(i,0) = ai0 * b(0,0) + ai1 * b(1,0) + ai2 * b(2,0) + ai3 * b(3,0);
155 r(i,1) = ai0 * b(0,1) + ai1 * b(1,1) + ai2 * b(2,1) + ai3 * b(3,1);
156 r(i,2) = ai0 * b(0,2) + ai1 * b(1,2) + ai2 * b(2,2) + ai3 * b(3,2);
157 r(i,3) = ai0 * b(0,3) + ai1 * b(1,3) + ai2 * b(2,3) + ai3 * b(3,3);
158 }
159
160 return r;
161 }
162
163 const matrix matrix::rotation (GLfloat angle, const vec3 &axis)
164 {
165 GLfloat xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c;
166
167 s = (GLfloat) sinf (angle * DEG2RAD);
168 c = (GLfloat) cosf (angle * DEG2RAD);
169
170 const GLfloat mag = norm (axis);
171
172 if (mag <= 1.0e-4)
173 return matrix (1);
174
175 matrix m;
176 const vec3 n = axis * (1. / mag);
177
178 xx = n.x * n.x;
179 yy = n.y * n.y;
180 zz = n.z * n.z;
181 xy = n.x * n.y;
182 yz = n.y * n.z;
183 zx = n.z * n.x;
184 xs = n.x * s;
185 ys = n.y * s;
186 zs = n.z * s;
187 one_c = 1.0F - c;
188
189 m(0,0) = (one_c * xx) + c;
190 m(0,1) = (one_c * xy) - zs;
191 m(0,2) = (one_c * zx) + ys;
192 m(0,3) = 0;
193
194 m(1,0) = (one_c * xy) + zs;
195 m(1,1) = (one_c * yy) + c;
196 m(1,2) = (one_c * yz) - xs;
197 m(1,3) = 0;
198
199 m(2,0) = (one_c * zx) - ys;
200 m(2,1) = (one_c * yz) + xs;
201 m(2,2) = (one_c * zz) + c;
202 m(2,3) = 0;
203
204 m(3,0) = 0;
205 m(3,1) = 0;
206 m(3,2) = 0;
207 m(3,3) = 1;
208
209 return m;
210 }
211
212 const vec3 operator *(const matrix &a, const vec3 &v)
213 {
214 return vec3 (
215 a(0,0) * v.x + a(0,1) * v.y + a(0,2) * v.z + a(0,3),
216 a(1,0) * v.x + a(1,1) * v.y + a(1,2) * v.z + a(1,3),
217 a(2,0) * v.x + a(2,1) * v.y + a(2,2) * v.z + a(2,3)
218 );
219 }
220
221 void matrix::print ()
222 {
223 printf ("\n");
224 printf ("[ %f, %f, %f, %f ]\n", data[0][0], data[1][0], data[2][0], data[3][0]);
225 printf ("[ %f, %f, %f, %f ]\n", data[0][1], data[1][1], data[2][1], data[3][1]);
226 printf ("[ %f, %f, %f, %f ]\n", data[0][2], data[1][2], data[2][2], data[3][2]);
227 printf ("[ %f, %f, %f, %f ]\n", data[0][3], data[1][3], data[2][3], data[3][3]);
228 }
229
230 const matrix matrix::translation (const vec3 &v)
231 {
232 matrix m(1);
233
234 m(0,3) = v.x;
235 m(1,3) = v.y;
236 m(2,3) = v.z;
237
238 return m;
239 }
240
241 /////////////////////////////////////////////////////////////////////////////
242
243 void draw_bbox (vertex_buffer_object &vb, const sector &a, const sector &b)
244 {
245 static GLint verts[] = {
246 0x8000, 0x8004, 0x8006, 0x8002, // -x
247 0x8001, 0x8003, 0x8007, 0x8005, // +x
248 0x8000, 0x8001, 0x8005, 0x8004, // -y
249 0x8007, 0x8003, 0x8002, 0x8006, // +y
250 0x8000, 0x8002, 0x8003, 0x8001, // -z
251 0x8004, 0x8005, 0x8007, 0x8006, // +z
252 0
253 };
254
255 point pa(a), pb(b);
256
257 vector<vertex_v3f> vd;
258
259 for (GLint *v = verts; *v; v++)
260 {
261 GLint mask = *v;
262
263 vd.push_back (point (
264 mask & 1 ? pb.x : pa.x,
265 mask & 2 ? pb.y : pa.y,
266 mask & 4 ? pb.z : pa.z
267 ));
268 }
269
270 vb.set (vd, GL_STATIC_DRAW_ARB);
271 vb.draw (GL_QUADS, 0, 6*4);
272 }
273
274 int nesting;
275
276 void errchk (const char *name, const char *args, const char *file, int line)
277 {
278 static int inbegin;
279
280 if (name[2] == 'B' && !strcmp (name, "glBegin"))
281 inbegin = 1;
282 else if (name[2] == 'E' && !strcmp (name, "glEnd"))
283 inbegin = 0;
284
285 if (inbegin)
286 return;
287
288 GLenum gl_derror = glGetError ();
289 if (gl_derror != GL_NO_ERROR)
290 {
291 fprintf (stderr, "%s:%d [GLERROR %d,%s] %s(%s)\n",
292 file, line, gl_derror, gluErrorString (gl_derror), name, args);
293 abort ();
294 }
295 }
296
297 }
298
299 //skedjuhlar main_scheduler;
300