static void hook_co_apply(struct HookData_cb *hd, const int j) { float *co = hd->vertexCos[j]; float fac; if (hd->use_falloff) { float len_sq; if (hd->use_uniform) { float co_uniform[3]; mul_v3_m3v3(co_uniform, hd->mat_uniform, co); len_sq = len_squared_v3v3(hd->cent, co_uniform); } else { len_sq = len_squared_v3v3(hd->cent, co); } fac = hook_falloff(hd, len_sq); } else { fac = hd->fac_orig; } if (fac) { if (hd->dvert) { fac *= defvert_find_weight(&hd->dvert[j], hd->defgrp_index); } if (fac) { float co_tmp[3]; mul_v3_m4v3(co_tmp, hd->mat, co); interp_v3_v3v3(co, co, co_tmp, fac); } } }
static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts, int UNUSED(useRenderParams), int UNUSED(isFinalCalc)) { HookModifierData *hmd = (HookModifierData*) md; bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget); float vec[3], mat[4][4], dmat[4][4]; int i, *index_pt; const float falloff_squared= hmd->falloff * hmd->falloff; /* for faster comparisons */ int max_dvert= 0; MDeformVert *dvert= NULL; int defgrp_index = -1; /* get world-space matrix of target, corrected for the space the verts are in */ if (hmd->subtarget[0] && pchan) { /* bone target if there's a matching pose-channel */ mul_m4_m4m4(dmat, pchan->pose_mat, hmd->object->obmat); } else { /* just object target */ copy_m4_m4(dmat, hmd->object->obmat); } invert_m4_m4(ob->imat, ob->obmat); mul_serie_m4(mat, ob->imat, dmat, hmd->parentinv, NULL, NULL, NULL, NULL, NULL); if((defgrp_index= defgroup_name_index(ob, hmd->name)) != -1) { Mesh *me = ob->data; if(dm) { dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT); if(dvert) { max_dvert = numVerts; } } else if(me->dvert) { dvert= me->dvert; if(dvert) { max_dvert = me->totvert; } } } /* Regarding index range checking below. * * This should always be true and I don't generally like * "paranoid" style code like this, but old files can have * indices that are out of range because old blender did * not correct them on exit editmode. - zr */ if(hmd->force == 0.0f) { /* do nothing, avoid annoying checks in the loop */ } else if(hmd->indexar) { /* vertex indices? */ const float fac_orig= hmd->force; float fac; const int *origindex_ar; /* if DerivedMesh is present and has original index data, * use it */ if(dm && (origindex_ar= dm->getVertDataArray(dm, CD_ORIGINDEX))) { for(i= 0, index_pt= hmd->indexar; i < hmd->totindex; i++, index_pt++) { if(*index_pt < numVerts) { int j; for(j = 0; j < numVerts; j++) { if(origindex_ar[j] == *index_pt) { float *co = vertexCos[j]; if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) { if(dvert) fac *= defvert_find_weight(dvert+j, defgrp_index); if(fac) { mul_v3_m4v3(vec, mat, co); interp_v3_v3v3(co, co, vec, fac); } } } } } } } else { /* missing dm or ORIGINDEX */ for(i= 0, index_pt= hmd->indexar; i < hmd->totindex; i++, index_pt++) { if(*index_pt < numVerts) { float *co = vertexCos[*index_pt]; if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) { if(dvert) fac *= defvert_find_weight(dvert+(*index_pt), defgrp_index); if(fac) { mul_v3_m4v3(vec, mat, co); interp_v3_v3v3(co, co, vec, fac); } } } } } } else if(dvert) { /* vertex group hook */ int i; const float fac_orig= hmd->force; for(i = 0; i < max_dvert; i++, dvert++) { float fac; float *co = vertexCos[i]; if((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) { fac *= defvert_find_weight(dvert, defgrp_index); if(fac) { mul_v3_m4v3(vec, mat, co); interp_v3_v3v3(co, co, vec, fac); } } } } }