Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_displace.c
| Show All 40 Lines | |||||
| #include "BKE_cdderivedmesh.h" | #include "BKE_cdderivedmesh.h" | ||||
| #include "BKE_library.h" | #include "BKE_library.h" | ||||
| #include "BKE_library_query.h" | #include "BKE_library_query.h" | ||||
| #include "BKE_mesh.h" | #include "BKE_mesh.h" | ||||
| #include "BKE_modifier.h" | #include "BKE_modifier.h" | ||||
| #include "BKE_texture.h" | #include "BKE_texture.h" | ||||
| #include "BKE_deform.h" | #include "BKE_deform.h" | ||||
| #include "BKE_object.h" | |||||
| #include "depsgraph_private.h" | #include "depsgraph_private.h" | ||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "MOD_util.h" | #include "MOD_util.h" | ||||
| #include "RE_shader_ext.h" | #include "RE_shader_ext.h" | ||||
| /* Displace */ | /* Displace */ | ||||
| static void initData(ModifierData *md) | static void initData(ModifierData *md) | ||||
| { | { | ||||
| DisplaceModifierData *dmd = (DisplaceModifierData *) md; | DisplaceModifierData *dmd = (DisplaceModifierData *) md; | ||||
| dmd->texture = NULL; | dmd->texture = NULL; | ||||
| dmd->strength = 1; | dmd->strength = 1; | ||||
| dmd->direction = MOD_DISP_DIR_NOR; | dmd->direction = MOD_DISP_DIR_NOR; | ||||
| dmd->midlevel = 0.5; | dmd->midlevel = 0.5; | ||||
| dmd->space = MOD_DISP_SPACE_LOCAL; | |||||
| } | } | ||||
| static void copyData(ModifierData *md, ModifierData *target) | static void copyData(ModifierData *md, ModifierData *target) | ||||
| { | { | ||||
| #if 0 | #if 0 | ||||
| DisplaceModifierData *dmd = (DisplaceModifierData *) md; | DisplaceModifierData *dmd = (DisplaceModifierData *) md; | ||||
| #endif | #endif | ||||
| DisplaceModifierData *tdmd = (DisplaceModifierData *) target; | DisplaceModifierData *tdmd = (DisplaceModifierData *) target; | ||||
| ▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | static void updateDepgraph(ModifierData *md, DagForest *forest, | ||||
| if (dmd->map_object && dmd->texmapping == MOD_DISP_MAP_OBJECT) { | if (dmd->map_object && dmd->texmapping == MOD_DISP_MAP_OBJECT) { | ||||
| DagNode *curNode = dag_get_node(forest, dmd->map_object); | DagNode *curNode = dag_get_node(forest, dmd->map_object); | ||||
| dag_add_relation(forest, curNode, obNode, | dag_add_relation(forest, curNode, obNode, | ||||
| DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Displace Modifier"); | DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "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)) | |||||
| { | |||||
| dag_add_relation(forest, obNode, obNode, | dag_add_relation(forest, obNode, obNode, | ||||
| DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Displace Modifier"); | DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Displace Modifier"); | ||||
| } | |||||
| } | } | ||||
| static void updateDepsgraph(ModifierData *md, | static void updateDepsgraph(ModifierData *md, | ||||
| struct Main *UNUSED(bmain), | struct Main *UNUSED(bmain), | ||||
| struct Scene *UNUSED(scene), | struct Scene *UNUSED(scene), | ||||
| Object *ob, | Object *ob, | ||||
| struct DepsNodeHandle *node) | struct DepsNodeHandle *node) | ||||
| { | { | ||||
| DisplaceModifierData *dmd = (DisplaceModifierData *)md; | DisplaceModifierData *dmd = (DisplaceModifierData *)md; | ||||
| if (dmd->map_object != NULL && dmd->texmapping == MOD_DISP_MAP_OBJECT) { | 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"); | 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"); | DEG_add_object_relation(node, ob, DEG_OB_COMP_TRANSFORM, "Displace Modifier"); | ||||
| } | } | ||||
brecht: This style follows convention I think, would use the same for the `if()` above. | |||||
| } | } | ||||
| /* dm must be a CDDerivedMesh */ | /* dm must be a CDDerivedMesh */ | ||||
| static void displaceModifier_do( | static void displaceModifier_do( | ||||
| DisplaceModifierData *dmd, Object *ob, | DisplaceModifierData *dmd, Object *ob, | ||||
| DerivedMesh *dm, float (*vertexCos)[3], int numVerts) | DerivedMesh *dm, float (*vertexCos)[3], int numVerts) | ||||
| { | { | ||||
| int i; | int i; | ||||
| MVert *mvert; | MVert *mvert; | ||||
| MDeformVert *dvert; | MDeformVert *dvert; | ||||
| int direction = dmd->direction; | int direction = dmd->direction; | ||||
| int defgrp_index; | int defgrp_index; | ||||
| float (*tex_co)[3]; | float (*tex_co)[3]; | ||||
| float weight = 1.0f; /* init value unused but some compilers may complain */ | 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 */ | const float delta_fixed = 1.0f - dmd->midlevel; /* when no texture is used, we fallback to white */ | ||||
| float (*vert_clnors)[3] = NULL; | float (*vert_clnors)[3] = NULL; | ||||
| float local_mat[4][4]; | |||||
| float local_mat_transp[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->texture && dmd->direction == MOD_DISP_DIR_RGB_XYZ) return; | ||||
| if (dmd->strength == 0.0f) return; | if (dmd->strength == 0.0f) return; | ||||
| mvert = CDDM_get_verts(dm); | mvert = CDDM_get_verts(dm); | ||||
| modifier_get_vgroup(ob, dm, dmd->defgrp_name, &dvert, &defgrp_index); | modifier_get_vgroup(ob, dm, dmd->defgrp_name, &dvert, &defgrp_index); | ||||
| if (dmd->texture) { | if (dmd->texture) { | ||||
| Show All 21 Lines | if (CustomData_has_layer(ldata, CD_CUSTOMLOOPNORMAL)) { | ||||
| vert_clnors = MEM_mallocN(sizeof(*vert_clnors) * (size_t)numVerts, __func__); | vert_clnors = MEM_mallocN(sizeof(*vert_clnors) * (size_t)numVerts, __func__); | ||||
| BKE_mesh_normals_loop_to_vertex(numVerts, dm->getLoopArray(dm), dm->getNumLoops(dm), | BKE_mesh_normals_loop_to_vertex(numVerts, dm->getLoopArray(dm), dm->getNumLoops(dm), | ||||
| (const float (*)[3])clnors, vert_clnors); | (const float (*)[3])clnors, vert_clnors); | ||||
| } | } | ||||
| else { | else { | ||||
| direction = MOD_DISP_DIR_NOR; | 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) | |||||
| { | |||||
| BKE_object_matrix_local_get(ob, local_mat); | |||||
brechtUnsubmitted Not Done Inline ActionsActually I think this is wrong, it should just use ob->obmat like other modifiers. What this function does is remove parenting from the matrix, which normally you only need to do in specific cases, like exporting to a file format where parenting is accounted for in another way. I'll fix that as part of committing. brecht: Actually I think this is wrong, it should just use `ob->obmat` like other modifiers. What this… | |||||
| transpose_m4_m4(local_mat_transp, local_mat); | |||||
| } | |||||
| for (i = 0; i < numVerts; i++) { | for (i = 0; i < numVerts; i++) { | ||||
| TexResult texres; | TexResult texres; | ||||
| float strength = dmd->strength; | float strength = dmd->strength; | ||||
| float delta; | float delta; | ||||
| float local_vec[3]; | |||||
| if (dvert) { | if (dvert) { | ||||
| weight = defvert_find_weight(dvert + i, defgrp_index); | weight = defvert_find_weight(dvert + i, defgrp_index); | ||||
| if (weight == 0.0f) continue; | if (weight == 0.0f) continue; | ||||
| } | } | ||||
| if (dmd->texture) { | if (dmd->texture) { | ||||
| texres.nor = NULL; | texres.nor = NULL; | ||||
| BKE_texture_get_value(dmd->modifier.scene, dmd->texture, tex_co[i], &texres, false); | BKE_texture_get_value(dmd->modifier.scene, dmd->texture, tex_co[i], &texres, false); | ||||
| delta = texres.tin - dmd->midlevel; | delta = texres.tin - dmd->midlevel; | ||||
| } | } | ||||
| else { | else { | ||||
| delta = delta_fixed; /* (1.0f - dmd->midlevel) */ /* never changes */ | delta = delta_fixed; /* (1.0f - dmd->midlevel) */ /* never changes */ | ||||
| } | } | ||||
| if (dvert) strength *= weight; | if (dvert) strength *= weight; | ||||
| delta *= strength; | delta *= strength; | ||||
| CLAMP(delta, -10000, 10000); | CLAMP(delta, -10000, 10000); | ||||
| switch (direction) { | switch (direction) { | ||||
| case MOD_DISP_DIR_X: | case MOD_DISP_DIR_X: | ||||
| if (use_global_direction) { | |||||
| vertexCos[i][0] += delta * local_mat[0][0]; | |||||
| vertexCos[i][1] += delta * local_mat[1][0]; | |||||
Not Done Inline ActionsConvention is: }
else {brecht: Convention is:
```
}
else {
``` | |||||
| vertexCos[i][2] += delta * local_mat[2][0]; | |||||
| } | |||||
| else { | |||||
| vertexCos[i][0] += delta; | vertexCos[i][0] += delta; | ||||
| } | |||||
| break; | break; | ||||
| case MOD_DISP_DIR_Y: | case MOD_DISP_DIR_Y: | ||||
| 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; | vertexCos[i][1] += delta; | ||||
| } | |||||
| break; | break; | ||||
| case MOD_DISP_DIR_Z: | case MOD_DISP_DIR_Z: | ||||
| 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; | vertexCos[i][2] += delta; | ||||
| } | |||||
| break; | break; | ||||
| case MOD_DISP_DIR_RGB_XYZ: | case MOD_DISP_DIR_RGB_XYZ: | ||||
| vertexCos[i][0] += (texres.tr - dmd->midlevel) * strength; | local_vec[0] = texres.tr; | ||||
| vertexCos[i][1] += (texres.tg - dmd->midlevel) * strength; | local_vec[1] = texres.tg; | ||||
| vertexCos[i][2] += (texres.tb - dmd->midlevel) * strength; | local_vec[2] = texres.tb; | ||||
| add_v3_fl(local_vec, -dmd->midlevel); | |||||
| if (use_global_direction) { | |||||
| mul_mat3_m4_v3(local_mat_transp, local_vec); | |||||
| } | |||||
| mul_v3_fl(local_vec, strength); | |||||
| add_v3_v3(vertexCos[i], local_vec); | |||||
| break; | break; | ||||
| case MOD_DISP_DIR_NOR: | case MOD_DISP_DIR_NOR: | ||||
| vertexCos[i][0] += delta * (mvert[i].no[0] / 32767.0f); | vertexCos[i][0] += delta * (mvert[i].no[0] / 32767.0f); | ||||
| vertexCos[i][1] += delta * (mvert[i].no[1] / 32767.0f); | vertexCos[i][1] += delta * (mvert[i].no[1] / 32767.0f); | ||||
| vertexCos[i][2] += delta * (mvert[i].no[2] / 32767.0f); | vertexCos[i][2] += delta * (mvert[i].no[2] / 32767.0f); | ||||
| break; | break; | ||||
| case MOD_DISP_DIR_CLNOR: | case MOD_DISP_DIR_CLNOR: | ||||
| madd_v3_v3fl(vertexCos[i], vert_clnors[i], delta); | madd_v3_v3fl(vertexCos[i], vert_clnors[i], delta); | ||||
| ▲ Show 20 Lines • Show All 69 Lines • Show Last 20 Lines | |||||
This style follows convention I think, would use the same for the if() above.