📄 loader_xmt.c
字号:
else return GF_SG_EVENT_UNKNOWN;}static u32 xmt_get_et_by_name(const char *_name){ char name[1024]; xmt_strip_name((char *)_name, name); if (!strcmp(name, "eventIn") || !strcmp(name, "inputOnly") ) return GF_SG_EVENT_IN; else if (!strcmp(name, "eventOut") || !strcmp(name, "outputOnly")) return GF_SG_EVENT_OUT; else if (!strcmp(name, "field") || !strcmp(name, "initializeOnly") ) return GF_SG_EVENT_FIELD; else if (!strcmp(name, "exposedField") || !strcmp(name, "inputOutput")) return GF_SG_EVENT_EXPOSED_FIELD; else return GF_SG_EVENT_UNKNOWN;}static void xmt_parse_script_field(GF_XMTParser *parser, GF_Node *node, const GF_XMLAttribute *attributes, u32 nb_attributes){ GF_ScriptField *scfield; GF_FieldInfo field; char *val = NULL; u32 fieldType, eventType, i; char *fieldName = NULL; fieldType = eventType = 0; val = NULL; for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i]; if (!att->value || !strlen(att->value)) continue; if (!strcmp(att->name, "name")) fieldName = att->value; else if (!strcmp(att->name, "type")) fieldType = xmt_get_ft_by_name(att->value); else if (!strcmp(att->name, "vrml97Hint") || !strcmp(att->name, "accessType")) eventType = xmt_get_script_et_by_name(att->value); else if (strstr(att->name, "value") || strstr(att->name, "Value")) val = att->value; } scfield = gf_sg_script_field_new(node, eventType, fieldType, fieldName); if (!scfield) { xmt_report(parser, GF_BAD_PARAM, "Cannot create script field - please check syntax"); return; } if (val) { gf_node_get_field_by_name(node, fieldName, &field); if (gf_sg_vrml_is_sf_field(fieldType)) { xmt_parse_sf_field(parser, &field, node, val); } else { xmt_parse_mf_field(parser, &field, node, val); } }}static u32 xmt_get_next_proto_id(GF_XMTParser *parser){ u32 ID; GF_SceneGraph *sc = parser->load->scene_graph; if (parser->parsing_proto) sc = gf_sg_proto_get_graph(parser->parsing_proto); ID = gf_sg_get_next_available_proto_id(sc); if (parser->load->ctx && (ID>parser->load->ctx->max_node_id)) parser->load->ctx->max_proto_id = ID; return ID;}static void xmt_parse_proto(GF_XMTParser *parser, const GF_XMLAttribute *attributes, u32 nb_attributes, GF_List *proto_list){ GF_FieldInfo info; GF_Proto *proto; char *szName, *extURL; u32 ID, i; ID = 0; szName = extURL = NULL; for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i]; if (!att->value || !strlen(att->value)) continue; if (!strcmp(att->name, "name")) szName = att->value; else if (!strcmp(att->name, "protoID")) ID = atoi(att->value); else if (!strcmp(att->name, "locations")) extURL = att->value; else if (!strcmp(att->name, "url")) extURL = att->value; } ID = xmt_get_next_proto_id(parser); proto = gf_sg_proto_new(parser->load->scene_graph, ID, szName, proto_list ? 1 : 0); if (proto_list) gf_list_add(proto_list, proto); if (parser->load->ctx && (parser->load->ctx->max_proto_id<ID)) parser->load->ctx->max_proto_id=ID; /*store previous proto*/ proto->userpriv = parser->parsing_proto; parser->parsing_proto = proto; parser->load->scene_graph = gf_sg_proto_get_graph(proto); if (extURL) { info.fieldType = GF_SG_VRML_MFURL; info.far_ptr = &proto->ExternProto; info.name = "ExternURL"; xmt_parse_mf_field(parser, &info, NULL, extURL); }}static u32 xmt_get_protofield_qp_type(const char *QP_Type){ if (!strcmp(QP_Type, "position3D")) return QC_3DPOS; else if (!strcmp(QP_Type, "position2D")) return QC_2DPOS; else if (!strcmp(QP_Type, "drawingOrder")) return QC_ORDER; else if (!strcmp(QP_Type, "color")) return QC_COLOR; else if (!strcmp(QP_Type, "textureCoordinate")) return QC_TEXTURE_COORD; else if (!strcmp(QP_Type, "angle")) return QC_ANGLE; else if (!strcmp(QP_Type, "scale")) return QC_SCALE; else if (!strcmp(QP_Type, "keys")) return QC_INTERPOL_KEYS; else if (!strcmp(QP_Type, "normals")) return QC_NORMALS; else if (!strcmp(QP_Type, "rotations")) return QC_ROTATION; else if (!strcmp(QP_Type, "size3D")) return QC_SIZE_3D; else if (!strcmp(QP_Type, "size2D")) return QC_SIZE_2D; else if (!strcmp(QP_Type, "linear")) return QC_LINEAR_SCALAR; else if (!strcmp(QP_Type, "coordIndex")) return QC_COORD_INDEX; else return 0;}static GF_Err x3d_get_default_container(GF_Node *par, GF_Node *n, GF_FieldInfo *info){ u32 i, count; count = gf_node_get_field_count(par); /*get the first field/exposedField accepting this child*/ for (i=0; i<count; i++) { gf_node_get_field(par, i, info); if ((info->fieldType!=GF_SG_VRML_SFNODE) && (info->fieldType!=GF_SG_VRML_MFNODE)) continue; if ((info->eventType==GF_SG_EVENT_OUT) || (info->eventType==GF_SG_EVENT_IN)) continue; if (gf_node_in_table(n, info->NDTtype)) return GF_OK; } return GF_BAD_PARAM;}static GF_Node *xmt_parse_element(GF_XMTParser *parser, char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes, XMTNodeStack *parent){ GF_Err e; GF_FieldInfo info; u32 tag, i, count, ID; Bool register_def = 0; Bool is_script = 0; GF_Node *node; GF_FieldInfo container; char *def_name; GF_Proto *proto = NULL; node = NULL; if (!strcmp(name, "NULL")) return NULL; if (!strcmp(name, "ROUTE")) { if (!parser->parsing_proto && (parser->doc_type==1) ) { GF_Command *sgcom = gf_sg_command_new(parser->load->scene_graph, GF_SG_ROUTE_INSERT); gf_list_add(parser->scene_au->commands, sgcom); xmt_parse_route(parser, attributes, nb_attributes, 0, sgcom); if (sgcom->RouteID) gf_list_add(parser->inserted_routes, sgcom); } else { xmt_parse_route(parser, attributes, nb_attributes, 0, NULL); } return NULL; } if (parent && parent->node && ((parent->node->sgprivate->tag==TAG_MPEG4_Script) || (parent->node->sgprivate->tag==TAG_X3D_Script)) ) { is_script = 1; if (!strcmp(name, "field")) { xmt_parse_script_field(parser, parent->node, attributes, nb_attributes); return NULL; } else if (!strcmp(name, "node") || !strcmp(name, "nodes") ) return NULL; } /*proto declaration*/ if (!strcmp(name, "ProtoDeclare") || !strcmp(name, "ExternProtoDeclare")) { if (!parser->parsing_proto && parser->command && !parser->command->new_proto_list) parser->command->new_proto_list = gf_list_new(); xmt_parse_proto(parser, attributes, nb_attributes, (!parser->parsing_proto && parser->command) ? parser->command->new_proto_list : NULL); return NULL; } /*proto parsing*/ if (parser->parsing_proto) { if (!strcmp(name, "IS")) return NULL; if (!strcmp(name, "field")) { char *fieldName = NULL; char *value = NULL; u32 fType, eType; fType = eType = 0; for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i]; if (!att->value || !strlen(att->value)) continue; if (!strcmp(att->name, "name")) fieldName = att->value; else if (!strcmp(att->name, "type")) fType = xmt_get_ft_by_name(att->value); else if (!strcmp(att->name, "vrml97Hint") || !strcmp(att->name, "accessType") ) eType = xmt_get_et_by_name(att->value); else if (strstr(att->name, "value") || strstr(att->name, "Value")) value = att->value; } parser->proto_field = gf_sg_proto_field_new(parser->parsing_proto, fType, eType, fieldName); if (value && strlen(value)) { gf_sg_proto_field_get_field(parser->proto_field, &info); if (gf_sg_vrml_is_sf_field(fType)) { xmt_parse_sf_field(parser, &info, NULL, value); } else { xmt_parse_mf_field(parser, &info, NULL, value); } } else if (gf_sg_vrml_get_sf_type(fType) != GF_SG_VRML_SFNODE) { gf_sg_proto_field_set_value_undefined(parser->proto_field); } /*SF/MFNode proto field: push node stack with container info but no parent*/ else { XMTNodeStack *pf_stack; GF_SAFEALLOC(pf_stack, XMTNodeStack); gf_sg_proto_field_get_field(parser->proto_field, &pf_stack->container_field); gf_list_add(parser->nodes, pf_stack); } return NULL; } /*X3D style*/ if (!strcmp(name, "ProtoInterface") || !strcmp(name, "ProtoBody")) return NULL; /*XMT1 decl for SFNode proto fields*/ if (parser->proto_field && (!strcmp(name, "node") || !strcmp(name, "nodes")) ) return NULL; /*anim & QP info */ if (parser->proto_field && !strcmp(name, "InterfaceCodingParameter")) { u32 qp_type, nbBits, hasMinMax, qp_sftype; Fixed ftMin, ftMax; ftMin = ftMax = 0; qp_type = hasMinMax = nbBits = 0; for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *) &attributes[i]; if (!att->value || !strlen(att->value)) continue; if (!strcmp(att->name, "quantCategory")) qp_type = xmt_get_protofield_qp_type(att->value); else if (!strcmp(att->name, "nbBits")) nbBits = atoi(att->value); else if (!strncmp(att->name, "position3DM", 11) || !strncmp(att->name, "position2DM", 11) || !strncmp(att->name, "drawOrderM", 10) || !strncmp(att->name, "colorM", 6) || !strncmp(att->name, "textureCoordinateM", 18) || !strncmp(att->name, "angleM", 6) || !strncmp(att->name, "scaleM", 6) || !strncmp(att->name, "keyM", 4) || !strncmp(att->name, "sizeM", 5) ) { hasMinMax = 1; if (strstr(att->name, "Min")) xmt_parse_float(parser, att->name, &ftMin, att->value); else xmt_parse_float(parser, att->name, &ftMax, att->value); } } if (gf_sg_vrml_get_sf_type(parser->proto_field->FieldType) == GF_SG_VRML_SFINT32) { qp_sftype = GF_SG_VRML_SFINT32; } else { qp_sftype = GF_SG_VRML_SFFLOAT; } gf_bifs_proto_field_set_aq_info(parser->proto_field, qp_type, hasMinMax, qp_sftype, &ftMin, &ftMax, nbBits); return NULL; } /*connect */ if (!strcmp(name, "connect")) { GF_ProtoFieldInterface *pf; Bool is_script = 0; GF_FieldInfo pfield, nfield; char *atField, *atProtoField; XMTNodeStack *last = (XMTNodeStack*)gf_list_last(parser->nodes); if (!last) { xmt_report(parser, GF_OK, "connect: no parent node specified - skipping"); return NULL; } atField = atProtoField = NULL; for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i]; if (!att->value || !strlen(att->value)) continue; if (!strcmp(att->name, "nodeField")) atField = att->value; else if (!strcmp(att->name, "protoField")) atProtoField = att->value; } if (!atField) { xmt_report(parser, GF_OK, "connect: Missing node field - skipping"); return NULL; } if (!atProtoField) { xmt_report(parser, GF_OK, "connect: Missing proto field - skipping"); return NULL; } if ( (e = gf_node_get_field_by_name(last->node, atField, &nfield)) != GF_OK) { u32 l_tag = gf_node_get_tag(last->node); if ((l_tag!=TAG_MPEG4_Script) && (l_tag!=TAG_X3D_Script)) { xmt_report(parser, e, "connect: %s not an field of node %s", atField, gf_node_get_class_name(last->node) ); return NULL; } is_script = 1; } pf = gf_sg_proto_field_find_by_name(parser->parsing_proto, atProtoField); if (!pf) { xmt_report(parser, GF_BAD_PARAM, "connect: Proto field %s is not defined", atProtoField); return NULL; } gf_sg_proto_field_get_field(pf, &pfield); if (is_script) { gf_sg_script_field_new(last->node, pfield.eventType, pfield.fieldType, atField); gf_node_get_field_by_name(last->node, atField, &nfield); } e = gf_sg_proto_field_set_ised(parser->parsing_proto, pfield.fieldIndex, last->node, nfield.fieldIndex); if (e) xmt_report(parser, GF_BAD_PARAM, "connect: %s", gf_error_to_string(e)); return NULL; } } /*proto instance field*/ if (!strcmp(name, "fieldValue")) { char *field, *value; if (!parent || (parent->node->sgprivate->tag != TAG_ProtoNode)) { xmt_report(parser, GF_OK, "Warning: fieldValue not a valid node"); return NULL; } field = value = NULL; for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i]; if (!att->value || !strlen(att->value)) continue; if (!strcmp(att->name, "name")) field = att->value; else if (!strstr(att->name, "Value") || !strstr(att->name, "value")) value = att->value; } if (!field) { xmt_report(parser, GF_OK, "Warning: unspecified proto field name - skipping"); return NULL; } e = gf_node_get_field_by_name(parent->node, field, &info); if (e) { xmt_report(parser, GF_OK, "Warning: Unknown proto field %s - skipping", field); return NULL; } if (value) { if (gf_sg_vrml_is_sf_field(info.fieldType)) { xmt_parse_sf_field(parser, &info, parent->node, value); } else { xmt_parse_mf_field(parser, &info, parent->node, value); } gf_sg_proto_mark_field_loaded(parent->node, &info); } else if (gf_sg_vrml_get_sf_type(info.fieldType) == GF_SG_VRML_SFNODE) { parent->container_field = info; parent->last = NULL; } return NULL; } if (parent && parent->node && (parent->node->sgprivate->tag == TAG_ProtoNode) && (!strcmp(name, "node") || !strcmp(name, "nodes")) ) { return NULL; } ID = 0; def_name = NULL; tag = 0; if (!strcmp(name, "ProtoInstance")) { for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i]; if (!att->value || !strlen(att->value)) continue; if (!strcmp(att->name, "name")) { GF_SceneGraph *sg = parser->load->scene_graph; while (1) { proto = gf_sg_find_proto(sg, 0, att->value); if (proto) break; sg = sg->parent_scene; if (!sg) break; } if (!proto) { xmt_report(parser, GF_BAD_PARAM, "%s: not a valid/supported proto", att->value); return NULL; } node = gf_sg_proto_create_instance(parser->load->scene_graph, proto); } else if (!strcmp(att->name, "USE")) { node = xmt_find_node(parser, att->value); e = GF_OK; if (!node) e = xmt_report(parser, GF_BAD_PARAM, "Warning: Cannot find node %s referenced in USE - skipping", att->value); if (e) return NULL; ID = 0; register_def = 0; tag = 0; count = 0; } } } else { tag = xmt_get_node_tag(parser, name); if (!tag) { /*XMT-A weird syntax*/ if (parent) { if (gf_node_get_field_by_name(parent->node, name, &parent->container_field)==GF_OK) { parent->last = NULL; if (parent->container_field.fieldType==GF_SG_VRML_SFCOMMANDBUFFER) { parser->command_buffer = (SFCommandBuffer*)parent->container_field.far_ptr; /*store command*/ parser->command_buffer->buffer = (unsigned char *)parser->command; parser->doc_state = 3; } return NULL; } parent->container_field.far_ptr = NULL; } else if (parser->command && (parser->command->tag == GF_SG_MULTIPLE_REPLACE)) { if (gf_node_get_field_by_name(parser->command->node, name, &container)==GF_OK) { GF_CommandField *field = gf_sg_command_field_new(parser->command); field->fieldIndex = container.fieldIndex; field->fieldType = container.fieldType; return NULL; } } xmt_report(parser, GF_OK, "Warning: %s is not a valid node - skipping", name); return NULL; } node = gf_node_new(parser->load->scene_graph, tag); if (!node) { xmt_report(parser, GF_SG_UNKNOWN_NODE, "Warning: %s is not a supported node - skipping", name); return NULL; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -