Line data Source code
1 : /*
2 : * GPAC - Multimedia Framework C SDK
3 : *
4 : * Authors: Jean Le Feuvre
5 : * Copyright (c) Telecom ParisTech 2000-2012
6 : * All rights reserved
7 : *
8 : * This file is part of GPAC / Scene Compositor sub-project
9 : *
10 : * GPAC is free software; you can redistribute it and/or modify
11 : * it under the terms of the GNU Lesser General Public License as published by
12 : * the Free Software Foundation; either version 2, or (at your option)
13 : * any later version.
14 : *
15 : * GPAC is distributed in the hope that it will be useful,
16 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : * GNU Lesser General Public License for more details.
19 : *
20 : * You should have received a copy of the GNU Lesser General Public
21 : * License along with this library; see the file COPYING. If not, write to
22 : * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 : *
24 : */
25 :
26 : #include "nodes_stacks.h"
27 :
28 : #ifndef GPAC_DISABLE_VRML
29 :
30 2 : GF_List *Bindable_GetStack(GF_Node *bindable)
31 : {
32 : void *st;
33 2 : if (!bindable) return 0;
34 2 : st = gf_node_get_private(bindable);
35 2 : switch (gf_node_get_tag(bindable)) {
36 0 : case TAG_MPEG4_Background2D:
37 0 : return ((Background2DStack*)st)->reg_stacks;
38 0 : case TAG_MPEG4_Viewport:
39 : case TAG_MPEG4_NavigationInfo:
40 : #ifndef GPAC_DISABLE_X3D
41 : case TAG_X3D_NavigationInfo:
42 : #endif
43 0 : return ((ViewStack*)st)->reg_stacks;
44 : #ifndef GPAC_DISABLE_3D
45 0 : case TAG_MPEG4_Background:
46 : #ifndef GPAC_DISABLE_X3D
47 : case TAG_X3D_Background:
48 : #endif
49 0 : return ((BackgroundStack*)st)->reg_stacks;
50 2 : case TAG_MPEG4_Viewpoint:
51 : case TAG_MPEG4_Fog:
52 : #ifndef GPAC_DISABLE_X3D
53 : case TAG_X3D_Viewpoint:
54 : case TAG_X3D_Fog:
55 : #endif
56 2 : return ((ViewStack*)st)->reg_stacks;
57 : #endif
58 : default:
59 : return NULL;
60 : }
61 : }
62 :
63 36130 : Bool Bindable_GetIsBound(GF_Node *bindable)
64 : {
65 36130 : if (!bindable) return GF_FALSE;
66 14623 : switch (gf_node_get_tag(bindable)) {
67 5790 : case TAG_MPEG4_Background2D:
68 5790 : return ((M_Background2D*)bindable)->isBound;
69 161 : case TAG_MPEG4_Viewport:
70 161 : return ((M_Viewport*)bindable)->isBound;
71 367 : case TAG_MPEG4_Background:
72 : #ifndef GPAC_DISABLE_X3D
73 : case TAG_X3D_Background:
74 : #endif
75 367 : return ((M_Background*)bindable)->isBound;
76 2086 : case TAG_MPEG4_NavigationInfo:
77 : #ifndef GPAC_DISABLE_X3D
78 : case TAG_X3D_NavigationInfo:
79 : #endif
80 2086 : return ((M_NavigationInfo*)bindable)->isBound;
81 4886 : case TAG_MPEG4_Viewpoint:
82 : #ifndef GPAC_DISABLE_X3D
83 : case TAG_X3D_Viewpoint:
84 : #endif
85 4886 : return ((M_Viewpoint*)bindable)->isBound;
86 1333 : case TAG_MPEG4_Fog:
87 : #ifndef GPAC_DISABLE_X3D
88 : case TAG_X3D_Fog:
89 : #endif
90 1333 : return ((M_Fog*)bindable)->isBound;
91 : default:
92 : return GF_FALSE;
93 : }
94 : }
95 :
96 1575 : void Bindable_SetIsBound(GF_Node *bindable, Bool val)
97 : {
98 : Bool has_bind_time = GF_FALSE;
99 1575 : if (!bindable) return;
100 1575 : switch (gf_node_get_tag(bindable)) {
101 1239 : case TAG_MPEG4_Background2D:
102 1239 : if ( ((M_Background2D*)bindable)->isBound == val) return;
103 1180 : ((M_Background2D*)bindable)->isBound = val;
104 1180 : break;
105 107 : case TAG_MPEG4_Viewport:
106 107 : if ( ((M_Viewport*)bindable)->isBound == val) return;
107 106 : ((M_Viewport*)bindable)->isBound = val;
108 106 : ((M_Viewport*)bindable)->bindTime = gf_node_get_scene_time(bindable);
109 : has_bind_time = GF_TRUE;
110 106 : break;
111 : #ifndef GPAC_DISABLE_X3D
112 0 : case TAG_X3D_Background:
113 0 : if ( ((X_Background*)bindable)->isBound == val) return;
114 0 : ((X_Background*)bindable)->isBound = val;
115 0 : ((X_Background*)bindable)->bindTime = gf_node_get_scene_time(bindable);
116 : has_bind_time = GF_TRUE;
117 0 : break;
118 : #endif
119 25 : case TAG_MPEG4_Background:
120 25 : if ( ((M_Background*)bindable)->isBound == val) return;
121 22 : ((M_Background*)bindable)->isBound = val;
122 22 : break;
123 : #ifndef GPAC_DISABLE_X3D
124 2 : case TAG_X3D_NavigationInfo:
125 2 : if ( ((X_NavigationInfo*)bindable)->isBound == val) return;
126 2 : ((X_NavigationInfo*)bindable)->isBound = val;
127 2 : ((X_NavigationInfo*)bindable)->bindTime = gf_node_get_scene_time(bindable);
128 : has_bind_time = GF_TRUE;
129 2 : break;
130 : #endif
131 54 : case TAG_MPEG4_NavigationInfo:
132 54 : if ( ((M_NavigationInfo*)bindable)->isBound == val) return;
133 54 : ((M_NavigationInfo*)bindable)->isBound = val;
134 54 : break;
135 138 : case TAG_MPEG4_Viewpoint:
136 : #ifndef GPAC_DISABLE_X3D
137 : case TAG_X3D_Viewpoint:
138 : #endif
139 138 : if ( ((M_Viewpoint*)bindable)->isBound == val) return;
140 132 : ((M_Viewpoint*)bindable)->isBound = val;
141 132 : ((M_Viewpoint*)bindable)->bindTime = gf_node_get_scene_time(bindable);
142 : has_bind_time = GF_TRUE;
143 132 : break;
144 : #ifndef GPAC_DISABLE_X3D
145 0 : case TAG_X3D_Fog:
146 0 : if ( ((X_Fog*)bindable)->isBound == val) return;
147 0 : ((X_Fog*)bindable)->isBound = val;
148 0 : ((X_Fog*)bindable)->bindTime = gf_node_get_scene_time(bindable);
149 : has_bind_time = GF_TRUE;
150 0 : break;
151 : #endif
152 10 : case TAG_MPEG4_Fog:
153 10 : if ( ((M_Fog*)bindable)->isBound == val) return;
154 10 : ((M_Fog*)bindable)->isBound = val;
155 10 : break;
156 : default:
157 : return;
158 : }
159 1506 : gf_node_event_out_str(bindable, "isBound");
160 1506 : if (has_bind_time) gf_node_event_out_str(bindable, "bindTime");
161 : /*force invalidate of the bindable stack's owner*/
162 1506 : gf_node_dirty_set(bindable, 0, GF_TRUE);
163 : }
164 :
165 :
166 77 : Bool Bindable_GetSetBind(GF_Node *bindable)
167 : {
168 77 : if (!bindable) return GF_FALSE;
169 77 : switch (gf_node_get_tag(bindable)) {
170 52 : case TAG_MPEG4_Background2D:
171 52 : return ((M_Background2D*)bindable)->set_bind;
172 7 : case TAG_MPEG4_Viewport:
173 7 : return ((M_Viewport*)bindable)->set_bind;
174 5 : case TAG_MPEG4_Background:
175 : #ifndef GPAC_DISABLE_X3D
176 : case TAG_X3D_Background:
177 : #endif
178 5 : return ((M_Background*)bindable)->set_bind;
179 0 : case TAG_MPEG4_NavigationInfo:
180 : #ifndef GPAC_DISABLE_X3D
181 : case TAG_X3D_NavigationInfo:
182 : #endif
183 0 : return ((M_NavigationInfo*)bindable)->set_bind;
184 11 : case TAG_MPEG4_Viewpoint:
185 : #ifndef GPAC_DISABLE_X3D
186 : case TAG_X3D_Viewpoint:
187 : #endif
188 11 : return ((M_Viewpoint*)bindable)->set_bind;
189 2 : case TAG_MPEG4_Fog:
190 : #ifndef GPAC_DISABLE_X3D
191 : case TAG_X3D_Fog:
192 : #endif
193 2 : return ((M_Fog*)bindable)->set_bind;
194 : default:
195 : return GF_FALSE;
196 : }
197 : }
198 :
199 25 : void Bindable_SetSetBindEx(GF_Node *bindable, Bool val, GF_List *stack)
200 : {
201 25 : if (!bindable) return;
202 25 : switch (gf_node_get_tag(bindable)) {
203 21 : case TAG_MPEG4_Background2D:
204 21 : ((M_Background2D*)bindable)->set_bind = val;
205 21 : ((M_Background2D*)bindable)->on_set_bind(bindable, NULL);
206 21 : break;
207 0 : case TAG_MPEG4_Viewport:
208 0 : ((M_Viewport*)bindable)->set_bind = val;
209 0 : ((M_Viewport*)bindable)->on_set_bind(bindable, (GF_Route*)stack);
210 0 : break;
211 0 : case TAG_MPEG4_Background:
212 : #ifndef GPAC_DISABLE_X3D
213 : case TAG_X3D_Background:
214 : #endif
215 0 : ((M_Background*)bindable)->set_bind = val;
216 0 : ((M_Background*)bindable)->on_set_bind(bindable, NULL);
217 0 : break;
218 0 : case TAG_MPEG4_NavigationInfo:
219 : #ifndef GPAC_DISABLE_X3D
220 : case TAG_X3D_NavigationInfo:
221 : #endif
222 0 : ((M_NavigationInfo*)bindable)->set_bind = val;
223 0 : ((M_NavigationInfo*)bindable)->on_set_bind(bindable, NULL);
224 0 : break;
225 4 : case TAG_MPEG4_Viewpoint:
226 : #ifndef GPAC_DISABLE_X3D
227 : case TAG_X3D_Viewpoint:
228 : #endif
229 4 : ((M_Viewpoint*)bindable)->set_bind = val;
230 4 : ((M_Viewpoint*)bindable)->on_set_bind(bindable, NULL);
231 4 : break;
232 0 : case TAG_MPEG4_Fog:
233 : #ifndef GPAC_DISABLE_X3D
234 : case TAG_X3D_Fog:
235 : #endif
236 0 : ((M_Fog*)bindable)->set_bind = val;
237 0 : ((M_Fog*)bindable)->on_set_bind(bindable, NULL);
238 0 : break;
239 : default:
240 : return;
241 : }
242 : }
243 0 : void Bindable_SetSetBind(GF_Node *bindable, Bool val)
244 : {
245 25 : Bindable_SetSetBindEx(bindable, val, NULL);
246 0 : }
247 :
248 77 : void Bindable_OnSetBind(GF_Node *bindable, GF_List *stack_list, GF_List *for_stack)
249 : {
250 : u32 i;
251 : Bool on_top, is_bound, set_bind;
252 : GF_Node *node;
253 : GF_List *stack;
254 :
255 77 : set_bind = Bindable_GetSetBind(bindable);
256 77 : is_bound = Bindable_GetIsBound(bindable);
257 :
258 81 : if (!set_bind && !is_bound) return;
259 75 : if (set_bind && is_bound) return;
260 :
261 73 : i=0;
262 221 : while ((stack = (GF_List*)gf_list_enum(stack_list, &i))) {
263 75 : if (for_stack && (for_stack!=stack)) continue;
264 :
265 75 : on_top = (gf_list_get(stack, 0)==bindable) ? GF_TRUE : GF_FALSE;
266 :
267 75 : if (!set_bind) {
268 14 : if (is_bound) Bindable_SetIsBound(bindable, GF_FALSE);
269 14 : if (on_top && (gf_list_count(stack)>1)) {
270 3 : gf_list_rem(stack, 0);
271 3 : gf_list_add(stack, bindable);
272 3 : node = (GF_Node*)gf_list_get(stack, 0);
273 3 : Bindable_SetIsBound(node, GF_TRUE);
274 : }
275 : } else {
276 61 : if (!is_bound) Bindable_SetIsBound(bindable, GF_TRUE);
277 61 : if (!on_top) {
278 : /*push old top one down and unbind*/
279 29 : node = (GF_Node*)gf_list_get(stack, 0);
280 29 : Bindable_SetIsBound(node, GF_FALSE);
281 : /*insert new top*/
282 29 : gf_list_del_item(stack, bindable);
283 29 : gf_list_insert(stack, bindable, 0);
284 : }
285 : }
286 : }
287 : /*force invalidate of the bindable stack's owner*/
288 73 : gf_node_dirty_set(bindable, 0, GF_TRUE);
289 : /*and redraw scene*/
290 73 : gf_sc_invalidate(gf_sc_get_compositor(bindable), NULL);
291 : }
292 :
293 3372 : void BindableStackDelete(GF_List *stack)
294 : {
295 6746 : while (gf_list_count(stack)) {
296 : GF_List *bind_stack_list;
297 2 : GF_Node *bindable = (GF_Node*)gf_list_get(stack, 0);
298 2 : gf_list_rem(stack, 0);
299 2 : bind_stack_list = Bindable_GetStack(bindable);
300 2 : if (bind_stack_list) {
301 2 : gf_list_del_item(bind_stack_list, stack);
302 : assert(gf_list_find(bind_stack_list, stack)<0);
303 : }
304 : }
305 3372 : gf_list_del(stack);
306 3372 : }
307 :
308 777 : void PreDestroyBindable(GF_Node *bindable, GF_List *stack_list)
309 : {
310 777 : Bool is_bound = Bindable_GetIsBound(bindable);
311 777 : Bindable_SetIsBound(bindable, GF_FALSE);
312 :
313 2283 : while (gf_list_count(stack_list)) {
314 729 : GF_List *stack = (GF_List*)gf_list_get(stack_list, 0);
315 729 : gf_list_rem(stack_list, 0);
316 729 : gf_list_del_item(stack, bindable);
317 729 : if (is_bound) {
318 710 : GF_Node *stack_top = (GF_Node*)gf_list_get(stack, 0);
319 710 : if (stack_top) Bindable_SetSetBind(stack_top, GF_TRUE);
320 : }
321 : }
322 777 : }
323 :
324 : #endif /*GPAC_DISABLE_VRML*/
|