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:
authorJanne Karhu <jhkarh@gmail.com>2011-02-12 17:38:34 +0300
committerJanne Karhu <jhkarh@gmail.com>2011-02-12 17:38:34 +0300
commitfafbd9d71b95776d1c7583476de74fccefab7f10 (patch)
tree838e0fbc2e53c0700a87ebc1fdf4798837ffda3e /source/blender/blenkernel
parentc8c86aa6a12a253680aa266ce1c5d51b1b39005a (diff)
Particles todo item: particle textures
* Effecting particle properties with textures was possible in 2.49, but not in 2.5 anymore. * Now particles have their own textures (available in texture panel for objects with particle systems), which are totally separate from the material textures. * Currently a basic set of particle properties is available for texture control. Some others could still be added, but the whole system is not intended as an "change anything with a texture" as this kind of functionality will be provided with node particles in the future much better. * Combined with the previously added "particle texture coordinates" this new functionality also solves the problem of animating particle properties through the particle lifetime nicely. * Currently the textures only use the intensity of the texture in "multiply" blending mode, so in order for the textures to effect a particle parameter there has to be a non-zero value defined for the parameter in the particle settings. Other blend modes can be added later if they're considered useful enough.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_particle.h14
-rw-r--r--source/blender/blenkernel/BKE_texture.h2
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c24
-rw-r--r--source/blender/blenkernel/intern/particle.c241
-rw-r--r--source/blender/blenkernel/intern/particle_system.c359
-rw-r--r--source/blender/blenkernel/intern/texture.c41
6 files changed, 322 insertions, 359 deletions
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 3f7523d5264..5c72973a0da 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -80,20 +80,10 @@ typedef struct ParticleSimulationData {
struct ListBase *colliders;
} ParticleSimulationData;
-//typedef struct ParticleReactEvent {
-// struct ParticleReactEvent *next, *prev;
-// int event, pa_num;
-// Object *ob;
-// struct ParticleSystem *psys;
-// struct ParticleKey state;
-//
-// float time, size;
-//}ParticleReactEvent;
-
typedef struct ParticleTexture{
float ivel; /* used in reset */
float time, life, exist, size; /* used in init */
- float pvel[3]; /* used in physics */
+ float damp, gravity, field; /* used in physics */
float length, clump, kink, effector;/* used in path caching */
float rough1, rough2, roughe; /* used in path caching */
} ParticleTexture;
@@ -291,7 +281,7 @@ float psys_get_dietime_from_cache(struct PointCache *cache, int index);
void psys_free_pdd(struct ParticleSystem *psys);
float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup);
-void psys_get_texture(struct ParticleSimulationData *sim, struct Material *ma, struct ParticleData *pa, struct ParticleTexture *ptex, int event);
+void psys_get_texture(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleTexture *ptex, int event, float cfra);
void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor);
float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values);
void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time);
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index cbae90f4c38..d559350a780 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -84,6 +84,7 @@ struct Tex *give_current_material_texture(struct Material *ma);
struct Tex *give_current_lamp_texture(struct Lamp *la);
struct Tex *give_current_world_texture(struct World *world);
struct Tex *give_current_brush_texture(struct Brush *br);
+struct Tex *give_current_particle_texture(struct ParticleSettings *part);
struct bNode *give_current_material_texture_node(struct Material *ma);
@@ -94,6 +95,7 @@ void set_current_brush_texture(struct Brush *br, struct Tex *tex);
void set_current_world_texture(struct World *wo, struct Tex *tex);
void set_current_material_texture(struct Material *ma, struct Tex *tex);
void set_current_lamp_texture(struct Lamp *la, struct Tex *tex);
+void set_current_particle_texture(struct ParticleSettings *part, struct Tex *tex);
struct TexMapping *add_mapping(void);
void init_mapping(struct TexMapping *texmap);
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 6db4e0ac081..07a47f84af5 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -40,6 +40,7 @@
#include "DNA_group_types.h"
#include "DNA_lattice_types.h"
#include "DNA_key_types.h"
+#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
@@ -2375,6 +2376,29 @@ static void dag_id_flush_update(Scene *sce, ID *id)
modifiers_foreachIDLink(obt, dag_id_flush_update__isDependentTexture, &data);
if (data.is_dependent)
obt->recalc |= OB_RECALC_DATA;
+
+ /* particle settings can use the texture as well */
+ if(obt->particlesystem.first) {
+ ParticleSystem *psys = obt->particlesystem.first;
+ MTex **mtexp, *mtex;
+ int a;
+ for(; psys; psys=psys->next) {
+ mtexp = psys->part->mtex;
+ for(a=0; a<MAX_MTEX; a++, mtexp++) {
+ mtex = *mtexp;
+ if(mtex && mtex->tex == (Tex*)id) {
+ obt->recalc |= OB_RECALC_DATA;
+
+ if(mtex->mapto & PAMAP_INIT)
+ psys->recalc |= PSYS_RECALC_RESET;
+ if(mtex->mapto & PAMAP_CHILD)
+ psys->recalc |= PSYS_RECALC_CHILD;
+
+ BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
+ }
+ }
+ }
+ }
}
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 5f45e06cfc4..38fd11b086f 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -77,8 +77,6 @@
#include "RE_render_ext.h"
-static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index,
- float *fuv, float *orco, ParticleTexture *ptex, int event);
static void get_child_modifier_parameters(ParticleSettings *part, ParticleThreadContext *ctx,
ChildParticle *cpa, short cpa_from, int cpa_num, float *cpa_fuv, float *orco, ParticleTexture *ptex);
static void do_child_modifiers(ParticleSimulationData *sim,
@@ -2860,6 +2858,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
Material *ma;
ParticleInterpolationData pind;
+ ParticleTexture ptex;
PARTICLE_P;
@@ -2909,8 +2908,8 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
/*---first main loop: create all actual particles' paths---*/
LOOP_SHOWN_PARTICLES {
if(!psys->totchild) {
- BLI_srandom(psys->seed + p);
- pa_length = 1.0f - part->randlength * BLI_frand();
+ psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f);
+ pa_length = ptex.length * (1.0f - part->randlength * PSYS_FRAND(psys->seed + p));
if(vg_length)
pa_length *= psys_particle_value_from_verts(psmd->dm,part->from,pa,vg_length);
}
@@ -3674,82 +3673,128 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, fl
return 1;
}
-static void get_cpa_texture(DerivedMesh *dm, Material *ma, int face_index, float *fw, float *orco, ParticleTexture *ptex, int event)
+#define SET_PARTICLE_TEXTURE(type, pvalue, texfac) if((event & mtex->mapto) & type) {pvalue = texture_value_blend(def, pvalue, value, texfac, blend);}
+#define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) if(event & type) { if(pvalue < 0.f) pvalue = 1.f+pvalue; CLAMP(pvalue, 0.0, 1.0); }
+#define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) if(event & type) { CLAMP(pvalue, -1.0, 1.0); }
+
+static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, float *fw, float *orco, ParticleTexture *ptex, int event, float cfra)
{
- MTex *mtex;
+ MTex *mtex, **mtexp = part->mtex;
int m,setvars=0;
- float value, rgba[4], texco[3];
+ float value, rgba[4], texvec[3];
- if(ma) for(m=0; m<MAX_MTEX; m++){
- mtex=ma->mtex[m];
- if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
+ ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
+ ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink =
+ ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.f;
+
+ ptex->length= 1.0f - part->randlength * PSYS_FRAND(child_index + 26);
+ ptex->length*= part->clength_thres < PSYS_FRAND(child_index + 27) ? part->clength : 1.0f;
+
+ for(m=0; m<MAX_MTEX; m++, mtexp++){
+ mtex = *mtexp;
+ if(mtex && mtex->mapto){
float def=mtex->def_var;
short blend=mtex->blendtype;
+ short texco = mtex->texco;
- if((mtex->texco & TEXCO_UV) && fw) {
- if(!get_particle_uv(dm, NULL, face_index, fw, mtex->uvname, texco))
- VECCOPY(texco,orco);
- }
- else
- VECCOPY(texco,orco);
+ if(ELEM(texco, TEXCO_UV, TEXCO_ORCO) && (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME) == 0 || part->distr == PART_DISTR_GRID))
+ texco = TEXCO_GLOB;
- externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3, 0);
- if((event & mtex->pmapto) & MAP_PA_TIME){
- if((setvars&MAP_PA_TIME)==0){
- ptex->time=0.0;
- setvars|=MAP_PA_TIME;
- }
- ptex->time= texture_value_blend(mtex->def_var,ptex->time,value,mtex->timefac,blend);
+ switch(texco) {
+ case TEXCO_GLOB:
+ copy_v3_v3(texvec, par->state.co);
+ break;
+ case TEXCO_OBJECT:
+ copy_v3_v3(texvec, par->state.co);
+ if(mtex->object)
+ mul_m4_v3(mtex->object->imat, texvec);
+ break;
+ case TEXCO_UV:
+ if(fw && get_particle_uv(dm, NULL, face_index, fw, mtex->uvname, texvec))
+ break;
+ /* no break, failed to get uv's, so let's try orco's */
+ case TEXCO_ORCO:
+ copy_v3_v3(texvec, orco);
+ break;
+ case TEXCO_PARTICLE:
+ /* texture coordinates in range [-1,1] */
+ texvec[0] = 2.f * (cfra - par->time)/(par->dietime-par->time) - 1.f;
+ texvec[1] = 0.f;
+ texvec[2] = 0.f;
+ break;
}
- if((event & mtex->pmapto) & MAP_PA_LENGTH)
- ptex->length= texture_value_blend(def,ptex->length,value,mtex->lengthfac,blend);
- if((event & mtex->pmapto) & MAP_PA_CLUMP)
- ptex->clump= texture_value_blend(def,ptex->clump,value,mtex->clumpfac,blend);
- if((event & mtex->pmapto) & MAP_PA_KINK)
- ptex->kink= texture_value_blend(def,ptex->kink,value,mtex->kinkfac,blend);
- if((event & mtex->pmapto) & MAP_PA_ROUGH)
+
+ externtex(mtex, texvec, &value, rgba, rgba+1, rgba+2, rgba+3, 0);
+
+ if((event & mtex->mapto) & PAMAP_ROUGH)
ptex->rough1= ptex->rough2= ptex->roughe= texture_value_blend(def,ptex->rough1,value,mtex->roughfac,blend);
- if((event & mtex->pmapto) & MAP_PA_DENS)
- ptex->exist= texture_value_blend(def,ptex->exist,value,mtex->padensfac,blend);
+
+ SET_PARTICLE_TEXTURE(PAMAP_LENGTH, ptex->length, mtex->lengthfac);
+ SET_PARTICLE_TEXTURE(PAMAP_CLUMP, ptex->clump, mtex->clumpfac);
+ SET_PARTICLE_TEXTURE(PAMAP_KINK, ptex->kink, mtex->kinkfac);
+ SET_PARTICLE_TEXTURE(PAMAP_DENS, ptex->exist, mtex->padensfac);
}
}
- if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
- if(event & MAP_PA_LENGTH) { CLAMP(ptex->length,0.0,1.0); }
- if(event & MAP_PA_CLUMP) { CLAMP(ptex->clump,0.0,1.0); }
- if(event & MAP_PA_KINK) { CLAMP(ptex->kink,0.0,1.0); }
- if(event & MAP_PA_ROUGH) {
- CLAMP(ptex->rough1,0.0,1.0);
- CLAMP(ptex->rough2,0.0,1.0);
- CLAMP(ptex->roughe,0.0,1.0);
- }
- if(event & MAP_PA_DENS) { CLAMP(ptex->exist,0.0,1.0); }
+
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_LENGTH, ptex->length);
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_CLUMP, ptex->clump);
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_KINK, ptex->kink);
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_ROUGH, ptex->rough1);
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_DENS, ptex->exist);
}
-void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *pa, ParticleTexture *ptex, int event)
+void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTexture *ptex, int event, float cfra)
{
+ ParticleSettings *part = sim->psys->part;
+ MTex **mtexp = part->mtex;
MTex *mtex;
int m;
- float value, rgba[4], co[3], texco[3];
+ float value, rgba[4], co[3], texvec[3];
int setvars=0;
- if(ma) for(m=0; m<MAX_MTEX; m++){
- mtex=ma->mtex[m];
- if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
+ /* initialize ptex */
+ ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
+ ptex->gravity = ptex->field = ptex->length = ptex->clump = ptex->kink =
+ ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.f;
+
+ ptex->time = (float)(pa - sim->psys->particles)/(float)sim->psys->totpart;
+
+ for(m=0; m<MAX_MTEX; m++, mtexp++){
+ mtex = *mtexp;
+ if(mtex && mtex->mapto){
float def=mtex->def_var;
short blend=mtex->blendtype;
+ short texco = mtex->texco;
- if((mtex->texco & TEXCO_UV) && ELEM(sim->psys->part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
- if(!get_particle_uv(sim->psmd->dm, pa, 0, pa->fuv, mtex->uvname, texco)) {
- /* failed to get uv's, let's try orco's */
- psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
- }
- }
- else {
- psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texco, 0);
+ if(ELEM(texco, TEXCO_UV, TEXCO_ORCO) && (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME) == 0 || part->distr == PART_DISTR_GRID))
+ texco = TEXCO_GLOB;
+
+ switch(texco) {
+ case TEXCO_GLOB:
+ copy_v3_v3(texvec, pa->state.co);
+ break;
+ case TEXCO_OBJECT:
+ copy_v3_v3(texvec, pa->state.co);
+ if(mtex->object)
+ mul_m4_v3(mtex->object->imat, texvec);
+ break;
+ case TEXCO_UV:
+ if(get_particle_uv(sim->psmd->dm, pa, 0, pa->fuv, mtex->uvname, texvec))
+ break;
+ /* no break, failed to get uv's, so let's try orco's */
+ case TEXCO_ORCO:
+ psys_particle_on_emitter(sim->psmd,sim->psys->part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,0,0,0,texvec, 0);
+ break;
+ case TEXCO_PARTICLE:
+ /* texture coordinates in range [-1,1] */
+ texvec[0] = 2.f * (cfra - pa->time)/(pa->dietime-pa->time) - 1.f;
+ texvec[1] = 0.f;
+ texvec[2] = 0.f;
+ break;
}
- externtex(mtex, texco, &value, rgba, rgba+1, rgba+2, rgba+3, 0);
+ externtex(mtex, texvec, &value, rgba, rgba+1, rgba+2, rgba+3, 0);
- if((event & mtex->pmapto) & MAP_PA_TIME){
+ if((event & mtex->mapto) & PAMAP_TIME) {
/* the first time has to set the base value for time regardless of blend mode */
if((setvars&MAP_PA_TIME)==0){
int flip= (mtex->timefac < 0.0f);
@@ -3761,32 +3806,26 @@ void psys_get_texture(ParticleSimulationData *sim, Material *ma, ParticleData *p
else
ptex->time= texture_value_blend(def,ptex->time,value,mtex->timefac,blend);
}
- if((event & mtex->pmapto) & MAP_PA_LIFE)
- ptex->life= texture_value_blend(def,ptex->life,value,mtex->lifefac,blend);
- if((event & mtex->pmapto) & MAP_PA_DENS)
- ptex->exist= texture_value_blend(def,ptex->exist,value,mtex->padensfac,blend);
- if((event & mtex->pmapto) & MAP_PA_SIZE)
- ptex->size= texture_value_blend(def,ptex->size,value,mtex->sizefac,blend);
- if((event & mtex->pmapto) & MAP_PA_IVEL)
- ptex->ivel= texture_value_blend(def,ptex->ivel,value,mtex->ivelfac,blend);
- if((event & mtex->pmapto) & MAP_PA_PVEL)
- texture_rgb_blend(ptex->pvel,rgba,ptex->pvel,value,mtex->pvelfac,blend);
- if((event & mtex->pmapto) & MAP_PA_LENGTH)
- ptex->length= texture_value_blend(def,ptex->length,value,mtex->lengthfac,blend);
- if((event & mtex->pmapto) & MAP_PA_CLUMP)
- ptex->clump= texture_value_blend(def,ptex->clump,value,mtex->clumpfac,blend);
- if((event & mtex->pmapto) & MAP_PA_KINK)
- ptex->kink= texture_value_blend(def,ptex->kink,value,mtex->kinkfac,blend);
- }
- }
- if(event & MAP_PA_TIME) { CLAMP(ptex->time,0.0,1.0); }
- if(event & MAP_PA_LIFE) { CLAMP(ptex->life,0.0,1.0); }
- if(event & MAP_PA_DENS) { CLAMP(ptex->exist,0.0,1.0); }
- if(event & MAP_PA_SIZE) { CLAMP(ptex->size,0.0,1.0); }
- if(event & MAP_PA_IVEL) { CLAMP(ptex->ivel,0.0,1.0); }
- if(event & MAP_PA_LENGTH) { CLAMP(ptex->length,0.0,1.0); }
- if(event & MAP_PA_CLUMP) { CLAMP(ptex->clump,0.0,1.0); }
- if(event & MAP_PA_KINK) { CLAMP(ptex->kink,0.0,1.0); }
+ SET_PARTICLE_TEXTURE(PAMAP_LIFE, ptex->life, mtex->lifefac)
+ SET_PARTICLE_TEXTURE(PAMAP_DENS, ptex->exist, mtex->padensfac)
+ SET_PARTICLE_TEXTURE(PAMAP_SIZE, ptex->size, mtex->sizefac)
+ SET_PARTICLE_TEXTURE(PAMAP_IVEL, ptex->ivel, mtex->ivelfac)
+ SET_PARTICLE_TEXTURE(PAMAP_FIELD, ptex->field, mtex->fieldfac)
+ SET_PARTICLE_TEXTURE(PAMAP_GRAVITY, ptex->gravity, mtex->gravityfac)
+ SET_PARTICLE_TEXTURE(PAMAP_DAMP, ptex->damp, mtex->dampfac)
+ SET_PARTICLE_TEXTURE(PAMAP_LENGTH, ptex->length, mtex->lengthfac)
+ }
+ }
+
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_TIME, ptex->time)
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_LIFE, ptex->life)
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_DENS, ptex->exist)
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_SIZE, ptex->size)
+ CLAMP_PARTICLE_TEXTURE_POSNEG(PAMAP_IVEL, ptex->ivel)
+ CLAMP_PARTICLE_TEXTURE_POSNEG(PAMAP_FIELD, ptex->field)
+ CLAMP_PARTICLE_TEXTURE_POSNEG(PAMAP_GRAVITY, ptex->gravity)
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_DAMP, ptex->damp)
+ CLAMP_PARTICLE_TEXTURE_POS(PAMAP_LENGTH, ptex->length)
}
/************************************************/
/* Particle State */
@@ -3829,28 +3868,8 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float UNUSED
ParticleSettings *part = psys->part;
float size; // time XXX
- if(part->childtype==PART_CHILD_FACES){
+ if(part->childtype==PART_CHILD_FACES)
size=part->size;
-
-#if 0 // XXX old animation system
- if((part->flag&PART_ABS_TIME)==0 && part->ipo){
- IpoCurve *icu;
-
- if(pa_time)
- time=*pa_time;
- else
- time=psys_get_child_time(psys,cpa,cfra,NULL,NULL);
-
- /* correction for lifetime */
- calc_ipo(part->ipo, 100*time);
-
- for(icu = part->ipo->curve.first; icu; icu=icu->next) {
- if(icu->adrcode == PART_SIZE)
- size = icu->curval;
- }
- }
-#endif // XXX old animation system
- }
else
size=psys->particles[cpa->parent].size;
@@ -3866,19 +3885,7 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
ParticleSystem *psys = ctx->sim.psys;
int i = cpa - psys->child;
- ptex->length= 1.0f - part->randlength * PSYS_FRAND(i + 26);
- ptex->clump=1.0;
- ptex->kink=1.0;
- ptex->rough1= 1.0;
- ptex->rough2= 1.0;
- ptex->roughe= 1.0;
- ptex->exist= 1.0;
- ptex->effector= 1.0;
-
- ptex->length*= part->clength_thres < PSYS_FRAND(i + 27) ? part->clength : 1.0f;
-
- get_cpa_texture(ctx->dm,ctx->ma,cpa_num,cpa_fuv,orco,ptex,
- MAP_PA_DENS|MAP_PA_LENGTH|MAP_PA_CLUMP|MAP_PA_KINK|MAP_PA_ROUGH);
+ get_cpa_texture(ctx->dm, psys, part, psys->particles + cpa->pa[0], i, cpa_num, cpa_fuv, orco, ptex, PAMAP_DENS|PAMAP_CHILD, psys->cfra);
if(ptex->exist < PSYS_FRAND(i + 24))
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 2e2decdf84d..409e9876599 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1519,62 +1519,37 @@ void psys_threads_free(ParticleThread *threads)
/* set particle parameters that don't change during particle's life */
void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p)
{
- ParticleSettings *part = sim->psys->part;
+ ParticleSystem *psys = sim->psys;
+ ParticleSettings *part = psys->part;
ParticleTexture ptex;
- Material *ma=0;
- //IpoCurve *icu=0; // XXX old animation system
- int totpart;
-
- totpart=sim->psys->totpart;
-
- ptex.life=ptex.size=ptex.exist=ptex.length=1.0;
- ptex.time=(float)p/(float)totpart;
-
- BLI_srandom(sim->psys->seed + p + 125);
-
- if(part->from!=PART_FROM_PARTICLE && part->type!=PART_FLUID){
- ma=give_current_material(sim->ob,part->omat);
-
- /* TODO: needs some work to make most blendtypes generally usefull */
- psys_get_texture(sim,ma,pa,&ptex,MAP_PA_INIT);
- }
-
- if(part->type==PART_HAIR)
- pa->time= 0.0f;
- //else if(part->type==PART_REACTOR && (part->flag&PART_REACT_STA_END)==0)
- // pa->time= 300000.0f; /* max frame */
- else{
- //icu=find_ipocurve(psys->part->ipo,PART_EMIT_TIME);
- //if(icu){
- // calc_icu(icu,100*ptex.time);
- // ptex.time=icu->curval;
- //}
- pa->time= part->sta + (part->end - part->sta)*ptex.time;
- }
+ pa->flag &= ~PARS_UNEXIST;
- if(part->type!=PART_HAIR && part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
- if(ptex.exist < BLI_frand())
+ if(part->from != PART_FROM_PARTICLE && part->type != PART_FLUID) {
+ psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.f);
+
+ if(ptex.exist < PSYS_FRAND(p+125))
pa->flag |= PARS_UNEXIST;
- else
- pa->flag &= ~PARS_UNEXIST;
+
+ pa->time = (part->type == PART_HAIR) ? 0.f : part->sta + (part->end - part->sta)*ptex.time;
}
- pa->hair_index=0;
+ pa->hair_index = 0;
/* we can't reset to -1 anymore since we've figured out correct index in distribute_particles */
/* usage other than straight after distribute has to handle this index by itself - jahka*/
//pa->num_dmcache = DMCACHE_NOTFOUND; /* assume we dont have a derived mesh face */
}
static void initialize_all_particles(ParticleSimulationData *sim)
{
- //IpoCurve *icu=0; // XXX old animation system
ParticleSystem *psys = sim->psys;
PARTICLE_P;
psys->totunexist = 0;
LOOP_PARTICLES {
- initialize_particle(sim, pa, p);
+ if((pa->flag & PARS_UNEXIST)==0)
+ initialize_particle(sim, pa, p);
+
if(pa->flag & PARS_UNEXIST)
psys->totunexist++;
}
@@ -1616,60 +1591,6 @@ static void initialize_all_particles(ParticleSimulationData *sim)
}
}
-
- if(psys->part->type != PART_FLUID) {
-#if 0 // XXX old animation system
- icu=find_ipocurve(psys->part->ipo,PART_EMIT_FREQ);
- if(icu){
- float time=psys->part->sta, end=psys->part->end;
- float v1, v2, a=0.0f, t1,t2, d;
-
- p=0;
- pa=psys->particles;
-
-
- calc_icu(icu,time);
- v1=icu->curval;
- if(v1<0.0f) v1=0.0f;
-
- calc_icu(icu,time+1.0f);
- v2=icu->curval;
- if(v2<0.0f) v2=0.0f;
-
- for(p=0, pa=psys->particles; p<totpart && time<end; p++, pa++){
- while(a+0.5f*(v1+v2) < (float)(p+1) && time<end){
- a+=0.5f*(v1+v2);
- v1=v2;
- time++;
- calc_icu(icu,time+1.0f);
- v2=icu->curval;
- }
- if(time<end){
- if(v1==v2){
- pa->time=time+((float)(p+1)-a)/v1;
- }
- else{
- d=(float)sqrt(v1*v1-2.0f*(v2-v1)*(a-(float)(p+1)));
- t1=(-v1+d)/(v2-v1);
- t2=(-v1-d)/(v2-v1);
-
- /* the root between 0-1 is the correct one */
- if(t1>0.0f && t1<=1.0f)
- pa->time=time+t1;
- else
- pa->time=time+t2;
- }
- }
-
- pa->dietime = pa->time+pa->lifetime;
- pa->flag &= ~PARS_UNEXIST;
- }
- for(; p<totpart; p++, pa++){
- pa->flag |= PARS_UNEXIST;
- }
- }
-#endif // XXX old animation system
- }
}
/* sets particle to the emitter surface with initial velocity & rotation */
void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, float cfra)
@@ -1678,35 +1599,14 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
ParticleSystem *psys = sim->psys;
ParticleSettings *part;
ParticleTexture ptex;
- ParticleKey state;
- //IpoCurve *icu=0; // XXX old animation system
float fac, phasefac, nor[3]={0,0,0},loc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
float r_vel[3],r_ave[3],r_rot[4],vec[3],p_vel[3]={0.0,0.0,0.0};
float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0};
- float q_phase[4], r_phase;
+ float q_phase[4];
int p = pa - psys->particles;
part=psys->part;
-
- ptex.ivel=1.0;
- ptex.life=1.0;
-
- /* we need to get every random even if they're not used so that they don't effect eachother */
- r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f);
- r_vel[1] = 2.0f * (PSYS_FRAND(p + 11) - 0.5f);
- r_vel[2] = 2.0f * (PSYS_FRAND(p + 12) - 0.5f);
-
- r_ave[0] = 2.0f * (PSYS_FRAND(p + 13) - 0.5f);
- r_ave[1] = 2.0f * (PSYS_FRAND(p + 14) - 0.5f);
- r_ave[2] = 2.0f * (PSYS_FRAND(p + 15) - 0.5f);
-
- r_rot[0] = 2.0f * (PSYS_FRAND(p + 16) - 0.5f);
- r_rot[1] = 2.0f * (PSYS_FRAND(p + 17) - 0.5f);
- r_rot[2] = 2.0f * (PSYS_FRAND(p + 18) - 0.5f);
- r_rot[3] = 2.0f * (PSYS_FRAND(p + 19) - 0.5f);
- normalize_qt(r_rot);
-
- r_phase = PSYS_FRAND(p + 20);
+#if 0 /* deprecated code */
if(part->from==PART_FROM_PARTICLE){
float speed;
ParticleSimulationData tsim= {0};
@@ -1733,79 +1633,93 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
VECCOPY(pa->fuv, loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */
}
else{
- /* get precise emitter matrix if particle is born */
- if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= sim->psys->cfra) {
- /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */
- BKE_animsys_evaluate_animdata(&sim->ob->id, sim->ob->adt, pa->time, ADT_RECALC_ANIM);
- where_is_object_time(sim->scene, sim->ob, pa->time);
- }
+#endif
+ /* get precise emitter matrix if particle is born */
+ if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= sim->psys->cfra) {
+ /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */
+ BKE_animsys_evaluate_animdata(&sim->ob->id, sim->ob->adt, pa->time, ADT_RECALC_ANIM);
+ where_is_object_time(sim->scene, sim->ob, pa->time);
+ }
- /* get birth location from object */
- if(part->tanfac!=0.0)
- psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
- else
- psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
+ /* get birth location from object */
+ if(part->tanfac != 0.f)
+ psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
+ else
+ psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
- /* get possible textural influence */
- psys_get_texture(sim, give_current_material(sim->ob,part->omat), pa, &ptex, MAP_PA_IVEL|MAP_PA_LIFE);
+ /* get possible textural influence */
+ psys_get_texture(sim, pa, &ptex, PAMAP_IVEL|PAMAP_LIFE, cfra);
- //if(vg_vel && pa->num != -1)
- // ptex.ivel*=psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_vel);
-
- /* particles live in global space so */
- /* let's convert: */
- /* -location */
- mul_m4_v3(ob->obmat,loc);
+ /* particles live in global space so */
+ /* let's convert: */
+ /* -location */
+ mul_m4_v3(ob->obmat, loc);
- /* -normal */
- mul_mat3_m4_v3(ob->obmat,nor);
- normalize_v3(nor);
-
- /* -tangent */
- if(part->tanfac!=0.0){
- //float phase=vg_rot?2.0f*(psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f;
- float phase=0.0f;
- mul_v3_fl(vtan,-(float)cos(M_PI*(part->tanphase+phase)));
- fac=-(float)sin(M_PI*(part->tanphase+phase));
- VECADDFAC(vtan,vtan,utan,fac);
-
- mul_mat3_m4_v3(ob->obmat,vtan);
-
- VECCOPY(utan,nor);
- mul_v3_fl(utan,dot_v3v3(vtan,nor));
- VECSUB(vtan,vtan,utan);
+ /* -normal */
+ mul_mat3_m4_v3(ob->obmat, nor);
+ normalize_v3(nor);
+
+ /* -tangent */
+ if(part->tanfac!=0.0){
+ //float phase=vg_rot?2.0f*(psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f;
+ float phase=0.0f;
+ mul_v3_fl(vtan,-(float)cos(M_PI*(part->tanphase+phase)));
+ fac=-(float)sin(M_PI*(part->tanphase+phase));
+ VECADDFAC(vtan,vtan,utan,fac);
+
+ mul_mat3_m4_v3(ob->obmat,vtan);
+
+ VECCOPY(utan,nor);
+ mul_v3_fl(utan,dot_v3v3(vtan,nor));
+ VECSUB(vtan,vtan,utan);
- normalize_v3(vtan);
- }
+ normalize_v3(vtan);
+ }
- /* -velocity */
- if(part->randfac!=0.0){
- mul_mat3_m4_v3(ob->obmat,r_vel);
- normalize_v3(r_vel);
- }
+ /* -velocity */
+ if(part->randfac!=0.0){
+ r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f);
+ r_vel[1] = 2.0f * (PSYS_FRAND(p + 11) - 0.5f);
+ r_vel[2] = 2.0f * (PSYS_FRAND(p + 12) - 0.5f);
- /* -angular velocity */
- if(part->avemode==PART_AVE_RAND){
- mul_mat3_m4_v3(ob->obmat,r_ave);
- normalize_v3(r_ave);
- }
+ mul_mat3_m4_v3(ob->obmat, r_vel);
+ normalize_v3(r_vel);
+ }
+
+ /* -angular velocity */
+ if(part->avemode==PART_AVE_RAND){
+ r_ave[0] = 2.0f * (PSYS_FRAND(p + 13) - 0.5f);
+ r_ave[1] = 2.0f * (PSYS_FRAND(p + 14) - 0.5f);
+ r_ave[2] = 2.0f * (PSYS_FRAND(p + 15) - 0.5f);
+
+ mul_mat3_m4_v3(ob->obmat,r_ave);
+ normalize_v3(r_ave);
+ }
- /* -rotation */
- if(part->randrotfac != 0.0f){
- mat4_to_quat(rot,ob->obmat);
- mul_qt_qtqt(r_rot,r_rot,rot);
- }
+ /* -rotation */
+ if(part->randrotfac != 0.0f){
+ r_rot[0] = 2.0f * (PSYS_FRAND(p + 16) - 0.5f);
+ r_rot[1] = 2.0f * (PSYS_FRAND(p + 17) - 0.5f);
+ r_rot[2] = 2.0f * (PSYS_FRAND(p + 18) - 0.5f);
+ r_rot[3] = 2.0f * (PSYS_FRAND(p + 19) - 0.5f);
+ normalize_qt(r_rot);
+
+ mat4_to_quat(rot,ob->obmat);
+ mul_qt_qtqt(r_rot,r_rot,rot);
+ }
+#if 0
}
+#endif
if(part->phystype==PART_PHYS_BOIDS && pa->boid) {
BoidParticle *bpa = pa->boid;
float dvec[3], q[4], mat[3][3];
- VECCOPY(pa->state.co,loc);
+ copy_v3_v3(pa->state.co,loc);
/* boids don't get any initial velocity */
- pa->state.vel[0]=pa->state.vel[1]=pa->state.vel[2]=0.0f;
+ zero_v3(pa->state.vel);
/* boids store direction in ave */
if(fabs(nor[2])==1.0f) {
@@ -1844,66 +1758,56 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
/* -velocity from: */
/* *reactions */
- if(dtime>0.0f){
- VECSUB(vel,pa->state.vel,pa->prev_state.vel);
+ if(dtime > 0.f){
+ sub_v3_v3v3(vel, pa->state.vel, pa->prev_state.vel);
}
/* *emitter velocity */
- if(dtime!=0.0 && part->obfac!=0.0){
- VECSUB(vel,loc,pa->state.co);
- mul_v3_fl(vel,part->obfac/dtime);
+ if(dtime != 0.f && part->obfac != 0.f){
+ sub_v3_v3v3(vel, loc, pa->state.co);
+ mul_v3_fl(vel, part->obfac/dtime);
}
/* *emitter normal */
- if(part->normfac!=0.0)
- VECADDFAC(vel,vel,nor,part->normfac);
+ if(part->normfac != 0.f)
+ madd_v3_v3fl(vel, nor, part->normfac);
/* *emitter tangent */
- if(sim->psmd && part->tanfac!=0.0)
- VECADDFAC(vel,vel,vtan,part->tanfac);
- //VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_tan):1.0f));
+ if(sim->psmd && part->tanfac != 0.f)
+ madd_v3_v3fl(vel, vtan, part->tanfac);
/* *emitter object orientation */
- if(part->ob_vel[0]!=0.0) {
+ if(part->ob_vel[0] != 0.f) {
normalize_v3_v3(vec, ob->obmat[0]);
- VECADDFAC(vel, vel, vec, part->ob_vel[0]);
+ madd_v3_v3fl(vel, vec, part->ob_vel[0]);
}
- if(part->ob_vel[1]!=0.0) {
+ if(part->ob_vel[1] != 0.f) {
normalize_v3_v3(vec, ob->obmat[1]);
- VECADDFAC(vel, vel, vec, part->ob_vel[1]);
+ madd_v3_v3fl(vel, vec, part->ob_vel[1]);
}
- if(part->ob_vel[2]!=0.0) {
+ if(part->ob_vel[2] != 0.f) {
normalize_v3_v3(vec, ob->obmat[2]);
- VECADDFAC(vel, vel, vec, part->ob_vel[2]);
+ madd_v3_v3fl(vel, vec, part->ob_vel[2]);
}
/* *texture */
/* TODO */
/* *random */
- if(part->randfac!=0.0)
- VECADDFAC(vel,vel,r_vel,part->randfac);
+ if(part->randfac != 0.f)
+ madd_v3_v3fl(vel, r_vel, part->randfac);
/* *particle */
- if(part->partfac!=0.0)
- VECADDFAC(vel,vel,p_vel,part->partfac);
-
- //icu=find_ipocurve(psys->part->ipo,PART_EMIT_VEL);
- //if(icu){
- // calc_icu(icu,100*((pa->time-part->sta)/(part->end-part->sta)));
- // ptex.ivel*=icu->curval;
- //}
-
- mul_v3_fl(vel,ptex.ivel);
+ if(part->partfac != 0.f)
+ madd_v3_v3fl(vel, p_vel, part->partfac);
- VECCOPY(pa->state.vel,vel);
+ mul_v3_v3fl(pa->state.vel, vel, ptex.ivel);
/* -location from emitter */
- VECCOPY(pa->state.co,loc);
+ copy_v3_v3(pa->state.co,loc);
/* -rotation */
- pa->state.rot[0]=1.0;
- pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0.0;
+ unit_qt(pa->state.rot);
if(part->rotmode){
/* create vector into which rotation is aligned */
@@ -1939,7 +1843,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
/* rotation phase */
phasefac = part->phasefac;
if(part->randphasefac != 0.0f)
- phasefac += part->randphasefac * r_phase;
+ phasefac += part->randphasefac * PSYS_FRAND(p + 20);
axis_angle_to_quat( q_phase,x_vec, phasefac*(float)M_PI);
/* combine base rotation & phase */
@@ -1948,25 +1852,19 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
/* -angular velocity */
- pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0;
+ zero_v3(pa->state.ave);
if(part->avemode){
switch(part->avemode){
case PART_AVE_SPIN:
- VECCOPY(pa->state.ave,vel);
+ copy_v3_v3(pa->state.ave, vel);
break;
case PART_AVE_RAND:
- VECCOPY(pa->state.ave,r_ave);
+ copy_v3_v3(pa->state.ave, r_ave);
break;
}
normalize_v3(pa->state.ave);
mul_v3_fl(pa->state.ave,part->avefac);
-
- //icu=find_ipocurve(psys->part->ipo,PART_EMIT_AVE);
- //if(icu){
- // calc_icu(icu,100*((pa->time-part->sta)/(part->end-part->sta)));
- // mul_v3_fl(pa->state.ave,icu->curval);
- //}
}
}
@@ -1975,7 +1873,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
pa->lifetime = 100.0f;
}
else{
- pa->lifetime = part->lifetime*ptex.life;
+ pa->lifetime = part->lifetime * ptex.life;
if(part->randlife != 0.0)
pa->lifetime *= 1.0f - part->randlife * PSYS_FRAND(p + 21);
@@ -2002,15 +1900,9 @@ static void reset_all_particles(ParticleSimulationData *sim, float dtime, float
{
ParticleData *pa;
int p, totpart=sim->psys->totpart;
- //float *vg_vel=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_VEL);
- //float *vg_tan=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_TAN);
- //float *vg_rot=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_ROT);
for(p=from, pa=sim->psys->particles+from; p<totpart; p++, pa++)
reset_particle(sim, pa, dtime, cfra);
-
- //if(vg_vel)
- // MEM_freeN(vg_vel);
}
/************************************************/
/* Particle targets */
@@ -2542,6 +2434,9 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
float force[3],impulse[3],dx[4][3],dv[4][3],oldpos[3];
float dtime=dfra*timestep, time, pa_mass=part->mass, fac /*, fra=sim->psys->cfra*/;
int i, steps=1;
+ ParticleTexture ptex;
+
+ psys_get_texture(sim, pa, &ptex, PAMAP_PHYSICS, cfra);
/* maintain angular velocity */
VECCOPY(pa->state.ave,pa->prev_state.ave);
@@ -2575,6 +2470,9 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
if(part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)
pdDoEffectors(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse);
+ mul_v3_fl(force, ptex.field);
+ mul_v3_fl(impulse, ptex.field);
+
/* calculate air-particle interaction */
if(part->dragfac!=0.0f){
fac=-part->dragfac*pa->size*pa->size*len_v3(states[i].vel);
@@ -2595,10 +2493,7 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
if(psys_uses_gravity(sim)
/* normal gravity is too strong for hair so it's disabled by default */
&& (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)) {
- float gravity[3];
- VECCOPY(gravity, sim->scene->physics_settings.gravity);
- mul_v3_fl(gravity, part->effector_weights->global_gravity);
- VECADD(force,force,gravity);
+ madd_v3_v3fl(force, sim->scene->physics_settings.gravity, part->effector_weights->global_gravity * ptex.gravity);
}
/* calculate next state */
@@ -2679,8 +2574,8 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra
}
/* damp affects final velocity */
- if(part->dampfac!=0.0)
- mul_v3_fl(pa->state.vel,1.0f-part->dampfac);
+ if(part->dampfac != 0.f)
+ mul_v3_fl(pa->state.vel, 1.f - part->dampfac * ptex.damp);
VECCOPY(pa->state.ave, states->ave);
@@ -3471,6 +3366,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
ParticleSystem *psys = sim->psys;
ParticleSettings *part=psys->part;
BoidBrainData bbd;
+ ParticleTexture ptex;
PARTICLE_P;
float timestep;
/* frame & time changes */
@@ -3485,7 +3381,8 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
if(dfra<0.0){
LOOP_EXISTING_PARTICLES {
- pa->size = part->size;
+ psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
+ pa->size = part->size*ptex.size;
if(part->randsize > 0.0)
pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
@@ -3538,7 +3435,9 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra)
LOOP_SHOWN_PARTICLES {
copy_particle_key(&pa->prev_state,&pa->state,1);
- pa->size = part->size;
+ psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
+
+ pa->size = part->size*ptex.size;
if(part->randsize > 0.0)
pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
@@ -3685,6 +3584,7 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
{
ParticleSystem *psys = sim->psys;
ParticleSettings *part = psys->part;
+ ParticleTexture ptex;
PARTICLE_P;
float disp, dietime;
@@ -3695,7 +3595,8 @@ static void cached_step(ParticleSimulationData *sim, float cfra)
disp= (float)psys_get_current_display_percentage(psys)/100.0f;
LOOP_PARTICLES {
- pa->size = part->size;
+ psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
+ pa->size = part->size*ptex.size;
if(part->randsize > 0.0)
pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 57c629d5544..0129e709505 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -51,6 +51,7 @@
#include "DNA_brush_types.h"
#include "DNA_node_types.h"
#include "DNA_color_types.h"
+#include "DNA_particle_types.h"
#include "IMB_imbuf.h"
@@ -671,7 +672,9 @@ void default_mtex(MTex *mtex)
mtex->lifefac= 1.0f;
mtex->sizefac= 1.0f;
mtex->ivelfac= 1.0f;
- mtex->pvelfac= 1.0f;
+ mtex->dampfac= 1.0f;
+ mtex->gravityfac= 1.0f;
+ mtex->fieldfac= 1.0f;
mtex->normapspace= MTEX_NSPACE_TANGENT;
}
@@ -1167,6 +1170,42 @@ void set_current_brush_texture(Brush *br, Tex *newtex)
}
}
+Tex *give_current_particle_texture(ParticleSettings *part)
+{
+ MTex *mtex= NULL;
+ Tex *tex= NULL;
+
+ if(!part) return 0;
+
+ mtex= part->mtex[(int)(part->texact)];
+ if(mtex) tex= mtex->tex;
+
+ return tex;
+}
+
+void set_current_particle_texture(ParticleSettings *part, Tex *newtex)
+{
+ int act= part->texact;
+
+ if(part->mtex[act] && part->mtex[act]->tex)
+ id_us_min(&part->mtex[act]->tex->id);
+
+ if(newtex) {
+ if(!part->mtex[act]) {
+ part->mtex[act]= add_mtex();
+ part->mtex[act]->texco= TEXCO_ORCO;
+ part->mtex[act]->blendtype= MTEX_MUL;
+ }
+
+ part->mtex[act]->tex= newtex;
+ id_us_plus(&newtex->id);
+ }
+ else if(part->mtex[act]) {
+ MEM_freeN(part->mtex[act]);
+ part->mtex[act]= NULL;
+ }
+}
+
/* ------------------------------------------------------------------------- */
EnvMap *BKE_add_envmap(void)