"Particle" texture coordinates for halo materials:
authorJanne Karhu <jhkarh@gmail.com>
Tue, 7 Dec 2010 12:58:25 +0000 (12:58 +0000)
committerJanne Karhu <jhkarh@gmail.com>
Tue, 7 Dec 2010 12:58:25 +0000 (12:58 +0000)
* Particle age can now be used as the texture x-coordinate, and location in a particle trail as the y-coordinate.
* This finally enables particles in 2.5 to change their color (or any other texturable material property) by their age.
* In 2.4x this was accomplished with the "100 frames == particle age", but this was both non-intuitive and slow as the animation system had to be recalculated for every particle.
* Currently these are 2d coordinates (age/lifetime == x-coordinate, trail particle index/number of trail particles == y-coordinate), but other particle properties or possibly even a user definable property can be added as coordinates in the future.
* On the code side this uses the same coordinate definition number (for halo materials) as strand coordinates (for surface materials). This is also nice as they intuitively mean nearly the same thing, i.e. along strand or during particle life.

source/blender/makesdna/DNA_material_types.h
source/blender/makesrna/intern/rna_material.c
source/blender/render/intern/include/renderdatabase.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/renderdatabase.c

index f8eb6e76693ed6b1919a80cb974af350d1ee63d9..5a117d59f8acaba39b5df61aaac370eeed2554d8 100644 (file)
@@ -300,6 +300,7 @@ typedef struct Material {
 #define TEXCO_TANGENT  4096
        /* still stored in vertex->accum, 1 D */
 #define TEXCO_STRAND   8192
+#define TEXCO_PARTICLE 8192 /* strand is used for normal materials, particle for halo materials */
 #define TEXCO_STRESS   16384
 #define TEXCO_SPEED            32768
 
index ec2e34fa0b6efca543dd8bf2143560570f4d12af..a964a07ac16cf4e56cda02d4fc0c318f0744188f 100644 (file)
@@ -40,7 +40,7 @@ static EnumPropertyItem prop_texture_coordinates_items[] = {
 {TEXCO_OBJECT, "OBJECT", 0, "Object", "Uses linked object's coordinates for texture coordinates"},
 {TEXCO_UV, "UV", 0, "UV", "Uses UV coordinates for texture coordinates"},
 {TEXCO_ORCO, "ORCO", 0, "Generated", "Uses the original undeformed coordinates of the object"},
-{TEXCO_STRAND, "STRAND", 0, "Strand", "Uses normalized strand texture coordinate (1D)"},
+{TEXCO_STRAND, "STRAND", 0, "Strand / Particle", "Uses normalized strand texture coordinate (1D) or particle age (X) and trail position (Y)"},
 {TEXCO_STICKY, "STICKY", 0, "Sticky", "Uses mesh's sticky coordinates for the texture coordinates"},
 {TEXCO_WINDOW, "WINDOW", 0, "Window", "Uses screen coordinates as texture coordinates"},
 {TEXCO_NORM, "NORMAL", 0, "Normal", "Uses normal vector as texture coordinates"},
index 4c80616665d038e8dde30768ff7f4be09435c12b..8ef68d4a5c1b6d1d7d9fbf1d137c0be6983a88ce 100644 (file)
@@ -96,7 +96,7 @@ struct VertRen *RE_findOrAddVert(struct ObjectRen *obr, int nr);
 struct StrandRen *RE_findOrAddStrand(struct ObjectRen *obr, int nr);
 struct HaloRen *RE_findOrAddHalo(struct ObjectRen *obr, int nr);
 struct HaloRen *RE_inithalo(struct Render *re, struct ObjectRen *obr, struct Material *ma, float *vec, float *vec1, float *orco, float hasize,  float vectsize, int seed);
-struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, struct Material *ma,   float *vec,   float *vec1, float *orco, float *uvco, float hasize, float vectsize, int seed);
+struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, struct DerivedMesh *dm, struct Material *ma,   float *vec,   float *vec1, float *orco, float *uvco, float hasize, float vectsize, int seed, float *pa_co);
 struct StrandBuffer *RE_addStrandBuffer(struct ObjectRen *obr, int totvert);
 
 struct ObjectRen *RE_addRenderObject(struct Render *re, struct Object *ob, struct Object *par, int index, int psysindex, int lay);
