FreeWRL/FreeX3D  3.0.0
Component_Grouping.c
1 /*
2 
3 
4 X3D Grouping Component
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 "../vrml_parser/CRoutes.h"
39 #include "../main/headers.h"
40 
41 #include "../opengl/OpenGL_Utils.h"
42 #include "../opengl/Frustum.h"
43 #include "../opengl/Material.h"
44 
45 #include "LinearAlgebra.h"
46 #include "Children.h"
47 #include "../scenegraph/RenderFuncs.h"
48 
49 void compile_Transform (struct X3D_Transform *node) {
50  INITIALIZE_EXTENT;
51 
52  /* printf ("changed Transform for node %u\n",node); */
53  node->__do_center = verify_translate ((GLfloat *)node->center.c);
54  node->__do_trans = verify_translate ((GLfloat *)node->translation.c);
55  node->__do_scale = verify_scale ((GLfloat *)node->scale.c);
56  node->__do_rotation = verify_rotate ((GLfloat *)node->rotation.c);
57  node->__do_scaleO = verify_rotate ((GLfloat *)node->scaleOrientation.c);
58 
59  node->__do_anything = (node->__do_center ||
60  node->__do_trans ||
61  node->__do_scale ||
62  node->__do_rotation ||
63  node->__do_scaleO);
64 
65  REINITIALIZE_SORTED_NODES_FIELD(node->children,node->_sortedChildren);
66  MARK_NODE_COMPILED
67 }
68 
69 
70 /* we compile the Group so that children are not continuously sorted */
71 void compile_Group(struct X3D_Group *node) {
72  REINITIALIZE_SORTED_NODES_FIELD(node->children,node->_sortedChildren);
73  /*
74  {
75  int i;
76  ConsoleMessage ("compile_Group, rootNode is %p",rootNode());
77  for (i=0; i<node->children.n; i++) ConsoleMessage ("compile_Group %p, c %d is %p",node,i,node->children.p[i]);
78  for (i=0; i<node->_sortedChildren.n; i++) ConsoleMessage ("compile_Group %p, sc %d is %p",node,i,node->_sortedChildren.p[i]);
79  }
80  */
81  MARK_NODE_COMPILED
82 }
83 
84 /* prep_Group - we need this so that distance (and, thus, distance sorting) works for Groups */
85 void prep_Group (struct X3D_Group *node) {
86  COMPILE_IF_REQUIRED
87  RECORD_DISTANCE
88 
89 /*
90 printf ("prepGroup %p (root %p), flags %x children %d ",node,rootNode,node->_renderFlags,node->children.n);
91 if ((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) printf ("VF_Viewpoint ");
92 if ((node->_renderFlags & VF_Geom) == VF_Geom) printf ("VF_Geom ");
93 if ((node->_renderFlags & VF_localLight) == VF_localLight) printf ("VF_localLight ");
94 if ((node->_renderFlags & VF_Sensitive) == VF_Sensitive) printf ("VF_Sensitive ");
95 if ((node->_renderFlags & VF_Blend) == VF_Blend) printf ("VF_Blend ");
96 if ((node->_renderFlags & VF_Proximity) == VF_Proximity) printf ("VF_Proximity ");
97 if ((node->_renderFlags & VF_Collision) == VF_Collision) printf ("VF_Collision ");
98 if ((node->_renderFlags & VF_globalLight) == VF_globalLight) printf ("VF_globalLight ");
99 if ((node->_renderFlags & VF_hasVisibleChildren) == VF_hasVisibleChildren) printf ("VF_hasVisibleChildren ");
100 if ((node->_renderFlags & VF_shouldSortChildren) == VF_shouldSortChildren) printf ("VF_shouldSortChildren ");*/
101 /*if ((node->_renderFlags & VF_inPickableGroup) == VF_inPickableGroup) printf ("VF_inPickableGroup "); */
102 /* printf ("\n"); */
103 
104 
105 
106 }
107 
108 /* do transforms, calculate the distance */
109 void prep_Transform (struct X3D_Transform *node) {
110 
111  COMPILE_IF_REQUIRED
112 
113  /* rendering the viewpoint means doing the inverse transformations in reverse order (while poping stack),
114  * so we do nothing here in that case -ncoder */
115 
116  /* printf ("prep_Transform, render_hier vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
117  render_vp,render_geom,render_light,render_sensitive,render_blend,render_proximity,render_collision); */
118 
119  /* do we have any geometry visible, and are we doing anything with geometry? */
120  OCCLUSIONTEST
121 
122  if(!renderstate()->render_vp) {
123  /* do we actually have any thing to rotate/translate/scale?? */
124  if (node->__do_anything) {
125 
126  FW_GL_PUSH_MATRIX();
127 
128  /* TRANSLATION */
129  if (node->__do_trans)
130  FW_GL_TRANSLATE_F(node->translation.c[0],node->translation.c[1],node->translation.c[2]);
131 
132  /* CENTER */
133  if (node->__do_center)
134  FW_GL_TRANSLATE_F(node->center.c[0],node->center.c[1],node->center.c[2]);
135 
136  /* ROTATION */
137  if (node->__do_rotation) {
138  FW_GL_ROTATE_RADIANS(node->rotation.c[3], node->rotation.c[0],node->rotation.c[1],node->rotation.c[2]);
139  }
140 
141  /* SCALEORIENTATION */
142  if (node->__do_scaleO) {
143  FW_GL_ROTATE_RADIANS(node->scaleOrientation.c[3], node->scaleOrientation.c[0], node->scaleOrientation.c[1],node->scaleOrientation.c[2]);
144  }
145 
146 
147  /* SCALE */
148  if (node->__do_scale)
149  FW_GL_SCALE_F(node->scale.c[0],node->scale.c[1],node->scale.c[2]);
150 
151  /* REVERSE SCALE ORIENTATION */
152  if (node->__do_scaleO)
153  FW_GL_ROTATE_RADIANS(-node->scaleOrientation.c[3], node->scaleOrientation.c[0], node->scaleOrientation.c[1],node->scaleOrientation.c[2]);
154 
155  /* REVERSE CENTER */
156  if (node->__do_center)
157  FW_GL_TRANSLATE_F(-node->center.c[0],-node->center.c[1],-node->center.c[2]);
158  }
159 
160  RECORD_DISTANCE
161 
162  }
163 }
164 
165 
166 void fin_Transform (struct X3D_Transform *node) {
167  OCCLUSIONTEST
168 
169  if(!renderstate()->render_vp) {
170  if (node->__do_anything) {
171  FW_GL_POP_MATRIX();
172  }
173  } else {
174  /*Rendering the viewpoint only means finding it, and calculating the reverse WorldView matrix.*/
175  if((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) {
176  FW_GL_TRANSLATE_F(((node->center).c[0]),((node->center).c[1]),((node->center).c[2])
177  );
178  FW_GL_ROTATE_RADIANS(((node->scaleOrientation).c[3]),((node->scaleOrientation).c[0]),((node->scaleOrientation).c[1]),((node->scaleOrientation).c[2])
179  );
180  FW_GL_SCALE_F((float)1.0/(((node->scale).c[0])),(float)1.0/(((node->scale).c[1])),(float)1.0/(((node->scale).c[2]))
181  );
182  FW_GL_ROTATE_RADIANS(-(((node->scaleOrientation).c[3])),((node->scaleOrientation).c[0]),((node->scaleOrientation).c[1]),((node->scaleOrientation).c[2])
183  );
184  FW_GL_ROTATE_RADIANS(-(((node->rotation).c[3])),((node->rotation).c[0]),((node->rotation).c[1]),((node->rotation).c[2])
185  );
186  FW_GL_TRANSLATE_F(-(((node->center).c[0])),-(((node->center).c[1])),-(((node->center).c[2]))
187  );
188  FW_GL_TRANSLATE_F(-(((node->translation).c[0])),-(((node->translation).c[1])),-(((node->translation).c[2]))
189  );
190  }
191  }
192 }
193 
194 void child_Switch (struct X3D_Switch *node) {
195  /* exceedingly simple - render only one child */
196  struct X3D_Node **pp;
197  int n;
198  int wc = node->whichChoice;
199 
200  /* is this VRML, or X3D?? */
201  n = 0;
202  pp = NULL;
203  if(node->children.n){
204  pp = node->children.p;
205  n = node->children.n;
206  } else if(node->choice.n){
207  pp = node->choice.p;
208  n = node->choice.n;
209  }
210  if(n && pp){
211  if(wc >= 0 && wc < n){
212  void * p = pp[wc];
213  render_node(p);
214  }
215  }
216  //if (node->__isX3D || (node->children).n) {
217  // if(wc >= 0 && wc < (node->children).n) {
218  // void *p = ((node->children).p[wc]);
219  // render_node(p);
220  // }
221  //} else {
222  // if(wc >= 0 && wc < ((node->choice).n)) {
223  // void *p = ((node->choice).p[wc]);
224  // render_node(p);
225  // }
226  //}
227 }
228 
229 
230 
231 void sib_prep_LocalFog(struct X3D_Node *parent, struct X3D_Node *sibAffector);
232 void sib_prep_DirectionalLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
233 void sib_prep_SpotlLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
234 void sib_prep_PointLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
235 void sib_prep_ClipPlane(struct X3D_Node *parent, struct X3D_Node *sibAffector);
236 void sib_prep_Effect(struct X3D_Node *parent, struct X3D_Node *sibAffector);
237 
238 void sib_prep(struct X3D_Node *parent, struct X3D_Node *sibAffector){
239  switch(sibAffector->_nodeType){
240  case NODE_DirectionalLight:
241  sib_prep_DirectionalLight(parent,sibAffector); break;
242  case NODE_SpotLight:
243  sib_prep_SpotlLight(parent,sibAffector); break;
244  case NODE_PointLight:
245  sib_prep_PointLight(parent,sibAffector); break;
246  case NODE_LocalFog:
247  sib_prep_LocalFog(parent,sibAffector); break;
248  case NODE_ClipPlane:
249  sib_prep_ClipPlane(parent,sibAffector); break;
250  case NODE_Effect:
251  sib_prep_Effect(parent,sibAffector); break;
252  default:
253  break;
254  }
255 }
256 
257 void sib_fin_LocalFog(struct X3D_Node *parent, struct X3D_Node *sibAffector);
258 void sib_fin_DirectionalLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
259 void sib_fin_SpotlLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
260 void sib_fin_PointLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
261 void sib_fin_ClipPlane(struct X3D_Node *parent, struct X3D_Node *sibAffector);
262 void sib_fin_Effect(struct X3D_Node *parent, struct X3D_Node *sibAffector);
263 
264 void sib_fin(struct X3D_Node *parent, struct X3D_Node *sibAffector){
265  switch(sibAffector->_nodeType){
266  case NODE_DirectionalLight:
267  sib_fin_DirectionalLight(parent,sibAffector); break;
268  case NODE_SpotLight:
269  sib_fin_SpotlLight(parent,sibAffector); break;
270  case NODE_PointLight:
271  sib_fin_PointLight(parent,sibAffector); break;
272  case NODE_LocalFog:
273  sib_fin_LocalFog(parent,sibAffector); break;
274  case NODE_ClipPlane:
275  sib_fin_ClipPlane(parent,sibAffector); break;
276  case NODE_Effect:
277  sib_fin_Effect(parent,sibAffector); break;
278  default:
279  break;
280  }
281 }
282 void prep_sibAffectors(struct X3D_Node *parent, struct Multi_Node* affectors){
283  if(affectors->n){
284  int j;
285  for(j=0;j<affectors->n;j++){
286  struct X3D_Node *sa = affectors->p[j];
287  sib_prep(parent,sa);
288  }
289  }
290 }
291 void fin_sibAffectors(struct X3D_Node *parent, struct Multi_Node* affectors){
292  if(affectors->n){
293  int j,jj;
294  for(jj=0;jj<affectors->n;jj++){
295  //we go backwards so any sib_fin popping is in reverse order to any sib_prep pushing,
296  // in case multiple push to same stack, as with multiple Effects
297  struct X3D_Node *sa;
298  j = affectors->n - jj - 1;
299  sa = affectors->p[j];
300  sib_fin(parent,sa);
301  }
302  }
303 }
304 
305 void child_StaticGroup (struct X3D_StaticGroup *node) {
306  CHILDREN_COUNT
307  //LOCAL_LIGHT_SAVE
308 
309  RETURN_FROM_CHILD_IF_NOT_FOR_ME
310 
311  /* did this change? */
312  if NODE_NEEDS_COMPILING {
313  REINITIALIZE_SORTED_NODES_FIELD(node->children,node->_sortedChildren);
314  //ConsoleMessage ("StaticGroup changed");
315  MARK_NODE_COMPILED;
316  }
317 
318  /* do we have a local light for a child? */
319  //LOCAL_LIGHT_CHILDREN(node->_sortedChildren);
320  prep_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
321 
322  /* now, just render the non-directionalLight children */
323  normalChildren(node->_sortedChildren);
324 
325  //LOCAL_LIGHT_OFF
326  fin_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
327 
328 }
329 
330 void child_Group (struct X3D_Group *node) {
331  // UNUSED int renderFirstProtoChildOnlyAsPerSpecs = 1;
332  CHILDREN_COUNT
333 // LOCAL_LIGHT_SAVE
334 
335  /*
336 printf ("chldGroup %p (root %p), flags %x children %d ",node,rootNode,node->_renderFlags,node->children.n);
337 if ((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) printf ("VF_Viewpoint ");
338 if ((node->_renderFlags & VF_Geom) == VF_Geom) printf ("VF_Geom ");
339 if ((node->_renderFlags & VF_localLight) == VF_localLight) printf ("VF_localLight ");
340 if ((node->_renderFlags & VF_Sensitive) == VF_Sensitive) printf ("VF_Sensitive ");
341 if ((node->_renderFlags & VF_Blend) == VF_Blend) printf ("VF_Blend ");
342 if ((node->_renderFlags & VF_Proximity) == VF_Proximity) printf ("VF_Proximity ");
343 if ((node->_renderFlags & VF_Collision) == VF_Collision) printf ("VF_Collision ");
344 if ((node->_renderFlags & VF_globalLight) == VF_globalLight) printf ("VF_globalLight ");
345 if ((node->_renderFlags & VF_hasVisibleChildren) == VF_hasVisibleChildren) printf ("VF_hasVisibleChildren ");
346 if ((node->_renderFlags & VF_shouldSortChildren) == VF_shouldSortChildren) printf ("VF_shouldSortChildren ");
347 printf ("\n");
348 */
349 
350  RETURN_FROM_CHILD_IF_NOT_FOR_ME
351 
352  if(1){
353  //stereoscopic experiments
354  ttrenderstate rs = renderstate();
355  if (rs->render_geom) { //== VF_Geom) {
356  if (node->_renderFlags & VF_HideLeft && (viewer_iside() == 0) ) {
357  return;
358  }
359  if (node->_renderFlags & VF_HideRight && (viewer_iside() == 1) ) {
360  return;
361  }
362  }
363  }
364  prep_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
365 
366 
367 #ifdef VERBOSE
368  {
369  int x;
370  struct X3D_Node *xx;
371 
372 printf ("child_Group, children.n %d sortedChildren.n %d\n",node->children.n, node->_sortedChildren.n);
373 
374  printf ("child_Group, this %p rf %x isProto %d\n",node,node->_renderFlags, node->FreeWRL__protoDef);
375 // printf (" ..., render_hier vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
376 // render_vp,render_geom,render_light,render_sensitive,render_blend,render_proximity,render_collision);
377  for (x=0; x<nc; x++) {
378  xx = X3D_NODE(node->_sortedChildren.p[x]);
379  if (xx)
380  printf (" %d: ch %p type %s dist %f\n",x, node->_sortedChildren.p[x],stringNodeType(xx->_nodeType),xx->_dist);
381  else printf (" chiuld %d null\n",x);
382  }
383  for (x=0; x<nc; x++) {
384  xx = X3D_NODE(node->_sortedChildren.p[x]);
385  if (xx)
386  printf (" %d: sch %p type %s dist %f\n",x, node->_sortedChildren.p[x],stringNodeType(xx->_nodeType),xx->_dist);
387  else printf (" chiuld %d null\n",x);
388  }
389  }
390 #endif //VERBOSE
391 
392 
393 
394 
395 
396  /* do we have a DirectionalLight for a child? */
397 // LOCAL_LIGHT_CHILDREN(node->_sortedChildren);
398 
399  /* printf ("chld_Group, for %u, protodef %d and FreeWRL_PROTOInterfaceNodes.n %d\n",
400  node, node->FreeWRL__protoDef, node->FreeWRL_PROTOInterfaceNodes.n); */
401  /* now, just render the non-directionalLight children */
402  // UNUSED renderFirstProtoChildOnlyAsPerSpecs = 0; //flux/vivaty render all children
403  normalChildren(node->_sortedChildren);
404 
405 
406 // LOCAL_LIGHT_OFF
407 
408  fin_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
409 
410 }
411 
412 
413 void child_Transform (struct X3D_Transform *node) {
414  //LOCAL_LIGHT_SAVE
415  CHILDREN_COUNT
416  OCCLUSIONTEST
417 
418  RETURN_FROM_CHILD_IF_NOT_FOR_ME
419 
420  if(1){
421  //stereoscopic experiments
422  ttrenderstate rs = renderstate();
423  if (rs->render_geom) { //== VF_Geom) {
424  if (node->_renderFlags & VF_HideLeft && (viewer_iside() == 0) ) {
425  return;
426  }
427  if (node->_renderFlags & VF_HideRight && (viewer_iside() == 1) ) {
428  return;
429  }
430  }
431  }
432  //if(node->__sibAffectors.n)
433  // printf("have transform sibaffectors\n");
434  prep_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
435 
436  /* any children at all? */
437  if (nc==0) return;
438 
439  //profile_start("local_light_kids");
440  /* do we have a local light for a child? */
441 // LOCAL_LIGHT_CHILDREN(node->_sortedChildren);
442  //profile_end("local_light_kids");
443  /* now, just render the non-directionalLight children */
444 
445  /* printf ("Transform %d, flags %d, render_sensitive %d\n",
446  node,node->_renderFlags,render_sensitive); */
447 
448  #ifdef CHILDVERBOSE
449  printf ("transform - doing normalChildren\n");
450  #endif
451 
452  normalChildren(node->_sortedChildren);
453 
454  #ifdef CHILDVERBOSE
455  printf ("transform - done normalChildren\n");
456  #endif
457 
458 // LOCAL_LIGHT_OFF
459  fin_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
460 }
461 
462 
463 /* prep_Proto - this is a ProtoInstance (not declare) */
464 /*pack 4 flags into one int, using char */
465 char ciflag_get(int flags, int index){
466  char *cflags = (char *)(&flags);
467  return cflags[index];
468 }
469 int ciflag_set(int flags, char flag, int index ){
470  char *cflags = (char *)(&flags);
471  cflags[index] = flag;
472  return flags;
473 }
474 void prep_Proto (struct X3D_Proto *node) {
475  if(0)printf("in prep_proto\n");
476  load_externProtoInstance(node);
477  COMPILE_IF_REQUIRED
478  //RECORD_DISTANCE
479 }
480 /* not sure why we would compile */
481 void compile_Proto(struct X3D_Proto *node) {
482  unsigned char pflag;
483  if(0)printf("in compile_proto\n");
484  pflag = ciflag_get(node->__protoFlags,2);
485  if(pflag == 2){
486  //scene
487  REINITIALIZE_SORTED_NODES_FIELD(node->__children,node->_sortedChildren);
488  }
489  MARK_NODE_COMPILED
490 }
491 
492 
493 /* render the first node only unless scene (see component_networking.c child_inline for scene-similar*/
494 void child_Proto (struct X3D_Proto *node) {
495  int nc;
496  unsigned char sceneflag;
497  int renderFirstProtoChildOnlyAsPerSpecs;
498  //LOCAL_LIGHT_SAVE
499  if(0)printf("in child_proto\n");
500  //CHILDREN_COUNT
501  nc = node->__children.n; //_sortedChildren.n;
502 /*
503 printf ("chldGroup %p (root %p), flags %x children %d ",node,rootNode,node->_renderFlags,node->children.n);
504 if ((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) printf ("VF_Viewpoint ");
505 if ((node->_renderFlags & VF_Geom) == VF_Geom) printf ("VF_Geom ");
506 if ((node->_renderFlags & VF_localLight) == VF_localLight) printf ("VF_localLight ");
507 if ((node->_renderFlags & VF_Sensitive) == VF_Sensitive) printf ("VF_Sensitive ");
508 if ((node->_renderFlags & VF_Blend) == VF_Blend) printf ("VF_Blend ");
509 if ((node->_renderFlags & VF_Proximity) == VF_Proximity) printf ("VF_Proximity ");
510 if ((node->_renderFlags & VF_Collision) == VF_Collision) printf ("VF_Collision ");
511 if ((node->_renderFlags & VF_globalLight) == VF_globalLight) printf ("VF_globalLight ");
512 if ((node->_renderFlags & VF_hasVisibleChildren) == VF_hasVisibleChildren) printf ("VF_hasVisibleChildren ");
513 if ((node->_renderFlags & VF_shouldSortChildren) == VF_shouldSortChildren) printf ("VF_shouldSortChildren ");
514 
515 printf ("\n");
516 */
517  RETURN_FROM_CHILD_IF_NOT_FOR_ME
518  //if(node->__loadstatus != LOAD_STABLE) return; #define LOAD_STABLE 10
519 
520 
521 #ifdef VERBOSE
522  {
523  int x;
524  struct X3D_Node *xx;
525 
526 printf ("child_Group, children.n %d sortedChildren.n %d\n",node->children.n, node->_sortedChildren.n);
527 
528  printf ("child_Group, this %p rf %x isProto %d\n",node,node->_renderFlags, node->FreeWRL__protoDef);
529 // printf (" ..., render_hier vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
530 // render_vp,render_geom,render_light,render_sensitive,render_blend,render_proximity,render_collision);
531  for (x=0; x<nc; x++) {
532  xx = X3D_NODE(node->_sortedChildren.p[x]);
533  if (xx)
534  printf (" %d: ch %p type %s dist %f\n",x, node->_sortedChildren.p[x],stringNodeType(xx->_nodeType),xx->_dist);
535  else printf (" chiuld %d null\n",x);
536  }
537  for (x=0; x<nc; x++) {
538  xx = X3D_NODE(node->_sortedChildren.p[x]);
539  if (xx)
540  printf (" %d: sch %p type %s dist %f\n",x, node->_sortedChildren.p[x],stringNodeType(xx->_nodeType),xx->_dist);
541  else printf (" chiuld %d null\n",x);
542  }
543  }
544 #endif //VERBOSE
545 
546 
547 
548 
549  prep_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
550 
551  /* do we have a DirectionalLight for a child? */
552  //if(nc){
553  // LOCAL_LIGHT_CHILDREN(node->__children);
554  //}else{
555  // LOCAL_LIGHT_CHILDREN(node->_sortedChildren);
556  //}
557 
558  /* printf ("chld_Group, for %u, protodef %d and FreeWRL_PROTOInterfaceNodes.n %d\n",
559  node, node->FreeWRL__protoDef, node->FreeWRL_PROTOInterfaceNodes.n); */
560  /* now, just render the non-directionalLight children */
561  //if ((node->FreeWRL__protoDef!=INT_ID_UNDEFINED) && renderstate()->render_geom) {
562  // (node->children).n = 1;
563  // normalChildren(node->children);
564  // (node->children).n = nc;
565  //} else {
566  // normalChildren(node->_sortedChildren);
567  //}
568  sceneflag = ciflag_get(node->__protoFlags,2);
569  renderFirstProtoChildOnlyAsPerSpecs = TRUE; //FALSE is like flux / vivaty
570  //I don't think inline.children comes through here, just scene and protoInstance
571  if(sceneflag == 2 ){
572  normalChildren(node->_sortedChildren);
573  }else{
574  if(renderFirstProtoChildOnlyAsPerSpecs && (renderstate()->render_geom || renderstate()->render_blend)) {
575  //H: its just when rendering drawable geometry that we take only the first node
576  (node->__children).n = 1;
577  normalChildren(node->__children);
578  (node->__children).n = nc;
579  } else {
580  //H: else even for Protobodies, we may visit all rootnodes & descendants
581  // in case they need some updating on a non-draw scenegraph pass?
582  normalChildren(node->__children);
583  }
584  }
585 
586  //LOCAL_LIGHT_OFF
587  fin_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
588 
589 }