Misc Render Features
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 9 Jan 2008 14:40:25 +0000 (14:40 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Wed, 9 Jan 2008 14:40:25 +0000 (14:40 +0000)
====================

- "From Dupli" option for orco and uv texture coordinates. For dupliverts,
  duplifaces and dupli particles, this uses the orco and uv at the point
  on the parent surface. Can for example be used for texturing feathers
  and leafs. Note that uv only works for duplifaces and particles emitted
  from faces, these are not defined at vertices.

- "Width Fade" option for strand render, to fade out along the width of the
  strand. Committing this so it can be tested, might be changed or removed
  even, if it doesn't give nice results.

17 files changed:
source/blender/blenkernel/BKE_anim.h
source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/particle.c
source/blender/makesdna/DNA_material_types.h
source/blender/makesdna/DNA_texture_types.h
source/blender/render/extern/include/RE_shader_ext.h
source/blender/render/intern/include/render_types.h
source/blender/render/intern/include/renderdatabase.h
source/blender/render/intern/source/convertblender.c
source/blender/render/intern/source/imagetexture.c
source/blender/render/intern/source/renderdatabase.c
source/blender/render/intern/source/shadeinput.c
source/blender/render/intern/source/strand.c
source/blender/render/intern/source/texture.c
source/blender/src/buttons_shading.c

index c3e978a5a9a404fbc0aa01056415bbb9f6ea69e3..7b7bd7f87046d770ce27f6e4e1ed1179fc2d206c 100644 (file)
@@ -46,6 +46,7 @@ typedef struct DupliObject {
        unsigned int origlay;
        int index, no_draw, type;
        float mat[4][4], omat[4][4];
+       float orco[3], uv[2];
 } DupliObject;
 
 void free_path(struct Path *path);
index a1ac97406e161659ea54d6976375e9c8f56fca38..d92e8bad1f904c2f7dda159b0a89cd667db43667 100644 (file)
@@ -244,6 +244,8 @@ float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa
 float psys_get_child_size(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *pa_time);
 void psys_get_particle_on_path(struct Object *ob, struct ParticleSystem *psys, int pa_num, struct ParticleKey *state, int vel);
 int psys_get_particle_state(struct Object *ob, struct ParticleSystem *psys, int p, struct ParticleKey *state, int always);
+void psys_get_dupli_texture(struct Object *ob, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco);
+void psys_get_dupli_path_transform(struct Object *ob, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale);
 
 ParticleThread *psys_threads_create(struct Object *ob, struct ParticleSystem *psys, int totthread);
 int psys_threads_init_distribution(ParticleThread *threads, struct DerivedMesh *dm, int from);
index aada60be21b3bd90ec00b0b078af5155d8e6a73d..9ee4e62b9cb1d3d61d90e86f0cd297c6b687cc0e 100644 (file)
@@ -2135,9 +2135,13 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
        }
 
        /* add an orco layer if needed */
-       if(dataMask & CD_MASK_ORCO)
+       if(dataMask & CD_MASK_ORCO) {
                add_orco_dm(ob, finaldm, orcodm);
 
+               if(deform_r && *deform_r)
+                       add_orco_dm(ob, *deform_r, NULL);
+       }
+
        *final_r = finaldm;
 
        if(orcodm)
index 40c776248cff74e30b4581ecee01cc68529fb8da..d20031179bf20ebb7113b284fe64017d0cd5b35e 100644 (file)
@@ -378,10 +378,12 @@ struct vertexDupliData {
        float pmat[4][4];
        float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */
        Object *ob, *par;
+       float (*orco)[3];
 };
 
 static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s)
 {
+       DupliObject *dob;
        struct vertexDupliData *vdd= userData;
        float vec[3], *q2, mat[3][3], tmat[4][4], obmat[4][4];
        
@@ -407,7 +409,9 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n
                Mat4CpyMat4(tmat, obmat);
                Mat4MulMat43(obmat, tmat, mat);
        }
-       new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS);
+       dob= new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS);
+       if(vdd->orco)
+               VECCOPY(dob->orco, vdd->orco[index]);
        
        if(vdd->ob->transflag & OB_DUPLI) {
                float tmpmat[4][4];
@@ -429,16 +433,25 @@ static void vertex_duplilist(ListBase *lb, ID *id, Object *par, float par_space_
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject * go = NULL;
+       CustomDataMask dataMask = CD_MASK_BAREMESH;
        
        Mat4CpyMat4(pmat, par->obmat);
        
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
+
+       if(G.rendering)
+               dataMask |= CD_MASK_ORCO;
        
        if(par==G.obedit)
-               dm= editmesh_get_derived_cage(CD_MASK_BAREMESH);
+               dm= editmesh_get_derived_cage(dataMask);
+       else
+               dm= mesh_get_derived_deform(par, dataMask);
+
+       if(G.rendering)
+               vdd.orco= dm->getVertDataArray(dm, CD_ORCO);
        else
-               dm = mesh_get_derived_deform(par, CD_MASK_BAREMESH);
+               vdd.orco= NULL;
        
        totvert = dm->getNumVerts(dm);
 
@@ -517,25 +530,31 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
 {
        Object *ob, *ob_iter;
        Base *base = NULL;
+       DupliObject *dob;
        DerivedMesh *dm;
+       Mesh *me;
+       MTFace *mtface;
        MFace *mface;
        MVert *mvert;
-       float pmat[4][4], imat[3][3];
+       float pmat[4][4], imat[3][3], (*orco)[3], w;
        int lay, oblay, totface, a;
        Scene *sce = NULL;
        Group *group = NULL;
        GroupObject *go = NULL;
-       
+       CustomDataMask dataMask = CD_MASK_BAREMESH;
        float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
        
        /* simple preventing of too deep nested groups */
        if(level>MAX_DUPLI_RECUR) return;
        
-       Mat4CpyMat4(pmat, par->obmat);
+       if(G.rendering)
+               dataMask |= CD_MASK_ORCO;
        
+       Mat4CpyMat4(pmat, par->obmat);
+
        if(par==G.obedit) {
                int totvert;
-               dm= editmesh_get_derived_cage(CD_MASK_BAREMESH);
+               dm= editmesh_get_derived_cage(dataMask);
                
                totface= dm->getNumFaces(dm);
                mface= MEM_mallocN(sizeof(MFace)*totface, "mface temp");
@@ -545,13 +564,22 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
                dm->copyVertArray(dm, mvert);
        }
        else {
-               dm = mesh_get_derived_deform(par, CD_MASK_BAREMESH);
+               dm = mesh_get_derived_deform(par, dataMask);
                
                totface= dm->getNumFaces(dm);
                mface= dm->getFaceArray(dm);
                mvert= dm->getVertArray(dm);
        }
-       
+
+       if(G.rendering) {
+               me= (Mesh*)par->data;
+               orco= dm->getVertDataArray(dm, CD_ORCO);
+               mtface= me->mtface;
+       }
+       else {
+               orco= NULL;
+               mtface= NULL;
+       }
        
        /* having to loop on scene OR group objects is NOT FUN */
        if (GS(id->name) == ID_SCE) {
@@ -595,10 +623,14 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
                                        if(ob->type!=OB_MBALL) ob->flag |= OB_DONE;     /* doesnt render */
 
                                        for(a=0; a<totface; a++) {
-                                               float *v1= mvert[ mface[a].v1 ].co;
-                                               float *v2= mvert[ mface[a].v2 ].co;
-                                               float *v3= mvert[ mface[a].v3 ].co;
-                                               float *v4= mface[a].v4?mvert[ mface[a].v4 ].co:NULL;
+                                               int mv1 = mface[a].v1;
+                                               int mv2 = mface[a].v2;
+                                               int mv3 = mface[a].v3;
+                                               int mv4 = mface[a].v4;
+                                               float *v1= mvert[mv1].co;
+                                               float *v2= mvert[mv2].co;
+                                               float *v3= mvert[mv3].co;
+                                               float *v4= (mv4)? mvert[mv4].co: NULL;
                                                float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4];
 
                                                /* translation */
@@ -632,7 +664,32 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
                                                Mat4CpyMat4(tmat, obmat);
                                                Mat4MulMat43(obmat, tmat, mat);
                                                
-                                               new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES);
+                                               dob= new_dupli_object(lb, ob, obmat, lay, a, OB_DUPLIFACES);
+                                               if(G.rendering) {
+                                                       w= (mv4)? 0.25f: 1.0f/3.0f;
+
+                                                       if(orco) {
+                                                               VECADDFAC(dob->orco, dob->orco, orco[mv1], w);
+                                                               VECADDFAC(dob->orco, dob->orco, orco[mv2], w);
+                                                               VECADDFAC(dob->orco, dob->orco, orco[mv3], w);
+                                                               if(mv4)
+                                                                       VECADDFAC(dob->orco, dob->orco, orco[mv4], w);
+                                                       }
+
+                                                       if(mtface) {
+                                                               dob->uv[0] += w*mtface[a].uv[0][0];
+                                                               dob->uv[1] += w*mtface[a].uv[0][1];
+                                                               dob->uv[0] += w*mtface[a].uv[1][0];
+                                                               dob->uv[1] += w*mtface[a].uv[1][1];
+                                                               dob->uv[0] += w*mtface[a].uv[2][0];
+                                                               dob->uv[1] += w*mtface[a].uv[2][1];
+
+                                                               if(mv4) {
+                                                                       dob->uv[0] += w*mtface[a].uv[3][0];
+                                                                       dob->uv[1] += w*mtface[a].uv[3][1];
+                                                               }
+                                                       }
+                                               }
                                                
                                                if(ob->transflag & OB_DUPLI) {
                                                        float tmpmat[4][4];
@@ -660,38 +717,14 @@ static void face_duplilist(ListBase *lb, ID *id, Object *par, float par_space_ma
        dm->release(dm);
 }
 
-static void particle_dupli_path_rotation(Object *ob, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale)
-{
-       float loc[3], nor[3], vec[3], side[3], len;
-
-       VecSubf(vec, (cache+cache->steps-1)->co, cache->co);
-       len= Normalize(vec);
-
-       if(pa)
-               psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
-       else
-               psys_particle_on_emitter(ob, psmd,
-                       (part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
-                       cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0);
-       
-       Crossf(side, nor, vec);
-       Normalize(side);
-       Crossf(nor, vec, side);
-
-       Mat4One(mat);
-       VECCOPY(mat[0], vec);
-       VECCOPY(mat[1], side);
-       VECCOPY(mat[2], nor);
-
-       *scale= len;
-}
-
 static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_space_mat[][4], ParticleSystem *psys, int level)
 {
        GroupObject *go;
        Object *ob=0, **oblist=0;
+       DupliObject *dob;
        ParticleSettings *part;
        ParticleData *pa;
+       ChildParticle *cpa=0;
        ParticleKey state;
        ParticleCacheKey *cache;
        ParticleSystemModifierData *psmd;
@@ -773,10 +806,11 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                        }
                        else {
                                /* TODO: figure these two out */
+                               cpa= &psys->child[a - totpart];
                                pa_num = a;
-                               pa_time = psys->particles[psys->child[a - totpart].parent].time;
+                               pa_time = psys->particles[cpa->parent].time;
 
-                               size=psys_get_child_size(psys, &psys->child[a - totpart], ctime, 0);
+                               size=psys_get_child_size(psys, cpa, ctime, 0);
                        }
 
                        if(part->draw_as==PART_DRAW_GR) {
@@ -795,12 +829,11 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                if(hair) {
                                        if(a < totpart) {
                                                cache = psys->pathcache[a];
-                                               particle_dupli_path_rotation(par, part, psmd, pa, 0, cache, pamat, &scale);
+                                               psys_get_dupli_path_transform(par, part, psmd, pa, 0, cache, pamat, &scale);
                                        }
                                        else {
-                                               ChildParticle *cpa= psys->child+(a-totpart);
                                                cache = psys->childcache[a-totpart];
-                                               particle_dupli_path_rotation(par, part, psmd, 0, cpa, cache, pamat, &scale);
+                                               psys_get_dupli_path_transform(par, part, psmd, 0, cpa, cache, pamat, &scale);
                                        }
 
                                        VECCOPY(pamat[3], cache->co);
@@ -833,7 +866,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                                else
                                                        Mat4CpyMat4(mat, tmat);
 
-                                               new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS);
+                                               dob= new_dupli_object(lb, go->ob, mat, par->lay, counter, OB_DUPLIPARTS);
+                                               if(G.rendering)
+                                                       psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
                                        }
                                }
                                else {
@@ -857,7 +892,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Object *par, float par_
                                        else
                                                Mat4CpyMat4(mat, tmat);
 
-                                       new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS);
+                                       dob= new_dupli_object(lb, ob, mat, par->lay, counter, OB_DUPLIPARTS);
+                                       if(G.rendering)
+                                               psys_get_dupli_texture(par, part, psmd, pa, cpa, dob->uv, dob->orco);
                                }
                        }
                }
