From e0a34e963fff4e569f6953325854b1c7acb6f1c6 Mon Sep 17 00:00:00 2001 From: Quentin Wenger Date: Sun, 23 Oct 2016 14:04:27 +0200 Subject: Displace modifier: add global/local space option for X/Y/Z/XYZ directions. Reviewed By: brecht Differential Revision: https://developer.blender.org/D2309 --- .../startup/bl_ui/properties_data_modifier.py | 3 ++ source/blender/makesdna/DNA_modifier_types.h | 8 ++- source/blender/makesrna/intern/rna_modifier.c | 11 ++++ source/blender/modifiers/intern/MOD_displace.c | 60 ++++++++++++++++++---- 4 files changed, 72 insertions(+), 10 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py index 84ee06c7d70..540c29f31e4 100644 --- a/release/scripts/startup/bl_ui/properties_data_modifier.py +++ b/release/scripts/startup/bl_ui/properties_data_modifier.py @@ -336,6 +336,9 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel): col = split.column(align=True) col.label(text="Direction:") col.prop(md, "direction", text="") + if md.direction in {'X', 'Y', 'Z', 'RGB_TO_XYZ'}: + col.label(text="Space:") + col.prop(md, "space", text="") col.label(text="Vertex Group:") col.prop_search(md, "vertex_group", ob, "vertex_groups", text="") diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 9187b76f012..1398e9de76f 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -383,7 +383,7 @@ typedef struct DisplaceModifierData { int direction; char defgrp_name[64]; /* MAX_VGROUP_NAME */ float midlevel; - int pad; + int space; } DisplaceModifierData; /* DisplaceModifierData->direction */ @@ -404,6 +404,12 @@ enum { MOD_DISP_MAP_UV = 3, }; +/* DisplaceModifierData->space */ +enum { + MOD_DISP_SPACE_LOCAL = 0, + MOD_DISP_SPACE_GLOBAL = 1, +}; + typedef struct UVProjectModifierData { ModifierData modifier; diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 34ca6a12fc3..39f6298ca61 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -2100,6 +2100,12 @@ static void rna_def_modifier_displace(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem prop_space_items[] = { + {MOD_DISP_SPACE_LOCAL, "LOCAL", 0, "Local", "Direction is defined in local coordinates"}, + {MOD_DISP_SPACE_GLOBAL, "GLOBAL", 0, "Global", "Direction is defined in global coordinates"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "DisplaceModifier", "Modifier"); RNA_def_struct_ui_text(srna, "Displace Modifier", "Displacement modifier"); RNA_def_struct_sdna(srna, "DisplaceModifierData"); @@ -2130,6 +2136,11 @@ static void rna_def_modifier_displace(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Direction", ""); RNA_def_property_update(prop, 0, "rna_Modifier_update"); + prop = RNA_def_property(srna, "space", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_space_items); + RNA_def_property_ui_text(prop, "Space", ""); + RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update"); + rna_def_modifier_generic_map_info(srna); } diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 9ba2d214d50..059e096ddb4 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -46,6 +46,7 @@ #include "BKE_modifier.h" #include "BKE_texture.h" #include "BKE_deform.h" +#include "BKE_object.h" #include "depsgraph_private.h" #include "MEM_guardedalloc.h" @@ -65,6 +66,7 @@ static void initData(ModifierData *md) dmd->strength = 1; dmd->direction = MOD_DISP_DIR_NOR; dmd->midlevel = 0.5; + dmd->space = MOD_DISP_SPACE_LOCAL; } static void copyData(ModifierData *md, ModifierData *target) @@ -171,10 +173,13 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } - if (dmd->texmapping == MOD_DISP_MAP_GLOBAL) + if (dmd->texmapping == MOD_DISP_MAP_GLOBAL || + (ELEM(dmd->direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ) && + dmd->space == MOD_DISP_SPACE_GLOBAL)) + { dag_add_relation(forest, obNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Displace Modifier"); - + } } static void updateDepsgraph(ModifierData *md, @@ -187,7 +192,10 @@ static void updateDepsgraph(ModifierData *md, if (dmd->map_object != NULL && dmd->texmapping == MOD_DISP_MAP_OBJECT) { DEG_add_object_relation(node, dmd->map_object, DEG_OB_COMP_TRANSFORM, "Displace Modifier"); } - if (dmd->texmapping == MOD_DISP_MAP_GLOBAL) { + if (dmd->texmapping == MOD_DISP_MAP_GLOBAL || + (ELEM(dmd->direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ) && + dmd->space == MOD_DISP_SPACE_GLOBAL)) + { DEG_add_object_relation(node, ob, DEG_OB_COMP_TRANSFORM, "Displace Modifier"); } } @@ -206,6 +214,8 @@ static void displaceModifier_do( float weight = 1.0f; /* init value unused but some compilers may complain */ const float delta_fixed = 1.0f - dmd->midlevel; /* when no texture is used, we fallback to white */ float (*vert_clnors)[3] = NULL; + float local_mat[4][4]; + const bool use_global_direction = dmd->space == MOD_DISP_SPACE_GLOBAL; if (!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) return; if (dmd->strength == 0.0f) return; @@ -243,11 +253,17 @@ static void displaceModifier_do( direction = MOD_DISP_DIR_NOR; } } + else if (ELEM(direction, MOD_DISP_DIR_X, MOD_DISP_DIR_Y, MOD_DISP_DIR_Z, MOD_DISP_DIR_RGB_XYZ) && + use_global_direction) + { + copy_m4_m4(local_mat, ob->obmat); + } for (i = 0; i < numVerts; i++) { TexResult texres; float strength = dmd->strength; float delta; + float local_vec[3]; if (dvert) { weight = defvert_find_weight(dvert + i, defgrp_index); @@ -270,18 +286,44 @@ static void displaceModifier_do( switch (direction) { case MOD_DISP_DIR_X: - vertexCos[i][0] += delta; + if (use_global_direction) { + vertexCos[i][0] += delta * local_mat[0][0]; + vertexCos[i][1] += delta * local_mat[1][0]; + vertexCos[i][2] += delta * local_mat[2][0]; + } + else { + vertexCos[i][0] += delta; + } break; case MOD_DISP_DIR_Y: - vertexCos[i][1] += delta; + if (use_global_direction) { + vertexCos[i][0] += delta * local_mat[0][1]; + vertexCos[i][1] += delta * local_mat[1][1]; + vertexCos[i][2] += delta * local_mat[2][1]; + } + else { + vertexCos[i][1] += delta; + } break; case MOD_DISP_DIR_Z: - vertexCos[i][2] += delta; + if (use_global_direction) { + vertexCos[i][0] += delta * local_mat[0][2]; + vertexCos[i][1] += delta * local_mat[1][2]; + vertexCos[i][2] += delta * local_mat[2][2]; + } + else { + vertexCos[i][2] += delta; + } break; case MOD_DISP_DIR_RGB_XYZ: - vertexCos[i][0] += (texres.tr - dmd->midlevel) * strength; - vertexCos[i][1] += (texres.tg - dmd->midlevel) * strength; - vertexCos[i][2] += (texres.tb - dmd->midlevel) * strength; + local_vec[0] = texres.tr - dmd->midlevel; + local_vec[1] = texres.tg - dmd->midlevel; + local_vec[2] = texres.tb - dmd->midlevel; + if (use_global_direction) { + mul_transposed_mat3_m4_v3(local_mat, local_vec); + } + mul_v3_fl(local_vec, strength); + add_v3_v3(vertexCos[i], local_vec); break; case MOD_DISP_DIR_NOR: vertexCos[i][0] += delta * (mvert[i].no[0] / 32767.0f); -- cgit v1.2.3