|
Blender
V2.59
|
00001 /* 00002 * $Id: MOD_displace.c 38300 2011-07-11 09:15:20Z blendix $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2005 by the Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): Daniel Dunbar 00024 * Ton Roosendaal, 00025 * Ben Batt, 00026 * Brecht Van Lommel, 00027 * Campbell Barton 00028 * 00029 * ***** END GPL LICENSE BLOCK ***** 00030 * 00031 */ 00032 00038 #include "DNA_meshdata_types.h" 00039 #include "DNA_object_types.h" 00040 00041 #include "BLI_math.h" 00042 #include "BLI_utildefines.h" 00043 00044 00045 #include "BKE_cdderivedmesh.h" 00046 #include "BKE_modifier.h" 00047 #include "BKE_texture.h" 00048 #include "BKE_deform.h" 00049 00050 #include "depsgraph_private.h" 00051 #include "MEM_guardedalloc.h" 00052 00053 #include "MOD_util.h" 00054 00055 #include "RE_shader_ext.h" 00056 00057 00058 /* Displace */ 00059 00060 static void initData(ModifierData *md) 00061 { 00062 DisplaceModifierData *dmd = (DisplaceModifierData*) md; 00063 00064 dmd->texture = NULL; 00065 dmd->strength = 1; 00066 dmd->direction = MOD_DISP_DIR_NOR; 00067 dmd->midlevel = 0.5; 00068 } 00069 00070 static void copyData(ModifierData *md, ModifierData *target) 00071 { 00072 DisplaceModifierData *dmd = (DisplaceModifierData*) md; 00073 DisplaceModifierData *tdmd = (DisplaceModifierData*) target; 00074 00075 tdmd->texture = dmd->texture; 00076 tdmd->strength = dmd->strength; 00077 tdmd->direction = dmd->direction; 00078 strncpy(tdmd->defgrp_name, dmd->defgrp_name, 32); 00079 tdmd->midlevel = dmd->midlevel; 00080 tdmd->texmapping = dmd->texmapping; 00081 tdmd->map_object = dmd->map_object; 00082 strncpy(tdmd->uvlayer_name, dmd->uvlayer_name, 32); 00083 } 00084 00085 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) 00086 { 00087 DisplaceModifierData *dmd = (DisplaceModifierData *)md; 00088 CustomDataMask dataMask = 0; 00089 00090 /* ask for vertexgroups if we need them */ 00091 if(dmd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT; 00092 00093 /* ask for UV coordinates if we need them */ 00094 if(dmd->texmapping == MOD_DISP_MAP_UV) dataMask |= CD_MASK_MTFACE; 00095 00096 return dataMask; 00097 } 00098 00099 static int dependsOnTime(ModifierData *md) 00100 { 00101 DisplaceModifierData *dmd = (DisplaceModifierData *)md; 00102 00103 if(dmd->texture) 00104 { 00105 return BKE_texture_dependsOnTime(dmd->texture); 00106 } 00107 else 00108 { 00109 return 0; 00110 } 00111 } 00112 00113 static int dependsOnNormals(ModifierData *md) 00114 { 00115 DisplaceModifierData *dmd = (DisplaceModifierData *)md; 00116 return (dmd->direction == MOD_DISP_DIR_NOR); 00117 } 00118 00119 static void foreachObjectLink(ModifierData *md, Object *ob, 00120 ObjectWalkFunc walk, void *userData) 00121 { 00122 DisplaceModifierData *dmd = (DisplaceModifierData*) md; 00123 00124 walk(userData, ob, &dmd->map_object); 00125 } 00126 00127 static void foreachIDLink(ModifierData *md, Object *ob, 00128 IDWalkFunc walk, void *userData) 00129 { 00130 DisplaceModifierData *dmd = (DisplaceModifierData*) md; 00131 00132 walk(userData, ob, (ID **)&dmd->texture); 00133 00134 foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); 00135 } 00136 00137 static int isDisabled(ModifierData *md, int UNUSED(useRenderParams)) 00138 { 00139 DisplaceModifierData *dmd = (DisplaceModifierData*) md; 00140 00141 return (!dmd->texture || dmd->strength == 0.0f); 00142 } 00143 00144 static void updateDepgraph(ModifierData *md, DagForest *forest, 00145 struct Scene *UNUSED(scene), 00146 Object *UNUSED(ob), 00147 DagNode *obNode) 00148 { 00149 DisplaceModifierData *dmd = (DisplaceModifierData*) md; 00150 00151 if(dmd->map_object && dmd->texmapping == MOD_DISP_MAP_OBJECT) { 00152 DagNode *curNode = dag_get_node(forest, dmd->map_object); 00153 00154 dag_add_relation(forest, curNode, obNode, 00155 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Displace Modifier"); 00156 } 00157 00158 00159 if(dmd->texmapping == MOD_DISP_MAP_GLOBAL) 00160 dag_add_relation(forest, obNode, obNode, 00161 DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Displace Modifier"); 00162 00163 } 00164 00165 /* dm must be a CDDerivedMesh */ 00166 static void displaceModifier_do( 00167 DisplaceModifierData *dmd, Object *ob, 00168 DerivedMesh *dm, float (*vertexCos)[3], int numVerts) 00169 { 00170 int i; 00171 MVert *mvert; 00172 MDeformVert *dvert; 00173 int defgrp_index; 00174 float (*tex_co)[3]; 00175 float weight= 1.0f; /* init value unused but some compilers may complain */ 00176 00177 if(!dmd->texture) return; 00178 if(dmd->strength == 0.0f) return; 00179 00180 mvert = CDDM_get_verts(dm); 00181 modifier_get_vgroup(ob, dm, dmd->defgrp_name, &dvert, &defgrp_index); 00182 00183 tex_co = MEM_callocN(sizeof(*tex_co) * numVerts, 00184 "displaceModifier_do tex_co"); 00185 get_texture_coords((MappingInfoModifierData *)dmd, ob, dm, vertexCos, tex_co, numVerts); 00186 00187 for(i = 0; i < numVerts; ++i) { 00188 TexResult texres; 00189 float delta = 0, strength = dmd->strength; 00190 00191 if(dvert) { 00192 weight= defvert_find_weight(dvert + i, defgrp_index); 00193 if(weight == 0.0f) continue; 00194 } 00195 00196 texres.nor = NULL; 00197 get_texture_value(dmd->texture, tex_co[i], &texres); 00198 00199 delta = texres.tin - dmd->midlevel; 00200 00201 if(dvert) strength *= weight; 00202 00203 delta *= strength; 00204 CLAMP(delta, -10000, 10000); 00205 00206 switch(dmd->direction) { 00207 case MOD_DISP_DIR_X: 00208 vertexCos[i][0] += delta; 00209 break; 00210 case MOD_DISP_DIR_Y: 00211 vertexCos[i][1] += delta; 00212 break; 00213 case MOD_DISP_DIR_Z: 00214 vertexCos[i][2] += delta; 00215 break; 00216 case MOD_DISP_DIR_RGB_XYZ: 00217 vertexCos[i][0] += (texres.tr - dmd->midlevel) * strength; 00218 vertexCos[i][1] += (texres.tg - dmd->midlevel) * strength; 00219 vertexCos[i][2] += (texres.tb - dmd->midlevel) * strength; 00220 break; 00221 case MOD_DISP_DIR_NOR: 00222 vertexCos[i][0] += delta * (mvert[i].no[0] / 32767.0f); 00223 vertexCos[i][1] += delta * (mvert[i].no[1] / 32767.0f); 00224 vertexCos[i][2] += delta * (mvert[i].no[2] / 32767.0f); 00225 break; 00226 } 00227 } 00228 00229 MEM_freeN(tex_co); 00230 } 00231 00232 static void deformVerts(ModifierData *md, Object *ob, 00233 DerivedMesh *derivedData, 00234 float (*vertexCos)[3], 00235 int numVerts, 00236 int UNUSED(useRenderParams), 00237 int UNUSED(isFinalCalc)) 00238 { 00239 DerivedMesh *dm= get_cddm(ob, NULL, derivedData, vertexCos); 00240 00241 displaceModifier_do((DisplaceModifierData *)md, ob, dm, 00242 vertexCos, numVerts); 00243 00244 if(dm != derivedData) 00245 dm->release(dm); 00246 } 00247 00248 static void deformVertsEM( 00249 ModifierData *md, Object *ob, struct EditMesh *editData, 00250 DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) 00251 { 00252 DerivedMesh *dm= get_cddm(ob, editData, derivedData, vertexCos); 00253 00254 displaceModifier_do((DisplaceModifierData *)md, ob, dm, 00255 vertexCos, numVerts); 00256 00257 if(dm != derivedData) 00258 dm->release(dm); 00259 } 00260 00261 00262 ModifierTypeInfo modifierType_Displace = { 00263 /* name */ "Displace", 00264 /* structName */ "DisplaceModifierData", 00265 /* structSize */ sizeof(DisplaceModifierData), 00266 /* type */ eModifierTypeType_OnlyDeform, 00267 /* flags */ eModifierTypeFlag_AcceptsMesh 00268 | eModifierTypeFlag_SupportsEditmode, 00269 00270 /* copyData */ copyData, 00271 /* deformVerts */ deformVerts, 00272 /* deformMatrices */ NULL, 00273 /* deformVertsEM */ deformVertsEM, 00274 /* deformMatricesEM */ NULL, 00275 /* applyModifier */ NULL, 00276 /* applyModifierEM */ NULL, 00277 /* initData */ initData, 00278 /* requiredDataMask */ requiredDataMask, 00279 /* freeData */ NULL, 00280 /* isDisabled */ isDisabled, 00281 /* updateDepgraph */ updateDepgraph, 00282 /* dependsOnTime */ dependsOnTime, 00283 /* dependsOnNormals */ dependsOnNormals, 00284 /* foreachObjectLink */ foreachObjectLink, 00285 /* foreachIDLink */ foreachIDLink, 00286 };