index 54b8a5c47e64bb57b188370a1b1185be69bd3323..0ac60e6da4e8c82a19646dc76e6523876ba72487 100644 (file)
@@ -3563,3 +3563,78 @@ int psys_get_particle_state(Object *ob, ParticleSystem *psys, int p, ParticleKey
        //}
 }
 
+void psys_get_dupli_texture(Object *ob, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, float *uv, float *orco)
+{
+       MFace *mface;
+       MTFace *mtface;
+       float loc[3];
+       int num;
+
+       if(cpa) {
+               if(part->childtype == PART_CHILD_FACES) {
+                       mtface= CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE);
+                       if(mtface) {
+                               mface= psmd->dm->getFaceData(psmd->dm, cpa->num, CD_MFACE);
+                               mtface += cpa->num;
+                               psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv);
+                       }
+                       else
+                               uv[0]= uv[1]= 0.0f;
+               }
+               else
+                       uv[0]= uv[1]= 0.0f;
+
+               psys_particle_on_emitter(ob, psmd,
+                       (part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
+                       cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,0,0,0,orco,0);
+       }
+       else {
+               if(part->from == PART_FROM_FACE) {
+                       mtface= CustomData_get_layer(&psmd->dm->faceData, CD_MTFACE);
+                       num= pa->num_dmcache;
+
+                       if(num == DMCACHE_NOTFOUND)
+                               if(pa->num < psmd->dm->getNumFaces(psmd->dm))
+                                       num= pa->num;
+
+                       if(mtface && num != DMCACHE_NOTFOUND) {
+                               mface= psmd->dm->getFaceData(psmd->dm, num, CD_MFACE);
+                               mtface += num;
+                               psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv);
+                       }
+                       else
+                               uv[0]= uv[1]= 0.0f;
+               }
+               else
+                       uv[0]= uv[1]= 0.0f;
+
+               psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,orco,0);
+       }
+}
+
+void psys_get_dupli_path_transform(Object *ob, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, ParticleCacheKey *cache, float mat[][4], float *scale)
+{
+       float loc[3], nor[3], vec[3], side[3], len;
+
+       VecSubf(vec, (cache+cache->steps-1)->co, cache->co);
+       len= Normalize(vec);
+
+       if(pa)
+               psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,nor,0,0,0,0);
+       else
+               psys_particle_on_emitter(ob, psmd,
+                       (part->childtype == PART_CHILD_FACES)? PART_FROM_FACE: PART_FROM_PARTICLE,
+                       cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,loc,nor,0,0,0,0);
+       
+       Crossf(side, nor, vec);
+       Normalize(side);
+       Crossf(nor, vec, side);
+
+       Mat4One(mat);
+       VECCOPY(mat[0], vec);
+       VECCOPY(mat[1], side);
+       VECCOPY(mat[2], nor);
+
+       *scale= len;
+}
+
index dd6b2692de6644ca1c8d275ef55e2ef3223462e0..1deda6a29d56a60a63542e8045c9f9ff0d373c6a 100644 (file)
@@ -85,7 +85,7 @@ typedef struct Material {
        short flarec, starc, linec, ringc;
        float hasize, flaresize, subsize, flareboost;
        float strand_sta, strand_end, strand_ease, strand_surfnor;
-       float strand_min, strand_pad;
+       float strand_min, strand_widthfade;
        char strand_uvname[32];
        
        float sbias;                    /* shadow bias */
index 182ac6025fd7bb4b4fdf171209efff49f374ec3d..88f37dcfd534392547c16232f6c3fb886fca0613 100644 (file)
@@ -347,11 +347,12 @@ typedef struct TexMapping {
 #define PROJ_Z                 3
 
 /* texflag */
-#define MTEX_RGBTOINT  1
-#define MTEX_STENCIL   2
-#define MTEX_NEGATIVE  4
-#define MTEX_ALPHAMIX  8
-#define MTEX_VIEWSPACE 16
+#define MTEX_RGBTOINT          1
+#define MTEX_STENCIL           2
+#define MTEX_NEGATIVE          4
+#define MTEX_ALPHAMIX          8
+#define MTEX_VIEWSPACE         16
+#define MTEX_DUPLI_MAPTO       32
 
 /* blendtype */
 #define MTEX_BLEND             0
index 5b81052f5d2789c0da3ecb5de466b94048997428..8971126e643bf4be9d499c999435915a8974446b 100644 (file)
@@ -133,6 +133,7 @@ typedef struct ShadeInput
        float lo[3], gl[3], ref[3], orn[3], winco[3], sticky[3], vcol[4], rad[3];
        float refcol[4], displace[3];
        float strand, tang[3], stress, winspeed[4];
+       float duplilo[3], dupliuv[3];
 
        ShadeInputUV uv[8];   /* 8 = MAX_MTFACE */
        ShadeInputCol col[8]; /* 8 = MAX_MCOL */
index 7fbbd0f5abc8d4990d1f730f5bde0b66508baaac..9034ff79243c99b13537bf8d7d20b95c1b828a4e 100644 (file)
@@ -266,6 +266,8 @@ typedef struct ObjectInstanceRen {
        float mat[4][4], imat[3][3];
        short flag;
 
+       float dupliorco[3], dupliuv[2];
+
        float *vectors;
        int totvector;
 } ObjectInstanceRen;
@@ -343,7 +345,7 @@ typedef struct StrandBuffer {
        unsigned int lay;
        int overrideuv;
        int flag, maxdepth;
-       float adaptcos, minwidth;
+       float adaptcos, minwidth, widthfade;
 
        float winmat[4][4];
        int winx, winy;
index c919a54008e385d86b0eccb81a31f1e9d66dcc10..a3a3b4e5e4a72035f8183a6a31b922f7e3bbf0ce 100644 (file)
@@ -94,7 +94,7 @@ struct HaloRen *RE_inithalo_particle(struct Render *re, struct ObjectRen *obr, s
 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);
-void RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4]);
+struct ObjectInstanceRen *RE_addRenderInstance(struct Render *re, struct ObjectRen *obr, struct Object *ob, struct Object *par, int index, int psysindex, float mat[][4]);
 void RE_makeRenderInstances(struct Render *re);
 void RE_instanceTransformNormal(struct ObjectInstanceRen *obi, float *nor, float *tnor);
 
index 56e7265b69e535ecc22d8e0cdd17328ce873a6bf..d9dcd9b251ddbdfc1751dda20d9bb5e04252d6bf 100644 (file)
@@ -1496,11 +1496,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
        float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time;
        float *orco=0,*surfnor=0,*uvco=0, strandlen=0.0f, curlen=0.0f;
        float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
-       float adapt_angle=0.0, adapt_pix=0.0, random;
-       float simplify[2];
+       float adapt_angle=0.0, adapt_pix=0.0, random, simplify[2];
        int i, a, k, max_k=0, totpart, totuv=0, override_uv=-1, dosimplify = 0;
        int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild;
-       int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0};
+       int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num;
        char **uv_name=0;
 
 /* 1. check that everything is ok & updated */
