Esempio n. 1
0
void drawable_3d_base_traverse(GF_Node *n, void *rs, Bool is_destroy, void (*build_shape)(GF_Node*,Drawable3D *,GF_TraverseState *) )
{
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	Drawable3D *stack = (Drawable3D*)gf_node_get_private(n);

	if (is_destroy) {
		drawable_3d_del(n);
		return;
	}
	if (gf_node_dirty_get(n)) {
		mesh_reset(stack->mesh);
		GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Rebuilding mesh %s\n", gf_node_get_class_name(n)));
		build_shape(n, stack, tr_state);
		gf_node_dirty_clear(n, 0);
	}
	switch (tr_state->traversing_mode) {
	case TRAVERSE_DRAW_3D:
		visual_3d_draw(tr_state, stack->mesh);
		drawable3d_check_focus_highlight(n, tr_state, &stack->mesh->bounds);
		break;
	case TRAVERSE_GET_BOUNDS:
		tr_state->bbox = stack->mesh->bounds;
		break;
	case TRAVERSE_PICK:
		visual_3d_vrml_drawable_pick(n, tr_state, stack->mesh, NULL);
		return;
	}
}
Esempio n. 2
0
void V4SceneManager::CreateIDandAddToPool(GF_Node *node)
{
	// gets a node ID
	u32 id = gf_sg_get_next_available_node_id(GetSceneGraph());

	char d[10]; // supposes no more than 1 000 000 000 objects

	// queries the pool to know which number to use for the name
	itoa(pools.GetCount(gf_node_get_tag(node)), d, 10); 

	char c[50];
	strcpy(c, gf_node_get_class_name(node));
	strncat(c, "_", 1);
	strncat(c, d, 10);

	gf_node_set_id(node, id, c); // assigns NodeID and name
	pools.Add(node); // adds to the node pool

}
Esempio n. 3
0
static void svg2bifs_node_end(void *sax_cbck, const char *name, const char *name_space)
{
    SVG2BIFS_Converter *converter = (SVG2BIFS_Converter *)sax_cbck;
    GF_Node *parent;

    SVGPropertiesPointers *backup_props = gf_node_get_private(converter->svg_parent);
    memcpy(&converter->svg_props, backup_props, sizeof(SVGPropertiesPointers));
//	gf_free(backup_props);
    gf_node_set_private(converter->svg_parent, NULL);

    if (!(gf_node_get_tag(converter->svg_parent) == TAG_SVG_animateTransform))
        converter->bifs_parent = gf_node_get_parent(converter->bifs_parent, 0);
    parent = gf_node_get_parent(converter->svg_parent, 0);
    gf_node_unregister(converter->svg_parent, parent);
    if (!parent) gf_sg_set_root_node(converter->svg_sg, NULL);
    converter->svg_parent = parent;
    converter->bifs_text_node = NULL;

    fprintf(stdout, "END:\t%s\t%s\n", converter->svg_parent ? gf_node_get_class_name(converter->svg_parent) : "none", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none");
}
Esempio n. 4
0
static void StatNode(GF_SceneStatistics *stat, GF_Node *n, Bool isUsed, Bool isDelete, GF_Node *prev)
{
	u32 i;
	GF_NodeStats *ptr = NULL;
	if (!stat) return;

	if (n->sgprivate->tag == TAG_ProtoNode) {
#ifndef GPAC_DISABLE_VRML
		GF_ProtoInstance *pr = (GF_ProtoInstance *)n;
		i=0;
		while ((ptr = (GF_NodeStats *)gf_list_enum(stat->proto_stats, &i))) {
			if (pr->proto_interface->ID == ptr->tag) break;
			ptr = NULL;
		}
		if (!ptr) {
			GF_SAFEALLOC(ptr, GF_NodeStats);
			ptr->tag = pr->proto_interface->ID;
			ptr->name = gf_sg_proto_get_class_name(pr->proto_interface);
			gf_list_add(stat->proto_stats, ptr);
		}
#endif
	} else {
		i=0;
		while ((ptr = (GF_NodeStats *)gf_list_enum(stat->node_stats, &i))) {
			if (n->sgprivate->tag == ptr->tag) break;
			ptr = NULL;
		}
		if (!ptr) {
			GF_SAFEALLOC(ptr, GF_NodeStats);
			ptr->tag = n->sgprivate->tag;
			ptr->name = gf_node_get_class_name(n);
			gf_list_add(stat->node_stats, ptr);
		}
	}
	if (isDelete) ptr->nb_del += n->sgprivate->num_instances;
	else if (isUsed) ptr->nb_used += 1;
	/*this is because the node passes twice in the stat, once on DumpNode and once in replaceALL*/
	else ptr->nb_created += prev ? (prev->sgprivate->num_instances - 1) : 1;
}
Esempio n. 5
0
Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_state)
{
	u32 k, i, count, num_nodes, num_changed;
	GF_IRect refreshRect;
	Bool redraw_all;
	Bool hyb_force_redraw=GF_FALSE;
#ifndef GPAC_DISABLE_VRML
	M_Background2D *bck = NULL;
	DrawableContext *bck_ctx = NULL;
#endif
	DrawableContext *ctx;
	struct _drawable_store *it, *prev;
	DrawableContext *first_opaque = NULL;
	Bool has_clear = 0;
	Bool has_changed = 0;
	Bool redraw_all_on_background_change = GF_TRUE;

	/*in direct mode the visual is always redrawn*/
	if (tr_state->immediate_draw) {
		/*flush pending contexts due to overlays*/
		visual_2d_flush_overlay_areas(visual, tr_state);

		visual_2d_release_raster(visual);
		visual_clean_contexts(visual);
		visual->num_nodes_prev_frame = visual->num_nodes_current_frame;
		return 1;
	}

	num_changed = 0;

	/*if the aspect ratio has changed redraw everything*/
	redraw_all = tr_state->invalidate_all;

#ifndef GPAC_DISABLE_3D
	if (visual->compositor->hybrid_opengl && !visual->offscreen) redraw_all_on_background_change = GF_FALSE;
#endif
	/*check for background changes for transparent nodes*/
#ifndef GPAC_DISABLE_VRML
	bck = (M_Background2D*)gf_list_get(visual->back_stack, 0);
	if (bck) {
		if (!bck->isBound) {
			if (visual->last_had_back) {
				if (redraw_all_on_background_change) redraw_all = 1;
				else hyb_force_redraw = 1;
			}
			visual->last_had_back = 0;
		} else {
			bck_ctx = b2d_get_context(bck, visual->back_stack);
			if (!visual->last_had_back || (bck_ctx->flags & CTX_REDRAW_MASK) ) {
				if (redraw_all_on_background_change) redraw_all = 1;
				else hyb_force_redraw = 1;
			}
			visual->last_had_back = (bck_ctx->aspect.fill_texture && !bck_ctx->aspect.fill_texture->transparent) ? 2 : 1;
		}
	} else
#endif
		if (visual->last_had_back) {
			visual->last_had_back = 0;
			if (redraw_all_on_background_change) redraw_all = 1;
			else hyb_force_redraw = 1;
		}

	num_nodes = 0;
	ctx = visual->context;
	while (ctx && ctx->drawable) {
		num_nodes++;

		drawctx_update_info(ctx, visual);
		if (!redraw_all) {
			u32 res;
			assert( gf_irect_inside(&visual->top_clipper, &ctx->bi->clip) );
			res = register_context_rect(&visual->to_redraw, ctx, num_nodes, &first_opaque);
			if (res) {
				num_changed ++;
				if (res==2)
					hyb_force_redraw=GF_TRUE;
			}

		}
		ctx = ctx->next;
	}

	/*garbage collection*/

	/*clear all remaining bounds since last frames (the ones that moved or that are not drawn this frame)*/
	prev = NULL;
	it = visual->prev_nodes;
	while (it) {
		while (drawable_get_previous_bound(it->drawable, &refreshRect, visual)) {
			if (!redraw_all) {
				//assert( gf_irect_inside(&visual->top_clipper, &refreshRect) );
				gf_irect_intersect(&refreshRect, &visual->top_clipper);
				register_dirty_rect(&visual->to_redraw, &refreshRect);
				has_clear=1;
			}
		}
		/*if node is marked as undrawn, remove from visual*/
		if (!(it->drawable->flags & DRAWABLE_DRAWN_ON_VISUAL)) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Node %s no longer on visual - unregistering it\n", gf_node_get_class_name(it->drawable->node)));

			/*remove all bounds info related to this visual and unreg node */
			drawable_reset_bounds(it->drawable, visual);

			it->drawable->flags &= ~DRAWABLE_REGISTERED_WITH_VISUAL;

			if (it->drawable->flags & DRAWABLE_IS_OVERLAY) {
				visual->compositor->video_out->Blit(visual->compositor->video_out, NULL, NULL, NULL, 1);
			}

			if (prev) prev->next = it->next;
			else visual->prev_nodes = it->next;
			if (!it->next) visual->last_prev_entry = prev;
			gf_free(it);
			it = prev ? prev->next : visual->prev_nodes;
		} else {
			prev = it;
			it = it->next;
		}
	}

	if (redraw_all) {
		ra_clear(&visual->to_redraw);
		ra_add(&visual->to_redraw, &visual->surf_rect);
#ifdef TRACK_OPAQUE_REGIONS
		visual->to_redraw.list[0].opaque_node_index=0;
#endif
	} else {
		ra_refresh(&visual->to_redraw);

		if (visual->compositor->debug_defer) {
			visual->ClearSurface(visual, &visual->top_clipper, 0);
		}
	}

	/*nothing to redraw*/
	if (!hyb_force_redraw && ra_is_empty(&visual->to_redraw) ) {
#ifndef GPAC_DISABLE_3D
		//force canvas draw
		visual->nb_objects_on_canvas_since_last_ogl_flush = 1;
#endif
		GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] No changes found since last frame - skipping redraw\n"));
		goto exit;
	}
	has_changed = 1;
	tr_state->traversing_mode = TRAVERSE_DRAW_2D;

	if (first_opaque && (visual->to_redraw.count==1) && gf_rect_equal(first_opaque->bi->clip, visual->to_redraw.list[0].rect)) {
		visual->has_modif=0;
		goto skip_background;
	}

	/*redraw everything*/
#ifndef GPAC_DISABLE_VRML
	if (bck_ctx) {
		drawable_check_bounds(bck_ctx, visual);
		tr_state->ctx = bck_ctx;
		visual->draw_node_index = 0;

		/*force clearing entire zone, not just viewport, when using color. If texture, we MUST
		use the VP clipper in order to compute offsets when blitting bitmaps*/
		if (bck_ctx->aspect.fill_texture && bck_ctx->aspect.fill_texture->stream) {
			bck_ctx->bi->clip = visual->top_clipper;
		} else {
			bck_ctx->bi->clip = visual->surf_rect;
		}
		bck_ctx->bi->unclip = gf_rect_ft(&bck_ctx->bi->clip);
		bck_ctx->next = visual->context;
		bck_ctx->flags |= CTX_BACKROUND_NOT_LAYER;
		gf_node_traverse(bck_ctx->drawable->node, tr_state);
		bck_ctx->flags &= ~CTX_BACKROUND_NOT_LAYER;
	} else
#endif /*GPAC_DISABLE_VRML*/
	{
		count = visual->to_redraw.count;
		for (k=0; k<count; k++) {
			GF_IRect rc;
			/*opaque area, skip*/
#ifdef TRACK_OPAQUE_REGIONS
			if (visual->to_redraw.list[k].opaque_node_index > 0) continue;
#endif
			rc = visual->to_redraw.list[k].rect;
			visual->ClearSurface(visual, &rc, 0);
		}
#ifndef GPAC_DISABLE_3D
		if (!count && hyb_force_redraw) {
			compositor_2d_hybgl_clear_surface_ex(tr_state->visual, NULL, 0, GF_FALSE);
		}
#endif
	}
	if (!redraw_all && !has_clear) visual->has_modif=0;

