1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *			Authors: Jean Le Feuvre
5  *			Copyright (c) Telecom ParisTech 2000-2019
6  *					All rights reserved
7  *
8  *  This file is part of GPAC / Scene Graph 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 
27 #ifndef _GF_SG_VRML_H_
28 #define _GF_SG_VRML_H_
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /*!
35 \file <gpac/scenegraph_vrml.h>
36 \brief Scenegraph for VRML files
37 */
38 
39 /*!
40 \addtogroup svrml BIFS/VRML/X3D Scenegraph
41 \ingroup scene_grp
42 \brief Scenegraph for VRML files.
43 
44 This section documents the Scenegraph for VRML files.
45 
46 @{
47  */
48 
49 
50 #include <gpac/scenegraph.h>
51 #include <gpac/maths.h>
52 
53 /*
54 	All extensions for VRML/MPEG-4/X3D graph structure
55 */
56 
57 /*! reserved NDT for MPEG4 (match binary coding)*/
58 #define MPEG4_RESERVED_NDT		200
59 
60 /*! the NDTs used in X3D not defined in MPEG4*/
61 enum
62 {
63 	NDT_SFMetadataNode = MPEG4_RESERVED_NDT+1,
64 	NDT_SFFillPropertiesNode,
65 	NDT_SFX3DLinePropertiesNode,
66 	NDT_SFGeoOriginNode,
67 	NDT_SFHAnimNode,
68 	NDT_SFHAnimDisplacerNode,
69 	NDT_SFNurbsControlCurveNode,
70 	NDT_SFNurbsSurfaceNode,
71 	NDT_SFNurbsCurveNode
72 };
73 
74 /*
75 	VRML / BIFS TYPES DEFINITION
76 */
77 
78 /*! event types of fields, as defined in the specs
79 	this should not be needed by non binary codecs
80 */
81 enum
82 {
83 	GF_SG_EVENT_FIELD		=	0,
84 	GF_SG_EVENT_EXPOSED_FIELD	=	1,
85 	GF_SG_EVENT_IN		=	2,
86 	GF_SG_EVENT_OUT		=	3,
87 	GF_SG_EVENT_UNKNOWN	=	4
88 };
89 /*! gets the event type name
90 \param EventType the event type
91 \param forX3D for X3D dumping
92 \return the event name
93 */
94 const char *gf_sg_vrml_get_event_type_name(u32 EventType, Bool forX3D);
95 
96 /*! field coding mode
97 
98 	BIFS defines the bitstream syntax contextually, and therefore sometimes refer to fields as indexed
99   in the node ("all" mode) or just as a sub-set (in, out, def, dyn modes) of similar types
100 */
101 enum
102 {
103 	/*all fields and events*/
104 	GF_SG_FIELD_CODING_ALL		=	0,
105 	/*defined fields (exposedField and Field)*/
106 	GF_SG_FIELD_CODING_DEF		=	1,
107 	/*input field (exposedField and eventIn)*/
108 	GF_SG_FIELD_CODING_IN		=	2,
109 	/*output field (exposedField and eventOut)*/
110 	GF_SG_FIELD_CODING_OUT		=	3,
111 	/*field that can be animated (subset of inFields) used in BIFS_Anim only*/
112 	GF_SG_FIELD_CODING_DYN		=	4
113 };
114 
115 /*! gets the number of field in the given mode (BIFS specific)
116 \param n the target node
117 \param IndexMode the field indexing mode
118 \return the number of field in this mode*/
119 u32 gf_node_get_num_fields_in_mode(GF_Node *n, u8 IndexMode);
120 
121 /*		SF Types	*/
122 /*! Boolean*/
123 typedef u32 SFBool;
124 /*! Integer*/
125 typedef s32 SFInt32;
126 /*! Integer*/
127 typedef s32 SFInt;
128 /*! Float*/
129 typedef Fixed SFFloat;
130 /*! Double*/
131 typedef Double SFDouble;
132 
133 /*! String*/
134 typedef struct
135 {
136 	char* buffer;
137 } SFString;
138 
139 /*! Time*/
140 typedef Double SFTime;
141 
142 /*! RGB color*/
143 typedef struct {
144 	Fixed	red;
145 	Fixed	green;
146 	Fixed	blue;
147 } SFColor;
148 
149 /*! RGBA color*/
150 typedef struct {
151 	Fixed	red;
152 	Fixed	green;
153 	Fixed	blue;
154 	Fixed	alpha;
155 } SFColorRGBA;
156 
157 /*! URL*/
158 typedef struct {
159 	u32 OD_ID;
160 	char *url;
161 } SFURL;
162 
163 /*! 2D vector (double)*/
164 typedef struct {
165 	Double	x;
166 	Double	y;
167 } SFVec2d;
168 
169 /*! 3D vector (double)*/
170 typedef struct {
171 	Double	x;
172 	Double	y;
173 	Double	z;
174 } SFVec3d;
175 
176 /*typedef's to main math tools*/
177 
178 /*! 2D vector (float)*/
179 typedef struct __vec2f SFVec2f;
180 /*! 3D vector (float)*/
181 typedef struct __vec3f SFVec3f;
182 /*! rotation (float)*/
183 typedef struct __vec4f SFRotation;
184 /*! 4D vector (float)*/
185 typedef struct __vec4f SFVec4f;
186 
187 /*! Image data (rgb pixels)*/
188 typedef struct {
189 	u32 width;
190 	u32 height;
191 	u8 numComponents;
192 	unsigned char* pixels;
193 } SFImage;
194 /*! BIFS Command Buffer*/
195 typedef struct {
196 	u32 bufferSize;
197 	u8* buffer;
198 	/*uncompressed command list*/
199 	GF_List *commandList;
200 } SFCommandBuffer;
201 
202 /*! Script
203  	Note: the javascript or vrml script is handled in its decompressed (textual) format
204 since most JS interpreter work with text*/
205 typedef struct {
206 	char* script_text;
207 } SFScript;
208 
209 /*! BIFS Attribute Reference*/
210 typedef struct {
211 	GF_Node *node;
212 	u32 fieldIndex;
213 } SFAttrRef;
214 
215 /*		MF Types	*/
216 
217 /*! generic MF field: all MF fields use the same syntax except MFNode which uses GF_List. You  can thus use
218 this structure to safely typecast MF field pointers*/
219 typedef struct {
220 	u32 count;
221 	u8 *array;
222 } GenMFField;
223 /*! Interger array*/
224 typedef struct {
225 	u32 count;
226 	s32* vals;
227 } MFInt32;
228 /*! Interger array*/
229 typedef struct {
230 	u32 count;
231 	s32* vals;
232 } MFInt;
233 /*! Float array*/
234 typedef struct {
235 	u32 count;
236 	Fixed *vals;
237 } MFFloat;
238 /*! Double array*/
239 typedef struct {
240 	u32 count;
241 	Double *vals;
242 } MFDouble;
243 /*! Boolean array*/
244 typedef struct {
245 	u32 count;
246 	u32* vals;
247 } MFBool;
248 /*! Color RGB array*/
249 typedef struct {
250 	u32 count;
251 	SFColor* vals;
252 } MFColor;
253 /*! Color RGBA array*/
254 typedef struct {
255 	u32 count;
256 	SFColorRGBA* vals;
257 } MFColorRGBA;
258 /*! Rotation array*/
259 typedef struct {
260 	u32 count;
261 	SFRotation*	vals;
262 } MFRotation;
263 /*! Time array*/
264 typedef struct {
265 	u32 count;
266 	Double* vals;
267 } MFTime;
268 /*! 2D Vector (float) array*/
269 typedef struct {
270 	u32 count;
271 	SFVec2f* vals;
272 } MFVec2f;
273 /*! 2D Vector (double) array*/
274 typedef struct {
275 	u32 count;
276 	SFVec2d* vals;
277 } MFVec2d;
278 /*! 3D Vector (float) array*/
279 typedef struct {
280 	u32 count;
281 	SFVec3f* vals;
282 } MFVec3f;
283 /*! 3D Vector (double) array*/
284 typedef struct {
285 	u32 count;
286 	SFVec3d* vals;
287 } MFVec3d;
288 /*! 4D Vector (float) array*/
289 typedef struct {
290 	u32 count;
291 	SFVec4f* vals;
292 } MFVec4f;
293 
294 /*! URL array*/
295 typedef struct {
296 	u32 count;
297 	SFURL* vals;
298 } MFURL;
299 /*! String array*/
300 typedef struct {
301 	u32 count;
302 	char** vals;
303 } MFString;
304 /*! Script array*/
305 typedef struct {
306 	u32 count;
307 	SFScript *vals;
308 } MFScript;
309 
310 /*! Attribute Reference array*/
311 typedef struct {
312 	u32 count;
313 	SFAttrRef* vals;
314 } MFAttrRef;
315 
316 /*! converts an SFColor to an SFColorRGBA by setting the alpha component to 1
317 \param val the input color
318 \return the RGBA color*/
319 SFColorRGBA gf_sg_sfcolor_to_rgba(SFColor val);
320 
321 /*! field types, as defined in BIFS encoding (used for scripts and proto coding)*/
322 enum
323 {
324 	GF_SG_VRML_SFBOOL		=	0,
325 	GF_SG_VRML_SFFLOAT		=	1,
326 	GF_SG_VRML_SFTIME		=	2,
327 	GF_SG_VRML_SFINT32		=	3,
328 	GF_SG_VRML_SFSTRING		=	4,
329 	GF_SG_VRML_SFVEC3F		=	5,
330 	GF_SG_VRML_SFVEC2F		=	6,
331 	GF_SG_VRML_SFCOLOR		=	7,
332 	GF_SG_VRML_SFROTATION	=	8,
333 	GF_SG_VRML_SFIMAGE		=	9,
334 	GF_SG_VRML_SFNODE		=	10,
335 	/*TO CHECK*/
336 	GF_SG_VRML_SFVEC4F		=	11,
337 
338 	/*used types in GPAC but not defined in the MPEG4 spec*/
339 	GF_SG_VRML_SFURL,
340 	GF_SG_VRML_SFSCRIPT,
341 	GF_SG_VRML_SFCOMMANDBUFFER,
342 	/*used types in X3D*/
343 	GF_SG_VRML_SFDOUBLE,
344 	GF_SG_VRML_SFCOLORRGBA,
345 	GF_SG_VRML_SFVEC2D,
346 	GF_SG_VRML_SFVEC3D,
347 
348 	GF_SG_VRML_FIRST_MF		= 32,
349 	GF_SG_VRML_MFBOOL		= GF_SG_VRML_FIRST_MF,
350 	GF_SG_VRML_MFFLOAT,
351 	GF_SG_VRML_MFTIME,
352 	GF_SG_VRML_MFINT32,
353 	GF_SG_VRML_MFSTRING,
354 	GF_SG_VRML_MFVEC3F,
355 	GF_SG_VRML_MFVEC2F,
356 	GF_SG_VRML_MFCOLOR,
357 	GF_SG_VRML_MFROTATION,
358 	GF_SG_VRML_MFIMAGE,
359 	GF_SG_VRML_MFNODE,
360 	GF_SG_VRML_MFVEC4F,
361 
362 	GF_SG_VRML_SFATTRREF	=	45,
363 	GF_SG_VRML_MFATTRREF	=	46,
364 
365 	/*used types in GPAC but not defined in the MPEG4 spec*/
366 	GF_SG_VRML_MFURL,
367 	GF_SG_VRML_MFSCRIPT,
368 	GF_SG_VRML_MFCOMMANDBUFFER,
369 
370 	/*used types in X3D*/
371 	GF_SG_VRML_MFDOUBLE,
372 	GF_SG_VRML_MFCOLORRGBA,
373 	GF_SG_VRML_MFVEC2D,
374 	GF_SG_VRML_MFVEC3D,
375 
376 	/*special event only used in routes for binding eventOut/exposedFields to script functions.
377 	 A route with ToField.FieldType set to this value holds a pointer to a function object.
378 	*/
379 	GF_SG_VRML_SCRIPT_FUNCTION,
380 
381 	/*special event only used in routes for binding eventOut/exposedFields to generic functions.
382 	 A route with ToField.FieldType set to this value holds a pointer to a function object.
383 	*/
384 	GF_SG_VRML_GENERIC_FUNCTION,
385 
386 	GF_SG_VRML_UNKNOWN
387 };
388 
389 /*! checks if a field is an SF field
390 \param FieldType the tragte filed type
391 \return GF_TRUE if field is a single field*/
392 Bool gf_sg_vrml_is_sf_field(u32 FieldType);
393 
394 /*! translates MF/SF to SF type
395 \param FieldType the tragte filed type
396 \return SF field type*/
397 u32 gf_sg_vrml_get_sf_type(u32 FieldType);
398 
399 /*! inserts (+alloc) a slot in the MFField with a specified position for insertion and sets the ptr to the newly created slot
400 \param mf pointer to the MF field
401 \param FieldType the MF field type
402 \param new_ptr set to the allocated slot (do not free)
403 \param InsertAt is the 0-based index for the new slot
404 \return error if any
405 */
406 GF_Err gf_sg_vrml_mf_insert(void *mf, u32 FieldType, void **new_ptr, u32 InsertAt);
407 /*! removes all items of the MFField
408 \param mf pointer to the MF field
409 \param FieldType the MF field type
410 \return error if any
411 */
412 GF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType);
413 
414 /*! deletes an MFUrl field
415 \note exported for URL handling in compositor
416 \param url the MF url field to reset
417 */
418 void gf_sg_mfurl_del(MFURL url);
419 /*! copies MFUrl field
420 \note exported for URL handling in compositor
421 \param dst the destination MF url field to copy
422 \param src the source MF url field to copy
423 */
424 void gf_sg_vrml_copy_mfurl(MFURL *dst, MFURL *src);
425 /*! interpolates SFRotation
426 \note exported for 3D camera in compositor
427 \param kv1 start value for interpolation
428 \param kv2 end value for interpolation
429 \param f interpolation factor
430 \return the interpolated result
431 */
432 SFRotation gf_sg_sfrotation_interpolate(SFRotation kv1, SFRotation kv2, Fixed f);
433 
434 /*! adds a new node to the "children" field
435 \warning DOES NOT CHECK CHILD/PARENT type compatibility
436 \param parent the target parent node
437 \param new_child the child to insert
438 \param pos the 0-BASED index in the list of children, -1 means end of list (append)
439 \return error if any
440 */
441 GF_Err gf_node_insert_child(GF_Node *parent, GF_Node *new_child, s32 pos);
442 
443 /*! removes and replace given child by specified node. If node is NULL, only delete target node
444 \warning DOES NOT CHECK CHILD/PARENT type compatibility
445 \param node the target node to replace
446 \param container the container list
447 \param pos the 0-BASED index in the list of children, -1 means end of list (append)
448 \param newNode the new node to use
449 \return error if any
450 */
451 GF_Err gf_node_replace_child(GF_Node *node, GF_ChildNodeItem **container, s32 pos, GF_Node *newNode);
452 
453 
454 /*! internal prototype*/
455 #define GF_SG_INTERNAL_PROTO	(PTR_TO_U_CAST -1)
456 
457 
458 #ifndef GPAC_DISABLE_VRML
459 
460 
461 /*! VRML grouping nodes macro - note we have inverted the children field to be
462 compatible with the base GF_ParentNode node
463 All grouping nodes (with "children" field) implement the following:
464 
465 addChildren: chain containing nodes to add passed as eventIn - handled internally through ROUTE
466 void (*on_addChildren)(GF_Node *pNode): add feventIn signaler - this is handled internally by the scene_graph and SHALL
467 NOT BE OVERRIDEN since it takes care of node(s) routing
468 
469 removeChildren: chain containing nodes to remove passed as eventIn - handled internally through ROUTE
470 
471 void (*on_removeChildren)(GF_Node *pNode): remove eventIn signaler - this is handled internally by the scene_graph and SHALL
472 NOT BE OVERRIDEN since it takes care of node(s) routing
473 
474 children: list of children SFNodes
475 */
476 #define VRML_CHILDREN							\
477 	CHILDREN									\
478 	GF_ChildNodeItem *addChildren;							\
479 	void (*on_addChildren)(GF_Node *pNode, struct _route *route);		\
480 	GF_ChildNodeItem *removeChildren;						\
481 	void (*on_removeChildren)(GF_Node *pNode, struct _route *route);		\
482 
483 /*! generic VRML parent node*/
484 typedef struct
485 {
486 	BASE_NODE
487 	VRML_CHILDREN
488 } GF_VRMLParent;
489 
490 /*! setup a vrml parent
491 \param n the target node*/
492 void gf_sg_vrml_parent_setup(GF_Node *n);
493 /*! resets all children in a vrml parent node (but does not destroy the node)
494 \param n the target node*/
495 void gf_sg_vrml_parent_destroy(GF_Node *n);
496 
497 /*! checks if a given node tag is in a given NDT table
498 \param tag the node tag
499 \param NDTType the NDT type
500 \return GF_TRUE if node tag is in the NDT*/
501 Bool gf_node_in_table_by_tag(u32 tag, u32 NDTType);
502 /*! gets field type name
503 \param FieldType the field type
504 \return the field name*/
505 const char *gf_sg_vrml_get_field_type_name(u32 FieldType);
506 
507 /*! allocates a new field
508 \note GF_SG_VRML_MFNODE will return a pointer to a GF_List structure (eg GF_List *), GF_SG_VRML_SFNODE will return NULL
509 \param FieldType the field type
510 \return the new field pointer*/
511 void *gf_sg_vrml_field_pointer_new(u32 FieldType);
512 /*! deletes a field pointer (including SF an,d MF nodes)
513 \param field the field pointer value
514 \param FieldType the field type
515 */
516 void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType);
517 
518 /*! adds at the end of an MF field
519 \param mf pointer to the MF field
520 \param FieldType the MF field type
521 \param new_ptr set to the allocated SF field slot - do not destroy
522 \return error if any
523 */
524 GF_Err gf_sg_vrml_mf_append(void *mf, u32 FieldType, void **new_ptr);
525 /*! removes the desired item of an MF field
526 \param mf pointer to the MF field
527 \param FieldType the MF field type
528 \param RemoveFrom the 0-based index of item to remove
529 \return error if any
530 */
531 GF_Err gf_sg_vrml_mf_remove(void *mf, u32 FieldType, u32 RemoveFrom);
532 /*! allocates an MF array
533 \param mf pointer to the MF field
534 \param FieldType the MF field type
535 \param NbItems number of items to allocate
536 \return error if any
537 */
538 GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems);
539 /*! gets the item in the MF array
540 \param mf pointer to the MF field
541 \param FieldType the MF field type
542 \param new_ptr set to the SF field slot - do not destroy
543 \param ItemPos the 0-based index of item to remove
544 \return error if any
545 */
546 GF_Err gf_sg_vrml_mf_get_item(void *mf, u32 FieldType, void **new_ptr, u32 ItemPos);
547 
548 /*! copies a field content EXCEPT SF/MFNode. Pointers to field shall be used
549 \param dest pointer to the MF field
550 \param orig pointer to the MF field
551 \param FieldType the MF field type
552 */
553 void gf_sg_vrml_field_copy(void *dest, void *orig, u32 FieldType);
554 
555 /*! clones a field content EXCEPT SF/MFNode. Pointers to field shall be used
556 \param dest pointer to the MF field
557 \param orig pointer to the MF field
558 \param FieldType the MF field type
559 \param inScene target scene graph for SFCommandBuffers cloning
560 */
561 void gf_sg_vrml_field_clone(void *dest, void *orig, u32 FieldType, GF_SceneGraph *inScene);
562 
563 /*! indicates whether 2 fields of same type EXCEPT SF/MFNode are equal
564 \param dest pointer to the MF field
565 \param orig pointer to the MF field
566 \param FieldType the MF field type
567 \return GF_TRUE if fields equal
568 */
569 Bool gf_sg_vrml_field_equal(void *dest, void *orig, u32 FieldType);
570 
571 
572 /*GF_Route manipultaion : routes are used to pass events between nodes. Event handling is managed by the scene graph
573 however only the nodes overloading the EventIn handler associated with the event will process the eventIn*/
574 
575 /*! creates a new route
576 \note routes are automatically destroyed if either the target or origin node of the route is destroyed
577 \param sg the target scene graph of the route
578 \param fromNode the source node triggering the event out
579 \param fromField the source field triggering the event out
580 \param toNode the destination node accepting the event in
581 \param toField the destination field accepting the event in
582 \return a new route object
583 */
584 GF_Route *gf_sg_route_new(GF_SceneGraph *sg, GF_Node *fromNode, u32 fromField, GF_Node *toNode, u32 toField);
585 
586 /*! destroys a route
587 \param route the target route
588 */
589 void gf_sg_route_del(GF_Route *route);
590 /*! destroys a route by ID
591 \param sg the scene graph of the route
592 \param routeID the ID of the route to destroy
593 \return error if any
594 */
595 GF_Err gf_sg_route_del_by_id(GF_SceneGraph *sg,u32 routeID);
596 
597 /*! locate a route by ID
598 \param sg the scene graph of the route
599 \param RouteID the ID of the route
600 \return the route object or NULL if not found
601 */
602 GF_Route *gf_sg_route_find(GF_SceneGraph *sg, u32 RouteID);
603 /*! locate a route by name
604 \param sg the scene graph of the route
605 \param name the name of the route
606 \return the route object or NULL if not found
607 */
608 GF_Route *gf_sg_route_find_by_name(GF_SceneGraph *sg, char *name);
609 /*! assigns a route ID
610 \param route the target route
611 \param ID the ID to assign
612 \return error if any - fails if a route with same ID already exists*/
613 GF_Err gf_sg_route_set_id(GF_Route *route, u32 ID);
614 
615 /*! assign a route name
616 \param route the target route
617 \param name the name to assign
618 \return error if any - fails if a route with same name already exists
619 */
620 GF_Err gf_sg_route_set_name(GF_Route *route, char *name);
621 /*! gets route name
622 \param route the target route
623 \return the route name or NULL if not set
624 */
625 char *gf_sg_route_get_name(GF_Route *route);
626 
627 /*! retuns next available RouteID
628 \note this doesn't track inserted routes, that's the caller responsability
629 \param sg the target scene graph of the route
630 \return the next available ID for routes
631 */
632 u32 gf_sg_get_next_available_route_id(GF_SceneGraph *sg);
633 /*! sets max defined route ID used in the scene - used to handle RouteInsert commands
634 note that this must be called by the user to be effective,; otherwise the max route ID is computed
635 from the routes present in scene
636 \param sg the target scene graph of the route
637 \param ID the value of the max defined route ID
638 */
639 void gf_sg_set_max_defined_route_id(GF_SceneGraph *sg, u32 ID);
640 
641 /*! creates a new route from a node output to a given callback/function
642 \param sg the target scene graph of the route
643 \param fromNode the source node emiting the event out
644 \param fromField the source field emiting the event out
645 \param cbk opaque data to pass to the callback
646 \param route_callback route callback function to call
647 */
648 void gf_sg_route_new_to_callback(GF_SceneGraph *sg, GF_Node *fromNode, u32 fromField, void *cbk, void ( *route_callback) (void *param, GF_FieldInfo *from_field) );
649 
650 /*! activates all routes currently triggered - this follows the event cascade model of VRML/MPEG4:
651 	- routes are collected during eventOut generation
652 	- routes are activated. If eventOuts are generated during activation the cycle goes on.
653 
654   A route cannot be activated twice in the same simulation tick, hence this function shall be called
655   ONCE AND ONLY ONCE per simulation tick
656 
657 Note that children scene graphs register their routes with the top-level graph, so only the main
658 scene graph needs to be activated
659 \param sg the target scene graph of the route
660 */
661 void gf_sg_activate_routes(GF_SceneGraph *sg);
662 
663 
664 /*
665 				proto handling
666 
667 	The lib allows you to construct prototype nodes as defined in VRML/MPEG4 by constructing
668 	proto interfaces and instantiating them. An instantiated proto is handled as a single node for
669 	rendering, thus an application will never handle proto instances for rendering
670 */
671 
672 /*! proto object*/
673 typedef struct _proto GF_Proto;
674 /*! proto field object*/
675 typedef struct _protofield GF_ProtoFieldInterface;
676 
677 
678 /*! retuns next available proto ID
679 \param sg the target scene graph of the proto
680 \return the next available proto ID
681 */
682 u32 gf_sg_get_next_available_proto_id(GF_SceneGraph *sg);
683 
684 /*! constructs a new proto identified by ID/name in the given scene
685 2 protos in the same scene may not have the same ID/name
686 
687 \param sg the target scene graph in which the proto is created
688 \param ProtoID ID of the proto to create
689 \param name name of the proto to create
690 \param unregistered if GF_TRUE, the proto is not stored in the graph main proto list but in an alternate list (used for memory handling of scene graph only). Several protos with the same ID/Name can be stored unregistered
691 \return a new proto object
692 */
693 GF_Proto *gf_sg_proto_new(GF_SceneGraph *sg, u32 ProtoID, char *name, Bool unregistered);
694 
695 /*! destroys a proto - can be used even if instances of the proto are still present
696 \param proto the target proto
697 \return error if any
698 */
699 GF_Err gf_sg_proto_del(GF_Proto *proto);
700 
701 /*! returns the graph associated with this proto. Such a graph cannot be used for rendering but is needed during
702 construction of proto dictionaries in case of nested protos
703 \param proto the target proto
704 \return associated scene graph proto the target proto
705 */
706 GF_SceneGraph *gf_sg_proto_get_graph(GF_Proto *proto);
707 
708 /*! adds node code - a proto is build of several nodes, the first node is used for rendering
709 and the others are kept private. This set of nodes is refered to as the proto "node code"
710 \param proto the target proto
711 \param n the node to add to the proto code
712 \return error if any
713 */
714 GF_Err gf_sg_proto_add_node_code(GF_Proto *proto, GF_Node *n);
715 
716 /*! gets number of field in the proto interface
717 \param proto the target proto
718 \return the number of fields
719 */
720 u32 gf_sg_proto_get_field_count(GF_Proto *proto);
721 /*! locates a field declaration by name
722 \param proto the target proto
723 \param fieldName the name of the field
724 \return the proto field interface or NULL if not found
725 */
726 GF_ProtoFieldInterface *gf_sg_proto_field_find_by_name(GF_Proto *proto, char *fieldName);
727 /*! locates field declaration by index
728 \param proto the target proto
729 \param fieldIndex 0-based index of the field to query
730 \return the proto field interface or NULL if not found
731 */
732 GF_ProtoFieldInterface *gf_sg_proto_field_find(GF_Proto *proto, u32 fieldIndex);
733 
734 /*! creates a new field declaration in the proto. of given fieldtype and eventType
735 fieldName can be NULL, if so the name will be fieldN, N being the index of the created field
736 \param proto the target proto
737 \param fieldType the data type of the field to create
738 \param eventType the event type of the field to create
739 \param fieldName the name of the field to create (may be NULL)
740 \return the new proto field interface
741 */
742 GF_ProtoFieldInterface *gf_sg_proto_field_new(GF_Proto *proto, u32 fieldType, u32 eventType, char *fieldName);
743 
744 /*! assigns the node field to a field of the proto (the node field IS the proto field)
745 the node shall be a node of the proto scenegraph, and the fieldtype/eventType of both fields shall match
746 (except SF/MFString and MF/SFURL which are allowed) due to BIFS semantics
747 
748 \param proto the target proto
749 \param protoFieldIndex the proto field index to assign
750 \param node the node (shall be part of the proto node code) to link to
751 \param nodeFieldIndex the field index of the node to link to
752 \return error if any
753 */
754 GF_Err gf_sg_proto_field_set_ised(GF_Proto *proto, u32 protoFieldIndex, GF_Node *node, u32 nodeFieldIndex);
755 
756 /*! returns field info of the field - this is typically used to setup the default value of the field
757 \param field the proto field interface to query
758 \param info filled with the proto field interface info
759 \return error if any
760 */
761 GF_Err gf_sg_proto_field_get_field(GF_ProtoFieldInterface *field, GF_FieldInfo *info);
762 
763 /*
764 	NOTE on proto instances:
765 		The proto instance is handled as an GF_Node outside the scenegraph lib, and is manipulated with the same functions
766 		as an GF_Node
767 		The proto instance may or may not be loaded.
768 		An unloaded instance only contains the proto instance fields
769 		A loaded instance contains the proto instance fields plus all the proto code (Nodes, routes) and
770 		will load any scripts present in it. This allows keeping the memory usage of proto very low, especially
771 		when nested protos (protos used as building blocks of their parent proto) are used.
772 */
773 
774 /*! creates the proto instance without the proto code
775 \param sg the target scene graph of the node
776 \param proto the proto to instanciate
777 \return the new prototype instance node
778 */
779 GF_Node *gf_sg_proto_create_instance(GF_SceneGraph *sg, GF_Proto *proto);
780 
781 /*! loads code in this instance - all subprotos are automatically created, thus you must only instantiate
782 top-level protos. VRML/BIFS doesn't allow for non top-level proto instanciation in the main graph
783 All nodes created in this proto will be forwarded to the app for initialization
784 \param proto_inst the proto instance to load
785 \return error if any
786 */
787 GF_Err gf_sg_proto_load_code(GF_Node *proto_inst);
788 
789 /*! locates a prototype definition by ID or by name. when looking by name, ID is ignored
790 \param sg the target scene graph of the proto
791 \param ProtoID the ID of the proto to locate
792 \param name the name of the proto to locate
793 \return the proto node or NULL if not found
794 */
795 GF_Proto *gf_sg_find_proto(GF_SceneGraph *sg, u32 ProtoID, char *name);
796 
797 /*! deletes all protos in given scene - does NOT delete instances of protos, only the proto object is destroyed
798 \param sg the target scene graph
799 \return error if any
800 */
801 GF_Err gf_sg_delete_all_protos(GF_SceneGraph *sg);
802 
803 /*! gets proto of a prototype instance node
804 \param node the target prototype instance node
805 \return the proto node or NULL if the node is not a prototype instance or the source proto was destroyed*/
806 GF_Proto *gf_node_get_proto(GF_Node *node);
807 /*! returns the ID of a proto
808 \param proto the target proto
809 \return the proto ID
810 */
811 u32 gf_sg_proto_get_id(GF_Proto *proto);
812 /*! returns the name of a proto
813 \param proto the target proto
814 \return the proto name
815 */
816 const char *gf_sg_proto_get_class_name(GF_Proto *proto);
817 
818 /*! checks if a proto instance field is an SFTime routed to a startTime/stopTime field in the proto code (MPEG-4 specific for updates)
819 \param node the target prototype instance node
820 \param field the target field info
821 \return GF_TRUE if this is the case
822 */
823 Bool gf_sg_proto_field_is_sftime_offset(GF_Node *node, GF_FieldInfo *field);
824 
825 /*! sets an ISed (route between proto instance and internal proto code) field in a proto instance (not a proto) - this is needed with dynamic node creation inside a proto instance (conditionals)
826 \param protoinst the target prototype instance node
827 \param protoFieldIndex field index in prototype instance node
828 \param node the target node
829 \param nodeFieldIndex field index in the target node
830 \return error if any
831 */
832 GF_Err gf_sg_proto_instance_set_ised(GF_Node *protoinst, u32 protoFieldIndex, GF_Node *node, u32 nodeFieldIndex);
833 
834 /*! returns root node (the one and only one being traversed) of this proto instance if any
835 \param node the target prototype instance node
836 \return the root node of the proto code - may be NULL
837 */
838 GF_Node *gf_node_get_proto_root(GF_Node *node);
839 
840 /*! indicates proto field has been parsed and its value is valid - this is needed for externProtos not specifying default
841 values
842 \param node the target prototype instance node
843 \param info the target field info
844 */
845 void gf_sg_proto_mark_field_loaded(GF_Node *node, GF_FieldInfo *info);
846 
847 
848 /*! sets proto loader callback - callback user data is the same as simulation time callback
849 
850 GetExternProtoLib is a pointer to the proto lib loader - this callback shall return the LPSCENEGRAPH
851 of the extern proto lib if found and loaded, NULL if not found and GF_SG_INTERNAL_PROTO for internal
852 hardcoded protos (extensions of MPEG-4 scene graph used for module deveopment)
853 \param sg the target scene graph
854 \param GetExternProtoLib the callback function
855 */
856 void gf_sg_set_proto_loader(GF_SceneGraph *sg, GF_SceneGraph *(*GetExternProtoLib)(void *SceneCallback, MFURL *lib_url));
857 
858 /*! gets a pointer to the MF URL field for externProto info - DO NOT TOUCH THIS FIELD
859 \param proto the target proto field
860 \return the MFURL associated with an extern proto, or NULL if proto is not an extern proto
861 */
862 MFURL *gf_sg_proto_get_extern_url(GF_Proto *proto);
863 
864 
865 /*
866 			JavaScript tools
867 */
868 
869 /*! script fields type don't have the same value as the bifs ones...*/
870 enum
871 {
872 	GF_SG_SCRIPT_TYPE_FIELD = 0,
873 	GF_SG_SCRIPT_TYPE_EVENT_IN,
874 	GF_SG_SCRIPT_TYPE_EVENT_OUT,
875 };
876 /*! script field object*/
877 typedef struct _scriptfield GF_ScriptField;
878 /*! creates new sript field - script fields are dynamically added to the node, and thus can be accessed through the
879 same functions as other GF_Node fields
880 \param script the script node
881 \param eventType the event type of the new field
882 \param fieldType the data type of the new field
883 \param name the name of the new field
884 \return a new scritp field
885 */
886 GF_ScriptField *gf_sg_script_field_new(GF_Node *script, u32 eventType, u32 fieldType, const char *name);
887 /*! retrieves field info of a script field object, useful to get the field index
888 \param field the script field to query
889 \param info filled with the field info
890 \return error if any
891 */
892 GF_Err gf_sg_script_field_get_info(GF_ScriptField *field, GF_FieldInfo *info);
893 
894 /*! activates eventIn for script node - needed for BIFS field replace
895 \param script the target script node
896 \param in_field the field info of the activated event in field
897 */
898 void gf_sg_script_event_in(GF_Node *script, GF_FieldInfo *in_field);
899 
900 
901 /*! signals eventOut has been set by field index
902 \note Routes are automatically triggered when the event is signaled
903 \param n the target node emitin the event
904 \param FieldIndex the field index emiting the event
905 */
906 void gf_node_event_out(GF_Node *n, u32 FieldIndex);
907 /*! signals eventOut has been set by event name.
908 \note Routes are automatically triggered when the event is signaled
909 \param n the target node emitin the event
910 \param eventName the name of the field emiting the event
911 */
912 void gf_node_event_out_str(GF_Node *n, const char *eventName);
913 
914 /*! gets MPEG-4 / VRML node tag by class name
915 \param node_name the node name
916 \return the node tag*/
917 u32 gf_node_mpeg4_type_by_class_name(const char *node_name);
918 
919 #ifndef GPAC_DISABLE_X3D
920 /*! gets X3D node tag by class name
921 \param node_name the node name
922 \return the node tag*/
923 u32 gf_node_x3d_type_by_class_name(const char *node_name);
924 #endif
925 
926 
927 #endif /*GPAC_DISABLE_VRML*/
928 
929 
930 /*! check if a hardcoded prototype node acts as a grouping node
931 \param n the target prototype instance node
932 \return GF_TRUE if acting as a grouping node*/
933 Bool gf_node_proto_is_grouping(GF_Node *n);
934 
935 /*! tags a hardcoded proto as being a grouping node
936 \param n the target prototype instance node
937 \return error if any
938 */
939 GF_Err gf_node_proto_set_grouping(GF_Node *n);
940 
941 /*! assigns callback to an eventIn field of an hardcoded proto
942 \param n the target prototype instance node
943 \param fieldIndex the target field index
944 \param event_in_cbk the event callback function
945 \return error if any
946 */
947 GF_Err gf_node_set_proto_eventin_handler(GF_Node *n, u32 fieldIndex, void (*event_in_cbk)(GF_Node *pThis, struct _route *route) );
948 
949 /*! @} */
950 
951 
952 #ifdef __cplusplus
953 }
954 #endif
955 
956 
957 
958 #endif /*_GF_SG_VRML_H_*/
959