@@ -1644,6 +1643,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
                                strandbuf->overrideuv= override_uv;
                                strandbuf->minwidth= ma->strand_min;
 
+                               if(ma->strand_widthfade == 0.0f)
+                                       strandbuf->widthfade= 0.0f;
+                               else if(ma->strand_widthfade >= 1.0f)
+                                       strandbuf->widthfade= 2.0f - ma->strand_widthfade;
+                               else
+                                       strandbuf->widthfade= 1.0f/MAX2(ma->strand_widthfade, 1e-5f);
+
                                if(part->flag & PART_HAIR_BSPLINE)
                                        strandbuf->flag |= R_STRAND_BSPLINE;
                                if(ma->mode & MA_STR_B_UNITS)
@@ -1700,13 +1706,25 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
 
                        if(uvco && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){
                                layer=psmd->dm->faceData.layers + CustomData_get_layer_index(&psmd->dm->faceData,CD_MFACE);
-                               for(i=0; i<totuv; i++){
-                                       MFace *mface=psmd->dm->getFaceData(psmd->dm,pa->num,CD_MFACE);
 
-                                       mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i);
-                                       mtface+=pa->num;
-                                       
-                                       psys_interpolate_uvs(mtface,mface->v4,pa->fuv,uvco+2*i);
+                   num= pa->num_dmcache;
+
+                               if(num == DMCACHE_NOTFOUND)
+                                       if(pa->num < psmd->dm->getNumFaces(psmd->dm))
+                                               num= pa->num;
+
+                               for(i=0; i<totuv; i++){
+                                       if(num != DMCACHE_NOTFOUND) {
+                                               MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE);
+                                               mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i);
+                                               mtface+=num;
+                                               
+                                               psys_interpolate_uvs(mtface,mface->v4,pa->fuv,uvco+2*i);
+                                       }
+                                       else {
+                                               uvco[2*i]= 0.0f;
+                                               uvco[2*i + 1]= 0.0f;
+                                       }
                                }
                        }
 