skip_background:

#ifndef GPAC_DISABLE_LOG
	if (gf_log_tool_level_on(GF_LOG_COMPOSE, GF_LOG_INFO)) {
		GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("[Visual2D] Redraw %d / %d nodes (all: %s - %d dirty rects\n)", num_changed, num_nodes, redraw_all ? "yes" : "no", visual->to_redraw.count));
		if (visual->to_redraw.count>1) GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("\n"));

		for (i=0; i<visual->to_redraw.count; i++) {
			GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("\tDirtyRect #%d: %d:%d@%dx%d\n", i+1, visual->to_redraw.list[i].rect.x, visual->to_redraw.list[i].rect.y, visual->to_redraw.list[i].rect.width, visual->to_redraw.list[i].rect.height));
			assert(visual->to_redraw.list[i].rect.width);
		}
	}
#endif

	visual->draw_node_index = 0;

	ctx = visual->context;
	while (ctx && ctx->drawable) {

		visual->draw_node_index ++;
		tr_state->ctx = ctx;

		/*if overlay we cannot remove the context and cannot draw directly*/
		if (! visual_2d_overlaps_overlay(tr_state->visual, ctx, tr_state)) {

			if (ctx->drawable->flags & DRAWABLE_USE_TRAVERSE_DRAW) {
				gf_node_traverse(ctx->drawable->node, tr_state);
			} else {
				drawable_draw(ctx->drawable, tr_state);
			}
		}
		ctx = ctx->next;
	}
	/*flush pending contexts due to overlays*/
	visual_2d_flush_overlay_areas(visual, tr_state);
#ifndef GPAC_DISABLE_VRML
	if (bck_ctx) bck_ctx->next = NULL;
#endif

	if (visual->direct_flush) {
		GF_DirtyRectangles dr;
		u32 i;
		dr.count = visual->to_redraw.count;
		dr.list = gf_malloc(sizeof(GF_IRect)*dr.count);
		for (i=0; i<dr.count; i++) {
			dr.list[i] = visual->to_redraw.list[i].rect;
		}
		visual->compositor->video_out->FlushRectangles(visual->compositor->video_out, &dr);
		visual->compositor->skip_flush=1;
		gf_free(dr.list);
	}

exit:
	/*clear dirty rects*/
	ra_clear(&visual->to_redraw);
	visual_2d_release_raster(visual);
	visual_clean_contexts(visual);
	visual->num_nodes_prev_frame = visual->num_nodes_current_frame;
	return has_changed;
}
Esempio n. 6
0
GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state)
{
	GF_Err e;
	u32 rem, count;
	struct _drawable_store *it, *prev;
#ifndef GPAC_DISABLE_VRML
	DrawableContext *ctx;
	M_Background2D *bck;
#endif
	u32 draw_mode;

	/*reset display list*/
	visual->cur_context = visual->context;
	if (visual->context) visual->context->drawable = NULL;
	visual->has_modif = 0;
	visual->has_overlays = 0;

	visual_2d_setup_projection(visual, tr_state);
	if (!visual->top_clipper.width || !visual->top_clipper.height)
		return GF_OK;

	tr_state->traversing_mode = TRAVERSE_SORT;
	visual->num_nodes_current_frame = 0;

	/*setup raster surface, brush and pen */
	e = visual_2d_init_raster(visual);
	if (e)
		return e;

	draw_mode = 0;
	if (tr_state->immediate_draw) draw_mode = 1;
	/*if we're requested to invalidate everything, switch to direct drawing but don't reset bounds*/
	else if (tr_state->invalidate_all) {
		tr_state->immediate_draw = 1;
		draw_mode = 2;
	}
	tr_state->invalidate_all = 0;

	/*reset prev nodes if any (previous traverse was indirect)*/
	rem = count = 0;
	prev = NULL;
	it = visual->prev_nodes;
	while (it) {
		/*node was not drawn on this visual*/
		if (!drawable_flush_bounds(it->drawable, visual, draw_mode)) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Unregistering previously drawn node %s from visual\n", gf_node_get_class_name(it->drawable->node)));

			/*remove all bounds info related to this visual and unreg node */
			drawable_reset_bounds(it->drawable, visual);

			if (prev) prev->next = it->next;
			else visual->prev_nodes = it->next;
			if (!it->next) visual->last_prev_entry = prev;
			rem++;
			gf_free(it);
			it = prev ? prev->next : visual->prev_nodes;
		} else {
			/*mark drawable as already registered with visual*/
			it->drawable->flags |= DRAWABLE_REGISTERED_WITH_VISUAL;
			prev = it;
			it = it->next;
			count++;
		}
	}
	GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Top visual initialized - %d nodes registered and %d removed - using %s rendering\n", count, rem, draw_mode ? "direct" : "dirty-rect"));
	if (!draw_mode) return GF_OK;

#ifndef GPAC_DISABLE_VRML
	/*direct mode, draw background*/
	bck = (M_Background2D*) gf_list_get(visual->back_stack, 0);
	if (bck && bck->isBound) {
		ctx = b2d_get_context(bck, visual->back_stack);
		if (ctx) {
			/*force clearing entire zone, not just viewport, when using color. If texture, we MUST
			use the VP clipper in order to compute offsets when blitting bitmaps*/
			if (ctx->aspect.fill_texture &&ctx->aspect.fill_texture->stream) {
				ctx->bi->clip = visual->top_clipper;
			} else {
				ctx->bi->clip = visual->surf_rect;
			}
			ctx->bi->unclip = gf_rect_ft(&ctx->bi->clip);
			tr_state->traversing_mode = TRAVERSE_BINDABLE;
			ctx->flags |= CTX_BACKROUND_NOT_LAYER;
			gf_node_traverse((GF_Node *) bck, tr_state);
			tr_state->traversing_mode = TRAVERSE_SORT;
			ctx->flags &= ~CTX_BACKROUND_NOT_LAYER;
		} else {
			visual->ClearSurface(visual, NULL, 0);
		}
	} else
