ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/entity.C
Revision: 1.55
Committed: Sat Oct 30 16:40:02 2004 UTC (21 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.54: +7 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.54 #include <cassert>
2     #include <cstdlib>
3 root 1.1 #include <algorithm>
4    
5     using namespace std;
6 root 1.42
7     #include "opengl.h"
8 root 1.1
9 root 1.28 #include "util.h"
10 root 1.1 #include "entity.h"
11 root 1.4 #include "oct.h"
12 root 1.13 #include "view.h"
13 root 1.1
14 root 1.21 /////////////////////////////////////////////////////////////////////////////
15    
16 root 1.38 geometry::~geometry ()
17 root 1.1 {
18 root 1.2 }
19    
20 root 1.38 template class geometry_opengl1d<GL_POINTS>;
21     template class geometry_opengl1d<GL_LINES>;
22     template class geometry_opengl1d<GL_LINE_STRIP>;
23     template class geometry_opengl1d<GL_LINE_LOOP>;
24     template class geometry_opengl2d<GL_TRIANGLES>;
25     template class geometry_opengl2d<GL_TRIANGLE_STRIP>;
26     template class geometry_opengl2d<GL_TRIANGLE_FAN>;
27     template class geometry_opengl2d<GL_QUADS>;
28     template class geometry_opengl2d<GL_QUAD_STRIP>;
29     template class geometry_opengl2d<GL_POLYGON>;
30 root 1.21
31 root 1.38 geometry_opengl::geometry_opengl ()
32 root 1.24 {
33     list = glGenLists (1);
34     }
35    
36 root 1.38 geometry_opengl::~geometry_opengl ()
37 root 1.24 {
38     glDeleteLists (list, 1);
39     }
40    
41 root 1.2 template<GLenum type>
42 root 1.46 void geometry_opengl1d<type>::set (const vector<vertex_v3f> &v)
43 root 1.2 {
44 root 1.38 clear ();
45     insert (end (), v.begin (), v.end ());
46    
47 root 1.6 bbox.reset ();
48    
49 root 1.38 for (const_iterator i = end (); i-- != begin (); )
50 root 1.54 bbox.add (i->v);
51 root 1.6
52 root 1.38 update ();
53 root 1.2 }
54    
55     template<GLenum type>
56 root 1.38 void geometry_opengl1d<type>::draw (view &ctx)
57 root 1.2 {
58     glBegin (type);
59    
60     for (iterator i = begin (); i < end (); ++i)
61 root 1.54 glVertex3fv ((GLfloat *)&i->v);
62 root 1.2
63     glEnd ();
64     }
65    
66     template<GLenum type>
67 root 1.46 void geometry_opengl2d<type>::set (const vector<vertex_t2f_n3f_v3f> &v)
68 root 1.2 {
69 root 1.24 bbox.reset ();
70    
71 root 1.46 for (vector<vertex_t2f_n3f_v3f>::const_iterator i = v.end (); i-- != v.begin (); )
72 root 1.54 bbox.add (i->v);
73 root 1.26
74 root 1.28 update ();
75 root 1.24
76     glNewList (list, GL_COMPILE);
77 root 1.14
78 root 1.20 #if 0
79 root 1.24 glBegin (type);
80    
81 root 1.46 for (vector<vertex_t2f_n3f_v3f>::const_iterator i = v.begin (); i < v.end (); ++i)
82 root 1.24 {
83     glTexCoord2fv ((GLfloat *)&i->t);
84     glNormal3fv ((GLfloat *)&i->n);
85 root 1.54 glVertex3fv ((GLfloat *)&i->v);
86 root 1.24 }
87 root 1.4
88 root 1.24 glEnd ();
89 root 1.19 #else
90 root 1.24 glEnableClientState (GL_VERTEX_ARRAY);
91     glEnableClientState (GL_NORMAL_ARRAY);
92     glEnableClientState (GL_TEXTURE_COORD_ARRAY);
93 root 1.54 glVertexPointer (3, GL_FLOAT, sizeof (vertex_t2f_n3f_v3f), (void *)&v.begin ()->v);
94 root 1.46 glNormalPointer (GL_FLOAT, sizeof (vertex_t2f_n3f_v3f), (void *)&v.begin ()->n);
95     glTexCoordPointer (2, GL_FLOAT, sizeof (vertex_t2f_n3f_v3f), (void *)&v.begin ()->t);
96 root 1.19
97 root 1.24 glDrawArrays (type, 0, v.size ());
98 root 1.46
99     glDisableClientState (GL_VERTEX_ARRAY);
100     glDisableClientState (GL_NORMAL_ARRAY);
101     glDisableClientState (GL_TEXTURE_COORD_ARRAY);
102 root 1.19 #endif
103 root 1.22
104 root 1.24 glEndList ();
105     }
106 root 1.2
107 root 1.24 template<GLenum type>
108 root 1.38 void geometry_opengl2d<type>::draw (view &ctx)
109 root 1.24 {
110 root 1.51 m->enable (ctx);
111 root 1.17 glCallList (list);
112 root 1.51 m->disable (ctx);
113 root 1.22 }
114    
115 root 1.44 void geometry_sphere::update ()
116     {
117     bbox.reset ();
118     bbox.add (-point (radius, radius, radius));
119     bbox.add ( point (radius, radius, radius));
120    
121     geometry::update ();
122     }
123    
124     void geometry_sphere::draw (view &ctx)
125     {
126 root 1.48 int n = min (100, max (15, (int)(ctx.pixfact * radius) / 10));
127 root 1.44
128     GLUquadric *quad = gluNewQuadric ();
129     gluQuadricTexture (quad, true);
130     gluSphere (quad, radius, n, n);
131     gluDeleteQuadric (quad);
132     }
133    
134 root 1.22 /////////////////////////////////////////////////////////////////////////////
135    
136 root 1.38 void geometry_transform::update ()
137 root 1.22 {
138 root 1.38 const box &sub = g->bbox;
139 root 1.27
140     bbox.reset ();
141     bbox.add (m * vec3 (sub.a.x, sub.a.y, sub.a.z));
142     bbox.add (m * vec3 (sub.b.x, sub.a.y, sub.a.z));
143     bbox.add (m * vec3 (sub.a.x, sub.b.y, sub.a.z));
144     bbox.add (m * vec3 (sub.b.x, sub.b.y, sub.a.z));
145     bbox.add (m * vec3 (sub.a.x, sub.a.y, sub.b.z));
146     bbox.add (m * vec3 (sub.b.x, sub.a.y, sub.b.z));
147     bbox.add (m * vec3 (sub.a.x, sub.b.y, sub.b.z));
148     bbox.add (m * vec3 (sub.b.x, sub.b.y, sub.b.z));
149 root 1.22
150 root 1.38 geometry::update ();
151 root 1.28 }
152    
153 root 1.38 #if 0
154     void geometry_transform::renormalize ()
155 root 1.28 {
156 root 1.34 point trans(m(0,3), m(1,3), m(2,3));
157     ::renormalize (e->orig, trans);
158     m(0,3) = trans.x; m(1,3) = trans.y; m(2,3) = trans.z;
159 root 1.38 }
160 root 1.28 #endif
161    
162 root 1.38 void geometry_transform::update (const matrix &xfrm)
163 root 1.28 {
164     m = m * xfrm;
165    
166     update ();
167     }
168    
169 root 1.38 void geometry_transform::set_matrix (const matrix &xfrm)
170 root 1.28 {
171     m = xfrm;
172    
173     update ();
174 root 1.22 }
175    
176 root 1.38 void geometry_transform::draw (view &ctx)
177 root 1.22 {
178 root 1.33 glPushMatrix ();
179     glMultMatrixf ((GLfloat *)&m);
180 root 1.38 g->draw (ctx);
181 root 1.33 glPopMatrix ();
182 root 1.2 }
183    
184 root 1.38 void geometry_anim::draw (view &ctx)
185 root 1.23 {
186 root 1.30 matrix save_m = m;
187 root 1.23
188 root 1.30 update (matrix::rotation (vx * timer.now, vec3 (1, 0, 0))
189     * matrix::rotation (vy * timer.now, vec3 (0, 1, 0))
190     * matrix::rotation (vz * timer.now, vec3 (0, 0, 1)));
191 root 1.28
192 root 1.38 geometry_transform::draw (ctx);
193 root 1.23
194     m = save_m;
195 root 1.38 }
196    
197     /////////////////////////////////////////////////////////////////////////////
198    
199     void geometry_filter::set (geometry *g)
200     {
201     this->g = g;
202    
203     if (g)
204     g->parent = this;
205    
206     update ();
207     }
208    
209     void geometry_filter::update ()
210     {
211     if (g)
212     {
213     bbox = g->bbox;
214     geometry::update ();
215     }
216     }
217    
218     void geometry_filter::draw (view &ctx)
219     {
220     g->draw (ctx);
221     }
222    
223     geometry_filter::~geometry_filter ()
224     {
225     delete g;
226     }
227    
228     /////////////////////////////////////////////////////////////////////////////
229    
230     void geometry_container::update ()
231     {
232     bbox.reset ();
233    
234     for (iterator i = end (); i-- != begin (); )
235     bbox.add ((*i)->bbox);
236    
237     geometry::update ();
238     }
239    
240     void geometry_container::add (geometry *g)
241     {
242     push_back (g);
243     g->parent = this;
244    
245     update ();
246     }
247    
248     void geometry_container::draw (view &ctx)
249     {
250     for (iterator i = end (); i-- != begin (); )
251     (*i)->draw (ctx);
252     }
253    
254     geometry_container::~geometry_container ()
255     {
256     for (iterator i = end (); i-- != begin (); )
257     delete *i;
258    
259     clear ();
260     }
261    
262 root 1.52 ///////////////////////////////////////////////////////////////////////////
263 root 1.38
264 root 1.39 static void nurbs_error (GLenum errorCode)
265     {
266     const GLubyte *estring;
267     estring = gluErrorString(errorCode);
268     fprintf (stderr, "Nurbs error: %s\n", estring);
269     }
270 root 1.40
271 root 1.39 void errorCallback(GLenum errorCode)
272     {
273     const GLubyte *estring;
274    
275     estring = gluErrorString(errorCode);
276     fprintf (stderr, "Tessellation Error: %s\n", estring);
277     exit (0);
278     }
279 root 1.54
280 root 1.41 void tcbBegin (GLenum prim)
281     {
282     glBegin (prim);
283     }
284 root 1.54
285 root 1.41 void tcbVertex (void *data)
286     {
287     glVertex3fv ((GLfloat *)data);
288     }
289 root 1.54
290 root 1.41 void tcbEnd ()
291     {
292     glEnd ();
293     }
294 root 1.54
295 root 1.39 void geometry_nurbs::set ()
296     {
297     // < XXX >: Testing CODE
298     int u, v;
299     for (u = 0; u < 4; u++) {
300     for (v = 0; v < 4; v++) {
301     ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5);
302     ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5);
303    
304     if ( (u == 1 || u == 2) && (v == 1 || v == 2))
305     ctlpoints[u][v][2] = 3.0;
306     else
307     ctlpoints[u][v][2] = -3.0;
308     }
309     }
310 root 1.41 tess = gluNewTess();
311 root 1.39 // </ XXX >
312 root 1.1
313 root 1.39 glEnable(GL_AUTO_NORMAL);
314     nurb = gluNewNurbsRenderer ();
315 root 1.41 gluNurbsProperty (nurb, GLU_AUTO_LOAD_MATRIX, GL_FALSE);
316     gluNurbsProperty (nurb, GLU_DISPLAY_MODE, GLU_FILL);
317     gluNurbsProperty (nurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
318     gluNurbsProperty (nurb, GLU_SAMPLING_METHOD, GLU_OBJECT_PATH_LENGTH);
319     gluNurbsProperty (nurb, GLU_SAMPLING_TOLERANCE, 1.0);
320 root 1.39 gluNurbsCallback (nurb, GLU_ERROR, (GLvoid (*)()) nurbs_error);
321 root 1.41 gluNurbsCallback (nurb, GLU_NURBS_BEGIN, (GLvoid(*)()) tcbBegin);
322     gluNurbsCallback (nurb, GLU_NURBS_VERTEX,(GLvoid(*)()) tcbVertex);
323     gluNurbsCallback (nurb, GLU_NURBS_END, tcbEnd);
324 root 1.39 glDisable(GL_AUTO_NORMAL);
325 root 1.41
326 root 1.39 }
327 root 1.40
328 root 1.39 void geometry_nurbs::draw (view &ctx)
329     {
330     GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
331    
332     GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
333     GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
334     GLfloat mat_shininess[] = { 100.0 };
335    
336     glClearColor (0.0, 0.0, 0.0, 0.0);
337     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
338     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
339     glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
340    
341    
342     glEnable(GL_AUTO_NORMAL);
343     gluBeginSurface (nurb);
344     gluNurbsSurface (nurb, 8, knots, 8, knots, 4 * 3, 3, &ctlpoints[0][0][0], 4, 4, GL_MAP2_VERTEX_3);
345 root 1.41 gluEndSurface (nurb);
346     /*
347     glEnable(GL_AUTO_NORMAL);
348     glPushMatrix();
349     GL_LG_DEBUG;
350     =======
351 root 1.39
352 root 1.40 gluEndSurface (nurb);
353 root 1.41 >>>>>>> 1.40
354 root 1.39 glDisable(GL_AUTO_NORMAL);
355 root 1.41 glPopMatrix();
356     glFlush();
357     */
358 root 1.39 }
359 root 1.52
360     /////////////////////////////////////////////////////////////////////////////
361    
362     entity::entity (geometry *g)
363     : geometry_filter(g)
364     , p(0,0,0)
365     {
366     update ();
367     }
368    
369     entity::~entity ()
370     {
371     hide ();
372     }
373    
374     void entity::move (const vec3 &v)
375     {
376     p = p + v;
377    
378     renormalize (orig, p);
379    
380     update ();
381     }
382    
383     void entity::show ()
384     {
385     if (!o.size ())
386     world.add (this);
387     }
388    
389     void entity::hide ()
390     {
391     for (vector<octant *>::iterator i = o.end (); i-- != o.begin (); )
392     (*i)->remove (this);
393    
394     o.clear ();
395     }
396    
397     void entity::update ()
398     {
399     if (!g)
400     return;
401    
402     bbox = g->bbox;
403    
404     a.x = orig.x + (soffs)floorf (bbox.a.x + p.x);
405     a.y = orig.y + (soffs)floorf (bbox.a.y + p.y);
406     a.z = orig.z + (soffs)floorf (bbox.a.z + p.z);
407     b.x = orig.x + (soffs)ceilf (bbox.b.x + p.x);
408     b.y = orig.y + (soffs)ceilf (bbox.b.y + p.y);
409     b.z = orig.z + (soffs)ceilf (bbox.b.z + p.z);
410    
411     if (o.size ())
412     {
413     hide ();
414     show ();
415     }
416     }
417    
418     void entity::draw (view &ctx)
419     {
420     sector diff = orig - ctx.orig;
421    
422     glPushMatrix ();
423     glTranslatef (diff.x + p.x, diff.y + p.y, diff.z + p.z);
424     g->draw (ctx);
425     glPopMatrix ();
426     }
427    
428     /////////////////////////////////////////////////////////////////////////////
429     //
430    
431     #define SIZE 33
432    
433     struct geometry_heightfield::node
434     {
435 root 1.54 vertex_t2f_n3f_v3f vd[SIZE][SIZE];
436 root 1.52 gl::vertex_buffer vb;
437 root 1.53 GLushort *ibp;
438 root 1.54 GLfloat hvar;
439     GLfloat x, y, e;
440 root 1.53
441 root 1.54 // 23
442     // 01
443     struct geometry_heightfield::node *sub[4];
444    
445     node ();
446 root 1.52 };
447 root 1.53
448 root 1.54 geometry_heightfield::node::node ()
449 root 1.53 {
450 root 1.54 sub[0] = sub[1] = sub[2] = sub[3] = 0;
451     //vb.set (vd);
452 root 1.53 }
453 root 1.52
454 root 1.54 static index_buffer ib;
455     static GLushort *ibp;
456     static int icnt;
457    
458     geometry_heightfield::geometry_heightfield (GLfloat sx, GLfloat sy)
459 root 1.55 : sx(sx), sy(sy)
460     , sm (max (sx, sy))
461 root 1.52 {
462 root 1.54 if (!ib)
463     {
464     ib.set<GLushort> (SIZE * SIZE * 6, GL_DYNAMIC_DRAW);
465     ibp = (GLushort *)ib.map ();
466    
467     GLushort *p = ibp;
468    
469     for (int x = 0; x < SIZE - 1; x++)
470     for (int y = 0; y < SIZE - 1; y++)
471     {
472     unsigned short a = (y + 0) * SIZE + (x + 0);
473     unsigned short b = (y + 0) * SIZE + (x + 1);
474     unsigned short c = (y + 1) * SIZE + (x + 1);
475     unsigned short d = (y + 1) * SIZE + (x + 0);
476    
477     *p++ = c; *p++ = b; *p++ = a;
478     *p++ = d; *p++ = c; *p++ = a;
479     }
480    
481     icnt = p - ibp;
482    
483     ib.unmap ();
484     }
485    
486 root 1.52 update ();
487 root 1.54
488     tree = new node;
489     tree->hvar = 0.01F * sx;
490     tree->x = tree->y = 0.F;
491     tree->e = 1.F;
492    
493     for (int x = 0; x < SIZE; x++)
494     for (int y = 0; y < SIZE; y++)
495     {
496     vertex_t2f_n3f_v3f &v = tree->vd[y][x];
497    
498     v.t = tex2 ((GLfloat)x / (SIZE - 1), (GLfloat)y / (SIZE - 1));
499     v.v = vec3 (sx * x / (SIZE - 1), tree->hvar * rand () / RAND_MAX, sy * y / (SIZE - 1));
500    
501     if (x && y)
502     v.n = normalize (cross (tree->vd[y-1][x].v - v.v, tree->vd[y][x-1].v - v.v));
503     else
504     v.n = vec3 (0, 1, 0);
505     }
506    
507     tree->vb.set (&tree->vd[0][0], SIZE * SIZE);
508    
509     bbox.reset ();
510     bbox.add (vec3 (0, 0, 0));
511     bbox.add (vec3 (sx, tree->hvar, sy));
512 root 1.52 }
513    
514     void geometry_heightfield::update ()
515     {
516     geometry::update ();
517     }
518    
519     void geometry_heightfield::draw (view &ctx)
520     {
521 root 1.55 if (ctx.pixfact * sm < 10 * SIZE || 1)
522     {
523     tree->vb.bind ();
524     ib.draw (GL_TRIANGLES, 0, icnt);
525     }
526 root 1.52 }
527