Recoded particles initial rotations to allow much more flexible settings.
authorJanne Karhu <jhkarh@gmail.com>
Tue, 1 Jan 2008 01:00:05 +0000 (01:00 +0000)
committerJanne Karhu <jhkarh@gmail.com>
Tue, 1 Jan 2008 01:00:05 +0000 (01:00 +0000)
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/makesdna/DNA_particle_types.h
source/blender/src/buttons_object.c

index d0bf8b412ef1e5169b9253010a614dc7e589cfa4..82b2d785c8ce0e246a767575e6c01e0d68cf9aec 100644 (file)
@@ -2795,7 +2795,6 @@ static void default_particle_settings(ParticleSettings *part)
        part->disp=100;
        part->from= PART_FROM_FACE;
        part->length= 1.0;
-       part->rotfac= 1.0;
        part->nbetween= 4;
        part->boidneighbours= 5;
 
index 880fb0c1ef67ced01469321a0370c639b1d2be3f..ac06f75737ff714f014a3eab2968997272c22364 100644 (file)
@@ -1533,10 +1533,9 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
        ParticleTexture ptex;
        ParticleKey state;
        IpoCurve *icu=0;
-       float fac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],*q2=0;
+       float fac, rotfac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],*q2=0;
        float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0};
-       float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0};
-
+       float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0};
        float q_one[4]={1.0,0.0,0.0,0.0}, q_phase[4];
        part=psys->part;
 
@@ -1637,7 +1636,7 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
                }
                
                /* -rotation                                                    */