#endif
	{
		visual->ClearSurface(visual, NULL, 0);
	}
	return GF_OK;
}
Esempio n. 7
0
GF_Err gf_bifs_enc_node(GF_BifsEncoder * codec, GF_Node *node, u32 NDT_Tag, GF_BitStream *bs, GF_Node *parent_node)
{
	u32 NDTBits, node_type, node_tag, BVersion, node_id;
	const char *node_name;
	Bool flag, reset_qp14;
	GF_Node *new_node;
	GF_Err e;

	assert(codec->info);
	GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[BIFS] Encode node %s\n", gf_node_get_class_name(node) ));

	/*NULL node is a USE of maxID*/
	if (!node) {
		GF_BIFS_WRITE_INT(codec, bs, 1, 1, "USE", NULL);
		GF_BIFS_WRITE_INT(codec, bs, (1<<codec->info->config.NodeIDBits) - 1 , codec->info->config.NodeIDBits, "NodeID", "NULL");
		return GF_OK;
	}

	flag = BE_NodeIsUSE(codec, node);
	GF_BIFS_WRITE_INT(codec, bs, flag ? 1 : 0, 1, "USE", (char*)gf_node_get_class_name(node));

	if (flag) {
		gf_bs_write_int(bs, gf_node_get_id(node) - 1, codec->info->config.NodeIDBits);
		new_node = gf_bifs_enc_find_node(codec, gf_node_get_id(node) );
		if (!new_node)
			return codec->LastError = GF_SG_UNKNOWN_NODE;

		/*restore QP14 length*/
		switch (gf_node_get_tag(new_node)) {
		case TAG_MPEG4_Coordinate:
		{
			u32 nbCoord = ((M_Coordinate *)new_node)->point.count;
			gf_bifs_enc_qp14_enter(codec, GF_TRUE);
			gf_bifs_enc_qp14_set_length(codec, nbCoord);
			gf_bifs_enc_qp14_enter(codec, GF_FALSE);
		}
		break;
		case TAG_MPEG4_Coordinate2D:
		{
			u32 nbCoord = ((M_Coordinate2D *)new_node)->point.count;
			gf_bifs_enc_qp14_enter(codec, GF_TRUE);
			gf_bifs_enc_qp14_set_length(codec, nbCoord);
			gf_bifs_enc_qp14_enter(codec, GF_FALSE);
		}
		break;
		}
		return GF_OK;
	}

	BVersion = GF_BIFS_V1;
	node_tag = node->sgprivate->tag;
	while (1) {
		node_type = gf_bifs_get_node_type(NDT_Tag, node_tag, BVersion);
		NDTBits = gf_bifs_get_ndt_bits(NDT_Tag, BVersion);
		if (BVersion==2 && (node_tag==TAG_ProtoNode)) node_type = 1;
		GF_BIFS_WRITE_INT(codec, bs, node_type, NDTBits, "ndt", NULL);
		if (node_type) break;

		BVersion += 1;
		if (BVersion > GF_BIFS_NUM_VERSION) {
			if (parent_node) {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s as a child of %s\n", gf_node_get_class_name(node), gf_node_get_class_name(parent_node) ));
			} else {
				GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[BIFS] Cannot encode node %s in the SFWorldNode context\n", gf_node_get_class_name(node) ));
			}
			return codec->LastError = GF_BIFS_UNKNOWN_VERSION;
		}
	}
	if (BVersion==2 && node_type==1) {
		GF_Proto *proto = ((GF_ProtoInstance *)node)->proto_interface;
		GF_BIFS_WRITE_INT(codec, bs, proto->ID, codec->info->config.ProtoIDBits, "protoID", NULL);
	}

	/*special handling of 3D mesh*/

	/*DEF'd node*/
	node_name = gf_node_get_name_and_id(node, &node_id);
	GF_BIFS_WRITE_INT(codec, bs, node_id ? 1 : 0, 1, "DEF", NULL);
	if (node_id) {
		GF_BIFS_WRITE_INT(codec, bs, node_id - 1, codec->info->config.NodeIDBits, "NodeID", NULL);
		if (codec->UseName) gf_bifs_enc_name(codec, bs, (char*) node_name );
	}

	/*no updates of time fields for now - NEEDED FOR A LIVE ENCODER*/

	/*if coords were not stored for QP14 before coding this node, reset QP14 it when leaving*/
	reset_qp14 = !codec->coord_stored;

	/*QP14 case*/
	switch (node_tag) {
	case TAG_MPEG4_Coordinate:
	case TAG_MPEG4_Coordinate2D:
		gf_bifs_enc_qp14_enter(codec, GF_TRUE);
	}

	e = EncNodeFields(codec, bs, node);
	if (e) return e;

	if (codec->coord_stored && reset_qp14)
		gf_bifs_enc_qp14_reset(codec);

	switch (node_tag) {
	case TAG_MPEG4_Coordinate:
	case TAG_MPEG4_Coordinate2D:
		gf_bifs_enc_qp14_enter(codec, GF_FALSE);
		break;
	}
	return GF_OK;
}
Esempio n. 8
0
static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes)
{
    u32 i;
    SVG2BIFS_Converter *converter = (SVG2BIFS_Converter *)sax_cbck;
    SVGPropertiesPointers *backup_props;
    char *id_string = NULL;
    u32	tag;
    SVG_Element *elt;
    SVG_DeferedAnimation *anim = NULL;

    tag = gf_xml_get_element_tag(name, 0);
    elt = (SVG_Element*)gf_node_new(converter->svg_sg, tag);
    if (!gf_sg_get_root_node(converter->svg_sg)) {
        gf_node_register((GF_Node *)elt, NULL);
        gf_sg_set_root_node(converter->svg_sg, (GF_Node *)elt);
    } else {
        gf_node_register((GF_Node *)elt, converter->svg_parent);
        //gf_node_list_add_child(&((GF_ParentNode*)converter->svg_parent)->children, (GF_Node *)elt);
    }

//	fprintf(stdout, "Converting %s\n", gf_node_get_class_name((GF_Node *)elt));
//	if (converter->bifs_parent) fprintf(stdout, "%s\n", gf_node_get_class_name(converter->bifs_parent));

    if (gf_svg_is_animation_tag(tag)) {
        GF_SAFEALLOC(anim, SVG_DeferedAnimation);
        /*default anim target is parent node*/
        anim->animation_elt = elt;
        if (converter->svg_parent) {
            anim->target = anim->anim_parent = (SVG_Element*) converter->svg_parent;
        }
    }

    for (i=0; i<nb_attributes; i++) {
        GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i];
        if (!att->value || !strlen(att->value)) continue;

        if (!stricmp(att->name, "style")) {
            gf_svg_parse_style((GF_Node *)elt, att->value);
        } else if (!stricmp(att->name, "id") || !stricmp(att->name, "xml:id")) {
            gf_svg_parse_element_id((GF_Node *)elt, att->value, 0);
            id_string = att->value;
        } else if (anim && !stricmp(att->name, "to")) {
            anim->to = gf_strdup(att->value);
        } else if (anim && !stricmp(att->name, "from")) {
            anim->from = gf_strdup(att->value);
        } else if (anim && !stricmp(att->name, "by")) {
            anim->by = gf_strdup(att->value);
        } else if (anim && !stricmp(att->name, "values")) {
            anim->values = gf_strdup(att->value);
        } else if (anim && (tag == TAG_SVG_animateTransform) && !stricmp(att->name, "type")) {
            anim->type = gf_strdup(att->value);
        } else {
            GF_FieldInfo info;
            if (gf_node_get_field_by_name((GF_Node *)elt, att->name, &info)==GF_OK) {
                gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0);
            } else {
                fprintf(stdout, "Skipping attribute %s\n", att->name);
            }
        }
    }

    if (anim) {
        svg_parse_animation(converter->svg_sg, anim);
    }

    memset(&converter->all_atts, 0, sizeof(SVGAllAttributes));
    gf_svg_flatten_attributes(elt, &converter->all_atts);

    backup_props = gf_malloc(sizeof(SVGPropertiesPointers));
    memcpy(backup_props, &converter->svg_props, sizeof(SVGPropertiesPointers));
    gf_node_set_private((GF_Node *)elt, backup_props);

    gf_svg_apply_inheritance(&converter->all_atts, &converter->svg_props);

    fprintf(stdout, "START\t%s\t%s\t%s", converter->svg_parent ? gf_node_get_class_name(converter->svg_parent) : "none", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none", name);
    converter->svg_parent = (GF_Node *)elt;
    if (!gf_sg_get_root_node(converter->bifs_sg)) {
        if (tag == TAG_SVG_svg) {
            GF_Node *node, *child;

            converter->bifs_sg->usePixelMetrics = 1;
            if (converter->all_atts.width && converter->all_atts.width->type == SVG_NUMBER_VALUE) {
                converter->bifs_sg->width = FIX2INT(converter->all_atts.width->value);
            } else {
                converter->bifs_sg->width = 320;
            }
            if (converter->all_atts.height && converter->all_atts.height->type == SVG_NUMBER_VALUE) {
                converter->bifs_sg->height = FIX2INT(converter->all_atts.height->value);
            } else {
                converter->bifs_sg->height = 200;
            }

            node = gf_node_new(converter->bifs_sg, TAG_MPEG4_OrderedGroup);
            gf_node_register(node, NULL);
            gf_sg_set_root_node(converter->bifs_sg, node);

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_QuantizationParameter);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_QuantizationParameter *qp = (M_QuantizationParameter *)child;
                qp->useEfficientCoding = 1;
            }

            /* SVG to BIFS coordinate transformation */
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Viewport);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_Viewport *vp = (M_Viewport*)child;
                if (converter->all_atts.viewBox) {
                    vp->size.x = converter->all_atts.viewBox->width;
                    vp->size.y = converter->all_atts.viewBox->height;
                    vp->position.x = converter->all_atts.viewBox->x+converter->all_atts.viewBox->width/2;
                    vp->position.y = -(converter->all_atts.viewBox->y+converter->all_atts.viewBox->height/2);
                } else {
                    vp->size.x = INT2FIX(converter->bifs_sg->width);
                    vp->size.y = INT2FIX(converter->bifs_sg->height);
                    vp->position.x = INT2FIX(converter->bifs_sg->width)/2;
                    vp->position.y = -INT2FIX(converter->bifs_sg->height)/2;
                }
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Background2D);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_Background2D *b = (M_Background2D *)child;
                b->backColor.red = FIX_ONE;
                b->backColor.green = FIX_ONE;
                b->backColor.blue = FIX_ONE;
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            {
                M_Transform2D *tr = (M_Transform2D *)node;
                tr->scale.y = -FIX_ONE;
            }
            converter->bifs_parent = node;
        }
    } else {
        GF_Node *node, *child;

        node = converter->bifs_parent;

        switch(tag) {
        case TAG_SVG_g:
        {
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
            } else {
                M_Group *g = (M_Group*)gf_node_new(converter->bifs_sg, TAG_MPEG4_Group);
                gf_node_register((GF_Node *)g, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, (GF_Node *)g);
                node = (GF_Node *)g;
                converter->bifs_parent = node;
            }
        }
        break;
        case TAG_SVG_rect:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            if (converter->all_atts.x || converter->all_atts.y) {
                child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
                gf_node_register(child, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
                node = child;
                child = NULL;
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
                {
                    M_Transform2D *tr = (M_Transform2D *)node;
                    if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value + (converter->all_atts.width?converter->all_atts.width->value/2:0);
                    if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value + (converter->all_atts.height?converter->all_atts.height->value/2:0);
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_Rectangle);
                gf_node_register(shape->geometry, (GF_Node *)shape);
                {
                    M_Rectangle *rect = (M_Rectangle *)shape->geometry;
                    if (converter->all_atts.width) rect->size.x = converter->all_atts.width->value;
                    if (converter->all_atts.height) rect->size.y = converter->all_atts.height->value;
                }

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_path:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            if (converter->all_atts.x || converter->all_atts.y) {
                child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
                gf_node_register(child, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
                node = child;
                child = NULL;
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
                {
                    M_Transform2D *tr = (M_Transform2D *)node;
                    if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value;
                    if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value;
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_XCurve2D);
                gf_node_register(shape->geometry, (GF_Node *)shape);
                if (converter->all_atts.d) {
                    M_Coordinate2D *c2d;
                    M_XCurve2D *xc = (M_XCurve2D *)shape->geometry;
                    u32 i, j, c, k;

                    xc->point = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
                    c2d = (M_Coordinate2D *)xc->point;
                    gf_node_register(xc->point, (GF_Node *)xc);

                    gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, converter->all_atts.d->n_points);
                    gf_sg_vrml_mf_alloc(&xc->type, GF_SG_VRML_MFINT32, converter->all_atts.d->n_points);

                    c = 0;
                    k = 0;
                    j = 0;
                    c2d->point.vals[k] = converter->all_atts.d->points[0];
                    k++;
                    xc->type.vals[0] = 0;
                    for (i = 1; i < converter->all_atts.d->n_points; ) {
                        switch(converter->all_atts.d->tags[i]) {
                        case GF_PATH_CURVE_ON:
                            c2d->point.vals[k] = converter->all_atts.d->points[i];
                            k++;

                            if (i-1 == converter->all_atts.d->contours[c]) {
                                xc->type.vals[j] = 0;
                                c++;
                            } else {
                                xc->type.vals[j] = 1;
                            }
                            i++;
                            break;
                        case GF_PATH_CURVE_CUBIC:
                            c2d->point.vals[k] = converter->all_atts.d->points[i];
                            c2d->point.vals[k+1] = converter->all_atts.d->points[i+1];
                            c2d->point.vals[k+2] = converter->all_atts.d->points[i+2];
                            k+=3;

                            xc->type.vals[j] = 2;
                            if (converter->all_atts.d->tags[i+2]==GF_PATH_CLOSE)  {
                                j++;
                                xc->type.vals[j] = 6;
                            }
                            i+=3;
                            break;
                        case GF_PATH_CLOSE:
                            xc->type.vals[j] = 6;
                            i++;
                            break;
                        case GF_PATH_CURVE_CONIC:
                            c2d->point.vals[k] = converter->all_atts.d->points[i];
                            c2d->point.vals[k+1] = converter->all_atts.d->points[i+1];
                            k+=2;

                            xc->type.vals[j] = 7;
                            if (converter->all_atts.d->tags[i+1]==GF_PATH_CLOSE)  {
                                j++;
                                xc->type.vals[j] = 6;
                            }
                            i+=2;
                            break;
                        }
                        j++;
                    }
                    xc->type.count = j;
                    c2d->point.count = k;
                }

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_polyline:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_IndexedFaceSet2D);
                gf_node_register(shape->geometry, (GF_Node *)shape);
                if (converter->all_atts.points) {
                    M_Coordinate2D *c2d;
                    M_IndexedFaceSet2D *ifs = (M_IndexedFaceSet2D *)shape->geometry;
                    u32 i;

                    ifs->coord = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
                    c2d = (M_Coordinate2D *)ifs->coord;
                    gf_node_register(ifs->coord, (GF_Node *)ifs);

                    gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, gf_list_count(*converter->all_atts.points));
                    for (i = 0; i < gf_list_count(*converter->all_atts.points); i++) {
                        SVG_Point *p = (SVG_Point *)gf_list_get(*converter->all_atts.points, i);
                        c2d->point.vals[i].x = p->x;
                        c2d->point.vals[i].y = p->y;
                    }
                }

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_text:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            {
                M_Transform2D *tr = (M_Transform2D *)child;
                if (converter->all_atts.text_x) tr->translation.x = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_x, 0))->value;
                if (converter->all_atts.text_y) tr->translation.y = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_y, 0))->value;
                tr->scale.y = -FIX_ONE;
            }
            node = child;
            child = NULL;
            if (!is_parent_set) {
                converter->bifs_parent = node;
                is_parent_set = 1;
            }

            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_FontStyle *fs;
                M_Text *text;
                M_Shape *shape = (M_Shape *)node;
                text = (M_Text *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Text);
                shape->geometry = (GF_Node *)text;
                converter->bifs_text_node = shape->geometry;
                gf_node_register(shape->geometry, (GF_Node *)shape);

                fs = (M_FontStyle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_XFontStyle);
                gf_node_register((GF_Node *)fs, (GF_Node*)text);
                text->fontStyle = (GF_Node *)fs;

                gf_sg_vrml_mf_alloc(&fs->family, GF_SG_VRML_MFSTRING, 1);
                fs->family.vals[0] = gf_strdup(converter->svg_props.font_family->value);
                fs->size = converter->svg_props.font_size->value;

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;
        case TAG_SVG_ellipse:
        case TAG_SVG_circle:
        {
            Bool is_parent_set = 0;
            if (converter->all_atts.transform) {
                node = add_transform_matrix(converter, node);
                converter->bifs_parent = node;
                is_parent_set = 1;
            }
            if (converter->force_transform) {
                node = add_transform2d(converter, node);
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            if (converter->all_atts.cx || converter->all_atts.cy) {
                child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
                gf_node_register(child, node);
                gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
                {
                    M_Transform2D *tr = (M_Transform2D *)child;
                    if (converter->all_atts.cx) tr->translation.x = converter->all_atts.cx->value;
                    if (converter->all_atts.cy) tr->translation.y = converter->all_atts.cy->value;
                }
                node = child;
                child = NULL;
                if (!is_parent_set) {
                    converter->bifs_parent = node;
                    is_parent_set = 1;
                }
            }
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            if (!is_parent_set) converter->bifs_parent = node;
            {
                M_Shape *shape = (M_Shape *)node;
                if (tag == TAG_SVG_ellipse) {
                    M_Ellipse *e = (M_Ellipse *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Ellipse);
                    shape->geometry = (GF_Node *)e;
                    e->radius.x = converter->all_atts.rx->value;
                    e->radius.y = converter->all_atts.ry->value;
                } else {
                    M_Circle *c = (M_Circle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Circle);
                    shape->geometry = (GF_Node *)c;
                    c->radius = converter->all_atts.r->value;
                }
                gf_node_register(shape->geometry, (GF_Node *)shape);

                shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
                gf_node_register(shape->appearance, (GF_Node *)shape);
            }
        }
        break;

        case TAG_SVG_defs:
        {
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Switch);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            {
                M_Switch *sw = (M_Switch *)node;
                sw->whichChoice = -1;
            }
            converter->bifs_parent = node;
        }
        break;
        case TAG_SVG_solidColor:
        {
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
            gf_node_register(child, node);
            gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            converter->bifs_parent = node;
        }
        break;
        case TAG_SVG_animateTransform:
        {
            GF_Node *child_ts;
            if (!gf_node_get_id(node)) {
                gf_node_set_id(node, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
            }

            child_ts = gf_node_new(converter->bifs_sg, TAG_MPEG4_TimeSensor);
            if (!gf_node_get_id(child_ts)) {
                gf_node_set_id(child_ts, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
            }
            gf_node_register(child_ts, node);
            gf_node_list_add_child(&((GF_ParentNode *)node)->children, child_ts);
            {
                M_TimeSensor *ts = (M_TimeSensor *)child_ts;
                if (converter->all_atts.dur) {
                    ts->cycleInterval = converter->all_atts.dur->clock_value;
                }
                if (converter->all_atts.repeatCount && converter->all_atts.repeatCount->type == SMIL_REPEATCOUNT_INDEFINITE) {
                    ts->loop = 1;
                }
            }

            if (converter->all_atts.transform_type) {
                GF_FieldInfo fromField, toField;

                switch (*converter->all_atts.transform_type) {
                case SVG_TRANSFORM_ROTATE:
                    child = gf_node_new(converter->bifs_sg, TAG_MPEG4_PositionInterpolator2D);
                    if (!gf_node_get_id(child)) {
                        gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
                    }
                    gf_node_register(child, node);
                    gf_node_list_add_child(&((GF_ParentNode *)node)->children, child);

                    gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField);
                    gf_node_get_field_by_name(child, "set_fraction", &toField);
                    gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex);

                    gf_node_get_field_by_name(child, "value_changed", &fromField);
                    gf_node_get_field_by_name(node, "rotationAngle", &toField);
                    gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex);
                    {
                        M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child;
                        if (converter->all_atts.keyTimes) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(*converter->all_atts.keyTimes);
                            for (i = 0; i < count; i++) {
                                Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i);
                                gf_sg_vrml_mf_append(&pi2d->key, GF_SG_VRML_MFFLOAT, &g);
                                *g = *f;
                            }
                        }
                        if (converter->all_atts.values) {
                            SFVec2f *g;
                            u32 count, i;
                            count = gf_list_count(converter->all_atts.values->values);
                            for (i = 0; i < count; i++) {
                                SVG_Point_Angle *p;
                                p = gf_list_get(converter->all_atts.values->values, i);
                                gf_sg_vrml_mf_append(&pi2d->keyValue, GF_SG_VRML_MFVEC2F, &g);
                                g->x = p->x;
                                g->y = p->y;
                            }
                        }
                    }


                    child = gf_node_new(converter->bifs_sg, TAG_MPEG4_ScalarInterpolator);
                    if (!gf_node_get_id(child)) {
                        gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
                    }
                    gf_node_register(child, node);
                    gf_node_list_add_child(&((GF_ParentNode *)node)->children, child);

                    gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField);
                    gf_node_get_field_by_name(child, "set_fraction", &toField);
                    gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex);

                    gf_node_get_field_by_name(child, "value_changed", &fromField);
                    gf_node_get_field_by_name(node, "center", &toField);
                    gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex);

                    {
                        M_ScalarInterpolator *si = (M_ScalarInterpolator *)child;
                        if (converter->all_atts.keyTimes) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(*converter->all_atts.keyTimes);
                            for (i = 0; i < count; i++) {
                                Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i);
                                gf_sg_vrml_mf_append(&si->key, GF_SG_VRML_MFFLOAT, &g);
                                *g = *f;
                            }
                        }
                        if (converter->all_atts.values) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(converter->all_atts.values->values);
                            for (i = 0; i < count; i++) {
                                SVG_Point_Angle *p;
                                p = gf_list_get(converter->all_atts.values->values, i);
                                gf_sg_vrml_mf_append(&si->keyValue, GF_SG_VRML_MFFLOAT, &g);
                                *g = p->angle;
                            }
                        }
                    }

                    break;

                case SVG_TRANSFORM_SCALE:
                case SVG_TRANSFORM_TRANSLATE:
                    child = gf_node_new(converter->bifs_sg, TAG_MPEG4_PositionInterpolator2D);
                    if (!gf_node_get_id(child)) {
                        gf_node_set_id(child, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);
                    }
                    gf_node_register(child, node);
                    gf_node_list_add_child(&((GF_ParentNode *)node)->children, child);

                    gf_node_get_field_by_name(child_ts, "fraction_changed", &fromField);
                    gf_node_get_field_by_name(child, "set_fraction", &toField);
                    gf_sg_route_new(converter->bifs_sg, child_ts, fromField.fieldIndex, child, toField.fieldIndex);

                    gf_node_get_field_by_name(child, "value_changed", &fromField);
                    if (*converter->all_atts.transform_type == SVG_TRANSFORM_SCALE)
                        gf_node_get_field_by_name(node, "scale", &toField);
                    else
                        gf_node_get_field_by_name(node, "translation", &toField);

                    gf_sg_route_new(converter->bifs_sg, child, fromField.fieldIndex, node, toField.fieldIndex);
                    {
                        M_PositionInterpolator2D *pi2d = (M_PositionInterpolator2D *)child;
                        if (converter->all_atts.keyTimes) {
                            SFFloat *g;
                            u32 count, i;
                            count = gf_list_count(*converter->all_atts.keyTimes);
                            for (i = 0; i < count; i++) {
                                Fixed *f = gf_list_get(*converter->all_atts.keyTimes, i);
                                gf_sg_vrml_mf_append(&pi2d->key, GF_SG_VRML_MFFLOAT, &g);
                                *g = *f;
                            }
                        }
                        if (converter->all_atts.values) {
                            SFVec2f *g;
                            u32 count, i;
                            count = gf_list_count(converter->all_atts.values->values);
                            for (i = 0; i < count; i++) {
                                SVG_Point *p;
                                p = gf_list_get(converter->all_atts.values->values, i);
                                gf_sg_vrml_mf_append(&pi2d->keyValue, GF_SG_VRML_MFVEC2F, &g);
                                g->x = p->x;
                                g->y = p->y;
                            }
                        }
                    }
                    break;
                default:
                    fprintf(stdout, "Warning: transformation type not supported \n");
                }
            }
            //converter->bifs_parent = node;
        }
        break;
        default:
        {
            fprintf(stdout, "Warning: element %s not supported \n", gf_node_get_class_name((GF_Node *)elt));
            child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
            gf_node_register(child, node);
            //gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
            node = child;
            child = NULL;
            converter->bifs_parent = node;
        }
        break;
        }

        if (id_string)
            gf_node_set_id(converter->bifs_parent, gf_sg_get_next_available_node_id(converter->bifs_sg), NULL);//gf_node_get_name((GF_Node *)elt));

    }
    fprintf(stdout, "\t%s\n", converter->bifs_parent ? gf_node_get_class_name(converter->bifs_parent) : "none");
}
static void visual_2d_fill_path(GF_VisualManager *visual, DrawableContext *ctx, GF_STENCIL stencil, GF_TraverseState *tr_state, Bool is_erase)
{
	Bool has_modif = GF_FALSE;
	GF_IRect clip;
	GF_Raster2D *raster = visual->compositor->rasterizer;

	/*background & direct drawing : use ctx clip*/
	if ((ctx->flags & CTX_IS_BACKGROUND) || tr_state->immediate_draw) {
		if (ctx->bi->clip.width && ctx->bi->clip.height) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (direct draw)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node) ));

			if (stencil) {
				raster->surface_set_clipper(visual->raster_surface, &ctx->bi->clip);
				raster->surface_fill(visual->raster_surface, stencil);
			} else {
				raster->surface_clear(visual->raster_surface, &ctx->bi->clip, 0);
			}

			has_modif = GF_TRUE;
		}
	}
	/*indirect drawing, draw path in all dirty areas*/
	else {
		u32 i;
		for (i=0; i<visual->to_redraw.count; i++) {
			/*there's an opaque region above, don't draw*/
#ifdef TRACK_OPAQUE_REGIONS
			if (!is_erase && (visual->draw_node_index<visual->to_redraw.list[i].opaque_node_index)) continue;
#endif
			clip = ctx->bi->clip;
			gf_irect_intersect(&clip, &visual->to_redraw.list[i].rect);
			if (clip.width && clip.height) {
				GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (indirect draw @ dirty rect idx %d)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node), i));
				if (stencil) {
					raster->surface_set_clipper(visual->raster_surface, &clip);
					raster->surface_fill(visual->raster_surface, stencil);
				} else {
					raster->surface_clear(visual->raster_surface, &clip, 0);
				}
				has_modif = 1;
			}
		}
	}