@@ -4076,6 +4094,7 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
 {
        Base *base;
        Object *ob;
+       ObjectInstanceRen *obi;
        Scene *sce;
        float mat[4][4], obmat[4][4];
 
@@ -4136,11 +4155,18 @@ static void database_init_objects(Render *re, unsigned int lay, int nolamps, int
                                                Mat4Invert(imat, obmat);
                                                MTC_Mat4MulSerie(mat, re->viewmat, dob->mat, imat, re->viewinv, 0, 0, 0, 0);
 
-                                               RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat);
+                                               obi= RE_addRenderInstance(re, NULL, obd, ob, dob->index, 0, mat);
+                                               VECCOPY(obi->dupliorco, dob->orco);
+                                               obi->dupliuv[0]= dob->uv[0];
+                                               obi->dupliuv[1]= dob->uv[1];
 
                                                psysindex= 1;
-                                               for(psys=obd->particlesystem.first; psys; psys=psys->next)
+                                               for(psys=obd->particlesystem.first; psys; psys=psys->next) {
                                                        RE_addRenderInstance(re, NULL, obd, ob, dob->index, psysindex++, mat);
+                                                       VECCOPY(obi->dupliorco, dob->orco);
+                                                       obi->dupliuv[0]= dob->uv[0];
+                                                       obi->dupliuv[1]= dob->uv[1];
+                                               }
                                                
                                                obd->flag |= OB_DONE;
                                                obd->transflag |= OB_RENDER_DUPLI;
index b950f54417ec1619509aaf96fd5d16c3a25b5780..7dc205e279435e0a2b8820012d08bf61a8d6d740 100644 (file)
@@ -93,10 +93,10 @@ static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y)
        else {
                char *rect = (char *)( ibuf->rect+ ofs);
 
-               col[0] = ((float)rect[0])/255.0f;
-               col[1] = ((float)rect[1])/255.0f;
-               col[2] = ((float)rect[2])/255.0f;
-               col[3] = ((float)rect[3])/255.0f;
+               col[0] = ((float)rect[0])*(1.0f/255.0f);
+               col[1] = ((float)rect[1])*(1.0f/255.0f);
+               col[2] = ((float)rect[2])*(1.0f/255.0f);
+               col[3] = ((float)rect[3])*(1.0f/255.0f);
        }       
 }
 
