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