FreeWRL/FreeX3D  3.0.0
Children.c
1 /*
2 
3 
4 Render the children of nodes.
5 
6 */
7 
8 
9 /****************************************************************************
10  This file is part of the FreeWRL/FreeX3D Distribution.
11 
12  Copyright 2009 CRC Canada. (http://www.crc.gc.ca)
13 
14  FreeWRL/FreeX3D is free software: you can redistribute it and/or modify
15  it under the terms of the GNU Lesser Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  FreeWRL/FreeX3D is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  GNU General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with FreeWRL/FreeX3D. If not, see <http://www.gnu.org/licenses/>.
26 ****************************************************************************/
27 
28 
29 
30 #include <config.h>
31 #include <system.h>
32 #include <display.h>
33 #include <internal.h>
34 
35 #include <libFreeWRL.h>
36 
37 #include "../vrml_parser/Structs.h"
38 #include "quaternion.h"
39 
40 #include "Children.h"
41 #include "Collision.h"
42 #include "../opengl/OpenGL_Utils.h"
43 #include "RenderFuncs.h"
44 #include "../opengl/Frustum.h"
45 
46 #define DJ_KEEP_COMPILER_WARNING 0
47 
48 #if DJ_KEEP_COMPILER_WARNING
49 #define VF_localLight 0x0004
50 #endif
51 
52 /* this grouping node has a local light for a child, render this first */
53 void localLightChildren(struct Multi_Node ch) {
54  int i;
55  for(i=0; i<ch.n; i++) {
56  struct X3D_Node *p = X3D_NODE(ch.p[i]);
57  if (p != NULL) {
58  if ((p->_nodeType == NODE_DirectionalLight) ||
59  (p->_nodeType == NODE_PointLight) ||
60  (p->_nodeType == NODE_SpotLight))
61  render_node(p);
62  }
63  }
64 }
65 
66 /* render all children, except the directionalight ones */
67 void normalChildren(struct Multi_Node ch) {
68  int i;
69  struct X3D_Node *p;
70 
71  for(i=0; i<ch.n; i++) {
72  p = X3D_NODE(ch.p[i]); //ATOMIC OP -if it bombs here with .n valid and .p junk, then addRemoveChildren has just expanded .p and FREEd the old one
73  //ConsoleMessage("NC, ch %d is %p",i,p);
74  if (p != NULL) {
75  /* printf ("child %d of %d is a %s\n",i,ch.n,stringNodeType(p->_nodeType)); */
76  /* as long as this is not a local light... if it is, it will be handled by
77  the localLightChildren function, above */
78  if (p->_nodeType == NODE_DirectionalLight) {
79  if (X3D_DIRECTIONALLIGHT(p)->global == TRUE) render_node(p);
80  } else if (p->_nodeType == NODE_SpotLight) {
81  if (X3D_SPOTLIGHT(p)->global == TRUE) render_node(p);
82  } else if (p->_nodeType == NODE_PointLight) {
83  if (X3D_POINTLIGHT(p)->global == TRUE)
84  render_node(p);
85  } else render_node(p);
86  }
87  }
88 }
89 
90 /* propagate flags up the scene graph */
91 /* used to tell the rendering pass that, there is/used to be nodes
92  * of interest down the branch. Eg, Transparent nodes - no sense going
93  * through it all when rendering only for nodes. */
94 
95 /* void update_renderFlag (struct X3D_Node *p, int flag) { */
96 //void update_renderFlagB (struct X3D_Node *p, int flag, char *fi, int li) {
97 void update_renderFlagB (struct X3D_Node *p, int flag, int li) {
98  int i;
99 
100  /* send notification up the chain */
101 
102 //JAS printf ("start of update_renderFlag from %d for %p (%s) flag %x parents %d\n",li,p, stringNodeType(p->_nodeType),
103 //JAS flag, vectorSize(p->_parentVector));
104 //JAS if (p->_nodeType == NODE_Shape) {
105 //JAS printf ("... and this one is our Shape...\n");
106 //JAS for (i = 0; i < vectorSize(p->_parentVector); i++) {
107 //JAS struct X3D_Node *me = vector_get(struct X3D_Node *,p->_parentVector, i);
108 //JAS printf ("Shape parent %d is %p, type %s\n",i,me,stringNodeType(me->_nodeType));
109 //JAS }
110 //JAS }
111 
112 
113 
114 //JAS if (vectorSize(p->_parentVector) <=0) {
115  //printf ("update_renderFlag, for node %p (%s), parentVector is zero, returning...\n",p,stringNodeType(p->_nodeType));
116 //JAS return;
117 //JAS }
118 
119  //if (p==NULL) {
120  // ConsoleMessage ("update_renderFlag, p NULL from %s:%d\n",fi,li);
121  // return;
122  //}
123 
124  p->_renderFlags = p->_renderFlags | flag;
125 
126  if (p->_parentVector == NULL) {
127  //ConsoleMessage ("update_renderFlag, %p->parentVector NULL refcount %d (%s) from %s:%d\n",p,p->referenceCount,stringNodeType(p->_nodeType),fi,li);
128  return;
129  }
130 
131  for (i = 0; i < vectorSize(p->_parentVector); i++) {
132  struct X3D_Node *me = vector_get(struct X3D_Node *,p->_parentVector, i);
133 
134  // JAS printf ("update_renderFlagB, reference count for parent %p is %d\n",me,me->referenceCount);
135  if (me->referenceCount > 0) {
136 
137  // JAS printf ("update_renderFlagB, line %d node type %p %s\n",__LINE__,me,stringNodeType(me->_nodeType));
138 
139  if (me==NULL) {
140  ConsoleMessage ("update_renderFlag, me NULL for child %d",i);
141  markForDispose(p, TRUE);
142  return;
143  }
144 
145  if (me->_parentVector == NULL) {
146 
147  // JAS printf ("update_renderFlagB, warning, for node %p (%s), pv %d, child has null parentVector\n",p,stringNodeType(p->_nodeType),i);
148  ConsoleMessage ("warning, for node %p (%s), pv %d, child has null parentVector\n",p,stringNodeType(p->_nodeType),i);
149  markForDispose(p, TRUE);
150  return;
151  }
152 
153  // printf ("node %d type %s has node %d type %s for a parent\n",p,stringNodeType(p->_nodeType),me,stringNodeType(me->_nodeType));
154  switch (me->_nodeType) {
155 
156  case NODE_Switch:
157  if (is_Switchchild_inrange(X3D_SWITCH(me),p)) {
158  /* printf ("switch, this is the chosen node\n"); */
159  update_renderFlagB(me,flag, __LINE__);
160  }
161  break;
162 
163  case NODE_LOD:
164  /* works for both X3D and VRML syntax; compare with the "_selected" field */
165  if (p == X3D_LODNODE(me)->_selected) {
166  update_renderFlagB(me,flag, __LINE__);
167  }
168  break;
169 
170  case NODE_GeoLOD:
171  if (is_GeoLODchild_inrange(X3D_GEOLOD(me),p)) {
172  /* printf ("switch, this is the chosen node\n"); */
173  update_renderFlagB(me,flag, __LINE__);
174  }
175  break;
176 
177  case NODE_CADLayer:
178  if (is_CADLayerchild_inrange(X3D_CADLAYER(me),p)) {
179  update_renderFlagB(me,flag, __LINE__);
180  }
181  break;
182 
183  default:
184 
185  update_renderFlagB(me,flag, __LINE__);
186  }
187  } // referenceCount check
188  }
189  /* printf ("finished update_RenderFlag for %d\n",p); */
190 }
191 void UPDATE_RENDERFLAG (struct X3D_Node *p, int flag, char *fi, int li){
192  if (p==NULL) {
193  ConsoleMessage ("update_renderFlag, p NULL from %s:%d\n",fi,li);
194  return;
195  }
196  //profile_start("update_rendrflg");
197  update_renderFlagB (p, flag, __LINE__);
198  //profile_end("update_rendrflg");
199  return;
200 }
201