35 #include <libFreeWRL.h>
37 #include "../vrml_parser/Structs.h"
38 #include "../main/headers.h"
39 #include "../scenegraph/quaternion.h"
40 #include "../scenegraph/Viewer.h"
42 #include "../opengl/OpenGL_Utils.h"
43 #include "../scenegraph/LinearAlgebra.h"
52 static void add_translation (
struct point_XYZ *arr,
float x,
float y,
float z,
int count);
53 static void multiply_in_scale(
struct point_XYZ *arr,
float x,
float y,
float z,
int count);
67 #undef OCCLUSIONVERBOSE
76 #define OCCCHECKNEXTLOOP 1
79 #define OCCCHECKSOON 4
85 #define OCCSHAPESAMPLESIZE 1
93 GLuint potentialOccluderCount;
94 void ** occluderNodePointer;
98 int maxOccludersFound;
109 GLuint OccResultsAvailable;
112 void *Frustum_constructor(){
113 void *v = MALLOCV(
sizeof(
struct pFrustum));
114 memset(v,0,
sizeof(
struct pFrustum));
117 void Frustum_init(
struct tFrustum *t){
119 t->OccFailed = FALSE;
121 t->prv = Frustum_constructor();
125 p->OccQueries = NULL;
128 p->potentialOccluderCount = 0;
129 p->occluderNodePointer = NULL;
133 p->maxOccludersFound = 0;
135 p->OccInitialized = FALSE;
140 p->OccResultsAvailable = FALSE;
147 if (render_geometry) {
148 if (p->potentialOccluderCount < p->OccQuerySize) {
149 TRACE_MSG (
"beginOcclusionQuery, potoc %d occQ %d\n",p->potentialOccluderCount, p->OccQuerySize);
150 if (node->__occludeCheckCount < 0) {
151 TRACE_MSG (
"beginOcclusionQuery, query %u, node %s\n",p->potentialOccluderCount, stringNodeType(node->_nodeType));
152 #if !defined(GL_ES_VERSION_2_0)
155 FW_GL_BEGIN_QUERY(GL_SAMPLES_PASSED, p->OccQueries[p->potentialOccluderCount]);
157 p->occluderNodePointer[p->potentialOccluderCount] = (
void *)node;
166 if (render_geometry) {
167 if (p->potentialOccluderCount < p->OccQuerySize) {
168 if (node->__occludeCheckCount < 0) {
169 TRACE_MSG (
"glEndQuery node %p\n",node);
170 #if !defined( GL_ES_VERSION_2_0 )
171 FW_GL_END_QUERY(GL_SAMPLES_PASSED);
173 p->potentialOccluderCount++;
179 #define PROP_EXTENT_CHECK \
180 if (maxx > geomParent->EXTENT_MAX_X) {geomParent->EXTENT_MAX_X = maxx; touched = TRUE;} \
181 if (minx < geomParent->EXTENT_MIN_X) {geomParent->EXTENT_MIN_X = minx; touched = TRUE;} \
182 if (maxy > geomParent->EXTENT_MAX_Y) {geomParent->EXTENT_MAX_Y = maxy; touched = TRUE;} \
183 if (miny < geomParent->EXTENT_MIN_Y) {geomParent->EXTENT_MIN_Y = miny; touched = TRUE;} \
184 if (maxz > geomParent->EXTENT_MAX_Z) {geomParent->EXTENT_MAX_Z = maxz; touched = TRUE;} \
185 if (minz < geomParent->EXTENT_MIN_Z) {geomParent->EXTENT_MIN_Z = minz; touched = TRUE;}
187 #define FRUSTUM_TRANS(myNodeType) \
188 if (me->_nodeType == NODE_##myNodeType) { \
195 if (!APPROX(me->EXTENT_MAX_X,-10000.0)) { \
196 struct X3D_##myNodeType *node; \
198 struct point_XYZ inxyz[8]; struct point_XYZ outxyz[8]; \
199 node = (struct X3D_##myNodeType *)me; \
202 BBV(0,MAX_X,MAX_Y,MAX_Z); \
203 BBV(1,MAX_X,MAX_Y,MIN_Z); \
204 BBV(2,MAX_X,MIN_Y,MAX_Z); \
205 BBV(3,MAX_X,MIN_Y,MIN_Z); \
206 BBV(4,MIN_X,MAX_Y,MAX_Z); \
207 BBV(5,MIN_X,MAX_Y,MIN_Z); \
208 BBV(6,MIN_X,MIN_Y,MAX_Z); \
209 BBV(7,MIN_X,MIN_Y,MIN_Z); \
212 if (node->__do_center) { \
213 add_translation(inxyz,-node->center.c[0],-node->center.c[1],-node->center.c[2],8); \
217 if (node->__do_scaleO) { \
218 vrmlrot_to_quaternion(&rq,node->scaleOrientation.c[0], node->scaleOrientation.c[1], node->scaleOrientation.c[2], -node->scaleOrientation.c[3]); \
219 quaternion_multi_rotation(outxyz,&rq,inxyz,8); \
222 memcpy (inxyz,outxyz,8*sizeof(struct point_XYZ)); \
226 if (node->__do_scale) { \
228 multiply_in_scale(inxyz,node->scale.c[0],node->scale.c[1],node->scale.c[2],8); \
232 if (node->__do_scaleO) { \
233 vrmlrot_to_quaternion(&rq,node->scaleOrientation.c[0], node->scaleOrientation.c[1], node->scaleOrientation.c[2], -node->scaleOrientation.c[3]); \
234 quaternion_multi_rotation(outxyz,&rq,inxyz,8); \
237 memcpy (inxyz,outxyz,8*sizeof(struct point_XYZ)); \
241 if (node->__do_rotation) { \
243 vrmlrot_to_quaternion(&rq,node->rotation.c[0], node->rotation.c[1], node->rotation.c[2], node->rotation.c[3]); \
244 quaternion_multi_rotation(outxyz,&rq,inxyz,8); \
247 memcpy (inxyz,outxyz,8*sizeof(struct point_XYZ)); \
251 if (node->__do_center) { \
253 add_translation(inxyz,node->center.c[0],node->center.c[1],node->center.c[2],8); \
257 if (node->__do_trans) { \
259 add_translation(inxyz,node->translation.c[0],node->translation.c[1],node->translation.c[2],8); \
266 maxx = -FLT_MAX; maxy = -FLT_MAX; maxz = -FLT_MAX; \
267 minx = FLT_MAX; miny = FLT_MAX; minz = FLT_MAX; \
268 for (i=0; i<8; i++) { \
269 if (inxyz[i].x > maxx) maxx = (float)inxyz[i].x; \
270 if (inxyz[i].y > maxy) maxy = (float)inxyz[i].y; \
271 if (inxyz[i].z > maxz) maxz = (float)inxyz[i].z; \
272 if (inxyz[i].x < minx) minx = (float)inxyz[i].x; \
273 if (inxyz[i].y < miny) miny = (float)inxyz[i].y; \
274 if (inxyz[i].z < minz) minz = (float)inxyz[i].z; \
280 #define FRUSTUM_GEOLOCATION \
281 if (me->_nodeType == NODE_GeoLocation) { \
288 if (!APPROX(me->EXTENT_MAX_X,-10000.0)) { \
289 struct X3D_GeoLocation *node; \
291 struct point_XYZ inxyz[8]; struct point_XYZ outxyz[8]; \
292 node = (struct X3D_GeoLocation *)me; \
295 BBV(0,MAX_X,MAX_Y,MAX_Z); \
296 BBV(1,MAX_X,MAX_Y,MIN_Z); \
297 BBV(2,MAX_X,MIN_Y,MAX_Z); \
298 BBV(3,MAX_X,MIN_Y,MIN_Z); \
299 BBV(4,MIN_X,MAX_Y,MAX_Z); \
300 BBV(5,MIN_X,MAX_Y,MIN_Z); \
301 BBV(6,MIN_X,MIN_Y,MAX_Z); \
302 BBV(7,MIN_X,MIN_Y,MIN_Z); \
306 vrmlrot_to_quaternion(&rq,node->__localOrient.c[0], node->__localOrient.c[1], node->__localOrient.c[2], node->__localOrient.c[3]); \
307 quaternion_multi_rotation(outxyz,&rq,inxyz,8); \
310 memcpy (inxyz,outxyz,8*sizeof(struct point_XYZ)); \
315 add_translation(inxyz,(float) node->__movedCoords.c[0],(float) node->__movedCoords.c[1],(float) node->__movedCoords.c[2],8); \
322 maxx = -FLT_MAX; maxy = -FLT_MAX; maxz = -FLT_MAX; \
323 minx = FLT_MAX; miny = FLT_MAX; minz = FLT_MAX; \
324 for (i=0; i<8; i++) { \
325 if (inxyz[i].x > maxx) maxx = (float) inxyz[i].x; \
326 if (inxyz[i].y > maxy) maxy = (float) inxyz[i].y; \
327 if (inxyz[i].z > maxz) maxz = (float) inxyz[i].z; \
328 if (inxyz[i].x < minx) minx = (float) inxyz[i].x; \
329 if (inxyz[i].y < miny) miny = (float) inxyz[i].y; \
330 if (inxyz[i].z < minz) minz = (float) inxyz[i].z; \
335 #define FRUSTUM_GEOTRANS \
336 if (me->_nodeType == NODE_GeoTransform) { \
343 if (!APPROX(me->EXTENT_MAX_X,-10000.0)) { \
344 struct X3D_GeoTransform *node; \
346 struct point_XYZ inxyz[8]; struct point_XYZ outxyz[8]; \
347 node = (struct X3D_GeoTransform *)me; \
350 BBV(0,MAX_X,MAX_Y,MAX_Z); \
351 BBV(1,MAX_X,MAX_Y,MIN_Z); \
352 BBV(2,MAX_X,MIN_Y,MAX_Z); \
353 BBV(3,MAX_X,MIN_Y,MIN_Z); \
354 BBV(4,MIN_X,MAX_Y,MAX_Z); \
355 BBV(5,MIN_X,MAX_Y,MIN_Z); \
356 BBV(6,MIN_X,MIN_Y,MAX_Z); \
357 BBV(7,MIN_X,MIN_Y,MIN_Z); \
360 if (node->__do_center) { \
361 add_translation(inxyz,(float) (-node->geoCenter.c[0]), (float) (-node->geoCenter.c[1]),(float)(-node->geoCenter.c[2]),8); \
365 if (node->__do_scaleO) { \
366 vrmlrot_to_quaternion(&rq,node->scaleOrientation.c[0], node->scaleOrientation.c[1], node->scaleOrientation.c[2], -node->scaleOrientation.c[3]); \
367 quaternion_multi_rotation(outxyz,&rq,inxyz,8); \
368 memcpy (inxyz,outxyz,8*sizeof(struct point_XYZ)); \
372 if (node->__do_scale) { \
373 multiply_in_scale(inxyz,node->scale.c[0],node->scale.c[1],node->scale.c[2],8); \
377 if (node->__do_scaleO) { \
378 vrmlrot_to_quaternion(&rq,node->scaleOrientation.c[0], node->scaleOrientation.c[1], node->scaleOrientation.c[2], -node->scaleOrientation.c[3]); \
379 quaternion_multi_rotation(outxyz,&rq,inxyz,8); \
380 memcpy (inxyz,outxyz,8*sizeof(struct point_XYZ)); \
384 if (node->__do_rotation) { \
385 vrmlrot_to_quaternion(&rq,node->rotation.c[0], node->rotation.c[1], node->rotation.c[2], node->rotation.c[3]); \
386 quaternion_multi_rotation(outxyz,&rq,inxyz,8); \
387 memcpy (inxyz,outxyz,8*sizeof(struct point_XYZ)); \
391 if (node->__do_center) { \
392 add_translation(inxyz,(float)node->geoCenter.c[0],(float)node->geoCenter.c[1],(float)node->geoCenter.c[2],8); \
394 add_translation (inxyz,(float) X3D_GEOTRANSFORM(node)->__movedCoords.c[0], (float) X3D_GEOTRANSFORM(node)->__movedCoords.c[1], (float) X3D_GEOTRANSFORM(node)->__movedCoords.c[2],8); \
396 vrmlrot_to_quaternion(&rq,X3D_GEOTRANSFORM(node)->__localOrient.c[0], X3D_GEOTRANSFORM(node)->__localOrient.c[1], X3D_GEOTRANSFORM(node)->__localOrient.c[2], X3D_GEOTRANSFORM(node)->__localOrient.c[3]); \
397 quaternion_multi_rotation(outxyz,&rq,inxyz,8); \
398 memcpy (inxyz,outxyz,8*sizeof(struct point_XYZ)); \
400 if (node->__do_trans) { \
401 add_translation(inxyz,node->translation.c[0],node->translation.c[1],node->translation.c[2],8); \
408 maxx = -FLT_MAX; maxy = -FLT_MAX; maxz = -FLT_MAX; \
409 minx = FLT_MAX; miny = FLT_MAX; minz = FLT_MAX; \
410 for (i=0; i<8; i++) { \
411 if (inxyz[i].x > maxx) maxx = (float) inxyz[i].x; \
412 if (inxyz[i].y > maxy) maxy = (float) inxyz[i].y; \
413 if (inxyz[i].z > maxz) maxz = (float) inxyz[i].z; \
414 if (inxyz[i].x < minx) minx = (float) inxyz[i].x; \
415 if (inxyz[i].y < miny) miny = (float) inxyz[i].y; \
416 if (inxyz[i].z < minz) minz = (float) inxyz[i].z; \
426 int wc = node->whichChoice;
429 if (node->__isX3D == 0) {
430 if(wc >= 0 && wc < ((node->choice).n)) {
431 void *p = ((node->choice).p[wc]);
432 return (X3D_NODE(p)==me);
435 if(wc >= 0 && wc < ((node->children).n)) {
436 void *p = ((node->children).p[wc]);
437 return (X3D_NODE(p)==me);
447 for (i=0; i<node->children.n; i++) {
450 if ((i >= node->visible.n) && (node->children.p[i] == me))
return TRUE;
453 else if ((node->visible.p[i]) && (node->children.p[i] == me))
return TRUE;
465 for (x=0; x<gpnode->rootNode.n; x++) {
474 if (me == X3D_NODE(gpnode->rootNode.p[x])) {
485 return (y ^ gpnode->__inRange);
497 void setExtent(
float maxx,
float minx,
float maxy,
float miny,
float maxz,
float minz,
struct X3D_Node *me) {
505 #ifdef FRUSTUMVERBOSE
506 printf (
"setExtent maxx %f minx %f maxy %f miny %f maxz %f minz %f me %p nt %s\n",
507 maxx, minx, maxy, miny, maxz, minz, me, stringNodeType(me->_nodeType));
511 me->EXTENT_MAX_X = maxx; me->EXTENT_MIN_X = minx;
512 me->EXTENT_MAX_Y = maxy; me->EXTENT_MIN_Y = miny;
513 me->EXTENT_MAX_Z = maxz; me->EXTENT_MIN_Z = minz;
515 if (me->_parentVector == NULL) {
516 #ifdef FRUSTUMVERBOSE
517 printf (
"setExtent, parentVector NULL for node %p type %s\n",
518 me,stringNodeType(me->_nodeType));
523 for (c=0; c<vectorSize(me->_parentVector); c++) {
524 shapeParent = vector_get(
struct X3D_Node *, me->_parentVector,c);
527 shapeParent->EXTENT_MAX_X = maxx; shapeParent->EXTENT_MIN_X = minx;
528 shapeParent->EXTENT_MAX_Y = maxy; shapeParent->EXTENT_MIN_Y = miny;
529 shapeParent->EXTENT_MAX_Z = maxz; shapeParent->EXTENT_MIN_Z = minz;
531 #ifdef FRUSTUMVERBOSE
532 if (shapeParent == NULL)
533 printf (
"parent %u of %u is %p, is null\n",c,vectorSize(me->_parentVector),shapeParent);
535 printf (
"parent %u of %u is %p, type %s\n",c,vectorSize(me->_parentVector),shapeParent,stringNodeType(shapeParent->_nodeType));
538 for (d=0; d<vectorSize(shapeParent->_parentVector); d++) {
539 geomParent = vector_get(
struct X3D_Node *, shapeParent->_parentVector,d);
541 #ifdef FRUSTUMVERBOSE
542 printf (
"setExtent in loop, parent %u of shape %s is %s\n",c,stringNodeType(shapeParent->_nodeType),
543 stringNodeType(geomParent->_nodeType));
546 if (!checkNode(geomParent, __FILE__, __LINE__)) printf (
"problem here with checkNode\n");
556 #ifdef FRUSTUMVERBOSE
557 printf (
"setExtent - now I am %p (%s) has extent maxx %f minx %f maxy %f miny %f maxz %f minz %f\n",
558 me, stringNodeType(me->_nodeType),
565 printf (
"setExtent - now parent %p (%s) has extent maxx %f minx %f maxy %f miny %f maxz %f minz %f\n",
566 geomParent, stringNodeType(geomParent->_nodeType),
567 geomParent->EXTENT_MAX_X ,
568 geomParent->EXTENT_MIN_X ,
569 geomParent->EXTENT_MAX_Y ,
570 geomParent->EXTENT_MIN_Y ,
571 geomParent->EXTENT_MAX_Z ,
572 geomParent->EXTENT_MIN_Z);
581 for (i=0; i<count; i++) {
582 quaternion_rotation(ret, quat, v);
588 #define BBV(num,XX,YY,ZZ) \
589 inxyz[num].x= (double) (me->EXTENT_##XX); \
590 inxyz[num].y= (double) (me->EXTENT_##YY); \
591 inxyz[num].z= (double) (me->EXTENT_##ZZ);
593 static void add_translation (
struct point_XYZ *arr,
float x,
float y,
float z,
int count) {
595 for (i=0; i<count; i++) {
603 static void multiply_in_scale(
struct point_XYZ *arr,
float x,
float y,
float z,
int count) {
605 for (i=0; i<count; i++) {
614 void printmatrix(GLDOUBLE* mat) {
616 for(i = 0; i< 16; i++) {
617 printf(
"mat[%d] = %4.3f%s",i,mat[i],i==3 ?
"\n" : i==7?
"\n" : i==11?
"\n" :
"");
627 void propagateExtent(
struct X3D_Node *me) {
628 float minx, miny, minz, maxx, maxy, maxz;
633 if (me==NULL)
return;
636 #ifdef FRUSTUMVERBOSE
637 printf (
"propextent Iam %s, myExtent (%4.2f %4.2f) (%4.2f %4.2f) (%4.2f %4.2f) me %p parents %d\n",
638 stringNodeType(me->_nodeType),
639 me->EXTENT_MAX_X, me->EXTENT_MIN_X,
640 me->EXTENT_MAX_Y, me->EXTENT_MIN_Y,
641 me->EXTENT_MAX_Z, me->EXTENT_MIN_Z,
642 me, vectorSize(me->_parentVector));
646 if (me->_parentVector == NULL) {
647 ConsoleMessage (
"propagateExtent, parentVector NULL, me %p %s\n",
648 me,stringNodeType(me->_nodeType));
655 maxx = me->EXTENT_MAX_X; minx = me->EXTENT_MIN_X;
656 maxy = me->EXTENT_MAX_Y; miny = me->EXTENT_MIN_Y;
657 maxz = me->EXTENT_MAX_Z; minz = me->EXTENT_MIN_Z;
660 FRUSTUM_TRANS(Transform);
663 FRUSTUM_TRANS(HAnimSite);
664 FRUSTUM_TRANS(HAnimJoint);
667 for (i=0; i<vectorSize(me->_parentVector); i++) {
668 geomParent = vector_get(
struct X3D_Node *, me->_parentVector, i);
674 switch (geomParent->_nodeType) {
676 if (is_GeoLODchild_inrange(X3D_GEOLOD(geomParent), me)) {
682 if (me == X3D_LODNODE(geomParent)->_selected) {
688 if (is_Switchchild_inrange(X3D_SWITCH(geomParent), me)) {
693 if (is_CADLayerchild_inrange(X3D_CADLAYER(geomParent),me)) {
703 #ifdef FRUSTUMVERBOSE
704 printf (
"after transform calcs me (%p %s) my parent %d is (%p %s) ext %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f\n",
705 me, stringNodeType(me->_nodeType),i,geomParent, stringNodeType(geomParent->_nodeType),
706 geomParent->EXTENT_MAX_X, geomParent->EXTENT_MIN_X,
707 geomParent->EXTENT_MAX_Y, geomParent->EXTENT_MIN_Y,
708 geomParent->EXTENT_MAX_Z, geomParent->EXTENT_MIN_Z);
712 if (touched) propagateExtent(geomParent);
719 void moveAndRotateThisPoint(
struct point_XYZ *mypt,
double x,
double y,
double z,
double *MM) {
722 inF[0] = (float) x; inF[1] = (float) y; inF[2] = (float) z;
725 transformf (outF,inF,MM);
728 printf (
"transformed %4.2f %4.2f %4.2f, to %4.2f %4.2f %4.2f\n",inF[0], inF[1], inF[2],
729 outF[0], outF[1], outF[2]);
731 mypt->x = outF[0]; mypt->y=outF[1],mypt->z = outF[2];
741 void record_ZBufferDistance(
struct X3D_Node *node) {
742 GLDOUBLE modelMatrix[16];
749 minMovedDist = -1000000000;
751 #ifdef FRUSTUMVERBOSE
752 printf (
"\nrecordDistance for node %p nodeType %s size %4.2f %4.2f %4.2f ",node, stringNodeType (node->_nodeType),
753 node->EXTENT_MAX_X - node->EXTENT_MIN_X,
754 node->EXTENT_MAX_Y - node->EXTENT_MIN_Y,
755 node->EXTENT_MAX_Z - node->EXTENT_MIN_Z
758 if (APPROX(node->EXTENT_MAX_X,-10000.0)) printf (
"EXTENT NOT INIT");
761 printf (
"recordDistance, max,min %f:%f, %f:%f, %f:%f\n",
762 node->EXTENT_MAX_X , node->EXTENT_MIN_X,
763 node->EXTENT_MAX_Y , node->EXTENT_MIN_Y,
764 node->EXTENT_MAX_Z , node->EXTENT_MIN_Z);
768 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
770 #ifdef TRY_ONLY_ONE_POINT
773 ex = (node->EXTENT_MAX_X - node->EXTENT_MIN_X) / 2.0;
774 ey = (node->EXTENT_MAX_Y - node->EXTENT_MIN_Y) / 2.0;
775 ez = (node->EXTENT_MAX_Z - node->EXTENT_MIN_Z) / 2.0;
776 printf (
" ex %lf ey %lf ez %lf\n",ex,ey,ez);
779 ex = node->EXTENT_MAX_X + node->EXTENT_MIN_X;
780 ey = node->EXTENT_MAX_Y + node->EXTENT_MIN_Y;
781 ez = node->EXTENT_MAX_Z + node->EXTENT_MIN_Z;
786 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
787 printf (
"%lf %lf %lf centre is %lf %lf %lf\n",ex,ey,ez,movedPt.x, movedPt.y, movedPt.z);
788 minMovedDist = movedPt.z;
793 ex = node->EXTENT_MIN_X;
794 ey = node->EXTENT_MIN_Y;
795 ez = node->EXTENT_MIN_Z;
796 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
797 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
800 ex = node->EXTENT_MIN_X;
801 ey = node->EXTENT_MIN_Y;
802 ez = node->EXTENT_MAX_Z;
803 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
804 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
807 ex = node->EXTENT_MIN_X;
808 ey = node->EXTENT_MAX_Y;
809 ez = node->EXTENT_MIN_Z;
810 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
811 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
814 ex = node->EXTENT_MIN_X;
815 ey = node->EXTENT_MAX_Y;
816 ez = node->EXTENT_MAX_Z;
817 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
818 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
821 ex = node->EXTENT_MAX_X;
822 ey = node->EXTENT_MIN_Y;
823 ez = node->EXTENT_MIN_Z;
824 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
825 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
828 ex = node->EXTENT_MAX_X;
829 ey = node->EXTENT_MIN_Y;
830 ez = node->EXTENT_MAX_Z;
831 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
832 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
835 ex = node->EXTENT_MAX_X;
836 ey = node->EXTENT_MAX_Y;
837 ez = node->EXTENT_MIN_Z;
838 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
839 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
842 ex = node->EXTENT_MAX_X;
843 ey = node->EXTENT_MAX_Y;
844 ez = node->EXTENT_MAX_Z;
845 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
846 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
850 node->_dist = minMovedDist;
852 #ifdef FRUSTUMVERBOSE
853 printf (
"I am at %lf %lf %lf\n",Viewer()->currentPosInModel.x, Viewer()->currentPosInModel.y, Viewer()->currentPosInModel.z);
854 printf (
"and distance to the nearest corner of the BB for this node is %lf\n", node->_dist);
859 #undef FRUSTUMVERBOSE
865 void OcclusionStartofRenderSceneUpdateScene() {
876 p->potentialOccluderCount = 0;
879 if (tg->Frustum.OccFailed)
return;
882 if (p->OccInitialized == FALSE) {
883 #ifdef OCCLUSIONVERBOSE
884 printf (
"initializing OcclusionCulling...\n");
887 if (gglobal()->internalc.global_occlusion_disable) {
888 tg->Frustum.OccFailed = TRUE;
891 rdr_caps = gglobal()->display.rdr_caps;
892 if (rdr_caps->av_occlusion_q) {
894 #ifdef OCCLUSIONVERBOSE
895 printf (
"OcclusionStartofRenderSceneUpdateScene: have OcclusionQuery\n");
900 p->OccQuerySize = p->maxOccludersFound + 1000;
902 p->occluderNodePointer = MALLOC (
void **,
sizeof (
void *) * p->OccQuerySize);
903 p->OccQueries = MALLOC (GLuint *,
sizeof(GLuint) * p->OccQuerySize);
904 FW_GL_GENQUERIES(p->OccQuerySize,p->OccQueries);
906 p->OccInitialized = TRUE;
907 for (i=0; i<p->OccQuerySize; i++) {
908 p->occluderNodePointer[i] = 0;
910 p->QueryCount = p->maxOccludersFound;
911 #ifdef OCCLUSIONVERBOSE
912 printf (
"QueryCount now %d\n",p->QueryCount);
916 #ifdef OCCLUSIONVERBOSE
917 printf (
"OcclusionStartofRenderSceneUpdateScene: DO NOT have OcclusionQuery\n");
922 tg->Frustum.OccFailed = TRUE;
931 if (p->maxOccludersFound > p->QueryCount) {
932 if (p->maxOccludersFound > p->OccQuerySize) {
937 if (p->OccQuerySize > 0) {
938 FW_GL_DELETEQUERIES (p->OccQuerySize, p->OccQueries);
942 p->OccQuerySize = p->maxOccludersFound + 1000;
943 p->occluderNodePointer = REALLOC (p->occluderNodePointer,sizeof (
void *) * p->OccQuerySize);
944 p->OccQueries = REALLOC (p->OccQueries,sizeof (GLuint) * p->OccQuerySize);
945 FW_GL_GENQUERIES(p->OccQuerySize,p->OccQueries);
946 ConsoleMessage (
"reinitialized queries... now %p",p->OccQueries);
947 for (i=0; i<p->OccQuerySize; i++) {
948 p->occluderNodePointer[i] = 0;
951 p->QueryCount = p->maxOccludersFound;
952 #ifdef OCCLUSIONVERBOSE
953 printf (
"QueryCount here is %d\n",p->QueryCount);
967 void OcclusionCulling () {
993 zeroVisibilityFlag();
996 if (tg->Frustum.OccFailed)
return;
1008 for (i=0; i<p->potentialOccluderCount; i++) {
1009 #ifdef OCCLUSIONVERBOSE
1010 printf (
"checking node %d of %d\n",i, p->potentialOccluderCount);
1016 shapePtr = X3D_SHAPE(p->occluderNodePointer[i]);
1017 if (shapePtr != NULL) {
1018 if (shapePtr->_nodeType == NODE_Shape) {
1020 checkCount = shapePtr->__occludeCheckCount;
1021 }
else if (shapePtr->_nodeType == NODE_VisibilitySensor) {
1022 visSenPtr = X3D_VISIBILITYSENSOR(shapePtr);
1024 checkCount = visSenPtr->__occludeCheckCount;
1026 printf (
"OcclusionCulling on node type %s not allowed\n",stringNodeType(shapePtr->_nodeType));
1031 #ifdef OCCLUSIONVERBOSE
1032 if (shapePtr) printf (
"OcclusionCulling, for a %s (index %d ptr %p) checkCount %d\n",stringNodeType(shapePtr->_nodeType),i,shapePtr,checkCount);
1033 else printf (
"OcclusionCulling, for a %s (index %d) checkCount %d\n",stringNodeType(visSenPtr->_nodeType),i,checkCount);
1038 FW_GL_GETQUERYOBJECTUIV(p->OccQueries[i],GL_QUERY_RESULT_AVAILABLE,&p->OccResultsAvailable);
1039 PRINT_GL_ERROR_IF_ANY(
"FW_GL_GETQUERYOBJECTUIV::QUERY_RESULTS_AVAIL");
1041 #define SLEEP_FOR_QUERY_RESULTS
1042 #ifdef SLEEP_FOR_QUERY_RESULTS
1044 while (p->OccResultsAvailable == GL_FALSE) {
1046 FW_GL_GETQUERYOBJECTUIV(p->OccQueries[i],GL_QUERY_RESULT_AVAILABLE,&p->OccResultsAvailable);
1047 PRINT_GL_ERROR_IF_ANY(
"FW_GL_GETQUERYOBJECTUIV::QUERY_RESULTS_AVAIL");
1052 #ifdef OCCLUSIONVERBOSE
1053 if (p->OccResultsAvailable == GL_FALSE) printf (
"results not ready for %d\n",i);
1058 if (p->OccResultsAvailable == GL_FALSE) samples = 10000;
1060 FW_GL_GETQUERYOBJECTUIV (p->OccQueries[i], GL_QUERY_RESULT, &samples);
1061 PRINT_GL_ERROR_IF_ANY(
"FW_GL_GETQUERYOBJECTUIV::QUERY");
1063 #ifdef OCCLUSIONVERBOSE
1064 printf (
"i %d checkc %d samples %d\n",i,checkCount,samples);
1067 if (p->occluderNodePointer[i] != 0) {
1070 if (visSenPtr != NULL) {
1072 #ifdef OCCLUSIONVERBOSE
1073 printf (
"OcclusionCulling, found VisibilitySensor at %d, fragments %d active %d\n",i,samples,checkCount);
1079 if (checkCount != OCCCHECKNEXTLOOP) {
1082 visSenPtr->__visible = TRUE;
1083 visSenPtr->__occludeCheckCount = OCCCHECKNEXTLOOP;
1084 visSenPtr->__Samples = samples;
1086 visSenPtr->__occludeCheckCount = OCCCHECKSOON;
1087 visSenPtr->__visible =FALSE;
1088 visSenPtr->__Samples = 0;
1100 else if (shapePtr != NULL) {
1101 #ifdef OCCLUSIONVERBOSE
1102 printf (
"OcclusionCulling, found Shape %d, fragments %d active %d\n",i,samples,checkCount);
1108 if (checkCount != OCCWAIT) {
1111 if (samples > OCCSHAPESAMPLESIZE) {
1112 TRACE_MSG (
"Shape %p is VISIBLE\n",shapePtr);
1113 shapePtr->__visible = TRUE;
1114 shapePtr->__occludeCheckCount= OCCWAIT;
1115 shapePtr->__Samples = samples;
1117 TRACE_MSG (
"Shape %p is NOT VISIBLE\n",shapePtr);
1118 shapePtr->__visible=FALSE;
1119 shapePtr->__occludeCheckCount = OCCCHECKSOON;
1120 shapePtr->__Samples = 0;
1133 void zeroOcclusion(
void) {
1142 if (tg->Frustum.OccFailed)
return;
1144 #ifdef OCCLUSIONVERBOSE
1145 printf (
"zeroOcclusion - potentialOccluderCount %d\n",p->potentialOccluderCount);
1148 for (i=0; i<p->potentialOccluderCount; i++) {
1149 #ifdef OCCLUSIONVERBOSE
1150 printf (
"checking node %d of %d\n",i, p->potentialOccluderCount);
1153 FW_GL_GETQUERYOBJECTUIV(p->OccQueries[i],GL_QUERY_RESULT_AVAILABLE,&p->OccResultsAvailable);
1154 PRINT_GL_ERROR_IF_ANY(
"FW_GL_GETQUERYOBJECTUIV::QUERY_RESULTS_AVAIL");
1155 #ifdef SLEEP_FOR_QUERY_RESULTS
1157 while (p->OccResultsAvailable == GL_FALSE) {
1158 #ifdef OCCLUSIONVERBOSE
1159 printf (
"zero - waiting and looping for results\n");
1162 FW_GL_GETQUERYOBJECTUIV(p->OccQueries[i],GL_QUERY_RESULT_AVAILABLE,&p->OccResultsAvailable);
1163 PRINT_GL_ERROR_IF_ANY(
"FW_GL_GETQUERYOBJECTUIV::QUERY_RESULTS_AVAIL");
1167 #ifdef OCCLUSIONVERBOSE
1168 printf (
"zeroOcclusion - done waiting\n");
1182 p->maxOccludersFound = 0;
1183 p->OccInitialized = FALSE;
1184 p->potentialOccluderCount = 0;
1186 FREE_IF_NZ(p->OccQueries);
1187 FREE_IF_NZ(p->occluderNodePointer);