FreeWRL / FreeX3D 4.3.0
Children.c
1/*
2
3
4Render 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 */
53void 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 */
67void 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 if (p->_nodeType == NODE_TextureProjectorPerspective) {
86 if (X3D_TEXTUREPROJECTORPERSPECTIVE(p)->global == TRUE)
87 render_node(p);
88 } else if (p->_nodeType == NODE_TextureProjectorParallel) {
89 if (X3D_TEXTUREPROJECTORPARALLEL(p)->global == TRUE)
90 render_node(p);
91 } else
92 render_node(p);
93 }
94 }
95}
96
97/* propagate flags up the scene graph */
98/* used to tell the rendering pass that, there is/used to be nodes
99 * of interest down the branch. Eg, Transparent nodes - no sense going
100 * through it all when rendering only for nodes. */
101
102/* void update_renderFlag (struct X3D_Node *p, int flag) { */
103//void update_renderFlagB (struct X3D_Node *p, int flag, char *fi, int li) {
104void update_renderFlagB (struct X3D_Node *p, int flag, int li) {
105 int i;
106
107 /* send notification up the chain */
108
109//JAS printf ("start of update_renderFlag from %d for %p (%s) flag %x parents %d\n",li,p, stringNodeType(p->_nodeType),
110//JAS flag, vectorSize(p->_parentVector));
111//JAS if (p->_nodeType == NODE_Shape) {
112//JAS printf ("... and this one is our Shape...\n");
113//JAS for (i = 0; i < vectorSize(p->_parentVector); i++) {
114//JAS struct X3D_Node *me = vector_get(struct X3D_Node *,p->_parentVector, i);
115//JAS printf ("Shape parent %d is %p, type %s\n",i,me,stringNodeType(me->_nodeType));
116//JAS }
117//JAS }
118
119
120
121//JAS if (vectorSize(p->_parentVector) <=0) {
122 //printf ("update_renderFlag, for node %p (%s), parentVector is zero, returning...\n",p,stringNodeType(p->_nodeType));
123//JAS return;
124//JAS }
125
126 //if (p==NULL) {
127 // ConsoleMessage ("update_renderFlag, p NULL from %s:%d\n",fi,li);
128 // return;
129 //}
130
131 p->_renderFlags = p->_renderFlags | flag;
132
133 if (p->_parentVector == NULL) {
134 //ConsoleMessage ("update_renderFlag, %p->parentVector NULL refcount %d (%s) from %s:%d\n",p,p->referenceCount,stringNodeType(p->_nodeType),fi,li);
135 return;
136 }
137
138 for (i = 0; i < vectorSize(p->_parentVector); i++) {
139 struct X3D_Node *me = vector_get(struct X3D_Node *,p->_parentVector, i);
140
141 // JAS printf ("update_renderFlagB, reference count for parent %p is %d\n",me,me->referenceCount);
142 if (me->referenceCount > 0) {
143
144 // JAS printf ("update_renderFlagB, line %d node type %p %s\n",__LINE__,me,stringNodeType(me->_nodeType));
145
146 if (me==NULL) {
147 ConsoleMessage ("update_renderFlag, me NULL for child %d",i);
148 markForDispose(p, TRUE);
149 return;
150 }
151
152 if (me->_parentVector == NULL) {
153
154 // JAS printf ("update_renderFlagB, warning, for node %p (%s), pv %d, child has null parentVector\n",p,stringNodeType(p->_nodeType),i);
155 ConsoleMessage ("warning, for node %p (%s), pv %d, child has null parentVector\n",p,stringNodeType(p->_nodeType),i);
156 markForDispose(p, TRUE);
157 return;
158 }
159
160 // printf ("node %d type %s has node %d type %s for a parent\n",p,stringNodeType(p->_nodeType),me,stringNodeType(me->_nodeType));
161 switch (me->_nodeType) {
162
163 case NODE_Switch:
164 if (is_Switchchild_inrange(X3D_SWITCH(me),p)) {
165 /* printf ("switch, this is the chosen node\n"); */
166 update_renderFlagB(me,flag, __LINE__);
167 }
168 break;
169
170 case NODE_LOD:
171 /* works for both X3D and VRML syntax; compare with the "_selected" field */
172 if (p == X3D_LODNODE(me)->_selected) {
173 update_renderFlagB(me,flag, __LINE__);
174 }
175 break;
176
177 case NODE_GeoLOD:
178 if (is_GeoLODchild_inrange(X3D_GEOLOD(me),p)) {
179 /* printf ("switch, this is the chosen node\n"); */
180 update_renderFlagB(me,flag, __LINE__);
181 }
182 break;
183
184 case NODE_CADLayer:
185 if (is_CADLayerchild_inrange(X3D_CADLAYER(me),p)) {
186 update_renderFlagB(me,flag, __LINE__);
187 }
188 break;
189
190 default:
191
192 update_renderFlagB(me,flag, __LINE__);
193 }
194 } // referenceCount check
195 }
196 /* printf ("finished update_RenderFlag for %d\n",p); */
197}
198void UPDATE_RENDERFLAG (struct X3D_Node *p, int flag, char *fi, int li){
199 if (p==NULL) {
200 ConsoleMessage ("update_renderFlag, p NULL from %s:%d\n",fi,li);
201 return;
202 }
203 //profile_start("update_rendrflg");
204 update_renderFlagB (p, flag, __LINE__);
205 //profile_end("update_rendrflg");
206 return;
207}
208