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