예제 #1
0
파일: path2d.c 프로젝트: erelh/gpac
GF_EXPORT
GF_Err gf_path_add_arc_to(GF_Path *gp, Fixed end_x, Fixed end_y, Fixed fa_x, Fixed fa_y, Fixed fb_x, Fixed fb_y, Bool cw)
{
	GF_Matrix2D mat, inv;
	Fixed angle, start_angle, end_angle, sweep, axis_w, axis_h, tmp, cx, cy, _vx, _vy, start_x, start_y;
	s32 i, num_steps;

	if (!gp->n_points) return GF_BAD_PARAM;

	start_x = gp->points[gp->n_points-1].x;
	start_y = gp->points[gp->n_points-1].y;

	cx = (fb_x + fa_x)/2;
	cy = (fb_y + fa_y)/2;

	angle = gf_atan2(fb_y-fa_y, fb_x-fa_x);
	gf_mx2d_init(mat);
	gf_mx2d_add_rotation(&mat, 0, 0, angle);
	gf_mx2d_add_translation(&mat, cx, cy);

	gf_mx2d_copy(inv, mat);
	gf_mx2d_inverse(&inv);
	gf_mx2d_apply_coords(&inv, &start_x, &start_y);
	gf_mx2d_apply_coords(&inv, &end_x, &end_y);
	gf_mx2d_apply_coords(&inv, &fa_x, &fa_y);
	gf_mx2d_apply_coords(&inv, &fb_x, &fb_y);

	//start angle and end angle
	start_angle = gf_atan2(start_y, start_x);
	end_angle = gf_atan2(end_y, end_x);
	tmp = gf_mulfix((start_x - fa_x), (start_x - fa_x)) + gf_mulfix((start_y - fa_y), (start_y - fa_y));
	axis_w = gf_sqrt(tmp);
	tmp = gf_mulfix((start_x - fb_x) , (start_x - fb_x)) + gf_mulfix((start_y - fb_y), (start_y - fb_y));
	axis_w += gf_sqrt(tmp);
	axis_w /= 2;
	axis_h = gf_sqrt(gf_mulfix(axis_w, axis_w) - gf_mulfix(fa_x,fa_x));
	sweep = end_angle - start_angle;

	if (cw) {
		if (sweep>0) sweep -= 2*GF_PI;
	} else {
		if (sweep<0) sweep += 2*GF_PI;
	}
	num_steps = GF_2D_DEFAULT_RES/2;
	for (i=1; i<=num_steps; i++) {
		angle = start_angle + sweep*i/num_steps;
		_vx = gf_mulfix(axis_w, gf_cos(angle));
		_vy = gf_mulfix(axis_h, gf_sin(angle));
		/*re-invert*/
		gf_mx2d_apply_coords(&mat, &_vx, &_vy);
		gf_path_add_line_to(gp, _vx, _vy);
	}
	return GF_OK;
}
예제 #2
0
파일: path2d.c 프로젝트: erelh/gpac
GF_Err gf_path_add_subpath(GF_Path *gp, GF_Path *src, GF_Matrix2D *mx)
{
	u32 i;
	if (!src) return GF_OK;
	gp->contours = gf_realloc(gp->contours, sizeof(u32) * (gp->n_contours + src->n_contours));
	if (!gp->contours) return GF_OUT_OF_MEM;
	for (i=0; i<src->n_contours; i++) {
		gp->contours[i+gp->n_contours] = src->contours[i] + gp->n_points;
	}
	gp->n_contours += src->n_contours;
	gp->n_alloc_points += src->n_alloc_points;
	gp->points = gf_realloc(gp->points, sizeof(GF_Point2D)*gp->n_alloc_points);
	if (!gp->points) return GF_OUT_OF_MEM;
	gp->tags = gf_realloc(gp->tags, sizeof(u8)*gp->n_alloc_points);
	if (!gp->tags) return GF_OUT_OF_MEM;
	memcpy(gp->points + gp->n_points, src->points, sizeof(GF_Point2D)*src->n_points);
	if (mx) {
		for (i=0;i<src->n_points; i++) {
			gf_mx2d_apply_coords(mx, &gp->points[i+gp->n_points].x, &gp->points[i+gp->n_points].y);
		}
	}
	memcpy(gp->tags + gp->n_points, src->tags, sizeof(u8)*src->n_points);
	gp->n_points += src->n_points;
	gf_rect_union(&gp->bbox, &src->bbox);
	if (!(src->flags & GF_PATH_FLATTENED)) gp->flags &= ~GF_PATH_FLATTENED;
	if (src->flags & GF_PATH_BBOX_DIRTY) gp->flags |= GF_PATH_BBOX_DIRTY;
	return GF_OK;
}
예제 #3
0
GF_Node *CT2D_PickNode(GF_TextureHandler *txh, DrawableContext *ctx, Fixed x, Fixed y)
{
	GF_Rect orig;
	GF_Matrix2D mat, tx_trans;
	Fixed width, height;
	Composite2DStack *st = (Composite2DStack *) gf_node_get_private(txh->owner);
	assert(st->surf);

	orig = ctx->bi->unclip;
	gf_mx2d_copy(mat, ctx->transform);
	gf_mx2d_inverse(&mat);
	gf_mx2d_apply_rect(&mat, &orig);

	gf_mx2d_init(mat);
	gf_mx2d_add_scale(&mat, orig.width / st->width, orig.height / st->height);
	get_gf_sr_texture_transform(ctx->appear, &st->txh, &tx_trans, (ctx->h_texture==&st->txh) ? 0 : 1, INT2FIX(orig.width), INT2FIX(orig.height));
	gf_mx2d_add_matrix(&mat, &tx_trans);
	gf_mx2d_add_translation(&mat, (orig.x), (orig.y - orig.height));
	gf_mx2d_add_matrix(&mat, &ctx->transform);

	gf_mx2d_inverse(&mat);
	gf_mx2d_apply_coords(&mat, &x, &y);

	width = INT2FIX(st->width);
	height = INT2FIX(st->height);
	while (x>width) x -= width;
	while (x < 0) x += width;
	while (y>height) y -= height;
	while (y < 0) y += height;
	x -= width / 2;
	y -= height / 2;

	return VS2D_PickNode(st->surf, x, y);
}
예제 #4
0
/*sound2D wraper - spacialization is not supported yet*/
static void TraverseSound2D(GF_Node *node, void *rs, Bool is_destroy)
{
	GF_TraverseState *tr_state = (GF_TraverseState*) rs;
	M_Sound2D *snd = (M_Sound2D *)node;
	Sound2DStack *st = (Sound2DStack *)gf_node_get_private(node);
	
	if (is_destroy) {
		gf_free(st);
		return;
	}
	if (!snd->source) return;

	/*this implies no DEF/USE for real location...*/
	st->pos.x = snd->location.x;
	st->pos.y = snd->location.y;
	st->pos.z = 0;
#ifndef GPAC_DISABLE_3D
	if (tr_state->visual->type_3d) 
		gf_mx_apply_vec(&tr_state->model_matrix, &st->pos);
	else
#endif
		gf_mx2d_apply_coords(&tr_state->transform, &st->pos.x, &st->pos.y);
	

	tr_state->sound_holder = &st->snd_ifce;
	gf_node_traverse((GF_Node *) snd->source, tr_state);
	tr_state->sound_holder = NULL;
	/*never cull Sound2d*/
	tr_state->disable_cull = 1;
}
예제 #5
0
void svg_drawable_pick(GF_Node *node, Drawable *drawable, GF_TraverseState *tr_state)
{
	DrawAspect2D asp;
	GF_Matrix2D inv_2d;
	Fixed x, y;
	Bool picked = 0;
	GF_Compositor *compositor = tr_state->visual->compositor;
	SVGPropertiesPointers backup_props;
	GF_Matrix2D backup_matrix;
	GF_Matrix mx_3d;
	SVGAllAttributes all_atts;

	if (!drawable->path) return;

	gf_svg_flatten_attributes((SVG_Element *)node, &all_atts);

	memcpy(&backup_props, tr_state->svg_props, sizeof(SVGPropertiesPointers));
	gf_svg_apply_inheritance(&all_atts, tr_state->svg_props);
	if (compositor_svg_is_display_off(tr_state->svg_props)) return;

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

	memset(&asp, 0, sizeof(DrawAspect2D));
	drawable_get_aspect_2d_svg(node, &asp, tr_state);

#ifndef GPAC_DISABLE_3D
	if (tr_state->visual->type_3d) {
		svg_drawable_3d_pick(drawable, tr_state, &asp);
		compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d);
		memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers));
		return;
	} 
