| /* | |
| * GPAC - Multimedia Framework C SDK | |
| * | |
| * Authors: Jean Le Feuvre | |
| * Copyright (c) Telecom ParisTech 2000-2026 | |
| * All rights reserved | |
| * | |
| * This file is part of GPAC / Scene Graph sub-project | |
| * | |
| * GPAC is free software; you can redistribute it and/or modify | |
| * it under the terms of the GNU Lesser General Public License as published by | |
| * the Free Software Foundation; either version 2, or (at your option) | |
| * any later version. | |
| * | |
| * GPAC is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU Lesser General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU Lesser General Public | |
| * License along with this library; see the file COPYING. If not, write to | |
| * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | |
| * | |
| */ | |
| #include <gpac/internal/scenegraph_dev.h> | |
| /*MPEG4 & X3D tags (for node tables & script handling)*/ | |
| #include <gpac/nodes_mpeg4.h> | |
| #include <gpac/nodes_x3d.h> | |
| #ifndef GPAC_DISABLE_VRML | |
| #include <gpac/internal/bifs_dev.h> | |
| GF_EXPORT | |
| Bool gf_node_in_table_by_tag(u32 tag, u32 NDTType) | |
| { | |
| if (!tag) return 0; | |
| if (tag==TAG_ProtoNode) return 1; | |
| else if (tag<=GF_NODE_RANGE_LAST_MPEG4) { | |
| #ifndef GPAC_DISABLE_BIFS | |
| u32 i; | |
| for (i=0; i<GF_BIFS_LAST_VERSION; i++) { | |
| if (gf_bifs_get_node_type(NDTType, tag, i+1)) return 1; | |
| } | |
| return 0; | |
| #else | |
| /*if BIFS is disabled, we don't have the NDTs - we therefore allow any node in any table otherwise we would reject | |
| them all*/ | |
| return 1; | |
| #endif | |
| } | |
| #ifndef GPAC_DISABLE_X3D | |
| else if (tag<=GF_NODE_RANGE_LAST_X3D) { | |
| return gf_x3d_get_node_type(NDTType, tag); | |
| } | |
| #endif | |
| return 0; | |
| } | |
| static void Node_on_add_children(GF_Node *node, GF_Route *route) | |
| { | |
| GF_ChildNodeItem *list; | |
| GF_FieldInfo field; | |
| GF_VRMLParent *n = (GF_VRMLParent *)node; | |
| if (n->children) { | |
| list = n->children; | |
| while (list->next) list = list->next; | |
| list->next = n->addChildren; | |
| } else { | |
| n->children = n->addChildren; | |
| } | |
| n->addChildren = NULL; | |
| /*signal children field is modified*/ | |
| field.name = "children"; | |
| field.eventType = GF_SG_EVENT_EXPOSED_FIELD; | |
| field.fieldType = GF_SG_VRML_MFNODE; | |
| field.NDTtype = -1; | |
| if ( node->sgprivate->tag == TAG_MPEG4_Transform ) | |
| field.fieldIndex = 3; | |
| else | |
| field.fieldIndex = 2; | |
| field.far_ptr = & n->children; | |
| gf_node_event_out(node, field.fieldIndex); | |
| gf_node_changed(node, &field); | |
| if (node->sgprivate->scenegraph->on_node_modified) { | |
| field.name = "addChildren"; | |
| field.eventType = GF_SG_EVENT_IN; | |
| field.fieldType = GF_SG_VRML_MFNODE; | |
| field.NDTtype = -1; | |
| field.fieldIndex = 0; | |
| field.far_ptr = & n->addChildren; | |
| node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, &field, NULL); | |
| } | |
| } | |
| static void Node_on_remove_children(GF_Node *node, GF_Route *route) | |
| { | |
| GF_ChildNodeItem *list; | |
| GF_FieldInfo field; | |
| GF_VRMLParent *n = (GF_VRMLParent *)node; | |
| if (!n->removeChildren) return; | |
| list = n->removeChildren; | |
| while (list) { | |
| if (gf_node_list_del_child(& n->children, list->node)) { | |
| gf_node_unregister(list->node, node); | |
| } | |
| list = list->next; | |
| } | |
| gf_node_unregister_children(node, n->removeChildren); | |
| n->removeChildren = NULL; | |
| /*signal children field is modified*/ | |
| field.name = "children"; | |
| field.eventType = GF_SG_EVENT_EXPOSED_FIELD; | |
| field.fieldType = GF_SG_VRML_MFNODE; | |
| field.NDTtype = -1; | |
| if ( node->sgprivate->tag == TAG_MPEG4_Transform ) | |
| field.fieldIndex = 3; | |
| else | |
| field.fieldIndex = 2; | |
| field.far_ptr = & n->children; | |
| gf_node_event_out(node, field.fieldIndex); | |
| gf_node_changed(node, &field); | |
| if (node->sgprivate->scenegraph->on_node_modified) { | |
| field.name = "removeChildren"; | |
| field.eventType = GF_SG_EVENT_IN; | |
| field.fieldType = GF_SG_VRML_MFNODE; | |
| field.NDTtype = -1; | |
| field.fieldIndex = 1; | |
| field.far_ptr = & n->removeChildren; | |
| node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, &field, NULL); | |
| } | |
| } | |
| void gf_sg_vrml_parent_setup(GF_Node *pNode) | |
| { | |
| GF_VRMLParent *par = (GF_VRMLParent *)pNode; | |
| par->children = NULL; | |
| par->addChildren = NULL; | |
| par->on_addChildren = Node_on_add_children; | |
| par->removeChildren = NULL; | |
| par->on_removeChildren = Node_on_remove_children; | |
| pNode->sgprivate->flags |= GF_SG_CHILD_DIRTY; | |
| } | |
| void gf_sg_vrml_parent_destroy(GF_Node *pNode) | |
| { | |
| GF_VRMLParent* par = (GF_VRMLParent*)pNode; | |
| GF_ChildNodeItem* addChildren = par->addChildren; | |
| GF_ChildNodeItem* removeChildren = par->removeChildren; | |
| par->addChildren = NULL; | |
| par->removeChildren = NULL; | |
| while (par->children) { | |
| GF_ChildNodeItem *cur = par->children; | |
| par->children = cur->next; | |
| if (cur->node != pNode) gf_node_unregister(cur->node, pNode); | |
| gf_free(cur); | |
| } | |
| par->children = NULL; | |
| gf_node_unregister_children(pNode, addChildren); | |
| gf_node_unregister_children(pNode, removeChildren); | |
| } | |
| GF_EXPORT | |
| GF_Err gf_sg_delete_all_protos(GF_SceneGraph *scene) | |
| { | |
| if (!scene) return GF_BAD_PARAM; | |
| while (gf_list_count(scene->protos)) { | |
| GF_Proto *p = (GF_Proto *)gf_list_get(scene->protos, 0); | |
| gf_sg_proto_del(p); | |
| } | |
| return GF_OK; | |
| } | |
| GF_EXPORT | |
| void gf_sg_set_proto_loader(GF_SceneGraph *scene, GF_SceneGraph *(*GetExternProtoLib)(void *SceneCallback, MFURL *lib_url)) | |
| { | |
| if (!scene) return; | |
| scene->GetExternProtoLib = GetExternProtoLib; | |
| } | |
| GF_EXPORT | |
| u32 gf_sg_get_next_available_route_id(GF_SceneGraph *sg) | |
| { | |
| u32 i, count; | |
| u32 ID = 0; | |
| if (!sg->max_defined_route_id) { | |
| count = gf_list_count(sg->Routes); | |
| /*routes are not sorted*/ | |
| for (i=0; i<count; i++) { | |
| GF_Route *r = (GF_Route *)gf_list_get(sg->Routes, i); | |
| if (ID<=r->ID) ID = r->ID; | |
| } | |
| return ID+1; | |
| } else { | |
| sg->max_defined_route_id++; | |
| return sg->max_defined_route_id; | |
| } | |
| } | |
| GF_EXPORT | |
| void gf_sg_set_max_defined_route_id(GF_SceneGraph *sg, u32 ID) | |
| { | |
| sg->max_defined_route_id = MAX(sg->max_defined_route_id, ID); | |
| } | |
| GF_EXPORT | |
| u32 gf_sg_get_next_available_proto_id(GF_SceneGraph *sg) | |
| { | |
| u32 i, count; | |
| u32 ID = 0; | |
| count = gf_list_count(sg->protos); | |
| /*protos are not sorted*/ | |
| for (i=0; i<count; i++) { | |
| GF_Proto *p = (GF_Proto *)gf_list_get(sg->protos, i); | |
| if (ID<=p->ID) ID = p->ID; | |
| } | |
| count = gf_list_count(sg->unregistered_protos); | |
| for (i=0; i<count; i++) { | |
| GF_Proto *p = (GF_Proto *)gf_list_get(sg->unregistered_protos, i); | |
| if (ID<=p->ID) ID = p->ID; | |
| } | |
| return ID+1; | |
| } | |
| //adds a child in the children list | |
| GF_EXPORT | |
| GF_Err gf_node_insert_child(GF_Node *parent, GF_Node *new_child, s32 Position) | |
| { | |
| GF_ParentNode *node = (GF_ParentNode *) parent; | |
| if (Position == -1) { | |
| gf_node_list_add_child(& node->children, new_child); | |
| } else { | |
| gf_node_list_insert_child(& node->children, new_child, Position); | |
| } | |
| return GF_OK; | |
| } | |
| #if 0 | |
| GF_Err gf_node_remove_child(GF_Node *parent, GF_Node *toremove_child) | |
| { | |
| if (!gf_node_list_del_child(& ((GF_ParentNode *) parent)->children, toremove_child)) return GF_BAD_PARAM; | |
| /*V4Studio doesn't handle DEF/USE properly yet...*/ | |
| /*gf_node_unregister(toremove_child, parent);*/ | |
| return GF_OK; | |
| } | |
| #endif | |
| GF_EXPORT | |
| void gf_sg_script_load(GF_Node *n) | |
| { | |
| if (n && n->sgprivate->scenegraph->script_load) n->sgprivate->scenegraph->script_load(n); | |
| } | |
| GF_EXPORT | |
| GF_Proto *gf_sg_find_proto(GF_SceneGraph *sg, u32 ProtoID, char *name) | |
| { | |
| GF_Proto *proto; | |
| u32 i; | |
| gf_assert(sg); | |
| /*browse all top-level */ | |
| i=0; | |
| while ((proto = (GF_Proto *)gf_list_enum(sg->protos, &i))) { | |
| /*first check on name if given, since parsers use this with ID=0*/ | |
| if (name) { | |
| if (proto->Name && !stricmp(name, proto->Name)) return proto; | |
| } else if (proto->ID == ProtoID) return proto; | |
| } | |
| /*browse all top-level unregistered in reverse order*/ | |
| for (i=gf_list_count(sg->unregistered_protos); i>0; i--) { | |
| proto = (GF_Proto *)gf_list_get(sg->unregistered_protos, i-1); | |
| if (name) { | |
| if (proto->Name && !stricmp(name, proto->Name)) return proto; | |
| } else if (proto->ID == ProtoID) return proto; | |
| } | |
| return NULL; | |
| } | |
| static SFBool *NewSFBool() | |
| { | |
| SFBool *tmp = (SFBool *)gf_malloc(sizeof(SFBool)); | |
| memset(tmp, 0, sizeof(SFBool)); | |
| return tmp; | |
| } | |
| static SFFloat *NewSFFloat() | |
| { | |
| SFFloat *tmp = (SFFloat *)gf_malloc(sizeof(SFFloat)); | |
| memset(tmp, 0, sizeof(SFFloat)); | |
| return tmp; | |
| } | |
| static SFDouble *NewSFDouble() | |
| { | |
| SFDouble *tmp = (SFDouble *)gf_malloc(sizeof(SFDouble)); | |
| memset(tmp, 0, sizeof(SFDouble)); | |
| return tmp; | |
| } | |
| static SFTime *NewSFTime() | |
| { | |
| SFTime *tmp = (SFTime *)gf_malloc(sizeof(SFTime)); | |
| memset(tmp, 0, sizeof(SFTime)); | |
| return tmp; | |
| } | |
| static SFInt32 *NewSFInt32() | |
| { | |
| SFInt32 *tmp = (SFInt32 *)gf_malloc(sizeof(SFInt32)); | |
| memset(tmp, 0, sizeof(SFInt32)); | |
| return tmp; | |
| } | |
| static SFString *NewSFString() | |
| { | |
| SFString *tmp = (SFString *)gf_malloc(sizeof(SFString)); | |
| memset(tmp, 0, sizeof(SFString)); | |
| return tmp; | |
| } | |
| static SFVec3f *NewSFVec3f() | |
| { | |
| SFVec3f *tmp = (SFVec3f *)gf_malloc(sizeof(SFVec3f)); | |
| memset(tmp, 0, sizeof(SFVec3f)); | |
| return tmp; | |
| } | |
| static SFVec3d *NewSFVec3d() | |
| { | |
| SFVec3d *tmp = (SFVec3d *)gf_malloc(sizeof(SFVec3d)); | |
| memset(tmp, 0, sizeof(SFVec3d)); | |
| return tmp; | |
| } | |
| static SFVec2f *NewSFVec2f() | |
| { | |
| SFVec2f *tmp = (SFVec2f *)gf_malloc(sizeof(SFVec2f)); | |
| memset(tmp, 0, sizeof(SFVec2f)); | |
| return tmp; | |
| } | |
| static SFVec2d *NewSFVec2d() | |
| { | |
| SFVec2d *tmp = (SFVec2d *)gf_malloc(sizeof(SFVec2d)); | |
| memset(tmp, 0, sizeof(SFVec2d)); | |
| return tmp; | |
| } | |
| static SFColor *NewSFColor() | |
| { | |
| SFColor *tmp = (SFColor *)gf_malloc(sizeof(SFColor)); | |
| memset(tmp, 0, sizeof(SFColor)); | |
| return tmp; | |
| } | |
| static SFColorRGBA *NewSFColorRGBA() | |
| { | |
| SFColorRGBA *tmp = (SFColorRGBA *)gf_malloc(sizeof(SFColorRGBA)); | |
| memset(tmp, 0, sizeof(SFColorRGBA)); | |
| return tmp; | |
| } | |
| static SFRotation *NewSFRotation() | |
| { | |
| SFRotation *tmp = (SFRotation *)gf_malloc(sizeof(SFRotation)); | |
| memset(tmp, 0, sizeof(SFRotation)); | |
| return tmp; | |
| } | |
| static SFImage *NewSFImage() | |
| { | |
| SFImage *tmp = (SFImage *)gf_malloc(sizeof(SFImage)); | |
| memset(tmp, 0, sizeof(SFImage)); | |
| return tmp; | |
| } | |
| static SFURL *NewSFURL() | |
| { | |
| SFURL *tmp = (SFURL *)gf_malloc(sizeof(SFURL)); | |
| memset(tmp, 0, sizeof(SFURL)); | |
| return tmp; | |
| } | |
| static SFCommandBuffer *NewSFCommandBuffer() | |
| { | |
| SFCommandBuffer *tmp = (SFCommandBuffer *)gf_malloc(sizeof(SFCommandBuffer)); | |
| memset(tmp, 0, sizeof(SFCommandBuffer)); | |
| tmp->commandList = gf_list_new(); | |
| return tmp; | |
| } | |
| static SFScript *NewSFScript() | |
| { | |
| SFScript *tmp = (SFScript *)gf_malloc(sizeof(SFScript)); | |
| memset(tmp, 0, sizeof(SFScript)); | |
| return tmp; | |
| } | |
| static SFAttrRef *NewSFAttrRef() | |
| { | |
| SFAttrRef *tmp; | |
| GF_SAFEALLOC(tmp, SFAttrRef); | |
| return tmp; | |
| } | |
| static MFBool *NewMFBool() | |
| { | |
| MFBool *tmp = (MFBool *)gf_malloc(sizeof(MFBool)); | |
| memset(tmp, 0, sizeof(MFBool)); | |
| return tmp; | |
| } | |
| static MFFloat *NewMFFloat() | |
| { | |
| MFFloat *tmp = (MFFloat *)gf_malloc(sizeof(MFFloat)); | |
| memset(tmp, 0, sizeof(MFFloat)); | |
| return tmp; | |
| } | |
| static MFTime *NewMFTime() | |
| { | |
| MFTime *tmp = (MFTime *)gf_malloc(sizeof(MFTime)); | |
| memset(tmp, 0, sizeof(MFTime)); | |
| return tmp; | |
| } | |
| static MFInt32 *NewMFInt32() | |
| { | |
| MFInt32 *tmp = (MFInt32 *)gf_malloc(sizeof(MFInt32)); | |
| memset(tmp, 0, sizeof(MFInt32)); | |
| return tmp; | |
| } | |
| static MFString *NewMFString() | |
| { | |
| MFString *tmp = (MFString *)gf_malloc(sizeof(MFString)); | |
| memset(tmp, 0, sizeof(MFString)); | |
| return tmp; | |
| } | |
| static MFVec3f *NewMFVec3f() | |
| { | |
| MFVec3f *tmp = (MFVec3f *)gf_malloc(sizeof(MFVec3f)); | |
| memset(tmp, 0, sizeof(MFVec3f)); | |
| return tmp; | |
| } | |
| static MFVec3d *NewMFVec3d() | |
| { | |
| MFVec3d *tmp = (MFVec3d *)gf_malloc(sizeof(MFVec3d)); | |
| memset(tmp, 0, sizeof(MFVec3d)); | |
| return tmp; | |
| } | |
| static MFVec2f *NewMFVec2f() | |
| { | |
| MFVec2f *tmp = (MFVec2f *)gf_malloc(sizeof(MFVec2f)); | |
| memset(tmp, 0, sizeof(MFVec2f)); | |
| return tmp; | |
| } | |
| static MFVec2d *NewMFVec2d() | |
| { | |
| MFVec2d *tmp = (MFVec2d *)gf_malloc(sizeof(MFVec2d)); | |
| memset(tmp, 0, sizeof(MFVec2d)); | |
| return tmp; | |
| } | |
| static MFColor *NewMFColor() | |
| { | |
| MFColor *tmp = (MFColor *)gf_malloc(sizeof(MFColor)); | |
| memset(tmp, 0, sizeof(MFColor)); | |
| return tmp; | |
| } | |
| static MFColorRGBA *NewMFColorRGBA() | |
| { | |
| MFColorRGBA *tmp = (MFColorRGBA *)gf_malloc(sizeof(MFColorRGBA)); | |
| memset(tmp, 0, sizeof(MFColorRGBA)); | |
| return tmp; | |
| } | |
| static MFRotation *NewMFRotation() | |
| { | |
| MFRotation *tmp = (MFRotation *)gf_malloc(sizeof(MFRotation)); | |
| memset(tmp, 0, sizeof(MFRotation)); | |
| return tmp; | |
| } | |
| static MFURL *NewMFURL() | |
| { | |
| MFURL *tmp = (MFURL *)gf_malloc(sizeof(MFURL)); | |
| memset(tmp, 0, sizeof(MFURL)); | |
| return tmp; | |
| } | |
| static MFScript *NewMFScript() | |
| { | |
| MFScript *tmp = (MFScript *)gf_malloc(sizeof(MFScript)); | |
| memset(tmp, 0, sizeof(MFScript)); | |
| return tmp; | |
| } | |
| static MFAttrRef *NewMFAttrRef() | |
| { | |
| MFAttrRef *tmp; | |
| GF_SAFEALLOC(tmp, MFAttrRef); | |
| return tmp; | |
| } | |
| GF_EXPORT | |
| void *gf_sg_vrml_field_pointer_new(u32 FieldType) | |
| { | |
| switch (FieldType) { | |
| case GF_SG_VRML_SFBOOL: | |
| return NewSFBool(); | |
| case GF_SG_VRML_SFFLOAT: | |
| return NewSFFloat(); | |
| case GF_SG_VRML_SFDOUBLE: | |
| return NewSFDouble(); | |
| case GF_SG_VRML_SFTIME: | |
| return NewSFTime(); | |
| case GF_SG_VRML_SFINT32: | |
| return NewSFInt32(); | |
| case GF_SG_VRML_SFSTRING: | |
| return NewSFString(); | |
| case GF_SG_VRML_SFVEC3F: | |
| return NewSFVec3f(); | |
| case GF_SG_VRML_SFVEC2F: | |
| return NewSFVec2f(); | |
| case GF_SG_VRML_SFVEC3D: | |
| return NewSFVec3d(); | |
| case GF_SG_VRML_SFVEC2D: | |
| return NewSFVec2d(); | |
| case GF_SG_VRML_SFCOLOR: | |
| return NewSFColor(); | |
| case GF_SG_VRML_SFCOLORRGBA: | |
| return NewSFColorRGBA(); | |
| case GF_SG_VRML_SFROTATION: | |
| return NewSFRotation(); | |
| case GF_SG_VRML_SFIMAGE: | |
| return NewSFImage(); | |
| case GF_SG_VRML_SFATTRREF: | |
| return NewSFAttrRef(); | |
| case GF_SG_VRML_MFBOOL: | |
| return NewMFBool(); | |
| case GF_SG_VRML_MFFLOAT: | |
| return NewMFFloat(); | |
| case GF_SG_VRML_MFTIME: | |
| return NewMFTime(); | |
| case GF_SG_VRML_MFINT32: | |
| return NewMFInt32(); | |
| case GF_SG_VRML_MFSTRING: | |
| return NewMFString(); | |
| case GF_SG_VRML_MFVEC3F: | |
| return NewMFVec3f(); | |
| case GF_SG_VRML_MFVEC2F: | |
| return NewMFVec2f(); | |
| case GF_SG_VRML_MFVEC3D: | |
| return NewMFVec3d(); | |
| case GF_SG_VRML_MFVEC2D: | |
| return NewMFVec2d(); | |
| case GF_SG_VRML_MFCOLOR: | |
| return NewMFColor(); | |
| case GF_SG_VRML_MFCOLORRGBA: | |
| return NewMFColorRGBA(); | |
| case GF_SG_VRML_MFROTATION: | |
| case GF_SG_VRML_MFVEC4F: | |
| return NewMFRotation(); | |
| case GF_SG_VRML_MFATTRREF: | |
| return NewMFAttrRef(); | |
| //used in commands | |
| case GF_SG_VRML_SFCOMMANDBUFFER: | |
| return NewSFCommandBuffer(); | |
| case GF_SG_VRML_SFURL: | |
| return NewSFURL(); | |
| case GF_SG_VRML_MFURL: | |
| return NewMFURL(); | |
| case GF_SG_VRML_SFSCRIPT: | |
| return NewSFScript(); | |
| case GF_SG_VRML_MFSCRIPT: | |
| return NewMFScript(); | |
| } | |
| return NULL; | |
| } | |
| void gf_sg_mfint32_del(MFInt32 par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mffloat_del(MFFloat par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfdouble_del(MFDouble par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfbool_del(MFBool par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfcolor_del(MFColor par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfcolorrgba_del(MFColorRGBA par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfrotation_del(MFRotation par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mftime_del(MFTime par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfvec2f_del(MFVec2f par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfvec2d_del(MFVec2d par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfvec3f_del(MFVec3f par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfvec3d_del(MFVec3d par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfvec4f_del(MFVec4f par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_mfattrref_del(MFAttrRef par) { | |
| gf_free(par.vals); | |
| } | |
| void gf_sg_sfimage_del(SFImage im) { | |
| gf_free(im.pixels); | |
| } | |
| void gf_sg_sfstring_del(SFString par) { | |
| if (par.buffer) gf_free(par.buffer); | |
| } | |
| void gf_sg_sfcommand_del(SFCommandBuffer cb) | |
| { | |
| u32 i; | |
| for (i=gf_list_count(cb.commandList); i>0; i--) { | |
| GF_Command *com = (GF_Command *)gf_list_get(cb.commandList, i-1); | |
| gf_sg_command_del(com); | |
| } | |
| gf_list_del(cb.commandList); | |
| if (cb.buffer) gf_free(cb.buffer); | |
| } | |
| GF_EXPORT | |
| void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType) | |
| { | |
| GF_Node *node; | |
| switch (FieldType) { | |
| case GF_SG_VRML_SFBOOL: | |
| case GF_SG_VRML_SFFLOAT: | |
| case GF_SG_VRML_SFDOUBLE: | |
| case GF_SG_VRML_SFTIME: | |
| case GF_SG_VRML_SFINT32: | |
| case GF_SG_VRML_SFVEC3F: | |
| case GF_SG_VRML_SFVEC3D: | |
| case GF_SG_VRML_SFVEC2F: | |
| case GF_SG_VRML_SFVEC2D: | |
| case GF_SG_VRML_SFCOLOR: | |
| case GF_SG_VRML_SFCOLORRGBA: | |
| case GF_SG_VRML_SFROTATION: | |
| case GF_SG_VRML_SFATTRREF: | |
| break; | |
| case GF_SG_VRML_SFSTRING: | |
| if ( ((SFString *)field)->buffer) gf_free(((SFString *)field)->buffer); | |
| break; | |
| case GF_SG_VRML_SFIMAGE: | |
| gf_sg_sfimage_del(* ((SFImage *)field)); | |
| break; | |
| case GF_SG_VRML_SFNODE: | |
| node = *(GF_Node **) field; | |
| if (node) gf_node_del(node); | |
| return; | |
| case GF_SG_VRML_SFCOMMANDBUFFER: | |
| gf_sg_sfcommand_del(*(SFCommandBuffer *)field); | |
| break; | |
| case GF_SG_VRML_MFBOOL: | |
| gf_sg_mfbool_del( * ((MFBool *) field)); | |
| break; | |
| case GF_SG_VRML_MFFLOAT: | |
| gf_sg_mffloat_del( * ((MFFloat *) field)); | |
| break; | |
| case GF_SG_VRML_MFDOUBLE: | |
| gf_sg_mfdouble_del( * ((MFDouble *) field)); | |
| break; | |
| case GF_SG_VRML_MFTIME: | |
| gf_sg_mftime_del( * ((MFTime *)field)); | |
| break; | |
| case GF_SG_VRML_MFINT32: | |
| gf_sg_mfint32_del( * ((MFInt32 *)field)); | |
| break; | |
| case GF_SG_VRML_MFSTRING: | |
| gf_sg_mfstring_del( *((MFString *)field)); | |
| break; | |
| case GF_SG_VRML_MFVEC3F: | |
| gf_sg_mfvec3f_del( * ((MFVec3f *)field)); | |
| break; | |
| case GF_SG_VRML_MFVEC2F: | |
| gf_sg_mfvec2f_del( * ((MFVec2f *)field)); | |
| break; | |
| case GF_SG_VRML_MFVEC3D: | |
| gf_sg_mfvec3d_del( * ((MFVec3d *)field)); | |
| break; | |
| case GF_SG_VRML_MFVEC2D: | |
| gf_sg_mfvec2d_del( * ((MFVec2d *)field)); | |
| break; | |
| case GF_SG_VRML_MFCOLOR: | |
| gf_sg_mfcolor_del( * ((MFColor *)field)); | |
| break; | |
| case GF_SG_VRML_MFCOLORRGBA: | |
| gf_sg_mfcolorrgba_del( * ((MFColorRGBA *)field)); | |
| break; | |
| case GF_SG_VRML_MFROTATION: | |
| case GF_SG_VRML_MFVEC4F: | |
| gf_sg_mfrotation_del( * ((MFRotation *)field)); | |
| break; | |
| case GF_SG_VRML_SFURL: | |
| gf_sg_sfurl_del( * ((SFURL *) field)); | |
| break; | |
| case GF_SG_VRML_MFURL: | |
| gf_sg_mfurl_del( * ((MFURL *) field)); | |
| break; | |
| case GF_SG_VRML_MFATTRREF: | |
| gf_sg_mfattrref_del( * ((MFAttrRef *) field)); | |
| break; | |
| //used only in proto since this field is created by default for regular nodes | |
| case GF_SG_VRML_MFNODE: | |
| gf_assert(0); | |
| return; | |
| case GF_SG_VRML_MFSCRIPT: | |
| gf_sg_mfscript_del( * ((MFScript *) field)); | |
| break; | |
| case GF_SG_VRML_SFSCRIPT: | |
| if (field && ((SFScript*)field)->script_text) | |
| gf_free(((SFScript*)field)->script_text); | |
| break; | |
| default: | |
| gf_assert(0); | |
| return; | |
| } | |
| //free pointer | |
| gf_free(field); | |
| } | |
| /********************************************************************* | |
| MF Fields manipulation (alloc, gf_realloc, GetAt) | |
| *********************************************************************/ | |
| GF_EXPORT | |
| const char *gf_sg_vrml_get_event_type_name(u32 EventType, Bool forX3D) | |
| { | |
| switch (EventType) { | |
| case GF_SG_EVENT_IN: | |
| return forX3D ? "inputOnly" : "eventIn"; | |
| case GF_SG_EVENT_FIELD: | |
| return forX3D ? "initializeOnly" : "field"; | |
| case GF_SG_EVENT_EXPOSED_FIELD: | |
| return forX3D ? "inputOutput" : "exposedField"; | |
| case GF_SG_EVENT_OUT: | |
| return forX3D ? "outputOnly" : "eventOut"; | |
| default: | |
| return "unknownEvent"; | |
| } | |
| } | |
| GF_EXPORT | |
| const char *gf_sg_vrml_get_field_type_name(u32 FieldType) | |
| { | |
| switch (FieldType) { | |
| case GF_SG_VRML_SFBOOL: | |
| return "SFBool"; | |
| case GF_SG_VRML_SFFLOAT: | |
| return "SFFloat"; | |
| case GF_SG_VRML_SFDOUBLE: | |
| return "SFDouble"; | |
| case GF_SG_VRML_SFTIME: | |
| return "SFTime"; | |
| case GF_SG_VRML_SFINT32: | |
| return "SFInt32"; | |
| case GF_SG_VRML_SFSTRING: | |
| return "SFString"; | |
| case GF_SG_VRML_SFVEC3F: | |
| return "SFVec3f"; | |
| case GF_SG_VRML_SFVEC2F: | |
| return "SFVec2f"; | |
| case GF_SG_VRML_SFVEC3D: | |
| return "SFVec3d"; | |
| case GF_SG_VRML_SFVEC2D: | |
| return "SFVec2d"; | |
| case GF_SG_VRML_SFCOLOR: | |
| return "SFColor"; | |
| case GF_SG_VRML_SFCOLORRGBA: | |
| return "SFColorRGBA"; | |
| case GF_SG_VRML_SFROTATION: | |
| return "SFRotation"; | |
| case GF_SG_VRML_SFIMAGE: | |
| return "SFImage"; | |
| case GF_SG_VRML_SFNODE: | |
| return "SFNode"; | |
| case GF_SG_VRML_SFVEC4F: | |
| return "SFVec4f"; | |
| case GF_SG_VRML_SFATTRREF: | |
| return "SFAttrRef"; | |
| case GF_SG_VRML_MFBOOL: | |
| return "MFBool"; | |
| case GF_SG_VRML_MFFLOAT: | |
| return "MFFloat"; | |
| case GF_SG_VRML_MFDOUBLE: | |
| return "MFDouble"; | |
| case GF_SG_VRML_MFTIME: | |
| return "MFTime"; | |
| case GF_SG_VRML_MFINT32: | |
| return "MFInt32"; | |
| case GF_SG_VRML_MFSTRING: | |
| return "MFString"; | |
| case GF_SG_VRML_MFVEC3F: | |
| return "MFVec3f"; | |
| case GF_SG_VRML_MFVEC2F: | |
| return "MFVec2f"; | |
| case GF_SG_VRML_MFVEC3D: | |
| return "MFVec3d"; | |
| case GF_SG_VRML_MFVEC2D: | |
| return "MFVec2d"; | |
| case GF_SG_VRML_MFCOLOR: | |
| return "MFColor"; | |
| case GF_SG_VRML_MFCOLORRGBA: | |
| return "MFColorRGBA"; | |
| case GF_SG_VRML_MFROTATION: | |
| return "MFRotation"; | |
| case GF_SG_VRML_MFIMAGE: | |
| return "MFImage"; | |
| case GF_SG_VRML_MFNODE: | |
| return "MFNode"; | |
| case GF_SG_VRML_MFVEC4F: | |
| return "MFVec4f"; | |
| case GF_SG_VRML_SFURL: | |
| return "SFURL"; | |
| case GF_SG_VRML_MFURL: | |
| return "MFURL"; | |
| case GF_SG_VRML_MFATTRREF: | |
| return "MFAttrRef"; | |
| case GF_SG_VRML_SFCOMMANDBUFFER: | |
| return "SFCommandBuffer"; | |
| case GF_SG_VRML_SFSCRIPT: | |
| return "SFScript"; | |
| case GF_SG_VRML_MFSCRIPT: | |
| return "MFScript"; | |
| default: | |
| return "UnknownType"; | |
| } | |
| } | |
| u32 gf_sg_field_type_by_name(char *fieldType) | |
| { | |
| if (!stricmp(fieldType, "SFBool")) return GF_SG_VRML_SFBOOL; | |
| else if (!stricmp(fieldType, "SFFloat")) return GF_SG_VRML_SFFLOAT; | |
| else if (!stricmp(fieldType, "SFDouble")) return GF_SG_VRML_SFDOUBLE; | |
| else if (!stricmp(fieldType, "SFTime")) return GF_SG_VRML_SFTIME; | |
| else if (!stricmp(fieldType, "SFInt32")) return GF_SG_VRML_SFINT32; | |
| else if (!stricmp(fieldType, "SFString")) return GF_SG_VRML_SFSTRING; | |
| else if (!stricmp(fieldType, "SFVec2f")) return GF_SG_VRML_SFVEC2F; | |
| else if (!stricmp(fieldType, "SFVec3f")) return GF_SG_VRML_SFVEC3F; | |
| else if (!stricmp(fieldType, "SFVec2d")) return GF_SG_VRML_SFVEC2D; | |
| else if (!stricmp(fieldType, "SFVec3d")) return GF_SG_VRML_SFVEC3D; | |
| else if (!stricmp(fieldType, "SFColor")) return GF_SG_VRML_SFCOLOR; | |
| else if (!stricmp(fieldType, "SFColorRGBA")) return GF_SG_VRML_SFCOLORRGBA; | |
| else if (!stricmp(fieldType, "SFRotation")) return GF_SG_VRML_SFROTATION; | |
| else if (!stricmp(fieldType, "SFImage")) return GF_SG_VRML_SFIMAGE; | |
| else if (!stricmp(fieldType, "SFAttrRef")) return GF_SG_VRML_SFATTRREF; | |
| else if (!stricmp(fieldType, "SFNode")) return GF_SG_VRML_SFNODE; | |
| else if (!stricmp(fieldType, "MFBool")) return GF_SG_VRML_MFBOOL; | |
| else if (!stricmp(fieldType, "MFFloat")) return GF_SG_VRML_MFFLOAT; | |
| else if (!stricmp(fieldType, "MFDouble")) return GF_SG_VRML_MFDOUBLE; | |
| else if (!stricmp(fieldType, "MFTime")) return GF_SG_VRML_MFTIME; | |
| else if (!stricmp(fieldType, "MFInt32")) return GF_SG_VRML_MFINT32; | |
| else if (!stricmp(fieldType, "MFString")) return GF_SG_VRML_MFSTRING; | |
| else if (!stricmp(fieldType, "MFVec2f")) return GF_SG_VRML_MFVEC2F; | |
| else if (!stricmp(fieldType, "MFVec3f")) return GF_SG_VRML_MFVEC3F; | |
| else if (!stricmp(fieldType, "MFVec2d")) return GF_SG_VRML_MFVEC2D; | |
| else if (!stricmp(fieldType, "MFVec3d")) return GF_SG_VRML_MFVEC3D; | |
| else if (!stricmp(fieldType, "MFColor")) return GF_SG_VRML_MFCOLOR; | |
| else if (!stricmp(fieldType, "MFColorRGBA")) return GF_SG_VRML_MFCOLORRGBA; | |
| else if (!stricmp(fieldType, "MFRotation")) return GF_SG_VRML_MFROTATION; | |
| else if (!stricmp(fieldType, "MFImage")) return GF_SG_VRML_MFIMAGE; | |
| else if (!stricmp(fieldType, "MFAttrRef")) return GF_SG_VRML_MFATTRREF; | |
| else if (!stricmp(fieldType, "MFNode")) return GF_SG_VRML_MFNODE; | |
| return GF_SG_VRML_UNKNOWN; | |
| } | |
| #endif | |
| void gf_sg_sfurl_del(SFURL url) { | |
| if (url.url) gf_free(url.url); | |
| } | |
| GF_EXPORT | |
| Bool gf_sg_vrml_is_sf_field(u32 FieldType) | |
| { | |
| //special case for AttrRef declared after first MF | |
| if (FieldType==GF_SG_VRML_SFATTRREF) return GF_TRUE; | |
| return (FieldType<GF_SG_VRML_FIRST_MF); | |
| } | |
| void gf_sg_mfstring_del(MFString par) | |
| { | |
| u32 i; | |
| for (i=0; i<par.count; i++) { | |
| if (par.vals[i]) gf_free(par.vals[i]); | |
| } | |
| gf_free(par.vals); | |
| } | |
| GF_EXPORT | |
| void gf_sg_mfurl_del(MFURL url) | |
| { | |
| u32 i; | |
| for (i=0; i<url.count; i++) { | |
| gf_sg_sfurl_del(url.vals[i]); | |
| } | |
| gf_free(url.vals); | |
| } | |
| void gf_sg_mfscript_del(MFScript sc) | |
| { | |
| u32 i; | |
| for (i=0; i<sc.count; i++) { | |
| if (sc.vals[i].script_text) gf_free(sc.vals[i].script_text); | |
| } | |
| gf_free(sc.vals); | |
| } | |
| void gf_sg_vrml_copy_mfurl(MFURL *dst, MFURL *src) | |
| { | |
| u32 i; | |
| gf_sg_vrml_mf_reset(dst, GF_SG_VRML_MFURL); | |
| dst->count = src->count; | |
| dst->vals = gf_malloc(sizeof(SFURL)*src->count); | |
| for (i=0; i<src->count; i++) { | |
| dst->vals[i].OD_ID = src->vals[i].OD_ID; | |
| dst->vals[i].url = src->vals[i].url ? gf_strdup(src->vals[i].url) : NULL; | |
| } | |
| } | |
| //return the size of fixed fields (eg no buffer in the field) | |
| u32 gf_sg_vrml_get_sf_size(u32 FieldType) | |
| { | |
| switch (FieldType) { | |
| case GF_SG_VRML_SFBOOL: | |
| case GF_SG_VRML_MFBOOL: | |
| return sizeof(SFBool); | |
| case GF_SG_VRML_SFFLOAT: | |
| case GF_SG_VRML_MFFLOAT: | |
| return sizeof(SFFloat); | |
| case GF_SG_VRML_SFTIME: | |
| case GF_SG_VRML_MFTIME: | |
| return sizeof(SFTime); | |
| case GF_SG_VRML_SFDOUBLE: | |
| case GF_SG_VRML_MFDOUBLE: | |
| return sizeof(SFDouble); | |
| case GF_SG_VRML_SFINT32: | |
| case GF_SG_VRML_MFINT32: | |
| return sizeof(SFInt32); | |
| case GF_SG_VRML_SFVEC3F: | |
| case GF_SG_VRML_MFVEC3F: | |
| return 3*sizeof(SFFloat); | |
| case GF_SG_VRML_SFVEC2F: | |
| case GF_SG_VRML_MFVEC2F: | |
| return 2*sizeof(SFFloat); | |
| case GF_SG_VRML_SFVEC3D: | |
| case GF_SG_VRML_MFVEC3D: | |
| return 3*sizeof(SFDouble); | |
| case GF_SG_VRML_SFCOLOR: | |
| case GF_SG_VRML_MFCOLOR: | |
| return 3*sizeof(SFFloat); | |
| case GF_SG_VRML_SFCOLORRGBA: | |
| case GF_SG_VRML_MFCOLORRGBA: | |
| return 4*sizeof(SFFloat); | |
| case GF_SG_VRML_SFROTATION: | |
| case GF_SG_VRML_MFROTATION: | |
| case GF_SG_VRML_MFVEC4F: | |
| return 4*sizeof(SFFloat); | |
| case GF_SG_VRML_SFATTRREF: | |
| case GF_SG_VRML_MFATTRREF: | |
| return sizeof(SFAttrRef); | |
| //check if that works!! | |
| case GF_SG_VRML_SFSTRING: | |
| case GF_SG_VRML_MFSTRING: | |
| //ptr to char | |
| return sizeof(SFString); | |
| case GF_SG_VRML_SFSCRIPT: | |
| case GF_SG_VRML_MFSCRIPT: | |
| return sizeof(SFScript); | |
| case GF_SG_VRML_SFURL: | |
| case GF_SG_VRML_MFURL: | |
| return sizeof(SFURL); | |
| default: | |
| return 0; | |
| } | |
| } | |
| GF_EXPORT | |
| u32 gf_sg_vrml_get_sf_type(u32 FieldType) | |
| { | |
| switch (FieldType) { | |
| case GF_SG_VRML_SFBOOL: | |
| case GF_SG_VRML_MFBOOL: | |
| return GF_SG_VRML_SFBOOL; | |
| case GF_SG_VRML_SFFLOAT: | |
| case GF_SG_VRML_MFFLOAT: | |
| return GF_SG_VRML_SFFLOAT; | |
| case GF_SG_VRML_SFDOUBLE: | |
| case GF_SG_VRML_MFDOUBLE: | |
| return GF_SG_VRML_SFDOUBLE; | |
| case GF_SG_VRML_SFTIME: | |
| case GF_SG_VRML_MFTIME: | |
| return GF_SG_VRML_SFTIME; | |
| case GF_SG_VRML_SFINT32: | |
| case GF_SG_VRML_MFINT32: | |
| return GF_SG_VRML_SFINT32; | |
| case GF_SG_VRML_SFVEC3F: | |
| case GF_SG_VRML_MFVEC3F: | |
| return GF_SG_VRML_SFVEC3F; | |
| case GF_SG_VRML_SFVEC4F: | |
| case GF_SG_VRML_MFVEC4F: | |
| return GF_SG_VRML_SFVEC4F; | |
| case GF_SG_VRML_SFVEC2F: | |
| case GF_SG_VRML_MFVEC2F: | |
| return GF_SG_VRML_SFVEC2F; | |
| case GF_SG_VRML_SFVEC3D: | |
| case GF_SG_VRML_MFVEC3D: | |
| return GF_SG_VRML_SFVEC3D; | |
| case GF_SG_VRML_SFVEC2D: | |
| case GF_SG_VRML_MFVEC2D: | |
| return GF_SG_VRML_SFVEC2D; | |
| case GF_SG_VRML_SFCOLOR: | |
| case GF_SG_VRML_MFCOLOR: | |
| return GF_SG_VRML_SFCOLOR; | |
| case GF_SG_VRML_SFCOLORRGBA: | |
| case GF_SG_VRML_MFCOLORRGBA: | |
| return GF_SG_VRML_SFCOLORRGBA; | |
| case GF_SG_VRML_SFROTATION: | |
| case GF_SG_VRML_MFROTATION: | |
| return GF_SG_VRML_SFROTATION; | |
| case GF_SG_VRML_SFATTRREF: | |
| case GF_SG_VRML_MFATTRREF: | |
| return GF_SG_VRML_SFATTRREF; | |
| //check if that works!! | |
| case GF_SG_VRML_SFSTRING: | |
| case GF_SG_VRML_MFSTRING: | |
| //ptr to char | |
| return GF_SG_VRML_SFSTRING; | |
| case GF_SG_VRML_SFSCRIPT: | |
| case GF_SG_VRML_MFSCRIPT: | |
| return GF_SG_VRML_SFSCRIPT; | |
| case GF_SG_VRML_SFURL: | |
| case GF_SG_VRML_MFURL: | |
| return GF_SG_VRML_SFURL; | |
| case GF_SG_VRML_SFNODE: | |
| case GF_SG_VRML_MFNODE: | |
| return GF_SG_VRML_SFNODE; | |
| default: | |
| return GF_SG_VRML_UNKNOWN; | |
| } | |
| } | |
| // | |
| // Insert (+alloc) an MFField with a specified position for insertion and sets the ptr to the | |
| // newly created slot | |
| // !! Doesnt work for MFNodes | |
| // InsertAt is the 0-based index for the new slot | |
| GF_EXPORT | |
| GF_Err gf_sg_vrml_mf_insert(void *mf, u32 FieldType, void **new_ptr, u32 InsertAt) | |
| { | |
| char *buffer; | |
| u32 FieldSize, i, k; | |
| GenMFField *mffield = (GenMFField *)mf; | |
| if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; | |
| if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM; | |
| FieldSize = gf_sg_vrml_get_sf_size(FieldType); | |
| //field we can't copy | |
| if (!FieldSize) return GF_BAD_PARAM; | |
| //first item ever | |
| if (!mffield->count || !mffield->array) { | |
| if (mffield->array) gf_free(mffield->array); | |
| mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize); | |
| memset(mffield->array, 0, sizeof(char)*FieldSize); | |
| mffield->count = 1; | |
| if (new_ptr) *new_ptr = mffield->array; | |
| return GF_OK; | |
| } | |
| //append at the end | |
| if (InsertAt >= mffield->count) { | |
| mffield->array = (char*)gf_realloc(mffield->array, sizeof(char)*(1+mffield->count)*FieldSize); | |
| memset(mffield->array + mffield->count * FieldSize, 0, FieldSize); | |
| if (new_ptr) *new_ptr = mffield->array + mffield->count * FieldSize; | |
| mffield->count += 1; | |
| return GF_OK; | |
| } | |
| //alloc 1+itemCount | |
| buffer = (char*)gf_malloc(sizeof(char)*(1+mffield->count)*FieldSize); | |
| //insert in the array | |
| k=0; | |
| for (i=0; i < mffield->count; i++) { | |
| if (InsertAt == i) { | |
| if (new_ptr) { | |
| *new_ptr = buffer + i*FieldSize; | |
| memset(*new_ptr, 0, sizeof(char)*FieldSize); | |
| } | |
| k = 1; | |
| } | |
| memcpy(buffer + (k+i) * FieldSize , mffield->array + i*FieldSize, FieldSize); | |
| } | |
| gf_free(mffield->array); | |
| mffield->array = buffer; | |
| mffield->count += 1; | |
| return GF_OK; | |
| } | |
| GF_EXPORT | |
| GF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType) | |
| { | |
| GenMFField *mffield = (GenMFField *)mf; | |
| if (!mffield || !mffield->array) return GF_OK; | |
| //field we can't copy | |
| if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; | |
| if (!gf_sg_vrml_get_sf_size(FieldType)) return GF_BAD_PARAM; | |
| switch (FieldType) { | |
| case GF_SG_VRML_MFSTRING: | |
| gf_sg_mfstring_del( * ((MFString *) mf)); | |
| break; | |
| case GF_SG_VRML_MFURL: | |
| gf_sg_mfurl_del( * ((MFURL *) mf)); | |
| break; | |
| case GF_SG_VRML_MFSCRIPT: | |
| gf_sg_mfscript_del( * ((MFScript *) mf)); | |
| break; | |
| default: | |
| if (mffield->array) gf_free(mffield->array); | |
| break; | |
| } | |
| mffield->array = NULL; | |
| mffield->count = 0; | |
| return GF_OK; | |
| } | |
| #ifndef GPAC_DISABLE_VRML | |
| #define MAX_MFFIELD_ALLOC 5000000 | |
| GF_EXPORT | |
| GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems) | |
| { | |
| u32 FieldSize; | |
| GenMFField *mffield = (GenMFField *)mf; | |
| if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; | |
| if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM; | |
| if (!mffield) return GF_NON_COMPLIANT_BITSTREAM; | |
| FieldSize = gf_sg_vrml_get_sf_size(FieldType); | |
| //field we can't copy | |
| if (!FieldSize) return GF_BAD_PARAM; | |
| if (NbItems>MAX_MFFIELD_ALLOC) return GF_IO_ERR; | |
| if (mffield->count==NbItems) return GF_OK; | |
| gf_sg_vrml_mf_reset(mf, FieldType); | |
| if (NbItems) { | |
| mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize*NbItems); | |
| memset(mffield->array, 0, sizeof(char)*FieldSize*NbItems); | |
| } | |
| mffield->count = NbItems; | |
| return GF_OK; | |
| } | |
| GF_EXPORT | |
| GF_Err gf_sg_vrml_mf_get_item(void *mf, u32 FieldType, void **new_ptr, u32 ItemPos) | |
| { | |
| u32 FieldSize; | |
| GenMFField *mffield = (GenMFField *)mf; | |
| *new_ptr = NULL; | |
| if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; | |
| if (FieldType == GF_SG_VRML_MFNODE) return GF_BAD_PARAM; | |
| if (!mffield) return GF_NON_COMPLIANT_BITSTREAM; | |
| FieldSize = gf_sg_vrml_get_sf_size(FieldType); | |
| //field we can't copy | |
| if (!FieldSize) return GF_BAD_PARAM; | |
| if (ItemPos >= mffield->count) return GF_BAD_PARAM; | |
| *new_ptr = mffield->array + ItemPos * FieldSize; | |
| return GF_OK; | |
| } | |
| GF_EXPORT | |
| GF_Err gf_sg_vrml_mf_append(void *mf, u32 FieldType, void **new_ptr) | |
| { | |
| GenMFField *mffield = (GenMFField *)mf; | |
| if (!mf) return GF_NON_COMPLIANT_BITSTREAM; | |
| return gf_sg_vrml_mf_insert(mf, FieldType, new_ptr, mffield->count+2); | |
| } | |
| //remove the specified item (0-based index) | |
| GF_EXPORT | |
| GF_Err gf_sg_vrml_mf_remove(void *mf, u32 FieldType, u32 RemoveFrom) | |
| { | |
| char *buffer; | |
| u32 FieldSize, i, k; | |
| GenMFField *mffield = (GenMFField *)mf; | |
| if (!mffield) return GF_NON_COMPLIANT_BITSTREAM; | |
| FieldSize = gf_sg_vrml_get_sf_size(FieldType); | |
| //field we can't copy | |
| if (!FieldSize) return GF_BAD_PARAM; | |
| if (!mffield->count || RemoveFrom >= mffield->count) return GF_BAD_PARAM; | |
| if (mffield->count == 1) { | |
| u32 sf_type = gf_sg_vrml_get_sf_type(FieldType); | |
| gf_sg_vrml_field_pointer_del(mffield->array, sf_type); | |
| mffield->array = NULL; | |
| mffield->count = 0; | |
| return GF_OK; | |
| } | |
| k=0; | |
| buffer = (char*)gf_malloc(sizeof(char)*(mffield->count-1)*FieldSize); | |
| for (i=0; i<mffield->count; i++) { | |
| if (RemoveFrom == i) { | |
| k = 1; | |
| } else { | |
| memcpy(buffer + (i-k)*FieldSize, mffield->array + i*FieldSize, FieldSize); | |
| } | |
| } | |
| gf_free(mffield->array); | |
| mffield->array = buffer; | |
| mffield->count -= 1; | |
| return GF_OK; | |
| } | |
| /*special cloning with type-casting from SF/MF strings to URL conversion since proto URL doesn't exist | |
| as a field type (it's just a stupid encoding trick) */ | |
| void VRML_FieldCopyCast(void *dest, u32 dst_field_type, void *orig, u32 ori_field_type) | |
| { | |
| SFURL *url; | |
| u32 size, i, sf_type_ori, sf_type_dst; | |
| void *dst_field, *orig_field; | |
| if (!dest || !orig) return; | |
| switch (dst_field_type) { | |
| case GF_SG_VRML_SFSTRING: | |
| if (ori_field_type == GF_SG_VRML_SFURL) { | |
| url = ((SFURL *)orig); | |
| if (url->OD_ID>0) { | |
| char tmp[50]; | |
| sprintf(tmp, "%d", url->OD_ID); | |
| if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); | |
| ((SFString*)dest)->buffer = gf_strdup(tmp); | |
| } else { | |
| if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); | |
| ((SFString*)dest)->buffer = url->url ? gf_strdup(url->url) : NULL; | |
| } | |
| } | |
| /*for SFString to MFString cast*/ | |
| else if (ori_field_type == GF_SG_VRML_SFSTRING) { | |
| if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); | |
| ((SFString*)dest)->buffer = ((SFString*)orig)->buffer ? gf_strdup(((SFString*)orig)->buffer) : NULL; | |
| } | |
| return; | |
| case GF_SG_VRML_SFURL: | |
| if (ori_field_type != GF_SG_VRML_SFSTRING) return; | |
| url = ((SFURL *)dest); | |
| url->OD_ID = 0; | |
| if (url->url) gf_free(url->url); | |
| if ( ((SFString*)orig)->buffer) | |
| url->url = gf_strdup(((SFString*)orig)->buffer); | |
| else | |
| url->url = NULL; | |
| return; | |
| case GF_SG_VRML_MFSTRING: | |
| case GF_SG_VRML_MFURL: | |
| break; | |
| default: | |
| return; | |
| } | |
| sf_type_dst = gf_sg_vrml_get_sf_type(dst_field_type); | |
| if (gf_sg_vrml_is_sf_field(ori_field_type)) { | |
| size = 1; | |
| gf_sg_vrml_mf_alloc(dest, dst_field_type, size); | |
| gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, 0); | |
| VRML_FieldCopyCast(dst_field, sf_type_dst, orig, ori_field_type); | |
| return; | |
| } | |
| size = ((GenMFField *)orig)->count; | |
| if (size != ((GenMFField *)dest)->count) gf_sg_vrml_mf_alloc(dest, dst_field_type, size); | |
| sf_type_ori = gf_sg_vrml_get_sf_type(ori_field_type); | |
| //duplicate all items | |
| for (i=0; i<size; i++) { | |
| gf_sg_vrml_mf_get_item(dest, dst_field_type, &dst_field, i); | |
| gf_sg_vrml_mf_get_item(orig, ori_field_type, &orig_field, i); | |
| VRML_FieldCopyCast(dst_field, sf_type_dst, orig_field, sf_type_ori); | |
| } | |
| return; | |
| } | |
| GF_EXPORT | |
| void gf_sg_vrml_field_clone(void *dest, void *orig, u32 field_type, GF_SceneGraph *inScene) | |
| { | |
| u32 size, i, sf_type; | |
| void *dst_field, *orig_field; | |
| if (!dest || !orig) return; | |
| switch (field_type) { | |
| case GF_SG_VRML_SFBOOL: | |
| memcpy(dest, orig, sizeof(SFBool)); | |
| break; | |
| case GF_SG_VRML_SFCOLOR: | |
| memcpy(dest, orig, sizeof(SFColor)); | |
| break; | |
| case GF_SG_VRML_SFFLOAT: | |
| memcpy(dest, orig, sizeof(SFFloat)); | |
| break; | |
| case GF_SG_VRML_SFINT32: | |
| memcpy(dest, orig, sizeof(SFInt32)); | |
| break; | |
| case GF_SG_VRML_SFROTATION: | |
| memcpy(dest, orig, sizeof(SFRotation)); | |
| break; | |
| case GF_SG_VRML_SFTIME: | |
| memcpy(dest, orig, sizeof(SFTime)); | |
| break; | |
| case GF_SG_VRML_SFVEC2F: | |
| memcpy(dest, orig, sizeof(SFVec2f)); | |
| break; | |
| case GF_SG_VRML_SFVEC3F: | |
| memcpy(dest, orig, sizeof(SFVec3f)); | |
| break; | |
| case GF_SG_VRML_SFATTRREF: | |
| memcpy(dest, orig, sizeof(SFAttrRef)); | |
| break; | |
| case GF_SG_VRML_SFSTRING: | |
| if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); | |
| if ( ((SFString*)orig)->buffer ) | |
| ((SFString*)dest)->buffer = gf_strdup(((SFString*)orig)->buffer); | |
| else | |
| ((SFString*)dest)->buffer = NULL; | |
| break; | |
| case GF_SG_VRML_SFURL: | |
| if ( ((SFURL *)dest)->url ) gf_free( ((SFURL *)dest)->url ); | |
| ((SFURL *)dest)->OD_ID = ((SFURL *)orig)->OD_ID; | |
| if (((SFURL *)orig)->url) | |
| ((SFURL *)dest)->url = gf_strdup(((SFURL *)orig)->url); | |
| else | |
| ((SFURL *)dest)->url = NULL; | |
| break; | |
| case GF_SG_VRML_SFIMAGE: | |
| if (((SFImage *)dest)->pixels) gf_free(((SFImage *)dest)->pixels); | |
| ((SFImage *)dest)->width = ((SFImage *)orig)->width; | |
| ((SFImage *)dest)->height = ((SFImage *)orig)->height; | |
| ((SFImage *)dest)->numComponents = ((SFImage *)orig)->numComponents; | |
| size = ((SFImage *)dest)->width * ((SFImage *)dest)->height * ((SFImage *)dest)->numComponents; | |
| if (((SFImage *)orig)->pixels && size > 0) { | |
| ((SFImage *)dest)->pixels = (u8*)gf_malloc(sizeof(char)*size); | |
| memcpy(((SFImage *)dest)->pixels, ((SFImage *)orig)->pixels, sizeof(char)*size); | |
| } else { | |
| ((SFImage *)dest)->pixels = NULL; | |
| } | |
| break; | |
| case GF_SG_VRML_SFCOMMANDBUFFER: | |
| { | |
| SFCommandBuffer *cb_dst = (SFCommandBuffer *)dest; | |
| SFCommandBuffer *cb_src = (SFCommandBuffer *)orig; | |
| cb_dst->bufferSize = cb_src->bufferSize; | |
| if (cb_dst->bufferSize && !gf_list_count(cb_src->commandList) ) { | |
| cb_dst->buffer = (u8*)gf_realloc(cb_dst->buffer, sizeof(char)*cb_dst->bufferSize); | |
| memcpy(cb_dst->buffer, cb_src->buffer, sizeof(char)*cb_src->bufferSize); | |
| } else { | |
| u32 j, c2; | |
| if (cb_dst->buffer) gf_free(cb_dst->buffer); | |
| cb_dst->buffer = NULL; | |
| /*clone command list*/ | |
| c2 = gf_list_count(cb_src->commandList); | |
| for (j=0; j<c2; j++) { | |
| GF_Command *sub_com = (GF_Command *)gf_list_get(cb_src->commandList, j); | |
| GF_Command *new_com = gf_sg_vrml_command_clone(sub_com, inScene, 0); | |
| gf_list_add(cb_dst->commandList, new_com); | |
| } | |
| } | |
| } | |
| break; | |
| /*simply copy text string*/ | |
| case GF_SG_VRML_SFSCRIPT: | |
| if (((SFScript*)dest)->script_text) gf_free(((SFScript*)dest)->script_text); | |
| ((SFScript*)dest)->script_text = NULL; | |
| if ( ((SFScript*)orig)->script_text) | |
| ((SFScript *)dest)->script_text = (char *)gf_strdup( (char*) ((SFScript*)orig)->script_text ); | |
| break; | |
| //simple MFFields, do a memcpy | |
| case GF_SG_VRML_MFBOOL: | |
| case GF_SG_VRML_MFFLOAT: | |
| case GF_SG_VRML_MFTIME: | |
| case GF_SG_VRML_MFINT32: | |
| case GF_SG_VRML_MFVEC3F: | |
| case GF_SG_VRML_MFVEC2F: | |
| case GF_SG_VRML_MFCOLOR: | |
| case GF_SG_VRML_MFROTATION: | |
| case GF_SG_VRML_MFATTRREF: | |
| size = gf_sg_vrml_get_sf_size(field_type) * ((GenMFField *)orig)->count; | |
| if (((GenMFField *)orig)->count != ((GenMFField *)dest)->count) { | |
| ((GenMFField *)dest)->array = gf_realloc(((GenMFField *)dest)->array, size); | |
| ((GenMFField *)dest)->count = ((GenMFField *)orig)->count; | |
| } | |
| if (size) | |
| memcpy(((GenMFField *)dest)->array, ((GenMFField *)orig)->array, size); | |
| break; | |
| //complex MFFields | |
| case GF_SG_VRML_MFSTRING: | |
| case GF_SG_VRML_MFIMAGE: | |
| case GF_SG_VRML_MFURL: | |
| case GF_SG_VRML_MFSCRIPT: | |
| size = ((GenMFField *)orig)->count; | |
| gf_sg_vrml_mf_reset(dest, field_type); | |
| gf_sg_vrml_mf_alloc(dest, field_type, size); | |
| sf_type = gf_sg_vrml_get_sf_type(field_type); | |
| //duplicate all items | |
| for (i=0; i<size; i++) { | |
| gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i); | |
| gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i); | |
| gf_sg_vrml_field_copy(dst_field, orig_field, sf_type); | |
| } | |
| break; | |
| } | |
| } | |
| GF_EXPORT | |
| void gf_sg_vrml_field_copy(void *dest, void *orig, u32 field_type) | |
| { | |
| gf_sg_vrml_field_clone(dest, orig, field_type, NULL); | |
| } | |
| GF_EXPORT | |
| Bool gf_sg_vrml_field_equal(void *dest, void *orig, u32 field_type) | |
| { | |
| u32 size, i, sf_type; | |
| void *dst_field, *orig_field; | |
| Bool changed = 0; | |
| if (!dest || !orig) return 0; | |
| switch (field_type) { | |
| case GF_SG_VRML_SFBOOL: | |
| changed = memcmp(dest, orig, sizeof(SFBool)); | |
| break; | |
| case GF_SG_VRML_SFCOLOR: | |
| if (((SFColor *)dest)->red != ((SFColor *)orig)->red) changed = 1; | |
| else if (((SFColor *)dest)->green != ((SFColor *)orig)->green) changed = 1; | |
| else if (((SFColor *)dest)->blue != ((SFColor *)orig)->blue) changed = 1; | |
| break; | |
| case GF_SG_VRML_SFFLOAT: | |
| if ( (*(SFFloat *)dest) != (*(SFFloat *)orig) ) changed = 1; | |
| break; | |
| case GF_SG_VRML_SFINT32: | |
| changed = memcmp(dest, orig, sizeof(SFInt32)); | |
| break; | |
| case GF_SG_VRML_SFROTATION: | |
| if (((SFRotation *)dest)->x != ((SFRotation *)orig)->x) changed = 1; | |
| else if (((SFRotation *)dest)->y != ((SFRotation *)orig)->y) changed = 1; | |
| else if (((SFRotation *)dest)->z != ((SFRotation *)orig)->z) changed = 1; | |
| else if (((SFRotation *)dest)->q != ((SFRotation *)orig)->q) changed = 1; | |
| break; | |
| case GF_SG_VRML_SFTIME: | |
| if ( (*(SFTime *)dest) != (*(SFTime*)orig) ) changed = 1; | |
| break; | |
| case GF_SG_VRML_SFVEC2F: | |
| if (((SFVec2f *)dest)->x != ((SFVec2f *)orig)->x) changed = 1; | |
| else if (((SFVec2f *)dest)->y != ((SFVec2f *)orig)->y) changed = 1; | |
| break; | |
| case GF_SG_VRML_SFVEC3F: | |
| if (((SFVec3f *)dest)->x != ((SFVec3f *)orig)->x) changed = 1; | |
| else if (((SFVec3f *)dest)->y != ((SFVec3f *)orig)->y) changed = 1; | |
| else if (((SFVec3f *)dest)->z != ((SFVec3f *)orig)->z) changed = 1; | |
| break; | |
| case GF_SG_VRML_SFSTRING: | |
| if ( ((SFString*)dest)->buffer && ((SFString*)orig)->buffer) { | |
| changed = strcmp(((SFString*)dest)->buffer, ((SFString*)orig)->buffer); | |
| } else { | |
| changed = ( !((SFString*)dest)->buffer && !((SFString*)orig)->buffer) ? 0 : 1; | |
| } | |
| break; | |
| case GF_SG_VRML_SFURL: | |
| if (((SFURL *)dest)->OD_ID > 0 || ((SFURL *)orig)->OD_ID > 0) { | |
| if ( ((SFURL *)orig)->OD_ID != ((SFURL *)dest)->OD_ID) changed = 1; | |
| } else { | |
| if ( ((SFURL *)orig)->url && ! ((SFURL *)dest)->url) changed = 1; | |
| else if ( ! ((SFURL *)orig)->url && ((SFURL *)dest)->url) changed = 1; | |
| else if ( ((SFURL *)orig)->url && ((SFURL *)dest)->url && strcmp( ((SFURL *)orig)->url , ((SFURL *)dest)->url) ) changed = 1; | |
| } | |
| break; | |
| case GF_SG_VRML_SFIMAGE: | |
| case GF_SG_VRML_SFATTRREF: | |
| case GF_SG_VRML_SFSCRIPT: | |
| case GF_SG_VRML_SFCOMMANDBUFFER: | |
| changed = 1; | |
| break; | |
| //MFFields | |
| case GF_SG_VRML_MFATTRREF: | |
| changed = 1; | |
| break; | |
| case GF_SG_VRML_MFBOOL: | |
| case GF_SG_VRML_MFFLOAT: | |
| case GF_SG_VRML_MFTIME: | |
| case GF_SG_VRML_MFINT32: | |
| case GF_SG_VRML_MFSTRING: | |
| case GF_SG_VRML_MFVEC3F: | |
| case GF_SG_VRML_MFVEC2F: | |
| case GF_SG_VRML_MFCOLOR: | |
| case GF_SG_VRML_MFROTATION: | |
| case GF_SG_VRML_MFIMAGE: | |
| case GF_SG_VRML_MFURL: | |
| case GF_SG_VRML_MFSCRIPT: | |
| if ( ((GenMFField *)orig)->count != ((GenMFField *)dest)->count) changed = 1; | |
| else { | |
| size = ((GenMFField *)orig)->count; | |
| sf_type = gf_sg_vrml_get_sf_type(field_type); | |
| for (i=0; i<size; i++) { | |
| gf_sg_vrml_mf_get_item(dest, field_type, &dst_field, i); | |
| gf_sg_vrml_mf_get_item(orig, field_type, &orig_field, i); | |
| if (! gf_sg_vrml_field_equal(dst_field, orig_field, sf_type) ) { | |
| changed = 1; | |
| break; | |
| } | |
| } | |
| } | |
| break; | |
| } | |
| return changed ? 0 : 1; | |
| } | |
| GF_EXPORT | |
| SFColorRGBA gf_sg_sfcolor_to_rgba(SFColor val) | |
| { | |
| SFColorRGBA res; | |
| res.alpha = FIX_ONE; | |
| res.red = val.red; | |
| res.green = val.green; | |
| res.blue = val.blue; | |
| return res; | |
| } | |
| GF_EXPORT | |
| u32 gf_node_get_num_fields_in_mode(GF_Node *Node, u8 IndexMode) | |
| { | |
| gf_assert(Node); | |
| if (Node->sgprivate->tag == TAG_ProtoNode) return gf_sg_proto_get_num_fields(Node, IndexMode); | |
| else if (Node->sgprivate->tag == TAG_MPEG4_Script) | |
| return gf_sg_script_get_num_fields(Node, IndexMode); | |
| #ifndef GPAC_DISABLE_X3D | |
| else if (Node->sgprivate->tag == TAG_X3D_Script) | |
| return gf_sg_script_get_num_fields(Node, IndexMode); | |
| #endif | |
| else if (Node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) return gf_sg_mpeg4_node_get_field_count(Node, IndexMode); | |
| #ifndef GPAC_DISABLE_X3D | |
| else if (Node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_sg_x3d_node_get_field_count(Node); | |
| #endif | |
| else return 0; | |
| } | |
| /*all our internally handled nodes*/ | |
| Bool InitColorInterpolator(M_ColorInterpolator *node); | |
| Bool InitCoordinateInterpolator2D(M_CoordinateInterpolator2D *node); | |
| Bool InitCoordinateInterpolator(M_CoordinateInterpolator *n); | |
| Bool InitNormalInterpolator(M_NormalInterpolator *n); | |
| Bool InitPositionInterpolator2D(M_PositionInterpolator2D *node); | |
| Bool InitPositionInterpolator(M_PositionInterpolator *node); | |
| Bool InitScalarInterpolator(M_ScalarInterpolator *node); | |
| Bool InitOrientationInterpolator(M_OrientationInterpolator *node); | |
| Bool InitValuator(M_Valuator *node); | |
| Bool InitCoordinateInterpolator4D(M_CoordinateInterpolator4D *node); | |
| Bool InitPositionInterpolator4D(M_PositionInterpolator4D *node); | |
| void PA_Init(GF_Node *n); | |
| void PA_Modified(GF_Node *n, GF_FieldInfo *field); | |
| void PA2D_Init(GF_Node *n); | |
| void PA2D_Modified(GF_Node *n, GF_FieldInfo *field); | |
| void SA_Init(GF_Node *n); | |
| void SA_Modified(GF_Node *n, GF_FieldInfo *field); | |
| /*X3D tools*/ | |
| void InitBooleanFilter(GF_Node *n); | |
| void InitBooleanSequencer(GF_Node *n); | |
| void InitBooleanToggle(GF_Node *n); | |
| void InitBooleanTrigger(GF_Node *n); | |
| void InitIntegerSequencer(GF_Node *n); | |
| void InitIntegerTrigger(GF_Node *n); | |
| void InitTimeTrigger(GF_Node *n); | |
| Bool gf_sg_vrml_node_init(GF_Node *node) | |
| { | |
| switch (node->sgprivate->tag) { | |
| case TAG_MPEG4_ColorInterpolator: | |
| #ifndef GPAC_DISABLE_X3D | |
| case TAG_X3D_ColorInterpolator: | |
| #endif | |
| return InitColorInterpolator((M_ColorInterpolator *)node); | |
| case TAG_MPEG4_CoordinateInterpolator: | |
| #ifndef GPAC_DISABLE_X3D | |
| case TAG_X3D_CoordinateInterpolator: | |
| #endif | |
| return InitCoordinateInterpolator((M_CoordinateInterpolator *)node); | |
| case TAG_MPEG4_CoordinateInterpolator2D: | |
| return InitCoordinateInterpolator2D((M_CoordinateInterpolator2D *)node); | |
| case TAG_MPEG4_NormalInterpolator: | |
| #ifndef GPAC_DISABLE_X3D | |
| case TAG_X3D_NormalInterpolator: | |
| #endif | |
| return InitNormalInterpolator((M_NormalInterpolator*)node); | |
| case TAG_MPEG4_OrientationInterpolator: | |
| #ifndef GPAC_DISABLE_X3D | |
| case TAG_X3D_OrientationInterpolator: | |
| #endif | |
| return InitOrientationInterpolator((M_OrientationInterpolator*)node); | |
| case TAG_MPEG4_PositionInterpolator: | |
| #ifndef GPAC_DISABLE_X3D | |
| case TAG_X3D_PositionInterpolator: | |
| #endif | |
| return InitPositionInterpolator((M_PositionInterpolator *)node); | |
| case TAG_MPEG4_PositionInterpolator2D: | |
| #ifndef GPAC_DISABLE_X3D | |
| case TAG_X3D_PositionInterpolator2D: | |
| #endif | |
| return InitPositionInterpolator2D((M_PositionInterpolator2D *)node); | |
| case TAG_MPEG4_ScalarInterpolator: | |
| #ifndef GPAC_DISABLE_X3D | |
| case TAG_X3D_ScalarInterpolator: | |
| #endif | |
| return InitScalarInterpolator((M_ScalarInterpolator *)node); | |
| case TAG_MPEG4_Valuator: | |
| return InitValuator((M_Valuator *)node); | |
| case TAG_MPEG4_PositionAnimator: | |
| PA_Init(node); | |
| return 1; | |
| case TAG_MPEG4_PositionAnimator2D: | |
| PA2D_Init(node); | |
| return 1; | |
| case TAG_MPEG4_ScalarAnimator: | |
| SA_Init(node); | |
| return 1; | |
| case TAG_MPEG4_PositionInterpolator4D: | |
| return InitPositionInterpolator4D((M_PositionInterpolator4D *)node); | |
| case TAG_MPEG4_CoordinateInterpolator4D: | |
| return InitCoordinateInterpolator4D((M_CoordinateInterpolator4D *)node); | |
| case TAG_MPEG4_Script: | |
| #ifndef GPAC_DISABLE_X3D | |
| case TAG_X3D_Script: | |
| #endif | |
| return 1; | |
| #ifndef GPAC_DISABLE_X3D | |
| case TAG_X3D_BooleanFilter: | |
| InitBooleanFilter(node); | |
| return 1; | |
| case TAG_X3D_BooleanSequencer: | |
| InitBooleanSequencer(node); | |
| return 1; | |
| case TAG_X3D_BooleanToggle: | |
| InitBooleanToggle(node); | |
| return 1; | |
| case TAG_X3D_BooleanTrigger: | |
| InitBooleanTrigger(node); | |
| return 1; | |
| case TAG_X3D_IntegerSequencer: | |
| InitIntegerSequencer(node); | |
| return 1; | |
| case TAG_X3D_IntegerTrigger: | |
| InitIntegerTrigger(node); | |
| return 1; | |
| case TAG_X3D_TimeTrigger: | |
| InitTimeTrigger(node); | |
| return 1; | |
| #endif | |
| } | |
| return 0; | |
| } | |
| Bool gf_sg_vrml_node_changed(GF_Node *node, GF_FieldInfo *field) | |
| { | |
| switch (node->sgprivate->tag) { | |
| case TAG_ProtoNode: | |
| /*hardcoded protos need modification notifs*/ | |
| if (node->sgprivate->UserCallback) return 0; | |
| case TAG_MPEG4_ColorInterpolator: | |
| case TAG_MPEG4_CoordinateInterpolator: | |
| case TAG_MPEG4_CoordinateInterpolator2D: | |
| case TAG_MPEG4_NormalInterpolator: | |
| case TAG_MPEG4_OrientationInterpolator: | |
| case TAG_MPEG4_PositionInterpolator: | |
| case TAG_MPEG4_PositionInterpolator2D: | |
| case TAG_MPEG4_ScalarInterpolator: | |
| case TAG_MPEG4_Valuator: | |
| case TAG_MPEG4_PositionInterpolator4D: | |
| case TAG_MPEG4_CoordinateInterpolator4D: | |
| case TAG_MPEG4_Script: | |
| #ifndef GPAC_DISABLE_X3D | |
| case TAG_X3D_ColorInterpolator: | |
| case TAG_X3D_CoordinateInterpolator: | |
| case TAG_X3D_NormalInterpolator: | |
| case TAG_X3D_OrientationInterpolator: | |
| case TAG_X3D_PositionInterpolator: | |
| case TAG_X3D_ScalarInterpolator: | |
| case TAG_X3D_Script: | |
| case TAG_X3D_BooleanFilter: | |
| case TAG_X3D_BooleanSequencer: | |
| case TAG_X3D_BooleanToggle: | |
| case TAG_X3D_BooleanTrigger: | |
| case TAG_X3D_IntegerSequencer: | |
| case TAG_X3D_IntegerTrigger: | |
| case TAG_X3D_TimeTrigger: | |
| #endif | |
| return 1; | |
| case TAG_MPEG4_PositionAnimator: | |
| PA_Modified(node, field); | |
| return 1; | |
| case TAG_MPEG4_PositionAnimator2D: | |
| PA2D_Modified(node, field); | |
| return 1; | |
| case TAG_MPEG4_ScalarAnimator: | |
| SA_Modified(node, field); | |
| return 1; | |
| } | |
| return 0; | |
| } | |
| #if 0 //unused | |
| char *gf_node_vrml_dump_attribute(GF_Node *n, GF_FieldInfo *info) | |
| { | |
| char szVal[1024]; | |
| switch (info->fieldType) { | |
| case GF_SG_VRML_SFBOOL: | |
| gf_strcpy(szVal, *((SFBool*)info->far_ptr) ? "TRUE" : "FALSE"); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFINT32: | |
| sprintf(szVal, "%d", *((SFInt32*)info->far_ptr) ); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFFLOAT: | |
| sprintf(szVal, "%g", FIX2FLT( *((SFFloat*)info->far_ptr) ) ); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFDOUBLE: | |
| sprintf(szVal, "%g", *((SFDouble *)info->far_ptr) ); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFTIME: | |
| sprintf(szVal, "%g", *((SFTime *)info->far_ptr) ); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFVEC2F: | |
| sprintf(szVal, "%g %g", FIX2FLT(((SFVec2f *)info->far_ptr)->x), FIX2FLT( ((SFVec2f *)info->far_ptr)->y) ); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFVEC2D: | |
| sprintf(szVal, "%g %g", ((SFVec2d *)info->far_ptr)->x, ((SFVec2d *)info->far_ptr)->y); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFVEC3F: | |
| sprintf(szVal, "%g %g %g", FIX2FLT(((SFVec3f *)info->far_ptr)->x), FIX2FLT( ((SFVec3f *)info->far_ptr)->y) , FIX2FLT( ((SFVec3f *)info->far_ptr)->z) ); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFVEC3D: | |
| sprintf(szVal, "%g %g %g", ((SFVec3d *)info->far_ptr)->x, ((SFVec3d *)info->far_ptr)->y, ((SFVec3d *)info->far_ptr)->z); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFCOLOR: | |
| sprintf(szVal, "%g %g %g", FIX2FLT(((SFColor *)info->far_ptr)->red), FIX2FLT( ((SFColor *)info->far_ptr)->green) , FIX2FLT( ((SFColor *)info->far_ptr)->blue) ); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFCOLORRGBA: | |
| sprintf(szVal, "%g %g %g %g", FIX2FLT(((SFColorRGBA *)info->far_ptr)->red), FIX2FLT( ((SFColorRGBA*)info->far_ptr)->green) , FIX2FLT( ((SFColorRGBA*)info->far_ptr)->blue) , FIX2FLT( ((SFColorRGBA*)info->far_ptr)->alpha) ); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFROTATION: | |
| sprintf(szVal, "%g %g %g %g", FIX2FLT(((SFRotation *)info->far_ptr)->x), FIX2FLT( ((SFRotation *)info->far_ptr)->y) , FIX2FLT( ((SFRotation *)info->far_ptr)->z), FIX2FLT( ((SFRotation *)info->far_ptr)->q) ); | |
| return gf_strdup(szVal); | |
| case GF_SG_VRML_SFSTRING: | |
| if (!((SFString*)info->far_ptr)->buffer ) return gf_strdup(""); | |
| return gf_strdup( ((SFString*)info->far_ptr)->buffer ); | |
| case GF_SG_VRML_SFURL: | |
| if (((SFURL *)info->far_ptr)->url) { | |
| return gf_strdup( ((SFURL *)info->far_ptr)->url ); | |
| } else { | |
| sprintf(szVal, "od://%d", ((SFURL *)info->far_ptr)->OD_ID); | |
| return gf_strdup(szVal); | |
| } | |
| case GF_SG_VRML_SFIMAGE: | |
| { | |
| u32 i, count; | |
| char *buf; | |
| SFImage *img = (SFImage *)info->far_ptr; | |
| count = img->width * img->height * img->numComponents; | |
| i = (3/*' 0x'*/ + 2/*%02X*/*img->numComponents)*count + 20; | |
| buf = gf_malloc(sizeof(char) * i); | |
| sprintf(buf , "%d %d %d", img->width, img->height, img->numComponents); | |
| for (i=0; i<count; ) { | |
| switch (img->numComponents) { | |
| case 1: | |
| sprintf(szVal, " 0x%02X", img->pixels[i]); | |
| i++; | |
| break; | |
| case 2: | |
| sprintf(szVal, " 0x%02X%02X", img->pixels[i], img->pixels[i+1]); | |
| i+=2; | |
| break; | |
| case 3: | |
| sprintf(szVal, " 0x%02X%02X%02X", img->pixels[i], img->pixels[i+1], img->pixels[i+2]); | |
| i+=3; | |
| break; | |
| case 4: | |
| sprintf(szVal, " 0x%02X%02X%02X%02X", img->pixels[i], img->pixels[i+1], img->pixels[i+2], img->pixels[i+3]); | |
| i+=4; | |
| break; | |
| } | |
| gf_strcat(buf, szVal); | |
| } | |
| return buf; | |
| } | |
| default: | |
| break; | |
| } | |
| /*todo - dump MFFields*/ | |
| return NULL; | |
| } | |
| #endif | |
| #endif /*GPAC_DISABLE_VRML*/ | |
| Bool gf_node_in_table(GF_Node *node, u32 NDTType) | |
| { | |
| #ifndef GPAC_DISABLE_VRML | |
| u32 tag = node ? node->sgprivate->tag : 0; | |
| if (tag==TAG_ProtoNode) { | |
| tag = gf_sg_proto_get_root_tag(((GF_ProtoInstance *)node)->proto_interface); | |
| if (tag==TAG_UndefinedNode) return 1; | |
| } | |
| return gf_node_in_table_by_tag(tag, NDTType); | |
| #else | |
| return 1; | |
| #endif | |
| } |