#ifndef GPAC_DISABLE_3D
	if (!is_erase)
		visual->nb_objects_on_canvas_since_last_ogl_flush++;
#endif
	if (has_modif) {
		visual->has_modif = 1;
#ifndef GPAC_DISABLE_3D
		if (!visual->offscreen && visual->compositor->hybrid_opengl && !is_erase)
			ra_union_rect(&visual->hybgl_drawn, &ctx->bi->clip);
#endif
	}
}
Esempio n. 10
0
void gf_sc_on_node_init(GF_Compositor *compositor, GF_Node *node)
{
	switch (gf_node_get_tag(node)) {
#ifndef GPAC_DISABLE_VRML
	case TAG_MPEG4_AnimationStream: compositor_init_animationstream(compositor, node); break;
	case TAG_MPEG4_AudioBuffer: compositor_init_audiobuffer(compositor, node); break;
	case TAG_MPEG4_AudioSource: compositor_init_audiosource(compositor, node); break;
	case TAG_MPEG4_AudioClip:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_AudioClip:
#endif
		compositor_init_audioclip(compositor, node); break;
	case TAG_MPEG4_TimeSensor:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_TimeSensor:
#endif
		compositor_init_timesensor(compositor, node); break;
	case TAG_MPEG4_ImageTexture:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_ImageTexture:
#endif
	case TAG_MPEG4_CacheTexture:
		compositor_init_imagetexture(compositor, node); break;

	case TAG_MPEG4_PixelTexture:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_PixelTexture:
#endif
		compositor_init_pixeltexture(compositor, node); break;
	case TAG_MPEG4_MovieTexture:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_MovieTexture:
#endif
		compositor_init_movietexture(compositor, node); break;

	case TAG_MPEG4_Background2D: compositor_init_background2d(compositor, node); break;
	case TAG_MPEG4_Bitmap: compositor_init_bitmap(compositor, node); break;
	case TAG_MPEG4_ColorTransform: compositor_init_colortransform(compositor, node); break;
	case TAG_MPEG4_Circle: compositor_init_circle(compositor, node); break;
	case TAG_MPEG4_Curve2D: compositor_init_curve2d(compositor, node); break;
	case TAG_MPEG4_XCurve2D: compositor_init_curve2d(compositor, node); break;
	case TAG_MPEG4_Ellipse: compositor_init_ellipse(compositor, node); break;
	case TAG_MPEG4_OrderedGroup: compositor_init_orderedgroup(compositor, node); break;
	case TAG_MPEG4_PointSet2D: compositor_init_pointset2d(compositor, node); break;
	case TAG_MPEG4_Transform2D: compositor_init_transform2d(compositor, node); break;
	case TAG_MPEG4_TransformMatrix2D: compositor_init_transformmatrix2d(compositor, node); break;
	case TAG_MPEG4_LineProperties: compositor_init_lineprops(compositor, node); break;
	case TAG_MPEG4_XLineProperties: compositor_init_lineprops(compositor, node); break;
	case TAG_MPEG4_Viewport: compositor_init_viewport(compositor, node); break;

	case TAG_MPEG4_IndexedLineSet2D: compositor_init_indexed_line_set2d(compositor, node); break;
	case TAG_MPEG4_IndexedFaceSet2D: compositor_init_indexed_face_set2d(compositor, node); break;

	case TAG_MPEG4_Sound2D: compositor_init_sound2d(compositor, node); break;

	case TAG_MPEG4_LinearGradient: compositor_init_linear_gradient(compositor, node); break;
	case TAG_MPEG4_RadialGradient: compositor_init_radial_gradient(compositor, node); break;

	case TAG_MPEG4_CompositeTexture2D: compositor_init_compositetexture2d(compositor, node); break;
	case TAG_MPEG4_MatteTexture: compositor_init_mattetexture(compositor, node); break;

	case TAG_MPEG4_Form: compositor_init_form(compositor, node); break;
	case TAG_MPEG4_Layer2D: compositor_init_layer2d(compositor, node); break;
	case TAG_MPEG4_Layout: compositor_init_layout(compositor, node); break;
	case TAG_MPEG4_PathLayout: compositor_init_path_layout(compositor, node); break;


	/*sensors*/
	case TAG_MPEG4_Anchor:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Anchor:
#endif
		compositor_init_anchor(compositor, node); break;
	case TAG_MPEG4_DiscSensor: compositor_init_disc_sensor(compositor, node); break;
	case TAG_MPEG4_PlaneSensor2D: compositor_init_plane_sensor2d(compositor, node); break;
	case TAG_MPEG4_ProximitySensor2D: compositor_init_proximity_sensor2d(compositor, node); break;
	case TAG_MPEG4_TouchSensor:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_TouchSensor:
#endif
		compositor_init_touch_sensor(compositor, node); break;

	case TAG_MPEG4_Group:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Group:
#endif
		compositor_init_group(compositor, node); break;
	case TAG_MPEG4_Rectangle:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Rectangle2D:
#endif
		compositor_init_rectangle(compositor, node); break;
	case TAG_MPEG4_Shape:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Shape:
#endif
		compositor_init_shape(compositor, node); break;
	case TAG_MPEG4_Switch:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Switch:
#endif
		compositor_init_switch(compositor, node); break;

	case TAG_MPEG4_Text:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Text:
#endif
		compositor_init_text(compositor, node); break;

#ifndef GPAC_DISABLE_3D
	case TAG_MPEG4_Background:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Background:
#endif
		compositor_init_background(compositor, node);
		break;
	case TAG_MPEG4_CylinderSensor:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_CylinderSensor:
#endif
		compositor_init_cylinder_sensor(compositor, node);
		break;
	case TAG_MPEG4_PlaneSensor:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_PlaneSensor:
#endif
		compositor_init_plane_sensor(compositor, node);
		break;
	case TAG_MPEG4_ProximitySensor:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_ProximitySensor:
#endif
		compositor_init_proximity_sensor(compositor, node);
		break;
	case TAG_MPEG4_SphereSensor:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_SphereSensor:
#endif
		compositor_init_sphere_sensor(compositor, node);
		break;
	case TAG_MPEG4_VisibilitySensor:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_VisibilitySensor:
#endif
		compositor_init_visibility_sensor(compositor, node);
		break;
	case TAG_MPEG4_Box:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Box:
#endif
		compositor_init_box(compositor, node);
		break;
	case TAG_MPEG4_Cone:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Cone:
#endif
		compositor_init_cone(compositor, node);
		break;
	case TAG_MPEG4_Cylinder:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Cylinder:
#endif
		compositor_init_cylinder(compositor, node);
		break;
	case TAG_MPEG4_ElevationGrid:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_ElevationGrid:
#endif
		compositor_init_elevation_grid(compositor, node);
		break;
	case TAG_MPEG4_Extrusion:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Extrusion:
#endif
		compositor_init_extrusion(compositor, node);
		break;
	case TAG_MPEG4_IndexedFaceSet:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_IndexedFaceSet:
#endif
		compositor_init_ifs(compositor, node);
		break;
	case TAG_MPEG4_IndexedLineSet:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_IndexedLineSet:
#endif
		compositor_init_ils(compositor, node);
		break;
	case TAG_MPEG4_PointSet:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_PointSet:
#endif
		compositor_init_point_set(compositor, node);
		break;
	case TAG_MPEG4_Sphere:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Sphere:
#endif
		compositor_init_sphere(compositor, node);
		break;
	case TAG_MPEG4_Billboard:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Billboard:
#endif
		compositor_init_billboard(compositor, node);
		break;
	case TAG_MPEG4_Collision:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Collision:
#endif
		compositor_init_collision(compositor, node);
		break;
	case TAG_MPEG4_LOD:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_LOD:
#endif
		compositor_init_lod(compositor, node);
		break;
	case TAG_MPEG4_Transform:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Transform:
#endif
		compositor_init_transform(compositor, node);
		break;
	case TAG_MPEG4_Sound:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Sound:
#endif
		compositor_init_sound(compositor, node);
		break;
	case TAG_MPEG4_Viewpoint:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Viewpoint:
#endif
		compositor_init_viewpoint(compositor, node);
		break;
	case TAG_MPEG4_NavigationInfo:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_NavigationInfo:
#endif
		compositor_init_navigation_info(compositor, node);
		break;
	case TAG_MPEG4_Fog:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_Fog:
#endif
		compositor_init_fog(compositor, node);
		break;
	case TAG_MPEG4_DirectionalLight:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_DirectionalLight:
#endif
		compositor_init_directional_light(compositor, node);
		break;
	case TAG_MPEG4_PointLight:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_PointLight:
#endif
		compositor_init_point_light(compositor, node);
		break;
	case TAG_MPEG4_SpotLight:
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_SpotLight:
#endif
		compositor_init_spot_light(compositor, node);
		break;

	case TAG_MPEG4_NonLinearDeformer:
		compositor_init_non_linear_deformer(compositor, node);
		break;

	case TAG_MPEG4_Layer3D:
		compositor_init_layer3d(compositor, node);
		break;
	case TAG_MPEG4_CompositeTexture3D:
		compositor_init_compositetexture3d(compositor, node);
		break;

	case TAG_MPEG4_EnvironmentTest:
		compositor_init_envtest(compositor, node);
		break;
#endif


	/*X3D nodes*/
#ifndef GPAC_DISABLE_X3D
	case TAG_X3D_StaticGroup: compositor_init_static_group(compositor, node); break;
	case TAG_X3D_Disk2D: compositor_init_disk2d(compositor, node); break;
	case TAG_X3D_Arc2D: case TAG_X3D_ArcClose2D: compositor_init_arc2d(compositor, node); break;
	case TAG_X3D_Polyline2D: compositor_init_polyline2d(compositor, node); break;
	case TAG_X3D_TriangleSet2D: compositor_init_triangle_set2d(compositor, node); break;

#ifndef GPAC_DISABLE_3D
	case TAG_X3D_Polypoint2D: compositor_init_polypoint2d(compositor, node); break;
	case TAG_X3D_LineSet: compositor_init_lineset(compositor, node); break;
	case TAG_X3D_TriangleSet: compositor_init_triangle_set(compositor, node); break;
	case TAG_X3D_TriangleStripSet: compositor_init_triangle_strip_set(compositor, node); break;
	case TAG_X3D_TriangleFanSet: compositor_init_triangle_fan_set(compositor, node); break;
	case TAG_X3D_IndexedTriangleFanSet: compositor_init_indexed_triangle_fan_set(compositor, node); break;
	case TAG_X3D_IndexedTriangleStripSet: compositor_init_indexed_triangle_strip_set(compositor, node); break;
	case TAG_X3D_IndexedTriangleSet: compositor_init_indexed_triangle_set(compositor, node); break;
#endif

#endif /*GPAC_DISABLE_X3D*/

	case TAG_ProtoNode: compositor_init_hardcoded_proto(compositor, node); break;

	case TAG_MPEG4_SBVCAnimation:
		compositor_init_afx_node(compositor, node, & ((M_SBVCAnimation *)node)->url);
		break;
	case TAG_MPEG4_BitWrapper:
		compositor_init_afx_node(compositor, node, & ((M_BitWrapper *)node)->url);
		break;

#endif /*GPAC_DISABLE_VRML*/

#ifndef GPAC_DISABLE_SVG
	/* SVG Part */
	case TAG_SVG_svg:				compositor_init_svg_svg(compositor, node); break;
	case TAG_SVG_g:					compositor_init_svg_g(compositor, node); break;
	case TAG_SVG_switch:			compositor_init_svg_switch(compositor, node); break;
	case TAG_SVG_rect:				compositor_init_svg_rect(compositor, node); break;
	case TAG_SVG_path:				compositor_init_svg_path(compositor, node); break;
	case TAG_SVG_circle:			compositor_init_svg_circle(compositor, node); break;
	case TAG_SVG_ellipse:			compositor_init_svg_ellipse(compositor, node); break;
	case TAG_SVG_line:				compositor_init_svg_line(compositor, node); break;
	case TAG_SVG_polyline:			compositor_init_svg_polyline(compositor, node); break;
	case TAG_SVG_polygon:			compositor_init_svg_polygon(compositor, node); break;
	case TAG_SVG_a:					compositor_init_svg_a(compositor, node); break;

	case TAG_SVG_linearGradient:	compositor_init_svg_linearGradient(compositor, node); break;
	case TAG_SVG_radialGradient:	compositor_init_svg_radialGradient(compositor, node); break;
	case TAG_SVG_solidColor:		compositor_init_svg_solidColor(compositor, node); break;
	case TAG_SVG_stop:				compositor_init_svg_stop(compositor, node); break;

	case TAG_SVG_text:				compositor_init_svg_text(compositor, node); break;
	case TAG_SVG_tspan:				compositor_init_svg_tspan(compositor, node); break;
	case TAG_SVG_textArea:			compositor_init_svg_textarea(compositor, node); break;
	case TAG_SVG_tbreak:			compositor_init_svg_tbreak(compositor, node); break;

	case TAG_SVG_image:				compositor_init_svg_image(compositor, node); break;
	case TAG_SVG_video:				compositor_init_svg_video(compositor, node); break;
	case TAG_SVG_audio:				compositor_init_svg_audio(compositor, node, 0); break;

	/*SVG font support - note that we initialize the font when parsing the font-face element, not the font element*/
	case TAG_SVG_font_face:			compositor_init_svg_font(compositor, node); break;
	case TAG_SVG_missing_glyph:
	case TAG_SVG_glyph:
		compositor_init_svg_glyph(compositor, node);
		break;
	case TAG_SVG_font_face_uri:
		compositor_init_svg_font_face_uri(compositor, node); break;

	case TAG_SVG_use:				compositor_init_svg_use(compositor, node); break;
	case TAG_SVG_animation:			compositor_init_svg_animation(compositor, node); break;
	case TAG_SVG_foreignObject:		compositor_init_svg_foreign_object(compositor, node); break;

	case TAG_SVG_filter:			compositor_init_svg_filter(compositor, node); break;

	case TAG_LSR_updates:			compositor_init_svg_updates(compositor, node); break;
#endif

	default:
		GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] node %s will not be rendered\n", gf_node_get_class_name(node)));
		break;
	}
}
Esempio n. 11
0
void compositor_init_afx_node(GF_Compositor *compositor, GF_Node *node, MFURL *url)
{
	GF_MediaObject *mo = gf_mo_register(node, url, 0, 0);
	if (!mo) {
		GF_LOG(GF_LOG_WARNING, GF_LOG_COMPOSE, ("[Compositor] AFX Decoder not found for node %s - node may not be completely/correctly rendered\n", gf_node_get_class_name(node)));
	}
#ifndef GPAC_DISABLE_VRML
	if (gf_node_get_tag(node)==TAG_MPEG4_BitWrapper) {
		compositor_init_bitwrapper(compositor, node);
	}
#endif
}
Esempio n. 12
0
static void TraverseLayer2D(GF_Node *node, void *rs, Bool is_destroy)
{
	GF_List *oldb, *oldv;
	GF_Node *viewport;
	GF_Node *back;
	Bool prev_layer;
	GF_Matrix2D backup;
	SFVec2f prev_vp;

#ifndef GPAC_DISABLE_3D
	GF_Matrix mx3d;
	GF_List *oldf, *oldn;
	GF_List *node_list_backup;
	GF_Rect prev_clipper;
	Bool had_clip;
#endif
	
	M_Layer2D *l = (M_Layer2D *)node;
	Layer2DStack *st = (Layer2DStack *) gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *) rs;
	
	if (is_destroy) {
		gf_list_del(st->backs);
		gf_list_del(st->views);
		group_2d_destroy(node, (GroupingNode2D*)st);
		gf_free(st);
		return;
	}

	/*layers can only be used in a 2D context*/
