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"
73 Effect *add_effect(int type)
83 bld= MEM_callocN(sizeof(BuildEff), "neweff");
91 paf= MEM_callocN(sizeof(PartEff), "neweff");
97 for(a=0; a<PAF_MAXMULT; a++) {
106 paf->defvec[2]= 1.0f;
112 wav= MEM_callocN(sizeof(WaveEff), "neweff");
115 wav->flag |= (WAV_X+WAV_Y+WAV_CYCL);
127 eff->type= eff->buttype= type;
133 void free_effect(Effect *eff)
137 if(eff->type==EFF_PARTICLE) {
139 if(paf->keys) MEM_freeN(paf->keys);
145 void free_effects(ListBase *lb)
151 BLI_remlink(lb, eff);
157 Effect *copy_effect(Effect *eff)
161 effn= MEM_dupallocN(eff);
162 if(effn->type==EFF_PARTICLE) ((PartEff *)effn)->keys= 0;
167 void copy_act_effect(Object *ob)
169 /* return de aktieve eff gekopieerd */
172 eff= ob->effect.first;
174 if(eff->flag & SELECT) {
176 effn= copy_effect(eff);
177 BLI_addtail(&ob->effect, effn);
179 eff->flag &= ~SELECT;
186 /* als tie hier komt: new effect */
187 eff= add_effect(EFF_BUILD);
188 BLI_addtail(&ob->effect, eff);
192 void copy_effects(ListBase *lbn, ListBase *lb)
196 lbn->first= lbn->last= 0;
200 effn= copy_effect(eff);
201 BLI_addtail(lbn, effn);
208 void deselectall_eff(Object *ob)
210 Effect *eff= ob->effect.first;
213 eff->flag &= ~SELECT;
218 void set_buildvars(Object *ob, int *start, int *end)
223 bld= ob->effect.first;
225 if(bld->type==EFF_BUILD) {
226 ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, bld->sfra-1.0f);
230 else if(ctime < bld->len) {
231 *end= *start+ (int)((*end - *start)*ctime/bld->len);
240 /* ***************** PARTICLES ***************** */
242 Particle *new_particle(PartEff *paf)
247 /* afspraak: als paf->keys==0: alloc */
249 pa= paf->keys= MEM_callocN( paf->totkey*paf->totpart*sizeof(Particle), "particlekeys" );
253 if(cur && cur<paf->totpart) pa+=paf->totkey;
259 PartEff *give_parteff(Object *ob)
263 paf= ob->effect.first;
265 if(paf->type==EFF_PARTICLE) return paf;
271 void where_is_particle(PartEff *paf, Particle *pa, float ctime, float *vec)
278 VECCOPY(vec, pa->co);
282 /* eerst op zoek naar de eerste particlekey */
283 a= (int)((paf->totkey-1)*(ctime-pa->time)/pa->lifetime);
284 if(a>=paf->totkey) a= paf->totkey-1;
288 if(a>0) p[0]= pa-1; else p[0]= pa;
291 if(a+1<paf->totkey) p[2]= pa+1; else p[2]= pa;
292 if(a+2<paf->totkey) p[3]= pa+2; else p[3]= p[2];
294 if(p[1]==p[2]) dt= 0.0;
295 else dt= (ctime-p[1]->time)/(p[2]->time - p[1]->time);
297 if(paf->flag & PAF_BSPLINE) set_four_ipo(dt, t, KEY_BSPLINE);
298 else set_four_ipo(dt, t, KEY_CARDINAL);
300 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];
301 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];
302 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 void particle_tex(MTex *mtex, PartEff *paf, float *co, float *no)
309 extern float Tin, Tr, Tg, Tb;
314 if(paf->texmap==PAF_TEXINT) {
316 no[0]+= Tin*paf->defvec[0];
317 no[1]+= Tin*paf->defvec[1];
318 no[2]+= Tin*paf->defvec[2];
320 else if(paf->texmap==PAF_TEXRGB) {
321 no[0]+= (Tr-0.5f)*paf->texfac;
322 no[1]+= (Tg-0.5f)*paf->texfac;
323 no[2]+= (Tb-0.5f)*paf->texfac;
325 else { /* PAF_TEXGRAD */
330 no[0]+= (old-Tin)*paf->texfac;
335 no[1]+= (old-Tin)*paf->texfac;
340 no[2]+= (old-Tin)*paf->texfac;
345 void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float *force, int deform, MTex *mtex)
347 Particle *pa, *opa = NULL;
348 float damp, deltalife;
351 damp= 1.0f-paf->damp;
354 /* startsnelheid: random */
355 if(paf->randfac!=0.0) {
356 pa->no[0]+= (float)(paf->randfac*( BLI_drand() -0.5));
357 pa->no[1]+= (float)(paf->randfac*( BLI_drand() -0.5));
358 pa->no[2]+= (float)(paf->randfac*( BLI_drand() -0.5));
361 /* startsnelheid: texture */
362 if(mtex && paf->texfac!=0.0) {
363 particle_tex(mtex, paf, pa->co, pa->no);
366 if(paf->totkey>1) deltalife= pa->lifetime/(paf->totkey-1);
367 else deltalife= pa->lifetime;
375 pa->time= opa->time+deltalife;
378 pa->co[0]= opa->co[0] + deltalife*opa->no[0];
379 pa->co[1]= opa->co[1] + deltalife*opa->no[1];
380 pa->co[2]= opa->co[2] + deltalife*opa->no[2];
382 /* nieuwe snelheid */
383 pa->no[0]= opa->no[0] + deltalife*force[0];
384 pa->no[1]= opa->no[1] + deltalife*force[1];
385 pa->no[2]= opa->no[2] + deltalife*force[2];
387 /* snelheid: texture */
388 if(mtex && paf->texfac!=0.0) {
389 particle_tex(mtex, paf, pa->co, pa->no);
399 /* opa wordt onderin ook gebruikt */
403 /* alle keys deformen */
407 calc_latt_deform(pa->co);
412 /* the big multiplication */
413 if(depth<PAF_MAXMULT && paf->mult[depth]!=0.0) {
415 /* new 'child' emerges from an average 'mult' part from
418 rt1= (int)(damp*paf->mult[depth]);
419 rt2= (int)((damp+1.0)*paf->mult[depth]);
422 for(b=0; b<paf->child[depth]; b++) {
423 pa= new_particle(paf);
425 pa->lifetime= paf->life[depth];
426 if(paf->randlife!=0.0) {
427 pa->lifetime*= 1.0f+ (float)(paf->randlife*( BLI_drand() - 0.5));
429 pa->mat_nr= paf->mat[depth];
431 make_particle_keys(depth+1, b, paf, pa, force, deform, mtex);
437 void init_mv_jit(float *jit, int num)
439 float *jit2, x, rad1, rad2, rad3;
444 rad1= (float)(1.0/sqrt((float)num));
445 rad2= (float)(1.0/((float)num));
446 rad3= (float)sqrt((float)num)/((float)num);
448 BLI_srand(31415926 + num);
451 for(i=0; i<num2; i+=2) {
453 jit[i]= x+ (float)(rad1*(0.5-BLI_drand()));
454 jit[i+1]= ((float)i/2)/num +(float)(rad1*(0.5-BLI_drand()));
456 jit[i]-= (float)floor(jit[i]);
457 jit[i+1]-= (float)floor(jit[i+1]);
460 x -= (float)floor(x);
463 jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
465 for (i=0 ; i<4 ; i++) {
466 RE_jitterate1(jit, jit2, num, rad1);
467 RE_jitterate1(jit, jit2, num, rad1);
468 RE_jitterate2(jit, jit2, num, rad2);
474 void give_mesh_mvert(Mesh *me, int nr, float *co, short *no)
477 static int jitlevel=1;
480 float u, v, *v1, *v2, *v3, *v4;
482 short *n1, *n2, *n3, *n4;
486 if(jit) MEM_freeN(jit);
491 if(me->totface==0 || nr<me->totvert) {
492 mvert= me->mvert + (nr % me->totvert);
493 VECCOPY(co, mvert->co);
494 VECCOPY(no, mvert->no);
501 jitlevel= nr/me->totface;
502 if(jitlevel==0) jitlevel= 1;
503 if(jitlevel>100) jitlevel= 100;
505 jit= MEM_callocN(2+ jitlevel*2*sizeof(float), "jit");
506 init_mv_jit(jit, jitlevel);
510 curjit= nr/me->totface;
511 curjit= curjit % jitlevel;
513 curface= nr % me->totface;
518 v1= (me->mvert+(mface->v1))->co;
519 v2= (me->mvert+(mface->v2))->co;
520 n1= (me->mvert+(mface->v1))->no;
521 n2= (me->mvert+(mface->v2))->no;
523 v3= (me->mvert+(mface->v2))->co;
524 v4= (me->mvert+(mface->v1))->co;
525 n3= (me->mvert+(mface->v2))->no;
526 n4= (me->mvert+(mface->v1))->no;
528 else if(mface->v4==0) {
529 v3= (me->mvert+(mface->v3))->co;
530 v4= (me->mvert+(mface->v1))->co;
531 n3= (me->mvert+(mface->v3))->no;
532 n4= (me->mvert+(mface->v1))->no;
535 v3= (me->mvert+(mface->v3))->co;
536 v4= (me->mvert+(mface->v4))->co;
537 n3= (me->mvert+(mface->v3))->no;
538 n4= (me->mvert+(mface->v4))->no;
544 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]);
545 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]);
546 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]);
548 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]);
549 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]);
550 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]);
556 void build_particle_system(Object *ob)
565 float framelenont, ftime, dtime, force[3], imat[3][3], vec[3];
566 float fac, prevobmat[4][4], sfraont, co[3];
567 int deform=0, a, cur, cfraont, cfralast, totpart;
570 if(ob->type!=OB_MESH) return;
572 if(me->totvert==0) return;
574 ma= give_current_material(ob, 1);
576 mtexmove= ma->mtex[7];
579 paf= give_parteff(ob);
584 disable_speed_curve(1);
586 /* alle particles genereren */
587 if(paf->keys) MEM_freeN(paf->keys);
591 cfraont= G.scene->r.cfra;
593 framelenont= G.scene->r.framelen;
594 G.scene->r.framelen= 1.0;
598 /* mult generaties? */
599 totpart= paf->totpart;
600 for(a=0; a<PAF_MAXMULT; a++) {
601 if(paf->mult[a]!=0.0) {
602 /* interessante formule! opdezewijze is na 'x' generaties het totale aantal paf->totpart */
603 totpart= (int)(totpart / (1.0+paf->mult[a]*paf->child[a]));
609 dtime= (paf->end - paf->sta)/totpart;
611 /* hele hiera onthouden */
614 pushdata(par, sizeof(Object));
618 /* alles op eerste frame zetten */
619 G.scene->r.cfra= cfralast= (int)floor(ftime);
622 /* do_ob_ipo(par); */
628 if((paf->flag & PAF_STATIC)==0) {
630 Mat4CpyMat4(prevobmat, ob->obmat);
631 Mat4Invert(ob->imat, ob->obmat);
632 Mat3CpyMat4(imat, ob->imat);
639 BLI_srand(paf->seed);
641 /* gaat anders veuls te hard */
642 force[0]= paf->force[0]*0.05f;
643 force[1]= paf->force[1]*0.05f;
644 force[2]= paf->force[2]*0.05f;
646 deform= (ob->parent && ob->parent->type==OB_LATTICE);
647 if(deform) init_latt_deform(ob->parent, 0);
650 give_mesh_mvert(me, totpart, co, no);
652 for(a=0; a<totpart; a++, ftime+=dtime) {
654 pa= new_particle(paf);
657 /* ob op juiste tijd zetten */
659 if((paf->flag & PAF_STATIC)==0) {
661 cur= (int)floor(ftime) + 1 ; /* + 1 heeft een reden: (obmat/prevobmat) anders beginnen b.v. komeetstaartjes te laat */
662 if(cfralast != cur) {
663 G.scene->r.cfra= cfralast= cur;
665 /* later bijgevoegd: blur? */
666 bsystem_time(ob, ob->parent, (float)G.scene->r.cfra, 0.0);
670 /* do_ob_ipo(par); */
671 par->ctime= -1234567.0;
676 Mat4CpyMat4(prevobmat, ob->obmat);
678 Mat4Invert(ob->imat, ob->obmat);
679 Mat3CpyMat4(imat, ob->imat);
682 /* coordinaat ophalen */
683 if(paf->flag & PAF_FACE) give_mesh_mvert(me, a, co, no);
685 mvert= me->mvert + (a % me->totvert);
686 VECCOPY(co, mvert->co);
687 VECCOPY(no, mvert->no);
692 if(paf->flag & PAF_STATIC);
694 Mat4MulVecfl(ob->obmat, pa->co);
697 Mat4MulVecfl(prevobmat, vec);
699 /* eerst even startsnelheid: object */
700 VecSubf(pa->no, pa->co, vec);
701 VecMulf(pa->no, paf->obfac);
703 /* nu juiste interframe co berekenen */
704 fac= (ftime- (float)floor(ftime));
705 pa->co[0]= fac*pa->co[0] + (1.0f-fac)*vec[0];
706 pa->co[1]= fac*pa->co[1] + (1.0f-fac)*vec[1];
707 pa->co[2]= fac*pa->co[2] + (1.0f-fac)*vec[2];
710 /* startsnelheid: normaal */
711 if(paf->normfac!=0.0) {
714 vec[0]= imat[0][0]*no[0] + imat[0][1]*no[1] + imat[0][2]*no[2];
715 vec[1]= imat[1][0]*no[0] + imat[1][1]*no[1] + imat[1][2]*no[2];
716 vec[2]= imat[2][0]*no[0] + imat[2][1]*no[1] + imat[2][2]*no[2];
719 VecMulf(vec, paf->normfac);
720 VecAddf(pa->no, pa->no, vec);
722 pa->lifetime= paf->lifetime;
723 if(paf->randlife!=0.0) {
724 pa->lifetime*= 1.0f+ (float)(paf->randlife*( BLI_drand() - 0.5));
728 make_particle_keys(0, a, paf, pa, force, deform, mtexmove);
731 if(deform) end_latt_deform();
734 G.scene->r.cfra= cfraont;
735 G.scene->r.framelen= framelenont;
736 give_mesh_mvert(0, 0, 0, 0);
739 /* hele hiera terug */
743 /* geen ob->ipo doen: insertkey behouden */
748 /* restore: NA popfirst */
751 disable_speed_curve(0);
757 /* ************* WAVE **************** */
759 void calc_wave_deform(WaveEff *wav, float ctime, float *co)
761 /* co is in lokale coords */
762 float lifefac, x, y, amplit;
764 /* mag eigenlijk niet voorkomen */
765 if((wav->flag & (WAV_X+WAV_Y))==0) return;
767 lifefac= wav->height;
769 if( wav->lifetime!=0.0) {
770 x= ctime - wav->timeoffs;
771 if(x>wav->lifetime) {
773 lifefac= x-wav->lifetime;
775 if(lifefac > wav->damp) lifefac= 0.0;
776 else lifefac= (float)(wav->height*(1.0 - sqrt(lifefac/wav->damp)));
779 if(lifefac==0.0) return;
781 x= co[0]-wav->startx;
782 y= co[1]-wav->starty;
784 if(wav->flag & WAV_X) {
785 if(wav->flag & WAV_Y) amplit= (float)sqrt( (x*x + y*y));
790 /* zo maaktie mooie cirkels */
791 amplit-= (ctime-wav->timeoffs)*wav->speed;
793 if(wav->flag & WAV_CYCL) {
794 amplit = (float)fmod(amplit-wav->width, 2.0*wav->width) + wav->width;
799 if(amplit> -wav->width && amplit<wav->width) {
801 amplit = amplit*wav->narrow;
802 amplit= (float)(1.0/exp(amplit*amplit) - wav->minfac);
804 co[2]+= lifefac*amplit;
808 void object_wave(Object *ob)
818 wav= ob->effect.first;
820 if(wav->type==EFF_WAVE) break;
825 if(ob->type==OB_MESH) {
827 ctime= bsystem_time(ob, 0, (float)G.scene->r.cfra, 0.0);
831 dl= find_displist_create(&ob->disp, DL_VERTS);
833 if(dl->verts) MEM_freeN(dl->verts);
835 dl->verts= MEM_mallocN(3*4*me->totvert, "wave");
837 wav= ob->effect.first;
839 if(wav->type==EFF_WAVE) {
842 wav->minfac= (float)(1.0/exp(wav->width*wav->narrow*wav->width*wav->narrow));
843 if(wav->damp==0) wav->damp= 10.0f;
848 for(a=0; a<me->totvert; a++, mvert++, fp+=3) {
849 if(first) VECCOPY(fp, mvert->co);
850 calc_wave_deform(wav, ctime, fp);