SVN maintenance.
[blender.git] / source / blender / modifiers / intern / MOD_hook.c
1 /*
2 * $Id$
3 *
4 * ***** BEGIN GPL LICENSE BLOCK *****
5 *
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.
10 *
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.
15 *
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.
19 *
20 * The Original Code is Copyright (C) 2005 by the Blender Foundation.
21 * All rights reserved.
22 *
23 * Contributor(s): Daniel Dunbar
24 *                 Ton Roosendaal,
25 *                 Ben Batt,
26 *                 Brecht Van Lommel,
27 *                 Campbell Barton
28 *
29 * ***** END GPL LICENSE BLOCK *****
30 *
31 */
32
33 #include "stddef.h"
34 #include "string.h"
35 #include "stdarg.h"
36 #include "math.h"
37 #include "float.h"
38
39 #include "BLI_kdtree.h"
40 #include "BLI_rand.h"
41 #include "BLI_uvproject.h"
42
43 #include "MEM_guardedalloc.h"
44
45 #include "DNA_armature_types.h"
46 #include "DNA_camera_types.h"
47 #include "DNA_curve_types.h"
48 #include "DNA_key_types.h"
49 #include "DNA_material_types.h"
50 #include "DNA_object_fluidsim.h"
51
52
53 #include "BKE_action.h"
54 #include "BKE_bmesh.h"
55 #include "BKE_cloth.h"
56 #include "BKE_cdderivedmesh.h"
57 #include "BKE_displist.h"
58 #include "BKE_fluidsim.h"
59 #include "BKE_global.h"
60 #include "BKE_multires.h"
61 #include "BKE_key.h"
62 #include "BKE_lattice.h"
63 #include "BKE_material.h"
64 #include "BKE_mesh.h"
65 #include "BKE_modifier.h"
66 #include "BKE_object.h"
67 #include "BKE_paint.h"
68 #include "BKE_particle.h"
69 #include "BKE_pointcache.h"
70 #include "BKE_scene.h"
71 #include "BKE_smoke.h"
72 #include "BKE_softbody.h"
73 #include "BKE_subsurf.h"
74 #include "BKE_texture.h"
75
76 #include "depsgraph_private.h"
77 #include "BKE_deform.h"
78 #include "BKE_shrinkwrap.h"
79
80 #include "LOD_decimation.h"
81
82 #include "CCGSubSurf.h"
83
84 #include "RE_shader_ext.h"
85
86 #include "MOD_modifiertypes.h"
87
88
89 static void initData(ModifierData *md) 
90 {
91         HookModifierData *hmd = (HookModifierData*) md;
92
93         hmd->force= 1.0;
94 }
95
96 static void copyData(ModifierData *md, ModifierData *target)
97 {
98         HookModifierData *hmd = (HookModifierData*) md;
99         HookModifierData *thmd = (HookModifierData*) target;
100
101         VECCOPY(thmd->cent, hmd->cent);
102         thmd->falloff = hmd->falloff;
103         thmd->force = hmd->force;
104         thmd->object = hmd->object;
105         thmd->totindex = hmd->totindex;
106         thmd->indexar = MEM_dupallocN(hmd->indexar);
107         memcpy(thmd->parentinv, hmd->parentinv, sizeof(hmd->parentinv));
108         strncpy(thmd->name, hmd->name, 32);
109         strncpy(thmd->subtarget, hmd->subtarget, 32);
110 }
111
112 static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
113 {
114         HookModifierData *hmd = (HookModifierData *)md;
115         CustomDataMask dataMask = 0;
116
117         /* ask for vertexgroups if we need them */
118         if(!hmd->indexar && hmd->name[0]) dataMask |= (1 << CD_MDEFORMVERT);
119
120         return dataMask;
121 }
122
123 static void freeData(ModifierData *md)
124 {
125         HookModifierData *hmd = (HookModifierData*) md;
126
127         if (hmd->indexar) MEM_freeN(hmd->indexar);
128 }
129
130 static int isDisabled(ModifierData *md, int useRenderParams)
131 {
132         HookModifierData *hmd = (HookModifierData*) md;
133
134         return !hmd->object;
135 }
136
137 static void foreachObjectLink(
138                                            ModifierData *md, Object *ob,
139         void (*walk)(void *userData, Object *ob, Object **obpoin),
140                    void *userData)
141 {
142         HookModifierData *hmd = (HookModifierData*) md;
143
144         walk(userData, ob, &hmd->object);
145 }
146
147 static void updateDepgraph(ModifierData *md, DagForest *forest, Scene *scene,
148                                         Object *ob, DagNode *obNode)
149 {
150         HookModifierData *hmd = (HookModifierData*) md;
151
152         if (hmd->object) {
153                 DagNode *curNode = dag_get_node(forest, hmd->object);
154                 
155                 if (hmd->subtarget[0])
156                         dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA|DAG_RL_DATA_DATA, "Hook Modifier");
157                 else
158                         dag_add_relation(forest, curNode, obNode, DAG_RL_OB_DATA, "Hook Modifier");
159         }
160 }
161
162 static void deformVerts(
163                                          ModifierData *md, Object *ob, DerivedMesh *derivedData,
164          float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
165 {
166         HookModifierData *hmd = (HookModifierData*) md;
167         bPoseChannel *pchan= get_pose_channel(hmd->object->pose, hmd->subtarget);
168         float vec[3], mat[4][4], dmat[4][4];
169         int i;
170         DerivedMesh *dm = derivedData;
171         
172         /* get world-space matrix of target, corrected for the space the verts are in */
173         if (hmd->subtarget[0] && pchan) {
174                 /* bone target if there's a matching pose-channel */
175                 mul_m4_m4m4(dmat, pchan->pose_mat, hmd->object->obmat);
176         }
177         else {
178                 /* just object target */
179                 copy_m4_m4(dmat, hmd->object->obmat);
180         }
181         invert_m4_m4(ob->imat, ob->obmat);
182         mul_serie_m4(mat, ob->imat, dmat, hmd->parentinv,
183                          NULL, NULL, NULL, NULL, NULL);
184
185         /* vertex indices? */
186         if(hmd->indexar) {
187                 for(i = 0; i < hmd->totindex; i++) {
188                         int index = hmd->indexar[i];
189
190                         /* This should always be true and I don't generally like 
191                         * "paranoid" style code like this, but old files can have
192                         * indices that are out of range because old blender did
193                         * not correct them on exit editmode. - zr
194                         */
195                         if(index < numVerts) {
196                                 float *co = vertexCos[index];
197                                 float fac = hmd->force;
198
199                                 /* if DerivedMesh is present and has original index data,
200                                 * use it
201                                 */
202                                 if(dm && dm->getVertDataArray(dm, CD_ORIGINDEX)) {
203                                         int j;
204                                         int orig_index;
205                                         for(j = 0; j < numVerts; ++j) {
206                                                 fac = hmd->force;
207                                                 orig_index = *(int *)dm->getVertData(dm, j,
208                                                                 CD_ORIGINDEX);
209                                                 if(orig_index == index) {
210                                                         co = vertexCos[j];
211                                                         if(hmd->falloff != 0.0) {
212                                                                 float len = len_v3v3(co, hmd->cent);
213                                                                 if(len > hmd->falloff) fac = 0.0;
214                                                                 else if(len > 0.0)
215                                                                         fac *= sqrt(1.0 - len / hmd->falloff);
216                                                         }
217
218                                                         if(fac != 0.0) {
219                                                                 mul_v3_m4v3(vec, mat, co);
220                                                                 interp_v3_v3v3(co, co, vec, fac);
221                                                         }
222                                                 }
223                                         }
224                                 } else {
225                                         if(hmd->falloff != 0.0) {
226                                                 float len = len_v3v3(co, hmd->cent);
227                                                 if(len > hmd->falloff) fac = 0.0;
228                                                 else if(len > 0.0)
229                                                         fac *= sqrt(1.0 - len / hmd->falloff);
230                                         }
231
232                                         if(fac != 0.0) {
233                                                 mul_v3_m4v3(vec, mat, co);
234                                                 interp_v3_v3v3(co, co, vec, fac);
235                                         }
236                                 }
237                         }
238                 }
239         } 
240         else if(hmd->name[0]) { /* vertex group hook */
241                 Mesh *me = ob->data;
242                 int use_dverts = 0;
243                 int maxVerts = 0;
244                 int defgrp_index = defgroup_name_index(ob, hmd->name);
245
246                 if(dm) {
247                         if(dm->getVertData(dm, 0, CD_MDEFORMVERT)) {
248                                 maxVerts = dm->getNumVerts(dm);
249                                 use_dverts = 1;
250                         }
251                 }
252                 else if(me->dvert) {
253                         maxVerts = me->totvert;
254                         use_dverts = 1;
255                 }
256
257                 if(defgrp_index >= 0 && use_dverts) {
258                         MDeformVert *dvert = me->dvert;
259                         int i, j;
260
261                         for(i = 0; i < maxVerts; i++, dvert++) {
262                                 if(dm) dvert = dm->getVertData(dm, i, CD_MDEFORMVERT);
263                                 for(j = 0; j < dvert->totweight; j++) {
264                                         if(dvert->dw[j].def_nr == defgrp_index) {
265                                                 float fac = hmd->force*dvert->dw[j].weight;
266                                                 float *co = vertexCos[i];
267
268                                                 if(hmd->falloff != 0.0) {
269                                                         float len = len_v3v3(co, hmd->cent);
270                                                         if(len > hmd->falloff) fac = 0.0;
271                                                         else if(len > 0.0)
272                                                                 fac *= sqrt(1.0 - len / hmd->falloff);
273                                                 }
274
275                                                 mul_v3_m4v3(vec, mat, co);
276                                                 interp_v3_v3v3(co, co, vec, fac);
277                                         }
278                                 }
279                         }
280                 }
281         }
282 }
283
284 static void deformVertsEM(
285                                            ModifierData *md, Object *ob, EditMesh *editData,
286            DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
287 {
288         DerivedMesh *dm = derivedData;
289
290         if(!derivedData) dm = CDDM_from_editmesh(editData, ob->data);
291
292         deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
293
294         if(!derivedData) dm->release(dm);
295 }
296
297
298 ModifierTypeInfo modifierType_Hook = {
299         /* name */              "Hook",
300         /* structName */        "HookModifierData",
301         /* structSize */        sizeof(HookModifierData),
302         /* type */              eModifierTypeType_OnlyDeform,
303         /* flags */             eModifierTypeFlag_AcceptsCVs
304                                                         | eModifierTypeFlag_SupportsEditmode,
305         /* copyData */          copyData,
306         /* deformVerts */       deformVerts,
307         /* deformVertsEM */     deformVertsEM,
308         /* deformMatricesEM */  0,
309         /* applyModifier */     0,
310         /* applyModifierEM */   0,
311         /* initData */          initData,
312         /* requiredDataMask */  requiredDataMask,
313         /* freeData */          freeData,
314         /* isDisabled */        isDisabled,
315         /* updateDepgraph */    updateDepgraph,
316         /* dependsOnTime */     0,
317         /* foreachObjectLink */ foreachObjectLink,
318         /* foreachIDLink */     0,
319 };