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