Made static particles working with a deformed Mesh, both for Lattice as
[blender.git] / source / blender / blenkernel / intern / effect.c
1 /*  effect.c
2  * 
3  * 
4  * $Id$
5  *
6  * ***** BEGIN GPL/BL DUAL 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. The Blender
12  * Foundation also sells licenses for use in proprietary software under
13  * the Blender License.  See http://www.blender.org/BL/ for information
14  * about this.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL/BL DUAL LICENSE BLOCK *****
33  */
34
35 #include <math.h>
36 #include <stdlib.h>
37
38 #include "MEM_guardedalloc.h"
39 #include "DNA_listBase.h"
40 #include "DNA_effect_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_material_types.h"
45 #include "DNA_curve_types.h"
46 #include "DNA_key_types.h"
47 #include "DNA_texture_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_lattice_types.h"
50 #include "DNA_ipo_types.h"
51
52 #include "BLI_blenlib.h"
53 #include "BLI_arithb.h"
54 #include "BLI_rand.h"
55
56 #include "BKE_utildefines.h"
57 #include "BKE_bad_level_calls.h"
58 #include "BKE_global.h"
59 #include "BKE_material.h"
60 #include "BKE_effect.h"
61 #include "BKE_key.h"
62 #include "BKE_ipo.h"
63 #include "BKE_screen.h"
64 #include "BKE_main.h"
65 #include "BKE_blender.h"
66 #include "BKE_object.h"
67 #include "BKE_displist.h"
68 #include "BKE_lattice.h"
69 #include "BKE_mesh.h"
70 #include "BKE_action.h"
71 #include "BKE_constraint.h"
72
73 #ifdef HAVE_CONFIG_H
74 #include <config.h>
75 #endif
76
77 Effect *add_effect(int type)
78 {
79         Effect *eff=0;
80         BuildEff *bld;
81         PartEff *paf;
82         WaveEff *wav;
83         int a;
84         
85         switch(type) {
86         case EFF_BUILD:
87                 bld= MEM_callocN(sizeof(BuildEff), "neweff");
88                 eff= (Effect *)bld;
89                 
90                 bld->sfra= 1.0;
91                 bld->len= 100.0;
92                 break;
93                 
94         case EFF_PARTICLE:
95                 paf= MEM_callocN(sizeof(PartEff), "neweff");
96                 eff= (Effect *)paf;
97                 
98                 paf->sta= 1.0;
99                 paf->end= 100.0;
100                 paf->lifetime= 50.0;
101                 for(a=0; a<PAF_MAXMULT; a++) {
102                         paf->life[a]= 50.0;
103                         paf->child[a]= 4;
104                         paf->mat[a]= 1;
105                 }
106                 
107                 paf->totpart= 1000;
108                 paf->totkey= 8;
109                 paf->staticstep= 5;
110                 paf->defvec[2]= 1.0f;
111                 paf->nabla= 0.05f;
112                 
113                 break;
114                 
115         case EFF_WAVE:
116                 wav= MEM_callocN(sizeof(WaveEff), "neweff");
117                 eff= (Effect *)wav;
118                 
119                 wav->flag |= (WAV_X+WAV_Y+WAV_CYCL);
120                 
121                 wav->height= 0.5f;
122                 wav->width= 1.5f;
123                 wav->speed= 0.5f;
124                 wav->narrow= 1.5f;
125                 wav->lifetime= 0.0f;
126                 wav->damp= 10.0f;
127                 
128                 break;
129         }
130         
131         eff->type= eff->buttype= type;
132         eff->flag |= SELECT;
133         
134         return eff;
135 }
136
137 void free_effect(Effect *eff)
138 {
139         PartEff *paf;
140         
141         if(eff->type==EFF_PARTICLE) {
142                 paf= (PartEff *)eff;
143                 if(paf->keys) MEM_freeN(paf->keys);
144         }
145         MEM_freeN(eff); 
146 }
147
148
149 void free_effects(ListBase *lb)
150 {
151         Effect *eff;
152         
153         eff= lb->first;
154         while(eff) {
155                 BLI_remlink(lb, eff);
156                 free_effect(eff);
157                 eff= lb->first;
158         }
159 }
160
161 Effect *copy_effect(Effect *eff) 
162 {
163         Effect *effn;
164         
165         effn= MEM_dupallocN(eff);
166         if(effn->type==EFF_PARTICLE) ((PartEff *)effn)->keys= 0;
167
168         return effn;    
169 }
170
171 void copy_act_effect(Object *ob)
172 {
173         /* return a copy of the active effect */
174         Effect *effn, *eff;
175         
176         eff= ob->effect.first;
177         while(eff) {
178                 if(eff->flag & SELECT) {
179                         
180                         effn= copy_effect(eff);
181                         BLI_addtail(&ob->effect, effn);
182                         
183                         eff->flag &= ~SELECT;
184                         return;
185                         
186                 }
187                 eff= eff->next;
188         }
189         
190         /* when it comes here: add new effect */
191         eff= add_effect(EFF_BUILD);
192         BLI_addtail(&ob->effect, eff);
193                         
194 }
195
196 void copy_effects(ListBase *lbn, ListBase *lb)
197 {
198         Effect *eff, *effn;
199
200         lbn->first= lbn->last= 0;
201
202         eff= lb->first;
203         while(eff) {
204                 effn= copy_effect(eff);
205                 BLI_addtail(lbn, effn);
206                 
207                 eff= eff->next;
208         }
209         
210 }
211
212 void deselectall_eff(Object *ob)
213 {
214         Effect *eff= ob->effect.first;
215         
216         while(eff) {
217                 eff->flag &= ~SELECT;
218                 eff= eff->next;
219         }
220 }
221
222 void set_buildvars(Object *ob, int *start, int *end)
223 {
224         BuildEff *bld;
225         float ctime;
226         
227         bld= ob->effect.first;
228         while(bld) {
229                 if(bld->type==EFF_BUILD) {
230                         ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, bld->sfra-1.0f);
231                         if(ctime < 0.0) {
232                                 *end= *start;
233                         }
234                         else if(ctime < bld->len) {
235                                 *end= *start+ (int)((*end - *start)*ctime/bld->len);
236                         }
237                         
238                         return;
239                 }
240                 bld= bld->next;
241         }
242 }
243
244 /* ***************** PARTICLES ***************** */
245
246 Particle *new_particle(PartEff *paf)
247 {
248         static Particle *pa;
249         static int cur;
250
251         /* we agree: when paf->keys==0: alloc */        
252         if(paf->keys==0) {
253                 pa= paf->keys= MEM_callocN( paf->totkey*paf->totpart*sizeof(Particle), "particlekeys" );
254                 cur= 0;
255         }
256         else {
257                 if(cur && cur<paf->totpart) pa+=paf->totkey;
258                 cur++;
259         }
260         return pa;
261 }
262
263 PartEff *give_parteff(Object *ob)
264 {
265         PartEff *paf;
266         
267         paf= ob->effect.first;
268         while(paf) {
269                 if(paf->type==EFF_PARTICLE) return paf;
270                 paf= paf->next;
271         }
272         return 0;
273 }
274
275 void where_is_particle(PartEff *paf, Particle *pa, float ctime, float *vec)
276 {
277         Particle *p[4];
278         float dt, t[4];
279         int a;
280         
281         if(paf->totkey==1) {
282                 VECCOPY(vec, pa->co);
283                 return;
284         }
285         
286         /* first find the first particlekey */
287         a= (int)((paf->totkey-1)*(ctime-pa->time)/pa->lifetime);
288         if(a>=paf->totkey) a= paf->totkey-1;
289         
290         pa+= a;
291         
292         if(a>0) p[0]= pa-1; else p[0]= pa;
293         p[1]= pa;
294         
295         if(a+1<paf->totkey) p[2]= pa+1; else p[2]= pa;
296         if(a+2<paf->totkey) p[3]= pa+2; else p[3]= p[2];
297         
298         if(p[1]==p[2]) dt= 0.0;
299         else dt= (ctime-p[1]->time)/(p[2]->time - p[1]->time);
300
301         if(paf->flag & PAF_BSPLINE) set_four_ipo(dt, t, KEY_BSPLINE);
302         else set_four_ipo(dt, t, KEY_CARDINAL);
303
304         vec[0]= t[0]*p[0]->co[0] + t[1]*p[1]->co[0] + t[2]*p[2]->co[0] + t[3]*p[3]->co[0];
305         vec[1]= t[0]*p[0]->co[1] + t[1]*p[1]->co[1] + t[2]*p[2]->co[1] + t[3]*p[3]->co[1];
306         vec[2]= t[0]*p[0]->co[2] + t[1]*p[1]->co[2] + t[2]*p[2]->co[2] + t[3]*p[3]->co[2];
307
308 }
309
310 void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no)
311 {                               
312         extern float Tin, Tr, Tg, Tb;
313         extern void externtex(struct MTex *mtex, float *vec);
314         float old;
315         
316         externtex(mtex, co);
317         
318         if(paf->texmap==PAF_TEXINT) {
319                 Tin*= paf->texfac;
320                 no[0]+= Tin*paf->defvec[0];
321                 no[1]+= Tin*paf->defvec[1];
322                 no[2]+= Tin*paf->defvec[2];
323         }
324         else if(paf->texmap==PAF_TEXRGB) {
325                 no[0]+= (Tr-0.5f)*paf->texfac;
326                 no[1]+= (Tg-0.5f)*paf->texfac;
327                 no[2]+= (Tb-0.5f)*paf->texfac;
328         }
329         else {  /* PAF_TEXGRAD */
330                 
331                 old= Tin;
332                 co[0]+= paf->nabla;
333                 externtex(mtex, co);
334                 no[0]+= (old-Tin)*paf->texfac;
335                 
336                 co[0]-= paf->nabla;
337                 co[1]+= paf->nabla;
338                 externtex(mtex, co);
339                 no[1]+= (old-Tin)*paf->texfac;
340                 
341                 co[1]-= paf->nabla;
342                 co[2]+= paf->nabla;
343                 externtex(mtex, co);
344                 no[2]+= (old-Tin)*paf->texfac;
345                 
346         }
347 }
348
349 static float linetriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3])
350 {
351         float p[3], s[3], d[3], e1[3], e2[3], q[3];
352         float a, f, u, v, t;
353
354         VecSubf(e1, v1, v0);
355         VecSubf(e2, v2, v0);
356         VecSubf(d, p2, p1);
357     Crossf(p, d, e2);
358     a = Inpf(e1, p);
359     if ((a > -0.000001) && (a < 0.000001)) return -1;
360     f = 1/a;
361     VecSubf(s, p1, v0);
362     u = f * Inpf(s, p);
363     if ((u < 0.0)||(u > 1.0)) return -1;
364     Crossf(q, s, e1);
365     t = f * Inpf(e2, q);
366     if ((t < 0.0)||(t > 1.0)) return -1;
367     v = f * Inpf(d, q);
368     if ((v < 0.0)||((u + v) > 1.0)) return -1;
369     return t;
370 }
371
372 static void get_forcefield(float opco[], float force[], float cur_time, unsigned int par_layer)
373 {
374         /* Particle gravity code */
375         /* Modifies the force on a particle according to its  */
376         /* distance from mesh vertices set to attract / repel */
377         Object *ob;
378         Base *base;
379         float vect_to_vert[3];
380         float f_force, distance;
381         float obloc[3];
382         float force_val, ffall_val;
383         short cur_frame;
384
385         /* Cycle through objects, get total of (1/(gravity_strength * dist^gravity_power)) */
386         /* Check for min distance here? */
387         base = G.scene->base.first;
388         while (base) {
389                 if(base->lay & par_layer) {
390                         ob= base->object;
391                         if(ob->pd && ob->pd->forcefield) {
392
393                                 /* Need to set r.cfra for paths (investigate, ton) */
394                                 cur_frame = G.scene->r.cfra;
395                                 G.scene->r.cfra = (short)cur_time;
396                                 where_is_object_time(ob, cur_time);
397                                 G.scene->r.cfra = cur_frame;
398                                 
399                                 /* only use center of object */
400                                 obloc[0] = ob->obmat[3][0];
401                                 obloc[1] = ob->obmat[3][1];
402                                 obloc[2] = ob->obmat[3][2];
403                                 
404                                 /* Get IPO force strength and fall off values here */
405                                 if (has_ipo_code(ob->ipo, OB_PD_FSTR))
406                                         force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, cur_time);
407                                 else 
408                                         force_val = ob->pd->f_strength;
409
410                                 if (has_ipo_code(ob->ipo, OB_PD_FFALL)) 
411                                         ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, cur_time);
412                                 else 
413                                         ffall_val = ob->pd->f_power;
414
415                                 /* Now calculate the gravitational force */
416                                 VecSubf(vect_to_vert, obloc, opco);
417                                 distance = Normalise(vect_to_vert);
418
419                                 /* Limit minimum distance to vertex so that */
420                                 /* the force is not too big */
421                                 if (distance < 0.001) distance = 0.001;
422                                 f_force = (force_val)*(1/(1000 * pow((double)distance, (double)ffall_val)));
423                                 force[0] += (vect_to_vert[0] * f_force );
424                                 force[1] += (vect_to_vert[1] * f_force );
425                                 force[2] += (vect_to_vert[2] * f_force );
426
427                         }
428                 }
429                 base = base->next;
430         }
431 }
432
433 static int get_deflection(float opco[3], float npco[3], float opno[3],
434         float npno[3], float life, float force[3], int def_depth,
435         float cur_time, unsigned int par_layer, int *last_object,
436                 int *last_face, int *same_face)
437 {
438         /* Particle deflection code */
439         /* The code is in two sections: the first part checks whether a particle has            */
440         /* intersected a face of a deflector mesh, given its old and new co-ords, opco and npco */
441         /* and which face it hit first                                                          */
442         /* The second part calculates the new co-ordinates given that collision and updates     */
443         /* the new co-ordinates accordingly */
444         Base *base;
445         Object *ob, *deflection_object = NULL;
446         Mesh *def_mesh;
447         MFace *mface, *deflection_face = NULL;
448         float *v1, *v2, *v3, *v4;
449         float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3];
450         float dv1[3], dv2[3], dv3[3];
451         float vect_to_int[3], refl_vel[3];
452         float d_intersect_co[3], d_intersect_vect[3], d_nvect[3], d_i_co_above[3];
453         float forcec[3];
454         float k_point3, dist_to_plane;
455         float first_dist, ref_plane_mag;
456         float dk_plane=0, dk_point1=0;
457         float icalctop, icalcbot, n_mag;
458         float mag_iv, x_m,y_m,z_m;
459         float damping, perm_thresh;
460         float perm_val, rdamp_val;
461         int a, deflected=0, deflected_now=0;
462         float t, min_t;
463         float mat[3][3], obloc[3];
464         short cur_frame;
465         float time_before, time_after;
466         float force_mag_norm;
467         int d_object=0, d_face=0, ds_object=0, ds_face=0;
468
469         first_dist = 200000;
470         min_t = 200000;
471
472         /* The first part of the code, finding the first intersected face*/
473         base= G.scene->base.first;
474         while (base) {
475                 /*Only proceed for mesh object in same layer */
476                 if(base->object->type==OB_MESH && (base->lay & par_layer)) {
477                         ob= base->object;
478                         /* only with deflecting set */
479                         if(ob->pd && ob->pd->deflect) {
480                                 def_mesh= ob->data;
481                         
482                                 d_object = d_object + 1;
483
484                                 d_face = d_face + 1;
485                                 mface= def_mesh->mface;
486                                 a = def_mesh->totface;
487                                 /*Find out where the object is at this time*/
488                                 cur_frame = G.scene->r.cfra;
489                                 G.scene->r.cfra = (short)cur_time;
490                                 where_is_object_time(ob, cur_time);
491                                 G.scene->r.cfra = cur_frame;
492                                 /*Pass the values from ob->obmat to mat*/
493                                 /*and the location values to obloc           */
494                                 Mat3CpyMat4(mat,ob->obmat);
495                                 obloc[0] = ob->obmat[3][0];
496                                 obloc[1] = ob->obmat[3][1];
497                                 obloc[2] = ob->obmat[3][2];
498
499                                 while (a--) {
500
501                                         /* Calculate the global co-ordinates of the vertices*/
502                                         v1= (def_mesh->mvert+(mface->v1))->co;
503                                         v2= (def_mesh->mvert+(mface->v2))->co;
504                                         v3= (def_mesh->mvert+(mface->v3))->co;
505                                         v4= (def_mesh->mvert+(mface->v4))->co;
506
507                                         VECCOPY(nv1, v1);
508                                         VECCOPY(nv2, v2);
509                                         VECCOPY(nv3, v3);
510                                         VECCOPY(nv4, v4);
511
512                                         /*Apply the objects deformation matrix*/
513                                         Mat3MulVecfl(mat, nv1);
514                                         Mat3MulVecfl(mat, nv2);
515                                         Mat3MulVecfl(mat, nv3);
516                                         Mat3MulVecfl(mat, nv4);
517
518                                         VecAddf(nv1, nv1, obloc);
519                                         VecAddf(nv2, nv2, obloc);
520                                         VecAddf(nv3, nv3, obloc);
521                                         VecAddf(nv4, nv4, obloc);
522
523                                         deflected_now = 0;
524
525                                         t = - 1;
526                                         t = linetriangle(opco, npco, nv1, nv2, nv3);
527                                         if ((t > 0)&&(t < min_t)) {
528                                             deflected = 1;
529                         deflected_now = 1;
530                                         }
531                                         else if (mface->v4) {
532                                                 t = linetriangle(opco, npco, nv1, nv3, nv4);
533                                                 if ((t > 0)&&(t < min_t)) {
534                                                     deflected = 1;
535                                                         deflected_now = 2;
536                                                 }
537                                         }
538                                         if ((deflected_now > 0)&&(t < min_t)) {
539                         min_t = t;
540                         ds_object = d_object;
541                                                 ds_face = d_face;
542                                                 deflection_object = ob;
543                                                 deflection_face = mface;
544                                                 if (deflected_now==1) {
545                                                         VECCOPY(dv1, nv1);
546                                                         VECCOPY(dv2, nv2);
547                                                         VECCOPY(dv3, nv3);
548                                                 }
549                                                 else {
550                                                         VECCOPY(dv1, nv1);
551                                                         VECCOPY(dv2, nv3);
552                                                         VECCOPY(dv3, nv4);
553                                                 }
554                                         }
555                                         mface++;
556                                 }
557                         }
558                 }
559                 base = base->next;
560         }
561
562         /* Here's the point to do the permeability calculation */
563         /* Set deflected to 0 if a random number is below the value */
564         /* Get the permeability IPO here*/
565         if (deflected) {
566                 
567                 if (has_ipo_code(deflection_object->ipo, OB_PD_PERM)) 
568                         perm_val = IPO_GetFloatValue(deflection_object->ipo, OB_PD_PERM, cur_time);
569                 else 
570                         perm_val = deflection_object->pd->pdef_perm;
571
572                 perm_thresh =  BLI_drand() - perm_val;
573                 if (perm_thresh < 0 ) {
574                         deflected = 0;
575                 }
576         }
577
578         /* Now for the second part of the deflection code - work out the new speed */
579         /* and position of the particle if a collision occurred */
580         if (deflected) {
581         VecSubf(edge1, dv1, dv2);
582                 VecSubf(edge2, dv3, dv2);
583                 Crossf(d_nvect, edge2, edge1);
584                 n_mag = Normalise(d_nvect);
585                 dk_plane = Inpf(d_nvect, nv1);
586                 dk_point1 = Inpf(d_nvect,opco);
587
588                 VecSubf(d_intersect_vect, npco, opco);
589
590                 d_intersect_co[0] = opco[0] + (min_t * (npco[0] - opco[0]));
591                 d_intersect_co[1] = opco[1] + (min_t * (npco[1] - opco[1]));
592                 d_intersect_co[2] = opco[2] + (min_t * (npco[2] - opco[2]));
593                 
594                 d_i_co_above[0] = (d_intersect_co[0] + (0.001 * d_nvect[0]));
595                 d_i_co_above[1] = (d_intersect_co[1] + (0.001 * d_nvect[1]));
596                 d_i_co_above[2] = (d_intersect_co[2] + (0.001 * d_nvect[2]));
597                 mag_iv = Normalise(d_intersect_vect);
598                 VECCOPY(npco, d_intersect_co);
599                 
600                 VecSubf(vect_to_int, opco, d_intersect_co);
601                 first_dist = Normalise(vect_to_int);
602
603                 /* Work out the lengths of time before and after collision*/
604                 time_before = (life*(first_dist / (mag_iv)));
605                 time_after =  (life*((mag_iv - first_dist) / (mag_iv)));
606
607                 /* We have to recalculate what the speed would have been at the */
608                 /* point of collision, not the key frame time */
609                 npno[0]= opno[0] + time_before*force[0];
610                 npno[1]= opno[1] + time_before*force[1];
611                 npno[2]= opno[2] + time_before*force[2];
612
613
614                 /* Reflect the speed vector in the face */
615                 x_m = (2 * npno[0] * d_nvect[0]);
616                 y_m = (2 * npno[1] * d_nvect[1]);
617                 z_m = (2 * npno[2] * d_nvect[2]);
618                 refl_vel[0] = npno[0] - (d_nvect[0] * (x_m + y_m + z_m));
619                 refl_vel[1] = npno[1] - (d_nvect[1] * (x_m + y_m + z_m));
620                 refl_vel[2] = npno[2] - (d_nvect[2] * (x_m + y_m + z_m));
621
622                 /*A random variation in the damping factor........ */
623                 /*Get the IPO values for damping here*/
624                 
625                 if (has_ipo_code(deflection_object->ipo, OB_PD_SDAMP)) 
626                         damping = IPO_GetFloatValue(deflection_object->ipo, OB_PD_SDAMP, cur_time);
627                 else 
628                         damping = deflection_object->pd->pdef_damp;
629                 
630                 if (has_ipo_code(deflection_object->ipo, OB_PD_RDAMP)) 
631                         rdamp_val = IPO_GetFloatValue(deflection_object->ipo, OB_PD_RDAMP, cur_time);
632                 else 
633                         rdamp_val = deflection_object->pd->pdef_rdamp;
634
635                 damping = damping + ((1 - damping) * (BLI_drand()*rdamp_val));
636                 damping = damping * damping;
637         ref_plane_mag = Inpf(refl_vel,d_nvect);
638
639                 if (damping > 0.999) damping = 0.999;
640
641                 /* Now add in the damping force - only damp in the direction of */
642                 /* the faces normal vector */
643                 npno[0] = (refl_vel[0] - (d_nvect[0] * ref_plane_mag * damping));
644                 npno[1] = (refl_vel[1] - (d_nvect[1] * ref_plane_mag * damping));
645                 npno[2] = (refl_vel[2] - (d_nvect[2] * ref_plane_mag * damping));
646
647                 /* Now reset opno */
648                 VECCOPY(opno,npno);
649                 VECCOPY(forcec, force);
650
651                 /* If the particle has bounced more than four times on the same */
652                 /* face within this cycle (depth > 4, same face > 4 )           */
653                 /* Then set the force to be only that component of the force    */
654                 /* in the same direction as the face normal                     */
655                 /* i.e. subtract the component of the force in the direction    */
656                 /* of the face normal from the actual force                     */
657                 if ((ds_object == *last_object) && (ds_face == *last_face)) {
658                         /* Increment same_face */
659                         *same_face = *same_face + 1;
660                         if ((*same_face > 3) && (def_depth > 3)) {
661                 force_mag_norm = Inpf(forcec, d_nvect);
662                 forcec[0] = forcec[0] - (d_nvect[0] * force_mag_norm);
663                 forcec[1] = forcec[1] - (d_nvect[1] * force_mag_norm);
664                 forcec[2] = forcec[2] - (d_nvect[2] * force_mag_norm);
665                         }
666                 }
667                 else *same_face = 1;
668
669                 *last_object = ds_object;
670                 *last_face = ds_face;
671
672                 /* We have the particles speed at the point of collision    */
673                 /* Now we want the particles speed at the current key frame */
674
675                 npno[0]= npno[0] + time_after*forcec[0];
676                 npno[1]= npno[1] + time_after*forcec[1];
677                 npno[2]= npno[2] + time_after*forcec[2];
678
679                 /* Now we have to recalculate pa->co for the remainder*/
680                 /* of the time since the intersect*/
681                 npco[0]= npco[0] + time_after*npno[0];
682                 npco[1]= npco[1] + time_after*npno[1];
683                 npco[2]= npco[2] + time_after*npno[2];
684
685                 /* And set the old co-ordinates back to the point just above the intersection */
686                 VECCOPY(opco, d_i_co_above);
687
688                 /* Finally update the time */
689                 life = time_after;
690                 cur_time += time_before;
691
692                 /* The particle may have fallen through the face again by now!!*/
693                 /* So check if the particle has changed sides of the plane compared*/
694                 /* the co-ordinates at the last keyframe*/
695                 /* But only do this as a last resort, if we've got to the end of the */
696                 /* number of collisions allowed */
697                 if (def_depth==9) {
698                         k_point3 = Inpf(d_nvect,npco);
699                         if (((dk_plane > k_point3) && (dk_plane < dk_point1))||((dk_plane < k_point3) && (dk_plane > dk_point1))) {
700
701                                 /* Yup, the pesky particle may have fallen through a hole!!! */
702                 /* So we'll cheat a bit and move the particle along the normal vector */
703                 /* until it's just the other side of the plane */
704                 icalctop = (dk_plane - d_nvect[0]*npco[0] - d_nvect[1]*npco[1] - d_nvect[2]*npco[2]);
705                 icalcbot = (d_nvect[0]*d_nvect[0] + d_nvect[1]*d_nvect[1] + d_nvect[2]*d_nvect[2]);
706                 dist_to_plane = icalctop / icalcbot;
707
708                 /*  Now just increase the distance a little to place */
709                 /* the point the other side of the plane */
710                 dist_to_plane *= 1.1;
711                 npco[0]= npco[0] + (dist_to_plane * d_nvect[0]);
712                 npco[1]= npco[1] + (dist_to_plane * d_nvect[1]);
713                 npco[2]= npco[2] + (dist_to_plane * d_nvect[2]);
714
715                         }
716                 }
717         }
718         return deflected;
719 }
720
721 void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *force, int deform, MTex *mtex, unsigned int par_layer)
722 {
723         Particle *pa, *opa = NULL;
724         float damp, deltalife, life;
725         float cur_time;
726         float opco[3], opno[3], npco[3], npno[3], new_force[3];
727         int b, rt1, rt2, deflected, deflection, finish_defs, def_count;
728         int last_ob, last_fc, same_fc;
729
730         damp= 1.0f-paf->damp;
731         pa= part;
732
733         /* start speed: random */
734         if(paf->randfac!=0.0) {
735                 pa->no[0]+= (float)(paf->randfac*( BLI_drand() -0.5));
736                 pa->no[1]+= (float)(paf->randfac*( BLI_drand() -0.5));
737                 pa->no[2]+= (float)(paf->randfac*( BLI_drand() -0.5));
738         }
739
740         /* start speed: texture */
741         if(mtex && paf->texfac!=0.0) {
742                 particle_tex(mtex, paf, pa->co, pa->no);
743         }
744
745         if(paf->totkey>1) deltalife= pa->lifetime/(paf->totkey-1);
746         else deltalife= pa->lifetime;
747
748         opa= pa;
749         pa++;
750
751         b= paf->totkey-1;
752         while(b--) {
753                 /* new time */
754                 pa->time= opa->time+deltalife;
755
756                 /* set initial variables                                */
757                 opco[0] = opa->co[0];
758                 opco[1] = opa->co[1];
759                 opco[2] = opa->co[2];
760
761                 new_force[0] = force[0];
762                 new_force[1] = force[1];
763                 new_force[2] = force[2];
764
765                 /* Check force field */
766                 cur_time = pa->time;
767                 get_forcefield(opco, new_force, cur_time, par_layer);
768
769                 /* new location */
770                 pa->co[0]= opa->co[0] + deltalife*opa->no[0];
771                 pa->co[1]= opa->co[1] + deltalife*opa->no[1];
772                 pa->co[2]= opa->co[2] + deltalife*opa->no[2];
773
774                 /* new speed */
775                 pa->no[0]= opa->no[0] + deltalife*new_force[0];
776                 pa->no[1]= opa->no[1] + deltalife*new_force[1];
777                 pa->no[2]= opa->no[2] + deltalife*new_force[2];
778
779                 /* Particle deflection code                             */
780                 deflection = 0;
781                 finish_defs = 1;
782                 def_count = 0;
783
784                 VECCOPY(opno, opa->no);
785                 VECCOPY(npco, pa->co);
786                 VECCOPY(npno, pa->no);
787
788                 life = deltalife;
789                 cur_time -= deltalife;
790
791                 last_ob = -1;
792                 last_fc = -1;
793                 same_fc = 0;
794
795                 /* First call the particle deflection check for the particle moving   */
796                 /* between the old co-ordinates and the new co-ordinates              */
797                 /* If a deflection occurs, call the code again, this time between the */
798                 /* intersection point and the updated new co-ordinates                */
799                 /* Bail out if we've done the calculation 10 times - this seems ok     */
800         /* for most scenes I've tested */
801                 while (finish_defs) {
802                         deflected =  get_deflection(opco, npco, opno, npno, life, new_force,
803                                                         def_count, cur_time, par_layer,
804                                                         &last_ob, &last_fc, &same_fc);
805                         if (deflected) {
806                                 def_count = def_count + 1;
807                                 deflection = 1;
808                                 if (def_count==10) finish_defs = 0;
809                         }
810                         else {
811                                 finish_defs = 0;
812                         }
813                 }
814
815                 /* Only update the particle positions and speed if we had a deflection */
816                 if (deflection) {
817                         pa->co[0] = npco[0];
818                         pa->co[1] = npco[1];
819                         pa->co[2] = npco[2];
820                         pa->no[0] = npno[0];
821                         pa->no[1] = npno[1];
822                         pa->no[2] = npno[2];
823                 }
824
825
826                 /* speed: texture */
827                 if(mtex && paf->texfac!=0.0) {
828                         particle_tex(mtex, paf, opa->co, opa->no);
829                 }
830                 if(damp!=1.0) {
831                         pa->no[0]*= damp;
832                         pa->no[1]*= damp;
833                         pa->no[2]*= damp;
834                 }
835         
836
837
838                 opa= pa;
839                 pa++;
840                 /* opa is used later on too! */
841         }
842
843         if(deform) {
844                 /* deform all keys */
845                 pa= part;
846                 b= paf->totkey;
847                 while(b--) {
848                         calc_latt_deform(pa->co);
849                         pa++;
850                 }
851         }
852         
853         /* the big multiplication */
854         if(depth<PAF_MAXMULT && paf->mult[depth]!=0.0) {
855                 
856                 /* new 'child' emerges from an average 'mult' part from 
857                         the particles */
858                 damp = (float)nr;
859                 rt1= (int)(damp*paf->mult[depth]);
860                 rt2= (int)((damp+1.0)*paf->mult[depth]);
861                 if(rt1!=rt2) {
862                         
863                         for(b=0; b<paf->child[depth]; b++) {
864                                 pa= new_particle(paf);
865                                 *pa= *opa;
866                                 pa->lifetime= paf->life[depth];
867                                 if(paf->randlife!=0.0) {
868                                         pa->lifetime*= 1.0f+ (float)(paf->randlife*( BLI_drand() - 0.5));
869                                 }
870                                 pa->mat_nr= paf->mat[depth];
871
872                                 make_particle_keys(depth+1, b, paf, pa, force, deform, mtex, par_layer);
873                         }
874                 }
875         }
876 }
877
878 void init_mv_jit(float *jit, int num,float seed2)
879 {
880         float *jit2, x, rad1, rad2, rad3;
881         int i, num2;
882
883         if(num==0) return;
884
885         rad1= (float)(1.0/sqrt((float)num));
886         rad2= (float)(1.0/((float)num));
887         rad3= (float)sqrt((float)num)/((float)num);
888
889         BLI_srand(31415926 + num + seed2);
890         x= 0;
891         num2 = 2 * num;
892         for(i=0; i<num2; i+=2) {
893         
894                 jit[i]= x+ (float)(rad1*(0.5-BLI_drand()));
895                 jit[i+1]= ((float)i/2)/num +(float)(rad1*(0.5-BLI_drand()));
896                 
897                 jit[i]-= (float)floor(jit[i]);
898                 jit[i+1]-= (float)floor(jit[i+1]);
899                 
900                 x+= rad3;
901                 x -= (float)floor(x);
902         }
903
904         jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
905
906         for (i=0 ; i<4 ; i++) {
907                 RE_jitterate1(jit, jit2, num, rad1);
908                 RE_jitterate1(jit, jit2, num, rad1);
909                 RE_jitterate2(jit, jit2, num, rad2);
910         }
911         MEM_freeN(jit2);
912 }
913
914
915 void give_mesh_mvert(Mesh *me, int nr, float *co, short *no, float seed2)
916 {
917         static float *jit=0;
918         static int jitlevel=1;
919         MVert *mvert, *mvertbase=NULL;
920         MFace *mface, *mfacebase=NULL;
921         float u, v, *v1, *v2, *v3, *v4;
922         int totface=0, totvert=0, curface, curjit;
923         short *n1, *n2, *n3, *n4;
924         
925         /* signal */
926         if(me==0) {
927                 if(jit) MEM_freeN(jit);
928                 jit= 0;
929                 return;
930         }
931         
932         /* get it from displist? */
933         if(me->disp.first) {
934                 DispList *dl= me->disp.first;
935                 if(dl->type==DL_MESH) {
936                         DispListMesh *dlm= dl->mesh;
937                         mvertbase= dlm->mvert;
938                         mfacebase= dlm->mface;
939                         totface= dlm->totface;
940                         totvert= dlm->totvert;
941                 }
942         }
943         
944         if(totvert==0) {
945                 mvertbase= me->mvert;
946                 mfacebase= me->mface;
947                 totface= me->totface;
948                 totvert= me->totvert;
949         }
950         
951         if(totface==0 || nr<totvert) {
952                 mvert= mvertbase + (nr % totvert);
953                 VECCOPY(co, mvert->co);
954                 VECCOPY(no, mvert->no);
955         }
956         else {
957
958                 nr-= totvert;
959                 
960                 if(jit==0) {
961                         jitlevel= nr/totface;
962                         if(jitlevel==0) jitlevel= 1;
963                         if(jitlevel>100) jitlevel= 100;
964
965                         jit= MEM_callocN(2+ jitlevel*2*sizeof(float), "jit");
966                         init_mv_jit(jit, jitlevel,seed2);
967                         
968                 }
969
970                 curjit= nr/totface;
971                 curjit= curjit % jitlevel;
972
973                 curface= nr % totface;
974                 
975                 mface= mfacebase;
976                 mface+= curface;
977
978                 v1= (mvertbase+(mface->v1))->co;
979                 v2= (mvertbase+(mface->v2))->co;
980                 n1= (mvertbase+(mface->v1))->no;
981                 n2= (mvertbase+(mface->v2))->no;
982                 if(mface->v3==0) {
983                         v3= (mvertbase+(mface->v2))->co;
984                         v4= (mvertbase+(mface->v1))->co;
985                         n3= (mvertbase+(mface->v2))->no;
986                         n4= (mvertbase+(mface->v1))->no;
987                 }
988                 else if(mface->v4==0) {
989                         v3= (mvertbase+(mface->v3))->co;
990                         v4= (mvertbase+(mface->v1))->co;
991                         n3= (mvertbase+(mface->v3))->no;
992                         n4= (mvertbase+(mface->v1))->no;
993                 }
994                 else {
995                         v3= (mvertbase+(mface->v3))->co;
996                         v4= (mvertbase+(mface->v4))->co;
997                         n3= (mvertbase+(mface->v3))->no;
998                         n4= (mvertbase+(mface->v4))->no;
999                 }
1000
1001                 u= jit[2*curjit];
1002                 v= jit[2*curjit+1];
1003
1004                 co[0]= (float)((1.0-u)*(1.0-v)*v1[0] + (1.0-u)*(v)*v2[0] + (u)*(v)*v3[0] + (u)*(1.0-v)*v4[0]);
1005                 co[1]= (float)((1.0-u)*(1.0-v)*v1[1] + (1.0-u)*(v)*v2[1] + (u)*(v)*v3[1] + (u)*(1.0-v)*v4[1]);
1006                 co[2]= (float)((1.0-u)*(1.0-v)*v1[2] + (1.0-u)*(v)*v2[2] + (u)*(v)*v3[2] + (u)*(1.0-v)*v4[2]);
1007                 
1008                 no[0]= (short)((1.0-u)*(1.0-v)*n1[0] + (1.0-u)*(v)*n2[0] + (u)*(v)*n3[0] + (u)*(1.0-v)*n4[0]);
1009                 no[1]= (short)((1.0-u)*(1.0-v)*n1[1] + (1.0-u)*(v)*n2[1] + (u)*(v)*n3[1] + (u)*(1.0-v)*n4[1]);
1010                 no[2]= (short)((1.0-u)*(1.0-v)*n1[2] + (1.0-u)*(v)*n2[2] + (u)*(v)*n3[2] + (u)*(1.0-v)*n4[2]);
1011                 
1012         }
1013 }
1014
1015
1016 void build_particle_system(Object *ob)
1017 {
1018         Object *par;
1019         PartEff *paf;
1020         Particle *pa;
1021         Mesh *me;
1022         MVert *mvert;
1023         MTex *mtexmove=0;
1024         Material *ma;
1025         int armature_parent;
1026         float framelenont, ftime, dtime, force[3], imat[3][3], vec[3];
1027         float fac, prevobmat[4][4], sfraont, co[3];
1028         int deform=0, a, b, c, cur, cfraont, cfralast, totpart;
1029         short no[3];
1030
1031         if(ob->type!=OB_MESH) return;
1032         me= ob->data;
1033         if(me->totvert==0) return;
1034
1035         ma= give_current_material(ob, 1);
1036         if(ma) {
1037                 mtexmove= ma->mtex[7];
1038         }
1039
1040         paf= give_parteff(ob);
1041         if(paf==NULL) return;
1042
1043         waitcursor(1);
1044
1045         disable_speed_curve(1);
1046
1047         /* generate all particles */
1048         if(paf->keys) MEM_freeN(paf->keys);
1049         paf->keys= NULL;
1050         new_particle(paf);
1051
1052         cfraont= G.scene->r.cfra;
1053         cfralast= -1000;
1054         framelenont= G.scene->r.framelen;
1055         G.scene->r.framelen= 1.0;
1056         sfraont= ob->sf;
1057         ob->sf= 0.0;
1058
1059         /* mult generations? */
1060         totpart= paf->totpart;
1061         for(a=0; a<PAF_MAXMULT; a++) {
1062                 if(paf->mult[a]!=0.0) {
1063                         /* interessant formula! this way after 'x' generations the total is paf->totpart */
1064                         totpart= (int)(totpart / (1.0+paf->mult[a]*paf->child[a]));
1065                 }
1066                 else break;
1067         }
1068
1069         ftime= paf->sta;
1070         dtime= (paf->end - paf->sta)/totpart;
1071
1072         /* remember full hierarchy */
1073         par= ob;
1074         while(par) {
1075                 pushdata(par, sizeof(Object));
1076                 par= par->parent;
1077         }
1078
1079         /* set it all at first frame */
1080         G.scene->r.cfra= cfralast= (int)floor(ftime);
1081         par= ob;
1082         armature_parent = 0;
1083         while(par) {
1084                 /* do_ob_ipo(par); */
1085                 do_ob_key(par);
1086                 /* Just checking whether theres an armature in the */
1087                 /* parent chain of the emitter, so we know whether */
1088                 /* to recalculate the armatures */
1089                 if(par->type==OB_ARMATURE) {
1090                         armature_parent = 1;
1091                 }
1092                 par= par->parent;
1093         }
1094         do_mat_ipo(ma);
1095
1096         if((paf->flag & PAF_STATIC)==0) {
1097                 where_is_object(ob);
1098                 Mat4CpyMat4(prevobmat, ob->obmat);
1099                 Mat4Invert(ob->imat, ob->obmat);
1100                 Mat3CpyMat4(imat, ob->imat);
1101         }
1102         else {
1103                 Mat4One(prevobmat);
1104                 Mat3One(imat);
1105         }
1106         
1107         BLI_srand(paf->seed);
1108         
1109         /* otherwise it goes way too fast */
1110         force[0]= paf->force[0]*0.05f;
1111         force[1]= paf->force[1]*0.05f;
1112         force[2]= paf->force[2]*0.05f;
1113         
1114         if( paf->flag & PAF_STATIC ) deform= 0;
1115         else {
1116                 deform= (ob->parent && ob->parent->type==OB_LATTICE);
1117                 if(deform) init_latt_deform(ob->parent, 0);
1118         }
1119         
1120         /* init */
1121         give_mesh_mvert(me, totpart, co, no,paf->seed);
1122
1123         if(me->disp.first) {
1124                 DispList *dl= me->disp.first;
1125                 if(dl->type==DL_MESH) printf("from disp\n");
1126         }
1127
1128         printf("\n");
1129         printf("Calculating particles......... \n");
1130
1131         for(a=0; a<totpart; a++, ftime+=dtime) {
1132                 
1133                 pa= new_particle(paf);
1134                 pa->time= ftime;
1135                 
1136                 c = totpart/100;
1137                 if (c==0){
1138                         c = 1;
1139                 }
1140
1141                 b=(a%c);
1142                 if (b==0) {
1143                         printf("\r Particle: %d / %d ", a, totpart);
1144                         fflush(stdout);
1145                 }
1146                 /* set ob at correct time */
1147                 
1148                 if((paf->flag & PAF_STATIC)==0) {
1149
1150                         cur= (int)floor(ftime) + 1 ;            /* + 1 has a reason: (obmat/prevobmat) otherwise comet-tails start too late */
1151                         if(cfralast != cur) {
1152                                 G.scene->r.cfra= cfralast= cur;
1153         
1154                                 /* added later: blur? */
1155                                 bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
1156                                 
1157                                 /* Update the armatures */
1158                                 if (armature_parent) {
1159                                         do_all_actions();
1160                                         rebuild_all_armature_displists();
1161                                 }
1162
1163                                 par= ob;
1164                                 while(par) {
1165                                         /* do_ob_ipo(par); */
1166                                         par->ctime= -1234567.0;
1167                                         do_ob_key(par);
1168                                         par= par->parent;
1169                                 }
1170                                 do_mat_ipo(ma);
1171                                 Mat4CpyMat4(prevobmat, ob->obmat);
1172                                 where_is_object(ob);
1173                                 Mat4Invert(ob->imat, ob->obmat);
1174                                 Mat3CpyMat4(imat, ob->imat);
1175                         }
1176                 }
1177                 /* get coordinates */
1178                 if(paf->flag & PAF_FACE) give_mesh_mvert(me, a, co, no,paf->seed);
1179                 else {
1180                         mvert= me->mvert + (a % me->totvert);
1181                         VECCOPY(co, mvert->co);
1182                         VECCOPY(no, mvert->no);
1183                 }
1184                 
1185                 VECCOPY(pa->co, co);
1186                 
1187                 if(paf->flag & PAF_STATIC);
1188                 else {
1189                         Mat4MulVecfl(ob->obmat, pa->co);
1190                 
1191                         VECCOPY(vec, co);
1192                         Mat4MulVecfl(prevobmat, vec);
1193                         
1194                         /* first start speed: object */
1195                         VecSubf(pa->no, pa->co, vec);
1196                         VecMulf(pa->no, paf->obfac);
1197                         
1198                         /* calculate the correct inter-frame */ 
1199                         fac= (ftime- (float)floor(ftime));
1200                         pa->co[0]= fac*pa->co[0] + (1.0f-fac)*vec[0];
1201                         pa->co[1]= fac*pa->co[1] + (1.0f-fac)*vec[1];
1202                         pa->co[2]= fac*pa->co[2] + (1.0f-fac)*vec[2];
1203                 }
1204
1205                 /* start speed: normal */
1206                 if(paf->normfac!=0.0) {
1207                         /* sp= mvert->no; */
1208                                 /* transpose ! */
1209                         vec[0]= imat[0][0]*no[0] + imat[0][1]*no[1] + imat[0][2]*no[2];
1210                         vec[1]= imat[1][0]*no[0] + imat[1][1]*no[1] + imat[1][2]*no[2];
1211                         vec[2]= imat[2][0]*no[0] + imat[2][1]*no[1] + imat[2][2]*no[2];         
1212                 
1213                         Normalise(vec);
1214                         VecMulf(vec, paf->normfac);
1215                         VecAddf(pa->no, pa->no, vec);
1216                 }
1217                 pa->lifetime= paf->lifetime;
1218                 if(paf->randlife!=0.0) {
1219                         pa->lifetime*= 1.0f+ (float)(paf->randlife*( BLI_drand() - 0.5));
1220                 }
1221                 pa->mat_nr= 1;
1222                 
1223                 make_particle_keys(0, a, paf, pa, force, deform, mtexmove, ob->lay);
1224         }
1225         
1226         printf("\r Particle: %d / %d \n", totpart, totpart);
1227         fflush(stdout);
1228         
1229         if(deform) end_latt_deform();
1230                 
1231         /* restore */
1232         G.scene->r.cfra= cfraont;
1233         G.scene->r.framelen= framelenont;
1234         give_mesh_mvert(0, 0, 0, 0,paf->seed);
1235
1236         /*Restore armature settings*/
1237         if((paf->flag & PAF_STATIC)==0) {
1238                 if (armature_parent) {
1239                         do_all_actions();
1240                         rebuild_all_armature_displists();
1241                 }
1242         }
1243         /* put hierarchy back */
1244         par= ob;
1245         while(par) {
1246                 popfirst(par);
1247                 /* do not do ob->ipo: keep insertkey */
1248                 do_ob_key(par);
1249                 par= par->parent;
1250         }
1251
1252         /* restore: AFTER popfirst */
1253         ob->sf= sfraont;
1254
1255         disable_speed_curve(0);
1256
1257         waitcursor(0);
1258
1259 }
1260
1261 /* ************* WAVE **************** */
1262
1263 void calc_wave_deform(WaveEff *wav, float ctime, float *co)
1264 {
1265         /* co is in local coords */
1266         float lifefac, x, y, amplit;
1267         
1268         /* actually this should not happen */
1269         if((wav->flag & (WAV_X+WAV_Y))==0) return;      
1270
1271         lifefac= wav->height;
1272         
1273         if( wav->lifetime!=0.0) {
1274                 x= ctime - wav->timeoffs;
1275                 if(x>wav->lifetime) {
1276                         
1277                         lifefac= x-wav->lifetime;
1278                         
1279                         if(lifefac > wav->damp) lifefac= 0.0;
1280                         else lifefac= (float)(wav->height*(1.0 - sqrt(lifefac/wav->damp)));
1281                 }
1282         }
1283         if(lifefac==0.0) return;
1284
1285         x= co[0]-wav->startx;
1286         y= co[1]-wav->starty;
1287
1288         if(wav->flag & WAV_X) {
1289                 if(wav->flag & WAV_Y) amplit= (float)sqrt( (x*x + y*y));
1290                 else amplit= x;
1291         }
1292         else amplit= y;
1293         
1294         /* this way it makes nice circles */
1295         amplit-= (ctime-wav->timeoffs)*wav->speed;
1296
1297         if(wav->flag & WAV_CYCL) {
1298                 amplit = (float)fmod(amplit-wav->width, 2.0*wav->width) + wav->width;
1299         }
1300
1301         /* GAUSSIAN */
1302         
1303         if(amplit> -wav->width && amplit<wav->width) {
1304         
1305                 amplit = amplit*wav->narrow;
1306                 amplit= (float)(1.0/exp(amplit*amplit) - wav->minfac);
1307
1308                 co[2]+= lifefac*amplit;
1309         }
1310 }
1311
1312 void object_wave(Object *ob)
1313 {
1314         WaveEff *wav;
1315         DispList *dl;
1316         Mesh *me;
1317         MVert *mvert;
1318         float *fp, ctime;
1319         int a, first;
1320         
1321         /* is there a wave */
1322         wav= ob->effect.first;
1323         while(wav) {
1324                 if(wav->type==EFF_WAVE) break;
1325                 wav= wav->next;
1326         }
1327         if(wav==0) return;
1328         
1329         if(ob->type==OB_MESH) {
1330
1331                 ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, 0.0);
1332                 first= 1;
1333                 
1334                 me= ob->data;
1335                 dl= find_displist_create(&ob->disp, DL_VERTS);
1336
1337                 if(dl->verts) MEM_freeN(dl->verts);
1338                 dl->nr= me->totvert;
1339                 dl->verts= MEM_mallocN(3*sizeof(float)*me->totvert, "wave");
1340
1341                 wav= ob->effect.first;
1342                 while(wav) {
1343                         if(wav->type==EFF_WAVE) {
1344                                 
1345                                 /* precalculate */
1346                                 wav->minfac= (float)(1.0/exp(wav->width*wav->narrow*wav->width*wav->narrow));
1347                                 if(wav->damp==0) wav->damp= 10.0f;
1348                                 
1349                                 mvert= me->mvert;
1350                                 fp= dl->verts;
1351                                 
1352                                 for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
1353                                         if(first) VECCOPY(fp, mvert->co);
1354                                         calc_wave_deform(wav, ctime, fp);
1355                                 }
1356                                 first= 0;
1357                         }
1358                         wav= wav->next;
1359                 }
1360         }
1361 }