#endif
	gf_mx2d_copy(inv_2d, tr_state->transform);
	gf_mx2d_inverse(&inv_2d);
	x = tr_state->ray.orig.x;
	y = tr_state->ray.orig.y;
	gf_mx2d_apply_coords(&inv_2d, &x, &y);

	picked = svg_drawable_is_over(drawable, x, y, &asp, tr_state, NULL);

	if (picked) {
		u32 count, i;
		compositor->hit_local_point.x = x;
		compositor->hit_local_point.y = y;
		compositor->hit_local_point.z = 0;

		gf_mx_from_mx2d(&compositor->hit_world_to_local, &tr_state->transform);
		gf_mx_from_mx2d(&compositor->hit_local_to_world, &inv_2d);

		compositor->hit_node = drawable->node;
		compositor->hit_use_dom_events = 1;
		compositor->hit_normal.x = compositor->hit_normal.y = 0; compositor->hit_normal.z = FIX_ONE;
		compositor->hit_texcoords.x = gf_divfix(x, drawable->path->bbox.width) + FIX_ONE/2;
		compositor->hit_texcoords.y = gf_divfix(y, drawable->path->bbox.height) + FIX_ONE/2;
		svg_clone_use_stack(compositor, tr_state);
		/*not use in SVG patterns*/
		compositor->hit_appear = NULL;

		/*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(tr_state->visual->compositor->sensors);
		count = gf_list_count(tr_state->vrml_sensors);
		for (i=0; i<count; i++) {
			gf_list_add(tr_state->visual->compositor->sensors, gf_list_get(tr_state->vrml_sensors, i));
		}

		GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Picking] node %s is under mouse - hit %g %g 0\n", gf_node_get_log_name(drawable->node), FIX2FLT(x), FIX2FLT(y)));
	}

	compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d);
	memcpy(tr_state->svg_props, &backup_props, sizeof(SVGPropertiesPointers));
}