diff options
-rw-r--r-- | source/blender/blenkernel/BKE_anim.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_particle.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 131 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 75 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_material_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_texture_types.h | 11 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_shader_ext.h | 1 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_types.h | 4 | ||||
-rw-r--r-- | source/blender/render/intern/include/renderdatabase.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 48 | ||||
-rw-r--r-- | source/blender/render/intern/source/imagetexture.c | 8 | ||||
-rw-r--r-- | source/blender/render/intern/source/renderdatabase.c | 4 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadeinput.c | 6 | ||||
-rw-r--r-- | source/blender/render/intern/source/strand.c | 66 | ||||
-rw-r--r-- | source/blender/render/intern/source/texture.c | 40 | ||||
-rw-r--r-- | source/blender/src/buttons_shading.c | 9 |
17 files changed, 297 insertions, 119 deletions
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index c3e978a5a9a..7b7bd7f8704 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -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); diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index a1ac97406e1..d92e8bad1f9 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -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); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index aada60be21b..9ee4e62b9cb 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -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) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 40c776248cf..d20031179bf 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -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); } } } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 54b8a5c47e6..0ac60e6da4e 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -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; +} + diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index dd6b2692de6..1deda6a29d5 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -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 */ diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 182ac6025fd..88f37dcfd53 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -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 diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 5b81052f5d2..8971126e643 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -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 */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 7fbbd0f5abc..9034ff79243 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -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; diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index c919a54008e..a3a3b4e5e4a 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -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); diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 56e7265b69e..d9dcd9b251d 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -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; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index b950f54417e..7dc205e2794 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -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); } } diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 059a72507c5..e84460d5dfc 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -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) diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index f937218cdb6..a6f4108c9df 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -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]; diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c index adaf2ae3259..3930a35dc68 100644 --- a/source/blender/render/intern/source/strand.c +++ b/source/blender/render/intern/source/strand.c @@ -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); } diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c index 0c0fd6edbd2..14f28c20f1c 100644 --- a/source/blender/render/intern/source/texture.c +++ b/source/blender/render/intern/source/texture.c @@ -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; diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 6d846e69308..26735eaa645 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -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); |