Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2005 by the Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Daniel Dunbar 00022 * Ton Roosendaal, 00023 * Ben Batt, 00024 * Brecht Van Lommel, 00025 * Campbell Barton 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 * 00029 */ 00030 00036 #include "BLI_math.h" 00037 00038 #include "DNA_meshdata_types.h" 00039 #include "DNA_scene_types.h" 00040 #include "DNA_object_types.h" 00041 00042 #include "BLI_utildefines.h" 00043 #include "BLI_string.h" 00044 00045 00046 #include "BKE_DerivedMesh.h" 00047 #include "BKE_object.h" 00048 #include "BKE_deform.h" 00049 #include "BKE_scene.h" 00050 00051 #include "depsgraph_private.h" 00052 00053 #include "MEM_guardedalloc.h" 00054 #include "RE_shader_ext.h" 00055 00056 #include "MOD_modifiertypes.h" 00057 #include "MOD_util.h" 00058 00059 static void initData(ModifierData *md) 00060 { 00061 WaveModifierData *wmd = (WaveModifierData*) md; // whadya know, moved here from Iraq 00062 00063 wmd->flag |= (MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL 00064 | MOD_WAVE_NORM_X | MOD_WAVE_NORM_Y | MOD_WAVE_NORM_Z); 00065 00066 wmd->objectcenter = NULL; 00067 wmd->texture = NULL; 00068 wmd->map_object = NULL; 00069 wmd->height= 0.5f; 00070 wmd->width= 1.5f; 00071 wmd->speed= 0.25f; 00072 wmd->narrow= 1.5f; 00073 wmd->lifetime= 0.0f; 00074 wmd->damp= 10.0f; 00075 wmd->falloff= 0.0f; 00076 wmd->texmapping = MOD_DISP_MAP_LOCAL; 00077 wmd->defgrp_name[0] = 0; 00078 } 00079 00080 static void copyData(ModifierData *md, ModifierData *target) 00081 { 00082 WaveModifierData *wmd = (WaveModifierData*) md; 00083 WaveModifierData *twmd = (WaveModifierData*) target; 00084 00085 twmd->damp = wmd->damp; 00086 twmd->flag = wmd->flag; 00087 twmd->height = wmd->height; 00088 twmd->lifetime = wmd->lifetime; 00089 twmd->narrow = wmd->narrow; 00090 twmd->speed = wmd->speed; 00091 twmd->startx = wmd->startx; 00092 twmd->starty = wmd->starty; 00093 twmd->timeoffs = wmd->timeoffs; 00094 twmd->width = wmd->width; 00095 twmd->falloff = wmd->falloff; 00096 twmd->objectcenter = wmd->objectcenter; 00097 twmd->texture = wmd->texture; 00098 twmd->map_object = wmd->map_object; 00099 twmd->texmapping = wmd->texmapping; 00100 BLI_strncpy(twmd->defgrp_name, wmd->defgrp_name, sizeof(twmd->defgrp_name)); 00101 } 00102 00103 static int dependsOnTime(ModifierData *UNUSED(md)) 00104 { 00105 return 1; 00106 } 00107 00108 static void foreachObjectLink( 00109 ModifierData *md, Object *ob, 00110 ObjectWalkFunc walk, void *userData) 00111 { 00112 WaveModifierData *wmd = (WaveModifierData*) md; 00113 00114 walk(userData, ob, &wmd->objectcenter); 00115 walk(userData, ob, &wmd->map_object); 00116 } 00117 00118 static void foreachIDLink(ModifierData *md, Object *ob, 00119 IDWalkFunc walk, void *userData) 00120 { 00121 WaveModifierData *wmd = (WaveModifierData*) md; 00122 00123 walk(userData, ob, (ID **)&wmd->texture); 00124 00125 foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); 00126 } 00127 00128 static void foreachTexLink(ModifierData *md, Object *ob, 00129 TexWalkFunc walk, void *userData) 00130 { 00131 walk(userData, ob, md, "texture"); 00132 } 00133 00134 static void updateDepgraph(ModifierData *md, DagForest *forest, 00135 Scene *UNUSED(scene), 00136 Object *UNUSED(ob), 00137 DagNode *obNode) 00138 { 00139 WaveModifierData *wmd = (WaveModifierData*) md; 00140 00141 if(wmd->objectcenter) { 00142 DagNode *curNode = dag_get_node(forest, wmd->objectcenter); 00143 00144 dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, 00145 "Wave Modifier"); 00146 } 00147 00148 if(wmd->map_object) { 00149 DagNode *curNode = dag_get_node(forest, wmd->map_object); 00150 00151 dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, 00152 "Wave Modifer"); 00153 } 00154 } 00155 00156 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) 00157 { 00158 WaveModifierData *wmd = (WaveModifierData *)md; 00159 CustomDataMask dataMask = 0; 00160 00161 00162 /* ask for UV coordinates if we need them */ 00163 if(wmd->texture && wmd->texmapping == MOD_DISP_MAP_UV) 00164 dataMask |= CD_MASK_MTFACE; 00165 00166 /* ask for vertexgroups if we need them */ 00167 if(wmd->defgrp_name[0]) 00168 dataMask |= CD_MASK_MDEFORMVERT; 00169 00170 return dataMask; 00171 } 00172 00173 static void waveModifier_do(WaveModifierData *md, 00174 Scene *scene, Object *ob, DerivedMesh *dm, 00175 float (*vertexCos)[3], int numVerts) 00176 { 00177 WaveModifierData *wmd = (WaveModifierData*) md; 00178 MVert *mvert = NULL; 00179 MDeformVert *dvert; 00180 int defgrp_index; 00181 float ctime = BKE_curframe(scene); 00182 float minfac = 00183 (float)(1.0 / exp(wmd->width * wmd->narrow * wmd->width * wmd->narrow)); 00184 float lifefac = wmd->height; 00185 float (*tex_co)[3] = NULL; 00186 const int wmd_axis= wmd->flag & (MOD_WAVE_X|MOD_WAVE_Y); 00187 const float falloff= wmd->falloff; 00188 float falloff_fac= 1.0f; /* when falloff == 0.0f this stays at 1.0f */ 00189 00190 if(wmd->flag & MOD_WAVE_NORM && ob->type == OB_MESH) 00191 mvert = dm->getVertArray(dm); 00192 00193 if(wmd->objectcenter){ 00194 float mat[4][4]; 00195 /* get the control object's location in local coordinates */ 00196 invert_m4_m4(ob->imat, ob->obmat); 00197 mult_m4_m4m4(mat, ob->imat, wmd->objectcenter->obmat); 00198 00199 wmd->startx = mat[3][0]; 00200 wmd->starty = mat[3][1]; 00201 } 00202 00203 /* get the index of the deform group */ 00204 modifier_get_vgroup(ob, dm, wmd->defgrp_name, &dvert, &defgrp_index); 00205 00206 if(wmd->damp == 0) wmd->damp = 10.0f; 00207 00208 if(wmd->lifetime != 0.0f) { 00209 float x = ctime - wmd->timeoffs; 00210 00211 if(x > wmd->lifetime) { 00212 lifefac = x - wmd->lifetime; 00213 00214 if(lifefac > wmd->damp) lifefac = 0.0; 00215 else lifefac = 00216 (float)(wmd->height * (1.0f - sqrtf(lifefac / wmd->damp))); 00217 } 00218 } 00219 00220 if(wmd->texture) { 00221 tex_co = MEM_mallocN(sizeof(*tex_co) * numVerts, 00222 "waveModifier_do tex_co"); 00223 get_texture_coords((MappingInfoModifierData *)wmd, ob, dm, vertexCos, tex_co, numVerts); 00224 } 00225 00226 if(lifefac != 0.0f) { 00227 /* avoid divide by zero checks within the loop */ 00228 float falloff_inv= falloff ? 1.0f / falloff : 1.0f; 00229 int i; 00230 00231 for(i = 0; i < numVerts; i++) { 00232 float *co = vertexCos[i]; 00233 float x = co[0] - wmd->startx; 00234 float y = co[1] - wmd->starty; 00235 float amplit= 0.0f; 00236 float def_weight= 1.0f; 00237 00238 /* get weights */ 00239 if(dvert) { 00240 def_weight= defvert_find_weight(&dvert[i], defgrp_index); 00241 00242 /* if this vert isn't in the vgroup, don't deform it */ 00243 if(def_weight == 0.0f) { 00244 continue; 00245 } 00246 } 00247 00248 switch(wmd_axis) { 00249 case MOD_WAVE_X|MOD_WAVE_Y: 00250 amplit = sqrtf(x*x + y*y); 00251 break; 00252 case MOD_WAVE_X: 00253 amplit = x; 00254 break; 00255 case MOD_WAVE_Y: 00256 amplit = y; 00257 break; 00258 } 00259 00260 /* this way it makes nice circles */ 00261 amplit -= (ctime - wmd->timeoffs) * wmd->speed; 00262 00263 if(wmd->flag & MOD_WAVE_CYCL) { 00264 amplit = (float)fmodf(amplit - wmd->width, 2.0f * wmd->width) 00265 + wmd->width; 00266 } 00267 00268 if(falloff != 0.0f) { 00269 float dist = 0.0f; 00270 00271 switch(wmd_axis) { 00272 case MOD_WAVE_X|MOD_WAVE_Y: 00273 dist = sqrtf(x*x + y*y); 00274 break; 00275 case MOD_WAVE_X: 00276 dist = fabsf(x); 00277 break; 00278 case MOD_WAVE_Y: 00279 dist = fabsf(y); 00280 break; 00281 } 00282 00283 falloff_fac = (1.0f - (dist * falloff_inv)); 00284 CLAMP(falloff_fac, 0.0f, 1.0f); 00285 } 00286 00287 /* GAUSSIAN */ 00288 if((falloff_fac != 0.0f) && (amplit > -wmd->width) && (amplit < wmd->width)) { 00289 amplit = amplit * wmd->narrow; 00290 amplit = (float)(1.0f / expf(amplit * amplit) - minfac); 00291 00292 /*apply texture*/ 00293 if(wmd->texture) { 00294 TexResult texres; 00295 texres.nor = NULL; 00296 get_texture_value(wmd->texture, tex_co[i], &texres); 00297 amplit *= texres.tin; 00298 } 00299 00300 /*apply weight & falloff */ 00301 amplit *= def_weight * falloff_fac; 00302 00303 if(mvert) { 00304 /* move along normals */ 00305 if(wmd->flag & MOD_WAVE_NORM_X) { 00306 co[0] += (lifefac * amplit) * mvert[i].no[0] / 32767.0f; 00307 } 00308 if(wmd->flag & MOD_WAVE_NORM_Y) { 00309 co[1] += (lifefac * amplit) * mvert[i].no[1] / 32767.0f; 00310 } 00311 if(wmd->flag & MOD_WAVE_NORM_Z) { 00312 co[2] += (lifefac * amplit) * mvert[i].no[2] / 32767.0f; 00313 } 00314 } 00315 else { 00316 /* move along local z axis */ 00317 co[2] += lifefac * amplit; 00318 } 00319 } 00320 } 00321 } 00322 00323 if(wmd->texture) MEM_freeN(tex_co); 00324 } 00325 00326 static void deformVerts(ModifierData *md, Object *ob, 00327 DerivedMesh *derivedData, 00328 float (*vertexCos)[3], 00329 int numVerts, 00330 int UNUSED(useRenderParams), 00331 int UNUSED(isFinalCalc)) 00332 { 00333 DerivedMesh *dm= derivedData; 00334 WaveModifierData *wmd = (WaveModifierData *)md; 00335 00336 if(wmd->flag & MOD_WAVE_NORM) 00337 dm= get_cddm(ob, NULL, dm, vertexCos); 00338 else if(wmd->texture || wmd->defgrp_name[0]) 00339 dm= get_dm(ob, NULL, dm, NULL, 0); 00340 00341 waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts); 00342 00343 if(dm != derivedData) 00344 dm->release(dm); 00345 } 00346 00347 static void deformVertsEM( 00348 ModifierData *md, Object *ob, struct EditMesh *editData, 00349 DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) 00350 { 00351 DerivedMesh *dm= derivedData; 00352 WaveModifierData *wmd = (WaveModifierData *)md; 00353 00354 if(wmd->flag & MOD_WAVE_NORM) 00355 dm= get_cddm(ob, editData, dm, vertexCos); 00356 else if(wmd->texture || wmd->defgrp_name[0]) 00357 dm= get_dm(ob, editData, dm, NULL, 0); 00358 00359 waveModifier_do(wmd, md->scene, ob, dm, vertexCos, numVerts); 00360 00361 if(dm != derivedData) 00362 dm->release(dm); 00363 } 00364 00365 00366 ModifierTypeInfo modifierType_Wave = { 00367 /* name */ "Wave", 00368 /* structName */ "WaveModifierData", 00369 /* structSize */ sizeof(WaveModifierData), 00370 /* type */ eModifierTypeType_OnlyDeform, 00371 /* flags */ eModifierTypeFlag_AcceptsCVs 00372 | eModifierTypeFlag_SupportsEditmode, 00373 /* copyData */ copyData, 00374 /* deformVerts */ deformVerts, 00375 /* deformMatrices */ NULL, 00376 /* deformVertsEM */ deformVertsEM, 00377 /* deformMatricesEM */ NULL, 00378 /* applyModifier */ NULL, 00379 /* applyModifierEM */ NULL, 00380 /* initData */ initData, 00381 /* requiredDataMask */ requiredDataMask, 00382 /* freeData */ NULL, 00383 /* isDisabled */ NULL, 00384 /* updateDepgraph */ updateDepgraph, 00385 /* dependsOnTime */ dependsOnTime, 00386 /* dependsOnNormals */ NULL, 00387 /* foreachObjectLink */ foreachObjectLink, 00388 /* foreachIDLink */ foreachIDLink, 00389 /* foreachTexLink */ foreachTexLink, 00390 };