-               if(part->rotmode==PART_ROT_RAND){
+               if(part->randrotfac != 0.0f){
                        QUATCOPY(r_rot,pa->r_rot);
                        Mat4ToQuat(ob->obmat,rot);
                        QuatMul(r_rot,r_rot,rot);
@@ -1688,34 +1687,49 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
        pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0.0;
 
        if(part->rotmode){
+               /* create vector into which rotation is aligned */
                switch(part->rotmode){
                        case PART_ROT_NOR:
-                               VecMulf(nor,-1.0);
-                               q2= vectoquat(nor, OB_POSX, OB_POSZ);
-                               VecMulf(nor,-1.0);
+                               VecCopyf(rot_vec, nor);
                                break;
                        case PART_ROT_VEL:
-                               VecMulf(vel,-1.0);
-                               q2= vectoquat(vel, OB_POSX, OB_POSZ);
-                               VecMulf(vel,-1.0);
+                               VecCopyf(rot_vec, vel);
+                               break;
+                       case PART_ROT_GLOB_X:
+                       case PART_ROT_GLOB_Y:
+                       case PART_ROT_GLOB_Z:
+                               rot_vec[part->rotmode - PART_ROT_GLOB_X] = 1.0f;
                                break;
-                       case PART_ROT_RAND:
-                               q2= r_rot;
+                       case PART_ROT_OB_X:
+                       case PART_ROT_OB_Y:
+                       case PART_ROT_OB_Z:
+                               VecCopyf(rot_vec, ob->obmat[part->rotmode - PART_ROT_OB_X]);
                                break;
                }
-               /* how much to rotate from rest position */
-               QuatInterpol(rot,q_one,q2,part->rotfac);
+               
+               /* create rotation quat */
+               VecMulf(rot_vec,-1.0);
+               q2= vectoquat(rot_vec, OB_POSX, OB_POSZ);
+
+               /* randomize rotation quat */
+               if(part->randrotfac!=0.0f)
+                       QuatInterpol(rot, q2, r_rot, part->randrotfac);
+               else
+                       QuatCopy(rot,q2);
 
-               /* phase */
-               VecRotToQuat(x_vec,part->phasefac*(float)M_PI,q_phase);
+               /* rotation phase */
+               phasefac = part->phasefac;
+               if(part->randphasefac != 0.0f) /* abuse r_ave[0] as a random number */
+                       phasefac += part->randphasefac * pa->r_ave[0];
+               VecRotToQuat(x_vec, phasefac*(float)M_PI, q_phase);
 
-               /* combine amount & phase */
-               QuatMul(pa->state.rot,rot,q_phase);
+               /* combine base rotation & phase */
+               QuatMul(pa->state.rot, rot, q_phase);
        }
 
        /* -angular velocity                                    */
 
-       pa->state.ave[0]=pa->state.ave[1]=pa->state.ave[2]=0.0;
+       pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0;
 
        if(part->avemode){
                switch(part->avemode){
@@ -1736,15 +1750,15 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
                }
        }
 
-       pa->dietime=pa->time+pa->lifetime;
+       pa->dietime = pa->time + pa->lifetime;
 
        if(pa->time >= cfra)
-               pa->alive=PARS_UNBORN;
+               pa->alive = PARS_UNBORN;
 
-       pa->state.time=cfra;
+       pa->state.time = cfra;
 
-       pa->stick_ob=0;
-       pa->flag&=~PARS_STICKY;
+       pa->stick_ob = 0;
+       pa->flag &= ~PARS_STICKY;
 }
 static void reset_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from)
 {
index 942c837df97ba2786a9b0a1816cf78daa09011ac..f83c2a5979953055b03cc88ab6487899bc9d4a76 100644 (file)
@@ -133,13 +133,13 @@ typedef struct ParticleSettings {
 
        /* initial velocity factors */
        float normfac, obfac, randfac, partfac, tanfac, tanphase, reactfac;
-       float rotfac, avefac, phasefac;
+       float avefac, phasefac, randrotfac, randphasefac;
        /* physical properties */
        float mass, size, randsize, reactshape;
        /* global physical properties */
        float acc[3], dragfac, brownfac, dampfac;
        /* length */
-       float length, abslength, randlength, pad;
+       float length, abslength, randlength;
        /* children */
        int child_nbr, ren_child_nbr;
        float parents, childsize, childrandsize;
@@ -355,7 +355,12 @@ typedef struct ParticleSystem{
 /* part->rotmode */
 #define PART_ROT_NOR           1
 #define PART_ROT_VEL           2
-#define PART_ROT_RAND          3
+#define PART_ROT_GLOB_X                3
+#define PART_ROT_GLOB_Y                4
+#define PART_ROT_GLOB_Z                5
+#define PART_ROT_OB_X          6
+#define PART_ROT_OB_Y          7
+#define PART_ROT_OB_Z          8
 
 /* part->avemode */
 #define PART_AVE_SPIN          1
index 8451a4c8afd8a636b6a5e150c906993caef02aec..243681bc800a5496e0bad9652a17e898137ae91b 100644 (file)
@@ -4139,15 +4139,17 @@ static void object_panel_particle_physics(Object *ob)
                uiDefBut(block, LABEL, 0, "Rotation:",  butx, (buty-=buth),butw,buth, NULL, 0.0, 0, 0, 0, "");
                uiBlockBeginAlign(block);
                uiDefButBitI(block, TOG, PART_ROT_DYN, B_PART_RECALC, "Dynamic",         butx,(buty-=buth*4/5),butw/2,buth*4/5, &part->flag, 0, 0, 0, 0, "Sets rotation to dynamic/constant");
-               uiDefButS(block, MENU, B_PART_RECALC, "Rotation %t|Random %x3|Velocity %x2|Normal %x1|None %x0", butx+butw/2,buty,butw/2,buth*4/5, &part->rotmode, 14.0, 0.0, 0, 0, "Select particle rotation mode");
+               uiDefButS(block, MENU, B_PART_RECALC, "Rotation%t|Object Z%x8|Object Y%x7|Object X%x6|Global Z%x5|Global Y%x4|Global X%x3|Velocity%x2|Normal%x1|None%x0", butx+butw/2,buty,butw/2,buth*4/5, &part->rotmode, 14.0, 0.0, 0, 0, "Particles initial rotation");
                uiBlockSetCol(block, TH_BUT_SETTING2);
-               uiDefButF(block, NUM, B_PART_RECALC, "Amount:",         butx,(buty-=buth*4/5),butw,buth*4/5, &part->rotfac, -1.0, 1.0, 1, 3, "Rotation amount");
-               uiDefButF(block, NUM, B_PART_RECALC, "Phase:",                  butx,(buty-=buth*4/5),butw,buth*4/5, &part->phasefac, -1.0, 1.0, 1, 3, "Initial rotation phase");
+               uiDefButF(block, NUM, B_PART_RECALC, "Random:",         butx,(buty-=buth*4/5),butw,buth*4/5, &part->randrotfac, 0.0, 1.0, 1, 3, "Randomize rotation");
+               uiDefButF(block, NUM, B_PART_RECALC, "Phase:",                  butx,(buty-=buth*4/5),butw/2,buth*4/5, &part->phasefac, -1.0, 1.0, 1, 3, "Initial rotation phase");
+               uiDefButF(block, NUM, B_PART_RECALC, "Rand:",                   butx+butw/2,buty,butw/2,buth*4/5, &part->randphasefac, 0.0, 1.0, 1, 3, "Randomize rotation phase");
                uiBlockSetCol(block, TH_AUTO);
 
                uiDefButS(block, MENU, B_PART_RECALC, "Angular v %t|Velocity%x3|Random%x2|Spin%x1|None%x0", butx,(buty-=buth*4/5),butw,buth*4/5, &part->avemode, 14.0, 0.0, 0, 0, "Select particle angular velocity mode");
                uiBlockSetCol(block, TH_BUT_SETTING2);
-               uiDefButF(block, NUM, B_PART_RECALC, "Angular v:",              butx,(buty-=buth*4/5),butw,buth*4/5, &part->avefac, -200.0, 200.0, 1, 3, "Angular velocity amount");
+               if(ELEM(part->avemode,PART_AVE_RAND,PART_AVE_SPIN))
+                       uiDefButF(block, NUM, B_PART_RECALC, "Angular v:",              butx,(buty-=buth*4/5),butw,buth*4/5, &part->avefac, -200.0, 200.0, 1, 3, "Angular velocity amount");
                uiBlockSetCol(block, TH_AUTO);
                uiBlockEndAlign(block);