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"
51static void quaternion_multi_rotation(
struct point_XYZ *ret,
const Quaternion *quat,
const struct point_XYZ * v,
int count);
52static void add_translation (
struct point_XYZ *arr,
float x,
float y,
float z,
int count);
53static 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;
112void *Frustum_constructor(){
113 void *v = MALLOCV(
sizeof(
struct pFrustum));
114 memset(v,0,
sizeof(
struct pFrustum));
117void Frustum_init(
struct tFrustum *t){
119 t->OccFailed = FALSE;
121 t->prv = Frustum_constructor();
123 ppFrustum p = (ppFrustum)t->prv;
125 p->OccQueries = NULL;
128 p->potentialOccluderCount = 0;
129 p->occluderNodePointer = NULL;
133 p->maxOccludersFound = 0;
135 p->OccInitialized = FALSE;
140 p->OccResultsAvailable = FALSE;
146 ppFrustum p = (ppFrustum)gglobal()->Frustum.prv;
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;
165 ppFrustum p = (ppFrustum)gglobal()->Frustum.prv;
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++;
181float *extent6f_constructor(
float *extent6,
float xmin,
float xmax,
float ymin,
float ymax,
float zmin,
float zmax){
183 e[0]=xmax; e[1] = xmin; e[2]=ymax; e[3]=ymin; e[4]=zmax; e[5]=zmin;
186float *extent6f_clear(
float *extent6){
189 e[0]=-10000.0; e[1]=10000.0; e[2]=-10000.0; e[3]=10000.0; e[4]=-10000.0; e[5]=10000.0;
192int extent6f_isSet(
float *extent6){
200 iret = (e[0] >= e[1] && e[2] >= e[3] && e[4] >= e[5]) ? TRUE : FALSE;
203float *extent6f_copy(
float *eout6,
float *ein6){
204 memcpy(eout6,ein6,6*
sizeof(
float));
207void extent6f_to_vec3f(
float *extent6,
float *pmin,
float *pmax){
210 pmin[i] = extent6[i*2 + 1];
211 pmax[i] = extent6[i*2 + 0];
214void extent6f_from_vec3f2(
float *extent6,
float *pmin,
float *pmax){
217 extent6[i*2 + 1] = pmin[i];
218 extent6[i*2 + 0] = pmax[i];
223float *extent6f_union_extent6f(
float *extent6,
float *ein6){
225 isa = extent6f_isSet(extent6);
226 isb = extent6f_isSet(ein6);
229 extent6[i*2 + 1] = min(extent6[i*2 + 1], ein6[i*2 + 1]);
230 extent6[i*2 + 0] = max(extent6[i*2 + 0], ein6[i*2 + 0]);
232 else if(isb) extent6f_copy(extent6,ein6);
235float *extent6f_intersect_extent6f(
float *extent6,
float *eina,
float *einb){
237 extent6f_clear(extent6);
238 isa = extent6f_isSet(eina);
239 isb = extent6f_isSet(einb);
242 extent6[i*2 + 1] = max(eina[i*2 + 1], einb[i*2 + 1]);
243 extent6[i*2 + 0] = min(eina[i*2 + 0], einb[i*2 + 0]);
247float *extent6f_union_vec3f(
float *extent6,
float *p3){
249 isa = extent6f_isSet(extent6);
252 extent6[i*2 + 1] = p3[i];
253 extent6[i*2 + 0] = p3[i];
256 extent6[i*2 + 1] = min(extent6[i*2 + 1], p3[i]);
257 extent6[i*2 + 0] = max(extent6[i*2 + 0], p3[i]);
261int extent6f_point_inside(
float *extent6,
float *pd){
263 for(
int i=0;i<3;i++){
264 inside = inside && extent6[i*2 + 1] < pd[i];
265 inside = inside && pd[i] < extent6[i*2 + 0];
269float *extent6f_union_vec2f(
float *extent6,
float *p2){
271 isa = extent6f_isSet(extent6);
274 extent6[i*2 + 1] = p2[i];
275 extent6[i*2 + 0] = p2[i];
278 extent6[i*2 + 1] = min(extent6[i*2 + 1], p2[i]);
279 extent6[i*2 + 0] = max(extent6[i*2 + 0], p2[i]);
283void extent6f_to_box3f8(
float *extent6,
float *p3f8){
290 p3f8[n*3 + 0] = extent6[0 + i];
291 p3f8[n*3 + 1] = extent6[2 + j];
292 p3f8[n*3 + 2] = extent6[4 + k];
296float * extent6f_from_box3fn(
float *extent6,
float *p,
int n){
298 extent6f_clear(extent6);
300 extent6f_union_vec3f(extent6,&p[i*3]);
303float * extent6f_from_box2fn(
float *extent6,
float *p,
int n){
305 extent6f_clear(extent6);
307 extent6f_union_vec2f(extent6,&p[i*2]);
310float *extent6f_scale3f(
float *eout6,
float *ein6,
float *s3){
313 eout6[i*2 + 0] = ein6[i*2 + 0] * s3[i];
314 eout6[i*2 + 1] = ein6[i*2 + 1] * s3[i];
318float *extent6f_translate3f(
float *eout6,
float *ein6,
float *p3){
321 eout6[i*2 + 0] = ein6[i*2 + 0] + p3[i];
322 eout6[i*2 + 1] = ein6[i*2 + 1] + p3[i];
326float *extent6f_translate3d(
float *eout6,
float *ein6,
double *p3){
329 eout6[i*2 + 0] = ein6[i*2 + 0] + p3[i];
330 eout6[i*2 + 1] = ein6[i*2 + 1] + p3[i];
334float *extent6f_get_center3f(
float *extent6,
float *center3){
337 center3[i] = .5f*(extent6[i*2 + 0] + extent6[i*2 + 1]);
341float extent6f_get_maxsize(
float *extent6){
346 msize = max(msize,extent6[i*2 + 0] - extent6[i*2 + 1]);
350void extent6f2bbox(
float *extent6,
float* center,
float *size){
352 for(
int i=0;i<3;i++){
353 if(extent6[2*i] >= extent6[2*i+1]){
354 center[i] = .5f*extent6[2*i] + .5f*extent6[2*i+1];
355 size[i] = extent6[2*i+0] - extent6[2*i+1];
362void bbox2extent6f(
float* center,
float *size,
float *extent6){
364 for(
int i=0;i<3;i++){
366 extent6[2*i +0] = center[i] + .5f*size[i];
367 extent6[2*i +1] = center[i] - .5f*size[i];
369 extent6[2*i +0] = -10000.0f;
370 extent6[2*i +1] = 10000.0f;
375float extent6f_get_maxradius(
float *extent6){
377 float radius, p3f8[8][3], pc[3], pd[3];
380 extent6f_get_center3f(extent6,pc);
381 extent6f_to_box3f8(extent6, p3f8[0]);
383 vecdif3f(pd,p3f8[i],pc);
384 radius = max(radius, veclength3f(pd));
388float *extent6f_rotate4f(
float *eout6,
float *ein6,
float *vrot4){
394 extent6f_to_box3f8(ein6,p3f[0]);
395 float2double(p3d[0],p3f[0],24);
396 vrmlrot_to_quaternion(&rq,vrot4[0],vrot4[1], vrot4[2], vrot4[3]);
398 quaternion_rotationd(p3d[i],&rq,p3d[i]);
400 double2float(p3f[0],p3d[0],24);
401 extent6f_from_box3fn(eout6,p3f[0],8);
405float *extent6f_rotate4d(
float *eout6,
float *ein6,
double *vrot4){
411 extent6f_to_box3f8(ein6,p3f[0]);
412 float2double(p3d[0],p3f[0],24);
413 vrmlrot_to_quaternion(&rq,vrot4[0],vrot4[1], vrot4[2], vrot4[3]);
415 quaternion_rotationd(p3d[i],&rq,p3d[i]);
417 double2float(p3f[0],p3d[0],24);
418 extent6f_from_box3fn(eout6,p3f[0],8);
421float *extent6f_mattransform4d(
float *eout6,
float *ein6,
double *mat4){
426 if(extent6f_isSet(ein6)){
427 extent6f_to_box3f8(ein6,p3f[0]);
428 float2double(p3d[0],p3f[0],24);
430 transformAFFINEd(p3d[i],p3d[i],mat4);
432 double2float(p3f[0],p3d[0],24);
433 extent6f_from_box3fn(eout6,p3f[0],8);
435 extent6f_clear(eout6);
440float *orientedBBox2extent6f(
float *extent6,
float *obb12){
442 float *center = &obb12[0];
443 float *hx = &obb12[3];
444 float *hy = &obb12[6];
445 float *hz = &obb12[9];
446 float p3f[8][3], temp[3], temp2[3];
450 for(
int k=0;k<2;k++){
451 veccopy3f(temp,center);
452 vecadd3f(temp,temp,vecscale3f(temp2,hx,i?1.0f:-1.0f));
453 vecadd3f(temp,temp,vecscale3f(temp2,hy,j?1.0f:-1.0f));
454 vecadd3f(temp,temp,vecscale3f(temp2,hz,k?1.0f:-1.0f));
455 veccopy3f(p3f[ijk], temp);
458 extent6f_from_box3fn(extent6,p3f[0], 8);
461float *orientedBBox2vec3fn(
float *p3fn24,
float *obb12){
463 float *center = &obb12[0];
464 float *hx = &obb12[3];
465 float *hy = &obb12[6];
466 float *hz = &obb12[9];
467 float *p3f[8], temp[3], temp2[3];
468 for(
int i=0;i<8;i++) p3f[i] = &p3fn24[3*i];
472 for(
int k=0;k<2;k++){
473 veccopy3f(temp,center);
474 vecadd3f(temp,temp,vecscale3f(temp2,hx,i?1.0f:-1.0f));
475 vecadd3f(temp,temp,vecscale3f(temp2,hy,j?1.0f:-1.0f));
476 vecadd3f(temp,temp,vecscale3f(temp2,hz,k?1.0f:-1.0f));
477 veccopy3f(p3f[ijk], temp);
484float *orientedBBox_mattransform4d(
float *out12,
float *obb12,
double *mat4){
488 float fmat4[16], fmat3[9],fmat3i[9],normat[9];
489 matdouble2float4(fmat4,mat4);
490 mat423f(fmat3,fmat4);
491 matinverse3f(fmat3i,fmat3);
492 mattranspose3f(normat,fmat3i);
495 transform3x3f(&out12[(i+1)*3],&obb12[(i+1)*3],normat);
497 transformf(out12,obb12,mat4);
501float *orientedBBox_mattransformAFFINE4d(
float *p3fn24,
float *obb12,
double *mat4){
508 for(
int i=0;i<8;i++) p3f[i] = &p3fn24[3*i];
510 orientedBBox2vec3fn(p3f[0],obb12);
511 for(
int i=0;i<8;i++){
512 float2double(d1,p3f[i],3);
513 transformAFFINEd(d2,d1,mat4);
514 double2float(p3f[i],d2,3);
518void extent6f_printf(
float *extent6){
520 printf(
"min,max x:%8.1f,%8.1f y:%8.1f,%8.1f z:%8.1f,%8.1f ",e[1],e[0],e[3],e[2],e[5],e[4]);
522void union_group_extent(
float *e6);
523void extent6f_setNodeExtentB(
float *extent6,
struct X3D_Node *node){
524 extent6f_copy(node->_extent,extent6);
525 union_group_extent(extent6);
527void extent6f_setParentExtentB(
float *extent6,
struct X3D_Node *me){
533 #ifdef FRUSTUMVERBOSE
535 printf(
" extent6f_setNodeExtentB me %p nt %s\n",me,stringNodeType(me->_nodeType));
540 if (me->_parentVector == NULL) {
541 #ifdef FRUSTUMVERBOSE
542 printf (
"setExtent, parentVector NULL for node %p type %s\n",
543 me,stringNodeType(me->_nodeType));
548 for (i=0; i<vectorSize(me->_parentVector); i++) {
549 shapeParent = vector_get(
struct X3D_Node *, me->_parentVector,i);
550 extent6f_copy(shapeParent->_extent,e);
551 for (j=0; j<vectorSize(shapeParent->_parentVector); j++) {
552 groupParent = vector_get(
struct X3D_Node *, shapeParent->_parentVector,j);
556 extent6f_union_extent6f(groupParent->_extent,e);
574void planed_setCoefficients(
struct Planed* p,
double a,
double b,
double c,
double d) {
577 vecsetd(p->normal,a,b,c);
579 double length = veclengthd(p->normal);
581 vecscaled(p->normal,p->normal,1.0/length);
584 vecscaled(p->p,p->normal,p->d);
586int imat(
int irow,
int icol){
588 int index = (icol-1)*4 + (irow-1);
591void setFrustumPlanes(
double *mvpMatrix,
struct Planed *pl) {
592 double *m = mvpMatrix;
593 planed_setCoefficients(&pl[NEARP],
594 m[imat(3,1)] + m[imat(4,1)],
595 m[imat(3,2)] + m[imat(4,2)],
596 m[imat(3,3)] + m[imat(4,3)],
597 m[imat(3,4)] + m[imat(4,4)]);
598 planed_setCoefficients(&pl[FARP],
599 -m[imat(3,1)] + m[imat(4,1)],
600 -m[imat(3,2)] + m[imat(4,2)],
601 -m[imat(3,3)] + m[imat(4,3)],
602 -m[imat(3,4)] + m[imat(4,4)]);
603 planed_setCoefficients(&pl[BOTTOM],
604 m[imat(2,1)] + m[imat(4,1)],
605 m[imat(2,2)] + m[imat(4,2)],
606 m[imat(2,3)] + m[imat(4,3)],
607 m[imat(2,4)] + m[imat(4,4)]);
608 planed_setCoefficients(&pl[TOP],
609 -m[imat(2,1)] + m[imat(4,1)],
610 -m[imat(2,2)] + m[imat(4,2)],
611 -m[imat(2,3)] + m[imat(4,3)],
612 -m[imat(2,4)] + m[imat(4,4)]);
613 planed_setCoefficients(&pl[LEFT],
614 m[imat(1,1)] + m[imat(4,1)],
615 m[imat(1,2)] + m[imat(4,2)],
616 m[imat(1,3)] + m[imat(4,3)],
617 m[imat(1,4)] + m[imat(4,4)]);
618 planed_setCoefficients(&pl[RIGHT],
619 -m[imat(1,1)] + m[imat(4,1)],
620 -m[imat(1,2)] + m[imat(4,2)],
621 -m[imat(1,3)] + m[imat(4,3)],
622 -m[imat(1,4)] + m[imat(4,4)]);
658int plane_intersect_plane_intersect_plane(
struct Planed *p1,
struct Planed *p2,
struct Planed *p3,
double *point){
661 int intersection = FALSE;
662 double pi[3], ptemp1[3], ptemp2[3], detval;
663 vecsetd(pi,0.0,0.0,0.0);
664 vecscaled(ptemp2,veccrossd(ptemp1,p2->normal,p3->normal),vecdotd(p1->p,p1->normal));
665 vecaddd(pi,pi,ptemp2);
666 vecscaled(ptemp2,veccrossd(ptemp1,p3->normal,p1->normal),vecdotd(p2->p,p2->normal));
667 vecaddd(pi,pi,ptemp2);
668 vecscaled(ptemp2,veccrossd(ptemp1,p1->normal,p2->normal),vecdotd(p3->p,p3->normal));
669 vecaddd(pi,pi,ptemp2);
670 detval = det3d(p1->normal,p2->normal,p3->normal);
673 vecscaled(point,pi,-1.0/detval);
679double plane_distance_to_point(
struct Planed *plane,
double *p){
681 double dist= vecdotd(plane->normal,p);
685int frustum_point_inside(
struct Planed *frustum_planes,
double *p) {
689 for(
int i=0; i < 6; i++) {
691 if(plane_distance_to_point(&frustum_planes[i],p) < 0.0)
696int frustum_generate_corner_points(
struct Planed *frustum_planes,
float *pf24n){
701 int order [] = {LEFT,TOP,RIGHT,BOTTOM};
702 for(
int i=0;i<2;i++){
703 for(
int j=0;j<4;j++){
709 if(!plane_intersect_plane_intersect_plane(&frustum_planes[i],&frustum_planes[jj],&frustum_planes[kk],pi))
711 double2float(&pf24n[n*3],pi,3);
720int frustum_box_inside(
struct Planed *frustum_planes,
float *corners3f,
int np) {
722 int result = INSIDE, out,in;
725 for(
int i=0; i < 6; i++) {
732 for (
int k = 0; k < np && (in==0 || out==0); k++) {
735 float2double(corner,&corners3f[k*3],3);
736 if( plane_distance_to_point(&frustum_planes[i], corner) < 0.0)
752void FRUSTUM_GEOELEVATIONGRID(
struct X3D_Node *me){
754 if (me->_nodeType == NODE_GeoElevationGrid) {
755 if( extent6f_isSet(me->_extent)) {
758 extent6f_rotate4d(ef6, me->_extent, node->__localOrient.c);
759 extent6f_translate3d(ef6,ef6,node->__autoOffset.c);
760 extent6f_setNodeExtentB(ef6,me);
769 int wc = node->whichChoice;
772 int spec = X3D_PROTO(node->_executionContext)->__specversion;
773 if (spec < 300 || (node->choice).n) {
775 if(wc >= 0 && wc < ((node->choice).n)) {
776 void *p = ((node->choice).p[wc]);
777 return (X3D_NODE(p)==me);
780 if(wc >= 0 && wc < ((node->children).n)) {
781 void *p = ((node->children).p[wc]);
782 return (X3D_NODE(p)==me);
810 for (x=0; x<gpnode->rootNode.n; x++) {
819 if (me == X3D_NODE(gpnode->rootNode.p[x])) {
830 return (y ^ gpnode->__inRange);
841void setExtent(
float maxx,
float minx,
float maxy,
float miny,
float maxz,
float minz,
struct X3D_Node *me) {
843 extent6f_constructor(e,minx,maxx,miny,maxy,minz,maxz);
844 extent6f_setNodeExtentB(e,me);
847static void quaternion_multi_rotation(
struct point_XYZ *ret,
const Quaternion *quat,
const struct point_XYZ * v,
int count){
849 for (i=0; i<count; i++) {
850 quaternion_rotation(ret, quat, v);
857static void add_translation (
struct point_XYZ *arr,
float x,
float y,
float z,
int count) {
859 for (i=0; i<count; i++) {
867static void multiply_in_scale(
struct point_XYZ *arr,
float x,
float y,
float z,
int count) {
869 for (i=0; i<count; i++) {
878void printmatrix(GLDOUBLE* mat) {
880 for(i = 0; i< 16; i++) {
881 printf(
"mat[%d] = %4.3f%s",i,mat[i],i==3 ?
"\n" : i==7?
"\n" : i==11?
"\n" :
"");
891void propagateExtent(
struct X3D_Node *me) {
897void moveAndRotateThisPoint(
struct point_XYZ *mypt,
double x,
double y,
double z,
double *MM) {
900 inF[0] = (float) x; inF[1] = (float) y; inF[2] = (float) z;
903 transformf (outF,inF,MM);
906 printf (
"transformed %4.2f %4.2f %4.2f, to %4.2f %4.2f %4.2f\n",inF[0], inF[1], inF[2],
907 outF[0], outF[1], outF[2]);
909 mypt->x = outF[0]; mypt->y=outF[1],mypt->z = outF[2];
929void record_ZBufferDistance(
struct X3D_Node *node,
void *bbfv) {
930 GLDOUBLE modelMatrix[16];
939 minMovedDist = -1000000000;
941 if (APPROX(node->EXTENT_MAX_X,-10000.0)) {
942 #ifdef FRUSTUMVERBOSE
943 printf (
"record_ZBufferDistance: EXTENT NOT INIT\n");
949 bbox2extent6f(bbf->bboxCenter.c,bbf->bboxSize.c,extent);
953 #ifdef FRUSTUMVERBOSE
954 ttrenderstate rs = renderstate();
957 printf (
"\nrecord_ZBufferDistance for node %p nodeType %s size %4.2f %4.2f %4.2f ",
958 node, stringNodeType (node->_nodeType),
959 node->EXTENT_MAX_X - node->EXTENT_MIN_X,
960 node->EXTENT_MAX_Y - node->EXTENT_MIN_Y,
961 node->EXTENT_MAX_Z - node->EXTENT_MIN_Z
964 if (node->_nodeType == NODE_Shape) {
965 printf (
"NODE: %s\n",stringNodeType(X3D_SHAPE(node)->geometry->_nodeType));
971 printf (
"record_ZBufferDistance, bbox size %4.3f,%4.3f,%4.3f, center %4.3f,%4.3f,%4.3f\n",
972 bbf->bboxSize.c[0], bbf->bboxSize.c[1], bbf->bboxSize.c[2],
973 bbf->bboxCenter.c[0], bbf->bboxCenter.c[1], bbf->bboxCenter.c[2]);
977 printf (
"ext6f %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f\n",
978 extent[0],extent[1],extent[2],extent[3],extent[4],extent[5]);
979 printf (
"oldext %4.2f %4.2f %4.2f %4.2f %4.2f %4.2f\n",
980 node->EXTENT_MAX_X,node->EXTENT_MIN_X,
981 node->EXTENT_MAX_Y,node->EXTENT_MIN_Y,
982 node->EXTENT_MAX_Z,node->EXTENT_MIN_Z);
991 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
993 #ifdef FRUSTUMVERBOSE
994 printf (
"modelMatrix:\n");
995 printf (
"\t%3.2f %3.2f %2.2f %3.2f\n",
996 modelMatrix[0],modelMatrix[1],modelMatrix[2],modelMatrix[3]);
997 printf (
"\t%3.2f %3.2f %2.2f %3.2f\n",
998 modelMatrix[4],modelMatrix[5],modelMatrix[6],modelMatrix[7]);
999 printf (
"\t%3.2f %3.2f %2.2f %3.2f\n",
1000 modelMatrix[8],modelMatrix[9],modelMatrix[10],modelMatrix[11]);
1001 printf (
"\t%3.2f %3.2f %2.2f %3.2f\n",
1002 modelMatrix[12],modelMatrix[13],modelMatrix[14],modelMatrix[15]);
1006 #ifdef DO_CENTER_ONLY
1007 moveAndRotateThisPoint (&movedPt,
1008 bbf->bboxCenter.c[0],
1009 bbf->bboxCenter.c[1],
1010 bbf->bboxCenter.c[2],
1012 printf (
"movd point %f %f %f\n",movedPt.x,movedPt.y,movedPt.z);
1013 minMovedDist = movedPt.z;
1026 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
1027 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
1032 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
1033 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
1038 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
1039 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
1044 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
1045 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
1050 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
1051 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
1056 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
1057 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
1062 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
1063 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
1068 moveAndRotateThisPoint (&movedPt, ex,ey,ez,modelMatrix);
1069 if (movedPt.z > minMovedDist) minMovedDist = movedPt.z;
1072 node->_dist = minMovedDist;
1074#ifdef FRUSTUMVERBOSE
1079#undef FRUSTUMVERBOSE
1085void OcclusionStartofRenderSceneUpdateScene() {
1090 ttglobal tg = gglobal();
1091 p = (ppFrustum)gglobal()->Frustum.prv;
1096 p->potentialOccluderCount = 0;
1099 if (tg->Frustum.OccFailed)
return;
1102 if (p->OccInitialized == FALSE) {
1103 #ifdef OCCLUSIONVERBOSE
1104 printf (
"initializing OcclusionCulling...\n");
1107 if (gglobal()->internalc.global_occlusion_disable) {
1108 tg->Frustum.OccFailed = TRUE;
1111 rdr_caps = gglobal()->display.rdr_caps;
1112 if (rdr_caps->av_occlusion_q) {
1114 #ifdef OCCLUSIONVERBOSE
1115 printf (
"OcclusionStartofRenderSceneUpdateScene: have OcclusionQuery\n");
1120 p->OccQuerySize = p->maxOccludersFound + 1000;
1122 p->occluderNodePointer = MALLOC (
void **,
sizeof (
void *) * p->OccQuerySize);
1123 p->OccQueries = MALLOC (GLuint *,
sizeof(GLuint) * p->OccQuerySize);
1124 FW_GL_GENQUERIES(p->OccQuerySize,p->OccQueries);
1126 p->OccInitialized = TRUE;
1127 for (i=0; i<p->OccQuerySize; i++) {
1128 p->occluderNodePointer[i] = 0;
1130 p->QueryCount = p->maxOccludersFound;
1131 #ifdef OCCLUSIONVERBOSE
1132 printf (
"QueryCount now %d\n",p->QueryCount);
1136 #ifdef OCCLUSIONVERBOSE
1137 printf (
"OcclusionStartofRenderSceneUpdateScene: DO NOT have OcclusionQuery\n");
1142 tg->Frustum.OccFailed = TRUE;
1151 if (p->maxOccludersFound > p->QueryCount) {
1152 if (p->maxOccludersFound > p->OccQuerySize) {
1157 if (p->OccQuerySize > 0) {
1158 FW_GL_DELETEQUERIES (p->OccQuerySize, p->OccQueries);
1162 p->OccQuerySize = p->maxOccludersFound + 1000;
1163 p->occluderNodePointer = REALLOC (p->occluderNodePointer,sizeof (
void *) * p->OccQuerySize);
1164 p->OccQueries = REALLOC (p->OccQueries,sizeof (GLuint) * p->OccQuerySize);
1165 FW_GL_GENQUERIES(p->OccQuerySize,p->OccQueries);
1166 ConsoleMessage (
"reinitialized queries... now %p",p->OccQueries);
1167 for (i=0; i<p->OccQuerySize; i++) {
1168 p->occluderNodePointer[i] = 0;
1171 p->QueryCount = p->maxOccludersFound;
1172 #ifdef OCCLUSIONVERBOSE
1173 printf (
"QueryCount here is %d\n",p->QueryCount);
1187void OcclusionCulling () {
1196 ttglobal tg = gglobal();
1197 p = (ppFrustum)tg->Frustum.prv;
1213 zeroVisibilityFlag();
1216 if (tg->Frustum.OccFailed)
return;
1228 for (i=0; i<p->potentialOccluderCount; i++) {
1229 #ifdef OCCLUSIONVERBOSE
1230 printf (
"checking node %d of %d\n",i, p->potentialOccluderCount);
1236 shapePtr = X3D_SHAPE(p->occluderNodePointer[i]);
1237 if (shapePtr != NULL) {
1238 if (shapePtr->_nodeType == NODE_Shape) {
1240 checkCount = shapePtr->__occludeCheckCount;
1241 }
else if (shapePtr->_nodeType == NODE_VisibilitySensor) {
1242 visSenPtr = X3D_VISIBILITYSENSOR(shapePtr);
1244 checkCount = visSenPtr->__occludeCheckCount;
1246 printf (
"OcclusionCulling on node type %s not allowed\n",stringNodeType(shapePtr->_nodeType));
1251 #ifdef OCCLUSIONVERBOSE
1252 if (shapePtr) printf (
"OcclusionCulling, for a %s (index %d ptr %p) checkCount %d\n",stringNodeType(shapePtr->_nodeType),i,shapePtr,checkCount);
1253 else printf (
"OcclusionCulling, for a %s (index %d) checkCount %d\n",stringNodeType(visSenPtr->_nodeType),i,checkCount);
1258 FW_GL_GETQUERYOBJECTUIV(p->OccQueries[i],GL_QUERY_RESULT_AVAILABLE,&p->OccResultsAvailable);
1259 PRINT_GL_ERROR_IF_ANY(
"FW_GL_GETQUERYOBJECTUIV::QUERY_RESULTS_AVAIL");
1261 #define SLEEP_FOR_QUERY_RESULTS
1262 #ifdef SLEEP_FOR_QUERY_RESULTS
1264 while (p->OccResultsAvailable == GL_FALSE) {
1266 FW_GL_GETQUERYOBJECTUIV(p->OccQueries[i],GL_QUERY_RESULT_AVAILABLE,&p->OccResultsAvailable);
1267 PRINT_GL_ERROR_IF_ANY(
"FW_GL_GETQUERYOBJECTUIV::QUERY_RESULTS_AVAIL");
1272 #ifdef OCCLUSIONVERBOSE
1273 if (p->OccResultsAvailable == GL_FALSE) printf (
"results not ready for %d\n",i);
1278 if (p->OccResultsAvailable == GL_FALSE) samples = 10000;
1280 FW_GL_GETQUERYOBJECTUIV (p->OccQueries[i], GL_QUERY_RESULT, &samples);
1281 PRINT_GL_ERROR_IF_ANY(
"FW_GL_GETQUERYOBJECTUIV::QUERY");
1283 #ifdef OCCLUSIONVERBOSE
1284 printf (
"i %d checkc %d samples %d\n",i,checkCount,samples);
1287 if (p->occluderNodePointer[i] != 0) {
1290 if (visSenPtr != NULL) {
1292 #ifdef OCCLUSIONVERBOSE
1293 printf (
"OcclusionCulling, found VisibilitySensor at %d, fragments %d active %d\n",i,samples,checkCount);
1299 if (checkCount != OCCCHECKNEXTLOOP) {
1302 visSenPtr->__visible = TRUE;
1303 visSenPtr->__occludeCheckCount = OCCCHECKNEXTLOOP;
1304 visSenPtr->__Samples = samples;
1306 visSenPtr->__occludeCheckCount = OCCCHECKSOON;
1307 visSenPtr->__visible =FALSE;
1308 visSenPtr->__Samples = 0;
1320 else if (shapePtr != NULL) {
1321 #ifdef OCCLUSIONVERBOSE
1322 printf (
"OcclusionCulling, found Shape %d, fragments %d active %d\n",i,samples,checkCount);
1328 if (checkCount != OCCWAIT) {
1331 if (samples > OCCSHAPESAMPLESIZE) {
1332 TRACE_MSG (
"Shape %p is VISIBLE\n",shapePtr);
1333 shapePtr->__visible = TRUE;
1334 shapePtr->__occludeCheckCount= OCCWAIT;
1335 shapePtr->__Samples = samples;
1337 TRACE_MSG (
"Shape %p is NOT VISIBLE\n",shapePtr);
1338 shapePtr->__visible=FALSE;
1339 shapePtr->__occludeCheckCount = OCCCHECKSOON;
1340 shapePtr->__Samples = 0;
1353void zeroOcclusion(
void) {
1359 ttglobal tg = gglobal();
1360 p= (ppFrustum)tg->Frustum.prv;
1362 if (tg->Frustum.OccFailed)
return;
1364 #ifdef OCCLUSIONVERBOSE
1365 printf (
"zeroOcclusion - potentialOccluderCount %d\n",p->potentialOccluderCount);
1368 for (i=0; i<p->potentialOccluderCount; i++) {
1369#ifdef OCCLUSIONVERBOSE
1370 printf (
"checking node %d of %d\n",i, p->potentialOccluderCount);
1373 FW_GL_GETQUERYOBJECTUIV(p->OccQueries[i],GL_QUERY_RESULT_AVAILABLE,&p->OccResultsAvailable);
1374 PRINT_GL_ERROR_IF_ANY(
"FW_GL_GETQUERYOBJECTUIV::QUERY_RESULTS_AVAIL");
1375#ifdef SLEEP_FOR_QUERY_RESULTS
1377 while (p->OccResultsAvailable == GL_FALSE) {
1378#ifdef OCCLUSIONVERBOSE
1379 printf (
"zero - waiting and looping for results\n");
1382 FW_GL_GETQUERYOBJECTUIV(p->OccQueries[i],GL_QUERY_RESULT_AVAILABLE,&p->OccResultsAvailable);
1383 PRINT_GL_ERROR_IF_ANY(
"FW_GL_GETQUERYOBJECTUIV::QUERY_RESULTS_AVAIL");
1387#ifdef OCCLUSIONVERBOSE
1388 printf (
"zeroOcclusion - done waiting\n");
1402 p->maxOccludersFound = 0;
1403 p->OccInitialized = FALSE;
1404 p->potentialOccluderCount = 0;
1406 FREE_IF_NZ(p->OccQueries);
1407 FREE_IF_NZ(p->occluderNodePointer);