- use more inline math funcitons where possible
[blender.git] / source / blender / modifiers / intern / MOD_cloth.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_cloth.h"
55 #include "BKE_cdderivedmesh.h"
56 #include "BKE_displist.h"
57 #include "BKE_fluidsim.h"
58 #include "BKE_global.h"
59 #include "BKE_multires.h"
60 #include "BKE_key.h"
61 #include "BKE_lattice.h"
62 #include "BKE_material.h"
63 #include "BKE_mesh.h"
64 #include "BKE_modifier.h"
65 #include "BKE_object.h"
66 #include "BKE_paint.h"
67 #include "BKE_particle.h"
68 #include "BKE_pointcache.h"
69 #include "BKE_scene.h"
70 #include "BKE_smoke.h"
71 #include "BKE_softbody.h"
72 #include "BKE_subsurf.h"
73 #include "BKE_texture.h"
74
75 #include "depsgraph_private.h"
76 #include "BKE_deform.h"
77 #include "BKE_shrinkwrap.h"
78
79 #include "LOD_decimation.h"
80
81 #include "CCGSubSurf.h"
82
83 #include "RE_shader_ext.h"
84
85 #include "MOD_modifiertypes.h"
86
87
88 static void initData(ModifierData *md) 
89 {
90         ClothModifierData *clmd = (ClothModifierData*) md;
91         
92         clmd->sim_parms = MEM_callocN(sizeof(ClothSimSettings), "cloth sim parms");
93         clmd->coll_parms = MEM_callocN(sizeof(ClothCollSettings), "cloth coll parms");
94         clmd->point_cache = BKE_ptcache_add(&clmd->ptcaches);
95         
96         /* check for alloc failing */
97         if(!clmd->sim_parms || !clmd->coll_parms || !clmd->point_cache)
98                 return;
99         
100         cloth_init (clmd);
101 }
102
103 static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
104                 DerivedMesh *derivedData, int useRenderParams, int isFinalCalc)
105 {
106         ClothModifierData *clmd = (ClothModifierData*) md;
107         DerivedMesh *result=NULL;
108         
109         /* check for alloc failing */
110         if(!clmd->sim_parms || !clmd->coll_parms)
111         {
112                 initData(md);
113                 
114                 if(!clmd->sim_parms || !clmd->coll_parms)
115                         return derivedData;
116         }
117
118         result = clothModifier_do(clmd, md->scene, ob, derivedData, useRenderParams, isFinalCalc);
119
120         if(result)
121         {
122                 CDDM_calc_normals(result);
123                 return result;
124         }
125         return derivedData;
126 }
127
128 static void updateDepgraph(
129                                          ModifierData *md, DagForest *forest, Scene *scene, Object *ob,
130           DagNode *obNode)
131 {
132         ClothModifierData *clmd = (ClothModifierData*) md;
133         
134         Base *base;
135         
136         if(clmd)
137         {
138                 for(base = scene->base.first; base; base= base->next) 
139                 {
140                         Object *ob1= base->object;
141                         if(ob1 != ob)
142                         {
143                                 CollisionModifierData *coll_clmd = (CollisionModifierData *)modifiers_findByType(ob1, eModifierType_Collision);
144                                 if(coll_clmd)
145                                 {
146                                         DagNode *curNode = dag_get_node(forest, ob1);
147                                         dag_add_relation(forest, curNode, obNode, DAG_RL_DATA_DATA|DAG_RL_OB_DATA, "Cloth Collision");
148                                 }
149                         }
150                 }
151         }
152 }
153
154 static CustomDataMask requiredDataMask(Object *ob, ModifierData *md)
155 {
156         CustomDataMask dataMask = 0;
157         ClothModifierData *clmd = (ClothModifierData*)md;
158
159         if(cloth_uses_vgroup(clmd))
160                 dataMask |= (1 << CD_MDEFORMVERT);
161
162         if(clmd->sim_parms->shapekey_rest != 0)
163                 dataMask |= (1 << CD_CLOTH_ORCO);
164
165         return dataMask;
166 }
167
168 static void copyData(ModifierData *md, ModifierData *target)
169 {
170         ClothModifierData *clmd = (ClothModifierData*) md;
171         ClothModifierData *tclmd = (ClothModifierData*) target;
172         
173         if(tclmd->sim_parms)
174                 MEM_freeN(tclmd->sim_parms);
175         if(tclmd->coll_parms)
176                 MEM_freeN(tclmd->coll_parms);
177         
178         BKE_ptcache_free_list(&tclmd->ptcaches);
179         tclmd->point_cache = NULL;
180         
181         tclmd->sim_parms = MEM_dupallocN(clmd->sim_parms);
182         if(clmd->sim_parms->effector_weights)
183                 tclmd->sim_parms->effector_weights = MEM_dupallocN(clmd->sim_parms->effector_weights);
184         tclmd->coll_parms = MEM_dupallocN(clmd->coll_parms);
185         tclmd->point_cache = BKE_ptcache_copy_list(&tclmd->ptcaches, &clmd->ptcaches);
186         tclmd->clothObject = NULL;
187 }
188
189 static int dependsOnTime(ModifierData *md)
190 {
191         return 1;
192 }
193
194 static void freeData(ModifierData *md)
195 {
196         ClothModifierData *clmd = (ClothModifierData*) md;
197         
198         if (clmd) 
199         {
200                 if(G.rt > 0)
201                         printf("clothModifier_freeData\n");
202                 
203                 cloth_free_modifier_extern (clmd);
204                 
205                 if(clmd->sim_parms) {
206                         if(clmd->sim_parms->effector_weights)
207                                 MEM_freeN(clmd->sim_parms->effector_weights);
208                         MEM_freeN(clmd->sim_parms);
209                 }
210                 if(clmd->coll_parms)
211                         MEM_freeN(clmd->coll_parms);    
212                 
213                 BKE_ptcache_free_list(&clmd->ptcaches);
214                 clmd->point_cache = NULL;
215         }
216 }
217
218
219 ModifierTypeInfo modifierType_Cloth = {
220         /* name */              "Cloth",
221         /* structName */        "ClothModifierData",
222         /* structSize */        sizeof(ClothModifierData),
223         /* type */              eModifierTypeType_Nonconstructive,
224         /* flags */             eModifierTypeFlag_AcceptsMesh |
225                                                         eModifierTypeFlag_UsesPointCache |
226                                                         eModifierTypeFlag_Single,
227
228         /* copyData */          copyData,
229         /* deformVerts */       0,
230         /* deformVertsEM */     0,
231         /* deformMatricesEM */  0,
232         /* applyModifier */     applyModifier,
233         /* applyModifierEM */   0,
234         /* initData */          0,
235         /* requiredDataMask */  requiredDataMask,
236         /* freeData */          freeData,
237         /* isDisabled */        0,
238         /* updateDepgraph */    updateDepgraph,
239         /* dependsOnTime */     dependsOnTime,
240         /* foreachObjectLink */ 0,
241         /* foreachIDLink */     0,
242 };