Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-01-09 17:40:25 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-01-09 17:40:25 +0300
commitead7a3324784277239d5960eaa5408c3b973f79d (patch)
tree19d81aca9f695cab2912b6bc58c11184cf5c0f7a
parent8b78a5cf3530fd440dba478792a7f016db30a63c (diff)
Misc Render Features
==================== - "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.
-rw-r--r--source/blender/blenkernel/BKE_anim.h1
-rw-r--r--source/blender/blenkernel/BKE_particle.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c6
-rw-r--r--source/blender/blenkernel/intern/anim.c131
-rw-r--r--source/blender/blenkernel/intern/particle.c75
-rw-r--r--source/blender/makesdna/DNA_material_types.h2
-rw-r--r--source/blender/makesdna/DNA_texture_types.h11
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h1
-rw-r--r--source/blender/render/intern/include/render_types.h4
-rw-r--r--source/blender/render/intern/include/renderdatabase.h2
-rw-r--r--source/blender/render/intern/source/convertblender.c48
-rw-r--r--source/blender/render/intern/source/imagetexture.c8
-rw-r--r--source/blender/render/intern/source/renderdatabase.c4
-rw-r--r--source/blender/render/intern/source/shadeinput.c6
-rw-r--r--source/blender/render/intern/source/strand.c66
-rw-r--r--source/blender/render/intern/source/texture.c40
-rw-r--r--source/blender/src/buttons_shading.c9
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);