diff options
Diffstat (limited to 'source/blender/modifiers/intern/MOD_displace.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_displace.c | 45 |
1 files changed, 40 insertions, 5 deletions
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index 2921472fe99..9ba2d214d50 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -37,10 +37,12 @@ #include "DNA_object_types.h" #include "BLI_utildefines.h" - +#include "BLI_math.h" #include "BKE_cdderivedmesh.h" #include "BKE_library.h" +#include "BKE_library_query.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_texture.h" #include "BKE_deform.h" @@ -98,6 +100,10 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) /* ask for UV coordinates if we need them */ if (dmd->texmapping == MOD_DISP_MAP_UV) dataMask |= CD_MASK_MTFACE; + if (dmd->direction == MOD_DISP_DIR_CLNOR) { + dataMask |= CD_MASK_CUSTOMLOOPNORMAL; + } + return dataMask; } @@ -116,7 +122,7 @@ static bool dependsOnTime(ModifierData *md) static bool dependsOnNormals(ModifierData *md) { DisplaceModifierData *dmd = (DisplaceModifierData *)md; - return (dmd->direction == MOD_DISP_DIR_NOR); + return ELEM(dmd->direction, MOD_DISP_DIR_NOR, MOD_DISP_DIR_CLNOR); } static void foreachObjectLink(ModifierData *md, Object *ob, @@ -124,7 +130,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob, { DisplaceModifierData *dmd = (DisplaceModifierData *) md; - walk(userData, ob, &dmd->map_object); + walk(userData, ob, &dmd->map_object, IDWALK_NOP); } static void foreachIDLink(ModifierData *md, Object *ob, @@ -132,7 +138,7 @@ static void foreachIDLink(ModifierData *md, Object *ob, { DisplaceModifierData *dmd = (DisplaceModifierData *) md; - walk(userData, ob, (ID **)&dmd->texture); + walk(userData, ob, (ID **)&dmd->texture, IDWALK_USER); foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); } @@ -194,10 +200,12 @@ static void displaceModifier_do( int i; MVert *mvert; MDeformVert *dvert; + int direction = dmd->direction; int defgrp_index; float (*tex_co)[3]; 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; if (!dmd->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) return; if (dmd->strength == 0.0f) return; @@ -216,6 +224,26 @@ static void displaceModifier_do( tex_co = NULL; } + if (direction == MOD_DISP_DIR_CLNOR) { + CustomData *ldata = dm->getLoopDataLayout(dm); + + if (CustomData_has_layer(ldata, CD_CUSTOMLOOPNORMAL)) { + float (*clnors)[3] = NULL; + + if ((dm->dirty & DM_DIRTY_NORMALS) || !CustomData_has_layer(ldata, CD_NORMAL)) { + dm->calcLoopNormals(dm, true, (float)M_PI); + } + + clnors = CustomData_get_layer(ldata, CD_NORMAL); + vert_clnors = MEM_mallocN(sizeof(*vert_clnors) * (size_t)numVerts, __func__); + BKE_mesh_normals_loop_to_vertex(numVerts, dm->getLoopArray(dm), dm->getNumLoops(dm), + (const float (*)[3])clnors, vert_clnors); + } + else { + direction = MOD_DISP_DIR_NOR; + } + } + for (i = 0; i < numVerts; i++) { TexResult texres; float strength = dmd->strength; @@ -240,7 +268,7 @@ static void displaceModifier_do( delta *= strength; CLAMP(delta, -10000, 10000); - switch (dmd->direction) { + switch (direction) { case MOD_DISP_DIR_X: vertexCos[i][0] += delta; break; @@ -260,12 +288,19 @@ static void displaceModifier_do( vertexCos[i][1] += delta * (mvert[i].no[1] / 32767.0f); vertexCos[i][2] += delta * (mvert[i].no[2] / 32767.0f); break; + case MOD_DISP_DIR_CLNOR: + madd_v3_v3fl(vertexCos[i], vert_clnors[i], delta); + break; } } if (tex_co) { MEM_freeN(tex_co); } + + if (vert_clnors) { + MEM_freeN(vert_clnors); + } } static void deformVerts(ModifierData *md, Object *ob, |