示例#1
0
文件: surface.c 项目: golgol7777/gpac
GF_Err evg_surface_set_path(GF_SURFACE _this, GF_Path *gp)
{
#ifndef INLINE_POINT_CONVERSION
	u32 i;
	GF_Point2D pt;
#endif
	EVGSurface *surf = (EVGSurface *)_this;

	if (!surf) return GF_BAD_PARAM;
	if (!gp || !gp->n_points) {
		surf->ftoutline.n_points = 0;
		surf->ftoutline.n_contours = 0;
		return GF_OK;
	}
	gf_path_flatten(gp);
	surf->ftoutline.n_points = gp->n_points;
	surf->ftoutline.n_contours = gp->n_contours;

	surf->ftoutline.tags = gp->tags;
	surf->ftoutline.contours = (s32*) gp->contours;

	/*store path bounds for gradient/textures*/
	gf_path_get_bounds(gp, &surf->path_bounds);
	/*invert Y (ft uses min Y)*/
	surf->path_bounds.y -= surf->path_bounds.height;

	surf->ftoutline.flags = 0;
	if (gp->flags & GF_PATH_FILL_ZERO_NONZERO) surf->ftoutline.flags = GF_PATH_FILL_ZERO_NONZERO;

#ifdef INLINE_POINT_CONVERSION
	surf->ftoutline.n_points = gp->n_points;
	surf->ftoutline.points = gp->points;
	surf->ftparams.mx = &surf->mat;
#else
	if (surf->pointlen < gp->n_points) {
		surf->points = gf_realloc(surf->points, sizeof(EVG_Vector) * gp->n_points);
		if (surf->points == NULL) {
			surf->pointlen = 0;
			return GF_OUT_OF_MEM;
		}
		surf->pointlen = gp->n_points;
	}
	surf->ftoutline.points = surf->points;
	
	for (i=0; i<gp->n_points; i++) {
		pt = gp->points[i];
		gf_mx2d_apply_point(&surf->mat, &pt);
#ifdef GPAC_FIXED_POINT
		surf->points[i].x = pt.x;
		surf->points[i].y = pt.y;
#else
		/*move to 16.16 representation*/
		surf->points[i].x = (u32) (pt.x * 0x10000L);
		surf->points[i].y = (u32) (pt.y * 0x10000L);
#endif
	}
#endif
	return GF_OK;
}
示例#2
0
static void TraversePlanarExtrusion(GF_Node *node, void *rs, Bool is_destroy)
{
    PlanarExtrusion plane_ext;
    Drawable *stack_2d;
    u32 i, j, k;
    MFVec3f spine_vec;
    SFVec3f d;
    Fixed spine_len;
    GF_Rect bounds;
    GF_Path *geo, *spine;
    GF_TraverseState *tr_state = (GF_TraverseState *)rs;
    Drawable3D *stack = (Drawable3D *)gf_node_get_private(node);

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

    if (!PlanarExtrusion_GetNode(node, &plane_ext)) return;
    if (!plane_ext.geometry || !plane_ext.spine) return;


    if (gf_node_dirty_get(node)) {
        u32 cur, nb_pts;
        u32 mode = tr_state->traversing_mode;
        geo = spine = NULL;

        tr_state->traversing_mode = TRAVERSE_GET_BOUNDS;
        gf_node_traverse(plane_ext.geometry, tr_state);
        gf_node_traverse(plane_ext.spine, tr_state);
        tr_state->traversing_mode = mode;

        switch (gf_node_get_tag(plane_ext.geometry) ) {
        case TAG_MPEG4_Circle:
        case TAG_MPEG4_Ellipse:
        case TAG_MPEG4_Rectangle:
        case TAG_MPEG4_Curve2D:
        case TAG_MPEG4_XCurve2D:
        case TAG_MPEG4_IndexedFaceSet2D:
        case TAG_MPEG4_IndexedLineSet2D:
            stack_2d = (Drawable*)gf_node_get_private(plane_ext.geometry);
            if (stack_2d) geo = stack_2d->path;
            break;
        default:
            return;
        }
        switch (gf_node_get_tag(plane_ext.spine) ) {
        case TAG_MPEG4_Circle:
        case TAG_MPEG4_Ellipse:
        case TAG_MPEG4_Rectangle:
        case TAG_MPEG4_Curve2D:
        case TAG_MPEG4_XCurve2D:
        case TAG_MPEG4_IndexedFaceSet2D:
        case TAG_MPEG4_IndexedLineSet2D:
            stack_2d = (Drawable*)gf_node_get_private(plane_ext.spine);
            if (stack_2d) spine = stack_2d->path;
            break;
        default:
            return;
        }
        if (!geo || !spine) return;

        mesh_reset(stack->mesh);
        gf_path_flatten(spine);
        gf_path_get_bounds(spine, &bounds);
        gf_path_flatten(geo);
        gf_path_get_bounds(geo, &bounds);

        cur = 0;
        for (i=0; i<spine->n_contours; i++) {
            nb_pts = 1 + spine->contours[i] - cur;
            spine_vec.vals = NULL;
            gf_sg_vrml_mf_alloc(&spine_vec, GF_SG_VRML_MFVEC3F, nb_pts);
            spine_len = 0;
            for (j=cur; j<nb_pts; j++) {
                spine_vec.vals[j].x = spine->points[j].x;
                spine_vec.vals[j].y = spine->points[j].y;
                spine_vec.vals[j].z = 0;
                if (j) {
                    gf_vec_diff(d, spine_vec.vals[j], spine_vec.vals[j-1]);
                    spine_len += gf_vec_len(d);
                }
            }
            cur += nb_pts;
            if (!plane_ext.orientation->count && !plane_ext.scale->count) {
                mesh_extrude_path_ext(stack->mesh, geo, &spine_vec, plane_ext.creaseAngle,
                                      bounds.x, bounds.y-bounds.height, bounds.width, bounds.height,
                                      plane_ext.beginCap, plane_ext.endCap, NULL, NULL, plane_ext.txAlongSpine);
            }
            /*interpolate orientation and scale along subpath line*/
            else {
                MFRotation ori;
                MFVec2f scale;
                Fixed cur_len, frac;

                ori.vals = NULL;
                gf_sg_vrml_mf_alloc(&ori, GF_SG_VRML_MFROTATION, nb_pts);
                scale.vals = NULL;
                gf_sg_vrml_mf_alloc(&scale, GF_SG_VRML_MFVEC2F, nb_pts);
                cur_len = 0;
                if (!plane_ext.orientation->count) ori.vals[0].y = FIX_ONE;
                if (!plane_ext.scale->count) scale.vals[0].x = scale.vals[0].y = FIX_ONE;
                for (j=0; j<nb_pts; j++) {
                    if (j) {
                        gf_vec_diff(d, spine_vec.vals[j], spine_vec.vals[j-1]);
                        cur_len += gf_vec_len(d);
                        ori.vals[j] = ori.vals[j-1];
                        scale.vals[j] = scale.vals[j-1];
                    }

                    if (plane_ext.orientation->count && (plane_ext.orientation->count == plane_ext.orientationKeys->count)) {

                        frac = gf_divfix(cur_len , spine_len);
                        if (frac < plane_ext.orientationKeys->vals[0]) ori.vals[j] = plane_ext.orientation->vals[0];
                        else if (frac >= plane_ext.orientationKeys->vals[plane_ext.orientationKeys->count-1]) ori.vals[j] = plane_ext.orientation->vals[plane_ext.orientationKeys->count-1];
                        else {
                            for (k=1; k<plane_ext.orientationKeys->count; k++) {
                                Fixed kDiff = plane_ext.orientationKeys->vals[k] - plane_ext.orientationKeys->vals[k-1];
                                if (!kDiff) continue;
                                if (frac < plane_ext.orientationKeys->vals[k-1]) continue;
                                if (frac > plane_ext.orientationKeys->vals[k]) continue;
                                frac = gf_divfix(frac - plane_ext.orientationKeys->vals[k-1], kDiff);
                                break;
                            }
                            ori.vals[j] = gf_sg_sfrotation_interpolate(plane_ext.orientation->vals[k-1], plane_ext.orientation->vals[k], frac);
                        }
                    }

                    if (plane_ext.scale->count == plane_ext.scaleKeys->count) {
                        frac = gf_divfix(cur_len , spine_len);
                        if (frac <= plane_ext.scaleKeys->vals[0]) scale.vals[j] = plane_ext.scale->vals[0];
                        else if (frac >= plane_ext.scaleKeys->vals[plane_ext.scaleKeys->count-1]) scale.vals[j] = plane_ext.scale->vals[plane_ext.scale->count-1];
                        else {
                            for (k=1; k<plane_ext.scaleKeys->count; k++) {
                                Fixed kDiff = plane_ext.scaleKeys->vals[k] - plane_ext.scaleKeys->vals[k-1];
                                if (!kDiff) continue;
                                if (frac < plane_ext.scaleKeys->vals[k-1]) continue;
                                if (frac > plane_ext.scaleKeys->vals[k]) continue;
                                frac = gf_divfix(frac - plane_ext.scaleKeys->vals[k-1], kDiff);
                                break;
                            }
                            scale.vals[j].x = gf_mulfix(plane_ext.scale->vals[k].x - plane_ext.scale->vals[k-1].x, frac) + plane_ext.scale->vals[k-1].x;
                            scale.vals[j].y = gf_mulfix(plane_ext.scale->vals[k].y - plane_ext.scale->vals[k-1].y, frac) + plane_ext.scale->vals[k-1].y;
                        }
                    }
                }

                mesh_extrude_path_ext(stack->mesh, geo, &spine_vec, plane_ext.creaseAngle,
                                      bounds.x, bounds.y-bounds.height, bounds.width, bounds.height,
                                      plane_ext.beginCap, plane_ext.endCap, &ori, &scale, plane_ext.txAlongSpine);

                gf_sg_vrml_mf_reset(&ori, GF_SG_VRML_MFROTATION);
                gf_sg_vrml_mf_reset(&scale, GF_SG_VRML_MFVEC2F);
            }

            gf_sg_vrml_mf_reset(&spine_vec, GF_SG_VRML_MFVEC3F);
        }
        mesh_update_bounds(stack->mesh);
        gf_mesh_build_aabbtree(stack->mesh);
    }

    if (tr_state->traversing_mode==TRAVERSE_DRAW_3D) {
        visual_3d_draw(tr_state, stack->mesh);
    } else if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) {
        tr_state->bbox = stack->mesh->bounds;
    }
}