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 "DNA_mesh_types.h" 00037 #include "DNA_meshdata_types.h" 00038 #include "DNA_object_types.h" 00039 00040 #include "BLI_math.h" 00041 #include "BLI_utildefines.h" 00042 #include "BLI_string.h" 00043 00044 #include "BKE_action.h" 00045 #include "BKE_cdderivedmesh.h" 00046 #include "BKE_modifier.h" 00047 #include "BKE_deform.h" 00048 00049 00050 #include "depsgraph_private.h" 00051 #include "MEM_guardedalloc.h" 00052 00053 #include "MOD_util.h" 00054 00055 static void initData(ModifierData *md) 00056 { 00057 HookModifierData *hmd = (HookModifierData*) md; 00058 00059 hmd->force= 1.0; 00060 } 00061 00062 static void copyData(ModifierData *md, ModifierData *target) 00063 { 00064 HookModifierData *hmd = (HookModifierData*) md; 00065 HookModifierData *thmd = (HookModifierData*) target; 00066 00067 copy_v3_v3(thmd->cent, hmd->cent); 00068 thmd->falloff = hmd->falloff; 00069 thmd->force = hmd->force; 00070 thmd->object = hmd->object; 00071 thmd->totindex = hmd->totindex; 00072 thmd->indexar = MEM_dupallocN(hmd->indexar); 00073 memcpy(thmd->parentinv, hmd->parentinv, sizeof(hmd->parentinv)); 00074 BLI_strncpy(thmd->name, hmd->name, sizeof(thmd->name)); 00075 BLI_strncpy(thmd->subtarget, hmd->subtarget, sizeof(thmd->subtarget)); 00076 } 00077 00078 static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) 00079 { 00080 HookModifierData *hmd = (HookModifierData *)md; 00081 CustomDataMask dataMask = 0; 00082 00083 /* ask for vertexgroups if we need them */ 00084 if(hmd->name[0]) dataMask |= CD_MASK_MDEFORMVERT; 00085 if(hmd->indexar) dataMask |= CD_MASK_ORIGINDEX; 00086 00087 return dataMask; 00088 } 00089 00090 static void freeData(ModifierData *md) 00091 { 00092 HookModifierData *hmd = (HookModifierData*) md; 00093 00094 if (hmd->indexar) MEM_freeN(hmd->indexar); 00095 } 00096 00097 static int isDisabled(ModifierData *md, int UNUSED(useRenderParams)) 00098 { 00099 HookModifierData *hmd = (HookModifierData*) md; 00100 00101 return !hmd->object; 00102 } 00103 00104 static void foreachObjectLink( 00105 ModifierData *md, Object *ob, 00106 void (*walk)(void *userData, Object *ob, Object **obpoin), 00107 void *userData) 00108 { 00109 HookModifierData *hmd = (HookModifierData*) md; 00110 00111 walk(userData, ob, &hmd->object); 00112 } 00113 00114 static void updateDepgraph(ModifierData *md, DagForest *forest, 00115 struct Scene *UNUSED(scene), 00116 Object *UNUSED(ob), 00117 DagNode *obNode) 00118 { 00119 HookModifierData *hmd = (HookModifierData*) md; 00120 00121 if (hmd->object) { 00122 DagNode *curNode = dag_get_node(forest, hmd->object); 00123 00124 if (hmd->subtarget[0]) 00125 dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA|DAG_RL_DATA_DATA, "Hook Modifier"); 00126 else 00127 dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "Hook Modifier"); 00128 } 00129 } 00130 00131 static float hook_falloff(float *co_1, float *co_2, const float falloff_squared, float fac) 00132 { 00133 if(falloff_squared) { 00134 float len_squared = len_squared_v3v3(co_1, co_2); 00135 if(len_squared > falloff_squared) { 00136 return 0.0f; 00137 } 00138 else if(len_squared > 0.0f) { 00139 return fac * (1.0f - (len_squared / falloff_squared)); 00140 } 00141 } 00142 00143 return fac; 00144 } 00145 00146 static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm, 00147 float (*vertexCos)[3], int numVerts) 00148 { 00149 bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget); 00150 float vec[3], mat[4][4], dmat[4][4]; 00151 int i, *index_pt; 00152 const float falloff_squared= hmd->falloff * hmd->falloff; /* for faster comparisons */ 00153 00154 MDeformVert *dvert; 00155 int defgrp_index, max_dvert; 00156 00157 /* get world-space matrix of target, corrected for the space the verts are in */ 00158 if (hmd->subtarget[0] && pchan) { 00159 /* bone target if there's a matching pose-channel */ 00160 mult_m4_m4m4(dmat, hmd->object->obmat, pchan->pose_mat); 00161 } 00162 else { 00163 /* just object target */ 00164 copy_m4_m4(dmat, hmd->object->obmat); 00165 } 00166 invert_m4_m4(ob->imat, ob->obmat); 00167 mul_serie_m4(mat, ob->imat, dmat, hmd->parentinv, 00168 NULL, NULL, NULL, NULL, NULL); 00169 00170 modifier_get_vgroup(ob, dm, hmd->name, &dvert, &defgrp_index); 00171 max_dvert = (dvert)? numVerts: 0; 00172 00173 /* Regarding index range checking below. 00174 * 00175 * This should always be true and I don't generally like 00176 * "paranoid" style code like this, but old files can have 00177 * indices that are out of range because old blender did 00178 * not correct them on exit editmode. - zr 00179 */ 00180 00181 if(hmd->force == 0.0f) { 00182 /* do nothing, avoid annoying checks in the loop */ 00183 } 00184 else if(hmd->indexar) { /* vertex indices? */ 00185 const float fac_orig= hmd->force; 00186 float fac; 00187 const int *origindex_ar; 00188 00189 /* if DerivedMesh is present and has original index data, use it */ 00190 if(dm && (origindex_ar= dm->getVertDataArray(dm, CD_ORIGINDEX))) { 00191 for(i= 0, index_pt= hmd->indexar; i < hmd->totindex; i++, index_pt++) { 00192 if(*index_pt < numVerts) { 00193 int j; 00194 00195 for(j = 0; j < numVerts; j++) { 00196 if(origindex_ar[j] == *index_pt) { 00197 float *co = vertexCos[j]; 00198 if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) { 00199 if(dvert) 00200 fac *= defvert_find_weight(dvert+j, defgrp_index); 00201 00202 if(fac) { 00203 mul_v3_m4v3(vec, mat, co); 00204 interp_v3_v3v3(co, co, vec, fac); 00205 } 00206 } 00207 } 00208 } 00209 } 00210 } 00211 } 00212 else { /* missing dm or ORIGINDEX */ 00213 for(i= 0, index_pt= hmd->indexar; i < hmd->totindex; i++, index_pt++) { 00214 if(*index_pt < numVerts) { 00215 float *co = vertexCos[*index_pt]; 00216 if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) { 00217 if(dvert) 00218 fac *= defvert_find_weight(dvert+(*index_pt), defgrp_index); 00219 00220 if(fac) { 00221 mul_v3_m4v3(vec, mat, co); 00222 interp_v3_v3v3(co, co, vec, fac); 00223 } 00224 } 00225 } 00226 } 00227 } 00228 } 00229 else if(dvert) { /* vertex group hook */ 00230 const float fac_orig= hmd->force; 00231 00232 for(i = 0; i < max_dvert; i++, dvert++) { 00233 float fac; 00234 float *co = vertexCos[i]; 00235 00236 if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) { 00237 fac *= defvert_find_weight(dvert, defgrp_index); 00238 if(fac) { 00239 mul_v3_m4v3(vec, mat, co); 00240 interp_v3_v3v3(co, co, vec, fac); 00241 } 00242 } 00243 } 00244 } 00245 } 00246 00247 static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, 00248 float (*vertexCos)[3], int numVerts, 00249 int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) 00250 { 00251 HookModifierData *hmd = (HookModifierData*) md; 00252 DerivedMesh *dm = derivedData; 00253 /* We need a valid dm for meshes when a vgroup is set... */ 00254 if(!dm && ob->type == OB_MESH && hmd->name[0] != '\0') 00255 dm = get_dm(ob, NULL, dm, NULL, 0); 00256 00257 deformVerts_do(hmd, ob, dm, vertexCos, numVerts); 00258 00259 if(derivedData != dm) 00260 dm->release(dm); 00261 } 00262 00263 static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editData, 00264 DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) 00265 { 00266 HookModifierData *hmd = (HookModifierData*) md; 00267 DerivedMesh *dm = derivedData; 00268 /* We need a valid dm for meshes when a vgroup is set... */ 00269 if(!dm && ob->type == OB_MESH && hmd->name[0] != '\0') 00270 dm = get_dm(ob, editData, dm, NULL, 0); 00271 00272 deformVerts_do(hmd, ob, dm, vertexCos, numVerts); 00273 00274 if(derivedData != dm) 00275 dm->release(dm); 00276 } 00277 00278 00279 ModifierTypeInfo modifierType_Hook = { 00280 /* name */ "Hook", 00281 /* structName */ "HookModifierData", 00282 /* structSize */ sizeof(HookModifierData), 00283 /* type */ eModifierTypeType_OnlyDeform, 00284 /* flags */ eModifierTypeFlag_AcceptsCVs 00285 | eModifierTypeFlag_SupportsEditmode, 00286 /* copyData */ copyData, 00287 /* deformVerts */ deformVerts, 00288 /* deformMatrices */ NULL, 00289 /* deformVertsEM */ deformVertsEM, 00290 /* deformMatricesEM */ NULL, 00291 /* applyModifier */ NULL, 00292 /* applyModifierEM */ NULL, 00293 /* initData */ initData, 00294 /* requiredDataMask */ requiredDataMask, 00295 /* freeData */ freeData, 00296 /* isDisabled */ isDisabled, 00297 /* updateDepgraph */ updateDepgraph, 00298 /* dependsOnTime */ NULL, 00299 /* dependsOnNormals */ NULL, 00300 /* foreachObjectLink */ foreachObjectLink, 00301 /* foreachIDLink */ NULL, 00302 /* foreachTexLink */ NULL, 00303 };