#ifndef GPAC_DISABLE_3D
	if (tr_state->visual->type_3d && tr_state->camera->is_3D) return;
#endif

	/*layer2D maintains its own stacks*/
	oldb = tr_state->backgrounds;
	oldv = tr_state->viewpoints;
	tr_state->backgrounds = st->backs;
	tr_state->viewpoints = st->views;
	prev_layer = tr_state->is_layer;
	tr_state->is_layer = 1;
#ifndef GPAC_DISABLE_3D
	oldf = tr_state->fogs;
	oldn = tr_state->navigations;
	tr_state->fogs = tr_state->navigations = NULL;
#endif

	l2d_CheckBindables(node, tr_state, st->first);

	back = (GF_Node*)gf_list_get(st->backs, 0);

	viewport = (GF_Node*)gf_list_get(st->views, 0);

	if ((tr_state->traversing_mode == TRAVERSE_SORT) || (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS)) {
		/*override group bounds*/
		visual_get_size_info(tr_state, &st->clip.width, &st->clip.height);
		/*setup bounds in local coord system*/
		if (l->size.x>=0) st->clip.width = l->size.x;
		if (l->size.y>=0) st->clip.height = l->size.y;
		st->clip = gf_rect_center(st->clip.width, st->clip.height);
		st->bounds = st->clip;
	}
	
	prev_vp = tr_state->vp_size;
	tr_state->vp_size.x = st->clip.width;
	tr_state->vp_size.y = st->clip.height;

	switch (tr_state->traversing_mode) {
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) {
			tr_state->layer_clipper = compositor_2d_update_clipper(tr_state, st->clip, &had_clip, &prev_clipper, 1);

			visual_3d_matrix_push(tr_state->visual);
			gf_mx_copy(mx3d, tr_state->model_matrix);

			/*setup clipping*/
			visual_3d_set_clipper_2d(tr_state->visual, tr_state->layer_clipper);
			
			/*apply background BEFORE viewport*/
			if (back) {
				tr_state->traversing_mode = TRAVERSE_BINDABLE;
				gf_bbox_from_rect(&tr_state->bbox, &st->clip);
				gf_node_traverse(back, tr_state);
			}

			/*sort all children without transform, and use current transform when flushing contexts*/
			gf_mx_init(tr_state->model_matrix);

			/*apply viewport*/
			if (viewport) {
				tr_state->traversing_mode = TRAVERSE_BINDABLE;
				tr_state->bounds = st->clip;
				gf_node_traverse(viewport, tr_state);
				visual_3d_matrix_add(tr_state->visual, tr_state->model_matrix.m);
			}


			node_list_backup = tr_state->visual->alpha_nodes_to_draw;
			tr_state->visual->alpha_nodes_to_draw = gf_list_new();
			tr_state->traversing_mode = TRAVERSE_SORT;
			/*reset cull flag*/
			tr_state->cull_flag = 0;
			group_2d_traverse(node, (GroupingNode2D *)st, tr_state);

			visual_3d_flush_contexts(tr_state->visual, tr_state);
			tr_state->traversing_mode = TRAVERSE_SORT;

			assert(!gf_list_count(tr_state->visual->alpha_nodes_to_draw));
			gf_list_del(tr_state->visual->alpha_nodes_to_draw);
			tr_state->visual->alpha_nodes_to_draw = node_list_backup;

			
			visual_3d_matrix_pop(tr_state->visual);
			gf_mx_copy(tr_state->model_matrix, mx3d);

			visual_3d_reset_clipper_2d(tr_state->visual);

			tr_state->has_layer_clip = had_clip;
			if (had_clip) {
				tr_state->layer_clipper = prev_clipper;
				visual_3d_set_clipper_2d(tr_state->visual, tr_state->layer_clipper);
			}
		} else 
#endif
		{
			GF_IRect prev_clip;
			GF_Rect rc;

			gf_mx2d_copy(backup, tr_state->transform);

			prev_clip = tr_state->visual->top_clipper;
			rc = st->clip;
			
			/*get clipper in world coordinate*/
			gf_mx2d_apply_rect(&tr_state->transform, &rc);

			if (viewport) {
				tr_state->traversing_mode = TRAVERSE_BINDABLE;
				tr_state->bounds = st->clip;
				gf_node_traverse(viewport, tr_state);
#if VIEWPORT_CLIPS
				/*move viewport box in world coordinate*/
				gf_mx2d_apply_rect(&backup, &tr_state->bounds);
				/*and intersect with layer clipper*/
				rect_intersect(&rc, &tr_state->bounds);
#endif
			}

			tr_state->visual->top_clipper = gf_rect_pixelize(&rc);
			gf_irect_intersect(&tr_state->visual->top_clipper, &prev_clip);
			tr_state->traversing_mode = TRAVERSE_SORT;

			if (tr_state->visual->top_clipper.width && tr_state->visual->top_clipper.height) {
				if (back && Bindable_GetIsBound(back) ) {
					DrawableContext *ctx;

					ctx = b2d_get_context((M_Background2D*) back, st->backs);
					gf_mx2d_init(ctx->transform);
					ctx->bi->clip = tr_state->visual->top_clipper;
					ctx->bi->unclip = rc;

					if (tr_state->immediate_draw) {
						tr_state->ctx = ctx;
						tr_state->traversing_mode = TRAVERSE_DRAW_2D;
						gf_node_traverse(back, tr_state);
						tr_state->traversing_mode = TRAVERSE_SORT;
						tr_state->ctx = NULL;
					} else {
						DrawableContext *back_ctx = visual_2d_get_drawable_context(tr_state->visual);

						gf_node_traverse(back, tr_state);

						back_ctx->flags = ctx->flags;
						back_ctx->flags &= ~CTX_IS_TRANSPARENT;
						back_ctx->flags |= CTX_IS_BACKGROUND;
						back_ctx->aspect = ctx->aspect;
						back_ctx->drawable = ctx->drawable;
						drawable_check_bounds(back_ctx, tr_state->visual);
						back_ctx->bi->clip = ctx->bi->clip;
						back_ctx->bi->unclip = ctx->bi->unclip;
					}
					/*keep track of node drawn*/
					if (!(ctx->drawable->flags & DRAWABLE_REGISTERED_WITH_VISUAL) ) {
						struct _drawable_store *it;
						GF_SAFEALLOC(it, struct _drawable_store);
						it->drawable = ctx->drawable;
						if (tr_state->visual->last_prev_entry) {
							tr_state->visual->last_prev_entry->next = it;
							tr_state->visual->last_prev_entry = it;
						} else {
							tr_state->visual->prev_nodes = tr_state->visual->last_prev_entry = it;
						}
						GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Layer2D] Registering new drawn node %s on visual\n", gf_node_get_class_name(it->drawable->node)));
						ctx->drawable->flags |= DRAWABLE_REGISTERED_WITH_VISUAL;
					}
				}

				group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
			}
			tr_state->visual->top_clipper = prev_clip;
			gf_mx2d_copy(tr_state->transform, backup);
		}
		break;
		
		/*check picking - we must fall in our 2D clipper*/
	case TRAVERSE_PICK:
		if (gf_sc_pick_in_clipper(tr_state, &st->clip)) {
		
#ifndef GPAC_DISABLE_3D
			if (tr_state->visual->type_3d) {
				/*apply viewport*/
				if (viewport) {
					gf_mx_copy(mx3d, tr_state->model_matrix);
					tr_state->traversing_mode = TRAVERSE_BINDABLE;
					tr_state->bounds = st->clip;
					gf_node_traverse(viewport, tr_state);
					tr_state->traversing_mode = TRAVERSE_PICK;
					group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
					gf_mx_copy(tr_state->model_matrix, mx3d);
				} else {
					group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
				}
			} else 
#endif
			{
				if (viewport) {
					gf_mx2d_copy(backup, tr_state->transform);
					tr_state->traversing_mode = TRAVERSE_BINDABLE;
					tr_state->bounds = st->clip;
					gf_node_traverse(viewport, tr_state);
					tr_state->traversing_mode = TRAVERSE_PICK;
					group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
					gf_mx2d_copy(tr_state->transform, backup);
				} else {
					group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
				}
			}	
		}
		break;
	case TRAVERSE_GET_BOUNDS:
		if (tr_state->for_node) {
			group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
		} else {
			tr_state->bounds = st->clip;
#ifndef GPAC_DISABLE_3D
			gf_bbox_from_rect(&tr_state->bbox, &st->clip);
#endif
		}
		break;

	case TRAVERSE_DRAW_2D:
		group_2d_traverse(node, (GroupingNode2D *)st, tr_state);
		break;

#ifndef GPAC_DISABLE_3D
	/*drawing a layer means drawing all sub-elements as a whole (no depth sorting with parents)*/
	case TRAVERSE_DRAW_3D:
		assert(0);
		break;
#endif
	}
	
	/*restore traversing state*/
	tr_state->vp_size = prev_vp;
	tr_state->backgrounds = oldb;
	tr_state->viewpoints = oldv;
	tr_state->is_layer = prev_layer;
#ifndef GPAC_DISABLE_3D
	tr_state->fogs = oldf;
	tr_state->navigations = oldn;
#endif

	/*in case we missed bindables*/
	if (st->first) {
		st->first = 0;
		gf_sc_invalidate(tr_state->visual->compositor, NULL);
	}
}
Esempio n. 13
0
static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes)
{
	u32 i;
	SVG_SANI_BIFS_Converter *converter = (SVG_SANI_BIFS_Converter *)sax_cbck;
	SVGPropertiesPointers *backup_props;
	char *id_string = NULL;

	u32	tag = gf_svg_get_element_tag(name);
	SVG_Element *elt = (SVG_Element*)gf_node_new(converter->svg_sg, tag);
	if (!gf_sg_get_root_node(converter->svg_sg)) {
		gf_node_register((GF_Node *)elt, NULL);
		gf_sg_set_root_node(converter->svg_sg, (GF_Node *)elt);
	} else {
		gf_node_register((GF_Node *)elt, converter->svg_parent);	
		//gf_node_list_add_child(&((GF_ParentNode*)converter->svg_parent)->children, (GF_Node *)elt);
	}
	converter->svg_parent = (GF_Node *)elt;
	
//	fprintf(stdout, "Converting %s\n", gf_node_get_class_name((GF_Node *)elt));
//	if (converter->bifs_parent) fprintf(stdout, "%s\n", gf_node_get_class_name(converter->bifs_parent));

	for (i=0; i<nb_attributes; i++) {
		GF_XMLAttribute *att = (GF_XMLAttribute *)&attributes[i];
		if (!att->value || !strlen(att->value)) continue;

		if (!stricmp(att->name, "style")) {
			gf_svg_parse_style((GF_Node *)elt, att->value);
		} else if (!stricmp(att->name, "id") || !stricmp(att->name, "xml:id")) {
			gf_svg_parse_element_id((GF_Node *)elt, att->value, 0);
			id_string = att->value;
		} else {
			GF_FieldInfo info;
			if (gf_node_get_field_by_name((GF_Node *)elt, att->name, &info)==GF_OK) {
				gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0);
			} else {
				fprintf(stdout, "Skipping attribute %s\n", att->name);
			}
		}
	}

	memset(&converter->all_atts, 0, sizeof(SVGAllAttributes));
	gf_svg_flatten_attributes(elt, &converter->all_atts);
	
	backup_props = gf_malloc(sizeof(SVGPropertiesPointers));
	memcpy(backup_props, &converter->svg_props, sizeof(SVGPropertiesPointers));
	gf_node_set_private((GF_Node *)elt, backup_props);

	gf_svg_apply_inheritance(&converter->all_atts, &converter->svg_props);

	if (!gf_sg_get_root_node(converter->bifs_sg)) {
		if (tag == TAG_SVG_svg) {
			GF_Node *node, *child;

			converter->bifs_sg->usePixelMetrics = 1;
			if (converter->all_atts.width && converter->all_atts.width->type == SVG_NUMBER_VALUE) {
				converter->bifs_sg->width = FIX2INT(converter->all_atts.width->value);
			} else {
				converter->bifs_sg->width = 320;
			}
			if (converter->all_atts.height && converter->all_atts.height->type == SVG_NUMBER_VALUE) {
				converter->bifs_sg->height = FIX2INT(converter->all_atts.height->value);
			} else {
				converter->bifs_sg->height = 200;
			}

			node = gf_node_new(converter->bifs_sg, TAG_MPEG4_OrderedGroup);
			gf_node_register(node, NULL);
			gf_sg_set_root_node(converter->bifs_sg, node);

			/* SVG to BIFS coordinate transformation */
			child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Viewport);
			gf_node_register(child, node);
			gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
			if (converter->all_atts.viewBox) {
				M_Viewport *vp = (M_Viewport*)child;
				vp->size.x = converter->all_atts.viewBox->width;
				vp->size.y = converter->all_atts.viewBox->height;
				vp->position.x = converter->all_atts.viewBox->x+converter->all_atts.viewBox->width/2;
				vp->position.y = -(converter->all_atts.viewBox->y+converter->all_atts.viewBox->height/2);
			} else {
				M_Viewport *vp = (M_Viewport*)child;
				vp->size.x = INT2FIX(converter->bifs_sg->width);
				vp->size.y = INT2FIX(converter->bifs_sg->height);
				vp->position.x = INT2FIX(converter->bifs_sg->width)/2;
				vp->position.y = -INT2FIX(converter->bifs_sg->height)/2;
			}

			child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Background2D);
			gf_node_register(child, node);
			gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
			{
				M_Background2D *b = (M_Background2D *)child;
				b->backColor.red = FIX_ONE;
				b->backColor.green = FIX_ONE;				
				b->backColor.blue = FIX_ONE;
			}

			child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
			gf_node_register(child, node);
			gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
			node = child;
			child = NULL;
			{
				M_Transform2D *tr = (M_Transform2D *)node;
				tr->scale.y = -FIX_ONE;
			}
			converter->bifs_parent = node;
		}
	} else {
		GF_Node *node, *child;
		
		node = converter->bifs_parent;

		switch(tag) {
		case TAG_SVG_g:
			{
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
				} else {
					M_Group *g = (M_Group*)gf_node_new(converter->bifs_sg, TAG_MPEG4_Group);
					gf_node_register((GF_Node *)g, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, (GF_Node *)g);
					node = (GF_Node *)g;
					converter->bifs_parent = node;
				}
			}
			break;
		case TAG_SVG_rect:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				} 
				if (converter->all_atts.x || converter->all_atts.y) {
					child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
					gf_node_register(child, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
					node = child;
					child = NULL;
					if (!is_parent_set) {
						converter->bifs_parent = node;
						is_parent_set = 1;
					}
					{
						M_Transform2D *tr = (M_Transform2D *)node;
						if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value + (converter->all_atts.width?converter->all_atts.width->value/2:0);
						if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value + (converter->all_atts.height?converter->all_atts.height->value/2:0);
					}
				} 
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_Rectangle);
					gf_node_register(shape->geometry, (GF_Node *)shape);
					{
						M_Rectangle *rect = (M_Rectangle *)shape->geometry;
						if (converter->all_atts.width) rect->size.x = converter->all_atts.width->value;
						if (converter->all_atts.height) rect->size.y = converter->all_atts.height->value;					
					}			
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_path:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				} 
				if (converter->all_atts.x || converter->all_atts.y) {
					child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
					gf_node_register(child, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
					node = child;
					child = NULL;
					if (!is_parent_set) {
						converter->bifs_parent = node;
						is_parent_set = 1;
					}
					{
						M_Transform2D *tr = (M_Transform2D *)node;
						if (converter->all_atts.x) tr->translation.x = converter->all_atts.x->value;
						if (converter->all_atts.y) tr->translation.y = converter->all_atts.y->value;
					}
				} 
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_XCurve2D);
					gf_node_register(shape->geometry, (GF_Node *)shape);
					if (converter->all_atts.d) {
						M_Coordinate2D *c2d;
						M_XCurve2D *xc = (M_XCurve2D *)shape->geometry;
						u32 i, j, c;

						xc->point = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
						c2d = (M_Coordinate2D *)xc->point;
						gf_node_register(xc->point, (GF_Node *)xc);
						
						gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, converter->all_atts.d->n_points);
						j= 0;
						for (i = 0; i < converter->all_atts.d->n_points; i++) {
							if (converter->all_atts.d->tags[i] != GF_PATH_CLOSE || i == converter->all_atts.d->n_points-1) {
								c2d->point.vals[j] = converter->all_atts.d->points[i];
								j++;
							}
						}
						c2d->point.count = j;

						gf_sg_vrml_mf_alloc(&xc->type, GF_SG_VRML_MFINT32, converter->all_atts.d->n_points);
						c = 0;
						j = 0;
						xc->type.vals[0] = 0;
						for (i = 1; i < converter->all_atts.d->n_points; i++) {
							switch(converter->all_atts.d->tags[i]) {
							case GF_PATH_CURVE_ON:
								if (c < converter->all_atts.d->n_contours &&
									i-1 == converter->all_atts.d->contours[c]) {
									xc->type.vals[j] = 0;
									c++;
								} else {
									xc->type.vals[j] = 1;
								}
								break;
							case GF_PATH_CURVE_CUBIC:
								xc->type.vals[j] = 2;
								i+=2;
								break;
							case GF_PATH_CLOSE:
								xc->type.vals[j] = 6;
								break;
							case GF_PATH_CURVE_CONIC:
								xc->type.vals[j] = 7;
								i++;
								break;
							}
							j++;
						}
						xc->type.count = j;
					}			
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_polyline:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				} 

				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					shape->geometry = gf_node_new(converter->bifs_sg, TAG_MPEG4_IndexedFaceSet2D);
					gf_node_register(shape->geometry, (GF_Node *)shape);
					if (converter->all_atts.points) {
						M_Coordinate2D *c2d;
						M_IndexedFaceSet2D *ifs = (M_IndexedFaceSet2D *)shape->geometry;
						u32 i;

						ifs->coord = gf_node_new(converter->bifs_sg, TAG_MPEG4_Coordinate2D);
						c2d = (M_Coordinate2D *)ifs->coord;
						gf_node_register(ifs->coord, (GF_Node *)ifs);
						
						gf_sg_vrml_mf_alloc(&c2d->point, GF_SG_VRML_MFVEC2F, gf_list_count(*converter->all_atts.points));
						for (i = 0; i < gf_list_count(*converter->all_atts.points); i++) {
							SVG_Point *p = (SVG_Point *)gf_list_get(*converter->all_atts.points, i);
							c2d->point.vals[i].x = p->x;
							c2d->point.vals[i].y = p->y;
						}						
					}			
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_text:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				}

				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				{
					M_Transform2D *tr = (M_Transform2D *)child;
					if (converter->all_atts.text_x) tr->translation.x = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_x, 0))->value;
					if (converter->all_atts.text_y) tr->translation.y = ((SVG_Coordinate *)gf_list_get(*converter->all_atts.text_y, 0))->value;
					tr->scale.y = -FIX_ONE;
				}
				node = child;
				child = NULL;
				if (!is_parent_set) {
					converter->bifs_parent = node;
					is_parent_set = 1;
				}

				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_FontStyle *fs;
					M_Text *text; 
					M_Shape *shape = (M_Shape *)node;
					text = (M_Text *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Text);
					shape->geometry = (GF_Node *)text;
					converter->bifs_text_node = shape->geometry;
					gf_node_register(shape->geometry, (GF_Node *)shape);
					
					fs = (M_FontStyle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_XFontStyle);
					gf_node_register((GF_Node *)fs, (GF_Node*)text);
					text->fontStyle = (GF_Node *)fs;

					gf_sg_vrml_mf_alloc(&fs->family, GF_SG_VRML_MFSTRING, 1);				
					fs->family.vals[0] = strdup(converter->svg_props.font_family->value);				
					fs->size = converter->svg_props.font_size->value;

					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;
		case TAG_SVG_ellipse:
		case TAG_SVG_circle:
			{
				Bool is_parent_set = 0;
				if (converter->all_atts.transform) {
					node = add_transform(converter, node);
					converter->bifs_parent = node;
					is_parent_set = 1;
				}
				if (converter->all_atts.cx || converter->all_atts.cy) {
					child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
					gf_node_register(child, node);
					gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
					{
						M_Transform2D *tr = (M_Transform2D *)child;
						if (converter->all_atts.cx) tr->translation.x = converter->all_atts.cx->value;
						if (converter->all_atts.cy) tr->translation.y = converter->all_atts.cy->value;
					}
					node = child;
					child = NULL;
					if (!is_parent_set) {
						converter->bifs_parent = node;
						is_parent_set = 1;
					}
				} 
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				if (!is_parent_set) converter->bifs_parent = node;
				{
					M_Shape *shape = (M_Shape *)node;
					if (tag == TAG_SVG_ellipse) {
						M_Ellipse *e = (M_Ellipse *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Ellipse);
						shape->geometry = (GF_Node *)e;
						e->radius.x = converter->all_atts.rx->value;
						e->radius.y = converter->all_atts.ry->value;
					} else {
						M_Circle *c = (M_Circle *)gf_node_new(converter->bifs_sg, TAG_MPEG4_Circle);
						shape->geometry = (GF_Node *)c;
						c->radius = converter->all_atts.r->value;
					}
					gf_node_register(shape->geometry, (GF_Node *)shape);
					
					shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg);
					gf_node_register(shape->appearance, (GF_Node *)shape);
				}
			}
			break;

		case TAG_SVG_defs:
			{
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Switch);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				{
					M_Switch *sw = (M_Switch *)node;
					sw->whichChoice = -1;
				}
				converter->bifs_parent = node;
			}
			break;
		case TAG_SVG_solidColor:
			{
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Shape);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				converter->bifs_parent = node;
			}
			break;
		default:
			{
				fprintf(stdout, "Warning: element %s not supported \n", gf_node_get_class_name((GF_Node *)elt));
				child = gf_node_new(converter->bifs_sg, TAG_MPEG4_Transform2D);
				gf_node_register(child, node);
				gf_node_list_add_child(&((GF_ParentNode*)node)->children, child);
				node = child;
				child = NULL;
				converter->bifs_parent = node;
			}
			break;
		}

		if (id_string) 
			gf_node_set_id(converter->bifs_parent, gf_node_get_id((GF_Node *)elt), gf_node_get_name((GF_Node *)elt));
	}
}
Esempio n. 14
0
void V4StudioTree::AddNodesToItem(wxTreeItemId parentItemId, GF_Node * node, s32 fieldIndex, s32 position) 
{
	GF_FieldInfo field;
	u32 count, i, j;
	char *name;

	if (!node) return;

	// displays the name and the defname it exists
  u32 s = strlen(gf_node_get_class_name(node));

  if (gf_node_get_name(node)) {
    s += strlen(gf_node_get_name(node));
    name = new char[s+4];
    strcpy(name, gf_node_get_class_name(node));
    strcat(name, " - ");
    strcat(name, gf_node_get_name(node));
  } else {
    name = new char[s+1];
    strcpy(name, gf_node_get_class_name(node));
  }

	GF_Node * parent = NULL;
	
	V4StudioTreeItemData *parentItemData = (V4StudioTreeItemData *)GetItemData(parentItemId);
	if (parentItemData != NULL) parent = parentItemData->GetNode();

	V4StudioTreeItemData * currentItemData = new V4StudioTreeItemData(node, parent, fieldIndex, position);
	wxTreeItemId nodeItemId;
	if (position == -1) nodeItemId = AppendItem(parentItemId, wxString(name), -1, -1, currentItemData);
	else nodeItemId = InsertItem(parentItemId, position, wxString(name), -1, -1, currentItemData);

  delete [] name;
  name = NULL;

	count = gf_node_get_field_count(node);
	for (i=0;i<count; i++) {		
		gf_node_get_field(node, i, &field);
		if (field.eventType == GF_SG_EVENT_IN || field.eventType == GF_SG_EVENT_OUT) continue;
		switch (field.fieldType) {
		case GF_SG_VRML_SFNODE:
			if (* (GF_Node **) field.far_ptr) {
				AddNodesToItem(nodeItemId, * (GF_Node **) field.far_ptr, i, -1);
			}
			break;
		case GF_SG_VRML_MFNODE:
			{
				GF_List *nodes = (* (GF_List **) field.far_ptr); // list of children
				u32 nbNodes = gf_list_count(nodes);
        u8 skipped = 0; // counts nodes not added

				for (j=0; j< nbNodes; j++) {          
          // gets a pointer to the current child
					GF_Node *child = (GF_Node *)gf_list_get(nodes, j);

          // prevents the dictionnary from being added to the graph
          const char * c = gf_node_get_name(child);
          if ( (c != NULL) && !strcmp(c,DICTNAME) ) {
            skipped++;
            continue;
          }

          // recursively adds children
					AddNodesToItem(nodeItemId, child, i, j-skipped);
				}
			}
			break;
		default:
			break;
		}
	}
	Expand(nodeItemId);
}
Esempio n. 15
0
Bool visual_2d_draw_frame(GF_VisualManager *visual, GF_Node *root, GF_TraverseState *tr_state, Bool is_root_visual)
{
	GF_SceneGraph *sg;
	GF_Matrix2D backup;
	u32 i;
	Bool res;
	GF_Err e;
#ifndef GPAC_DISABLE_LOG
	u32 itime, time = gf_sys_clock();
#endif

	gf_mx2d_copy(backup, tr_state->transform);
	visual->bounds_tracker_modif_flag = DRAWABLE_HAS_CHANGED;

	e = visual_2d_init_draw(visual, tr_state);
	if (e) {
		gf_mx2d_copy(tr_state->transform, backup);
		GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Visual2D] Cannot init draw phase: %s\n", gf_error_to_string(e)));
		return 0;
	}

