Beispiel #1
0
static void TraverseILS2D(GF_Node *node, void *rs, Bool is_destroy)
{
	DrawableContext *ctx;
	M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node;
	Drawable *stack = (Drawable *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		drawable_node_del(node);
		return;
	}

	if (!ils2D->coord) return;

	ils2d_check_changes(node, stack, tr_state);

	switch (tr_state->traversing_mode) {
	case TRAVERSE_DRAW_2D:
		ILS2D_Draw(node, tr_state);
		return;
#ifndef GPAC_DISABLE_3D
	case TRAVERSE_DRAW_3D:
		if (!stack->mesh) {
			stack->mesh = new_mesh();
			mesh_new_ils(stack->mesh, ils2D->coord, &ils2D->coordIndex, ils2D->color, &ils2D->colorIndex, ils2D->colorPerVertex, 0);
		}
		if (ils2D->color) {
			DrawAspect2D asp;
			memset(&asp, 0, sizeof(DrawAspect2D));
			drawable_get_aspect_2d_mpeg4(node, &asp, tr_state);

			visual_3d_mesh_strike(tr_state, stack->mesh, asp.pen_props.width, asp.line_scale, asp.pen_props.dash);
		} else {
			visual_3d_draw_2d(stack, tr_state);
		}
		return;
#endif
	case TRAVERSE_PICK:
		vrml_drawable_pick(stack, tr_state);
		return;
	case TRAVERSE_GET_BOUNDS:
		gf_path_get_bounds(stack->path, &tr_state->bounds);
		return;
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) return;
#endif

		ctx = drawable_init_context_mpeg4(stack, tr_state);
		if (!ctx) return;
		/*ILS2D are NEVER filled*/
		ctx->aspect.fill_color &= 0x00FFFFFF;
		drawable_finalize_sort(ctx, tr_state, NULL);
		return;
	default:
		return;
	}
}
Beispiel #2
0
static void TraversePointSet2D(GF_Node *node, void *rs, Bool is_destroy)
{
	DrawableContext *ctx;
	M_PointSet2D *ps2D = (M_PointSet2D *)node;
	Drawable *stack = (Drawable *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		drawable_node_del(node);
		return;
	}

	if (!ps2D->coord) return;

	pointset2d_check_changes(node, stack, tr_state);

	switch (tr_state->traversing_mode) {
	case TRAVERSE_DRAW_2D:
		PointSet2D_Draw(node, tr_state);
		return;
#ifndef GPAC_DISABLE_3D
	case TRAVERSE_DRAW_3D:
	{
		DrawAspect2D asp;
		if (!stack->mesh) {
			stack->mesh = new_mesh();
			mesh_new_ps(stack->mesh, ps2D->coord, ps2D->color);
		}
		memset(&asp, 0, sizeof(DrawAspect2D));
		drawable_get_aspect_2d_mpeg4(node, &asp, tr_state);
		visual_3d_set_material_2d_argb(tr_state->visual, asp.fill_color);
		visual_3d_mesh_paint(tr_state, stack->mesh);
		return;
	}
#endif
	case TRAVERSE_GET_BOUNDS:
		gf_path_get_bounds(stack->path, &tr_state->bounds);
		return;
	case TRAVERSE_PICK:
		return;
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) return;
#endif
		ctx = drawable_init_context_mpeg4(stack, tr_state);
		if (!ctx) return;
		drawable_finalize_sort(ctx, tr_state, NULL);
		break;
	default:
		return;
	}
}
Beispiel #3
0
static void TraverseArc2D(GF_Node *node, void *rs, Bool is_destroy)
{
	DrawableContext *ctx;
	Drawable *stack = (Drawable *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	if (is_destroy) {
		drawable_node_del(node);
		return;
	}

	arc2d_check_changes(node, stack, tr_state);

	switch (tr_state->traversing_mode) {
#ifndef GPAC_DISABLE_3D
	case TRAVERSE_DRAW_3D:
		if (!stack->mesh) {
			stack->mesh = new_mesh();
			if (gf_node_get_tag(node)==TAG_X3D_Arc2D) {
				mesh_get_outline(stack->mesh, stack->path);
			} else {
				mesh_from_path(stack->mesh, stack->path);
			}
		}
		visual_3d_draw_2d(stack, tr_state);
		return;
#endif
	case TRAVERSE_GET_BOUNDS:
		gf_path_get_bounds(stack->path, &tr_state->bounds);
#ifndef GPAC_DISABLE_3D
		gf_bbox_from_rect(&tr_state->bbox, &tr_state->bounds);
#endif
		return;
	case TRAVERSE_PICK:
		vrml_drawable_pick(stack, tr_state);
		return;
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) return;
#endif
		ctx = drawable_init_context_mpeg4(stack, tr_state);
		if (!ctx) return;
		drawable_finalize_sort(ctx, tr_state, NULL);
		return;
	}
}
Beispiel #4
0
static void TraverseIndexedCurve2D(GF_Node *node, void *rs, Bool is_destroy)
{
    DrawableContext *ctx;
    IndexedCurve2D ic2d;
    GF_TraverseState *tr_state = (GF_TraverseState *)rs;
    Drawable *stack = (Drawable *)gf_node_get_private(node);

    if (is_destroy) {
        drawable_node_del(node);
        return;
    }

    if (gf_node_dirty_get(node)) {
        if (!IndexedCurve2D_GetNode(node, &ic2d)) return;
        curve2d_check_changes((GF_Node*) &ic2d, stack, tr_state, &ic2d.index);
    }

    switch (tr_state->traversing_mode) {
#ifndef GPAC_DISABLE_3D
    case TRAVERSE_DRAW_3D:
        if (!stack->mesh) {
            stack->mesh = new_mesh();
            mesh_from_path(stack->mesh, stack->path);
        }
        visual_3d_draw_2d(stack, tr_state);
        return;
#endif
    case TRAVERSE_PICK:
        vrml_drawable_pick(stack, tr_state);
        return;
    case TRAVERSE_GET_BOUNDS:
        gf_path_get_bounds(stack->path, &tr_state->bounds);
        return;
    case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
        if (tr_state->visual->type_3d) return;
#endif
        ctx = drawable_init_context_mpeg4(stack, tr_state);
        if (!ctx) return;
        drawable_finalize_sort(ctx, tr_state, NULL);
        return;
    }
}
Beispiel #5
0
static void TraverseCircle(GF_Node *node, void *rs, Bool is_destroy)
{
	DrawableContext *ctx;
	Drawable *stack = (Drawable *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		drawable_node_del(node);
		return;
	}

	circle_check_changes(node, stack, tr_state);

	switch (tr_state->traversing_mode) {
#ifndef GPAC_DISABLE_3D
	case TRAVERSE_DRAW_3D:
		if (!stack->mesh) {
			Fixed a = ((M_Circle *) node)->radius * 2;
			stack->mesh = new_mesh();
			mesh_new_ellipse(stack->mesh, a, a, tr_state->visual->compositor->high_speed);
		}
		visual_3d_draw_2d(stack, tr_state);
		return;
#endif
	case TRAVERSE_GET_BOUNDS:
		gf_path_get_bounds(stack->path, &tr_state->bounds);
		return;
	case TRAVERSE_PICK:
		vrml_drawable_pick(stack, tr_state);
		return;
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) return;
#endif
		ctx = drawable_init_context_mpeg4(stack, tr_state);
		if (!ctx) return;
		drawable_finalize_sort(ctx, tr_state, NULL);
		return;
	}
}
Beispiel #6
0
static void TraverseDisk2D(GF_Node *node, void *rs, Bool is_destroy)
{
	DrawableContext *ctx;
	Drawable *stack = (Drawable *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		drawable_node_del(node);
		return;
	}

	disk2d_check_changes(node, stack, tr_state);

	switch (tr_state->traversing_mode) {
#ifndef GPAC_DISABLE_3D
	case TRAVERSE_DRAW_3D:
		if (!stack->mesh) {
			stack->mesh = new_mesh();
			/*FIXME - enable it with OpenGL-ES*/
			mesh_from_path(stack->mesh, stack->path);
		}
		visual_3d_draw_2d(stack, tr_state);
		return;
#endif
	case TRAVERSE_GET_BOUNDS:
		gf_path_get_bounds(stack->path, &tr_state->bounds);
		return;
	case TRAVERSE_PICK:
		vrml_drawable_pick(stack, tr_state);
		return;
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) return;
#endif
		ctx = drawable_init_context_mpeg4(stack, tr_state);
		if (!ctx) return;
		drawable_finalize_sort(ctx, tr_state, NULL);
		return;
	}
}
Beispiel #7
0
static void TraverseRectangle(GF_Node *node, void *rs, Bool is_destroy)
{
	DrawableContext *ctx;
	Drawable *stack = (Drawable *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		drawable_node_del(node);
		return;
	}

	rectangle_check_changes(node, stack, tr_state);

	switch (tr_state->traversing_mode) {
	case TRAVERSE_DRAW_2D:
		compositor_2d_draw_rectangle(tr_state);
		return;
#ifndef GPAC_DISABLE_3D
	case TRAVERSE_DRAW_3D:
		if (!stack->mesh) {
			stack->mesh = new_mesh();
			mesh_new_rectangle(stack->mesh, ((M_Rectangle *) node)->size, NULL, 0);
		}
		visual_3d_draw_2d(stack, tr_state);
		return;
#endif
	case TRAVERSE_PICK:
		vrml_drawable_pick(stack, tr_state);
		return;
	case TRAVERSE_GET_BOUNDS:
		gf_path_get_bounds(stack->path, &tr_state->bounds);
		return;
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) return;
#endif
		break;
	default:
		return;
	}

	ctx = drawable_init_context_mpeg4(stack, tr_state);
	if (!ctx) return;

	/*if rotated, object is transparent (doesn't fill bounds) and antialias must be used*/
	if (tr_state->transform.m[1] || tr_state->transform.m[3]) {
	}
	else {

		/*if alpha or not filled, transparent*/
		if (ctx->aspect.fill_color && (GF_COL_A(ctx->aspect.fill_color) != 0xFF)) {
		}
		/*if texture transparent, transparent*/
		else if (ctx->aspect.fill_texture && ctx->aspect.fill_texture->transparent) {
		}
		/*TODO check matrix for alpha*/
		else if (!tr_state->color_mat.identity) {
		}
		/*otherwise, not transparent*/
		else {
			ctx->flags &= ~CTX_IS_TRANSPARENT;
		}
		/*if no line width, we skip antialiasing*/
		if (!ctx->aspect.pen_props.width) ctx->flags |= CTX_NO_ANTIALIAS;
	}
	drawable_finalize_sort(ctx, tr_state, NULL);
}
Beispiel #8
0
static void svg_drawable_traverse(GF_Node *node, void *rs, Bool is_destroy,
							void (*rebuild_path)(GF_Node *, Drawable *, SVGAllAttributes *),
							Bool is_svg_rect, Bool is_svg_path)
{
	GF_Matrix2D backup_matrix;
	GF_Matrix mx_3d;
	DrawableContext *ctx;
	SVGPropertiesPointers backup_props;
	u32 backup_flags;
	Drawable *drawable = (Drawable *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;
	SVGAllAttributes all_atts;

	if (is_destroy) {
#if USE_GF_PATH
		/* The path is the same as the one in the SVG node, don't delete it here */
		if (is_svg_path) drawable->path = NULL;
#endif
		drawable_node_del(node);
		return;
	}
	assert(tr_state->traversing_mode!=TRAVERSE_DRAW_2D);

	
	if (tr_state->traversing_mode==TRAVERSE_PICK) {
		svg_drawable_pick(node, drawable, tr_state);
		return;
	}

	/*flatten attributes and apply animations + inheritance*/
	gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);
	if (!compositor_svg_traverse_base(node, &all_atts, (GF_TraverseState *)rs, &backup_props, &backup_flags))
		return;
	
	/* Recreates the path (i.e the shape) only if the node is dirty */
	if (gf_node_dirty_get(node) & GF_SG_SVG_GEOMETRY_DIRTY) {
		/*the rebuild function is responsible for cleaning the path*/
		rebuild_path(node, drawable, &all_atts);
		gf_node_dirty_clear(node, GF_SG_SVG_GEOMETRY_DIRTY);
		drawable_mark_modified(drawable, tr_state);
	}
	if (drawable->path) {
		if (*(tr_state->svg_props->fill_rule)==GF_PATH_FILL_ZERO_NONZERO) {
			if (!(drawable->path->flags & GF_PATH_FILL_ZERO_NONZERO)) {
				drawable->path->flags |= GF_PATH_FILL_ZERO_NONZERO;
				drawable_mark_modified(drawable, tr_state);
			}
		} else {
			if (drawable->path->flags & GF_PATH_FILL_ZERO_NONZERO) {
				drawable->path->flags &= ~GF_PATH_FILL_ZERO_NONZERO;
				drawable_mark_modified(drawable, tr_state);
			}
		}
	}

	if (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS) {
		if (! compositor_svg_is_display_off(tr_state->svg_props)) {
			DrawAspect2D asp;
			gf_path_get_bounds(drawable->path, &tr_state->bounds);
			if (!tr_state->ignore_strike) {
				memset(&asp, 0, sizeof(DrawAspect2D));
				drawable_get_aspect_2d_svg(node, &asp, tr_state);
				if (asp.pen_props.width) {
					StrikeInfo2D *si = drawable_get_strikeinfo(tr_state->visual->compositor, drawable, &asp, NULL, drawable->path, 0, NULL);
					if (si && si->outline) {
						gf_path_get_bounds(si->outline, &tr_state->bounds);
					}
				}
			}
			compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, NULL);
			if (!tr_state->abort_bounds_traverse)
				gf_mx2d_apply_rect(&tr_state->transform, &tr_state->bounds);
			gf_sc_get_nodes_bounds(node, NULL, tr_state, NULL);

			compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, NULL);
		}
	} else if (tr_state->traversing_mode == TRAVERSE_SORT) {
		/*reset our flags - this may break reuse of nodes and change-detection in dirty-rect algo */
		gf_node_dirty_clear(node, 0);

		if (!compositor_svg_is_display_off(tr_state->svg_props) &&
			( *(tr_state->svg_props->visibility) != SVG_VISIBILITY_HIDDEN) ) {

			compositor_svg_apply_local_transformation(tr_state, &all_atts, &backup_matrix, &mx_3d);

			ctx = drawable_init_context_svg(drawable, tr_state);
			if (ctx) {
				if (is_svg_rect) {
					if (ctx->aspect.fill_texture && ctx->aspect.fill_texture->transparent) {}
					else if (GF_COL_A(ctx->aspect.fill_color) != 0xFF) {}
					else if (ctx->transform.m[1] || ctx->transform.m[3]) {}
					else {
						ctx->flags &= ~CTX_IS_TRANSPARENT;
						if (!ctx->aspect.pen_props.width) 
							ctx->flags |= CTX_NO_ANTIALIAS;
					}
				}

				if (all_atts.pathLength && all_atts.pathLength->type==SVG_NUMBER_VALUE) 
					ctx->aspect.pen_props.path_length = all_atts.pathLength->value;

#ifndef GPAC_DISABLE_3D
				if (tr_state->visual->type_3d) {
					if (!drawable->mesh) {
						drawable->mesh = new_mesh();
						if (drawable->path) mesh_from_path(drawable->mesh, drawable->path);
					}
					visual_3d_draw_from_context(ctx, tr_state);
					ctx->drawable = NULL;
				} else 
#endif
				{
					drawable_finalize_sort(ctx, tr_state, NULL);
				}
			}
			compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d);
		}
	}

	memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers));
	tr_state->svg_flags = backup_flags;
}
Beispiel #9
0
static void TraverseTriangleSet2D(GF_Node *node, void *rs, Bool is_destroy)
{
	DrawableContext *ctx;
	Drawable *stack = (Drawable *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		drawable_node_del(node);
		return;
	}

	triangleset2d_check_changes(node, stack, tr_state);

	switch (tr_state->traversing_mode) {
#ifndef GPAC_DISABLE_3D
	case TRAVERSE_DRAW_3D:
		if (!stack->mesh) {
			SFColorRGBA col;
			u32 i, count, idx;
			GF_Vertex v1, v2, v3;
			X_TriangleSet2D *p = (X_TriangleSet2D *)node;

			stack->mesh = new_mesh();
			stack->mesh->mesh_type = MESH_TRIANGLES;
			col.red = col.green = col.blue = 0;
			col.alpha = FIX_ONE;
			v1.color = MESH_MAKE_COL(col);
			v1.normal.x = v1.normal.y = 0;
			v1.normal.z = MESH_NORMAL_UNIT;
			v1.pos.z = 0;
			v3 = v2 = v1;
			count = p->vertices.count;
			while (count%3) count--;
			for (i=0; i<count; i+=3) {
				idx = stack->mesh->v_count;
				v1.pos.x = p->vertices.vals[i].x;
				v1.pos.y = p->vertices.vals[i].y;
				v2.pos.x = p->vertices.vals[i+1].x;
				v2.pos.y = p->vertices.vals[i+1].y;
				v3.pos.x = p->vertices.vals[i+2].x;
				v3.pos.y = p->vertices.vals[i+2].y;
				mesh_set_vertex_vx(stack->mesh, &v1);
				mesh_set_vertex_vx(stack->mesh, &v2);
				mesh_set_vertex_vx(stack->mesh, &v3);
				gf_vec_diff(v2.pos, v2.pos, v1.pos);
				gf_vec_diff(v3.pos, v3.pos, v1.pos);
				v1.pos = gf_vec_cross(v2.pos, v3.pos);
				if (v1.pos.z<0) {
					mesh_set_triangle(stack->mesh, idx, idx+2, idx+1);
				} else {
					mesh_set_triangle(stack->mesh, idx, idx+1, idx+2);
				}
			}
			stack->mesh->flags |= MESH_IS_2D;
			mesh_update_bounds(stack->mesh);
		}
		visual_3d_draw_2d(stack, tr_state);
		return;
#endif
	case TRAVERSE_GET_BOUNDS:
		gf_path_get_bounds(stack->path, &tr_state->bounds);
		return;
	case TRAVERSE_PICK:
		vrml_drawable_pick(stack, tr_state);
		return;
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) return;
#endif
		ctx = drawable_init_context_mpeg4(stack, tr_state);
		if (!ctx) return;
		drawable_finalize_sort(ctx, tr_state, NULL);
		return;
	}
}
static void TraverseIFS2D(GF_Node *node, void *rs, Bool is_destroy)
{
	DrawableContext *ctx;
	M_IndexedFaceSet2D *ifs2D = (M_IndexedFaceSet2D *)node;
	Drawable *stack = (Drawable *)gf_node_get_private(node);
	GF_TraverseState *tr_state = (GF_TraverseState *)rs;

	if (is_destroy) {
		drawable_node_del(node);
		return;
	}
	if (!ifs2D->coord) return;

	ifs2d_check_changes(node, stack, tr_state);

	switch (tr_state->traversing_mode) {
	case TRAVERSE_DRAW_2D:
		IFS2D_Draw(node, tr_state);
		return;
#ifndef GPAC_DISABLE_3D
	case TRAVERSE_DRAW_3D:
	{
		DrawAspect2D asp;

		if (!stack->mesh) {
			stack->mesh = new_mesh();
			mesh_new_ifs2d(stack->mesh, node);
		}

		memset(&asp, 0, sizeof(DrawAspect2D));
		drawable_get_aspect_2d_mpeg4(node, &asp, tr_state);
		if (ifs2D->color && !GF_COL_A(asp.fill_color) ) {
			/*use special func to disable outline recompute and handle recompute ourselves*/
			StrikeInfo2D *si = drawable_get_strikeinfo(tr_state->visual->compositor, stack, &asp, tr_state->appear, NULL, 0, tr_state);
			if (!si->mesh_outline) {
				si->mesh_outline = new_mesh();
				mesh_new_ils(si->mesh_outline, ifs2D->coord, &ifs2D->coordIndex, ifs2D->color, &ifs2D->colorIndex, ifs2D->colorPerVertex, 1);
			}
			visual_3d_mesh_strike(tr_state, si->mesh_outline, asp.pen_props.width, asp.line_scale, asp.pen_props.dash);
		} else {
			visual_3d_draw_2d_with_aspect(stack, tr_state, &asp);
		}
		return;
	} 
#endif
	case TRAVERSE_PICK:
		vrml_drawable_pick(stack, tr_state);
		return;
	case TRAVERSE_GET_BOUNDS:
		gf_path_get_bounds(stack->path, &tr_state->bounds);
		return;
	case TRAVERSE_SORT:
#ifndef GPAC_DISABLE_3D
		if (tr_state->visual->type_3d) return;
#endif

		ctx = drawable_init_context_mpeg4(stack, tr_state);
		if (!ctx) return;
		drawable_finalize_sort(ctx, tr_state, NULL);
		return;
	}
}