index 6fec75c5e42b369e3775ce72d6bf8d7101a597d0..e22e916fe869b56002b485dd42a4bd1b232d5782 100644 (file)
@@ -1252,14 +1252,14 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float
 
 }
 
-static void particle_curve(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, float *loc, float *loc1, int seed)
+static void particle_curve(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, float *loc, float *loc1, int seed, float *pa_co)
 {
        HaloRen *har=0;
 
        if(ma->material_type == MA_TYPE_WIRE)
                static_particle_wire(obr, ma, loc, loc1, sd->first, sd->line);
        else if(ma->material_type == MA_TYPE_HALO) {
-               har= RE_inithalo_particle(re, obr, dm, ma, loc, loc1, sd->orco, sd->uvco, sd->size, 1.0, seed);
+               har= RE_inithalo_particle(re, obr, dm, ma, loc, loc1, sd->orco, sd->uvco, sd->size, 1.0, seed, pa_co);
                if(har) har->lay= obr->ob->lay;
        }
        else
@@ -1387,7 +1387,7 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Particl
                mtf->uv[3][1] = uvy;
        }
 }
-static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, ParticleBillboardData *bb, ParticleKey *state, int seed, float hasize)
+static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, ParticleBillboardData *bb, ParticleKey *state, int seed, float hasize, float *pa_co)
 {
        float loc[3], loc0[3], loc1[3], vel[3];
        
@@ -1412,7 +1412,7 @@ static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re
                        VECADDFAC(loc0, loc, vel, -part->draw_line[0]);
                        VECADDFAC(loc1, loc, vel, part->draw_line[1]);
 
-                       particle_curve(re, obr, dm, ma, sd, loc0, loc1, seed);
+                       particle_curve(re, obr, dm, ma, sd, loc0, loc1, seed, pa_co);
 
                        break;
 
@@ -1429,7 +1429,7 @@ static void particle_normal_ren(short ren_as, ParticleSettings *part, Render *re
                {
                        HaloRen *har=0;
 
-                       har = RE_inithalo_particle(re, obr, dm, ma, loc, NULL, sd->orco, sd->uvco, hasize, 0.0, seed);
+                       har = RE_inithalo_particle(re, obr, dm, ma, loc, NULL, sd->orco, sd->uvco, hasize, 0.0, seed, pa_co);
                        
                        if(har) har->lay= obr->ob->lay;
 
@@ -1497,7 +1497,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
        float strandlen=0.0f, curlen=0.0f;
        float hasize, pa_size, r_tilt, r_length, cfra= BKE_curframe(re->scene);
        float pa_time, pa_birthtime, pa_dietime;
-       float random, simplify[2];
+       float random, simplify[2], pa_co[3];
        int i, a, k, max_k=0, totpart, dosimplify = 0, dosurfacecache = 0;
        int totchild=0;
        int seed, path_nbr=0, orco1=0, num;
@@ -1718,20 +1718,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                        pa_time=(cfra-pa->time)/pa->lifetime;
                        pa_birthtime = pa->time;
                        pa_dietime = pa->dietime;
-#if 0 // XXX old animation system
-                       if((part->flag&PART_ABS_TIME) == 0){
-                               if(ma->ipo) {
-                                       /* correction for lifetime */
-                                       calc_ipo(ma->ipo, 100.0f * pa_time);
-                                       execute_ipo((ID *)ma, ma->ipo);
-                               }
-                               if(part->ipo){
-                                       /* correction for lifetime */
-                                       calc_ipo(part->ipo, 100.0f*pa_time);
-                                       execute_ipo((ID *)part, part->ipo);
-                               }
-                       }
-#endif // XXX old animation system
 
                        hasize = ma->hasize;
 
@@ -1779,22 +1765,6 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                        }
                        
                        pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
-
-#if 0 // XXX old animation system
-                       if((part->flag & PART_ABS_TIME) == 0) {
-                               if(ma->ipo){
-                                       /* correction for lifetime */
-                                       calc_ipo(ma->ipo, 100.0f * pa_time);
-                                       execute_ipo((ID *)ma, ma->ipo);
-                               }
-                               if(part->ipo) {
-                                       /* correction for lifetime */
-                                       calc_ipo(part->ipo, 100.0f * pa_time);
-                                       execute_ipo((ID *)part, part->ipo);
-                               }
-                       }
-#endif // XXX old animation system
-
                        pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time);
 
                        r_tilt = 2.0f*(PSYS_FRAND(a + 21) - 0.5f);
@@ -1842,6 +1812,11 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                        }
                }
 
