⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vrml_proto.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					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>GF_Proto *gf_sg_proto_new(GF_SceneGraph *inScene, u32 ProtoID, char *name, Bool unregistered){	GF_Proto *tmp;	if (!inScene) return NULL;	/*make sure we don't define a proto already defined in this scope*/	if (!unregistered) {		tmp = gf_sg_find_proto(inScene, ProtoID, name);		if (tmp) return NULL;	}	GF_SAFEALLOC(tmp, GF_Proto)	if (!tmp) return NULL;	tmp->proto_fields = gf_list_new();	tmp->node_code = gf_list_new();	tmp->parent_graph = inScene;	tmp->sub_graph = gf_sg_new_subscene(inScene);	tmp->instances = gf_list_new();	if (name) 		tmp->Name = strdup(name);	else		tmp->Name = strdup("Unnamed Proto");	tmp->ID = ProtoID;	if (!unregistered) {		gf_list_add(inScene->protos, tmp);	} else {		gf_list_add(inScene->unregistered_protos, tmp);	}	return tmp;}GF_Err gf_sg_proto_set_in_graph(GF_Proto *proto, GF_SceneGraph *inScene, Bool set_in){	u32 i;	GF_Proto *tmp;	GF_List *removeFrom;	GF_List *insertIn;	if (set_in) {		removeFrom = proto->parent_graph->unregistered_protos;		insertIn = proto->parent_graph->protos;	} else {		insertIn = proto->parent_graph->unregistered_protos;		removeFrom = proto->parent_graph->protos;	}	gf_list_del_item(removeFrom, proto);	i=0;	while ((tmp = (GF_Proto*)gf_list_enum(insertIn, &i))) {		if (tmp==proto) return GF_OK;		if (!set_in) continue;		/*if registering, make sure no other proto has the same ID/name*/		if (tmp->ID==proto->ID) return GF_BAD_PARAM;		if (!stricmp(tmp->Name, proto->Name)) return GF_BAD_PARAM;	}	return gf_list_add(insertIn, proto);}GF_Err gf_sg_proto_del(GF_Proto *proto){	GF_Node *node;	GF_ProtoFieldInterface *field;	s32 i;	if (!proto) return GF_OK;	i = gf_list_del_item(proto->parent_graph->protos, proto);	if (i<0) i = gf_list_del_item(proto->parent_graph->unregistered_protos, proto);	if (proto->userpriv && proto->OnDelete) proto->OnDelete(proto->userpriv);	/*first destroy the code*/	while (gf_list_count(proto->node_code)) {		node = (GF_Node*)gf_list_get(proto->node_code, 0);		gf_node_unregister(node, NULL);		gf_list_rem(proto->node_code, 0);	}	gf_list_del(proto->node_code);	/*delete interface*/	while (gf_list_count(proto->proto_fields)) {		field = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, 0);		if (field->userpriv && field->OnDelete) field->OnDelete(field->userpriv);		if (field->FieldType==GF_SG_VRML_SFNODE) {			if (field->def_sfnode_value) 				gf_node_unregister(field->def_sfnode_value, NULL);		} 		else if (field->FieldType==GF_SG_VRML_MFNODE) {			if (field->def_mfnode_value)				gf_node_unregister_children(NULL, field->def_mfnode_value);		} 		else if (field->def_value) 			gf_sg_vrml_field_pointer_del(field->def_value, field->FieldType);			if (field->FieldName) free(field->FieldName);		/*QP fields are SF fields, we can safely free() them*/		if (field->qp_max_value) free(field->qp_max_value);		if (field->qp_min_value) free(field->qp_min_value);		free(field);		gf_list_rem(proto->proto_fields, 0);	}	gf_list_del(proto->proto_fields);	while (gf_list_count(proto->instances)) {		GF_ProtoInstance *p = (GF_ProtoInstance *)gf_list_get(proto->instances, 0);		gf_list_rem(proto->instances, 0);		p->proto_interface = NULL;	}	/*delete sub graph*/	gf_sg_del(proto->sub_graph);	if (proto->Name) free(proto->Name);	gf_sg_mfurl_del(proto->ExternProto);	gf_list_del(proto->instances);		free(proto);	return GF_OK;}GF_SceneGraph *gf_sg_proto_get_graph(GF_Proto *proto){	return proto ? proto->sub_graph : NULL;}void gf_sg_proto_set_private(GF_Proto *p, void *ptr, void (*OnDelete)(void *ptr) ){	if (p) {		p->userpriv = ptr;		p->OnDelete = OnDelete;	}}void *gf_sg_proto_get_private(GF_Proto *p){	return p ? p->userpriv : NULL;}GF_EXPORTMFURL *gf_sg_proto_get_extern_url(GF_Proto *proto){	return proto ? &proto->ExternProto : NULL;}GF_Err gf_sg_proto_add_node_code(GF_Proto *proto, GF_Node *pNode){	if (!proto) return GF_BAD_PARAM;	return gf_list_add(proto->node_code, pNode);}GF_ProtoFieldInterface *gf_sg_proto_field_find_by_name(GF_Proto *proto, char *fieldName){	GF_ProtoFieldInterface *ptr;	u32 i=0;	while ((ptr = (GF_ProtoFieldInterface*)gf_list_enum(proto->proto_fields, &i))) {		if (ptr->FieldName && !strcmp(ptr->FieldName, fieldName)) return ptr;	}	return NULL;}GF_ProtoFieldInterface *gf_sg_proto_field_new(GF_Proto *proto, u32 fieldType, u32 eventType, char *fieldName){	GF_ProtoFieldInterface *tmp;	if (fieldName) {		tmp = gf_sg_proto_field_find_by_name(proto, fieldName);		if (tmp) return NULL;	}	GF_SAFEALLOC(tmp, GF_ProtoFieldInterface)	if (!tmp) return NULL;	tmp->FieldType = fieldType;	tmp->EventType = eventType;		/*create container - can be NULL if SF node*/	if ( fieldType == GF_SG_VRML_SFNODE) {		tmp->def_sfnode_value = NULL;		tmp->def_value = &tmp->def_sfnode_value;	} else if ( fieldType == GF_SG_VRML_MFNODE) {		tmp->def_mfnode_value = NULL;		tmp->def_value = &tmp->def_mfnode_value;	} else {		tmp->def_value = gf_sg_vrml_field_pointer_new(fieldType);	}		if (fieldName) tmp->FieldName = strdup(fieldName);		tmp->ALL_index = gf_list_count(proto->proto_fields);	tmp->OUT_index = tmp->DEF_index = tmp->IN_index = (u32) -1;	switch (eventType) {	case GF_SG_EVENT_EXPOSED_FIELD:		tmp->IN_index = proto->NumIn;		proto->NumIn ++;		tmp->OUT_index = proto->NumOut;		proto->NumOut ++;	case GF_SG_EVENT_FIELD:		tmp->DEF_index = proto->NumDef;		proto->NumDef ++;		break;	case GF_SG_EVENT_IN:		tmp->IN_index = proto->NumIn;		proto->NumIn ++;		break;	case GF_SG_EVENT_OUT:		tmp->OUT_index = proto->NumOut;		proto->NumOut ++;		break;	}	gf_list_add(proto->proto_fields, tmp);	return tmp;}void gf_sg_proto_field_set_private(GF_ProtoFieldInterface *field, void *ptr, void (*OnDelete)(void *ptr)){	if (field) {		field->userpriv = ptr;		field->OnDelete = OnDelete;	}}void *gf_sg_proto_field_get_private(GF_ProtoFieldInterface *field){	return field ? field->userpriv : NULL;}GF_Err gf_sg_proto_field_get_field(GF_ProtoFieldInterface *field, GF_FieldInfo *info){	if (!field || !info) return GF_BAD_PARAM;	memset(info, 0, sizeof(GF_FieldInfo));	info->fieldIndex = field->ALL_index;	info->fieldType = field->FieldType;	info->eventType = field->EventType;	info->far_ptr = field->def_value;	info->name = field->FieldName;	info->NDTtype = NDT_SFWorldNode;	return GF_OK;}GF_Err gf_sg_proto_get_field(GF_Proto *proto, GF_Node *node, GF_FieldInfo *info){	GF_ProtoFieldInterface *proto_field;	GF_ProtoInstance *inst;	GF_ProtoField *field;	if (!proto && !node) return GF_BAD_PARAM;	if (proto) {		proto_field = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, info->fieldIndex);		if (!proto_field) return GF_BAD_PARAM;		info->fieldType = proto_field->FieldType;		info->eventType = proto_field->EventType;		info->fieldIndex = proto_field->ALL_index;		info->NDTtype = NDT_SFWorldNode;		info->far_ptr = proto_field->def_value;		info->name = proto_field->FieldName;		return GF_OK;	}	/*otherwise this is an instanciated proto*/	if (node->sgprivate->tag!=TAG_ProtoNode) return GF_BAD_PARAM;	inst = (GF_ProtoInstance *) node;	field = (GF_ProtoField*)gf_list_get(inst->fields, info->fieldIndex);	if (!field) return GF_BAD_PARAM;	info->fieldType = field->FieldType;	info->eventType = field->EventType;	/*SF/MF nodes need pointers to field object - cf gf_sg_proto_create_node*/	if (gf_sg_vrml_get_sf_type(field->FieldType) == GF_SG_VRML_SFNODE) {		info->far_ptr = &field->field_pointer;	} else {		info->far_ptr = field->field_pointer;	}	/*set the name - watchout for deletion case*/	if (inst->proto_interface) {		proto_field = (GF_ProtoFieldInterface*)gf_list_get(inst->proto_interface->proto_fields, info->fieldIndex);		info->name = proto_field->FieldName;	} else {		info->name = "ProtoFieldDeleted";	}	info->NDTtype = NDT_SFWorldNode;	return GF_OK;}s32 gf_sg_proto_get_field_index_by_name(GF_Proto *proto, GF_Node *node, char *name){	u32 i;	GF_ProtoFieldInterface *proto_field;	GF_Proto *__proto;	if (node && (node->sgprivate->tag!=TAG_ProtoNode)) return -1;	__proto = proto ? proto : ((GF_ProtoInstance *) node)->proto_interface;	if (!__proto ) return -1;	for (i=0; i<gf_list_count(__proto->proto_fields); i++) {		proto_field = (GF_ProtoFieldInterface*)gf_list_get(__proto->proto_fields, i);		if (proto_field->FieldName && !strcmp(proto_field->FieldName, name)) return i;	}	return -1;}GF_EXPORTGF_Node *gf_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *cloned_parent){	u32 i, count, id;	const char *orig_name;	Bool is_script;	GF_Node *node, *child;	GF_ChildNodeItem *list, *last;	GF_Route *r1, *r2;	void BIFS_SetupConditionalClone(GF_Node *node, GF_Node *orig);	GF_ProtoInstance *proto;	GF_Proto *proto_node;	GF_FieldInfo field_orig, field;	/*this is not a mistake*/	if (!orig) return NULL;	/*check for DEF/USE*/	orig_name  = gf_node_get_name_and_id(orig, &id);	if (id) {		node = gf_sg_find_node(inScene, id);		/*node already created, USE*/		if (node) {			gf_node_register(node, cloned_parent);			return node;		}	}	/*create a node*/	if (orig->sgprivate->tag == TAG_ProtoNode) {		proto_node = ((GF_ProtoInstance *)orig)->proto_interface;		/*create the instance but don't load the code -c we MUST wait for ISed routes to be cloned before*/		node = gf_sg_proto_create_node(inScene, proto_node, (GF_ProtoInstance *) orig);	} else {		node = gf_node_new(inScene, orig->sgprivate->tag);	}	count = gf_node_get_field_count(orig);	is_script = 0;	if ((orig->sgprivate->tag==TAG_MPEG4_Script) || (orig->sgprivate->tag==TAG_X3D_Script)) is_script = 1;	if (is_script) gf_sg_script_prepare_clone(node, orig);	/*copy each field*/	for (i=0; i<count; i++) {		gf_node_get_field(orig, i, &field_orig);		/*get target ptr*/		gf_node_get_field(node, i, &field);		assert(field.eventType==field_orig.eventType);		assert(field.fieldType==field_orig.fieldType);		/*duplicate it*/		switch (field.fieldType) {		case GF_SG_VRML_SFNODE:			child = gf_node_clone(inScene, (* ((GF_Node **) field_orig.far_ptr)), node);			*((GF_Node **) field.far_ptr) = child;			break;		case GF_SG_VRML_MFNODE:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -