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); } } }
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); }
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); } }
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; }