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

📄 base_scenegraph.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
📖 第 1 页 / 共 3 页
字号:
			node->sgprivate->parents->next = NULL;			node->sgprivate->parents->node = parentNode;		} else {			GF_ParentList *item, *nlist = node->sgprivate->parents;			while (nlist->next) nlist = nlist->next;			item = (GF_ParentList*)malloc(sizeof(GF_ParentList));			item->next = NULL;			item->node = parentNode;			nlist->next = item;		}	}	return GF_OK;}/*replace or remove node instance in the given node (eg in all GF_Node or MFNode fields)this doesn't propagate in the scene graph. If updateOrderedGroup and new_node is NULL, the order field of OGis updated*/static void ReplaceDEFNode(GF_Node *FromNode, GF_Node *node, GF_Node *newNode, Bool updateOrderedGroup){	u32 i, j;	GF_Node *p;	GF_ChildNodeItem *list;	GF_FieldInfo field;	/*browse all fields*/	for (i=0; i<gf_node_get_field_count(FromNode); i++) {		gf_node_get_field(FromNode, i, &field);		switch (field.fieldType) {		case GF_SG_VRML_SFNODE:			/*set to NULL for SFFields*/			p = *((GF_Node **) field.far_ptr);			/*this is a USE / DEF*/			if (p == node) {				*((GF_Node **) field.far_ptr) = NULL;				if (newNode) {					*((GF_Node **) field.far_ptr) = newNode;				}				goto exit;			}			break;		case GF_SG_VRML_MFNODE:			list = *(GF_ChildNodeItem **) field.far_ptr;			j=0;			while (list) {				/*replace nodes different from newNode but with same ID*/				if ((newNode == list->node) || (list->node != node)) {					list = list->next;					j++;					continue;				}				if (newNode) {					list->node = newNode;				} else {					gf_node_list_del_child( (GF_ChildNodeItem **) field.far_ptr, list->node);					if (updateOrderedGroup && (FromNode->sgprivate->tag==TAG_MPEG4_OrderedGroup)) {						M_OrderedGroup *og = (M_OrderedGroup *)FromNode;						gf_sg_vrml_mf_remove(&og->order, GF_SG_VRML_SFINT32, j);					}				}				goto exit;			}			break;			/*not a node, continue*/		default:			continue;		}	}	/*since we don't filter parent nodes this is called once per USE, not per container, so return if found*/exit:	gf_node_changed(FromNode, &field);}#ifndef GPAC_DISABLE_SVGstatic void Replace_IRI(GF_SceneGraph *sg, GF_Node *old_node, GF_Node *newNode){	u32 i, count;	count = gf_list_count(sg->xlink_hrefs);	for (i=0; i<count; i++) {		XMLRI *iri = (XMLRI *)gf_list_get(sg->xlink_hrefs, i);		if (iri->target == old_node) {			iri->target = newNode;			if (!newNode) {				gf_list_rem(sg->xlink_hrefs, i);				i--;				count--;			}		} 	}}/*replace or remove node instance in the given node (eg in all IRI)*/static void ReplaceIRINode(GF_Node *FromNode, GF_Node *old_node, GF_Node *newNode){	GF_ChildNodeItem *prev = NULL;	GF_ChildNodeItem *child = ((SVG_Element *)FromNode)->children;	while (child) {		if (child->node != old_node) {			prev = child;			child = child->next;			continue;		}		if (newNode) {			child->node = newNode;		} else {			if (prev) prev->next = child->next;			else ((SVG_Element *)FromNode)->children = child->next;			free(child);		}		break;	}}#endif/*get all parents of the node and replace, the instance of the node and finally destroy the node*/GF_Err gf_node_replace(GF_Node *node, GF_Node *new_node, Bool updateOrderedGroup){	u32 type;	Bool replace_root;	GF_Node *par;	GF_SceneGraph *pSG = node->sgprivate->scenegraph;	/*if this is a proto its is registered in its parent graph, not the current*/	if (node == (GF_Node*)pSG->pOwningProto) pSG = pSG->parent_scene;//	if (!SG_SearchForNodeIndex(pSG, node, &i)) return GF_BAD_PARAM;//	assert(node == pSG->node_registry[i]);	type = node->sgprivate->tag;#ifndef GPAC_DISABLE_SVG	if (((type>= GF_NODE_RANGE_FIRST_SVG) && (type<= GF_NODE_RANGE_LAST_SVG)) #ifdef GPAC_ENABLE_SVG_SA		|| ((type>= GF_NODE_RANGE_FIRST_SVG_SA) && (type<= GF_NODE_RANGE_LAST_SVG_SA)) #endif#ifdef GPAC_ENABLE_SVG_SANI		|| ((type>= GF_NODE_RANGE_FIRST_SVG_SANI) && (type<= GF_NODE_RANGE_LAST_SVG_SANI))#endif		) {		type = 1;		Replace_IRI(pSG, node, new_node);	} else #endif		type = 0;	/*first check if this is the root node*/	replace_root = (node->sgprivate->scenegraph->RootNode == node) ? 1 : 0;	while (node->sgprivate->parents) {		Bool do_break = node->sgprivate->parents->next ? 0 : 1;		par = node->sgprivate->parents->node;#ifndef GPAC_DISABLE_SVG		if (type)			ReplaceIRINode(par, node, new_node);		else#endif			ReplaceDEFNode(par, node, new_node, updateOrderedGroup);		if (new_node) gf_node_register(new_node, par);		gf_node_unregister(node, par);		gf_node_changed(par, NULL);		if (do_break) break;	}	if (replace_root) {		pSG = node->sgprivate->scenegraph;		gf_node_unregister(node, NULL);		pSG->RootNode = new_node;	}	return GF_OK;}static GFINLINE void insert_node_def(GF_SceneGraph *sg, GF_Node *def, u32 ID, const char *name){	NodeIDedItem *reg_node, *cur;	reg_node = (NodeIDedItem *) malloc(sizeof(NodeIDedItem));	reg_node->node = def;	reg_node->NodeID = ID;	reg_node->NodeName = name ? strdup(name) : NULL;	reg_node->next = NULL;	if (!sg->id_node) {		sg->id_node = reg_node;		sg->id_node_last = sg->id_node;	} else if (sg->id_node->NodeID>ID) {		reg_node->next = sg->id_node;		sg->id_node = reg_node;	} else if (sg->id_node_last->NodeID < ID) {		sg->id_node_last->next = reg_node;		sg->id_node_last = reg_node;	} else {		cur = sg->id_node;		while (cur->next) {			if (cur->next->NodeID>ID) {				reg_node->next = cur->next;				cur->next = reg_node;				return;			}			cur = cur->next;		}		cur->next = reg_node;	}}GF_EXPORTGF_Err gf_node_set_id(GF_Node *p, u32 ID, const char *name){	GF_SceneGraph *pSG; 	if (!ID || !p || !p->sgprivate->scenegraph) return GF_BAD_PARAM;	pSG = p->sgprivate->scenegraph;	/*if this is a proto register to the parent graph, not the current*/	if (p == (GF_Node*)pSG->pOwningProto) pSG = pSG->parent_scene;	/*new DEF ID*/	if (!(p->sgprivate->flags & GF_NODE_IS_DEF) ) {		p->sgprivate->flags |= GF_NODE_IS_DEF;	} 	/*reassigning ID, remove node def*/	else {		remove_node_id(pSG, p);	}	insert_node_def(pSG, p, ID, name);	return GF_OK;}GF_EXPORTGF_Err gf_node_remove_id(GF_Node *p){	GF_SceneGraph *pSG; 	if (!p) return GF_BAD_PARAM;	pSG = p->sgprivate->scenegraph;	/*if this is a proto register to the parent graph, not the current*/	if (p == (GF_Node*)pSG->pOwningProto) pSG = pSG->parent_scene;	/*new DEF ID*/	if (p->sgprivate->flags & GF_NODE_IS_DEF) {		remove_node_id(pSG, p);		p->sgprivate->flags &= ~GF_NODE_IS_DEF;		return GF_OK;	} 	return GF_BAD_PARAM;}/*calls RenderNode on this node*/GF_EXPORTvoid gf_node_render(GF_Node *node, void *renderStack){	if (!node || !node->sgprivate) return;	if (node->sgprivate->flags & GF_NODE_IS_DEACTIVATED) return;	if (node->sgprivate->tag != TAG_ProtoNode) {		if (node->sgprivate->UserCallback) { #ifdef GF_CYCLIC_RENDER_ON			if (node->sgprivate->flags & GF_NODE_IN_RENDER) return;			node->sgprivate->flags |= GF_NODE_IN_RENDER;			assert(node->sgprivate->flags);#endif			GF_LOG(GF_LOG_DEBUG, GF_LOG_SCENE, ("[SceneGraph] Traversing node %s\n", gf_node_get_class_name(node) ));			node->sgprivate->UserCallback(node, renderStack, 0);#ifdef GF_CYCLIC_RENDER_ON			node->sgprivate->flags &= ~GF_NODE_IN_RENDER;#endif		}		return;	}	/*proto only traverses its first child*/	if (((GF_ProtoInstance *) node)->RenderingNode) {		node = ((GF_ProtoInstance *) node)->RenderingNode;	}	/*if no rendering function is assigned this is a real proto (otherwise this is an hardcoded one)*/	else if (!node->sgprivate->UserCallback) {		/*if no rendering node, check if the proto is fully instanciated (externProto)*/		GF_ProtoInstance *proto_inst = (GF_ProtoInstance *) node;		gf_node_dirty_clear(node, 0);		/*proto has been deleted or dummy proto (without node code)*/		if (!proto_inst->proto_interface || proto_inst->is_loaded) return;		/*try to load the code*/		gf_sg_proto_instanciate(proto_inst);		if (!proto_inst->RenderingNode) {			gf_node_dirty_set(node, 0, 1);			return;		}		node = proto_inst->RenderingNode;		node->sgprivate->scenegraph->NodeCallback(node->sgprivate->scenegraph->userpriv, GF_SG_CALLBACK_MODIFIED, node, NULL);	}	if (node->sgprivate->UserCallback) {#ifdef GF_CYCLIC_RENDER_ON		if (node->sgprivate->flags & GF_NODE_IN_RENDER) return;		node->sgprivate->flags |= GF_NODE_IN_RENDER;#endif		GF_LOG(GF_LOG_DEBUG, GF_LOG_SCENE, ("[SceneGraph] Traversing node %s\n", gf_node_get_class_name(node) ));		node->sgprivate->UserCallback(node, renderStack, 0);#ifdef GF_CYCLIC_RENDER_ON		node->sgprivate->flags &= ~GF_NODE_IN_RENDER;#endif	}}GF_EXPORTvoid gf_node_allow_cyclic_render(GF_Node *node){#ifdef GF_CYCLIC_RENDER_ON	if (node) node->sgprivate->flags &= ~GF_NODE_IN_RENDER;#endif}/*blindly calls RenderNode on all nodes in the "children" list*/GF_EXPORTvoid gf_node_render_children(GF_Node *node, void *renderStack){	GF_ChildNodeItem *child;	assert(node);	child = ((GF_ParentNode *)node)->children;	while (child) {		gf_node_render(child->node, renderStack);		child = child->next;	}}GF_EXPORTGF_SceneGraph *gf_node_get_graph(GF_Node *node){	return (node ? node->sgprivate->scenegraph : NULL);}GF_EXPORTGF_Node *gf_sg_find_node(GF_SceneGraph *sg, u32 nodeID){	NodeIDedItem *reg_node = sg->id_node;	while (reg_node) {		if (reg_node->NodeID == nodeID) return reg_node->node;		reg_node = reg_node->next;	}	return NULL;}GF_EXPORTGF_Node *gf_sg_find_node_by_name(GF_SceneGraph *sg, char *name){	if (name) {		NodeIDedItem *reg_node = sg->id_node;		while (reg_node) {			if (reg_node->NodeName && !strcmp(reg_node->NodeName, name)) return reg_node->node;			reg_node = reg_node->next;		}	}	return NULL;}GF_EXPORTu32 gf_sg_get_next_available_node_id(GF_SceneGraph *sg) {	u32 ID;	NodeIDedItem *reg_node;	if (!sg->id_node) return 1;	reg_node = sg->id_node;	ID = reg_node->NodeID;	/*nodes are sorted*/	while (reg_node->next) {		if (ID+1<reg_node->next->NodeID) return ID+1;		ID = reg_node->next->NodeID;		reg_node = reg_node->next;	}	return ID+1;}u32 gf_sg_get_max_node_id(GF_SceneGraph *sg){	NodeIDedItem *reg_node;	if (!sg->id_node) return 0;	if (sg->id_node_last) return sg->id_node_last->NodeID;	reg_node = sg->id_node;	while (reg_node->next) reg_node = reg_node->next;	return reg_node->NodeID;}void gf_node_setup(GF_Node *p, u32 tag){	GF_SAFEALLOC(p->sgprivate, NodePriv);	p->sgprivate->tag = tag;	p->sgprivate->flags = GF_SG_NODE_DIRTY;}GF_Node *gf_sg_new_base_node(){	GF_Node *newnode = (GF_Node *)malloc(sizeof(GF_Node));	gf_node_setup(newnode, TAG_UndefinedNode);	return newnode;}GF_EXPORTu32 gf_node_get_tag(GF_Node*p){	assert(p);	return p->sgprivate->tag;}GF_EXPORTu32 gf_node_get_id(GF_Node*p){	NodeIDedItem *reg_node;	GF_SceneGraph *sg; 	assert(p);	if (!(p->sgprivate->flags & GF_NODE_IS_DEF)) return 0;	sg = p->sgprivate->scenegraph;	/*if this is a proto, look in parent graph*/	if (p == (GF_Node*)sg->pOwningProto) sg = sg->parent_scene;	reg_node = sg->id_node;	while (reg_node) {		if (reg_node->node==p) return reg_node->NodeID;		reg_node = reg_node->next;	}	return 0;}GF_EXPORTconst char *gf_node_get_name(GF_Node*p){	GF_SceneGraph *sg; 	NodeIDedItem *reg_node;	assert(p);	if (!(p->sgprivate->flags & GF_NODE_IS_DEF)) return NULL;	sg = p->sgprivate->scenegraph;	/*if this is a proto, look in parent graph*/	if (p == (GF_Node*)sg->pOwningProto) sg = sg->parent_scene;	reg_node = sg->id_node;	while (reg_node) {		if (reg_node->node==p) return reg_node->NodeName;		reg_node = reg_node->next;	}	return NULL;}GF_EXPORTconst char *gf_node_get_name_and_id(GF_Node*p, u32 *id){	GF_SceneGraph *sg; 	NodeIDedItem *reg_node;	assert(p);	if (!(p->sgprivate->flags & GF_NODE_IS_DEF)) {		*id = 0;		return NULL;	}	sg = p->sgprivate->scenegraph;	/*if this is a proto, look in parent graph*/	if (p == (GF_Node*)sg->pOwningProto) sg = sg->parent_scene;	reg_node = sg->id_node;	while (reg_node) {		if (reg_node->node==p) {			*id = reg_node->NodeID;			return reg_node->NodeName;		}		reg_node = reg_node->next;	}	*id = 0;	return NULL;}GF_EXPORTvoid *gf_node_get_private(GF_Node*p){	assert(p);	return p->sgprivate->UserPrivate;}GF_EXPORTvoid gf_node_set_private(GF_Node*p, void *pr){	assert(p);	p->sgprivate->UserPrivate = pr;}GF_EXPORTGF_Err gf_node_set_callback_function(GF_Node *p, void (*RenderNode)(GF_Node *node, void *render_stack, Bool is_destroy) ){	assert(p);	p->sgprivate->UserCallback = RenderNode;	return GF_OK;}void gf_sg_parent_setup(GF_Node *node){	((GF_ParentNode *)node)->children = NULL;	node->sgprivate->flags |= GF_SG_CHILD_DIRTY;}GF_EXPORTvoid gf_node_unregister_children(GF_Node *container, GF_ChildNodeItem *child){	GF_ChildNodeItem *cur;	while (child) {		gf_node_unregister(child->node, container);		cur = child;		child = child->next;		free(cur);	}}GF_EXPORTGF_Err gf_node_list_insert_child(GF_ChildNodeItem **list, GF_Node *n, u32 pos){	GF_ChildNodeItem *child, *cur, *prev;	u32 cur_pos = 0;		assert(pos != (u32) -1);	child = *list;		cur = (GF_ChildNodeItem*) malloc(sizeof(GF_ChildNodeItem));	if (!cur) return GF_OUT_OF_MEM;	cur->node = n;	cur->next = NULL;	prev = NULL;	while (child) {		if (pos==cur_pos) break;		/*append*/		if (!child->next) {			child->next = cur;			return GF_OK;		}		prev = child;		child = child->next;		cur_pos++;	}	cur->next = child;	if (prev) prev->next = cur;	else *list = cur;	return GF_OK;}GF_EXPORTGF_Node *gf_node_list_get_child(GF_ChildNodeItem *list, s32 pos){	s32 cur_pos = 0;

⌨️ 快捷键说明

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