Exemplo n.º 1
0
static void uv_warp_compute(void *userdata, const int i)
{
	const UVWarpData *data = userdata;

	const MPoly *mp = &data->mpoly[i];
	const MLoop *ml = &data->mloop[mp->loopstart];
	MLoopUV *mluv = &data->mloopuv[mp->loopstart];

	const MDeformVert *dvert = data->dvert;
	const int defgrp_index = data->defgrp_index;

	float (*warp_mat)[4] = data->warp_mat;
	const int axis_u = data->axis_u;
	const int axis_v = data->axis_v;

	int l;

	if (dvert) {
		for (l = 0; l < mp->totloop; l++, ml++, mluv++) {
			float uv[2];
			const float weight = defvert_find_weight(&dvert[ml->v], defgrp_index);

			uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat, axis_u, axis_v);
			interp_v2_v2v2(mluv->uv, mluv->uv, uv, weight);
		}
	}
	else {
		for (l = 0; l < mp->totloop; l++, ml++, mluv++) {
			uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat, axis_u, axis_v);
		}
	}
}
Exemplo n.º 2
0
static void stroke_elem_interp(
        struct StrokeElem *selem_out,
        const struct StrokeElem *selem_a,  const struct StrokeElem *selem_b, float t)
{
	interp_v2_v2v2(selem_out->mval, selem_a->mval, selem_b->mval, t);
	interp_v3_v3v3(selem_out->location_world, selem_a->location_world, selem_b->location_world, t);
	interp_v3_v3v3(selem_out->location_local, selem_a->location_local, selem_b->location_local, t);
	selem_out->pressure = interpf(selem_a->pressure, selem_b->pressure, t);
}
Exemplo n.º 3
0
void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, const float mouse_pos[2])
{
	const float u = 0.5f;
	const float r = RAKE_THRESHHOLD;

	float dpos[2];
	sub_v2_v2v2(dpos, ups->last_rake, mouse_pos);

	if (len_squared_v2(dpos) >= r * r) {
		ups->brush_rotation = atan2(dpos[0], dpos[1]);

		interp_v2_v2v2(ups->last_rake, ups->last_rake,
		               mouse_pos, u);
	}
}
/* NOTE: frame number should be in clip space, not scene space */
static void track_plane_from_existing_motion(MovieTrackingPlaneTrack *plane_track, int start_frame,
                                             int direction, bool retrack)
{
	MovieTrackingPlaneMarker *start_plane_marker = BKE_tracking_plane_marker_get(plane_track, start_frame);
	MovieTrackingPlaneMarker *keyframe_plane_marker = NULL;
	MovieTrackingPlaneMarker new_plane_marker;
	int current_frame, frame_delta = direction > 0 ? 1 : -1;

	if (plane_track->flag & PLANE_TRACK_AUTOKEY) {
		/* Find a keyframe in given direction. */
		for (current_frame = start_frame; ; current_frame += frame_delta) {
			MovieTrackingPlaneMarker *next_plane_marker =
				BKE_tracking_plane_marker_get_exact(plane_track, current_frame + frame_delta);

			if (next_plane_marker == NULL) {
				break;
			}

			if ((next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
				keyframe_plane_marker = next_plane_marker;
				break;
			}
		}
	}
	else {
		start_plane_marker->flag |= PLANE_MARKER_TRACKED;
	}

	new_plane_marker = *start_plane_marker;
	new_plane_marker.flag |= PLANE_MARKER_TRACKED;

	for (current_frame = start_frame; ; current_frame += frame_delta) {
		MovieTrackingPlaneMarker *next_plane_marker =
			BKE_tracking_plane_marker_get_exact(plane_track, current_frame + frame_delta);
		Vec2 *x1, *x2;
		int i, num_correspondences;
		double H_double[3][3];
		float H[3][3];

		/* As soon as we meet keyframed plane, we stop updating the sequence. */
		if (next_plane_marker && (next_plane_marker->flag & PLANE_MARKER_TRACKED) == 0) {
			/* Don't override keyframes if track is in auto-keyframe mode */
			if (plane_track->flag & PLANE_TRACK_AUTOKEY) {
				break;
			}
		}

		num_correspondences =
			point_markers_correspondences_on_both_image(plane_track, current_frame, current_frame + frame_delta,
			                                            &x1, &x2);

		if (num_correspondences < 4) {
			MEM_freeN(x1);
			MEM_freeN(x2);

			break;
		}

		libmv_homography2DFromCorrespondencesEuc(x1, x2, num_correspondences, H_double);

		copy_m3_m3d(H, H_double);

		for (i = 0; i < 4; i++) {
			float vec[3] = {0.0f, 0.0f, 1.0f}, vec2[3];
			copy_v2_v2(vec, new_plane_marker.corners[i]);

			/* Apply homography */
			mul_v3_m3v3(vec2, H, vec);

			/* Normalize. */
			vec2[0] /= vec2[2];
			vec2[1] /= vec2[2];

			copy_v2_v2(new_plane_marker.corners[i], vec2);
		}

		new_plane_marker.framenr = current_frame + frame_delta;

		if (!retrack && keyframe_plane_marker &&
		    next_plane_marker &&
		    (plane_track->flag & PLANE_TRACK_AUTOKEY))
		{
			float fac = ((float) next_plane_marker->framenr - start_plane_marker->framenr) /
			            ((float) keyframe_plane_marker->framenr - start_plane_marker->framenr);

			fac = 3 * fac * fac - 2 * fac * fac * fac;

			for (i = 0; i < 4; i++) {
				interp_v2_v2v2(new_plane_marker.corners[i], new_plane_marker.corners[i],
				               next_plane_marker->corners[i], fac);
			}
		}

		BKE_tracking_plane_marker_insert(plane_track, &new_plane_marker);

		MEM_freeN(x1);
		MEM_freeN(x2);
	}
}
Exemplo n.º 5
0
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
                                  DerivedMesh *dm,
                                  ModifierApplyFlag UNUSED(flag))
{
	UVWarpModifierData *umd = (UVWarpModifierData *) md;
	int i, numPolys, numLoops;
	MPoly *mpoly;
	MLoop *mloop;
	MLoopUV *mloopuv;
	MDeformVert *dvert;
	int defgrp_index;
	char uvname[MAX_CUSTOMDATA_LAYER_NAME];
	float mat_src[4][4];
	float mat_dst[4][4];
	float imat_dst[4][4];
	float warp_mat[4][4];
	const int axis_u = umd->axis_u;
	const int axis_v = umd->axis_v;

	/* make sure there are UV Maps available */
	if (!CustomData_has_layer(&dm->loopData, CD_MLOOPUV)) {
		return dm;
	}
	else if (ELEM(NULL, umd->object_src, umd->object_dst)) {
		modifier_setError(md, "From/To objects must be set");
		return dm;
	}

	/* make sure anything moving UVs is available */
	matrix_from_obj_pchan(mat_src, umd->object_src, umd->bone_src);
	matrix_from_obj_pchan(mat_dst, umd->object_dst, umd->bone_dst);

	invert_m4_m4(imat_dst, mat_dst);
	mul_m4_m4m4(warp_mat, imat_dst, mat_src);

	/* apply warp */
	if (!is_zero_v2(umd->center)) {
		float mat_cent[4][4];
		float imat_cent[4][4];

		unit_m4(mat_cent);
		mat_cent[3][axis_u] = umd->center[0];
		mat_cent[3][axis_v] = umd->center[1];

		invert_m4_m4(imat_cent, mat_cent);

		mul_m4_m4m4(warp_mat, warp_mat, imat_cent);
		mul_m4_m4m4(warp_mat, mat_cent, warp_mat);
	}

	/* make sure we're using an existing layer */
	CustomData_validate_layer_name(&dm->loopData, CD_MLOOPUV, umd->uvlayer_name, uvname);

	numPolys = dm->getNumPolys(dm);
	numLoops = dm->getNumLoops(dm);

	mpoly = dm->getPolyArray(dm);
	mloop = dm->getLoopArray(dm);
	/* make sure we are not modifying the original UV map */
	mloopuv = CustomData_duplicate_referenced_layer_named(&dm->loopData, CD_MLOOPUV, uvname, numLoops);
	modifier_get_vgroup(ob, dm, umd->vgroup_name, &dvert, &defgrp_index);

	if (dvert) {
#pragma omp parallel for if (numPolys > OMP_LIMIT)
		for (i = 0; i < numPolys; i++) {
			float uv[2];
			MPoly *mp     = &mpoly[i];
			MLoop *ml     = &mloop[mp->loopstart];
			MLoopUV *mluv = &mloopuv[mp->loopstart];
			int l;
			for (l = 0; l < mp->totloop; l++, ml++, mluv++) {
				const float weight = defvert_find_weight(&dvert[ml->v], defgrp_index);
				uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat, axis_u, axis_v);
				interp_v2_v2v2(mluv->uv, mluv->uv, uv, weight);
			}
		}
	}
	else {
#pragma omp parallel for if (numPolys > OMP_LIMIT)
		for (i = 0; i < numPolys; i++) {
			MPoly *mp     = &mpoly[i];
			// MLoop *ml     = &mloop[mp->loopstart];
			MLoopUV *mluv = &mloopuv[mp->loopstart];
			int l;
			for (l = 0; l < mp->totloop; l++, /* ml++, */ mluv++) {
				uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat, axis_u, axis_v);
			}
		}
	}

	dm->dirty |= DM_DIRTY_TESS_CDLAYERS;

	return dm;
}