#ifndef GPAC_DISABLE_LOG
	itime = gf_sys_clock();
	visual->compositor->traverse_setup_time = itime - time;
	time = itime;
#endif

	GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Traversing scene subtree (root node %s)\n", root ? gf_node_get_class_name(root) : "none"));

	if (is_root_visual) {
		gf_node_traverse(root, tr_state);

		i=0;
		while ((sg = (GF_SceneGraph*)gf_list_enum(visual->compositor->extra_scenes, &i))) {
			gf_sc_traverse_subscene(visual->compositor, root, sg, tr_state);
		}
	} else {
		gf_node_traverse(root, tr_state);
	}

#ifndef GPAC_DISABLE_LOG
	itime = gf_sys_clock();
	visual->compositor->traverse_and_direct_draw_time = itime - time;
	time = itime;
#endif

	gf_mx2d_copy(tr_state->transform, backup);
	res = visual_2d_terminate_draw(visual, tr_state);

#ifndef GPAC_DISABLE_LOG
	if (!tr_state->immediate_draw) {
		visual->compositor->indirect_draw_time = gf_sys_clock() - time;
	}
#endif

	return res;
}
Esempio n. 16
0
void svg_drawable_3d_pick(Drawable *drawable, GF_TraverseState *tr_state, DrawAspect2D *asp) 
{
	SFVec3f local_pt, world_pt, vdiff;
	SFVec3f hit_normal;
	SFVec2f text_coords;
	u32 i, count;
	Fixed sqdist;
	Bool node_is_over;
	GF_Compositor *compositor;
	GF_Matrix mx;
	GF_Ray r;

	compositor = tr_state->visual->compositor;

	node_is_over = 0;
	r = tr_state->ray;
	gf_mx_copy(mx, tr_state->model_matrix);
	gf_mx_inverse(&mx);
	gf_mx_apply_ray(&mx, &r);

	/*if we already have a hit point don't check anything below...*/
	if (compositor->hit_square_dist && !compositor->grabbed_sensor && !tr_state->layer3d) {
		GF_Plane p;
		GF_BBox box;
		SFVec3f hit = compositor->hit_world_point;
		gf_mx_apply_vec(&mx, &hit);
		p.normal = r.dir;
		p.d = -1 * gf_vec_dot(p.normal, hit);
		gf_bbox_from_rect(&box, &drawable->path->bbox);

		if (gf_bbox_plane_relation(&box, &p) == GF_BBOX_FRONT) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Picking] bounding box of node %s (DEF %s) below current hit point - skipping\n", gf_node_get_class_name(drawable->node), gf_node_get_name(drawable->node)));
			return;
		}
	}
	node_is_over = 0;
	if (compositor_get_2d_plane_intersection(&r, &local_pt)) {
		node_is_over = svg_drawable_is_over(drawable, local_pt.x, local_pt.y, asp, tr_state, NULL);
	}

	if (!node_is_over) return;

	hit_normal.x = hit_normal.y = 0; hit_normal.z = FIX_ONE;
	text_coords.x = gf_divfix(local_pt.x, drawable->path->bbox.width) + FIX_ONE/2;
	text_coords.y = gf_divfix(local_pt.y, drawable->path->bbox.height) + FIX_ONE/2;

	/*check distance from user and keep the closest hitpoint*/
	world_pt = local_pt;
	gf_mx_apply_vec(&tr_state->model_matrix, &world_pt);

	for (i=0; i<tr_state->num_clip_planes; i++) {
		if (gf_plane_get_distance(&tr_state->clip_planes[i], &world_pt) < 0) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Picking] node %s (def %s) is not in clipper half space\n", gf_node_get_class_name(drawable->node), gf_node_get_name(drawable->node)));
			return;
		}
	}

	gf_vec_diff(vdiff, world_pt, tr_state->ray.orig);
	sqdist = gf_vec_lensq(vdiff);
	if (compositor->hit_square_dist && (compositor->hit_square_dist+FIX_EPSILON<sqdist)) {
		GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Picking] node %s (def %s) is farther (%g) than current pick (%g)\n", gf_node_get_class_name(drawable->node), gf_node_get_name(drawable->node), FIX2FLT(sqdist), FIX2FLT(compositor->hit_square_dist)));
		return;
	}

	compositor->hit_square_dist = sqdist;

	/*also stack any VRML sensors present at the current level. If the event is not catched
	by a listener in the SVG tree, the event will be forwarded to the VRML tree*/
	gf_list_reset(compositor->sensors);
	count = gf_list_count(tr_state->vrml_sensors);
	for (i=0; i<count; i++) {
		gf_list_add(compositor->sensors, gf_list_get(tr_state->vrml_sensors, i));
	}

	gf_mx_copy(compositor->hit_world_to_local, tr_state->model_matrix);
	gf_mx_copy(compositor->hit_local_to_world, mx);
	compositor->hit_local_point = local_pt;
	compositor->hit_world_point = world_pt;
	compositor->hit_world_ray = tr_state->ray;
	compositor->hit_normal = hit_normal;
	compositor->hit_texcoords = text_coords;

	svg_clone_use_stack(compositor, tr_state);
	/*not use in SVG patterns*/
	compositor->hit_appear = NULL;
	compositor->hit_node = drawable->node;
	compositor->hit_text = NULL;
	compositor->hit_use_dom_events = 1;

	GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Picking] node %s (def %s) is under mouse - hit %g %g %g\n", gf_node_get_class_name(drawable->node), gf_node_get_name(drawable->node),
			FIX2FLT(world_pt.x), FIX2FLT(world_pt.y), FIX2FLT(world_pt.z)));
}
Esempio n. 17
0
static void visual_2d_fill_path(GF_VisualManager *visual, DrawableContext *ctx, GF_STENCIL stencil, GF_TraverseState *tr_state)
{
	GF_IRect clip;
	GF_Raster2D *raster = visual->compositor->rasterizer;

	/*background & direct drawing : use ctx clip*/
	if ((ctx->flags & CTX_IS_BACKGROUND) || tr_state->immediate_draw) {
		if (ctx->bi->clip.width && ctx->bi->clip.height) {
			GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (direct draw)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node) ));

			if (stencil) {
				raster->surface_set_clipper(visual->raster_surface, &ctx->bi->clip);
				raster->surface_fill(visual->raster_surface, stencil);
			} else {
				raster->surface_clear(visual->raster_surface, &ctx->bi->clip, 0);
			}

			visual->has_modif = 1;
		}
	}
	/*indirect drawing, draw path in all dirty areas*/
	else {
		u32 i;
		for (i=0; i<visual->to_redraw.count; i++) {
			/*there's an opaque region above, don't draw*/
#ifdef TRACK_OPAQUE_REGIONS
			if (visual->draw_node_index<visual->to_redraw.opaque_node_index[i]) continue;
#endif
			clip = ctx->bi->clip;
			gf_irect_intersect(&clip, &visual->to_redraw.list[i]);
			if (clip.width && clip.height) {
				GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s[%s] (indirect draw @ dirty rect idx %d)\n", gf_node_get_log_name(ctx->drawable->node), gf_node_get_class_name(ctx->drawable->node), i));
				if (stencil) {
					raster->surface_set_clipper(visual->raster_surface, &clip);
					raster->surface_fill(visual->raster_surface, stencil);
				} else {
					raster->surface_clear(visual->raster_surface, &clip, 0);
				}
				visual->has_modif = 1;
			}
		}
	}
}