7 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
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
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.
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.
26 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
27 * All rights reserved.
29 * The Original Code is: all of this file.
31 * Contributor(s): none yet.
33 * ***** END GPL/BL DUAL LICENSE BLOCK *****
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"
51 #include "BLI_blenlib.h"
52 #include "BLI_arithb.h"
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"
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"
70 Effect *add_effect(int type)
80 bld= MEM_callocN(sizeof(BuildEff), "neweff");
88 paf= MEM_callocN(sizeof(PartEff), "neweff");
94 for(a=0; a<PAF_MAXMULT; a++) {
103 paf->defvec[2]= 1.0f;
109 wav= MEM_callocN(sizeof(WaveEff), "neweff");
112 wav->flag |= (WAV_X+WAV_Y+WAV_CYCL);
124 eff->type= eff->buttype= type;
130 void free_effect(Effect *eff)
134 if(eff->type==EFF_PARTICLE) {
136 if(paf->keys) MEM_freeN(paf->keys);
142 void free_effects(ListBase *lb)
148 BLI_remlink(lb, eff);
154 Effect *copy_effect(Effect *eff)
158 effn= MEM_dupallocN(eff);
159 if(effn->type==EFF_PARTICLE) ((PartEff *)effn)->keys= 0;
164 void copy_act_effect(Object *ob)
166 /* return de aktieve eff gekopieerd */
169 eff= ob->effect.first;
171 if(eff->flag & SELECT) {
173 effn= copy_effect(eff);
174 BLI_addtail(&ob->effect, effn);
176 eff->flag &= ~SELECT;
183 /* als tie hier komt: new effect */
184 eff= add_effect(EFF_BUILD);
185 BLI_addtail(&ob->effect, eff);
189 void copy_effects(ListBase *lbn, ListBase *lb)
193 lbn->first= lbn->last= 0;
197 effn= copy_effect(eff);
198 BLI_addtail(lbn, effn);
205 void deselectall_eff(Object *ob)
207 Effect *eff= ob->effect.first;
210 eff->flag &= ~SELECT;
215 void set_buildvars(Object *ob, int *start, int *end)
220 bld= ob->effect.first;
222 if(bld->type==EFF_BUILD) {
223 ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, bld->sfra-1.0f);
227 else if(ctime < bld->len) {
228 *end= *start+ (int)((*end - *start)*ctime/bld->len);
237 /* ***************** PARTICLES ***************** */
239 Particle *new_particle(PartEff *paf)
244 /* afspraak: als paf->keys==0: alloc */
246 pa= paf->keys= MEM_callocN( paf->totkey*paf->totpart*sizeof(Particle), "particlekeys" );
250 if(cur && cur<paf->totpart) pa+=paf->totkey;
256 PartEff *give_parteff(Object *ob)
260 paf= ob->effect.first;
262 if(paf->type==EFF_PARTICLE) return paf;
268 void where_is_particle(PartEff *paf, Particle *pa, float ctime, float *vec)
275 VECCOPY(vec, pa->co);
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;
285 if(a>0) p[0]= pa-1; else p[0]= pa;
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];
291 if(p[1]==p[2]) dt= 0.0;
292 else dt= (ctime-p[1]->time)/(p[2]->time - p[1]->time);
294 if(paf->flag & PAF_BSPLINE) set_four_ipo(dt, t, KEY_BSPLINE);
295 else set_four_ipo(dt, t, KEY_CARDINAL);
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];
304 void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no)
306 extern float Tin, Tr, Tg, Tb;
311 if(paf->texmap==PAF_TEXINT) {
313 no[0]+= Tin*paf->defvec[0];
314 no[1]+= Tin*paf->defvec[1];
315 no[2]+= Tin*paf->defvec[2];
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;
322 else { /* PAF_TEXGRAD */
327 no[0]+= (old-Tin)*paf->texfac;
332 no[1]+= (old-Tin)*paf->texfac;
337 no[2]+= (old-Tin)*paf->texfac;
342 void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *force, int deform, MTex *mtex)
344 Particle *pa, *opa = NULL;
345 float damp, deltalife;
348 damp= 1.0f-paf->damp;
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));
358 /* startsnelheid: texture */
359 if(mtex && paf->texfac!=0.0) {
360 particle_tex(mtex, paf, pa->co, pa->no);
366 deltalife= pa->lifetime/(paf->totkey-1);
373 pa->time= opa->time+deltalife;
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];
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];
385 /* snelheid: texture */
386 if(mtex && paf->texfac!=0.0) {
387 particle_tex(mtex, paf, pa->co, pa->no);
397 /* opa wordt onderin ook gebruikt */
402 /* alle keys deformen */
406 calc_latt_deform(pa->co);
411 /* de grote vermenigvuldiging */
412 if(depth<PAF_MAXMULT && paf->mult[depth]!=0.0) {
414 /* uit gemiddeld 'mult' deel van de particles ontstaan 'child' nieuwe */
416 rt1= (int)(damp*paf->mult[depth]);
417 rt2= (int)((damp+1.0)*paf->mult[depth]);
420 for(b=0; b<paf->child[depth]; b++) {
421 pa= new_particle(paf);
423 pa->lifetime= paf->life[depth];
424 if(paf->randlife!=0.0) {
425 pa->lifetime*= 1.0f+ (float)(paf->randlife*( BLI_drand() - 0.5));
427 pa->mat_nr= paf->mat[depth];
429 make_particle_keys(depth+1, b, paf, pa, force, deform, mtex);
435 void init_mv_jit(float *jit, int num)
437 float *jit2, x, rad1, rad2, rad3;
442 rad1= (float)(1.0/sqrt((float)num));
443 rad2= (float)(1.0/((float)num));
444 rad3= (float)sqrt((float)num)/((float)num);
446 BLI_srand(31415926 + num);
448 for(i=0; i<2*num; i+=2) {
450 jit[i]= x+ (float)(rad1*(0.5-BLI_drand()));
451 jit[i+1]= ((float)i/2)/num +(float)(rad1*(0.5-BLI_drand()));
453 jit[i]-= (float)floor(jit[i]);
454 jit[i+1]-= (float)floor(jit[i+1]);
457 x -= (float)floor(x);
460 jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
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);
471 void give_mesh_mvert(Mesh *me, int nr, float *co, short *no)
474 static int jitlevel=1;
477 float u, v, *v1, *v2, *v3, *v4;
479 short *n1, *n2, *n3, *n4;
483 if(jit) MEM_freeN(jit);
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);
498 jitlevel= nr/me->totface;
499 if(jitlevel==0) jitlevel= 1;
500 if(jitlevel>100) jitlevel= 100;
502 jit= MEM_callocN(2+ jitlevel*2*sizeof(float), "jit");
503 init_mv_jit(jit, jitlevel);
507 curjit= nr/me->totface;
508 curjit= curjit % jitlevel;
510 curface= nr % me->totface;
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;
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;
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;
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;
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]);
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]);
553 void build_particle_system(Object *ob)
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;
567 if(ob->type!=OB_MESH) return;
569 if(me->totvert==0) return;
571 ma= give_current_material(ob, 1);
573 mtexmove= ma->mtex[7];
576 paf= give_parteff(ob);
581 disable_speed_curve(1);
583 /* alle particles genereren */
584 if(paf->keys) MEM_freeN(paf->keys);
588 cfraont= G.scene->r.cfra;
590 framelenont= G.scene->r.framelen;
591 G.scene->r.framelen= 1.0;
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]));
606 dtime= (paf->end - paf->sta)/totpart;
608 /* hele hiera onthouden */
611 pushdata(par, sizeof(Object));
615 /* alles op eerste frame zetten */
616 G.scene->r.cfra= cfralast= (int)floor(ftime);
619 /* do_ob_ipo(par); */
625 if((paf->flag & PAF_STATIC)==0) {
627 Mat4CpyMat4(prevobmat, ob->obmat);
628 Mat4Invert(ob->imat, ob->obmat);
629 Mat3CpyMat4(imat, ob->imat);
636 BLI_srand(paf->seed);
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;
643 deform= (ob->parent && ob->parent->type==OB_LATTICE);
644 if(deform) init_latt_deform(ob->parent, 0);
647 give_mesh_mvert(me, totpart, co, no);
649 for(a=0; a<totpart; a++, ftime+=dtime) {
651 pa= new_particle(paf);
654 /* ob op juiste tijd zetten */
656 if((paf->flag & PAF_STATIC)==0) {
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;
662 /* later bijgevoegd: blur? */
663 bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
667 /* do_ob_ipo(par); */
668 par->ctime= -1234567.0;
673 Mat4CpyMat4(prevobmat, ob->obmat);
675 Mat4Invert(ob->imat, ob->obmat);
676 Mat3CpyMat4(imat, ob->imat);
679 /* coordinaat ophalen */
680 if(paf->flag & PAF_FACE) give_mesh_mvert(me, a, co, no);
682 mvert= me->mvert + (a % me->totvert);
683 VECCOPY(co, mvert->co);
684 VECCOPY(no, mvert->no);
689 if(paf->flag & PAF_STATIC);
691 Mat4MulVecfl(ob->obmat, pa->co);
694 Mat4MulVecfl(prevobmat, vec);
696 /* eerst even startsnelheid: object */
697 VecSubf(pa->no, pa->co, vec);
698 VecMulf(pa->no, paf->obfac);
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];
707 /* startsnelheid: normaal */
708 if(paf->normfac!=0.0) {
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];
716 VecMulf(vec, paf->normfac);
717 VecAddf(pa->no, pa->no, vec);
719 pa->lifetime= paf->lifetime;
720 if(paf->randlife!=0.0) {
721 pa->lifetime*= 1.0f+ (float)(paf->randlife*( BLI_drand() - 0.5));
725 make_particle_keys(0, a, paf, pa, force, deform, mtexmove);
728 if(deform) end_latt_deform();
731 G.scene->r.cfra= cfraont;
732 G.scene->r.framelen= framelenont;
733 give_mesh_mvert(0, 0, 0, 0);
736 /* hele hiera terug */
740 /* geen ob->ipo doen: insertkey behouden */
745 /* restore: NA popfirst */
748 disable_speed_curve(0);
754 /* ************* WAVE **************** */
756 void calc_wave_deform(WaveEff *wav, float ctime, float *co)
758 /* co is in lokale coords */
759 float lifefac, x, y, amplit;
761 /* mag eigenlijk niet voorkomen */
762 if((wav->flag & (WAV_X+WAV_Y))==0) return;
764 lifefac= wav->height;
766 if( wav->lifetime!=0.0) {
767 x= ctime - wav->timeoffs;
768 if(x>wav->lifetime) {
770 lifefac= x-wav->lifetime;
772 if(lifefac > wav->damp) lifefac= 0.0;
773 else lifefac= (float)(wav->height*(1.0 - sqrt(lifefac/wav->damp)));
776 if(lifefac==0.0) return;
778 x= co[0]-wav->startx;
779 y= co[1]-wav->starty;
781 if(wav->flag & WAV_X) {
782 if(wav->flag & WAV_Y) amplit= (float)sqrt( (x*x + y*y));
787 /* zo maaktie mooie cirkels */
788 amplit-= (ctime-wav->timeoffs)*wav->speed;
790 if(wav->flag & WAV_CYCL) {
791 amplit = (float)fmod(amplit-wav->width, 2.0*wav->width) + wav->width;
796 if(amplit> -wav->width && amplit<wav->width) {
798 amplit = amplit*wav->narrow;
799 amplit= (float)(1.0/exp(amplit*amplit) - wav->minfac);
801 co[2]+= lifefac*amplit;
805 void object_wave(Object *ob)
815 wav= ob->effect.first;
817 if(wav->type==EFF_WAVE) break;
822 if(ob->type==OB_MESH) {
824 ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, 0.0);
828 dl= find_displist_create(&ob->disp, DL_VERTS);
830 if(dl->verts) MEM_freeN(dl->verts);
832 dl->verts= MEM_mallocN(3*4*me->totvert, "wave");
834 wav= ob->effect.first;
836 if(wav->type==EFF_WAVE) {
839 wav->minfac= (float)(1.0/exp(wav->width*wav->narrow*wav->width*wav->narrow));
840 if(wav->damp==0) wav->damp= 10.0f;
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);