From d0ac7ef08742b439187837064da2ad2abcefb831 Mon Sep 17 00:00:00 2001 From: Ben Batt Date: Sun, 29 Apr 2007 16:15:50 +0000 Subject: Patch #6584 - Texture functionality in the wave modifier This patch allows the user to use a texture to modulate the wave modifier's amplitude. Thanks to Michael Fox (mfoxdoggg) for the patch! --- source/blender/blenkernel/intern/DerivedMesh.c | 1 - source/blender/blenkernel/intern/modifier.c | 179 ++++++++++++++++++++++++- source/blender/makesdna/DNA_modifier_types.h | 13 ++ source/blender/src/buttons_editing.c | 36 ++++- source/blender/src/editface.c | 2 +- source/blender/src/unwrapper.c | 1 - source/blender/src/vpaint.c | 2 - 7 files changed, 222 insertions(+), 12 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index fa8f76178d5..79da171fe5c 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1517,7 +1517,6 @@ static void vDM_release(DerivedMesh *dm) DerivedMesh *derivedmesh_from_versemesh(VNode *vnode, float (*vertexCos)[3]) { VDerivedMesh *vdm = MEM_callocN(sizeof(*vdm), "vdm"); - struct VerseVert *vvert; vdm->vnode = vnode; vdm->vertex_layer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 2e269bb6fdc..2d7113f7cc0 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -3327,12 +3327,15 @@ static void waveModifier_initData(ModifierData *md) wmd->flag |= (WAV_X+WAV_Y+WAV_CYCL); wmd->objectcenter = NULL; + wmd->texture = NULL; + wmd->map_object = NULL; wmd->height= 0.5f; wmd->width= 1.5f; wmd->speed= 0.5f; wmd->narrow= 1.5f; wmd->lifetime= 0.0f; wmd->damp= 10.0f; + wmd->texmapping = MOD_WAV_MAP_LOCAL; } static void waveModifier_copyData(ModifierData *md, ModifierData *target) @@ -3351,6 +3354,9 @@ static void waveModifier_copyData(ModifierData *md, ModifierData *target) twmd->timeoffs = wmd->timeoffs; twmd->width = wmd->width; twmd->objectcenter = wmd->objectcenter; + twmd->texture = wmd->texture; + twmd->map_object = wmd->map_object; + twmd->texmapping = wmd->texmapping; } static int waveModifier_dependsOnTime(ModifierData *md) @@ -3359,13 +3365,23 @@ static int waveModifier_dependsOnTime(ModifierData *md) } static void waveModifier_foreachObjectLink( - ModifierData *md, Object *ob, - void (*walk)(void *userData, Object *ob, Object **obpoin), - void *userData) + ModifierData *md, Object *ob, + ObjectWalkFunc walk, void *userData) { WaveModifierData *wmd = (WaveModifierData*) md; walk(userData, ob, &wmd->objectcenter); + walk(userData, ob, &wmd->map_object); +} + +static void waveModifier_foreachIDLink(ModifierData *md, Object *ob, + IDWalkFunc walk, void *userData) +{ + WaveModifierData *wmd = (WaveModifierData*) md; + + walk(userData, ob, (ID **)&wmd->texture); + + waveModifier_foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); } static void waveModifier_updateDepgraph( @@ -3379,10 +3395,117 @@ static void waveModifier_updateDepgraph( dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA); } + + if(wmd->map_object) { + DagNode *curNode = dag_get_node(forest, wmd->map_object); + + dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA); + } } -static void waveModifier_deformVerts( - ModifierData *md, Object *ob, DerivedMesh *derivedData, +CustomDataMask waveModifier_requiredDataMask(ModifierData *md) +{ + WaveModifierData *wmd = (WaveModifierData *)md; + CustomDataMask dataMask = 0; + + + /* ask for UV coordinates if we need them */ + if(wmd->texture && wmd->texmapping == MOD_WAV_MAP_UV) + dataMask |= (1 << CD_MTFACE); + + return dataMask; +} + +static void wavemod_get_texture_coords(WaveModifierData *wmd, Object *ob, + DerivedMesh *dm, + float (*co)[3], float (*texco)[3], + int numVerts) +{ + int i; + int texmapping = wmd->texmapping; + + if(texmapping == MOD_WAV_MAP_OBJECT) { + if(wmd->map_object) + Mat4Invert(wmd->map_object->imat, wmd->map_object->obmat); + else /* if there is no map object, default to local */ + texmapping = MOD_WAV_MAP_LOCAL; + } + + /* UVs need special handling, since they come from faces */ + if(texmapping == MOD_WAV_MAP_UV) { + if(dm->getFaceDataArray(dm, CD_MTFACE)) { + MFace *mface = dm->getFaceArray(dm); + MFace *mf; + char *done = MEM_callocN(sizeof(*done) * numVerts, + "get_texture_coords done"); + int numFaces = dm->getNumFaces(dm); + MTFace *tf; + + validate_layer_name(&dm->faceData, CD_MTFACE, wmd->uvlayer_name); + + tf = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, + wmd->uvlayer_name); + + /* 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_WAV_MAP_LOCAL; + } + + for(i = 0; i < numVerts; ++i, ++co, ++texco) { + switch(texmapping) { + case MOD_WAV_MAP_LOCAL: + VECCOPY(*texco, *co); + break; + case MOD_WAV_MAP_GLOBAL: + VECCOPY(*texco, *co); + Mat4MulVecfl(ob->obmat, *texco); + break; + case MOD_WAV_MAP_OBJECT: + VECCOPY(*texco, *co); + Mat4MulVecfl(ob->obmat, *texco); + Mat4MulVecfl(wmd->map_object->imat, *texco); + break; + } + } +} + +static void waveModifier_do( + WaveModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { WaveModifierData *wmd = (WaveModifierData*) md; @@ -3390,6 +3513,7 @@ static void waveModifier_deformVerts( float minfac = (float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow)); float lifefac = wmd->height; + float (*tex_co)[3]; if(wmd->objectcenter){ float mat[4][4]; @@ -3415,6 +3539,12 @@ static void waveModifier_deformVerts( } } + if(wmd->texture) { + tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts, + "waveModifier_do tex_co"); + wavemod_get_texture_coords(wmd, ob, dm, vertexCos, tex_co, numVerts); + } + if(lifefac != 0.0) { int i; @@ -3423,6 +3553,13 @@ static void waveModifier_deformVerts( float x = co[0] - wmd->startx; float y = co[1] - wmd->starty; float amplit= 0.0f; + TexResult texres; + + if(wmd->texture) { + texres.nor = NULL; + get_texture_value(wmd->texture, tex_co[i], &texres); + } + if(wmd->flag & WAV_X) { if(wmd->flag & WAV_Y) amplit = (float)sqrt(x*x + y*y); @@ -3443,18 +3580,46 @@ static void waveModifier_deformVerts( if(amplit > -wmd->width && amplit < wmd->width) { amplit = amplit * wmd->narrow; amplit = (float)(1.0 / exp(amplit * amplit) - minfac); + if(wmd->texture) + amplit = amplit * texres.tin; co[2] += lifefac * amplit; } } } + + if(wmd->texture) MEM_freeN(tex_co); +} + +static void waveModifier_deformVerts( + ModifierData *md, Object *ob, DerivedMesh *derivedData, + float (*vertexCos)[3], int numVerts) +{ + DerivedMesh *dm; + WaveModifierData *wmd = (WaveModifierData *)md; + + if(!wmd->texture || derivedData) dm = derivedData; + else if(ob->type == OB_MESH) dm = CDDM_from_mesh(ob->data, ob); + else return; + + waveModifier_do(wmd, ob, dm, vertexCos, numVerts); + + if(dm != derivedData) dm->release(dm); } static void waveModifier_deformVertsEM( ModifierData *md, Object *ob, EditMesh *editData, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { - waveModifier_deformVerts(md, ob, NULL, vertexCos, numVerts); + DerivedMesh *dm; + WaveModifierData *wmd = (WaveModifierData *)md; + + if(!wmd->texture || derivedData) dm = derivedData; + else dm = CDDM_from_editmesh(editData, ob->data); + + waveModifier_do(wmd, ob, dm, vertexCos, numVerts); + + if(dm != derivedData) dm->release(dm); } /* Armature */ @@ -3972,7 +4137,9 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->initData = waveModifier_initData; mti->copyData = waveModifier_copyData; mti->dependsOnTime = waveModifier_dependsOnTime; + mti->requiredDataMask = waveModifier_requiredDataMask; mti->foreachObjectLink = waveModifier_foreachObjectLink; + mti->foreachIDLink = waveModifier_foreachIDLink; mti->updateDepgraph = waveModifier_updateDepgraph; mti->deformVerts = waveModifier_deformVerts; mti->deformVertsEM = waveModifier_deformVertsEM; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 836cf171643..c5c37406c46 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -233,15 +233,28 @@ typedef struct DecimateModifierData { int faceCount; } DecimateModifierData; +enum { + MOD_WAV_MAP_LOCAL, + MOD_WAV_MAP_GLOBAL, + MOD_WAV_MAP_OBJECT, + MOD_WAV_MAP_UV, +}; + typedef struct WaveModifierData { ModifierData modifier; struct Object *objectcenter; + struct Tex *texture; + struct Object *map_object; short flag, pad; float startx, starty, height, width; float narrow, speed, damp; + + int texmapping, uvlayer_tmp; + + char uvlayer_name[32]; float timeoffs, lifetime; } WaveModifierData; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index d113179bbe2..c20b52b35b8 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1602,7 +1602,11 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco } else if (md->type==eModifierType_Decimate) { height = 48; } else if (md->type==eModifierType_Wave) { - height = 248; + WaveModifierData *wmd = (WaveModifierData *)md; + height = 280; + if(wmd->texmapping == MOD_WAV_MAP_OBJECT || + wmd->texmapping == MOD_WAV_MAP_UV) + height += 19; } else if (md->type==eModifierType_Armature) { height = 67; } else if (md->type==eModifierType_Hook) { @@ -1837,6 +1841,36 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta x:", lx,(cy-=19),113,19, &wmd->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis"); uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta y:", lx+115,cy,105,19, &wmd->starty, -100.0, 100.0, 100, 0, "Starting position for the Y axis"); uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_MODIFIER_RECALC, "Ob: ", lx, (cy-=19), 220,19, &wmd->objectcenter, "Object to use as Starting Position (leave blank to disable)"); + uiDefIDPoinBut(block, modifier_testTexture, ID_TE, B_CHANGEDEP,"Texture: ", lx, (cy -= 19), 220, 19, &wmd->texture,"Texture with which to modulate wave"); + sprintf(str, "Texture Coordinates%%t" + "|Local%%x%d|Global%%x%d|Object%%x%d|UV%%x%d", + MOD_WAV_MAP_LOCAL, MOD_WAV_MAP_GLOBAL, + MOD_WAV_MAP_OBJECT, MOD_WAV_MAP_UV); + uiDefButI(block, MENU, B_MODIFIER_RECALC, str, + lx, (cy -= 19), 220, 19, &wmd->texmapping, + 0.0, 1.0, 0, 0, + "Texture coordinates used for modulation input"); + if (wmd->texmapping == MOD_WAV_MAP_UV) { + char *strtmp; + int i; + CustomData *fdata = G.obedit ? &G.editMesh->fdata + : &((Mesh*)ob->data)->fdata; + build_uvlayer_menu_vars(fdata, &strtmp, &wmd->uvlayer_tmp, + wmd->uvlayer_name); + but = uiDefButI(block, MENU, B_MODIFIER_RECALC, strtmp, + lx, (cy -= 19), 220, 19, &wmd->uvlayer_tmp, + 0.0, 1.0, 0, 0, "Set the UV layer to use"); + MEM_freeN(strtmp); + i = CustomData_get_layer_index(fdata, CD_MTFACE); + uiButSetFunc(but, set_displace_uvlayer, wmd, + &fdata->layers[i]); + } + if(wmd->texmapping == MOD_DISP_MAP_OBJECT) { + uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_CHANGEDEP, + "Ob: ", lx, (cy -= 19), 220, 19, + &wmd->map_object, + "Object to get texture coordinates from"); + } cy -= 19; uiBlockBeginAlign(block); uiDefButF(block, NUMSLI, B_MODIFIER_RECALC, "Speed:", lx,(cy-=19),220,19, &wmd->speed, -2.0, 2.0, 0, 0, "Specify the wave speed"); diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index c45d742301e..2e89242c038 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -555,7 +555,7 @@ MTFace *get_active_tface(MCol **mcol) { Mesh *me; MTFace *tf; - MTFace *mf; + MFace *mf; int a; if(OBACT==NULL || OBACT->type!=OB_MESH) diff --git a/source/blender/src/unwrapper.c b/source/blender/src/unwrapper.c index 5a93c2b3077..bb4c58acd03 100644 --- a/source/blender/src/unwrapper.c +++ b/source/blender/src/unwrapper.c @@ -82,7 +82,6 @@ static void hash_add_face(EdgeHash *ehash, MFace *mf) void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index) { - MTFace *tf; MFace *mf; int a, doit=1, mark=0; char *linkflag; diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index a53c1508f0a..7a9e6a5475e 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -1082,7 +1082,6 @@ void weight_paint(void) Object *ob; Mesh *me; MFace *mface; - MTFace *tface; float mat[4][4], imat[4][4], paintweight, *vertexcosnos; float vpimat[3][3]; int *indexar, index, totindex, alpha, totw; @@ -1356,7 +1355,6 @@ void vertex_paint() Object *ob; Mesh *me; MFace *mface; - MTFace *tface; float mat[4][4], imat[4][4], *vertexcosnos; float vpimat[3][3]; unsigned int paintcol=0, *mcol, *mcolorig, fcol1, fcol2; -- cgit v1.2.3