Initial revision
[blender.git] / source / blender / blenkernel / intern / effect.c
1 /*  effect.c        MIX MODEL
2  * 
3  *  dec 95
4  * 
5  * $Id$
6  *
7  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version. The Blender
13  * Foundation also sells licenses for use in proprietary software under
14  * the Blender License.  See http://www.blender.org/BL/ for information
15  * about this.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software Foundation,
24  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  *
26  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
27  * All rights reserved.
28  *
29  * The Original Code is: all of this file.
30  *
31  * Contributor(s): none yet.
32  *
33  * ***** END GPL/BL DUAL LICENSE BLOCK *****
34  */
35
36 #include <math.h>
37 #include <stdlib.h>
38
39 #include "MEM_guardedalloc.h"
40 #include "DNA_listBase.h"
41 #include "DNA_effect_types.h"
42 #include "DNA_object_types.h"
43 #include "DNA_mesh_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
51 #include "BLI_blenlib.h"
52 #include "BLI_arithb.h"
53 #include "BLI_rand.h"
54
55 #include "BKE_utildefines.h"
56 #include "BKE_bad_level_calls.h"
57 #include "BKE_global.h"
58 #include "BKE_material.h"
59 #include "BKE_effect.h"
60 #include "BKE_key.h"
61 #include "BKE_ipo.h"
62 #include "BKE_screen.h"
63 #include "BKE_texture.h"
64 #include "BKE_blender.h"
65 #include "BKE_object.h"
66 #include "BKE_displist.h"
67 #include "BKE_lattice.h"
68
69
70 Effect *add_effect(int type)
71 {
72         Effect *eff=0;
73         BuildEff *bld;
74         PartEff *paf;
75         WaveEff *wav;
76         int a;
77         
78         switch(type) {
79         case EFF_BUILD:
80                 bld= MEM_callocN(sizeof(BuildEff), "neweff");
81                 eff= (Effect *)bld;
82                 
83                 bld->sfra= 1.0;
84                 bld->len= 100.0;
85                 break;
86                 
87         case EFF_PARTICLE:
88                 paf= MEM_callocN(sizeof(PartEff), "neweff");
89                 eff= (Effect *)paf;
90                 
91                 paf->sta= 1.0;
92                 paf->end= 100.0;
93                 paf->lifetime= 50.0;
94                 for(a=0; a<PAF_MAXMULT; a++) {
95                         paf->life[a]= 50.0;
96                         paf->child[a]= 4;
97                         paf->mat[a]= 1;
98                 }
99                 
100                 paf->totpart= 1000;
101                 paf->totkey= 8;
102                 paf->staticstep= 5;
103                 paf->defvec[2]= 1.0f;
104                 paf->nabla= 0.05f;
105                 
106                 break;
107                 
108         case EFF_WAVE:
109                 wav= MEM_callocN(sizeof(WaveEff), "neweff");
110                 eff= (Effect *)wav;
111                 
112                 wav->flag |= (WAV_X+WAV_Y+WAV_CYCL);
113                 
114                 wav->height= 0.5f;
115                 wav->width= 1.5f;
116                 wav->speed= 0.5f;
117                 wav->narrow= 1.5f;
118                 wav->lifetime= 0.0f;
119                 wav->damp= 10.0f;
120                 
121                 break;
122         }
123         
124         eff->type= eff->buttype= type;
125         eff->flag |= SELECT;
126         
127         return eff;
128 }
129
130 void free_effect(Effect *eff)
131 {
132         PartEff *paf;
133         
134         if(eff->type==EFF_PARTICLE) {
135                 paf= (PartEff *)eff;
136                 if(paf->keys) MEM_freeN(paf->keys);
137         }
138         MEM_freeN(eff); 
139 }
140
141
142 void free_effects(ListBase *lb)
143 {
144         Effect *eff;
145         
146         eff= lb->first;
147         while(eff) {
148                 BLI_remlink(lb, eff);
149                 free_effect(eff);
150                 eff= lb->first;
151         }
152 }
153
154 Effect *copy_effect(Effect *eff) 
155 {
156         Effect *effn;
157         
158         effn= MEM_dupallocN(eff);
159         if(effn->type==EFF_PARTICLE) ((PartEff *)effn)->keys= 0;
160
161         return effn;    
162 }
163
164 void copy_act_effect(Object *ob)
165 {
166         /* return de aktieve eff gekopieerd */
167         Effect *effn, *eff;
168         
169         eff= ob->effect.first;
170         while(eff) {
171                 if(eff->flag & SELECT) {
172                         
173                         effn= copy_effect(eff);
174                         BLI_addtail(&ob->effect, effn);
175                         
176                         eff->flag &= ~SELECT;
177                         return;
178                         
179                 }
180                 eff= eff->next;
181         }
182         
183         /* als tie hier komt: new effect */
184         eff= add_effect(EFF_BUILD);
185         BLI_addtail(&ob->effect, eff);
186                         
187 }
188
189 void copy_effects(ListBase *lbn, ListBase *lb)
190 {
191         Effect *eff, *effn;
192
193         lbn->first= lbn->last= 0;
194
195         eff= lb->first;
196         while(eff) {
197                 effn= copy_effect(eff);
198                 BLI_addtail(lbn, effn);
199                 
200                 eff= eff->next;
201         }
202         
203 }
204
205 void deselectall_eff(Object *ob)
206 {
207         Effect *eff= ob->effect.first;
208         
209         while(eff) {
210                 eff->flag &= ~SELECT;
211                 eff= eff->next;
212         }
213 }
214
215 void set_buildvars(Object *ob, int *start, int *end)
216 {
217         BuildEff *bld;
218         float ctime;
219         
220         bld= ob->effect.first;
221         while(bld) {
222                 if(bld->type==EFF_BUILD) {
223                         ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, bld->sfra-1.0f);
224                         if(ctime < 0.0) {
225                                 *end= *start;
226                         }
227                         else if(ctime < bld->len) {
228                                 *end= *start+ (int)((*end - *start)*ctime/bld->len);
229                         }
230                         
231                         return;
232                 }
233                 bld= bld->next;
234         }
235 }
236
237 /* ***************** PARTICLES ***************** */
238
239 Particle *new_particle(PartEff *paf)
240 {
241         static Particle *pa;
242         static int cur;
243
244         /* afspraak: als paf->keys==0: alloc */ 
245         if(paf->keys==0) {
246                 pa= paf->keys= MEM_callocN( paf->totkey*paf->totpart*sizeof(Particle), "particlekeys" );
247                 cur= 0;
248         }
249         else {
250                 if(cur && cur<paf->totpart) pa+=paf->totkey;
251                 cur++;
252         }
253         return pa;
254 }
255
256 PartEff *give_parteff(Object *ob)
257 {
258         PartEff *paf;
259         
260         paf= ob->effect.first;
261         while(paf) {
262                 if(paf->type==EFF_PARTICLE) return paf;
263                 paf= paf->next;
264         }
265         return 0;
266 }
267
268 void where_is_particle(PartEff *paf, Particle *pa, float ctime, float *vec)
269 {
270         Particle *p[4];
271         float dt, t[4];
272         int a;
273         
274         if(paf->totkey==1) {
275                 VECCOPY(vec, pa->co);
276                 return;
277         }
278         
279         /* eerst op zoek naar de eerste particlekey */
280         a= (int)((paf->totkey-1)*(ctime-pa->time)/pa->lifetime);
281         if(a>=paf->totkey) a= paf->totkey-1;
282         
283         pa+= a;
284         
285         if(a>0) p[0]= pa-1; else p[0]= pa;
286         p[1]= pa;
287         
288         if(a+1<paf->totkey) p[2]= pa+1; else p[2]= pa;
289         if(a+2<paf->totkey) p[3]= pa+2; else p[3]= p[2];
290         
291         if(p[1]==p[2]) dt= 0.0;
292         else dt= (ctime-p[1]->time)/(p[2]->time - p[1]->time);
293
294         if(paf->flag & PAF_BSPLINE) set_four_ipo(dt, t, KEY_BSPLINE);
295         else set_four_ipo(dt, t, KEY_CARDINAL);
296
297         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];
298         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];
299         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];
300
301 }
302
303
304 void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no)
305 {                               
306         extern float Tin, Tr, Tg, Tb;
307         float old;
308         
309         externtex(mtex, co);
310         
311         if(paf->texmap==PAF_TEXINT) {
312                 Tin*= paf->texfac;
313                 no[0]+= Tin*paf->defvec[0];
314                 no[1]+= Tin*paf->defvec[1];
315                 no[2]+= Tin*paf->defvec[2];
316         }
317         else if(paf->texmap==PAF_TEXRGB) {
318                 no[0]+= (Tr-0.5f)*paf->texfac;
319                 no[1]+= (Tg-0.5f)*paf->texfac;
320                 no[2]+= (Tb-0.5f)*paf->texfac;
321         }
322         else {  /* PAF_TEXGRAD */
323                 
324                 old= Tin;
325                 co[0]+= paf->nabla;
326                 externtex(mtex, co);
327                 no[0]+= (old-Tin)*paf->texfac;
328                 
329                 co[0]-= paf->nabla;
330                 co[1]+= paf->nabla;
331                 externtex(mtex, co);
332                 no[1]+= (old-Tin)*paf->texfac;
333                 
334                 co[1]-= paf->nabla;
335                 co[2]+= paf->nabla;
336                 externtex(mtex, co);
337                 no[2]+= (old-Tin)*paf->texfac;
338                 
339         }
340 }
341
342 void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *force, int deform, MTex *mtex)
343 {
344         Particle *pa, *opa = NULL;
345         float damp, deltalife;
346         int b, rt1, rt2;
347         
348         damp= 1.0f-paf->damp;
349         pa= part;
350         
351         /* startsnelheid: random */
352         if(paf->randfac!=0.0) {
353                 pa->no[0]+= (float)(paf->randfac*( BLI_drand() -0.5));
354                 pa->no[1]+= (float)(paf->randfac*( BLI_drand() -0.5));
355                 pa->no[2]+= (float)(paf->randfac*( BLI_drand() -0.5));
356         }
357         
358         /* startsnelheid: texture */
359         if(mtex && paf->texfac!=0.0) {
360                 particle_tex(mtex, paf, pa->co, pa->no);
361         }
362         
363         /* keys */
364         if(paf->totkey>1) {
365                 
366                 deltalife= pa->lifetime/(paf->totkey-1);
367                 opa= pa;
368                 pa++;
369                 
370                 b= paf->totkey-1;
371                 while(b--) {
372                         /* nieuwe tijd */
373                         pa->time= opa->time+deltalife;
374                         
375                         /* nieuwe plek */
376                         pa->co[0]= opa->co[0] + deltalife*opa->no[0];
377                         pa->co[1]= opa->co[1] + deltalife*opa->no[1];
378                         pa->co[2]= opa->co[2] + deltalife*opa->no[2];
379                         
380                         /* nieuwe snelheid */
381                         pa->no[0]= opa->no[0] + deltalife*force[0];
382                         pa->no[1]= opa->no[1] + deltalife*force[1];
383                         pa->no[2]= opa->no[2] + deltalife*force[2];
384
385                         /* snelheid: texture */
386                         if(mtex && paf->texfac!=0.0) {
387                                 particle_tex(mtex, paf, pa->co, pa->no);
388                         }
389                         if(damp!=1.0) {
390                                 pa->no[0]*= damp;
391                                 pa->no[1]*= damp;
392                                 pa->no[2]*= damp;
393                         }
394         
395                         opa= pa;
396                         pa++;
397                         /* opa wordt onderin ook gebruikt */
398                 }
399         }
400
401         if(deform) {
402                 /* alle keys deformen */
403                 pa= part;
404                 b= paf->totkey;
405                 while(b--) {
406                         calc_latt_deform(pa->co);
407                         pa++;
408                 }
409         }
410         
411         /* de grote vermenigvuldiging */
412         if(depth<PAF_MAXMULT && paf->mult[depth]!=0.0) {
413                 
414                 /* uit gemiddeld 'mult' deel van de particles ontstaan 'child' nieuwe */
415                 damp = (float)nr;
416                 rt1= (int)(damp*paf->mult[depth]);
417                 rt2= (int)((damp+1.0)*paf->mult[depth]);
418                 if(rt1!=rt2) {
419                         
420                         for(b=0; b<paf->child[depth]; b++) {
421                                 pa= new_particle(paf);
422                                 *pa= *opa;
423                                 pa->lifetime= paf->life[depth];
424                                 if(paf->randlife!=0.0) {
425                                         pa->lifetime*= 1.0f+ (float)(paf->randlife*( BLI_drand() - 0.5));
426                                 }
427                                 pa->mat_nr= paf->mat[depth];
428                                 
429                                 make_particle_keys(depth+1, b, paf, pa, force, deform, mtex);
430                         }
431                 }
432         }
433 }
434
435 void init_mv_jit(float *jit, int num)
436 {
437         float *jit2, x, rad1, rad2, rad3;
438         int i;
439
440         if(num==0) return;
441
442         rad1= (float)(1.0/sqrt((float)num));
443         rad2= (float)(1.0/((float)num));
444         rad3= (float)sqrt((float)num)/((float)num);
445
446         BLI_srand(31415926 + num);
447         x= 0;
448         for(i=0; i<2*num; i+=2) {
449         
450                 jit[i]= x+ (float)(rad1*(0.5-BLI_drand()));
451                 jit[i+1]= ((float)i/2)/num +(float)(rad1*(0.5-BLI_drand()));
452                 
453                 jit[i]-= (float)floor(jit[i]);
454                 jit[i+1]-= (float)floor(jit[i+1]);
455                 
456                 x+= rad3;
457                 x -= (float)floor(x);
458         }
459
460         jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
461
462         for (i=0 ; i<4 ; i++) {
463                 RE_jitterate1(jit, jit2, num, rad1);
464                 RE_jitterate1(jit, jit2, num, rad1);
465                 RE_jitterate2(jit, jit2, num, rad2);
466         }
467         MEM_freeN(jit2);
468 }
469
470
471 void give_mesh_mvert(Mesh *me, int nr, float *co, short *no)
472 {
473         static float *jit=0;
474         static int jitlevel=1;
475         MVert *mvert;
476         MFace *mface;
477         float u, v, *v1, *v2, *v3, *v4;
478         int curface, curjit;
479         short *n1, *n2, *n3, *n4;
480         
481         /* signal */
482         if(me==0) {
483                 if(jit) MEM_freeN(jit);
484                 jit= 0;
485                 return;
486         }
487         
488         if(me->totface==0 || nr<me->totvert) {
489                 mvert= me->mvert + (nr % me->totvert);
490                 VECCOPY(co, mvert->co);
491                 VECCOPY(no, mvert->no);
492         }
493         else {
494                 
495                 nr-= me->totvert;
496                 
497                 if(jit==0) {
498                         jitlevel= nr/me->totface;
499                         if(jitlevel==0) jitlevel= 1;
500                         if(jitlevel>100) jitlevel= 100;
501                         
502                         jit= MEM_callocN(2+ jitlevel*2*sizeof(float), "jit");
503                         init_mv_jit(jit, jitlevel);
504                         
505                 }
506
507                 curjit= nr/me->totface;
508                 curjit= curjit % jitlevel;
509
510                 curface= nr % me->totface;
511                 
512                 mface= me->mface;
513                 mface+= curface;
514                 
515                 v1= (me->mvert+(mface->v1))->co;
516                 v2= (me->mvert+(mface->v2))->co;
517                 n1= (me->mvert+(mface->v1))->no;
518                 n2= (me->mvert+(mface->v2))->no;
519                 if(mface->v3==0) {
520                         v3= (me->mvert+(mface->v2))->co;
521                         v4= (me->mvert+(mface->v1))->co;
522                         n3= (me->mvert+(mface->v2))->no;
523                         n4= (me->mvert+(mface->v1))->no;
524                 }
525                 else if(mface->v4==0) {
526                         v3= (me->mvert+(mface->v3))->co;
527                         v4= (me->mvert+(mface->v1))->co;
528                         n3= (me->mvert+(mface->v3))->no;
529                         n4= (me->mvert+(mface->v1))->no;
530                 }
531                 else {
532                         v3= (me->mvert+(mface->v3))->co;
533                         v4= (me->mvert+(mface->v4))->co;
534                         n3= (me->mvert+(mface->v3))->no;
535                         n4= (me->mvert+(mface->v4))->no;
536                 }
537
538                 u= jit[2*curjit];
539                 v= jit[2*curjit+1];
540
541                 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]);
542                 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]);
543                 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]);
544                 
545                 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]);
546                 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]);
547                 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]);
548                 
549         }
550 }
551
552
553 void build_particle_system(Object *ob)
554 {
555         Object *par;
556         PartEff *paf;
557         Particle *pa;
558         Mesh *me;
559         MVert *mvert;
560         MTex *mtexmove=0;
561         Material *ma;
562         float framelenont, ftime, dtime, force[3], imat[3][3], vec[3];
563         float fac, prevobmat[4][4], sfraont, co[3];
564         int deform=0, a, cur, cfraont, cfralast, totpart;
565         short no[3];
566         
567         if(ob->type!=OB_MESH) return;
568         me= ob->data;
569         if(me->totvert==0) return;
570         
571         ma= give_current_material(ob, 1);
572         if(ma) {
573                 mtexmove= ma->mtex[7];
574         }
575         
576         paf= give_parteff(ob);
577         if(paf==0) return;
578
579         waitcursor(1);
580         
581         disable_speed_curve(1);
582         
583         /* alle particles genereren */
584         if(paf->keys) MEM_freeN(paf->keys);
585         paf->keys= 0;
586         new_particle(paf);      
587
588         cfraont= G.scene->r.cfra;
589         cfralast= -1000;
590         framelenont= G.scene->r.framelen;
591         G.scene->r.framelen= 1.0;
592         sfraont= ob->sf;
593         ob->sf= 0.0;
594         
595         /* mult generaties? */
596         totpart= paf->totpart;
597         for(a=0; a<PAF_MAXMULT; a++) {
598                 if(paf->mult[a]!=0.0) {
599                         /* interessante formule! opdezewijze is na 'x' generaties het totale aantal paf->totpart */
600                         totpart= (int)(totpart / (1.0+paf->mult[a]*paf->child[a]));
601                 }
602                 else break;
603         }
604
605         ftime= paf->sta;
606         dtime= (paf->end - paf->sta)/totpart;
607         
608         /* hele hiera onthouden */
609         par= ob;
610         while(par) {
611                 pushdata(par, sizeof(Object));
612                 par= par->parent;
613         }
614
615         /* alles op eerste frame zetten */
616         G.scene->r.cfra= cfralast= (int)floor(ftime);
617         par= ob;
618         while(par) {
619                 /* do_ob_ipo(par); */
620                 do_ob_key(par);
621                 par= par->parent;
622         }
623         do_mat_ipo(ma);
624         
625         if((paf->flag & PAF_STATIC)==0) {
626                 where_is_object(ob);
627                 Mat4CpyMat4(prevobmat, ob->obmat);
628                 Mat4Invert(ob->imat, ob->obmat);
629                 Mat3CpyMat4(imat, ob->imat);
630         }
631         else {
632                 Mat4One(prevobmat);
633                 Mat3One(imat);
634         }
635         
636         BLI_srand(paf->seed);
637         
638         /* gaat anders veuls te hard */
639         force[0]= paf->force[0]*0.05f;
640         force[1]= paf->force[1]*0.05f;
641         force[2]= paf->force[2]*0.05f;
642         
643         deform= (ob->parent && ob->parent->type==OB_LATTICE);
644         if(deform) init_latt_deform(ob->parent, 0);
645         
646         /* init */
647         give_mesh_mvert(me, totpart, co, no);
648         
649         for(a=0; a<totpart; a++, ftime+=dtime) {
650                 
651                 pa= new_particle(paf);
652                 pa->time= ftime;
653                 
654                 /* ob op juiste tijd zetten */
655                 
656                 if((paf->flag & PAF_STATIC)==0) {
657                 
658                         cur= (int)floor(ftime) + 1 ;            /* + 1 heeft een reden: (obmat/prevobmat) anders beginnen b.v. komeetstaartjes te laat */
659                         if(cfralast != cur) {
660                                 G.scene->r.cfra= cfralast= cur;
661         
662                                 /* later bijgevoegd: blur? */
663                                 bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
664                                 
665                                 par= ob;
666                                 while(par) {
667                                         /* do_ob_ipo(par); */
668                                         par->ctime= -1234567.0;
669                                         do_ob_key(par);
670                                         par= par->parent;
671                                 }
672                                 do_mat_ipo(ma);
673                                 Mat4CpyMat4(prevobmat, ob->obmat);
674                                 where_is_object(ob);
675                                 Mat4Invert(ob->imat, ob->obmat);
676                                 Mat3CpyMat4(imat, ob->imat);
677                         }
678                 }
679                 /* coordinaat ophalen */
680                 if(paf->flag & PAF_FACE) give_mesh_mvert(me, a, co, no);
681                 else {
682                         mvert= me->mvert + (a % me->totvert);
683                         VECCOPY(co, mvert->co);
684                         VECCOPY(no, mvert->no);
685                 }
686                 
687                 VECCOPY(pa->co, co);
688                 
689                 if(paf->flag & PAF_STATIC);
690                 else {
691                         Mat4MulVecfl(ob->obmat, pa->co);
692                 
693                         VECCOPY(vec, co);
694                         Mat4MulVecfl(prevobmat, vec);
695                         
696                         /* eerst even startsnelheid: object */
697                         VecSubf(pa->no, pa->co, vec);
698                         VecMulf(pa->no, paf->obfac);
699                         
700                         /* nu juiste interframe co berekenen */ 
701                         fac= (ftime- (float)floor(ftime));
702                         pa->co[0]= fac*pa->co[0] + (1.0f-fac)*vec[0];
703                         pa->co[1]= fac*pa->co[1] + (1.0f-fac)*vec[1];
704                         pa->co[2]= fac*pa->co[2] + (1.0f-fac)*vec[2];
705                 }
706                 
707                 /* startsnelheid: normaal */
708                 if(paf->normfac!=0.0) {
709                         /* sp= mvert->no; */
710                                 /* transpose ! */
711                         vec[0]= imat[0][0]*no[0] + imat[0][1]*no[1] + imat[0][2]*no[2];
712                         vec[1]= imat[1][0]*no[0] + imat[1][1]*no[1] + imat[1][2]*no[2];
713                         vec[2]= imat[2][0]*no[0] + imat[2][1]*no[1] + imat[2][2]*no[2];         
714                 
715                         Normalise(vec);
716                         VecMulf(vec, paf->normfac);
717                         VecAddf(pa->no, pa->no, vec);
718                 }
719                 pa->lifetime= paf->lifetime;
720                 if(paf->randlife!=0.0) {
721                         pa->lifetime*= 1.0f+ (float)(paf->randlife*( BLI_drand() - 0.5));
722                 }
723                 pa->mat_nr= 1;
724                 
725                 make_particle_keys(0, a, paf, pa, force, deform, mtexmove);
726         }
727         
728         if(deform) end_latt_deform();
729                 
730         /* restore */
731         G.scene->r.cfra= cfraont;
732         G.scene->r.framelen= framelenont;
733         give_mesh_mvert(0, 0, 0, 0);
734
735
736         /* hele hiera terug */
737         par= ob;
738         while(par) {
739                 popfirst(par);
740                 /* geen ob->ipo doen: insertkey behouden */
741                 do_ob_key(par);
742                 par= par->parent;
743         }
744
745         /* restore: NA popfirst */
746         ob->sf= sfraont;
747
748         disable_speed_curve(0);
749
750         waitcursor(0);
751
752 }
753
754 /* ************* WAVE **************** */
755
756 void calc_wave_deform(WaveEff *wav, float ctime, float *co)
757 {
758         /* co is in lokale coords */
759         float lifefac, x, y, amplit;
760         
761         /* mag eigenlijk niet voorkomen */
762         if((wav->flag & (WAV_X+WAV_Y))==0) return;      
763
764         lifefac= wav->height;
765         
766         if( wav->lifetime!=0.0) {
767                 x= ctime - wav->timeoffs;
768                 if(x>wav->lifetime) {
769                         
770                         lifefac= x-wav->lifetime;
771                         
772                         if(lifefac > wav->damp) lifefac= 0.0;
773                         else lifefac= (float)(wav->height*(1.0 - sqrt(lifefac/wav->damp)));
774                 }
775         }
776         if(lifefac==0.0) return;
777
778         x= co[0]-wav->startx;
779         y= co[1]-wav->starty;
780
781         if(wav->flag & WAV_X) {
782                 if(wav->flag & WAV_Y) amplit= (float)sqrt( (x*x + y*y));
783                 else amplit= x;
784         }
785         else amplit= y;
786         
787         /* zo maaktie mooie cirkels */
788         amplit-= (ctime-wav->timeoffs)*wav->speed;
789
790         if(wav->flag & WAV_CYCL) {
791                 amplit = (float)fmod(amplit-wav->width, 2.0*wav->width) + wav->width;
792         }
793
794         /* GAUSSIAN */
795         
796         if(amplit> -wav->width && amplit<wav->width) {
797         
798                 amplit = amplit*wav->narrow;
799                 amplit= (float)(1.0/exp(amplit*amplit) - wav->minfac);
800
801                 co[2]+= lifefac*amplit;
802         }
803 }
804
805 void object_wave(Object *ob)
806 {
807         WaveEff *wav;
808         DispList *dl;
809         Mesh *me;
810         MVert *mvert;
811         float *fp, ctime;
812         int a, first;
813         
814         /* is er een mave */
815         wav= ob->effect.first;
816         while(wav) {
817                 if(wav->type==EFF_WAVE) break;
818                 wav= wav->next;
819         }
820         if(wav==0) return;
821         
822         if(ob->type==OB_MESH) {
823
824                 ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, 0.0);
825                 first= 1;
826                 
827                 me= ob->data;
828                 dl= find_displist_create(&ob->disp, DL_VERTS);
829
830                 if(dl->verts) MEM_freeN(dl->verts);
831                 dl->nr= me->totvert;
832                 dl->verts= MEM_mallocN(3*4*me->totvert, "wave");
833
834                 wav= ob->effect.first;
835                 while(wav) {
836                         if(wav->type==EFF_WAVE) {
837                                 
838                                 /* voorberekenen */
839                                 wav->minfac= (float)(1.0/exp(wav->width*wav->narrow*wav->width*wav->narrow));
840                                 if(wav->damp==0) wav->damp= 10.0f;
841                                 
842                                 mvert= me->mvert;
843                                 fp= dl->verts;
844                                 
845                                 for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
846                                         if(first) VECCOPY(fp, mvert->co);
847                                         calc_wave_deform(wav, ctime, fp);
848                                 }
849                                 first= 0;
850                         }
851                         wav= wav->next;
852                 }
853         }
854 }