FreeWRL / FreeX3D 4.3.0
Component_Grouping.c
1/*
2
3
4X3D 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
49void 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 */
71void 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 */
85void prep_Group (struct X3D_Group *node) {
86 COMPILE_IF_REQUIRED
87 RECORD_DISTANCE
88
89/*
90printf ("prepGroup %p (root %p), flags %x children %d ",node,rootNode,node->_renderFlags,node->children.n);
91if ((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) printf ("VF_Viewpoint ");
92if ((node->_renderFlags & VF_Geom) == VF_Geom) printf ("VF_Geom ");
93if ((node->_renderFlags & VF_localLight) == VF_localLight) printf ("VF_localLight ");
94if ((node->_renderFlags & VF_Sensitive) == VF_Sensitive) printf ("VF_Sensitive ");
95if ((node->_renderFlags & VF_Blend) == VF_Blend) printf ("VF_Blend ");
96if ((node->_renderFlags & VF_Proximity) == VF_Proximity) printf ("VF_Proximity ");
97if ((node->_renderFlags & VF_Collision) == VF_Collision) printf ("VF_Collision ");
98if ((node->_renderFlags & VF_globalLight) == VF_globalLight) printf ("VF_globalLight ");
99if ((node->_renderFlags & VF_hasVisibleChildren) == VF_hasVisibleChildren) printf ("VF_hasVisibleChildren ");
100if ((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 */
109void 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
166void 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
194void 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
231void sib_prep_LocalFog(struct X3D_Node *parent, struct X3D_Node *sibAffector);
232void sib_prep_DirectionalLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
233void sib_prep_SpotlLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
234void sib_prep_PointLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
235void sib_prep_ClipPlane(struct X3D_Node *parent, struct X3D_Node *sibAffector);
236void sib_prep_Effect(struct X3D_Node *parent, struct X3D_Node *sibAffector);
237void sib_prep_TextureProjector(struct X3D_Node *parent, struct X3D_Node *sibAffector);
238
239void sib_prep(struct X3D_Node *parent, struct X3D_Node *sibAffector){
240 switch(sibAffector->_nodeType){
241 case NODE_DirectionalLight:
242 sib_prep_DirectionalLight(parent,sibAffector); break;
243 case NODE_SpotLight:
244 sib_prep_SpotlLight(parent,sibAffector); break;
245 case NODE_PointLight:
246 sib_prep_PointLight(parent,sibAffector); break;
247 case NODE_LocalFog:
248 sib_prep_LocalFog(parent,sibAffector); break;
249 case NODE_ClipPlane:
250 sib_prep_ClipPlane(parent,sibAffector); break;
251 case NODE_Effect:
252 sib_prep_Effect(parent,sibAffector); break;
253 case NODE_TextureProjectorPerspective:
254 case NODE_TextureProjectorParallel:
255 sib_prep_TextureProjector(parent,sibAffector); break;
256 default:
257 break;
258 }
259}
260
261void sib_fin_LocalFog(struct X3D_Node *parent, struct X3D_Node *sibAffector);
262void sib_fin_DirectionalLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
263void sib_fin_SpotlLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
264void sib_fin_PointLight(struct X3D_Node *parent, struct X3D_Node *sibAffector);
265void sib_fin_ClipPlane(struct X3D_Node *parent, struct X3D_Node *sibAffector);
266void sib_fin_Effect(struct X3D_Node *parent, struct X3D_Node *sibAffector);
267void sib_fin_TextureProjector(struct X3D_Node *parent, struct X3D_Node *sibAffector);
268
269void sib_fin(struct X3D_Node *parent, struct X3D_Node *sibAffector){
270 switch(sibAffector->_nodeType){
271 case NODE_DirectionalLight:
272 sib_fin_DirectionalLight(parent,sibAffector); break;
273 case NODE_SpotLight:
274 sib_fin_SpotlLight(parent,sibAffector); break;
275 case NODE_PointLight:
276 sib_fin_PointLight(parent,sibAffector); break;
277 case NODE_LocalFog:
278 sib_fin_LocalFog(parent,sibAffector); break;
279 case NODE_ClipPlane:
280 sib_fin_ClipPlane(parent,sibAffector); break;
281 case NODE_Effect:
282 sib_fin_Effect(parent,sibAffector); break;
283 case NODE_TextureProjectorPerspective:
284 case NODE_TextureProjectorParallel:
285 sib_fin_TextureProjector(parent,sibAffector); break;
286
287 default:
288 break;
289 }
290}
291void prep_sibAffectors(struct X3D_Node *parent, struct Multi_Node* affectors){
292 if(affectors->n){
293 int j;
294 for(j=0;j<affectors->n;j++){
295 struct X3D_Node *sa = affectors->p[j];
296 sib_prep(parent,sa);
297 }
298 }
299}
300void fin_sibAffectors(struct X3D_Node *parent, struct Multi_Node* affectors){
301 if(affectors->n){
302 int j,jj;
303 for(jj=0;jj<affectors->n;jj++){
304 //we go backwards so any sib_fin popping is in reverse order to any sib_prep pushing,
305 // in case multiple push to same stack, as with multiple Effects
306 struct X3D_Node *sa;
307 j = affectors->n - jj - 1;
308 sa = affectors->p[j];
309 sib_fin(parent,sa);
310 }
311 }
312}
313
314void child_StaticGroup (struct X3D_StaticGroup *node) {
315 CHILDREN_COUNT
316 //LOCAL_LIGHT_SAVE
317
318 RETURN_FROM_CHILD_IF_NOT_FOR_ME
319
320 /* did this change? */
321 if NODE_NEEDS_COMPILING {
322 REINITIALIZE_SORTED_NODES_FIELD(node->children,node->_sortedChildren);
323 //ConsoleMessage ("StaticGroup changed");
324 MARK_NODE_COMPILED;
325 }
326
327 /* do we have a local light for a child? */
328 //LOCAL_LIGHT_CHILDREN(node->_sortedChildren);
329 prep_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
330
331 /* now, just render the non-directionalLight children */
332 normalChildren(node->_sortedChildren);
333
334 //LOCAL_LIGHT_OFF
335 fin_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
336
337}
338
339void child_Group (struct X3D_Group *node) {
340 // UNUSED int renderFirstProtoChildOnlyAsPerSpecs = 1;
341 CHILDREN_COUNT
342// LOCAL_LIGHT_SAVE
343
344 /*
345printf ("chldGroup %p (root %p), flags %x children %d ",node,rootNode,node->_renderFlags,node->children.n);
346if ((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) printf ("VF_Viewpoint ");
347if ((node->_renderFlags & VF_Geom) == VF_Geom) printf ("VF_Geom ");
348if ((node->_renderFlags & VF_localLight) == VF_localLight) printf ("VF_localLight ");
349if ((node->_renderFlags & VF_Sensitive) == VF_Sensitive) printf ("VF_Sensitive ");
350if ((node->_renderFlags & VF_Blend) == VF_Blend) printf ("VF_Blend ");
351if ((node->_renderFlags & VF_Proximity) == VF_Proximity) printf ("VF_Proximity ");
352if ((node->_renderFlags & VF_Collision) == VF_Collision) printf ("VF_Collision ");
353if ((node->_renderFlags & VF_globalLight) == VF_globalLight) printf ("VF_globalLight ");
354if ((node->_renderFlags & VF_hasVisibleChildren) == VF_hasVisibleChildren) printf ("VF_hasVisibleChildren ");
355if ((node->_renderFlags & VF_shouldSortChildren) == VF_shouldSortChildren) printf ("VF_shouldSortChildren ");
356printf ("\n");
357*/
358
359 RETURN_FROM_CHILD_IF_NOT_FOR_ME
360
361 if(1){
362 //stereoscopic experiments
363 ttrenderstate rs = renderstate();
364 if (rs->render_geom) { //== VF_Geom) {
365 if (node->_renderFlags & VF_HideLeft && (viewer_iside() == 0) ) {
366 return;
367 }
368 if (node->_renderFlags & VF_HideRight && (viewer_iside() == 1) ) {
369 return;
370 }
371 }
372 }
373 prep_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
374
375
376#ifdef VERBOSE
377 {
378 int x;
379 struct X3D_Node *xx;
380
381printf ("child_Group, children.n %d sortedChildren.n %d\n",node->children.n, node->_sortedChildren.n);
382
383 printf ("child_Group, this %p rf %x isProto %d\n",node,node->_renderFlags, node->FreeWRL__protoDef);
384// printf (" ..., render_hier vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
385// render_vp,render_geom,render_light,render_sensitive,render_blend,render_proximity,render_collision);
386 for (x=0; x<nc; x++) {
387 xx = X3D_NODE(node->_sortedChildren.p[x]);
388 if (xx)
389 printf (" %d: ch %p type %s dist %f\n",x, node->_sortedChildren.p[x],stringNodeType(xx->_nodeType),xx->_dist);
390 else printf (" chiuld %d null\n",x);
391 }
392 for (x=0; x<nc; x++) {
393 xx = X3D_NODE(node->_sortedChildren.p[x]);
394 if (xx)
395 printf (" %d: sch %p type %s dist %f\n",x, node->_sortedChildren.p[x],stringNodeType(xx->_nodeType),xx->_dist);
396 else printf (" chiuld %d null\n",x);
397 }
398 }
399#endif //VERBOSE
400
401
402
403
404
405 /* do we have a DirectionalLight for a child? */
406// LOCAL_LIGHT_CHILDREN(node->_sortedChildren);
407
408 /* printf ("chld_Group, for %u, protodef %d and FreeWRL_PROTOInterfaceNodes.n %d\n",
409 node, node->FreeWRL__protoDef, node->FreeWRL_PROTOInterfaceNodes.n); */
410 /* now, just render the non-directionalLight children */
411 // UNUSED renderFirstProtoChildOnlyAsPerSpecs = 0; //flux/vivaty render all children
412 normalChildren(node->_sortedChildren);
413
414
415// LOCAL_LIGHT_OFF
416
417 fin_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
418
419}
420
421
422void child_Transform (struct X3D_Transform *node) {
423 //LOCAL_LIGHT_SAVE
424 CHILDREN_COUNT
425 OCCLUSIONTEST
426
427 RETURN_FROM_CHILD_IF_NOT_FOR_ME
428
429 if(1){
430 //stereoscopic experiments
431 ttrenderstate rs = renderstate();
432 if (rs->render_geom) { //== VF_Geom) {
433 if (node->_renderFlags & VF_HideLeft && (viewer_iside() == 0) ) {
434 return;
435 }
436 if (node->_renderFlags & VF_HideRight && (viewer_iside() == 1) ) {
437 return;
438 }
439 }
440 }
441
442 /* any children at all? */
443 if (nc==0) return;
444
445 //if(node->__sibAffectors.n)
446 // printf("have transform sibaffectors\n");
447 prep_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
448
449
450 //profile_start("local_light_kids");
451 /* do we have a local light for a child? */
452// LOCAL_LIGHT_CHILDREN(node->_sortedChildren);
453 //profile_end("local_light_kids");
454 /* now, just render the non-directionalLight children */
455
456 /* printf ("Transform %d, flags %d, render_sensitive %d\n",
457 node,node->_renderFlags,render_sensitive); */
458
459 #ifdef CHILDVERBOSE
460 printf ("transform - doing normalChildren\n");
461 #endif
462
463 normalChildren(node->_sortedChildren);
464
465 #ifdef CHILDVERBOSE
466 printf ("transform - done normalChildren\n");
467 #endif
468
469// LOCAL_LIGHT_OFF
470 fin_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
471}
472
473
474/* prep_Proto - this is a ProtoInstance (not declare) */
475/*pack 4 flags into one int, using char */
476char ciflag_get(int flags, int index){
477 char *cflags = (char *)(&flags);
478 return cflags[index];
479}
480int ciflag_set(int flags, char flag, int index ){
481 char *cflags = (char *)(&flags);
482 cflags[index] = flag;
483 return flags;
484}
485void prep_Proto (struct X3D_Proto *node) {
486 if(0)printf("in prep_proto\n");
487 load_externProtoInstance(node);
488 COMPILE_IF_REQUIRED
489 //RECORD_DISTANCE
490}
491/* not sure why we would compile */
492void compile_Proto(struct X3D_Proto *node) {
493 unsigned char pflag;
494 if(0)printf("in compile_proto\n");
495 pflag = ciflag_get(node->__protoFlags,2);
496 if(pflag == 2){
497 //scene
498 REINITIALIZE_SORTED_NODES_FIELD(node->__children,node->_sortedChildren);
499 }
500 MARK_NODE_COMPILED
501}
502
503
504//UNIT statement - applying unit scalefactor during rendering
505int doLengthUnits();
506int isUnitSpecVersionOK(int specversion);
507static int unitoption_scalescene = TRUE; //FALSE is this what specs say, don't scale top scene?
508void prep_unitscale (struct X3D_Proto *ec) {
509 //if(doLengthUnits() && isUnitSpecVersionOK(ec->__specversion)){
510 if(doLengthUnits()){
511 if(!renderstate()->render_vp) {
512 struct X3D_Proto *parent;
513 double factor = 1.0; //default factor applied if current context < v3.3
514 double parentfactor = 1.0; //default factor applied if parent context < v3.3 or no parent
515 parent = X3D_PROTO(ec->_executionContext); //__parentProto); //not sure this is correct. Looking for parent context of Instance, not ProtoDefinition
516 FW_GL_PUSH_MATRIX();
517 // SCALE
518 if(isUnitSpecVersionOK(ec->__specversion)){
519 factor = ec->__unitlengthfactor;
520 }
521 if(parent){
522 if(isUnitSpecVersionOK(parent->__specversion))
523 parentfactor = parent->__unitlengthfactor;
524 }else {
525 //there's no higher level context, which means we are in the top scene
526 if(unitoption_scalescene){
527 parentfactor = 1.0; //scale top scene length to SI base units [m] (not what specs say)
528 }else{
529 parentfactor = factor;
530 //top level scene gets scale of 1 ie if its in feet it stays feet, .3048/.3048=1 as per specs
531 //this is so defaults like Sphere radius=1 will be 1 foot, no need to tinker with defaults
532 }
533 }
534 //printf("( factor %lf / parentfactor= %lf ", factor, parentfactor);
535 factor = factor / parentfactor;
536 //printf(" = %lf)\n",factor);
537 FW_GL_SCALE_D(factor,factor,factor);
538 //RECORD_DISTANCE
539 }
540 }
541}
542
543
544void fin_unitscale (struct X3D_Proto *ec) {
545
546 //if(doLengthUnits() && isUnitSpecVersionOK(ec->__specversion)){
547 if(doLengthUnits()){
548 if(!renderstate()->render_vp) {
549 FW_GL_POP_MATRIX();
550 }
551 /*
552 else {
553 //Rendering the viewpoint only means finding it, and calculating the reverse WorldView matrix.
554 if((ec->_renderFlags & VF_Viewpoint) == VF_Viewpoint) {
555 struct X3D_Proto *parent;
556 double factor = 1.0;
557 double parentfactor = 1.0;
558 parent = X3D_PROTO(ec->__parentProto); //not sure this is correct. Looking for parent context of Instance, not ProtoDefinition
559 if(parent)
560 parentfactor = parent->__unitlengthfactor;
561 FW_GL_PUSH_MATRIX();
562 // SCALE
563 factor = ec->__unitlengthfactor;
564 factor = parentfactor / factor;
565
566 FW_GL_SCALE_D(factor,factor,factor);
567 }
568 }
569 */
570 }
571}
572
573
574/* render the first node only unless scene (see component_networking.c child_inline for scene-similar*/
575void child_Proto (struct X3D_Proto *node) {
576 int nc;
577 unsigned char sceneflag;
578 int renderFirstProtoChildOnlyAsPerSpecs;
579 //LOCAL_LIGHT_SAVE
580 if(0)printf("in child_proto\n");
581 //CHILDREN_COUNT
582 nc = node->__children.n; //_sortedChildren.n;
583/*
584printf ("chldGroup %p (root %p), flags %x children %d ",node,rootNode,node->_renderFlags,node->children.n);
585if ((node->_renderFlags & VF_Viewpoint) == VF_Viewpoint) printf ("VF_Viewpoint ");
586if ((node->_renderFlags & VF_Geom) == VF_Geom) printf ("VF_Geom ");
587if ((node->_renderFlags & VF_localLight) == VF_localLight) printf ("VF_localLight ");
588if ((node->_renderFlags & VF_Sensitive) == VF_Sensitive) printf ("VF_Sensitive ");
589if ((node->_renderFlags & VF_Blend) == VF_Blend) printf ("VF_Blend ");
590if ((node->_renderFlags & VF_Proximity) == VF_Proximity) printf ("VF_Proximity ");
591if ((node->_renderFlags & VF_Collision) == VF_Collision) printf ("VF_Collision ");
592if ((node->_renderFlags & VF_globalLight) == VF_globalLight) printf ("VF_globalLight ");
593if ((node->_renderFlags & VF_hasVisibleChildren) == VF_hasVisibleChildren) printf ("VF_hasVisibleChildren ");
594if ((node->_renderFlags & VF_shouldSortChildren) == VF_shouldSortChildren) printf ("VF_shouldSortChildren ");
595
596printf ("\n");
597*/
598 RETURN_FROM_CHILD_IF_NOT_FOR_ME
599 //if(node->__loadstatus != LOAD_STABLE) return; #define LOAD_STABLE 10
600 prep_unitscale(node);
601
602#ifdef VERBOSE
603 {
604 int x;
605 struct X3D_Node *xx;
606
607printf ("child_Group, children.n %d sortedChildren.n %d\n",node->children.n, node->_sortedChildren.n);
608
609 printf ("child_Group, this %p rf %x isProto %d\n",node,node->_renderFlags, node->FreeWRL__protoDef);
610// printf (" ..., render_hier vp %d geom %d light %d sens %d blend %d prox %d col %d\n",
611// render_vp,render_geom,render_light,render_sensitive,render_blend,render_proximity,render_collision);
612 for (x=0; x<nc; x++) {
613 xx = X3D_NODE(node->_sortedChildren.p[x]);
614 if (xx)
615 printf (" %d: ch %p type %s dist %f\n",x, node->_sortedChildren.p[x],stringNodeType(xx->_nodeType),xx->_dist);
616 else printf (" chiuld %d null\n",x);
617 }
618 for (x=0; x<nc; x++) {
619 xx = X3D_NODE(node->_sortedChildren.p[x]);
620 if (xx)
621 printf (" %d: sch %p type %s dist %f\n",x, node->_sortedChildren.p[x],stringNodeType(xx->_nodeType),xx->_dist);
622 else printf (" chiuld %d null\n",x);
623 }
624 }
625#endif //VERBOSE
626
627
628
629
630 prep_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
631
632 /* do we have a DirectionalLight for a child? */
633 //if(nc){
634 // LOCAL_LIGHT_CHILDREN(node->__children);
635 //}else{
636 // LOCAL_LIGHT_CHILDREN(node->_sortedChildren);
637 //}
638
639 /* printf ("chld_Group, for %u, protodef %d and FreeWRL_PROTOInterfaceNodes.n %d\n",
640 node, node->FreeWRL__protoDef, node->FreeWRL_PROTOInterfaceNodes.n); */
641 /* now, just render the non-directionalLight children */
642 //if ((node->FreeWRL__protoDef!=INT_ID_UNDEFINED) && renderstate()->render_geom) {
643 // (node->children).n = 1;
644 // normalChildren(node->children);
645 // (node->children).n = nc;
646 //} else {
647 // normalChildren(node->_sortedChildren);
648 //}
649 sceneflag = ciflag_get(node->__protoFlags,2);
650 renderFirstProtoChildOnlyAsPerSpecs = TRUE; //FALSE is like flux / vivaty
651 //I don't think inline.children comes through here, just scene and protoInstance
652 if(sceneflag == 2 ){
653 normalChildren(node->_sortedChildren);
654 }else{
655 if(renderFirstProtoChildOnlyAsPerSpecs && (renderstate()->render_geom || renderstate()->render_blend)) {
656 //H: its just when rendering drawable geometry that we take only the first node
657 (node->__children).n = 1;
658 normalChildren(node->__children);
659 (node->__children).n = nc;
660 } else {
661 //H: else even for Protobodies, we may visit all rootnodes & descendants
662 // in case they need some updating on a non-draw scenegraph pass?
663 normalChildren(node->__children);
664 }
665 }
666
667 //LOCAL_LIGHT_OFF
668 fin_sibAffectors((struct X3D_Node*)node,&node->__sibAffectors);
669 fin_unitscale(node);
670}
671