diff options
author | Joseph Eagar <joeedh@gmail.com> | 2011-05-09 03:43:18 +0400 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2011-05-09 03:43:18 +0400 |
commit | 6ef77cf95accc3cb914e7efd964118ce6e9521cf (patch) | |
tree | 1d8dbf95355038c93f79f9053a0bf1d55b561ec3 /source/blender/modifiers | |
parent | 3462ddf17f38eb61fc3bb2751d55de15a47455c3 (diff) | |
parent | 770119d16f7dbee99a60d19540818892c970c4e2 (diff) |
=bmesh= merge from trunk at r36529
Diffstat (limited to 'source/blender/modifiers')
-rw-r--r-- | source/blender/modifiers/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/modifiers/MOD_modifiertypes.h | 1 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_build.c | 18 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_cast.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_displace.c | 91 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_explode.c | 28 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_multires.c | 1 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_ngoninterp.c | 6 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_simpledeform.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_util.c | 94 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_util.h | 5 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_warp.c | 365 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_wave.c | 93 |
13 files changed, 540 insertions, 167 deletions
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index 4a02306b443..ede55eafbf7 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -76,6 +76,7 @@ set(SRC intern/MOD_surface.c intern/MOD_util.c intern/MOD_uvproject.c + intern/MOD_warp.c intern/MOD_wave.c MOD_modifiertypes.h diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index 44d06e3ef47..510a3d0fc77 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -71,6 +71,7 @@ extern ModifierTypeInfo modifierType_Smoke; extern ModifierTypeInfo modifierType_ShapeKey; extern ModifierTypeInfo modifierType_Solidify; extern ModifierTypeInfo modifierType_Screw; +extern ModifierTypeInfo modifierType_Warp; extern ModifierTypeInfo modifierType_NgonInterp; /* MOD_util.c */ diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index 7cb9c1b7c19..84cb8caec43 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -230,17 +230,17 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, !BLI_ghashIterator_isDone(hashIter); BLI_ghashIterator_step(hashIter) ) { - MVert source; - MVert *dest; - int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); - int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); + MVert source; + MVert *dest; + int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter)); + int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter)); - dm->getVert(dm, oldIndex, &source); - dest = CDDM_get_vert(result, newIndex); + dm->getVert(dm, oldIndex, &source); + dest = CDDM_get_vert(result, newIndex); - DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); - *dest = source; - } + DM_copy_vert_data(dm, result, oldIndex, newIndex, 1); + *dest = source; + } BLI_ghashIterator_free(hashIter); /* copy the edges across, remapping indices */ diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index 5cb352ef482..1069b1e7098 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -597,7 +597,7 @@ static void deformVerts(ModifierData *md, Object *ob, } static void deformVertsEM( - ModifierData *md, Object *ob, struct EditMesh *editData, + ModifierData *md, Object *ob, struct BMEditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, 0); diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index deec5a44da8..1f111aca48a 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -162,92 +162,6 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } -static void get_texture_coords(DisplaceModifierData *dmd, Object *ob, - DerivedMesh *dm, - float (*co)[3], float (*texco)[3], - int numVerts) -{ - int i; - int texmapping = dmd->texmapping; - float mapob_imat[4][4]; - - if(texmapping == MOD_DISP_MAP_OBJECT) { - if(dmd->map_object) - invert_m4_m4(mapob_imat, dmd->map_object->obmat); - else /* if there is no map object, default to local */ - texmapping = MOD_DISP_MAP_LOCAL; - } - - /* UVs need special handling, since they come from faces */ - if(texmapping == MOD_DISP_MAP_UV) { - if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) { - MFace *mface = dm->getTessFaceArray(dm); - MFace *mf; - char *done = MEM_callocN(sizeof(*done) * numVerts, - "get_texture_coords done"); - int numFaces = dm->getNumTessFaces(dm); - char uvname[32]; - MTFace *tf; - - validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname); - tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname); - - /* verts are given the UV from the first face that uses them */ - for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) { - if(!done[mf->v1]) { - texco[mf->v1][0] = tf->uv[0][0]; - texco[mf->v1][1] = tf->uv[0][1]; - texco[mf->v1][2] = 0; - done[mf->v1] = 1; - } - if(!done[mf->v2]) { - texco[mf->v2][0] = tf->uv[1][0]; - texco[mf->v2][1] = tf->uv[1][1]; - texco[mf->v2][2] = 0; - done[mf->v2] = 1; - } - if(!done[mf->v3]) { - texco[mf->v3][0] = tf->uv[2][0]; - texco[mf->v3][1] = tf->uv[2][1]; - texco[mf->v3][2] = 0; - done[mf->v3] = 1; - } - if(!done[mf->v4]) { - texco[mf->v4][0] = tf->uv[3][0]; - texco[mf->v4][1] = tf->uv[3][1]; - texco[mf->v4][2] = 0; - done[mf->v4] = 1; - } - } - - /* remap UVs from [0, 1] to [-1, 1] */ - for(i = 0; i < numVerts; ++i) { - texco[i][0] = texco[i][0] * 2 - 1; - texco[i][1] = texco[i][1] * 2 - 1; - } - - MEM_freeN(done); - return; - } else /* if there are no UVs, default to local */ - texmapping = MOD_DISP_MAP_LOCAL; - } - - for(i = 0; i < numVerts; ++i, ++co, ++texco) { - switch(texmapping) { - case MOD_DISP_MAP_LOCAL: - copy_v3_v3(*texco, *co); - break; - case MOD_DISP_MAP_GLOBAL: - mul_v3_m4v3(*texco, ob->obmat, *co); - break; - case MOD_DISP_MAP_OBJECT: - mul_v3_m4v3(*texco, ob->obmat, *co); - mul_m4_v3(mapob_imat, *texco); - break; - } - } -} - /* dm must be a CDDerivedMesh */ static void displaceModifier_do( DisplaceModifierData *dmd, Object *ob, @@ -260,6 +174,7 @@ static void displaceModifier_do( float (*tex_co)[3]; if(!dmd->texture) return; + if(dmd->strength == 0.0f) return; defgrp_index = defgroup_name_index(ob, dmd->defgrp_name); @@ -269,7 +184,7 @@ static void displaceModifier_do( tex_co = MEM_callocN(sizeof(*tex_co) * numVerts, "displaceModifier_do tex_co"); - get_texture_coords(dmd, ob, dm, vertexCos, tex_co, numVerts); + get_texture_coords((MappingInfoModifierData *)dmd, ob, dm, vertexCos, tex_co, numVerts); for(i = 0; i < numVerts; ++i) { @@ -285,7 +200,7 @@ static void displaceModifier_do( break; } } - if(!def_weight) continue; + if(!def_weight || def_weight->weight==0.0f) continue; } texres.nor = NULL; diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 46a94a023b1..38570f2248f 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1001,19 +1001,19 @@ static DerivedMesh * applyModifier(ModifierData *md, Object *ob, createFacepa(emd,psmd,derivedData); } - /* 2. create new mesh */ - if(emd->flag & eExplodeFlag_EdgeCut){ - int *facepa = emd->facepa; - DerivedMesh *splitdm=cutEdges(emd,dm); - DerivedMesh *explode=explodeMesh(emd, psmd, md->scene, ob, splitdm); - - MEM_freeN(emd->facepa); - emd->facepa=facepa; - splitdm->release(splitdm); - return explode; - } - else - return explodeMesh(emd, psmd, md->scene, ob, derivedData); + /* 2. create new mesh */ + if(emd->flag & eExplodeFlag_EdgeCut){ + int *facepa = emd->facepa; + DerivedMesh *splitdm=cutEdges(emd,dm); + DerivedMesh *explode=explodeMesh(emd, psmd, md->scene, ob, splitdm); + + MEM_freeN(emd->facepa); + emd->facepa=facepa; + splitdm->release(splitdm); + return explode; + } + else + return explodeMesh(emd, psmd, md->scene, ob, derivedData); } return derivedData; } @@ -1023,7 +1023,7 @@ ModifierTypeInfo modifierType_Explode = { /* name */ "Explode", /* structName */ "ExplodeModifierData", /* structSize */ sizeof(ExplodeModifierData), - /* type */ eModifierTypeType_Nonconstructive, + /* type */ eModifierTypeType_Constructive, /* flags */ eModifierTypeFlag_AcceptsMesh, /* copyData */ copyData, /* deformVerts */ NULL, diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index 7296271eeb0..29d4c2a0530 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -112,6 +112,7 @@ ModifierTypeInfo modifierType_Multires = { /* structSize */ sizeof(MultiresModifierData), /* type */ eModifierTypeType_Constructive, /* flags */ eModifierTypeFlag_AcceptsMesh + | eModifierTypeFlag_SupportsMapping | eModifierTypeFlag_RequiresOriginalData, /* copyData */ copyData, diff --git a/source/blender/modifiers/intern/MOD_ngoninterp.c b/source/blender/modifiers/intern/MOD_ngoninterp.c index af2d8cca4b9..c3b5382910d 100644 --- a/source/blender/modifiers/intern/MOD_ngoninterp.c +++ b/source/blender/modifiers/intern/MOD_ngoninterp.c @@ -254,15 +254,15 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, add_v3_v3(cos[j], cent); } - copy_v3_v3(co, mvert + mf2->v1); + copy_v3_v3(co, (mvert + mf2->v1)->co); interp_weights_poly_v3(w, cos, mp->totloop, co); CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 0); - copy_v3_v3(co, mvert + mf2->v2); + copy_v3_v3(co, (mvert + mf2->v2)->co); interp_weights_poly_v3(w, cos, mp->totloop, co); CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 1); - copy_v3_v3(co, mvert + mf2->v3); + copy_v3_v3(co, (mvert + mf2->v3)->co); interp_weights_poly_v3(w, cos, mp->totloop, co); CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 2); diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 2e6d9350148..ea4771b679a 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -56,7 +56,7 @@ /* Clamps/Limits the given coordinate to: limits[0] <= co[axis] <= limits[1] - * The ammount of clamp is saved on dcut */ + * The amount of clamp is saved on dcut */ static void axis_limit(int axis, const float limits[2], float co[3], float dcut[3]) { float val = co[axis]; diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 323531702fa..8091df06455 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -40,8 +40,11 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_curve_types.h" +#include "DNA_meshdata_types.h" #include "BLI_utildefines.h" +#include "BLI_math_vector.h" +#include "BLI_math_matrix.h" #include "BKE_cdderivedmesh.h" #include "BKE_mesh.h" @@ -74,6 +77,92 @@ void get_texture_value(Tex *texture, float *tex_co, TexResult *texres) texres->tr = texres->tg = texres->tb = texres->tin; } +void get_texture_coords(MappingInfoModifierData *dmd, Object *ob, + DerivedMesh *dm, + float (*co)[3], float (*texco)[3], + int numVerts) +{ + int i; + int texmapping = dmd->texmapping; + float mapob_imat[4][4]; + + if(texmapping == MOD_DISP_MAP_OBJECT) { + if(dmd->map_object) + invert_m4_m4(mapob_imat, dmd->map_object->obmat); + else /* if there is no map object, default to local */ + texmapping = MOD_DISP_MAP_LOCAL; + } + + /* UVs need special handling, since they come from faces */ + if(texmapping == MOD_DISP_MAP_UV) { + if(CustomData_has_layer(&dm->faceData, CD_MTFACE)) { + MFace *mface = dm->getTessFaceArray(dm); + MFace *mf; + char *done = MEM_callocN(sizeof(*done) * numVerts, + "get_texture_coords done"); + int numFaces = dm->getNumTessFaces(dm); + char uvname[32]; + MTFace *tf; + + validate_layer_name(&dm->faceData, CD_MTFACE, dmd->uvlayer_name, uvname); + tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname); + + /* verts are given the UV from the first face that uses them */ + for(i = 0, mf = mface; i < numFaces; ++i, ++mf, ++tf) { + if(!done[mf->v1]) { + texco[mf->v1][0] = tf->uv[0][0]; + texco[mf->v1][1] = tf->uv[0][1]; + texco[mf->v1][2] = 0; + done[mf->v1] = 1; + } + if(!done[mf->v2]) { + texco[mf->v2][0] = tf->uv[1][0]; + texco[mf->v2][1] = tf->uv[1][1]; + texco[mf->v2][2] = 0; + done[mf->v2] = 1; + } + if(!done[mf->v3]) { + texco[mf->v3][0] = tf->uv[2][0]; + texco[mf->v3][1] = tf->uv[2][1]; + texco[mf->v3][2] = 0; + done[mf->v3] = 1; + } + if(!done[mf->v4]) { + texco[mf->v4][0] = tf->uv[3][0]; + texco[mf->v4][1] = tf->uv[3][1]; + texco[mf->v4][2] = 0; + done[mf->v4] = 1; + } + } + + /* remap UVs from [0, 1] to [-1, 1] */ + for(i = 0; i < numVerts; ++i) { + texco[i][0] = texco[i][0] * 2 - 1; + texco[i][1] = texco[i][1] * 2 - 1; + } + + MEM_freeN(done); + return; + } else /* if there are no UVs, default to local */ + texmapping = MOD_DISP_MAP_LOCAL; + } + + for(i = 0; i < numVerts; ++i, ++co, ++texco) { + switch(texmapping) { + case MOD_DISP_MAP_LOCAL: + copy_v3_v3(*texco, *co); + break; + case MOD_DISP_MAP_GLOBAL: + mul_v3_m4v3(*texco, ob->obmat, *co); + break; + case MOD_DISP_MAP_OBJECT: + mul_v3_m4v3(*texco, ob->obmat, *co); + mul_m4_v3(mapob_imat, *texco); + break; + } + } +} + void modifier_vgroup_cache(ModifierData *md, float (*vertexCos)[3]) { while((md=md->next) && md->type==eModifierType_Armature) { @@ -106,7 +195,7 @@ void validate_layer_name(const CustomData *data, int type, char *name, char *out } /* returns a cdderivedmesh if dm == NULL or is another type of derivedmesh */ -DerivedMesh *get_cddm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (*vertexCos)[3]) +DerivedMesh *get_cddm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3]) { if(dm && dm->type == DM_TYPE_CDDM) return dm; @@ -126,7 +215,7 @@ DerivedMesh *get_cddm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (* } /* returns a derived mesh if dm == NULL, for deforming modifiers that need it */ -DerivedMesh *get_dm(Object *ob, struct EditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int orco) +DerivedMesh *get_dm(Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int orco) { if(dm) return dm; @@ -189,6 +278,7 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(ShapeKey); INIT_TYPE(Solidify); INIT_TYPE(Screw); + INIT_TYPE(Warp); INIT_TYPE(NgonInterp); #undef INIT_TYPE } diff --git a/source/blender/modifiers/intern/MOD_util.h b/source/blender/modifiers/intern/MOD_util.h index a42151904e9..d991dbfbdc3 100644 --- a/source/blender/modifiers/intern/MOD_util.h +++ b/source/blender/modifiers/intern/MOD_util.h @@ -46,9 +46,10 @@ struct EditMesh; struct ModifierData; void get_texture_value(struct Tex *texture, float *tex_co, struct TexResult *texres); +void get_texture_coords(struct MappingInfoModifierData *dmd, struct Object *ob, struct DerivedMesh *dm, float (*co)[3], float (*texco)[3], int numVerts); void modifier_vgroup_cache(struct ModifierData *md, float (*vertexCos)[3]); void validate_layer_name(const struct CustomData *data, int type, char *name, char *outname); -struct DerivedMesh *get_cddm(struct Object *ob, struct EditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3]); -struct DerivedMesh *get_dm(struct Object *ob, struct EditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3], int orco); +struct DerivedMesh *get_cddm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3]); +struct DerivedMesh *get_dm(struct Object *ob, struct BMEditMesh *em, struct DerivedMesh *dm, float (*vertexCos)[3], int orco); #endif /* MOD_UTIL_H */ diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c new file mode 100644 index 00000000000..acdbf493267 --- /dev/null +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -0,0 +1,365 @@ +/* +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* Contributor(s): Campbell Barton +* +* ***** END GPL LICENSE BLOCK ***** +* +*/ + +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_modifier.h" +#include "BKE_deform.h" +#include "BKE_texture.h" +#include "BKE_colortools.h" + +#include "DNA_object_types.h" +#include "DNA_meshdata_types.h" + +#include "depsgraph_private.h" + +#include "RE_shader_ext.h" + +#include "MOD_util.h" + + +static void initData(ModifierData *md) +{ + WarpModifierData *wmd = (WarpModifierData*) md; + + wmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + wmd->texture = NULL; + wmd->strength = 1.0f; + wmd->falloff_radius = 1.0f; + wmd->falloff_type = eWarp_Falloff_Smooth; + wmd->flag = 0; +} + +static void copyData(ModifierData *md, ModifierData *target) +{ + WarpModifierData *wmd = (WarpModifierData*) md; + WarpModifierData *twmd = (WarpModifierData*) target; + + twmd->object_from = wmd->object_from; + twmd->object_to = wmd->object_to; + + twmd->strength = wmd->strength; + twmd->falloff_radius = wmd->falloff_radius; + twmd->falloff_type = wmd->falloff_type; + strncpy(twmd->defgrp_name, wmd->defgrp_name, sizeof(twmd->defgrp_name)); + twmd->curfalloff = curvemapping_copy(wmd->curfalloff); + + /* map info */ + twmd->texture = wmd->texture; + twmd->map_object = wmd->map_object; + strncpy(twmd->uvlayer_name, wmd->uvlayer_name, sizeof(twmd->uvlayer_name)); + twmd->texmapping= wmd->texmapping; +} + +static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) +{ + WarpModifierData *wmd = (WarpModifierData *)md; + CustomDataMask dataMask = 0; + + /* ask for vertexgroups if we need them */ + if(wmd->defgrp_name[0]) dataMask |= (1 << CD_MDEFORMVERT); + dataMask |= (1 << CD_MDEFORMVERT); + + /* ask for UV coordinates if we need them */ + if(wmd->texmapping == MOD_DISP_MAP_UV) dataMask |= (1 << CD_MTFACE); + + return dataMask; +} + +static int dependsOnTime(ModifierData *md) +{ + WarpModifierData *wmd = (WarpModifierData *)md; + + if(wmd->texture) { + return BKE_texture_dependsOnTime(wmd->texture); + } + else { + return 0; + } +} + +static void freeData(ModifierData *md) +{ + WarpModifierData *wmd = (WarpModifierData *) md; + curvemapping_free(wmd->curfalloff); +} + + +static int isDisabled(ModifierData *md, int UNUSED(userRenderParams)) +{ + WarpModifierData *wmd = (WarpModifierData*) md; + + return !(wmd->object_from && wmd->object_to); +} + +static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk, void *userData) +{ + WarpModifierData *wmd = (WarpModifierData*) md; + + walk(userData, ob, &wmd->object_from); + walk(userData, ob, &wmd->object_to); + walk(userData, ob, &wmd->map_object); +} + +static void foreachIDLink(ModifierData *md, Object *ob, IDWalkFunc walk, void *userData) +{ + WarpModifierData *wmd = (WarpModifierData*) md; + + walk(userData, ob, (ID **)&wmd->texture); + + walk(userData, ob, (ID **)&wmd->object_from); + walk(userData, ob, (ID **)&wmd->object_to); + walk(userData, ob, (ID **)&wmd->map_object); +} + +static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene), + Object *UNUSED(ob), DagNode *obNode) +{ + WarpModifierData *wmd = (WarpModifierData*) md; + + if(wmd->object_from && wmd->object_to) { + DagNode *fromNode = dag_get_node(forest, wmd->object_from); + DagNode *toNode = dag_get_node(forest, wmd->object_to); + + dag_add_relation(forest, fromNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Warp Modifier1"); + dag_add_relation(forest, toNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Warp Modifier2"); + } + + if((wmd->texmapping == MOD_DISP_MAP_OBJECT) && wmd->map_object) { + DagNode *curNode = dag_get_node(forest, wmd->map_object); + dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Warp Modifier3"); + } +} + +static void warpModifier_do(WarpModifierData *wmd, Object *ob, + DerivedMesh *dm, float (*vertexCos)[3], int numVerts) +{ + float obinv[4][4]; + float mat_from[4][4]; + float mat_from_inv[4][4]; + float mat_to[4][4]; + float mat_unit[4][4]; + float mat_final[4][4]; + + float tmat[4][4]; + + float strength = wmd->strength; + float fac = 1.0f, weight; + int i; + int defgrp_index = defgroup_name_index(ob, wmd->defgrp_name); + MDeformVert *dv= NULL; + + float (*tex_co)[3]= NULL; + + if(!(wmd->object_from && wmd->object_to)) + return; + + if(wmd->curfalloff==NULL) /* should never happen, but bad lib linking could cause it */ + wmd->curfalloff = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f); + + invert_m4_m4(obinv, ob->obmat); + + mul_m4_m4m4(mat_from, wmd->object_from->obmat, obinv); + mul_m4_m4m4(mat_to, wmd->object_to->obmat, obinv); + + invert_m4_m4(tmat, mat_from); // swap? + mul_m4_m4m4(mat_final, mat_to, tmat); + + invert_m4_m4(mat_from_inv, mat_from); + + unit_m4(mat_unit); + + if(strength < 0.0f) { + float loc[3]; + strength = -strength; + + /* inverted location is not useful, just use the negative */ + copy_v3_v3(loc, mat_final[3]); + invert_m4(mat_final); + negate_v3_v3(mat_final[3], loc); + + } + weight= strength; + + if(wmd->texture) { + tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts, "warpModifier_do tex_co"); + get_texture_coords((MappingInfoModifierData *)wmd, ob, dm, vertexCos, tex_co, numVerts); + } + + for(i = 0; i < numVerts; i++) { + float *co = vertexCos[i]; + + if(wmd->falloff_type==eWarp_Falloff_None || + ((fac=len_v3v3(co, mat_from[3])) < wmd->falloff_radius && (fac=(wmd->falloff_radius-fac)/wmd->falloff_radius)) ) { + + /* skip if no vert group found */ + if(defgrp_index >= 0) { + dv = dm->getVertData(dm, i, CD_MDEFORMVERT); + + if(dv) { + weight = defvert_find_weight(dv, defgrp_index) * wmd->strength; + if(weight <= 0.0f) + continue; + } + } + + + /* closely match PROP_SMOOTH and similar */ + switch(wmd->falloff_type) { + case eWarp_Falloff_None: + fac = 1.0f; + break; + case eWarp_Falloff_Curve: + fac = curvemapping_evaluateF(wmd->curfalloff, 0, fac); + break; + case eWarp_Falloff_Sharp: + fac = fac*fac; + break; + case eWarp_Falloff_Smooth: + fac = 3.0f*fac*fac - 2.0f*fac*fac*fac; + break; + case eWarp_Falloff_Root: + fac = (float)sqrt(fac); + break; + case eWarp_Falloff_Linear: + /* pass */ + break; + case eWarp_Falloff_Const: + fac = 1.0f; + break; + case eWarp_Falloff_Sphere: + fac = (float)sqrt(2*fac - fac * fac); + break; + } + + fac *= weight; + + if(tex_co) { + TexResult texres; + texres.nor = NULL; + get_texture_value(wmd->texture, tex_co[i], &texres); + fac *= texres.tin; + } + + /* into the 'from' objects space */ + mul_m4_v3(mat_from_inv, co); + + if(fac >= 1.0f) { + mul_m4_v3(mat_final, co); + } + else if(fac > 0.0f) { + if(wmd->flag & MOD_WARP_VOLUME_PRESERVE) { + /* interpolate the matrix for nicer locations */ + blend_m4_m4m4(tmat, mat_unit, mat_final, fac); + mul_m4_v3(tmat, co); + } + else { + float tvec[3]; + mul_v3_m4v3(tvec, mat_final, co); + interp_v3_v3v3(co, co, tvec, fac); + } + } + + /* out of the 'from' objects space */ + mul_m4_v3(mat_from, co); + } + } + + if(tex_co) + MEM_freeN(tex_co); + +} + +static int warp_needs_dm(WarpModifierData *wmd) +{ + return wmd->texture || wmd->defgrp_name[0]; +} + +static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, + float (*vertexCos)[3], int numVerts, int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) +{ + DerivedMesh *dm= NULL; + int use_dm= warp_needs_dm((WarpModifierData *)md); + + if(use_dm) { + dm= get_cddm(ob, NULL, derivedData, vertexCos); + } + + warpModifier_do((WarpModifierData *)md, ob, dm, vertexCos, numVerts); + + if(use_dm) { + if(dm != derivedData) dm->release(dm); + } +} + +static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editData, + DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) +{ + DerivedMesh *dm = derivedData; + int use_dm= warp_needs_dm((WarpModifierData *)md); + + if(use_dm) { + if(!derivedData) + dm = CDDM_from_BMEditMesh(editData, ob->data, 0); + } + + deformVerts(md, ob, dm, vertexCos, numVerts, 0, 0); + + if(use_dm) { + if(!derivedData) dm->release(dm); + } +} + + +ModifierTypeInfo modifierType_Warp = { + /* name */ "Warp", + /* structName */ "WarpModifierData", + /* structSize */ sizeof(WarpModifierData), + /* type */ eModifierTypeType_OnlyDeform, + /* flags */ eModifierTypeFlag_AcceptsCVs + | eModifierTypeFlag_SupportsEditmode, + /* copyData */ copyData, + /* deformVerts */ deformVerts, + /* deformMatrices */ NULL, + /* deformVertsEM */ deformVertsEM, + /* deformMatricesEM */ NULL, + /* applyModifier */ 0, + /* applyModifierEM */ 0, + /* initData */ initData, + /* requiredDataMask */ requiredDataMask, + /* freeData */ freeData, + /* isDisabled */ isDisabled, + /* updateDepgraph */ updateDepgraph, + /* dependsOnTime */ dependsOnTime, + /* dependsOnNormals */ NULL, + /* foreachObjectLink */ foreachObjectLink, + /* foreachIDLink */ foreachIDLink, +}; diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index e3ee612374a..11cf159edc9 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -263,6 +263,9 @@ static void waveModifier_do(WaveModifierData *md, (float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow)); float lifefac = wmd->height; float (*tex_co)[3] = NULL; + const int wmd_axis= wmd->flag & (MOD_WAVE_X|MOD_WAVE_Y); + const float falloff= wmd->falloff; + float falloff_fac= 1.0f; /* when falloff == 0.0f this stays at 1.0f */ if(wmd->flag & MOD_WAVE_NORM && ob->type == OB_MESH) mvert = dm->getVertArray(dm); @@ -306,7 +309,7 @@ static void waveModifier_do(WaveModifierData *md, if(lifefac != 0.0f) { /* avoid divide by zero checks within the loop */ - float falloff_inv= wmd->falloff ? 1.0f / wmd->falloff : 1.0f; + float falloff_inv= falloff ? 1.0f / falloff : 1.0f; int i; for(i = 0; i < numVerts; i++) { @@ -314,51 +317,29 @@ static void waveModifier_do(WaveModifierData *md, float x = co[0] - wmd->startx; float y = co[1] - wmd->starty; float amplit= 0.0f; - float dist = 0.0f; - float falloff_fac = 0.0f; - TexResult texres; - MDeformWeight *def_weight = NULL; + float def_weight= 1.0f; /* get weights */ if(dvert) { - int j; - for(j = 0; j < dvert[i].totweight; ++j) { - if(dvert[i].dw[j].def_nr == defgrp_index) { - def_weight = &dvert[i].dw[j]; - break; - } - } + def_weight= defvert_find_weight(&dvert[i], defgrp_index); /* if this vert isn't in the vgroup, don't deform it */ - if(!def_weight) continue; - } - - if(wmd->texture) { - texres.nor = NULL; - get_texture_value(wmd->texture, tex_co[i], &texres); - } - - /*get dist*/ - if(wmd->flag & MOD_WAVE_X) { - if(wmd->flag & MOD_WAVE_Y){ - dist = (float)sqrt(x*x + y*y); - } - else{ - dist = fabs(x); + if(def_weight == 0.0f) { + continue; } } - else if(wmd->flag & MOD_WAVE_Y) { - dist = fabs(y); - } - - falloff_fac = (1.0f - (dist * falloff_inv)); - if(wmd->flag & MOD_WAVE_X) { - if(wmd->flag & MOD_WAVE_Y) amplit = (float)sqrt(x*x + y*y); - else amplit = x; + switch(wmd_axis) { + case MOD_WAVE_X|MOD_WAVE_Y: + amplit = sqrtf(x*x + y*y); + break; + case MOD_WAVE_X: + amplit = x; + break; + case MOD_WAVE_Y: + amplit = y; + break; } - else if(wmd->flag & MOD_WAVE_Y) - amplit= y; /* this way it makes nice circles */ amplit -= (ctime - wmd->timeoffs) * wmd->speed; @@ -368,22 +349,40 @@ static void waveModifier_do(WaveModifierData *md, + wmd->width; } + if(falloff != 0.0f) { + float dist = 0.0f; + + switch(wmd_axis) { + case MOD_WAVE_X|MOD_WAVE_Y: + dist = sqrtf(x*x + y*y); + break; + case MOD_WAVE_X: + dist = fabsf(x); + break; + case MOD_WAVE_Y: + dist = fabsf(y); + break; + } + + falloff_fac = (1.0f - (dist * falloff_inv)); + CLAMP(falloff_fac, 0.0f, 1.0f); + } + /* GAUSSIAN */ - if(amplit > -wmd->width && amplit < wmd->width) { + if((falloff_fac != 0.0f) && (amplit > -wmd->width) && (amplit < wmd->width)) { amplit = amplit * wmd->narrow; amplit = (float)(1.0f / expf(amplit * amplit) - minfac); /*apply texture*/ - if(wmd->texture) - amplit = amplit * texres.tin; - - /*apply weight*/ - if(def_weight) - amplit = amplit * def_weight->weight; + if(wmd->texture) { + TexResult texres; + texres.nor = NULL; + get_texture_value(wmd->texture, tex_co[i], &texres); + amplit *= texres.tin; + } - /*apply falloff*/ - if (wmd->falloff > 0) - amplit = amplit * falloff_fac; + /*apply weight & falloff */ + amplit *= def_weight * falloff_fac; if(mvert) { /* move along normals */ |