34#include <libFreeWRL.h>
36#include "../vrml_parser/Structs.h"
37#include "../main/headers.h"
38#include "../vrml_parser/CParseGeneral.h"
39#include "../scenegraph/Vector.h"
40#include "../vrml_parser/CFieldDecls.h"
41#include "../vrml_parser/CParseParser.h"
42#include "../vrml_parser/CParseLexer.h"
43#include "../vrml_parser/CRoutes.h"
44#include "../opengl/OpenGL_Utils.h"
46#include "../scenegraph/quaternion.h"
47#include "../scenegraph/Viewer.h"
48#include "../scenegraph/Component_Shape.h"
49#include "../scenegraph/Component_Geospatial.h"
50#include "../scenegraph/RenderFuncs.h"
51#include "../scenegraph/Component_ProgrammableShaders.h"
52#include "../ui/common.h"
53#include "../scenegraph/LinearAlgebra.h"
55void setup_projection();
66static void saveBGVert (
float *colptr,
float *pt,
int *vertexno,
float *col,
double dist,
double x,
double y,
double z) ;
68void init_bindablestack(
bindablestack *bstack,
int layerId,
int nodetype){
69 bstack->background = newVector(
struct X3D_Node*, 2);
70 bstack->viewpoint = newVector(
struct X3D_Node*, 2);
71 bstack->fog = newVector(
struct X3D_Node*, 2);
72 bstack->navigation = newVector(
struct X3D_Node*, 2);
73 bstack->layerId = layerId;
74 loadIdentityMatrix(bstack->screenorientationmatrix);
75 loadIdentityMatrix(bstack->viewtransformmatrix);
76 loadIdentityMatrix(bstack->posorimatrix);
77 loadIdentityMatrix(bstack->stereooffsetmatrix[0]);
78 loadIdentityMatrix(bstack->stereooffsetmatrix[1]);
81 bstack->viewer = NULL;
82 bstack->nodetype = nodetype;
83 loadIdentityMatrix(bstack->pickraymatrix[0]);
84 loadIdentityMatrix(bstack->pickraymatrix[1]);
87 deleteVector(
struct X3D_Node*, bstack->background);
88 deleteVector(
struct X3D_Node*, bstack->viewpoint);
89 deleteVector(
struct X3D_Node*, bstack->fog);
90 deleteVector(
struct X3D_Node*, bstack->navigation);
91 FREE_IF_NZ(bstack->viewer);
97void *Bindable_constructor(){
98 void *v = MALLOCV(
sizeof(
struct pBindable));
102void Bindable_init(
struct tBindable *t){
110 t->prv = Bindable_constructor();
115 init_bindablestack(&p->bstack,0, NODE_Viewpoint);
117 p->naviinfo.width = 0.25;
118 p->naviinfo.height = 1.6;
119 p->naviinfo.step = 0.75;
120 t->naviinfo = &p->naviinfo;
124void Bindable_clear(
struct tBindable *t){
131 for(i=0;i<vectorSize(t->bstacks);i++){
133 free_bindablestack(bstack);
134 if(i>0) FREE_IF_NZ(bstack);
143 for(i=0;i<vectorSize(tg->Bindable.bstacks);i++){
144 bstacktmp = vector_get(
bindablestack*,tg->Bindable.bstacks,i);
145 if(bstacktmp->layerId == layerId){
155 int layerId = bstack->layerId;
156 while(vectorSize(tg->Bindable.bstacks)<layerId+1)
158 vector_set(
bindablestack*,tg->Bindable.bstacks,layerId,bstack);
163 return getBindableStacksByLayer(tg,tg->Bindable.activeLayer);
165int getBindableStacksCount(
ttglobal tg){
166 return vectorSize(tg->Bindable.bstacks);
168void printStatsBindingStacks()
173 nstacks = getBindableStacksCount(tg);
174 for(i=0;i<nstacks;i++){
175 bstack = getBindableStacksByLayer(tg,i);
177 ConsoleMessage(
"Layer %d",i);
178 if(i == tg->Bindable.activeLayer)
179 ConsoleMessage(
" activeLayer");
180 ConsoleMessage(
":\n");
183 if(i == tg->Bindable.activeLayer)
185 ConsoleMessage(
"Layer %d%s:\n",i,al);
187 ConsoleMessage(
"%25s %d\n",
"Background stack count", vectorSize(bstack->background));
188 ConsoleMessage(
"%25s %d\n",
"Fog stack count", vectorSize(bstack->fog));
189 ConsoleMessage(
"%25s %d\n",
"Navigation stack count", vectorSize(bstack->navigation));
190 ConsoleMessage(
"%25s %d\n",
"Viewpoint stack count", vectorSize(bstack->viewpoint));
195void set_naviWidthHeightStep(
double wid,
double hei,
double step) {
200 p->naviinfo.width = wid;
201 p->naviinfo.height = hei;
202 p->naviinfo.step = step;
215 viewer->speed = (double) node->speed;
216 if (node->avatarSize.n < 2) {
219 if(node->avatarSize.n == 1){
222 double avScale = (double)(node->avatarSize.p[0])/1.6;
223 set_naviWidthHeightStep (.25*avScale,1.6*avScale,.75*avScale);
226 set_naviWidthHeightStep ((
double)(node->avatarSize.p[0]),
227 (
double)(node->avatarSize.p[1]),
228 (
double)((node->avatarSize.p[2])));
232 svptr = node->type.p;
235 for (i=0; i<18; i++)
viewer->oktypes[i] = FALSE;
239 for (i = 0; i < node->type.n; i++) {
241 typeptr = svptr[i]->strptr;
243 if (strcmp(typeptr,
"WALK") == 0) {
244 viewer->oktypes[VIEWER_WALK] = TRUE;
245 if (i==0) fwl_set_viewer_type0(
viewer, VIEWER_WALK);
247 if (strcmp(typeptr,
"FLY") == 0) {
248 viewer->oktypes[VIEWER_FLY] = TRUE;
249 if (i==0) fwl_set_viewer_type0(
viewer, VIEWER_FLY);
251 if (strcmp(typeptr,
"EXAMINE") == 0) {
252 viewer->oktypes[VIEWER_EXAMINE] = TRUE;
253 if (i==0) fwl_set_viewer_type0(
viewer, VIEWER_EXAMINE);
255 if (strcmp(typeptr,
"NONE") == 0) {
256 viewer->oktypes[VIEWER_NONE] = TRUE;
257 if (i==0) fwl_set_viewer_type0(
viewer, VIEWER_NONE);
259 if (strcmp(typeptr,
"EXFLY") == 0) {
260 viewer->oktypes[VIEWER_EXFLY] = TRUE;
261 if (i==0) fwl_set_viewer_type0(
viewer, VIEWER_EXFLY);
263 if (strcmp(typeptr,
"EXPLORE") == 0) {
264 viewer->oktypes[VIEWER_EXPLORE] = TRUE;
265 if (i==0) fwl_set_viewer_type0(
viewer, VIEWER_EXPLORE);
267 if (strcmp(typeptr,
"LOOKAT") == 0) {
268 viewer->oktypes[VIEWER_LOOKAT] = TRUE;
271 if (strcmp(typeptr,
"SPHERICAL") == 0) {
272 viewer->oktypes[VIEWER_SPHERICAL] = TRUE;
273 if (i==0) fwl_set_viewer_type0(
viewer, VIEWER_SPHERICAL);
275 if (strcmp(typeptr,
"TURNTABLE") == 0) {
276 viewer->oktypes[VIEWER_TURNTABLE] = TRUE;
277 if (i == 0) fwl_set_viewer_type0(
viewer, VIEWER_TURNTABLE);
279 if (strcmp(typeptr,
"DIST") == 0) {
280 viewer->oktypes[VIEWER_DIST] = TRUE;
281 if (i == 0) fwl_set_viewer_type0(
viewer, VIEWER_DIST);
284 if (strcmp(typeptr,
"ANY") == 0) {
285 viewer->oktypes[VIEWER_EXAMINE] = TRUE;
286 viewer->oktypes[VIEWER_WALK] = TRUE;
287 viewer->oktypes[VIEWER_EXFLY] = TRUE;
288 viewer->oktypes[VIEWER_FLY] = TRUE;
289 viewer->oktypes[VIEWER_EXPLORE] = TRUE;
290 viewer->oktypes[VIEWER_LOOKAT] = TRUE;
291 viewer->oktypes[VIEWER_SPHERICAL] = TRUE;
292 viewer->oktypes[VIEWER_TURNTABLE] = TRUE;
293 viewer->oktypes[VIEWER_DIST] = TRUE;
294 if (i==0) fwl_set_viewer_type0(
viewer, VIEWER_WALK);
297 viewer->headlight = node->headlight;
302 viewer->transitionTime = node->transitionTime;
304 if (
viewer->transitionTime < 0.0)
viewer->transitionTime = 0.0;
306 viewer->transitionType = VIEWER_TRANSITION_LINEAR;
307 if (node->transitionType.n > 0) {
308 if (strcmp(
"LINEAR", node->transitionType.p[0]->strptr) == 0)
viewer->transitionType = VIEWER_TRANSITION_LINEAR;
309 else if (strcmp(
"TELEPORT", node->transitionType.p[0]->strptr) == 0)
viewer->transitionType = VIEWER_TRANSITION_TELEPORT;
310 else if (strcmp(
"ANIMATE", node->transitionType.p[0]->strptr) == 0)
viewer->transitionType = VIEWER_TRANSITION_ANIMATE;
312 ConsoleMessage (
"Unknown NavigationInfo transitionType :%s:",node->transitionType.p[0]->strptr);
319int layerFromBindable(
struct X3D_Node *node){
321 switch(node->_nodeType){
323 layerId = X3D_VIEWPOINT(node)->_layerId;
break;
324 case NODE_OrthoViewpoint:
325 layerId = X3D_ORTHOVIEWPOINT(node)->_layerId;
break;
326 case NODE_GeoViewpoint:
327 layerId = X3D_GEOVIEWPOINT(node)->_layerId;
break;
328 case NODE_Background:
329 layerId = X3D_BACKGROUND(node)->_layerId;
break;
330 case NODE_TextureBackground:
331 layerId = X3D_TEXTUREBACKGROUND(node)->_layerId;
break;
333 layerId = X3D_FOG(node)->_layerId;
break;
334 case NODE_NavigationInfo:
335 layerId = X3D_NAVIGATIONINFO(node)->_layerId;
break;
343void send_bind_to(
struct X3D_Node *node,
int value) {
348 layerId = layerFromBindable(node);
349 switch (node->_nodeType) {
350 case NODE_Background: {
352 bg->set_bind = value;
353 bind_node (node, getBindableStacksByLayer(tg,bg->_layerId)->background);
357 case NODE_TextureBackground: {
359 tbg->set_bind = value;
360 bind_node (node, getBindableStacksByLayer(tg,tbg->_layerId)->background);
364 case NODE_OrthoViewpoint: {
366 ovp->set_bind = value;
367 setMenuStatusVP(ovp->description->strptr);
368 bind_node (node, getBindableStacksByLayer(tg,ovp->_layerId)->viewpoint);
370 bind_OrthoViewpoint (ovp);
375 case NODE_Viewpoint: {
377 vp->set_bind = value;
378 setMenuStatusVP (vp->description->strptr);
379 bind_node (node, getBindableStacksByLayer(tg,vp->_layerId)->viewpoint);
386 case NODE_GeoViewpoint: {
388 gvp->set_bind = value;
389 setMenuStatusVP (gvp->description->strptr);
390 bind_node (node, getBindableStacksByLayer(tg,gvp->_layerId)->viewpoint);
392 bind_GeoViewpoint (gvp);
400 fg->set_bind = value;
401 bind_node (node, getBindableStacksByLayer(tg,fg->_layerId)->fog);
408 case NODE_NavigationInfo: {
410 nv->set_bind = value;
411 bind_node (node, getBindableStacksByLayer(tg,nv->_layerId)->navigation);
412 if (value==1) set_naviinfo(nv);
417 ConsoleMessage(
"send_bind_to, cant send a set_bind to %s %p!!\n",stringNodeType(node->_nodeType),node);
427static size_t setBindofst(
void *node) {
430 switch (tn->_nodeType) {
431 case NODE_Background:
return offsetof(
struct X3D_Background, set_bind);
433 case NODE_Viewpoint:
return offsetof(
struct X3D_Viewpoint, set_bind);
436 case NODE_Fog:
return offsetof(
struct X3D_Fog, set_bind);
438 default: {printf (
"setBindoffst - huh? node type %d\n",tn->_nodeType); }
444static size_t bindTimeoffst (
struct X3D_Node *node) {
445 X3D_NODE_CHECK(node);
447 switch (node->_nodeType) {
448 case NODE_Background:
return offsetof(
struct X3D_Background, bindTime);
450 case NODE_Viewpoint:
return offsetof(
struct X3D_Viewpoint, bindTime);
453 case NODE_Fog:
return offsetof(
struct X3D_Fog, bindTime);
455 default: {printf (
"bindTimeoffst - huh? node type %s\n",stringNodeType(node->_nodeType)); }
461static size_t isboundofst(
void *node) {
467 X3D_NODE_CHECK(node);
469 switch (tn->_nodeType) {
470 case NODE_Background:
return offsetof(
struct X3D_Background, isBound);
472 case NODE_Viewpoint:
return offsetof(
struct X3D_Viewpoint, isBound);
475 case NODE_Fog:
return offsetof(
struct X3D_Fog, isBound);
477 default: {printf (
"isBoundoffst - huh? node type %s\n",stringNodeType(tn->_nodeType)); }
481int removeNodeFromVector(
int iaction,
struct Vector *v,
struct X3D_Node *node);
487 isBoundPtr = offsetPointer_deref(
int*, node, isboundofst(node));
488 setBindPtr = offsetPointer_deref(
int*, node, setBindofst(node));
491 printf (
"bind_node, node %p (%s), set_bind %d isBound %d\n",node,stringNodeType(node->_nodeType),*setBindPtr,*isBoundPtr);
495 if (*isBoundPtr && (*setBindPtr != 0) ){
497 printf(
"%p already bound\n",node);
509 if (*setBindPtr == 1) {
518 MARK_EVENT (node, (
unsigned int) isboundofst(node));
521 offst = bindTimeoffst(node);
524 dp = offsetPointer_deref(
double*, node, offst);
526 MARK_EVENT (node, offst);
530 if (vectorSize(thisStack)>0) {
533 oldTOS = vector_back(
struct X3D_Node *,thisStack);
536 if (oldTOS == node)
return;
537 isBoundPtr = offsetPointer_deref(
int*, oldTOS, isboundofst(oldTOS));
538 setBindPtr = offsetPointer_deref(
int*, oldTOS, setBindofst(oldTOS));
541 MARK_EVENT (oldTOS, (
unsigned int) isboundofst(oldTOS));
545 vector_pushBack(
struct X3D_Node*,thisStack,node);
548 }
else if (*setBindPtr == 0) {
556 MARK_EVENT (node, (
unsigned int) isboundofst(node));
559 if (vectorSize(thisStack)>0) {
562 oldTOS = vector_back(
struct X3D_Node *,thisStack);
565 if (oldTOS != node) {
566 if(!removeNodeFromVector(0, thisStack, node)){
567 if (node->_nodeType == NODE_Viewpoint){
570 printf (
"can not pop from stack, not top (%p != %p)\n",node,oldTOS);
571 printf (
"%p Viewpoint, description :%s:\n",node,X3D_VIEWPOINT(node)->description->strptr);
572 printf (
"%p Viewpoint, description :%s:\n",oldTOS,X3D_VIEWPOINT(oldTOS)->description->strptr);
573 printf (
"oldTOS, isBound %d, setBindPtr %d\n",*(offsetPointer_deref(
int*, oldTOS, isboundofst(oldTOS))),
574 *(offsetPointer_deref(
int*, oldTOS, setBindofst(oldTOS))));
575 printf(
"and not found in stack\n");
583 vector_popBack(
struct X3D_Node *,thisStack);
584 removeNodeFromVector(0, thisStack, node);
585 if (vectorSize(thisStack)>0) {
587 oldTOS = vector_back(
struct X3D_Node *,thisStack);
590 isBoundPtr = offsetPointer_deref(
int*, oldTOS, isboundofst(oldTOS));
591 setBindPtr = offsetPointer_deref(
int*, oldTOS, setBindofst(oldTOS));
594 MARK_EVENT (oldTOS, (
unsigned int) isboundofst(oldTOS));
603 printf (
"setBindPtr %d\n",*setBindPtr);
609void bind_Fog(
struct X3D_Fog *node){
629void render_Fog_OLD (
struct X3D_Fog *node) {
630 #ifndef GL_ES_VERSION_2_0
636 GLfloat fog_colour [4];
639 GLDOUBLE unit[16] = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
648 if (node->set_bind < 100) {
650 bind_node (X3D_NODE(node), getActiveBindableStacks(tg)->fog);
656 if(!node->isBound)
return;
657 if (node->visibilityRange <= 0.00001)
return;
659 fog_colour[0] = node->color.c[0];
660 fog_colour[1] = node->color.c[1];
661 fog_colour[2] = node->color.c[2];
662 fog_colour[3] = (float) 1.0;
664 fogptr = node->fogType->strptr;
665 foglen = node->fogType->len;
667 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, mod);
668 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
670 FW_GLU_UNPROJECT(0.0f,0.0f,0.0f,mod,proj,viewport,&x,&y,&z);
671 FW_GL_TRANSLATE_D(x,y,z);
673 FW_GLU_UNPROJECT(0.0f,0.0f,0.0f,mod,unit,viewport,&x,&y,&z);
675 FW_GLU_PROJECT(x+1,y,z,mod,unit,viewport,&x1,&y1,&z1);
676 sx = 1/sqrt( x1*x1 + y1*y1 + z1*z1*4 );
677 FW_GLU_PROJECT(x,y+1,z,mod,unit,viewport,&x1,&y1,&z1);
678 sy = 1/sqrt( x1*x1 + y1*y1 + z1*z1*4 );
679 FW_GLU_PROJECT(x,y,z+1,mod,unit,viewport,&x1,&y1,&z1);
680 sz = 1/sqrt( x1*x1 + y1*y1 + z1*z1*4 );
682 FW_GL_SCALE_D(sx,sy,sz);
686 FW_GL_FOGFV(GL_FOG_COLOR,fog_colour);
689 if (strcmp(
"LINEAR",fogptr)) {
691 FW_GL_FOGF(GL_FOG_DENSITY, (
float) (4.0)/ (node->visibilityRange));
692 FW_GL_FOGF(GL_FOG_END, (
float) (node->visibilityRange));
693 FW_GL_FOGI(GL_FOG_MODE, GL_EXP);
696 FW_GL_FOGF(GL_FOG_START, (
float) 1.0);
697 FW_GL_FOGF(GL_FOG_END, (
float) (node->visibilityRange));
698 FW_GL_FOGI(GL_FOG_MODE, GL_LINEAR);
714static void saveBGVert (
float *colptr,
float *pt,
715 int *vertexno,
float *col,
double dist,
716 double x,
double y,
double z) {
718 memcpy (&colptr[*vertexno*3], col,
sizeof(
float)*3);
721 pt[*vertexno*3+0] = (float)(x*dist);
722 pt[*vertexno*3+1] = (float)(y*dist);
723 pt[*vertexno*3+2] = (float)(z*dist);
729static void moveBackgroundCentre () {
732 GLDOUBLE unit[16] = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
739 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, mod);
741 FW_GL_GETDOUBLEV(GL_PROJECTION_MATRIX, proj);
743 FW_GLU_UNPROJECT(0.0f,0.0f,0.0f,mod,proj,viewport,&x,&y,&z);
744 FW_GL_TRANSLATE_D(x,y,z);
749 FW_GLU_UNPROJECT(0.0f,0.0f,0.0f,mod,unit,viewport,&x,&y,&z);
751 FW_GLU_PROJECT(x+1,y,z,mod,unit,viewport,&x1,&y1,&z1);
752 sx = 1/sqrt( x1*x1 + y1*y1 + z1*z1*4 );
753 FW_GLU_PROJECT(x,y+1,z,mod,unit,viewport,&x1,&y1,&z1);
754 sy = 1/sqrt( x1*x1 + y1*y1 + z1*z1*4 );
755 FW_GLU_PROJECT(x,y,z+1,mod,unit,viewport,&x1,&y1,&z1);
756 sz = 1/sqrt( x1*x1 + y1*y1 + z1*z1*4 );
759 FW_GL_SCALE_D(sx,sy,sz);
768 p.x = p.y = p.z = 0.0;
769 matinverseAFFINE(modi,mod);
770 transform(&p,&p,modi);
771 FW_GL_TRANSLATE_D(p.x,p.y,p.z);
778 transform(&q,&q,mod);
779 sx = 1.0/sqrt( q.x*q.x + q.y*q.y + q.z*q.z );
782 transform(&q,&q,mod);
783 sy = 1.0/sqrt( q.x*q.x + q.y*q.y + q.z*q.z );
786 transform(&q,&q,mod);
787 sz = 1.0/sqrt( q.x*q.x + q.y*q.y + q.z*q.z );
791 FW_GL_SCALE_D(sx,sy,sz);
797static void recalculateBackgroundVectors(
struct X3D_Background *node) {
801 double va1, va2, ha1, ha2;
809 struct SFColor *skyCol;
int skyColCt;
810 struct SFColor *gndCol;
int gndColCt;
811 float *skyAng;
int skyAngCt;
812 float *gndAng;
int gndAngCt;
813 float *newPoints;
float *newColors;
814 double outsideRadius, insideRadius;
825 outsideRadius = 1.001;
826 insideRadius = 1.0005;
829 if (node->_nodeType == NODE_Background) {
830 skyCol = node->skyColor.p;
831 gndCol = node ->groundColor.p;
832 skyColCt = node->skyColor.n;
833 gndColCt = node->groundColor.n;
834 skyAng = node->skyAngle.p;
835 gndAng = node ->groundAngle.p;
836 skyAngCt = node->skyAngle.n;
837 gndAngCt = node->groundAngle.n;
840 skyCol = tbnode->skyColor.p;
841 gndCol = tbnode ->groundColor.p;
842 skyColCt = tbnode->skyColor.n;
843 gndColCt = tbnode->groundColor.n;
844 skyAng = tbnode->skyAngle.p;
845 gndAng = tbnode ->groundAngle.p;
846 skyAngCt = tbnode->skyAngle.n;
847 gndAngCt = tbnode->groundAngle.n;
851 if ((skyColCt == 0) & (gndColCt == 0)) {
852 if (node->_nodeType == NODE_Background) {
855 FREE_IF_NZ (node->__points.p);
856 FREE_IF_NZ (node->__colours.p);
857 node->__quadcount = 0;
859 tbnode->_ichange = tbnode->_change;
862 FREE_IF_NZ (tbnode->__points.p);
863 FREE_IF_NZ (tbnode->__colours.p);
864 tbnode->__quadcount = 0;
875 estq += (skyColCt-1) * 20 + 20;
886 if(gndColCt == 1) estq += 40;
887 else if (gndColCt>0) estq += (gndColCt-1) * 20;
890 newPoints = MALLOC (GLfloat *,
sizeof (GLfloat) * estq * 3 * 6);
891 newColors = MALLOC (GLfloat *,
sizeof (GLfloat) * estq * 3 * 6);
899 for(v=0; v < 2; v++) {
900 for(h=0; h<hdiv; h++) {
901 ha1 = h * PI*2 / hdiv;
902 ha2 = (h+1) * PI*2 / hdiv;
903 saveBGVert (newColors, newPoints, &actq,&c1->c[0],outsideRadius, sin(va2)*cos(ha1), cos(va2), sin(va2)*sin(ha1));
904 saveBGVert (newColors, newPoints, &actq,&c1->c[0],outsideRadius, sin(va2)*cos(ha2), cos(va2), sin(va2)*sin(ha2));
905 saveBGVert (newColors, newPoints, &actq,&c1->c[0],outsideRadius, sin(va1)*cos(ha2), cos(va1), sin(va1)*sin(ha2));
906 saveBGVert (newColors, newPoints, &actq,&c1->c[0],outsideRadius, sin(va2)*cos(ha1), cos(va2), sin(va2)*sin(ha1));
907 saveBGVert (newColors, newPoints, &actq,&c1->c[0],outsideRadius, sin(va1)*cos(ha2), cos(va1), sin(va1)*sin(ha2));
908 saveBGVert (newColors, newPoints, &actq,&c1->c[0],outsideRadius, sin(va1)*cos(ha1), cos(va1), sin(va1) * sin(ha1));
926 for(v=0; v<(skyColCt-1); v++) {
929 if (skyAngCt>0) { va2 = skyAng[v];}
932 for(h=0; h<hdiv; h++) {
933 ha1 = h * PI*2 / hdiv;
934 ha2 = (h+1) * PI*2 / hdiv;
935 saveBGVert(newColors,newPoints, &actq,&c2->c[0],outsideRadius, sin(va2)*cos(ha1), cos(va2), sin(va2) * sin(ha1));
936 saveBGVert(newColors,newPoints, &actq,&c2->c[0],outsideRadius, sin(va2)*cos(ha2), cos(va2), sin(va2) * sin(ha2));
937 saveBGVert(newColors,newPoints, &actq,&c1->c[0],outsideRadius, sin(va1)*cos(ha2), cos(va1), sin(va1) * sin(ha2));
938 saveBGVert(newColors,newPoints, &actq,&c2->c[0],outsideRadius, sin(va2)*cos(ha1), cos(va2), sin(va2) * sin(ha1));
939 saveBGVert(newColors,newPoints, &actq,&c1->c[0],outsideRadius, sin(va1)*cos(ha2), cos(va1), sin(va1) * sin(ha2));
940 saveBGVert(newColors,newPoints, &actq,&c1->c[0],outsideRadius, sin(va1) * cos(ha1), cos(va1), sin(va1) * sin(ha1));
947 if (va2 < (PI-0.01)) {
948 for(h=0; h<hdiv; h++) {
949 ha1 = h * PI*2 / hdiv;
950 ha2 = (h+1) * PI*2 / hdiv;
951 saveBGVert(newColors,newPoints,&actq,&c2->c[0],outsideRadius, sin(PI) * cos(ha1), cos(PI), sin(PI) * sin(ha1));
952 saveBGVert(newColors,newPoints,&actq,&c2->c[0],outsideRadius, sin(PI) * cos(ha2), cos(PI), sin(PI) * sin(ha2));
953 saveBGVert(newColors,newPoints,&actq,&c2->c[0],outsideRadius, sin(va2) * cos(ha2), cos(va2), sin(va2) * sin(ha2));
954 saveBGVert(newColors,newPoints,&actq,&c2->c[0],outsideRadius, sin(PI) * cos(ha1), cos(PI), sin(PI) * sin(ha1));
955 saveBGVert(newColors,newPoints,&actq,&c2->c[0],outsideRadius, sin(va2) * cos(ha2), cos(va2), sin(va2) * sin(ha2));
956 saveBGVert(newColors,newPoints,&actq,&c2->c[0],outsideRadius, sin(va2) * cos(ha1), cos(va2), sin(va2) * sin(ha1));
966 for(h=0; h<hdiv; h++) {
967 ha1 = h * PI*2 / hdiv;
968 ha2 = (h+1) * PI*2 / hdiv;
970 saveBGVert(newColors,newPoints,&actq,&c1->c[0],insideRadius, sin(PI) * cos(ha1), cos(PI), sin(PI) * sin(ha1));
971 saveBGVert(newColors,newPoints,&actq,&c1->c[0],insideRadius, sin(PI) * cos(ha2), cos(PI), sin(PI) * sin(ha2));
972 saveBGVert(newColors,newPoints,&actq,&c1->c[0],insideRadius, sin(PI/2) * cos(ha2), cos(PI/2), sin(PI/2) * sin(ha2));
973 saveBGVert(newColors,newPoints,&actq,&c1->c[0],insideRadius, sin(PI) * cos(ha1), cos(PI), sin(PI) * sin(ha1));
974 saveBGVert(newColors,newPoints,&actq,&c1->c[0],insideRadius, sin(PI/2) * cos(ha2), cos(PI/2), sin(PI/2) * sin(ha2));
975 saveBGVert(newColors,newPoints,&actq,&c1->c[0],insideRadius, sin(PI/2) * cos(ha1), cos(PI/2), sin(PI/2) * sin(ha1));
979 for(v=0; v<gndColCt-1; v++) {
982 if (v>=gndAngCt) va2 = PI;
983 else va2 = PI - gndAng[v];
985 for(h=0; h<hdiv; h++) {
986 ha1 = h * PI*2 / hdiv;
987 ha2 = (h+1) * PI*2 / hdiv;
989 saveBGVert(newColors,newPoints,&actq,&c1->c[0],insideRadius, sin(va1)*cos(ha1), cos(va1), sin(va1)*sin(ha1));
990 saveBGVert(newColors,newPoints,&actq,&c1->c[0],insideRadius, sin(va1)*cos(ha2), cos(va1), sin(va1)*sin(ha2));
991 saveBGVert(newColors,newPoints,&actq,&c2->c[0],insideRadius, sin(va2)*cos(ha2), cos(va2), sin(va2)*sin(ha2));
992 saveBGVert(newColors,newPoints,&actq,&c1->c[0],insideRadius, sin(va1)*cos(ha1), cos(va1), sin(va1)*sin(ha1));
993 saveBGVert(newColors,newPoints,&actq,&c2->c[0],insideRadius, sin(va2)*cos(ha2), cos(va2), sin(va2)*sin(ha2));
994 saveBGVert(newColors,newPoints,&actq,&c2->c[0],insideRadius, sin(va2) * cos(ha1), cos(va2), sin(va2)*sin(ha1));
1003 if (actq > (estq*6)) {
1004 printf (
"Background quadcount error, %d > %d\n",
1011 if (node->_nodeType == NODE_Background) {
1016 FREE_IF_NZ (node->__points.p);
1017 FREE_IF_NZ (node->__colours.p);
1018 node->__quadcount = actq;
1020 tbnode->_ichange = tbnode->_change;
1022 FREE_IF_NZ (tbnode->__points.p);
1023 FREE_IF_NZ (tbnode->__colours.p);
1024 tbnode->__quadcount = actq;
1032 float *npp = newPoints;
1033 float *ncp = newColors;
1036 if (node->_nodeType == NODE_Background) {
1037 if (node->__VBO == 0) glGenBuffers(1,(
unsigned int*) &node->__VBO);
1039 if (tbnode->__VBO == 0) glGenBuffers(1,(
unsigned int*) &tbnode->__VBO);
1048 for (i=0; i<actq; i++) {
1049 combinedBuffer[i].vert.c[0] = *npp; npp++;
1050 combinedBuffer[i].vert.c[1] = *npp; npp++;
1051 combinedBuffer[i].vert.c[2] = *npp; npp++;
1052 combinedBuffer[i].col.c[0] = *ncp; ncp++;
1053 combinedBuffer[i].col.c[1] = *ncp; ncp++;
1054 combinedBuffer[i].col.c[2] = *ncp; ncp++;
1055 combinedBuffer[i].col.c[3] = 1.0f;
1057 FREE_IF_NZ(newPoints);
1058 FREE_IF_NZ(newColors);
1061 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,node->__VBO);
1062 glBufferData(GL_ARRAY_BUFFER,
sizeof (
struct MyVertex)*actq, combinedBuffer, GL_STATIC_DRAW);
1064 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER,0);
1067 FREE_IF_NZ(combinedBuffer);
1073 if (renderstate()->render_blend)
return;
1074 if(!node->isBound)
return;
1077 double viewi[16], mat[16];
1081 bstack = getActiveBindableStacks(tg);
1082 matinverseAFFINE(viewi,bstack->viewmatrix);
1083 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX,mat);
1085 matmultiplyAFFINE(bstack->backgroundmatrix,mat,viewi);
1090 if (renderstate()->render_blend)
return;
1091 if(!node->isBound)
return;
1094 double viewi[16], mat[16];
1098 bstack = getActiveBindableStacks(tg);
1099 matinverseAFFINE(viewi,bstack->viewmatrix);
1100 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX,mat);
1102 matmultiplyAFFINE(bstack->backgroundmatrix,mat,viewi);
1110 if (renderstate()->render_blend)
return;
1114 if (node->set_bind < 100) {
1115 bind_node (X3D_NODE(node), getActiveBindableStacks(tg)->background);
1119 if(!node->isBound)
return;
1121 if (vectorSize(getActiveBindableStacks(tg)->fog) >0) glDisable(GL_FOG);
1124 moveBackgroundCentre();
1126 if (NODE_NEEDS_COMPILING) {
1127 recalculateBackgroundVectors(node);
1140 glDisable(GL_DEPTH_TEST);
1141 enableGlobalShader(getMyShader(COLOUR_MATERIAL_SHADER));
1144 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
1145 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, node->__VBO);
1146 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
1147 FW_GL_VERTEX_POINTER(3, GL_FLOAT, (GLsizei)
sizeof(
struct MyVertex), (GLfloat *)BUFFER_OFFSET(0));
1148 FW_GL_COLOR_POINTER(4, GL_FLOAT, (GLsizei)
sizeof(
struct MyVertex), (GLfloat *)BUFFER_OFFSET(
sizeof(
struct SFVec3f)));
1151 sendArraysToGPU (GL_TRIANGLES, 0, node->__quadcount);
1154 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
1155 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
1156 finishedWithGlobalShader();
1159 if (((node->backUrl).n>0) ||
1160 ((node->frontUrl).n>0) ||
1161 ((node->leftUrl).n>0) ||
1162 ((node->rightUrl).n>0) ||
1163 ((node->topUrl).n>0) ||
1164 ((node->bottomUrl).n>0)) {
1166 glEnable(GL_TEXTURE_2D);
1168 FW_GL_VERTEX_POINTER (3,GL_FLOAT,0,BackgroundVert);
1169 FW_GL_NORMAL_POINTER (GL_FLOAT,0,Backnorms);
1170 FW_GL_TEXCOORD_POINTER (2,GL_FLOAT,0,boxtex,0);
1172 enableGlobalShader(getMyShader(ONE_TEX_APPEARANCE_SHADER));
1175 loadBackgroundTextures(node);
1177 finishedWithGlobalShader();
1179 glEnable(GL_DEPTH_TEST);
1184 if (vectorSize(getActiveBindableStacks(tg)->fog) >0) glEnable(GL_FOG);
1198void fw_gluPerspective_2(GLDOUBLE xcenter, GLDOUBLE fovy, GLDOUBLE aspect, GLDOUBLE zNear, GLDOUBLE zFar);
1199void fw_depth_slice_push(
double nearplane,
double farplane){
1219 double save_nearPlane, save_farPlane;
1222 FW_GL_MATRIX_MODE(GL_PROJECTION);
1223 FW_GL_PUSH_MATRIX();
1225 save_nearPlane =
viewer->nearPlane;
1226 save_farPlane =
viewer->farPlane;
1227 viewer->nearPlane = nearplane;
1228 viewer->farPlane = farplane;
1230 viewer->nearPlane = save_nearPlane;
1231 viewer->farPlane = save_farPlane;
1233void fw_depth_slice_pop(){
1234 FW_GL_MATRIX_MODE(GL_PROJECTION);
1236 FW_GL_MATRIX_MODE(GL_MODELVIEW);
1245 if (vectorSize(getActiveBindableStacks(tg)->fog) >0) glDisable(GL_FOG);
1251 moveBackgroundCentre();
1256 double pp[3], mvmat[16], mvinv[16];
1259 bstack = getActiveBindableStacks(tg);
1260 FW_GL_MATRIX_MODE(GL_MODELVIEW);
1261 FW_GL_PUSH_MATRIX();
1262 FW_GL_TRANSFORM_D(bstack->backgroundmatrix);
1268 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, mvmat);
1269 matinverseAFFINE(mvinv,mvmat);
1270 vecsetd(pp,0.0,0.0,0.0);
1271 transformAFFINEd(pp,pp,mvinv);
1272 FW_GL_TRANSLATE_D(pp[0],pp[1],pp[2]);
1275 double sx,sy,sz, q[3],p[3],d[3];
1277 vecsetd(p,0.0,0.0,0.0);
1278 transformAFFINEd(p,p,mvmat);
1279 vecsetd(q,1.0,0.0,0.0);
1280 transformAFFINEd(q,q,mvmat);
1281 sx = 1.0/veclengthd(vecdifd(d,q,p));
1282 vecsetd(q,0.0,1.0,0.0);
1283 transformAFFINEd(q,q,mvmat);
1284 sy = 1.0/veclengthd(vecdifd(d,q,p));
1285 vecsetd(q,0.0,0.0,1.0);
1286 transformAFFINEd(q,q,mvmat);
1287 sz = 1.0/veclengthd(vecdifd(d,q,p));
1289 FW_GL_SCALE_D(sx,sy,sz);
1295 FW_GL_MATRIX_MODE(GL_MODELVIEW);
1296 FW_GL_PUSH_MATRIX();
1297 FW_GL_LOAD_IDENTITY();
1300 double matA2BVVA[16],matBVVA2A[16];
1301 avatar2BoundViewpointVerticalAvatar(matA2BVVA,matBVVA2A);
1302 fw_glSetDoublev(GL_MODELVIEW_MATRIX,matBVVA2A);
1306 if (NODE_NEEDS_COMPILING) {
1307 recalculateBackgroundVectors(node);
1319 didPerspective = FALSE;
1330 FW_GL_SCALE_D (bgscale, bgscale, bgscale);
1333 GLclampd znear, zfar;
1334 fw_depth_slice_push(.1,100);
1335 didPerspective = TRUE;
1337 glDisable(GL_DEPTH_TEST);
1338 glDepthMask(GL_FALSE);
1339 enableGlobalShader(getMyShader(COLOUR_MATERIAL_SHADER));
1342 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
1343 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, node->__VBO);
1344 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
1345 FW_GL_VERTEX_POINTER(3, GL_FLOAT, (GLsizei)
sizeof(
struct MyVertex), (GLfloat *)BUFFER_OFFSET(0));
1346 FW_GL_COLOR_POINTER(4, GL_FLOAT, (GLsizei)
sizeof(
struct MyVertex), (GLfloat *)BUFFER_OFFSET(
sizeof(
struct SFVec3f)));
1349 sendArraysToGPU (GL_TRIANGLES, 0, node->__quadcount);
1352 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
1353 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
1354 finishedWithGlobalShader();
1357 if (((node->backUrl).n>0) ||
1358 ((node->frontUrl).n>0) ||
1359 ((node->leftUrl).n>0) ||
1360 ((node->rightUrl).n>0) ||
1361 ((node->topUrl).n>0) ||
1362 ((node->bottomUrl).n>0)) {
1363 glEnable(GL_TEXTURE_2D);
1365 FW_GL_VERTEX_POINTER (3,GL_FLOAT,0,BackgroundVert);
1366 FW_GL_NORMAL_POINTER (GL_FLOAT,0,Backnorms);
1367 FW_GL_TEXCOORD_POINTER (2,GL_FLOAT,0,boxtex,0);
1369 enableGlobalShader(getMyShader(ONE_TEX_APPEARANCE_SHADER));
1372 loadBackgroundTextures(node);
1373 finishedWithGlobalShader();
1375 glDepthMask(GL_TRUE);
1376 glEnable(GL_DEPTH_TEST);
1378 fw_depth_slice_pop();
1384 if (vectorSize(getActiveBindableStacks(tg)->fog) >0) glEnable(GL_FOG);
1393 if (renderstate()->render_blend)
return;
1398 if (node->set_bind < 100) {
1399 bind_node (X3D_NODE(node), getActiveBindableStacks(tg)->background);
1403 if(!node->isBound)
return;
1406 if (vectorSize(getActiveBindableStacks(tg)->fog) >0) glDisable(GL_FOG);
1409 moveBackgroundCentre();
1411 if NODE_NEEDS_COMPILING
1418 glDisable(GL_DEPTH_TEST);
1420 enableGlobalShader(getMyShader(COLOUR_MATERIAL_SHADER));
1422 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, node->__VBO);
1425 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
1426 FW_GL_VERTEX_POINTER(3, GL_FLOAT,
sizeof(
struct MyVertex), (GLfloat *)BUFFER_OFFSET(0));
1427 FW_GL_COLOR_POINTER(4, GL_FLOAT,
sizeof(
struct MyVertex), (GLfloat *)BUFFER_OFFSET(
sizeof(
struct SFVec3f)));
1429 sendArraysToGPU (GL_TRIANGLES, 0, node->__quadcount);
1431 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
1432 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
1433 finishedWithGlobalShader();
1436 if ((node->backTexture !=0) ||
1437 (node->frontTexture !=0) ||
1438 (node->leftTexture !=0) ||
1439 (node->rightTexture !=0) ||
1440 (node->topTexture !=0) ||
1441 (node->bottomTexture !=0)) {
1444 enableGlobalShader(getMyShader(ONE_TEX_APPEARANCE_SHADER));
1448 loadTextureBackgroundTextures(node);
1450 finishedWithGlobalShader();
1453 glEnable(GL_DEPTH_TEST);
1458 if (vectorSize(getActiveBindableStacks(tg)->fog) >0) glEnable (GL_FOG);
1482 if (vectorSize(getActiveBindableStacks(tg)->fog) >0) glDisable(GL_FOG);
1486 moveBackgroundCentre();
1491 double pp[3], mvmat[16], mvinv[16];
1494 bstack = getActiveBindableStacks(tg);
1495 FW_GL_MATRIX_MODE(GL_MODELVIEW);
1496 FW_GL_PUSH_MATRIX();
1497 FW_GL_TRANSFORM_D(bstack->backgroundmatrix);
1500 FW_GL_GETDOUBLEV(GL_MODELVIEW_MATRIX, mvmat);
1501 matinverseAFFINE(mvinv,mvmat);
1502 vecsetd(pp,0.0,0.0,0.0);
1503 transformAFFINEd(pp,pp,mvinv);
1504 FW_GL_TRANSLATE_D(pp[0],pp[1],pp[2]);
1507 double sx,sy,sz, q[3],p[3],d[3];
1509 vecsetd(p,0.0,0.0,0.0);
1510 transformAFFINEd(p,p,mvmat);
1511 vecsetd(q,1.0,0.0,0.0);
1512 transformAFFINEd(q,q,mvmat);
1513 sx = 1.0/veclengthd(vecdifd(d,q,p));
1514 vecsetd(q,0.0,1.0,0.0);
1515 transformAFFINEd(q,q,mvmat);
1516 sy = 1.0/veclengthd(vecdifd(d,q,p));
1517 vecsetd(q,0.0,0.0,1.0);
1518 transformAFFINEd(q,q,mvmat);
1519 sz = 1.0/veclengthd(vecdifd(d,q,p));
1521 FW_GL_SCALE_D(sx,sy,sz);
1526 if NODE_NEEDS_COMPILING
1533 didPerspective = FALSE;
1537 if(
viewer->nearPlane > bgscale) bgscale =
viewer->nearPlane;
1538 FW_GL_SCALE_D (bgscale, bgscale, bgscale);
1541 GLclampd znear, zfar;
1542 fw_depth_slice_push(.1,100);
1543 didPerspective = TRUE;
1546 glDisable(GL_DEPTH_TEST);
1548 enableGlobalShader(getMyShader(COLOUR_MATERIAL_SHADER));
1550 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, node->__VBO);
1553 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
1554 FW_GL_VERTEX_POINTER(3, GL_FLOAT,
sizeof(
struct MyVertex), (GLfloat *)BUFFER_OFFSET(0));
1555 FW_GL_COLOR_POINTER(4, GL_FLOAT,
sizeof(
struct MyVertex), (GLfloat *)BUFFER_OFFSET(
sizeof(
struct SFVec3f)));
1557 sendArraysToGPU (GL_TRIANGLES, 0, node->__quadcount);
1559 FW_GL_BINDBUFFER(GL_ARRAY_BUFFER, 0);
1560 FW_GL_BINDBUFFER(GL_ELEMENT_ARRAY_BUFFER, 0);
1561 finishedWithGlobalShader();
1564 if ((node->backTexture !=0) ||
1565 (node->frontTexture !=0) ||
1566 (node->leftTexture !=0) ||
1567 (node->rightTexture !=0) ||
1568 (node->topTexture !=0) ||
1569 (node->bottomTexture !=0)) {
1572 enableGlobalShader(getMyShader(ONE_TEX_APPEARANCE_SHADER));
1574 loadTextureBackgroundTextures(node);
1576 finishedWithGlobalShader();
1579 glEnable(GL_DEPTH_TEST);
1581 fw_depth_slice_pop();
1587 if (vectorSize(getActiveBindableStacks(tg)->fog) >0) glEnable (GL_FOG);
1590void render_bound_background(){
1595 if (vectorSize(getActiveBindableStacks(tg)->background) >0){
1596 struct X3D_Node * node = vector_back(
struct X3D_Node *,getActiveBindableStacks(tg)->background);
1597 switch(node->_nodeType){
1598 case NODE_Background:
1601 case NODE_TextureBackground: