diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_math_matrix.h | 3 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_matrix.c | 10 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 12 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 6 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_modifier.c | 15 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_uvwarp.c | 83 |
6 files changed, 90 insertions, 39 deletions
diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index ac0f5f44c74..acefe18fd40 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -60,6 +60,9 @@ void copy_m4d_m4(double R[4][4], const float A[4][4]); void swap_m3m3(float A[3][3], float B[3][3]); void swap_m4m4(float A[4][4], float B[4][4]); +/* Build index shuffle matrix */ +void shuffle_m4(float R[4][4], int index[4]); + /******************************** Arithmetic *********************************/ void add_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3]); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 4d8a2f72eca..86a08a42247 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -210,6 +210,16 @@ void swap_m4m4(float m1[4][4], float m2[4][4]) } } +void shuffle_m4(float R[4][4], int index[4]) +{ + zero_m4(R); + for (int k = 0; k < 4; k++) { + if (index[k] >= 0) { + R[index[k]][k] = 1.0f; + } + } +} + /******************************** Arithmetic *********************************/ void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4]) diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 886c7195d9e..8baea5c8c4b 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -4482,5 +4482,17 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) } } } + + /* Add 2D transform to UV Warp modifier. */ + if (!DNA_struct_elem_find(fd->filesdna, "UVWarpModifierData", "float", "scale[2]")) { + for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { + for (ModifierData *md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_UVWarp) { + UVWarpModifierData *umd = (UVWarpModifierData *)md; + copy_v2_fl(umd->scale, 1.0f); + } + } + } + } } } diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 82237a10d23..7a61118921d 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -1742,10 +1742,14 @@ typedef struct UVWarpModifierData { ModifierData modifier; char axis_u, axis_v; - char _pad[6]; + char _pad[2]; /** Used for rotate/scale. */ float center[2]; + float offset[2]; + float scale[2]; + float rotation; + /** Source. */ struct Object *object_src; /** Optional name of bone target, MAX_ID_NAME-2. */ diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index eb88f4523ab..ea0f917ca77 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -4599,6 +4599,21 @@ static void rna_def_modifier_uvwarp(BlenderRNA *brna) RNA_def_property_ui_text(prop, "UV Center", "Center point for rotate/scale"); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "offset"); + RNA_def_property_ui_text(prop, "Offset", "2D Offset for the warp"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "scale"); + RNA_def_property_ui_text(prop, "Scale", "2D Scale for the warp"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + + prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_ANGLE); + RNA_def_property_float_sdna(prop, NULL, "rotation"); + RNA_def_property_ui_text(prop, "Rotation", "2D Rotation for the warp"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "object_from", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "object_src"); RNA_def_property_ui_text(prop, "Object From", "Object defining offset"); diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c index dd9787c3c0b..2dfb9031c38 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.c +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -38,18 +38,13 @@ #include "MOD_util.h" -static void uv_warp_from_mat4_pair( - float uv_dst[2], const float uv_src[2], float warp_mat[4][4], int axis_u, int axis_v) +static void uv_warp_from_mat4_pair(float uv_dst[2], const float uv_src[2], float warp_mat[4][4]) { float tuv[3] = {0.0f}; - tuv[axis_u] = uv_src[0]; - tuv[axis_v] = uv_src[1]; - + copy_v2_v2(tuv, uv_src); mul_m4_v3(warp_mat, tuv); - - uv_dst[0] = tuv[axis_u]; - uv_dst[1] = tuv[axis_v]; + copy_v2_v2(uv_dst, tuv); } static void initData(ModifierData *md) @@ -58,6 +53,7 @@ static void initData(ModifierData *md) umd->axis_u = 0; umd->axis_v = 1; copy_v2_fl(umd->center, 0.5f); + copy_v2_fl(umd->scale, 1.0f); } static void requiredDataMask(Object *UNUSED(ob), @@ -92,8 +88,6 @@ typedef struct UVWarpData { int defgrp_index; float (*warp_mat)[4]; - int axis_u; - int axis_v; } UVWarpData; static void uv_warp_compute(void *__restrict userdata, @@ -110,8 +104,6 @@ static void uv_warp_compute(void *__restrict userdata, 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; @@ -120,13 +112,13 @@ static void uv_warp_compute(void *__restrict userdata, 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); + uv_warp_from_mat4_pair(uv, mluv->uv, warp_mat); 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); + uv_warp_from_mat4_pair(mluv->uv, mluv->uv, warp_mat); } } } @@ -141,9 +133,6 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes 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; @@ -152,32 +141,52 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (!CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) { return mesh; } - else if (ELEM(NULL, umd->object_src, umd->object_dst)) { - modifier_setError(md, "From/To objects must be set"); - return mesh; - } - /* 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); + if (!ELEM(NULL, umd->object_src, umd->object_dst)) { + float mat_src[4][4]; + float mat_dst[4][4]; + float imat_dst[4][4]; + float shuf_mat[4][4]; + + /* 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); + 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]; + /* 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]; + 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); + 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); + mul_m4_m4m4(warp_mat, warp_mat, imat_cent); + mul_m4_m4m4(warp_mat, mat_cent, warp_mat); + } + + int shuf_indices[4] = {axis_u, axis_v, -1, 3}; + shuffle_m4(shuf_mat, shuf_indices); + mul_m4_m4m4(warp_mat, shuf_mat, warp_mat); + transpose_m4(shuf_mat); + mul_m4_m4m4(warp_mat, warp_mat, shuf_mat); } + else { + unit_m4(warp_mat); + } + + /* Apply direct 2d transform. */ + translate_m4(warp_mat, umd->center[0], umd->center[1], 0.0f); + const float scale[3] = {umd->scale[0], umd->scale[1], 1.0f}; + rescale_m4(warp_mat, scale); + rotate_m4(warp_mat, 'Z', umd->rotation); + translate_m4(warp_mat, umd->offset[0], umd->offset[1], 0.0f); + translate_m4(warp_mat, -umd->center[0], -umd->center[1], 0.0f); /* make sure we're using an existing layer */ CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, umd->uvlayer_name, uvname); @@ -199,8 +208,6 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes .dvert = dvert, .defgrp_index = defgrp_index, .warp_mat = warp_mat, - .axis_u = axis_u, - .axis_v = axis_v, }; TaskParallelSettings settings; BLI_parallel_range_settings_defaults(&settings); |