index 059a72507c56128a3c075331dcaefebce502b07e..e84460d5dfc7d711a25a5479543f3b97dc909f97 100644 (file)
@@ -1261,7 +1261,7 @@ void project_renderdata(Render *re, void (*projectfunc)(float *, float mat[][4],
 
 /* ------------------------------------------------------------------------- */
 
-void RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4])
+ObjectInstanceRen *RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, int index, int psysindex, float mat[][4])
 {
        ObjectInstanceRen *obi;
        float mat3[3][3];
@@ -1281,6 +1281,8 @@ void RE_addRenderInstance(Render *re, ObjectRen *obr, Object *ob, Object *par, i
        }
 
        BLI_addtail(&re->instancetable, obi);
+
+       return obi;
 }
 
 void RE_makeRenderInstances(Render *re)
index f937218cdb6490bfb75ee1d958041efce58c45ad..a6f4108c9df69b1cf1017912a7526e42ba6b58e4 100644 (file)
@@ -919,6 +919,8 @@ void shade_input_set_shade_texco(ShadeInput *shi)
                                        shi->dylo[2]= dl*o3[2]-shi->dy_u*o1[2]-shi->dy_v*o2[2];
                                }
                        }
+
+                       VECCOPY(shi->duplilo, obi->dupliorco);
                }
                
                if(texco & TEXCO_GLOB) {
@@ -1033,6 +1035,10 @@ void shade_input_set_shade_texco(ShadeInput *shi)
                                }
                        }
 
+                       shi->dupliuv[0]= -1.0f + 2.0f*obi->dupliuv[0];
+                       shi->dupliuv[1]= -1.0f + 2.0f*obi->dupliuv[1];
+                       shi->dupliuv[2]= 0.0f;
+
                        if(shi->totuv == 0) {
                                ShadeInputUV *suv= &shi->uv[0];
 
index adaf2ae3259f3a00726d7ba9b8b1137c2ce9ba3b..3930a35dc68124e3adc08881a7e949b950e8f681 100644 (file)
@@ -436,7 +436,7 @@ typedef struct StrandPart {
        GHash *hash;
        StrandPoint point1, point2;
        ShadeSample ssamp1, ssamp2, ssamp;
-       float t[3];
+       float t[3], s[3];
 } StrandPart;
 
 typedef struct StrandSortSegment {
@@ -520,6 +520,23 @@ static void add_strand_obindex(RenderLayer *rl, int offset, ObjectRen *obr)
        }
 }
 
+static void strand_apply_shaderesult_alpha(ShadeResult *shr, float alpha)
+{
+       if(alpha < 1.0f) {
+               shr->combined[0] *= alpha;
+               shr->combined[1] *= alpha;
+               shr->combined[2] *= alpha;
+               shr->combined[3] *= alpha;
+
+               shr->col[0] *= alpha;
+               shr->col[1] *= alpha;
+               shr->col[2] *= alpha;
+               shr->col[3] *= alpha;
+
+               shr->alpha *= alpha;
+       }
+}
+
 static void do_strand_point_project(float winmat[][4], ZSpan *zspan, float *co, float *hoco, float *zco)
 {
        projectvert(co, winmat, hoco);
@@ -537,7 +554,6 @@ static void strand_project_point(float winmat[][4], float winx, float winy, Stra
        spoint->y= spoint->hoco[1]*div*winy*0.5f;
 }
 
-#include "BLI_rand.h"
 static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *sseg, StrandPoint *spoint);
 
 static void strand_shade_get(StrandPart *spart, int lookup, ShadeSample *ssamp, StrandPoint *spoint, StrandVert *svert, StrandSegment *sseg)
@@ -576,22 +592,6 @@ static void strand_shade_segment(StrandPart *spart)
                strand_shade_get(spart, !last, &spart->ssamp2, &sseg->point2, sseg->v[2], sseg);
                sseg->shaded= 1;
        }
-
-#if 0
-       float c[3];
-       
-       c[0]= BLI_frand();
-       c[1]= BLI_frand();
-       c[2]= BLI_frand();
-
-       spart->ssamp1.shr[0].combined[0] *= c[0];
-       spart->ssamp1.shr[0].combined[1] *= c[1];
-       spart->ssamp1.shr[0].combined[2] *= c[2];
-
-       spart->ssamp2.shr[0].combined[0] *= c[0];
-       spart->ssamp2.shr[0].combined[1] *= c[1];
-       spart->ssamp2.shr[0].combined[2] *= c[2];
-#endif
 }
 
 static void do_strand_blend(void *handle, int x, int y, float u, float v, float z)
