35 #include <libFreeWRL.h>
37 #include "../vrml_parser/Structs.h"
38 #include "../vrml_parser/CRoutes.h"
39 #include "../main/headers.h"
41 #include "LinearAlgebra.h"
42 #include "Component_Geospatial.h"
43 #include "../opengl/Frustum.h"
44 #include "../opengl/OpenGL_Utils.h"
45 #include "../scenegraph/Component_Shape.h"
46 #include "../scenegraph/RenderFuncs.h"
57 static void *Component_EnvironSensor_constructor(){
64 void Component_EnvironSensor_init(
struct tComponent_EnvironSensor *t){
67 t->prv = Component_EnvironSensor_constructor();
71 p->candoVisibility = TRUE;
76 #ifdef VISIBILITYOCCLUSION
93 static const struct point_XYZ yvec = {0,0.05,0};
94 static const struct point_XYZ zvec = {0,0,-0.05};
95 static const struct point_XYZ zpvec = {0,0,0.05};
96 static const struct point_XYZ orig = {0,0,0};
97 struct point_XYZ t_zvec, t_yvec, t_orig, t_center;
98 GLDOUBLE modelMatrix[16];
99 GLDOUBLE projMatrix[16];
100 GLDOUBLE view2prox[16];
102 if(!((node->enabled)))
return;
112 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
113 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, projMatrix);
114 FW_GLU_UNPROJECT(orig.x,orig.y,orig.z,modelMatrix,projMatrix,viewport,
115 &t_orig.x,&t_orig.y,&t_orig.z);
116 FW_GLU_UNPROJECT(zvec.x,zvec.y,zvec.z,modelMatrix,projMatrix,viewport,
117 &t_zvec.x,&t_zvec.y,&t_zvec.z);
118 FW_GLU_UNPROJECT(yvec.x,yvec.y,yvec.z,modelMatrix,projMatrix,viewport,
119 &t_yvec.x,&t_yvec.y,&t_yvec.z);
120 matinverse(view2prox,modelMatrix);
121 transform(&t_center,&orig, view2prox);
129 cx = t_center.x - ((node->center ).c[0]);
130 cy = t_center.y - ((node->center ).c[1]);
131 cz = t_center.z - ((node->center ).c[2]);
133 if(((node->size).c[0]) == 0 || ((node->size).c[1]) == 0 || ((node->size).c[2]) == 0)
return;
135 if(fabs(cx) > ((node->size).c[0])/2 ||
136 fabs(cy) > ((node->size).c[1])/2 ||
137 fabs(cz) > ((node->size).c[2])/2) {
147 ((node->__t1).c[0]) = (float)t_center.x;
148 ((node->__t1).c[1]) = (
float)t_center.y;
149 ((node->__t1).c[2]) = (float)t_center.z;
151 VECDIFF(t_zvec,t_orig,dr1r2);
152 VECDIFF(t_yvec,t_orig,dr2r3);
158 len = sqrt(VECSQ(dr1r2)); VECSCALE(dr1r2,1/len);
159 len = sqrt(VECSQ(dr2r3)); VECSCALE(dr2r3,1/len);
175 if(fabs(VECPT(dr1r2, dr2r3)) > 0.001) {
176 printf (
"Sorry, can't handle unevenly scaled ProximitySensors yet :("
177 "dp: %f v: (%f %f %f) (%f %f %f)\n", VECPT(dr1r2, dr2r3),
178 dr1r2.x,dr1r2.y,dr1r2.z,
179 dr2r3.x,dr2r3.y,dr2r3.z
185 if(APPROX(dr1r2.z,1.0)) {
187 ((node->__t2).c[0]) = (float) 0;
188 ((node->__t2).c[1]) = (float) 0;
189 ((node->__t2).c[2]) = (float) 1;
190 ((node->__t2).c[3]) = (float) atan2(-dr2r3.x,dr2r3.y);
191 }
else if(APPROX(dr2r3.y,1.0)) {
193 ((node->__t2).c[0]) = (float) 0;
194 ((node->__t2).c[1]) = (float) 1;
195 ((node->__t2).c[2]) = (float) 0;
196 ((node->__t2).c[3]) = (float) atan2(dr1r2.x,dr1r2.z);
205 VECCP(nor1,nor2,ins);
207 len = sqrt(VECSQ(ins)); VECSCALE(ins,1/len);
210 VECCP(dr1r2,ins, nor1);
211 VECCP(zpvec, ins, nor2);
212 len = sqrt(VECSQ(nor1)); VECSCALE(nor1,1/len);
213 len = sqrt(VECSQ(nor2)); VECSCALE(nor2,1/len);
214 VECCP(nor1,nor2,ins);
216 ((node->__t2).c[3]) = (float) -atan2(sqrt(VECSQ(ins)), VECPT(nor1,nor2));
219 ((node->__t2).c[0]) = (float) ins.x;
220 ((node->__t2).c[1]) = (
float) ins.y;
221 ((node->__t2).c[2]) = (float) ins.z;
236 void do_ProximitySensorTick(
void *ptr) {
241 if (node->__oldEnabled != node->enabled) {
242 node->__oldEnabled = node->enabled;
245 if (!node->enabled)
return;
250 if (!node->isActive) {
252 printf (
"PROX - initial defaults\n");
255 node->isActive = TRUE;
256 node->enterTime = TickTime();
262 if (memcmp ((
void *) &node->position_changed,(
void *) &node->__t1,
sizeof(
struct SFColor))) {
264 printf (
"PROX - position changed!!! \n");
267 memcpy ((
void *) &node->position_changed,
268 (
void *) &node->__t1,
sizeof(
struct SFColor));
271 if (memcmp ((
void *) &node->orientation_changed, (
void *) &node->__t2,
sizeof(
struct SFRotation))) {
273 printf (
"PROX - orientation changed!!!\n ");
276 memcpy ((
void *) &node->orientation_changed,
277 (
void *) &node->__t2,
sizeof(
struct SFRotation));
282 if (node->isActive) {
284 printf (
"PROX - stopping\n");
287 node->isActive = FALSE;
288 node->exitTime = TickTime();
299 void transformMBB(GLDOUBLE *rMBBmin, GLDOUBLE *rMBBmax, GLDOUBLE *matTransform, GLDOUBLE* inMBBmin, GLDOUBLE* inMBBmax);
300 int transformMBB4d(GLDOUBLE *rMBBmin, GLDOUBLE *rMBBmax, GLDOUBLE *matTransform, GLDOUBLE* inMBBmin, GLDOUBLE* inMBBmax,
int isAffine);
301 int __gluInvertMatrixd(
const GLDOUBLE m[16], GLDOUBLE invOut[16]);
302 void __gluMultMatrixVecd(
const GLDOUBLE matrix[16],
const GLDOUBLE in[4], GLDOUBLE out[4]);
305 static void twoPoints2RayMatrix(
double *ptnear,
double* ptfar,
double* rayMatrix){
306 double R1[16], R2[16], R3[16], T[16], rayMatrixInverse[16];
313 mattranslate(T,A[0],A[1],A[2]);
316 if(0) printf(
"Cdif %f %f %f\n",C[0],C[1],C[2]);
317 yaw = atan2(C[0],-C[2]);
318 matrixFromAxisAngle4d(R1, -yaw, 0.0, 1.0, 0.0);
319 transformAFFINEd(C,C,R1);
320 if(0) printf(
"Yawed Cdif %f %f %f\n",C[0],C[1],C[2]);
321 pitch = atan2(C[1],-C[2]);
322 if(0) printf(
"atan2 yaw=%f pitch=%f\n",yaw,pitch);
324 if(0) printf(
"[yaw=%f pitch=%f\n",yaw,pitch);
326 matrixFromAxisAngle4d(R1, pitch, 1.0, 0.0, 0.0);
327 if(0) printmatrix2(R1,
"pure R1");
328 matrixFromAxisAngle4d(R2, yaw, 0.0, 1.0, 0.0);
329 if(0) printmatrix2(R2,
"pure R2");
330 matmultiplyAFFINE(R3,R1,R2);
331 if(0) printmatrix2(R3,
"R3=R1*R2");
332 matmultiplyAFFINE(rayMatrixInverse,R3, T);
333 matinverseAFFINE(rayMatrix,rayMatrixInverse);
337 static int frustumHitsMBB(
float *extent){
342 GLDOUBLE modelMatrix[16], projectionMatrix[16];
344 GLDOUBLE smin[3], smax[3], shapeMBBmin[3], shapeMBBmax[3];
346 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, modelMatrix);
347 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, projectionMatrix);
352 shapeMBBmin[i] = extent[i*2 + 1];
353 shapeMBBmax[i] = extent[i*2];
356 transformMBB(smin,smax,modelMatrix,shapeMBBmin,shapeMBBmax);
358 isIn = smin[2] < 0.0;
384 double rayMatrix[16], modelMatrixPlus[16], projInverse[16], nearplane, farplane;
385 double A[4], B[4], a[4], b[4];
398 a[0] = a[1] = b[0] = b[1] = xy;
403 __gluMultMatrixVecd(projInverse, a, A);
404 vecscaled(A,A,1.0/A[3]);
409 __gluMultMatrixVecd(projInverse, b, B);
410 vecscaled(B,B,1.0/B[3]);
413 twoPoints2RayMatrix(A,B,rayMatrix);
415 matmultiplyAFFINE(modelMatrixPlus,modelMatrix,rayMatrix);
418 transformMBB(smin,smax,modelMatrixPlus,shapeMBBmin,shapeMBBmax);
422 isIn = isIn && smax[i] > 0.0;
424 isIn = isIn && smin[i] < 0.0;
429 transformMBB(smin,smax,modelMatrix,shapeMBBmin,shapeMBBmax);
430 isIn = isIn && smin[2] < nearplane;
431 isIn = isIn && smax[2] > farplane;
449 if (!p->candoVisibility)
return;
460 float emin[3], emax[3];
461 vecadd3f(emax, node->center.c, node->size.c);
462 vecdif3f(emin, node->center.c, node->size.c);
465 node->_extent[i*2 + 1] = emin[i];
466 node->_extent[i*2] = emax[i];
468 ihit = frustumHitsMBB(node->_extent);
478 #ifdef VISIBILITYOCCLUSION
480 if (tg->Frustum.OccFailed) {
481 p->candoVisibility = FALSE;
482 ConsoleMessage(
"VisibilitySensor: OpenGL on this machine does not support GL_ARB_occlusion_query");
489 if (rs->render_blend) {
492 beginOcclusionQuery(node,renderstate()->render_geom);
496 rendVisibilityBox(node);
502 endOcclusionQuery(node,renderstate()->render_geom);
509 #ifdef VISIBILITYOCCLUSION
512 #ifdef HAVE_TO_REIMPLEMENT
513 extern GLfloat boxnorms[];
515 float x = ((node->size).c[0])/2;
516 float y = ((node->size).c[1])/2;
517 float z = ((node->size).c[2])/2;
518 float cx = node->center.c[0];
519 float cy = node->center.c[1];
520 float cz = node->center.c[2];
523 if ((x < 0) || (y < 0) || (z < 0))
return;
526 setExtent(cx+x, cx-x, cx+y, cx-y, cx+z, cx-z,X3D_NODE(node));
532 if NODE_NEEDS_COMPILING {
538 if (!node->__points.p) node->__points.p = MALLOC (
struct SFVec3f*,
sizeof(
struct SFVec3f)*(36));
542 pt = (
float *) node->__points.p;
544 #define PTF0 *pt++ = cx+x; *pt++ = cy+y; *pt++ = cz+z;
545 #define PTF1 *pt++ = cx-x; *pt++ = cy+y; *pt++ = cz+z;
546 #define PTF2 *pt++ = cx-x; *pt++ = cy-y; *pt++ = cz+z;
547 #define PTF3 *pt++ = cx+x; *pt++ = cy-y; *pt++ = cz+z;
548 #define PTR0 *pt++ = cx+x; *pt++ = cy+y; *pt++ = cz-z;
549 #define PTR1 *pt++ = cx-x; *pt++ = cy+y; *pt++ = cz-z;
550 #define PTR2 *pt++ = cx-x; *pt++ = cy-y; *pt++ = cz-z;
551 #define PTR3 *pt++ = cx+x; *pt++ = cy-y; *pt++ = cz-z;
554 PTF0 PTF1 PTF2 PTF0 PTF2 PTF3
555 PTR2 PTR1 PTR0 PTR3 PTR2 PTR0
556 PTF0 PTR0 PTR1 PTF0 PTR1 PTF1
557 PTF3 PTF2 PTR2 PTF3 PTR2 PTR3
558 PTF0 PTF3 PTR3 PTF0 PTR3 PTR0
559 PTF1 PTR1 PTR2 PTF1 PTR2 PTF2
564 FW_GL_DEPTHMASK(FALSE);
570 FW_GL_VERTEX_POINTER(3,GL_FLOAT,0,(GLfloat *)node->__points.p);
571 FW_GL_NORMAL_POINTER(GL_FLOAT,0,boxnorms);
574 sendArraysToGPU (GL_TRIANGLES, 0, 36);
575 FW_GL_DEPTHMASK(TRUE);
576 #endif// HAVE_TO_REIMPLEMENT
578 #endif // VISIBILITYOCCLUSION
581 void do_VisibilitySensorTick (
void *ptr) {
586 if (node->__oldEnabled != node->enabled) {
587 node->__oldEnabled = node->enabled;
590 if (!node->enabled)
return;
594 printf (
"do_VisibilitySensorTick, samples %d\n",node->__samples);
597 if (node->__Samples > 0) {
598 if (!node->isActive) {
600 printf (
"visibilitysensor - now active\n");
604 node->enterTime = TickTime();
609 if (node->isActive) {
611 printf (
"visibilitysensor - going inactive\n");
615 node->exitTime = TickTime();
653 int overlapMBBs(GLDOUBLE *MBBmin1, GLDOUBLE *MBBmax1, GLDOUBLE *MBBmin2, GLDOUBLE* MBBmax2);
678 void do_TransformSensorTick (
void *ptr) {
686 if (node->__oldEnabled != node->enabled) {
687 node->__oldEnabled = node->enabled;
691 if (!node->enabled)
return;
693 if(((node->size).c[0]) <= 0.0f || ((node->size).c[1]) <= 0.0f || ((node->size).c[2]) <= 0.0f)
return;
696 printf (
"do_TransformSensorTick enabled\n");
702 unode = node->targetObject;
707 while((mehit = usehit_next(menode,mehit))){
709 double meinv[16],memin[3],memax[3];
710 float emin[3], emax[3], halfsize[3];
712 matinverseAFFINE(meinv,mehit->mvm);
719 matmultiplyAFFINE(ident,meinv,mehit->mvm);
721 printf(
"inverse check do_TransformSensor\n");
723 for(j=0;j<4;j++) printf(
"%lf ",ident[i*3+j]);
729 vecscale3f(halfsize,node->size.c,.5f);
730 vecadd3f(emax, node->center.c, halfsize);
731 vecdif3f(emin, node->center.c, halfsize);
734 node->_extent[i*2 + 1] = emin[i];
735 node->_extent[i*2] = emax[i];
739 memin[i] = node->_extent[i*2 + 1];
740 memax[i] = node->_extent[i*2];
745 while((uhit = usehit_next(unode,uhit))){
748 double u2me[16], umin[3],umax[3],uumin[3],uumax[3];
749 matmultiplyAFFINE(u2me,uhit->mvm,meinv);
753 umin[i] = unode->_extent[i*2 + 1];
754 umax[i] = unode->_extent[i*2];
756 transformMBB(uumin,uumax,u2me,umin,umax);
758 if( overlapMBBs(memin, memax, uumin, uumax) ){
760 static const struct point_XYZ yvec = {0,0.05,0};
761 static const struct point_XYZ zvec = {0,0,-0.05};
762 static const struct point_XYZ zpvec = {0,0,0.05};
763 static const struct point_XYZ orig = {0,0,0};
770 double t1u[3], t1me[3];
773 if (!node->isActive) {
775 printf (
"transformensor - now active\n");
779 node->enterTime = TickTime();
786 for(i=0;i<3;i++) t1u[i] = (umin[i] + umax[i])*.5;
787 transformAFFINEd(t1me,t1u,u2me);
788 for(i=0;i<3;i++) node->__t1.c[i] = (
float)t1me[i] - node->center.c[i];
789 if (memcmp ((
void *) &node->position_changed,(
void *) &node->__t1,
sizeof(
struct SFColor))) {
791 printf (
"PROX - position changed!!! \n");
794 memcpy ((
void *) &node->position_changed,
795 (
void *) &node->__t1,
sizeof(
struct SFColor));
799 transformAFFINE(&t_yvec,&yvec,u2me);
800 transformAFFINE(&t_zvec,&zvec,u2me);
801 transformAFFINE(&t_orig,&orig,u2me);
802 VECDIFF(t_zvec,t_orig,dr1r2);
803 VECDIFF(t_yvec,t_orig,dr2r3);
809 len = sqrt(VECSQ(dr1r2)); VECSCALE(dr1r2,1/len);
810 len = sqrt(VECSQ(dr2r3)); VECSCALE(dr2r3,1/len);
826 if(fabs(VECPT(dr1r2, dr2r3)) > 0.001) {
827 printf (
"Sorry, can't handle unevenly scaled ProximitySensors yet :("
828 "dp: %f v: (%f %f %f) (%f %f %f)\n", VECPT(dr1r2, dr2r3),
829 dr1r2.x,dr1r2.y,dr1r2.z,
830 dr2r3.x,dr2r3.y,dr2r3.z
836 if(APPROX(dr1r2.z,1.0)) {
838 ((node->__t2).c[0]) = (float) 0;
839 ((node->__t2).c[1]) = (float) 0;
840 ((node->__t2).c[2]) = (float) 1;
841 ((node->__t2).c[3]) = (float) atan2(-dr2r3.x,dr2r3.y);
842 }
else if(APPROX(dr2r3.y,1.0)) {
844 ((node->__t2).c[0]) = (float) 0;
845 ((node->__t2).c[1]) = (float) 1;
846 ((node->__t2).c[2]) = (float) 0;
847 ((node->__t2).c[3]) = (float) atan2(dr1r2.x,dr1r2.z);
856 VECCP(nor1,nor2,ins);
858 len = sqrt(VECSQ(ins)); VECSCALE(ins,1/len);
861 VECCP(dr1r2,ins, nor1);
862 VECCP(zpvec, ins, nor2);
863 len = sqrt(VECSQ(nor1)); VECSCALE(nor1,1/len);
864 len = sqrt(VECSQ(nor2)); VECSCALE(nor2,1/len);
865 VECCP(nor1,nor2,ins);
867 ((node->__t2).c[3]) = (float) -atan2(sqrt(VECSQ(ins)), VECPT(nor1,nor2));
870 ((node->__t2).c[0]) = (float) ins.x;
871 ((node->__t2).c[1]) = (
float) ins.y;
872 ((node->__t2).c[2]) = (float) ins.z;
875 if (memcmp ((
void *) &node->orientation_changed, (
void *) &node->__t2,
sizeof(
struct SFRotation))) {
877 printf (
"PROX - orientation changed!!!\n ");
880 memcpy ((
void *) &node->orientation_changed,
881 (
void *) &node->__t2,
sizeof(
struct SFRotation));
889 if (node->isActive) {
891 printf (
"transformsensor - going inactive\n");
895 node->exitTime = TickTime();
902 node->targetObject->_renderFlags |= VF_USE;
904 node->_renderFlags |= VF_USE;