+               /* TEXCO_PARTICLE */
+               pa_co[0] = pa_time;
+               pa_co[1] = 0.f;
+               pa_co[2] = 0.f;
+
                /* surface normal shading setup */
                if(ma->mode_l & MA_STR_SURFDIFF) {
                        mul_m3_v3(nmat, nor);
@@ -1934,14 +1909,14 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                                                VECSUB(loc0,loc1,loc);
                                                VECADD(loc0,loc1,loc0);
 
-                                               particle_curve(re, obr, psmd->dm, ma, &sd, loc1, loc0, seed);
+                                               particle_curve(re, obr, psmd->dm, ma, &sd, loc1, loc0, seed, pa_co);
                                        }
 
                                        sd.first = 0;
                                        sd.time = time;
 
                                        if(k)
-                                               particle_curve(re, obr, psmd->dm, ma, &sd, loc, loc1, seed);
+                                               particle_curve(re, obr, psmd->dm, ma, &sd, loc, loc1, seed, pa_co);
 
                                        VECCOPY(loc1,loc);
                                }
@@ -1978,7 +1953,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                                                bb.num = a;
                                        }
 
-                                       particle_normal_ren(part->ren_as, part, re, obr, psmd->dm, ma, &sd, &bb, &state, seed, hasize);
+                                       pa_co[0] = (part->draw & PART_ABS_PATH_TIME) ? (ct-pa_birthtime)/(pa_dietime-pa_birthtime) : ct;
+                                       pa_co[1] = (float)i/(float)(trail_count-1);
+
+                                       particle_normal_ren(part->ren_as, part, re, obr, psmd->dm, ma, &sd, &bb, &state, seed, hasize, pa_co);
                                }
                        }
                        else {
@@ -1998,7 +1976,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                                        bb.num = a;
                                }
 
-                               particle_normal_ren(part->ren_as, part, re, obr, psmd->dm, ma, &sd, &bb, &state, seed, hasize);
+                               particle_normal_ren(part->ren_as, part, re, obr, psmd->dm, ma, &sd, &bb, &state, seed, hasize, pa_co);
                        }
                }
 
index 9c2a3c143af4533c2d038e0c6ac63014e8d341bb..979d221dae06a57b1287a2c6b9b5084b576cb5f7 100644 (file)
@@ -1042,7 +1042,7 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,   float *vec,   f
 }
 
 HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma,   float *vec,   float *vec1, 
-                                 float *orco, float *uvco, float hasize, float vectsize, int seed)
+                                 float *orco, float *uvco, float hasize, float vectsize, int seed, float *pa_co)
 {
        HaloRen *har;
        MTex *mtex;
@@ -1147,6 +1147,12 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
                                texvec[1]=2.0f*uvco[2*uv_index+1]-1.0f;
                                texvec[2]=0.0f;
                        }
+                       else if(mtex->texco & TEXCO_PARTICLE) {
+                               /* particle coordinates in range [0,1] */
+                               texvec[0] = 2.f * pa_co[0] - 1.f;
+                               texvec[1] = 2.f * pa_co[1] - 1.f;
+                               texvec[2] = pa_co[2];
+                       }
                        else if(orco) {
                                VECCOPY(texvec, orco);
                        }