@@ -599,7 +599,7 @@ static void do_strand_blend(void *handle, int x, int y, float u, float v, float
        StrandPart *spart= (StrandPart*)handle;
        StrandBuffer *buffer= spart->segment->buffer;
        ShadeResult *shr;
-       float /**pass,*/ t;
+       float /**pass,*/ t, s;
        int offset, zverg;
 
        /* check again solid z-buffer */
@@ -625,6 +625,14 @@ static void do_strand_blend(void *handle, int x, int y, float u, float v, float
                interpolate_shade_result(spart->ssamp1.shr, spart->ssamp2.shr, t,
                        spart->ssamp.shr, spart->addpassflag);
 
+               /* alpha along width */
+               if(buffer->widthfade != 0.0f) {
+                       s = fabs(u*spart->s[0] + v*spart->s[1] + (1.0f-u-v)*spart->s[2]);
+                       s = 1.0f - pow(s, buffer->widthfade);
+
+                       strand_apply_shaderesult_alpha(spart->ssamp.shr, s);
+               }
+
                /* add in shaderesult array for part */
                spart->ssamp.shi[0].mask= (1<<spart->sample);
                addtosamp_shr(shr, &spart->ssamp, spart->addpassflag);
@@ -696,19 +704,7 @@ static void strand_shade_point(Render *re, ShadeSample *ssamp, StrandSegment *ss
        shade_input_do_shade(shi, shr);
 
        /* apply simplification */
-       if(spoint->alpha < 1.0f) {
-               shr->combined[0] *= spoint->alpha;
-               shr->combined[1] *= spoint->alpha;
-               shr->combined[2] *= spoint->alpha;
-               shr->combined[3] *= spoint->alpha;
-
-               shr->col[0] *= spoint->alpha;
-               shr->col[1] *= spoint->alpha;
-               shr->col[2] *= spoint->alpha;
-               shr->col[3] *= spoint->alpha;
-
-               shr->alpha *= spoint->alpha;
-       }
+       strand_apply_shaderesult_alpha(shr, spoint->alpha);
 
        /* include lamphalos for strand, since halo layer was added already */
        if(re->flag & R_LAMPHALO)
@@ -747,12 +743,18 @@ static void do_scanconvert_strand(Render *re, StrandPart *spart, ZSpan *zspan, f
        spart->sample= sample;
 
        spart->t[0]= t-dt;
+       spart->s[0]= -1.0f;
        spart->t[1]= t-dt;
+       spart->s[1]= 1.0f;
        spart->t[2]= t;
+       spart->s[2]= 1.0f;
        zspan_scanconvert_strand(zspan, spart, jco1, jco2, jco3, do_strand_blend);
        spart->t[0]= t-dt;
+       spart->s[0]= -1.0f;
        spart->t[1]= t;
+       spart->s[1]= 1.0f;
        spart->t[2]= t;
+       spart->s[2]= -1.0f;
        zspan_scanconvert_strand(zspan, spart, jco1, jco3, jco4, do_strand_blend);
 }
 
index 0c0fd6edbd253fa8a2014502abeeda9aa47251f8..14f28c20f1c2b8f30d8fc98e26d086fcc8047550 100644 (file)
@@ -1427,7 +1427,14 @@ void do_material_tex(ShadeInput *shi)
 
                        /* which coords */
                        if(mtex->texco==TEXCO_ORCO) {
-                               co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
+                               if(mtex->texflag & MTEX_DUPLI_MAPTO) {
+                                       co= shi->duplilo; dx= dxt; dy= dyt;
+                                       dxt[0]= dxt[1]= dxt[2]= 0.0f;
+                                       dyt[0]= dyt[1]= dyt[2]= 0.0f;
+                               }
+                               else {
+                                       co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
+                               }
                        }
                        else if(mtex->texco==TEXCO_STICKY) {
                                co= shi->sticky; dx= shi->dxsticky; dy= shi->dysticky;
@@ -1466,21 +1473,28 @@ void do_material_tex(ShadeInput *shi)
                                co= shi->gl; dx= shi->dxco; dy= shi->dyco;
                        }
                        else if(mtex->texco==TEXCO_UV) {
-                               ShadeInputUV *suv= &shi->uv[shi->actuv];
-                               int i;
-
-                               if(mtex->uvname[0] != 0) {
-                                       for(i = 0; i < shi->totuv; i++) {
-                                               if(strcmp(shi->uv[i].name, mtex->uvname)==0) {
-                                                       suv= &shi->uv[i];
-                                                       break;
+                               if(mtex->texflag & MTEX_DUPLI_MAPTO) {
+                                       co= shi->dupliuv; dx= dxt; dy= dyt;
+                                       dxt[0]= dxt[1]= dxt[2]= 0.0f;
+                                       dyt[0]= dyt[1]= dyt[2]= 0.0f;
+                               }
+                               else {
+                                       ShadeInputUV *suv= &shi->uv[shi->actuv];
+                                       int i;
+
+                                       if(mtex->uvname[0] != 0) {
+                                               for(i = 0; i < shi->totuv; i++) {
+                                                       if(strcmp(shi->uv[i].name, mtex->uvname)==0) {
+                                                               suv= &shi->uv[i];
+                                                               break;
+                                                       }
                                                }
                                        }
-                               }
 
-                               co= suv->uv;
-                               dx= suv->dxuv;
-                               dy= suv->dyuv; 
+                                       co= suv->uv;
+                                       dx= suv->dxuv;
+                                       dy= suv->dyuv; 
+                               }
                        }
                        else if(mtex->texco==TEXCO_WINDOW) {
                                co= shi->winco; dx= shi->dxwin; dy= shi->dywin;
index 6d846e693084c797faa010240a474fee33a4b693..26735eaa645487f9b2c53d7e8fc495b6be62014c 100644 (file)
@@ -3299,7 +3299,7 @@ static void material_panel_map_input(Object *ob, Material *ma)
        uiBlockBeginAlign(block);
        uiDefButS(block, ROW, B_MATPRV, "Glob",                 630,180,45,18, &(mtex->texco), 4.0, (float)TEXCO_GLOB, 0, 0, "Uses global coordinates for the texture coordinates");
        uiDefButS(block, ROW, B_MATPRV, "Object",               675,180,75,18, &(mtex->texco), 4.0, (float)TEXCO_OBJECT, 0, 0, "Uses linked object's coordinates for texture coordinates");
-       if(mtex->texco == TEXCO_UV) {
+       if(mtex->texco == TEXCO_UV && !(mtex->texflag & MTEX_DUPLI_MAPTO)) {
                if(!verify_valid_uv_name(mtex->uvname))
             uiBlockSetCol(block, TH_REDALERT);
                but=uiDefBut(block, TEX, B_MATPRV, "UV:", 750,180,158,18, mtex->uvname, 0, 31, 0, 0, "Set name of UV layer to use, default is active UV layer");
@@ -3321,6 +3321,10 @@ static void material_panel_map_input(Object *ob, Material *ma)
        
        uiDefButS(block, ROW, B_MATPRV, "Stress",               630,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_STRESS, 0, 0, "Uses the difference of edge lengths compared to original coordinates of the mesh");
        uiDefButS(block, ROW, B_MATPRV, "Tangent",              700,140,70,18, &(mtex->texco), 4.0, (float)TEXCO_TANGENT, 0, 0, "Uses the optional tangent vector as texture coordinates");
+       uiBlockEndAlign(block);
+
+       if(ELEM(mtex->texco, TEXCO_UV, TEXCO_ORCO))
+               uiDefButBitS(block, TOG, MTEX_DUPLI_MAPTO, B_MATPRV, "From Dupli",      820,140,88,18, &(mtex->texflag), 0, 0, 0, 0, "If object is duplicated by vertices, faces or particles, inherit texture coordinate from parent object");
 
        /* COORDS */
        uiBlockBeginAlign(block);
@@ -3855,7 +3859,7 @@ static uiBlock *strand_menu(void *mat_v)
 {
        Material *ma= mat_v;
        uiBlock *block;
-       int buth=20, butw=230, butx=10, buty=160;
+       int buth=20, butw=230, butx=10, buty=180;
 
        block= uiNewBlock(&curarea->uiblocks, "strand menu", UI_EMBOSS, UI_HELV, curarea->win);
         
@@ -3885,6 +3889,7 @@ static uiBlock *strand_menu(void *mat_v)
                uiDefButF(block, NUMSLI, 0, "End ",             butx,buty-=buth, butw,buth,  &ma->strand_end, 0.25, 10.0, 2, 0, "End size of strands in pixels");
        }
        uiDefButF(block, NUMSLI, 0, "Shape ",   butx,buty-=buth, butw,buth,  &ma->strand_ease, -0.9, 0.9, 2, 0, "Shape of strands, positive value makes it rounder, negative makes it spiky");
+       uiDefButF(block, NUMSLI, 0, "Width Fade ",      butx,buty-=buth, butw,buth,  &ma->strand_widthfade, 0.0, 2.0, 2, 0, "Transparency along the width of the strand");
        uiDefBut(block, TEX, B_MATPRV, "UV:", butx,buty-=buth,butw,buth, ma->strand_uvname, 0, 31, 0, 0, "Set name of UV layer to override");
 
        uiBlockSetDirection(block, UI_TOP);