ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libgender/entity.C
Revision: 1.64
Committed: Sat Nov 6 01:10:11 2004 UTC (21 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.63: +1 -0 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 root 1.61 m->enable (ctx);
129 root 1.44 GLUquadric *quad = gluNewQuadric ();
130     gluQuadricTexture (quad, true);
131     gluSphere (quad, radius, n, n);
132     gluDeleteQuadric (quad);
133 root 1.61 m->disable (ctx);
134 root 1.44 }
135    
136 root 1.22 /////////////////////////////////////////////////////////////////////////////
137    
138 root 1.63 void geometry_indexed_2d::draw (view &ctx)
139     {
140     m->enable (ctx);
141     vb.bind ();
142 root 1.64 printf ("f = %x %x\n", ib.format, type);
143 root 1.63 ib.draw (type, 0, ib.count);
144     m->disable (ctx);
145     }
146    
147     /////////////////////////////////////////////////////////////////////////////
148    
149 root 1.38 void geometry_transform::update ()
150 root 1.22 {
151 root 1.38 const box &sub = g->bbox;
152 root 1.27
153     bbox.reset ();
154     bbox.add (m * vec3 (sub.a.x, sub.a.y, sub.a.z));
155     bbox.add (m * vec3 (sub.b.x, sub.a.y, sub.a.z));
156     bbox.add (m * vec3 (sub.a.x, sub.b.y, sub.a.z));
157     bbox.add (m * vec3 (sub.b.x, sub.b.y, sub.a.z));
158     bbox.add (m * vec3 (sub.a.x, sub.a.y, sub.b.z));
159     bbox.add (m * vec3 (sub.b.x, sub.a.y, sub.b.z));
160     bbox.add (m * vec3 (sub.a.x, sub.b.y, sub.b.z));
161     bbox.add (m * vec3 (sub.b.x, sub.b.y, sub.b.z));
162 root 1.22
163 root 1.38 geometry::update ();
164 root 1.28 }
165    
166 root 1.38 #if 0
167     void geometry_transform::renormalize ()
168 root 1.28 {
169 root 1.34 point trans(m(0,3), m(1,3), m(2,3));
170     ::renormalize (e->orig, trans);
171     m(0,3) = trans.x; m(1,3) = trans.y; m(2,3) = trans.z;
172 root 1.38 }
173 root 1.28 #endif
174    
175 root 1.38 void geometry_transform::update (const matrix &xfrm)
176 root 1.28 {
177     m = m * xfrm;
178    
179     update ();
180     }
181    
182 root 1.38 void geometry_transform::set_matrix (const matrix &xfrm)
183 root 1.28 {
184     m = xfrm;
185    
186     update ();
187 root 1.22 }
188    
189 root 1.38 void geometry_transform::draw (view &ctx)
190 root 1.22 {
191 root 1.33 glPushMatrix ();
192     glMultMatrixf ((GLfloat *)&m);
193 root 1.38 g->draw (ctx);
194 root 1.33 glPopMatrix ();
195 root 1.2 }
196    
197 root 1.38 void geometry_anim::draw (view &ctx)
198 root 1.23 {
199 root 1.30 matrix save_m = m;
200 root 1.23
201 root 1.30 update (matrix::rotation (vx * timer.now, vec3 (1, 0, 0))
202     * matrix::rotation (vy * timer.now, vec3 (0, 1, 0))
203     * matrix::rotation (vz * timer.now, vec3 (0, 0, 1)));
204 root 1.28
205 root 1.38 geometry_transform::draw (ctx);
206 root 1.23
207     m = save_m;
208 root 1.38 }
209    
210     /////////////////////////////////////////////////////////////////////////////
211    
212     void geometry_filter::set (geometry *g)
213     {
214     this->g = g;
215    
216     if (g)
217     g->parent = this;
218    
219     update ();
220     }
221    
222     void geometry_filter::update ()
223     {
224     if (g)
225     {
226     bbox = g->bbox;
227     geometry::update ();
228     }
229     }
230    
231     void geometry_filter::draw (view &ctx)
232     {
233     g->draw (ctx);
234     }
235    
236     geometry_filter::~geometry_filter ()
237     {
238     delete g;
239     }
240    
241     /////////////////////////////////////////////////////////////////////////////
242    
243     void geometry_container::update ()
244     {
245     bbox.reset ();
246    
247     for (iterator i = end (); i-- != begin (); )
248     bbox.add ((*i)->bbox);
249    
250     geometry::update ();
251     }
252    
253     void geometry_container::add (geometry *g)
254     {
255     push_back (g);
256     g->parent = this;
257    
258     update ();
259     }
260    
261     void geometry_container::draw (view &ctx)
262     {
263     for (iterator i = end (); i-- != begin (); )
264     (*i)->draw (ctx);
265     }
266    
267     geometry_container::~geometry_container ()
268     {
269     for (iterator i = end (); i-- != begin (); )
270     delete *i;
271    
272     clear ();
273     }
274    
275 root 1.52 ///////////////////////////////////////////////////////////////////////////
276 root 1.38
277 root 1.39 static void nurbs_error (GLenum errorCode)
278     {
279     const GLubyte *estring;
280     estring = gluErrorString(errorCode);
281     fprintf (stderr, "Nurbs error: %s\n", estring);
282     }
283 root 1.40
284 root 1.39 void errorCallback(GLenum errorCode)
285     {
286     const GLubyte *estring;
287    
288     estring = gluErrorString(errorCode);
289     fprintf (stderr, "Tessellation Error: %s\n", estring);
290     exit (0);
291     }
292 root 1.54
293 root 1.41 void tcbBegin (GLenum prim)
294     {
295     glBegin (prim);
296     }
297 root 1.54
298 root 1.41 void tcbVertex (void *data)
299     {
300     glVertex3fv ((GLfloat *)data);
301     }
302 root 1.54
303 root 1.41 void tcbEnd ()
304     {
305     glEnd ();
306     }
307 root 1.54
308 root 1.39 void geometry_nurbs::set ()
309     {
310     // < XXX >: Testing CODE
311     int u, v;
312     for (u = 0; u < 4; u++) {
313     for (v = 0; v < 4; v++) {
314     ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5);
315     ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5);
316    
317     if ( (u == 1 || u == 2) && (v == 1 || v == 2))
318     ctlpoints[u][v][2] = 3.0;
319     else
320     ctlpoints[u][v][2] = -3.0;
321     }
322     }
323 root 1.41 tess = gluNewTess();
324 root 1.39 // </ XXX >
325 root 1.1
326 root 1.39 glEnable(GL_AUTO_NORMAL);
327     nurb = gluNewNurbsRenderer ();
328 root 1.41 gluNurbsProperty (nurb, GLU_AUTO_LOAD_MATRIX, GL_FALSE);
329     gluNurbsProperty (nurb, GLU_DISPLAY_MODE, GLU_FILL);
330     gluNurbsProperty (nurb, GLU_NURBS_MODE, GLU_NURBS_TESSELLATOR);
331     gluNurbsProperty (nurb, GLU_SAMPLING_METHOD, GLU_OBJECT_PATH_LENGTH);
332     gluNurbsProperty (nurb, GLU_SAMPLING_TOLERANCE, 1.0);
333 root 1.39 gluNurbsCallback (nurb, GLU_ERROR, (GLvoid (*)()) nurbs_error);
334 root 1.41 gluNurbsCallback (nurb, GLU_NURBS_BEGIN, (GLvoid(*)()) tcbBegin);
335     gluNurbsCallback (nurb, GLU_NURBS_VERTEX,(GLvoid(*)()) tcbVertex);
336     gluNurbsCallback (nurb, GLU_NURBS_END, tcbEnd);
337 root 1.39 glDisable(GL_AUTO_NORMAL);
338 root 1.41
339 root 1.39 }
340 root 1.40
341 root 1.39 void geometry_nurbs::draw (view &ctx)
342     {
343     GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0};
344    
345     GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 };
346     GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
347     GLfloat mat_shininess[] = { 100.0 };
348    
349     glClearColor (0.0, 0.0, 0.0, 0.0);
350     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
351     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
352     glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
353    
354    
355     glEnable(GL_AUTO_NORMAL);
356     gluBeginSurface (nurb);
357     gluNurbsSurface (nurb, 8, knots, 8, knots, 4 * 3, 3, &ctlpoints[0][0][0], 4, 4, GL_MAP2_VERTEX_3);
358 root 1.41 gluEndSurface (nurb);
359     /*
360     glEnable(GL_AUTO_NORMAL);
361     glPushMatrix();
362     GL_LG_DEBUG;
363     =======
364 root 1.39
365 root 1.40 gluEndSurface (nurb);
366 root 1.41 >>>>>>> 1.40
367 root 1.39 glDisable(GL_AUTO_NORMAL);
368 root 1.41 glPopMatrix();
369     glFlush();
370     */
371 root 1.39 }
372 root 1.52
373     /////////////////////////////////////////////////////////////////////////////
374    
375     entity::entity (geometry *g)
376     : geometry_filter(g)
377     , p(0,0,0)
378     {
379     update ();
380     }
381    
382     entity::~entity ()
383     {
384     hide ();
385     }
386    
387     void entity::move (const vec3 &v)
388     {
389     p = p + v;
390    
391     renormalize (orig, p);
392    
393     update ();
394     }
395    
396     void entity::show ()
397     {
398     if (!o.size ())
399     world.add (this);
400     }
401    
402     void entity::hide ()
403     {
404     for (vector<octant *>::iterator i = o.end (); i-- != o.begin (); )
405     (*i)->remove (this);
406    
407     o.clear ();
408     }
409    
410     void entity::update ()
411     {
412     if (!g)
413     return;
414    
415     bbox = g->bbox;
416    
417     a.x = orig.x + (soffs)floorf (bbox.a.x + p.x);
418     a.y = orig.y + (soffs)floorf (bbox.a.y + p.y);
419     a.z = orig.z + (soffs)floorf (bbox.a.z + p.z);
420     b.x = orig.x + (soffs)ceilf (bbox.b.x + p.x);
421     b.y = orig.y + (soffs)ceilf (bbox.b.y + p.y);
422     b.z = orig.z + (soffs)ceilf (bbox.b.z + p.z);
423    
424     if (o.size ())
425     {
426     hide ();
427     show ();
428     }
429     }
430    
431     void entity::draw (view &ctx)
432     {
433 root 1.57 ctx.eorig = orig - ctx.orig;
434 root 1.52
435     glPushMatrix ();
436 root 1.57 glTranslatef (p.x + ctx.eorig.x, p.y + ctx.eorig.y, p.z + ctx.eorig.z);
437 root 1.52 g->draw (ctx);
438     glPopMatrix ();
439     }
440    
441     /////////////////////////////////////////////////////////////////////////////
442     //
443    
444     #define SIZE 33
445    
446     struct geometry_heightfield::node
447     {
448 root 1.54 vertex_t2f_n3f_v3f vd[SIZE][SIZE];
449 root 1.52 gl::vertex_buffer vb;
450 root 1.53 GLushort *ibp;
451 root 1.54 GLfloat hvar;
452 root 1.58 GLfloat x, y, z, e;
453 root 1.53
454 root 1.54 // 23
455     // 01
456     struct geometry_heightfield::node *sub[4];
457    
458 root 1.56 void update_normals ();
459     void draw (view &ctx);
460    
461 root 1.54 node ();
462 root 1.52 };
463 root 1.53
464 root 1.54 geometry_heightfield::node::node ()
465 root 1.53 {
466 root 1.54 sub[0] = sub[1] = sub[2] = sub[3] = 0;
467     //vb.set (vd);
468 root 1.53 }
469 root 1.52
470 root 1.54 static index_buffer ib;
471     static GLushort *ibp;
472     static int icnt;
473    
474     geometry_heightfield::geometry_heightfield (GLfloat sx, GLfloat sy)
475 root 1.55 : sx(sx), sy(sy)
476     , sm (max (sx, sy))
477 root 1.52 {
478 root 1.54 if (!ib)
479     {
480 root 1.58 ib.set<GLushort> (SIZE * SIZE * 6, GL_STATIC_DRAW);
481 root 1.54 ibp = (GLushort *)ib.map ();
482    
483     GLushort *p = ibp;
484    
485     for (int x = 0; x < SIZE - 1; x++)
486     for (int y = 0; y < SIZE - 1; y++)
487     {
488     unsigned short a = (y + 0) * SIZE + (x + 0);
489     unsigned short b = (y + 0) * SIZE + (x + 1);
490     unsigned short c = (y + 1) * SIZE + (x + 1);
491     unsigned short d = (y + 1) * SIZE + (x + 0);
492    
493     *p++ = c; *p++ = b; *p++ = a;
494     *p++ = d; *p++ = c; *p++ = a;
495     }
496    
497     icnt = p - ibp;
498    
499     ib.unmap ();
500     }
501    
502 root 1.52 update ();
503 root 1.54
504     tree = new node;
505     tree->hvar = 0.01F * sx;
506     tree->x = tree->y = 0.F;
507 root 1.56 tree->e = sm;
508 root 1.54
509     for (int x = 0; x < SIZE; x++)
510     for (int y = 0; y < SIZE; y++)
511     {
512     vertex_t2f_n3f_v3f &v = tree->vd[y][x];
513    
514     v.t = tex2 ((GLfloat)x / (SIZE - 1), (GLfloat)y / (SIZE - 1));
515     v.v = vec3 (sx * x / (SIZE - 1), tree->hvar * rand () / RAND_MAX, sy * y / (SIZE - 1));
516 root 1.58 v.n = vec3 (0, 1, 0);
517 root 1.54 }
518    
519 root 1.56 tree->update_normals ();
520    
521 root 1.54 tree->vb.set (&tree->vd[0][0], SIZE * SIZE);
522    
523     bbox.reset ();
524     bbox.add (vec3 (0, 0, 0));
525     bbox.add (vec3 (sx, tree->hvar, sy));
526 root 1.52 }
527    
528     void geometry_heightfield::update ()
529     {
530     geometry::update ();
531     }
532    
533 root 1.58 static int maxcnt, thiscnt;
534     static GLfloat mine;
535 root 1.57
536 root 1.52 void geometry_heightfield::draw (view &ctx)
537     {
538 root 1.62 testmat->enable (ctx);
539 root 1.57 maxcnt = 10;
540 root 1.58 thiscnt = 0;
541     mine = 1e38;
542 root 1.56 tree->draw (ctx);
543 root 1.62 testmat->disable (ctx);
544 root 1.59 //printf (" TC %d mine %f\n", thiscnt, mine);
545 root 1.56 }
546    
547     void geometry_heightfield::node::update_normals ()
548     {
549 root 1.58 GLfloat az = 0.F;
550    
551 root 1.56 for (int x = 0; x < SIZE; x++)
552     for (int y = 0; y < SIZE; y++)
553     {
554     vertex_t2f_n3f_v3f &v = vd[y][x];
555    
556     if (x && y)
557     v.n = normalize (cross (vd[y-1][x].v - v.v, vd[y][x-1].v - v.v));
558 root 1.58
559     az += v.v.y;
560 root 1.56 }
561 root 1.58
562     z = az / (SIZE * SIZE);
563 root 1.56 }
564    
565     void geometry_heightfield::node::draw (view &ctx)
566     {
567 root 1.58 vec3 center = vec3 (ctx.eorig) + vec3 (x + e * .5F, z, y + e * .5F);
568     GLfloat d = length (center);
569 root 1.57
570     if (!overlap (ctx.frustum.c, sphere (center, e * 2)))
571     return;
572    
573 root 1.58 if (d > e * 2.F)
574 root 1.55 {
575 root 1.58 if (mine > e) mine = e; thiscnt++;
576 root 1.56 vb.bind ();
577 root 1.55 ib.draw (GL_TRIANGLES, 0, icnt);
578 root 1.56 }
579     else
580     {
581     for (int i = 0; i < 4; i++)
582     {
583     if (!sub[i])
584     {
585 root 1.57 if (!--maxcnt)
586     {
587     vb.bind ();
588     ib.draw (GL_TRIANGLES, 0, icnt);
589     }
590    
591 root 1.56 node *n = sub[i] = new node;
592    
593 root 1.57 n->hvar = hvar * 0.5;
594 root 1.56 n->x = x + (i & 1 ? e * .5F : 0.F);
595     n->y = y + (i & 2 ? e * .5F : 0.F);
596     n->e = e * .5F;
597    
598     for (int x = 0; x < SIZE; x++)
599     for (int y = 0; y < SIZE; y++)
600     n->vd[y][x] = vd[(y >> 1) + (i & 2 ? SIZE / 2 : 0)][(x >> 1) + (i & 1 ? SIZE / 2 : 0)];
601    
602 root 1.58 for (int x = 1; x < SIZE; x += 2)
603     for (int y = 0; y < SIZE; y += 2)
604     {
605     n->vd[y][x].t = (n->vd[y][x-1].t + n->vd[y][x+1].t) * 0.5F;
606     n->vd[y][x].v = (n->vd[y][x-1].v + n->vd[y][x+1].v) * 0.5F;
607 root 1.60 if (y && y < SIZE - 1)
608     n->vd[y][x].v.y += n->hvar * (GLfloat)rand () / RAND_MAX - n->hvar * .5F;
609 root 1.58 }
610 root 1.57
611 root 1.58 for (int x = 0; x < SIZE; x++)
612     for (int y = 1; y < SIZE; y += 2)
613 root 1.56 {
614 root 1.58 n->vd[y][x].t = (n->vd[y-1][x].t + n->vd[y+1][x].t) * 0.5F;
615 root 1.57 n->vd[y][x].v = (n->vd[y-1][x].v + n->vd[y+1][x].v) * 0.5F;
616 root 1.60 if (x && x < SIZE - 1)
617     n->vd[y][x].v.y += n->hvar * (GLfloat)rand () / RAND_MAX - n->hvar * .5F;
618 root 1.56 }
619    
620     n->update_normals ();
621    
622     n->vb.set (&n->vd[0][0], SIZE * SIZE);
623     }
624    
625     sub[i]->draw (ctx);
626     }
627 root 1.55 }
628 root 1.52 }
629