Patch/Bugfix so wind noise got controlable seed and therefore redoable cloth sims...
[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 "RE_render_ext.h"
84
85 /* fluid sim particle import */
86 #ifndef DISABLE_ELBEEM
87 #include "DNA_object_fluidsim.h"
88 #include "LBM_fluidsim.h"
89 #include "elbeem.h"
90 #include <zlib.h>
91 #include <string.h>
92 #endif // DISABLE_ELBEEM
93
94 /* temporal struct, used for reading return of mesh_get_mapped_verts_nors() */
95 typedef struct VeNoCo {
96         float co[3], no[3];
97 } VeNoCo;
98
99 /* ***************** PARTICLES ***************** */
100
101 /* deprecated, only keep this for readfile.c */
102 PartEff *give_parteff(Object *ob)
103 {
104         PartEff *paf;
105         
106         paf= ob->effect.first;
107         while(paf) {
108                 if(paf->type==EFF_PARTICLE) return paf;
109                 paf= paf->next;
110         }
111         return 0;
112 }
113
114 void free_effect(Effect *eff)
115 {
116         PartEff *paf;
117         
118         if(eff->type==EFF_PARTICLE) {
119                 paf= (PartEff *)eff;
120                 if(paf->keys) MEM_freeN(paf->keys);
121         }
122         MEM_freeN(eff); 
123 }
124
125
126 void free_effects(ListBase *lb)
127 {
128         Effect *eff;
129         
130         eff= lb->first;
131         while(eff) {
132                 BLI_remlink(lb, eff);
133                 free_effect(eff);
134                 eff= lb->first;
135         }
136 }
137
138 /* -------------------------- Effectors ------------------ */
139
140 static void add_to_effectorcache(ListBase *lb, Object *ob, Object *obsrc)
141 {
142         pEffectorCache *ec;
143         PartDeflect *pd= ob->pd;
144                         
145         if(pd->forcefield == PFIELD_GUIDE) {
146                 if(ob->type==OB_CURVE && obsrc->type==OB_MESH) {        /* guides only do mesh particles */
147                         Curve *cu= ob->data;
148                         if(cu->flag & CU_PATH) {
149                                 if(cu->path==NULL || cu->path->data==NULL)
150                                         makeDispListCurveTypes(ob, 0);
151                                 if(cu->path && cu->path->data) {
152                                         ec= MEM_callocN(sizeof(pEffectorCache), "effector cache");
153                                         ec->ob= ob;
154                                         BLI_addtail(lb, ec);
155                                 }
156                         }
157                 }
158         }
159         else if(pd->forcefield) {
160                 
161                 if(pd->forcefield == PFIELD_WIND)
162                 {
163                         pd->rng = rng_new(pd->seed);
164                 }
165         
166                 ec= MEM_callocN(sizeof(pEffectorCache), "effector cache");
167                 ec->ob= ob;
168                 BLI_addtail(lb, ec);
169         }
170 }
171
172 /* returns ListBase handle with objects taking part in the effecting */
173 ListBase *pdInitEffectors(Object *obsrc, Group *group)
174 {
175         static ListBase listb={NULL, NULL};
176         pEffectorCache *ec;
177         Base *base;
178         unsigned int layer= obsrc->lay;
179         
180         if(group) {
181                 GroupObject *go;
182                 
183                 for(go= group->gobject.first; go; go= go->next) {
184                         if( (go->ob->lay & layer) && go->ob->pd && go->ob!=obsrc) {
185                                 add_to_effectorcache(&listb, go->ob, obsrc);
186                         }
187                 }
188         }
189         else {
190                 for(base = G.scene->base.first; base; base= base->next) {
191                         if( (base->lay & layer) && base->object->pd && base->object!=obsrc) {
192                                 add_to_effectorcache(&listb, base->object, obsrc);
193                         }
194                 }
195         }
196         
197         /* make a full copy */
198         for(ec= listb.first; ec; ec= ec->next) {
199                 ec->obcopy= *(ec->ob);
200         }
201
202         if(listb.first)
203                 return &listb;
204         
205         return NULL;
206 }
207
208 void pdEndEffectors(ListBase *lb)
209 {
210         if(lb) {
211                 pEffectorCache *ec;
212                 /* restore full copy */
213                 for(ec= lb->first; ec; ec= ec->next)
214                 {
215                         if(ec->ob->pd && (ec->ob->pd->forcefield == PFIELD_WIND))
216                                 rng_free(ec->ob->pd->rng);
217                         
218                         *(ec->ob)= ec->obcopy;
219                 }
220
221                 BLI_freelistN(lb);
222         }
223 }
224
225
226 /************************************************/
227 /*                      Effectors               */
228 /************************************************/
229
230 // triangle - ray callback function
231 static void eff_tri_ray_hit(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
232 {       
233         // whenever we hit a bounding box, we don't check further
234         hit->dist = -1;
235         hit->index = 1;
236 }
237
238 // get visibility of a wind ray
239 static float eff_calc_visibility(Object *ob, float *co, float *dir)
240 {
241         CollisionModifierData **collobjs = NULL;
242         int numcollobj = 0, i;
243         float norm[3], len = 0.0;
244         float visibility = 1.0;
245         
246         collobjs = get_collisionobjects(ob, &numcollobj);
247         
248         if(!collobjs)
249                 return 0;
250         
251         VECCOPY(norm, dir);
252         VecNegf(norm);
253         len = Normalize(norm);
254         
255         // check all collision objects
256         for(i = 0; i < numcollobj; i++)
257         {
258                 CollisionModifierData *collmd = collobjs[i];
259                 
260                 if(collmd->bvhtree)
261                 {
262                         BVHTreeRayHit hit;
263                         
264                         hit.index = -1;
265                         hit.dist = len + FLT_EPSILON;
266                         
267                         // check if the way is blocked
268                         if(BLI_bvhtree_ray_cast(collmd->bvhtree, co, norm, 0.0f, &hit, eff_tri_ray_hit, NULL)>=0)
269                         {
270                                 // visibility is only between 0 and 1, calculated from 1-absorption
271                                 visibility *= MAX2(0.0, MIN2(1.0, (1.0-((float)collmd->absorption)*0.01)));
272                                 
273                                 if(visibility <= 0.0f)
274                                         break;
275                         }
276                 }
277         }
278         
279         MEM_freeN(collobjs);
280         
281         return visibility;
282 }
283
284 // noise function for wind e.g.
285 static float wind_func(struct RNG *rng, float strength)
286 {
287         int random = (rng_getInt(rng)+1) % 128; // max 2357
288         float force = rng_getFloat(rng) + 1.0f;
289         float ret;
290         float sign = 0;
291         
292         sign = ((float)random > 64.0) ? 1.0: -1.0; // dividing by 2 is not giving equal sign distribution
293         
294         ret = sign*((float)random / force)*strength/128.0f;
295         
296         return ret;
297 }
298
299 /* maxdist: zero effect from this distance outwards (if usemax) */
300 /* mindist: full effect up to this distance (if usemin) */
301 /* power: falloff with formula 1/r^power */
302 static float falloff_func(float fac, int usemin, float mindist, int usemax, float maxdist, float power)
303 {
304         /* first quick checks */
305         if(usemax && fac > maxdist)
306                 return 0.0f;
307
308         if(usemin && fac < mindist)
309                 return 1.0f;
310
311         if(!usemin)
312                 mindist = 0.0;
313
314         return pow((double)1.0+fac-mindist, (double)-power);
315 }
316
317 static float falloff_func_dist(PartDeflect *pd, float fac)
318 {
319         return falloff_func(fac, pd->flag&PFIELD_USEMIN, pd->mindist, pd->flag&PFIELD_USEMAX, pd->maxdist, pd->f_power);
320 }
321
322 static float falloff_func_rad(PartDeflect *pd, float fac)
323 {
324         return falloff_func(fac, pd->flag&PFIELD_USEMINR, pd->minrad, pd->flag&PFIELD_USEMAXR, pd->maxrad, pd->f_power_r);
325 }
326
327 float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part)
328 {
329         float eff_dir[3], temp[3];
330         float falloff=1.0, fac, r_fac;
331
332         if(pd->forcefield==PFIELD_LENNARDJ)
333                 return falloff; /* Lennard-Jones field has it's own falloff built in */
334
335         VecCopyf(eff_dir,eff_velocity);
336         Normalize(eff_dir);
337
338         if(pd->flag & PFIELD_POSZ && Inpf(eff_dir,vec_to_part)<0.0f)
339                 falloff=0.0f;
340         else switch(pd->falloff){
341                 case PFIELD_FALL_SPHERE:
342                         fac=VecLength(vec_to_part);
343                         falloff= falloff_func_dist(pd, fac);
344                         break;
345
346                 case PFIELD_FALL_TUBE:
347                         fac=Inpf(vec_to_part,eff_dir);
348                         falloff= falloff_func_dist(pd, ABS(fac));
349                         if(falloff == 0.0f)
350                                 break;
351
352                         VECADDFAC(temp,vec_to_part,eff_dir,-fac);
353                         r_fac=VecLength(temp);
354                         falloff*= falloff_func_rad(pd, r_fac);
355                         break;
356                 case PFIELD_FALL_CONE:
357                         fac=Inpf(vec_to_part,eff_dir);
358                         falloff= falloff_func_dist(pd, ABS(fac));
359                         if(falloff == 0.0f)
360                                 break;
361
362                         r_fac=saacos(fac/VecLength(vec_to_part))*180.0f/(float)M_PI;
363                         falloff*= falloff_func_rad(pd, r_fac);
364
365                         break;
366         }
367
368         return falloff;
369 }
370
371 void do_physical_effector(Object *ob, float *opco, 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, float charge, float pa_size)
372 {
373         float mag_vec[3]={0,0,0};
374         float temp[3], temp2[3];
375         float eff_vel[3];
376         float noise = 0, visibility;
377         
378         // calculate visibility
379         visibility = eff_calc_visibility(ob, opco, vec_to_part);
380         if(visibility <= 0.0)
381                 return;
382         falloff *= visibility;
383
384         VecCopyf(eff_vel,eff_velocity);
385         Normalize(eff_vel);
386
387         switch(type){
388                 case PFIELD_WIND:
389                         VECCOPY(mag_vec,eff_vel);
390                         
391                         // add wind noise here, only if we have wind
392                         if((noise_factor > 0.0f) && (force_val > FLT_EPSILON))
393                                 noise = wind_func(rng, noise_factor);
394                         
395                         VecMulf(mag_vec,(force_val+noise)*falloff);
396                         VecAddf(field,field,mag_vec);
397                         break;
398
399                 case PFIELD_FORCE:
400                         if(planar)
401                                 Projf(mag_vec,vec_to_part,eff_vel);
402                         else
403                                 VecCopyf(mag_vec,vec_to_part);
404
405                         Normalize(mag_vec);
406
407                         VecMulf(mag_vec,force_val*falloff);
408                         VecAddf(field,field,mag_vec);
409                         break;
410
411                 case PFIELD_VORTEX:
412                         Crossf(mag_vec,eff_vel,vec_to_part);
413
414                         Normalize(mag_vec);
415
416                         VecMulf(mag_vec,force_val*distance*falloff);
417                         VecAddf(field,field,mag_vec);
418
419                         break;
420                 case PFIELD_MAGNET:
421                         if(planar)
422                                 VecCopyf(temp,eff_vel);
423                         else
424                                 /* magnetic field of a moving charge */
425                                 Crossf(temp,eff_vel,vec_to_part);
426
427                         Normalize(temp);
428
429                         Crossf(temp2,velocity,temp);
430                         VecAddf(mag_vec,mag_vec,temp2);
431
432                         VecMulf(mag_vec,force_val*falloff);
433                         VecAddf(field,field,mag_vec);
434                         break;
435                 case PFIELD_HARMONIC:
436                         if(planar)
437                                 Projf(mag_vec,vec_to_part,eff_vel);
438                         else
439                                 VecCopyf(mag_vec,vec_to_part);
440
441                         VecMulf(mag_vec,force_val*falloff);
442                         VecSubf(field,field,mag_vec);
443
444                         VecCopyf(mag_vec,velocity);
445                         VecMulf(mag_vec,damp*2.0f*(float)sqrt(force_val));
446                         VecSubf(field,field,mag_vec);
447                         break;
448                 case PFIELD_CHARGE:
449                         if(planar)
450                                 Projf(mag_vec,vec_to_part,eff_vel);
451                         else
452                                 VecCopyf(mag_vec,vec_to_part);
453
454                         Normalize(mag_vec);
455
456                         VecMulf(mag_vec,charge*force_val*falloff);
457                         VecAddf(field,field,mag_vec);
458                         break;
459                 case PFIELD_LENNARDJ:
460                 {
461                         float fac;
462
463                         if(planar) {
464                                 Projf(mag_vec,vec_to_part,eff_vel);
465                                 distance = VecLength(mag_vec);
466                         }
467                         else
468                                 VecCopyf(mag_vec,vec_to_part);
469
470                         /* at this distance the field is 60 times weaker than maximum */
471                         if(distance > 2.22 * (size+pa_size))
472                                 break;
473
474                         fac = pow((size+pa_size)/distance,6.0);
475                         
476                         fac = - fac * (1.0 - fac) / distance;
477
478                         /* limit the repulsive term drastically to avoid huge forces */
479                         fac = ((fac>2.0) ? 2.0 : fac);
480
481                         /* 0.003715 is the fac value at 2.22 times (size+pa_size),
482                            substracted to avoid discontinuity at the border
483                         */
484                         VecMulf(mag_vec, force_val * (fac-0.0037315));
485                         VecAddf(field,field,mag_vec);
486                         break;
487                 }
488         }
489 }
490
491 /*  -------- pdDoEffectors() --------
492     generic force/speed system, now used for particles and softbodies
493         lb                      = listbase with objects that take part in effecting
494         opco            = global coord, as input
495     force               = force accumulator
496     speed               = actual current speed which can be altered
497         cur_time        = "external" time in frames, is constant for static particles
498         loc_time        = "local" time in frames, range <0-1> for the lifetime of particle
499     par_layer   = layer the caller is in
500         flags           = only used for softbody wind now
501         guide           = old speed of particle
502
503 */
504 void pdDoEffectors(ListBase *lb, float *opco, float *force, float *speed, float cur_time, float loc_time, unsigned int flags)
505 {
506 /*
507         Modifies the force on a particle according to its
508         relation with the effector object
509         Different kind of effectors include:
510                 Forcefields: Gravity-like attractor
511                 (force power is related to the inverse of distance to the power of a falloff value)
512                 Vortex fields: swirling effectors
513                 (particles rotate around Z-axis of the object. otherwise, same relation as)
514                 (Forcefields, but this is not done through a force/acceleration)
515                 Guide: particles on a path
516                 (particles are guided along a curve bezier or old nurbs)
517                 (is independent of other effectors)
518 */
519         Object *ob;
520         pEffectorCache *ec;
521         PartDeflect *pd;
522         
523         float distance, vec_to_part[3];
524         float falloff;
525
526         /* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
527         /* Check for min distance here? (yes would be cool to add that, ton) */
528         
529         for(ec = lb->first; ec; ec= ec->next) {
530                 /* object effectors were fully checked to be OK to evaluate! */
531                 ob= ec->ob;
532                 pd= ob->pd;
533                         
534                 /* Get IPO force strength and fall off values here */
535                 where_is_object_time(ob,cur_time);
536                         
537                 /* use center of object for distance calculus */
538                 VecSubf(vec_to_part, opco, ob->obmat[3]);
539                 distance = VecLength(vec_to_part);
540
541                 falloff=effector_falloff(pd,ob->obmat[2],vec_to_part);          
542                 
543                 if(falloff<=0.0f)
544                         ;       /* don't do anything */
545                 else {
546                         float field[3]={0,0,0}, tmp[3];
547                         VECCOPY(field, force);
548                         do_physical_effector(ob, opco, pd->forcefield,pd->f_strength,distance,
549                                                                 falloff,pd->f_dist,pd->f_damp,ob->obmat[2],vec_to_part,
550                                                                 speed,force,pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise, 0.0f, 0.0f);
551                         
552                         // for softbody backward compatibility
553                         if(flags & PE_WIND_AS_SPEED){
554                                 VECSUB(tmp, force, field);
555                                 VECSUB(speed, speed, tmp);
556                         }
557                 }
558         }
559 }