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