Little tweaks so 0 wind results in 0 noise, also removed double-mass dependancy in...
[blender.git] / source / blender / blenkernel / intern / effect.c
1 /*  effect.c
2  * 
3  * 
4  * $Id$
5  *
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
23  * All rights reserved.
24  *
25  * The Original Code is: all of this file.
26  *
27  * Contributor(s): none yet.
28  *
29  * ***** END GPL LICENSE BLOCK *****
30  */
31
32 #include <math.h>
33 #include <stdlib.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_curve_types.h"
38 #include "DNA_effect_types.h"
39 #include "DNA_group_types.h"
40 #include "DNA_ipo_types.h"
41 #include "DNA_key_types.h"
42 #include "DNA_lattice_types.h"
43 #include "DNA_listBase.h"
44 #include "DNA_mesh_types.h"
45 #include "DNA_meshdata_types.h"
46 #include "DNA_material_types.h"
47 #include "DNA_object_types.h"
48 #include "DNA_object_force.h"
49 #include "DNA_texture_types.h"
50 #include "DNA_scene_types.h"
51
52 #include "BLI_arithb.h"
53 #include "BLI_blenlib.h"
54 #include "BLI_jitter.h"
55 #include "BLI_rand.h"
56
57 #include "BKE_action.h"
58 #include "BKE_anim.h"           /* needed for where_on_path */
59 #include "BKE_armature.h"
60 #include "BKE_bad_level_calls.h"
61 #include "BKE_blender.h"
62 #include "BKE_collision.h"
63 #include "BKE_constraint.h"
64 #include "BKE_deform.h"
65 #include "BKE_depsgraph.h"
66 #include "BKE_displist.h"
67 #include "BKE_DerivedMesh.h"
68 #include "BKE_effect.h"
69 #include "BKE_global.h"
70 #include "BKE_group.h"
71 #include "BKE_ipo.h"
72 #include "BKE_key.h"
73 #include "BKE_lattice.h"
74 #include "BKE_mesh.h"
75 #include "BKE_material.h"
76 #include "BKE_main.h"
77 #include "BKE_modifier.h"
78 #include "BKE_object.h"
79 #include "BKE_scene.h"
80 #include "BKE_screen.h"
81 #include "BKE_utildefines.h"
82
83 #include "PIL_time.h"
84 #include "RE_render_ext.h"
85
86 /* fluid sim particle import */
87 #ifndef DISABLE_ELBEEM
88 #include "DNA_object_fluidsim.h"
89 #include "LBM_fluidsim.h"
90 #include "elbeem.h"
91 #include <zlib.h>
92 #include <string.h>
93 #endif // DISABLE_ELBEEM
94
95 /* temporal struct, used for reading return of mesh_get_mapped_verts_nors() */
96 typedef struct VeNoCo {
97         float co[3], no[3];
98 } VeNoCo;
99
100 /* ***************** PARTICLES ***************** */
101
102 /* deprecated, only keep this for readfile.c */
103 PartEff *give_parteff(Object *ob)
104 {
105         PartEff *paf;
106         
107         paf= ob->effect.first;
108         while(paf) {
109                 if(paf->type==EFF_PARTICLE) return paf;
110                 paf= paf->next;
111         }
112         return 0;
113 }
114
115 void free_effect(Effect *eff)
116 {
117         PartEff *paf;
118         
119         if(eff->type==EFF_PARTICLE) {
120                 paf= (PartEff *)eff;
121                 if(paf->keys) MEM_freeN(paf->keys);
122         }
123         MEM_freeN(eff); 
124 }
125
126
127 void free_effects(ListBase *lb)
128 {
129         Effect *eff;
130         
131         eff= lb->first;
132         while(eff) {
133                 BLI_remlink(lb, eff);
134                 free_effect(eff);
135                 eff= lb->first;
136         }
137 }
138
139 /* -------------------------- Effectors ------------------ */
140
141 static void add_to_effectorcache(ListBase *lb, Object *ob, Object *obsrc)
142 {
143         pEffectorCache *ec;
144         PartDeflect *pd= ob->pd;
145                         
146         if(pd->forcefield == PFIELD_GUIDE) {
147                 if(ob->type==OB_CURVE && obsrc->type==OB_MESH) {        /* guides only do mesh particles */
148                         Curve *cu= ob->data;
149                         if(cu->flag & CU_PATH) {
150                                 if(cu->path==NULL || cu->path->data==NULL)
151                                         makeDispListCurveTypes(ob, 0);
152                                 if(cu->path && cu->path->data) {
153                                         ec= MEM_callocN(sizeof(pEffectorCache), "effector cache");
154                                         ec->ob= ob;
155                                         BLI_addtail(lb, ec);
156                                 }
157                         }
158                 }
159         }
160         else if(pd->forcefield) {
161                 
162                 if(pd->forcefield == PFIELD_WIND)
163                 {
164                         pd->rng = rng_new(1);
165                         rng_srandom(pd->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); // use better seed
166                 }
167         
168                 ec= MEM_callocN(sizeof(pEffectorCache), "effector cache");
169                 ec->ob= ob;
170                 BLI_addtail(lb, ec);
171         }
172 }
173
174 /* returns ListBase handle with objects taking part in the effecting */
175 ListBase *pdInitEffectors(Object *obsrc, Group *group)
176 {
177         static ListBase listb={NULL, NULL};
178         pEffectorCache *ec;
179         Base *base;
180         unsigned int layer= obsrc->lay;
181         
182         if(group) {
183                 GroupObject *go;
184                 
185                 for(go= group->gobject.first; go; go= go->next) {
186                         if( (go->ob->lay & layer) && go->ob->pd && go->ob!=obsrc) {
187                                 add_to_effectorcache(&listb, go->ob, obsrc);
188                         }
189                 }
190         }
191         else {
192                 for(base = G.scene->base.first; base; base= base->next) {
193                         if( (base->lay & layer) && base->object->pd && base->object!=obsrc) {
194                                 add_to_effectorcache(&listb, base->object, obsrc);
195                         }
196                 }
197         }
198         
199         /* make a full copy */
200         for(ec= listb.first; ec; ec= ec->next) {
201                 ec->obcopy= *(ec->ob);
202         }
203
204         if(listb.first)
205                 return &listb;
206         
207         return NULL;
208 }
209
210 void pdEndEffectors(ListBase *lb)
211 {
212         if(lb) {
213                 pEffectorCache *ec;
214                 /* restore full copy */
215                 for(ec= lb->first; ec; ec= ec->next)
216                 {
217                         if(ec->ob->pd && (ec->ob->pd->forcefield == PFIELD_WIND))
218                                 rng_free(ec->ob->pd->rng);
219                         
220                         *(ec->ob)= ec->obcopy;
221                 }
222
223                 BLI_freelistN(lb);
224         }
225 }
226
227
228 /************************************************/
229 /*                      Effectors               */
230 /************************************************/
231
232 // noise function for wind e.g.
233 static float wind_func(struct RNG *rng, float strength)
234 {
235         int random = (rng_getInt(rng)+1) % 65535; // max 2357
236         float force = rng_getFloat(rng) + 1.0f;
237         float ret;
238         float sign = 0;
239         
240         sign = (random > 32000.0) ? 1.0: -1.0; // dividing by 2 is not giving equal sign distribution
241         
242         ret = sign*((float)random / force)*strength/65535.0f;
243         
244         return ret;
245 }
246
247
248 static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power)
249 {
250         if(!usemin)
251                 mindist= 0.0f;
252
253         if(fac < mindist) {
254                 return 1.0f;
255         }
256         else if(usemax) {
257                 if(fac>maxdist || (maxdist-mindist)<=0.0f)
258                         return 0.0f;
259
260                 fac= (fac-mindist)/(maxdist-mindist);
261                 return 1.0f - (float)pow((double)fac, (double)power);
262         }
263         else
264                 return pow((double)1.0f+fac-mindist, (double)-power);
265 }
266
267 static float falloff_func_dist(PartDeflect *pd, float fac)
268 {
269         return falloff_func(fac, pd->flag&PFIELD_USEMIN, pd->mindist, pd->flag&PFIELD_USEMAX, pd->maxdist, pd->f_power);
270 }
271
272 static float falloff_func_rad(PartDeflect *pd, float fac)
273 {
274         return falloff_func(fac, pd->flag&PFIELD_USEMINR, pd->minrad, pd->flag&PFIELD_USEMAXR, pd->maxrad, pd->f_power_r);
275 }
276
277 float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
278 {
279         float eff_dir[3], temp[3];
280         float falloff=1.0, fac, r_fac;
281         
282         VecCopyf(eff_dir,eff_velocity);
283         Normalize(eff_dir);
284
285         if(pd->flag & PFIELD_POSZ && Inpf(eff_dir,vec_to_part)<0.0f)
286                 falloff=0.0f;
287         else switch(pd->falloff){
288                 case PFIELD_FALL_SPHERE:
289                         fac=VecLength(vec_to_part);
290                         falloff= falloff_func_dist(pd, fac);
291                         break;
292
293                 case PFIELD_FALL_TUBE:
294                         fac=Inpf(vec_to_part,eff_dir);
295                         falloff= falloff_func_dist(pd, ABS(fac));
296                         if(falloff == 0.0f)
297                                 break;
298
299                         VECADDFAC(temp,vec_to_part,eff_dir,-fac);
300                         r_fac=VecLength(temp);
301                         falloff*= falloff_func_rad(pd, r_fac);
302                         break;
303                 case PFIELD_FALL_CONE:
304                         fac=Inpf(vec_to_part,eff_dir);
305                         falloff= falloff_func_dist(pd, ABS(fac));
306                         if(falloff == 0.0f)
307                                 break;
308
309                         r_fac=saacos(fac/VecLength(vec_to_part))*180.0f/(float)M_PI;
310                         falloff*= falloff_func_rad(pd, r_fac);
311
312                         break;
313         }
314
315         return falloff;
316 }
317
318 void do_physical_effector(short type, float force_val, float distance, float falloff, float size, float damp, float *eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, struct RNG *rng, float noise_factor)
319 {
320         float mag_vec[3]={0,0,0};
321         float temp[3], temp2[3];
322         float eff_vel[3];
323         float noise = 0;
324
325         VecCopyf(eff_vel,eff_velocity);
326         Normalize(eff_vel);
327
328         switch(type){
329                 case PFIELD_WIND:
330                         VECCOPY(mag_vec,eff_vel);
331                         
332                         // add wind noise here, only if we have wind
333                         if((noise_factor> 0.0f) && (force_val > FLT_EPSILON))
334                                 noise = wind_func(rng, noise_factor);
335                         
336                         VecMulf(mag_vec,(force_val+noise)*falloff);
337                         VecAddf(field,field,mag_vec);
338                         break;
339
340                 case PFIELD_FORCE:
341                         if(planar)
342                                 Projf(mag_vec,vec_to_part,eff_vel);
343                         else
344                                 VecCopyf(mag_vec,vec_to_part);
345
346                         VecMulf(mag_vec,force_val*falloff);
347                         VecAddf(field,field,mag_vec);
348                         break;
349
350                 case PFIELD_VORTEX:
351                         Crossf(mag_vec,eff_vel,vec_to_part);
352                         Normalize(mag_vec);
353
354                         VecMulf(mag_vec,force_val*distance*falloff);
355                         VecAddf(field,field,mag_vec);
356
357                         break;
358                 case PFIELD_MAGNET:
359                         if(planar)
360                                 VecCopyf(temp,eff_vel);
361                         else
362                                 /* magnetic field of a moving charge */
363                                 Crossf(temp,eff_vel,vec_to_part);
364
365                         Crossf(temp2,velocity,temp);
366                         VecAddf(mag_vec,mag_vec,temp2);
367
368                         VecMulf(mag_vec,force_val*falloff);
369                         VecAddf(field,field,mag_vec);
370                         break;
371                 case PFIELD_HARMONIC:
372                         if(planar)
373                                 Projf(mag_vec,vec_to_part,eff_vel);
374                         else
375                                 VecCopyf(mag_vec,vec_to_part);
376
377                         VecMulf(mag_vec,force_val*falloff);
378                         VecSubf(field,field,mag_vec);
379
380                         VecCopyf(mag_vec,velocity);
381                         /* 1.9 is an experimental value to get critical damping at damp=1.0 */
382                         VecMulf(mag_vec,damp*1.9f*(float)sqrt(force_val));
383                         VecSubf(field,field,mag_vec);
384                         break;
385                 case PFIELD_NUCLEAR:
386                         /*pow here is root of cosine expression below*/
387                         //rad=(float)pow(2.0,-1.0/power)*distance/size;
388                         //VECCOPY(mag_vec,vec_to_part);
389                         //Normalize(mag_vec);
390                         //VecMulf(mag_vec,(float)cos(3.0*M_PI/2.0*(1.0-1.0/(pow(rad,power)+1.0)))/(rad+0.2f));
391                         //VECADDFAC(field,field,mag_vec,force_val);
392                         break;
393         }
394 }
395
396
397 static void eff_tri_ray_hit(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
398 {       
399         hit->dist = -1;
400         hit->index = 1;
401 }
402
403 float eff_calc_visibility(Object *ob, float *co, float *dir, float cur_time)
404 {
405         CollisionModifierData **collobjs = NULL;
406         int numcollobj = 0, i;
407         float norm[3], len = 0.0;
408         float visibility = 1.0;
409         
410         collobjs = get_collisionobjects(ob, &numcollobj);
411         
412         if(!collobjs)
413                 return 0;
414         
415         VECCOPY(norm, dir);
416         VecMulf(norm, -1.0);
417         len = Normalize(norm);
418         
419         // check all collision objects
420         for(i = 0; i < numcollobj; i++)
421         {
422                 CollisionModifierData *collmd = collobjs[i];
423                 
424                 if(collmd->bvhtree)
425                 {
426                         BVHTreeRayHit hit;
427                         
428                         hit.index = -1;
429                         hit.dist = len + FLT_EPSILON;
430                         
431                         
432                         // check if the way is blocked
433                         if(BLI_bvhtree_ray_cast(collmd->bvhtree, co, norm, &hit, eff_tri_ray_hit, NULL)>=0)
434                         {
435                                 visibility *= MAX2(0.0, MIN2(1.0, (1.0-((float)collmd->absorbation)*0.01)));
436                         }
437                 }
438         }
439         
440         MEM_freeN(collobjs);
441         
442         return visibility;
443 }
444
445
446 /*  -------- pdDoEffectors() --------
447     generic force/speed system, now used for particles and softbodies
448         lb                      = listbase with objects that take part in effecting
449         opco            = global coord, as input
450     force               = force accumulator
451     speed               = actual current speed which can be altered
452         cur_time        = "external" time in frames, is constant for static particles
453         loc_time        = "local" time in frames, range <0-1> for the lifetime of particle
454     par_layer   = layer the caller is in
455         flags           = only used for softbody wind now
456         guide           = old speed of particle
457
458 */
459 void pdDoEffectors(ListBase *lb, float *opco, float *force, float *speed, float cur_time, float loc_time, unsigned int flags)
460 {
461 /*
462         Modifies the force on a particle according to its
463         relation with the effector object
464         Different kind of effectors include:
465                 Forcefields: Gravity-like attractor
466                 (force power is related to the inverse of distance to the power of a falloff value)
467                 Vortex fields: swirling effectors
468                 (particles rotate around Z-axis of the object. otherwise, same relation as)
469                 (Forcefields, but this is not done through a force/acceleration)
470                 Guide: particles on a path
471                 (particles are guided along a curve bezier or old nurbs)
472                 (is independent of other effectors)
473 */
474         Object *ob;
475         pEffectorCache *ec;
476         PartDeflect *pd;
477         float vect_to_vert[3];
478         float *obloc;
479         
480         float distance, vec_to_part[3];
481         float falloff, visibility;
482
483         /* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
484         /* Check for min distance here? (yes would be cool to add that, ton) */
485         
486         for(ec = lb->first; ec; ec= ec->next) {
487                 /* object effectors were fully checked to be OK to evaluate! */
488                 ob= ec->ob;
489                 pd= ob->pd;
490                         
491                 /* Get IPO force strength and fall off values here */
492                 where_is_object_time(ob,cur_time);
493                         
494                 /* use center of object for distance calculus */
495                 obloc= ob->obmat[3];
496                 VECSUB(vect_to_vert, obloc, opco);
497                 distance = VecLength(vect_to_vert);
498                 
499                 VecSubf(vec_to_part, opco, ob->obmat[3]);
500                 distance = VecLength(vec_to_part);
501
502                 falloff=effector_falloff(pd,ob->obmat[2],vec_to_part);
503                 
504                 if(falloff<=0.0f)
505                         continue;
506                 
507                 visibility = eff_calc_visibility(ob, opco, vec_to_part, cur_time);
508                 
509                 if((visibility*falloff)<=0.0f)
510                         ;       /* don't do anything */
511                 else {
512                         float field[3]={0,0,0}, tmp[3];
513                         VECCOPY(field, force);
514                         do_physical_effector(pd->forcefield,pd->f_strength,distance,
515                                                                 visibility*falloff,pd->f_dist,pd->f_damp,ob->obmat[2],vec_to_part,
516                                                                 speed,force,pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise);
517                         
518                         // for softbody backward compatibility
519                         if(flags & PE_WIND_AS_SPEED){
520                                 VECSUB(tmp, force, field);
521                                 VECSUB(speed, speed, tmp);
522                         }
523                 }
524         }
525 }