2
* $Id: MOD_hook.c 29429 2010-06-13 00:11:42Z campbellbarton $
4
* ***** BEGIN GPL LICENSE BLOCK *****
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
21
* All rights reserved.
23
* Contributor(s): Daniel Dunbar
29
* ***** END GPL LICENSE BLOCK *****
2
* ***** BEGIN GPL LICENSE BLOCK *****
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License
6
* as published by the Free Software Foundation; either version 2
7
* of the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software Foundation,
16
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
19
* All rights reserved.
21
* Contributor(s): Daniel Dunbar
27
* ***** END GPL LICENSE BLOCK *****
31
/** \file blender/modifiers/intern/MOD_hook.c
33
36
#include "DNA_mesh_types.h"
34
37
#include "DNA_meshdata_types.h"
38
#include "DNA_object_types.h"
36
40
#include "BLI_math.h"
41
#include "BLI_utildefines.h"
42
#include "BLI_string.h"
38
44
#include "BKE_action.h"
39
45
#include "BKE_cdderivedmesh.h"
40
46
#include "BKE_modifier.h"
41
47
#include "BKE_deform.h"
43
50
#include "depsgraph_private.h"
44
51
#include "MEM_guardedalloc.h"
47
55
static void initData(ModifierData *md)
63
71
thmd->totindex = hmd->totindex;
64
72
thmd->indexar = MEM_dupallocN(hmd->indexar);
65
73
memcpy(thmd->parentinv, hmd->parentinv, sizeof(hmd->parentinv));
66
strncpy(thmd->name, hmd->name, 32);
67
strncpy(thmd->subtarget, hmd->subtarget, 32);
74
BLI_strncpy(thmd->name, hmd->name, sizeof(thmd->name));
75
BLI_strncpy(thmd->subtarget, hmd->subtarget, sizeof(thmd->subtarget));
70
static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
78
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
72
80
HookModifierData *hmd = (HookModifierData *)md;
73
81
CustomDataMask dataMask = 0;
75
83
/* ask for vertexgroups if we need them */
76
if(!hmd->indexar && hmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT);
84
if (hmd->name[0]) dataMask |= CD_MASK_MDEFORMVERT;
85
if (hmd->indexar) dataMask |= CD_MASK_ORIGINDEX;
120
static void deformVerts(
121
ModifierData *md, Object *ob, DerivedMesh *derivedData,
122
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
124
HookModifierData *hmd = (HookModifierData*) md;
131
static float hook_falloff(float *co_1, float *co_2, const float falloff_squared, float fac)
133
if (falloff_squared) {
134
float len_squared = len_squared_v3v3(co_1, co_2);
135
if (len_squared > falloff_squared) {
138
else if (len_squared > 0.0f) {
139
return fac * (1.0f - (len_squared / falloff_squared));
146
static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm,
147
float (*vertexCos)[3], int numVerts)
125
149
bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget);
126
150
float vec[3], mat[4][4], dmat[4][4];
128
DerivedMesh *dm = derivedData;
152
const float falloff_squared= hmd->falloff * hmd->falloff; /* for faster comparisons */
155
int defgrp_index, max_dvert;
130
157
/* get world-space matrix of target, corrected for the space the verts are in */
131
158
if (hmd->subtarget[0] && pchan) {
132
159
/* bone target if there's a matching pose-channel */
133
mul_m4_m4m4(dmat, pchan->pose_mat, hmd->object->obmat);
160
mult_m4_m4m4(dmat, hmd->object->obmat, pchan->pose_mat);
136
163
/* just object target */
139
166
invert_m4_m4(ob->imat, ob->obmat);
140
167
mul_serie_m4(mat, ob->imat, dmat, hmd->parentinv,
141
NULL, NULL, NULL, NULL, NULL);
143
/* vertex indices? */
145
for(i = 0; i < hmd->totindex; i++) {
146
int index = hmd->indexar[i];
148
/* This should always be true and I don't generally like
149
* "paranoid" style code like this, but old files can have
150
* indices that are out of range because old blender did
151
* not correct them on exit editmode. - zr
153
if(index < numVerts) {
154
float *co = vertexCos[index];
155
float fac = hmd->force;
157
/* if DerivedMesh is present and has original index data,
160
if(dm && dm->getVertDataArray(dm, CD_ORIGINDEX)) {
168
NULL, NULL, NULL, NULL, NULL);
170
modifier_get_vgroup(ob, dm, hmd->name, &dvert, &defgrp_index);
171
max_dvert = (dvert)? numVerts: 0;
173
/* Regarding index range checking below.
175
* This should always be true and I don't generally like
176
* "paranoid" style code like this, but old files can have
177
* indices that are out of range because old blender did
178
* not correct them on exit editmode. - zr
181
if (hmd->force == 0.0f) {
182
/* do nothing, avoid annoying checks in the loop */
184
else if (hmd->indexar) { /* vertex indices? */
185
const float fac_orig= hmd->force;
187
const int *origindex_ar;
189
/* if DerivedMesh is present and has original index data, use it */
190
if (dm && (origindex_ar= dm->getVertDataArray(dm, CD_ORIGINDEX))) {
191
for (i= 0, index_pt= hmd->indexar; i < hmd->totindex; i++, index_pt++) {
192
if (*index_pt < numVerts) {
163
for(j = 0; j < numVerts; ++j) {
165
orig_index = *(int *)dm->getVertData(dm, j,
167
if(orig_index == index) {
169
if(hmd->falloff != 0.0) {
170
float len = len_v3v3(co, hmd->cent);
171
if(len > hmd->falloff) fac = 0.0;
173
fac *= sqrt(1.0 - len / hmd->falloff);
177
mul_v3_m4v3(vec, mat, co);
178
interp_v3_v3v3(co, co, vec, fac);
183
if(hmd->falloff != 0.0) {
184
float len = len_v3v3(co, hmd->cent);
185
if(len > hmd->falloff) fac = 0.0;
187
fac *= sqrt(1.0 - len / hmd->falloff);
191
mul_v3_m4v3(vec, mat, co);
192
interp_v3_v3v3(co, co, vec, fac);
198
else if(hmd->name[0]) { /* vertex group hook */
202
int defgrp_index = defgroup_name_index(ob, hmd->name);
205
if(dm->getVertData(dm, 0, CD_MDEFORMVERT)) {
206
maxVerts = dm->getNumVerts(dm);
211
maxVerts = me->totvert;
215
if(defgrp_index >= 0 && use_dverts) {
216
MDeformVert *dvert = me->dvert;
195
for (j = 0; j < numVerts; j++) {
196
if (origindex_ar[j] == *index_pt) {
197
float *co = vertexCos[j];
198
if ((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
200
fac *= defvert_find_weight(dvert+j, defgrp_index);
203
mul_v3_m4v3(vec, mat, co);
204
interp_v3_v3v3(co, co, vec, fac);
212
else { /* missing dm or ORIGINDEX */
213
for (i= 0, index_pt= hmd->indexar; i < hmd->totindex; i++, index_pt++) {
214
if (*index_pt < numVerts) {
215
float *co = vertexCos[*index_pt];
216
if ((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
218
fac *= defvert_find_weight(dvert+(*index_pt), defgrp_index);
221
mul_v3_m4v3(vec, mat, co);
222
interp_v3_v3v3(co, co, vec, fac);
229
else if (dvert) { /* vertex group hook */
230
const float fac_orig= hmd->force;
232
for (i = 0; i < max_dvert; i++, dvert++) {
220
for(i = 0; i < maxVerts; i++, dvert++) {
221
if(dm) dvert = dm->getVertData(dm, i, CD_MDEFORMVERT);
223
fac= defvert_find_weight(dvert, defgrp_index);
226
float *co = vertexCos[i];
228
if(hmd->falloff != 0.0) {
229
float len = len_v3v3(co, hmd->cent);
230
if(len > hmd->falloff) fac = 0.0;
232
fac *= sqrt(1.0 - len / hmd->falloff);
234
float *co = vertexCos[i];
236
if ((fac= hook_falloff(hmd->cent, co, falloff_squared, fac_orig))) {
237
fac *= defvert_find_weight(dvert, defgrp_index);
235
239
mul_v3_m4v3(vec, mat, co);
236
240
interp_v3_v3v3(co, co, vec, fac);
243
static void deformVertsEM(
244
ModifierData *md, Object *ob, struct EditMesh *editData,
245
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
247
DerivedMesh *dm = derivedData;
249
if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
251
deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
253
if(!derivedData) dm->release(dm);
247
static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData,
248
float (*vertexCos)[3], int numVerts,
249
int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
251
HookModifierData *hmd = (HookModifierData*) md;
252
DerivedMesh *dm = derivedData;
253
/* We need a valid dm for meshes when a vgroup is set... */
254
if (!dm && ob->type == OB_MESH && hmd->name[0] != '\0')
255
dm = get_dm(ob, NULL, dm, NULL, 0);
257
deformVerts_do(hmd, ob, dm, vertexCos, numVerts);
259
if (derivedData != dm)
263
static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editData,
264
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
266
HookModifierData *hmd = (HookModifierData*) md;
267
DerivedMesh *dm = derivedData;
268
/* We need a valid dm for meshes when a vgroup is set... */
269
if (!dm && ob->type == OB_MESH && hmd->name[0] != '\0')
270
dm = get_dm(ob, editData, dm, NULL, 0);
272
deformVerts_do(hmd, ob, dm, vertexCos, numVerts);
274
if (derivedData != dm)
263
285
| eModifierTypeFlag_SupportsEditmode,
264
286
/* copyData */ copyData,
265
287
/* deformVerts */ deformVerts,
288
/* deformMatrices */ NULL,
266
289
/* deformVertsEM */ deformVertsEM,
267
/* deformMatricesEM */ 0,
268
/* applyModifier */ 0,
269
/* applyModifierEM */ 0,
290
/* deformMatricesEM */ NULL,
291
/* applyModifier */ NULL,
292
/* applyModifierEM */ NULL,
270
293
/* initData */ initData,
271
294
/* requiredDataMask */ requiredDataMask,
272
295
/* freeData */ freeData,
273
296
/* isDisabled */ isDisabled,
274
297
/* updateDepgraph */ updateDepgraph,
275
/* dependsOnTime */ 0,
298
/* dependsOnTime */ NULL,
299
/* dependsOnNormals */ NULL,
276
300
/* foreachObjectLink */ foreachObjectLink,
277
/* foreachIDLink */ 0,
301
/* foreachIDLink */ NULL,
302
/* foreachTexLink */ NULL,