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.
This commit is contained in:
parent
c8c86aa6a1
commit
fafbd9d71b
|
@ -60,6 +60,12 @@ def context_tex_datablock(context):
|
|||
return idblock
|
||||
|
||||
idblock = context.brush
|
||||
if idblock:
|
||||
return idblock
|
||||
|
||||
if context.particle_system:
|
||||
idblock = context.particle_system.settings
|
||||
|
||||
return idblock
|
||||
|
||||
|
||||
|
@ -84,7 +90,7 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel, bpy.types.Panel):
|
|||
engine = context.scene.render.engine
|
||||
if not hasattr(context, "texture_slot"):
|
||||
return False
|
||||
return ((context.material or context.world or context.lamp or context.brush or context.texture)
|
||||
return ((context.material or context.world or context.lamp or context.brush or context.texture or context.particle_system)
|
||||
and (engine in cls.COMPAT_ENGINES))
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -983,20 +989,49 @@ class TEXTURE_PT_influence(TextureSlotPanel, bpy.types.Panel):
|
|||
col = split.column()
|
||||
factor_but(col, "use_map_zenith_up", "zenith_up_factor", "Zenith Up")
|
||||
factor_but(col, "use_map_zenith_down", "zenith_down_factor", "Zenith Down")
|
||||
elif isinstance(idblock, bpy.types.ParticleSettings):
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
col.label(text="General:")
|
||||
factor_but(col, "use_map_time", "time_factor", "Time")
|
||||
factor_but(col, "use_map_life", "life_factor", "Lifetime")
|
||||
factor_but(col, "use_map_density", "density_factor", "Density")
|
||||
factor_but(col, "use_map_size", "size_factor", "Size")
|
||||
|
||||
col = split.column()
|
||||
col.label(text="Physics:")
|
||||
factor_but(col, "use_map_velocity", "velocity_factor", "Velocity")
|
||||
factor_but(col, "use_map_damp", "damp_factor", "Damp")
|
||||
factor_but(col, "use_map_gravity", "gravity_factor", "Gravity")
|
||||
factor_but(col, "use_map_field", "field_factor", "Force Fields")
|
||||
|
||||
layout.label(text="Hair:")
|
||||
|
||||
split = layout.split()
|
||||
|
||||
col = split.column()
|
||||
factor_but(col, "use_map_length", "length_factor", "Length")
|
||||
factor_but(col, "use_map_clump", "clump_factor", "Clump")
|
||||
|
||||
col = split.column()
|
||||
factor_but(col, "use_map_kink", "kink_factor", "Kink")
|
||||
factor_but(col, "use_map_rough", "rough_factor", "Rough")
|
||||
|
||||
layout.separator()
|
||||
|
||||
if not isinstance(idblock, bpy.types.ParticleSettings):
|
||||
split = layout.split()
|
||||
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.prop(tex, "blend_type", text="Blend")
|
||||
col.prop(tex, "use_rgb_to_intensity")
|
||||
# color is used on grayscale textures even when use_rgb_to_intensity is disabled.
|
||||
col.prop(tex, "color", text="")
|
||||
|
||||
col = split.column()
|
||||
col.prop(tex, "blend_type", text="Blend")
|
||||
col.prop(tex, "use_rgb_to_intensity")
|
||||
# color is used on grayscale textures even when use_rgb_to_intensity is disabled.
|
||||
col.prop(tex, "color", text="")
|
||||
|
||||
col = split.column()
|
||||
col.prop(tex, "invert", text="Negative")
|
||||
col.prop(tex, "use_stencil")
|
||||
col = split.column()
|
||||
col.prop(tex, "invert", text="Negative")
|
||||
col.prop(tex, "use_stencil")
|
||||
|
||||
if isinstance(idblock, bpy.types.Material) or isinstance(idblock, bpy.types.World):
|
||||
col.prop(tex, "default_value", text="DVar", slider=True)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
MTex *mtex;
|
||||
int m,setvars=0;
|
||||
float value, rgba[4], texco[3];
|
||||
#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); }
|
||||
|
||||
if(ma) for(m=0; m<MAX_MTEX; m++){
|
||||
mtex=ma->mtex[m];
|
||||
if(mtex && (ma->septex & (1<<m))==0 && mtex->pmapto){
|
||||
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, **mtexp = part->mtex;
|
||||
int m,setvars=0;
|
||||
float value, rgba[4], texvec[3];
|
||||
|
||||
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);
|
||||
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)
|
||||
}
|
||||
}
|
||||
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); }
|
||||
|
||||
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))
|
||||
|
|
|
@ -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;
|
||||
pa->flag &= ~PARS_UNEXIST;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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 possible textural influence */
|
||||
psys_get_texture(sim, give_current_material(sim->ob,part->omat), pa, &ptex, MAP_PA_IVEL|MAP_PA_LIFE);
|
||||
|
||||
//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);
|
||||
|
||||
/* -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);
|
||||
}
|
||||
|
||||
|
||||
/* -velocity */
|
||||
if(part->randfac!=0.0){
|
||||
mul_mat3_m4_v3(ob->obmat,r_vel);
|
||||
normalize_v3(r_vel);
|
||||
}
|
||||
|
||||
/* -angular velocity */
|
||||
if(part->avemode==PART_AVE_RAND){
|
||||
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);
|
||||
}
|
||||
#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.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, pa, &ptex, PAMAP_IVEL|PAMAP_LIFE, cfra);
|
||||
|
||||
/* 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);
|
||||
|
||||
normalize_v3(vtan);
|
||||
}
|
||||
|
||||
|
||||
/* -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);
|
||||
|
||||
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){
|
||||
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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -3017,6 +3017,8 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
|
|||
{
|
||||
ParticleSettings *part;
|
||||
ParticleDupliWeight *dw;
|
||||
MTex *mtex;
|
||||
int a;
|
||||
|
||||
part= main->particle.first;
|
||||
while(part) {
|
||||
|
@ -3062,6 +3064,15 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(a=0; a<MAX_MTEX; a++) {
|
||||
mtex= part->mtex[a];
|
||||
if(mtex) {
|
||||
mtex->tex = newlibadr_us(fd, part->id.lib, mtex->tex);
|
||||
mtex->object = newlibadr(fd, part->id.lib, mtex->object);
|
||||
}
|
||||
}
|
||||
|
||||
part->id.flag -= LIB_NEEDLINK;
|
||||
}
|
||||
part= part->id.next;
|
||||
|
@ -3075,6 +3086,7 @@ static void direct_link_partdeflect(PartDeflect *pd)
|
|||
|
||||
static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
|
||||
{
|
||||
int a;
|
||||
part->adt= newdataadr(fd, part->adt);
|
||||
part->pd= newdataadr(fd, part->pd);
|
||||
part->pd2= newdataadr(fd, part->pd2);
|
||||
|
@ -3102,6 +3114,9 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
|
|||
link_list(fd, &state->actions);
|
||||
}
|
||||
}
|
||||
for(a=0; a<MAX_MTEX; a++) {
|
||||
part->mtex[a]= newdataadr(fd, part->mtex[a]);
|
||||
}
|
||||
}
|
||||
|
||||
static void lib_link_particlesystems(FileData *fd, Object *ob, ID *id, ListBase *particles)
|
||||
|
@ -6576,7 +6591,6 @@ static void do_version_mtex_factor_2_50(MTex **mtex_array, short idtype)
|
|||
mtex->lifefac= (neg & MAP_PA_LIFE)? -varfac: varfac;
|
||||
mtex->sizefac= (neg & MAP_PA_SIZE)? -varfac: varfac;
|
||||
mtex->ivelfac= (neg & MAP_PA_IVEL)? -varfac: varfac;
|
||||
mtex->pvelfac= (neg & MAP_PA_PVEL)? -varfac: varfac;
|
||||
|
||||
mtex->shadowfac= (neg & LAMAP_SHAD)? -colfac: colfac;
|
||||
|
||||
|
|
|
@ -823,6 +823,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
|
|||
{
|
||||
ParticleSettings *part;
|
||||
ParticleDupliWeight *dw;
|
||||
int a;
|
||||
|
||||
part= idbase->first;
|
||||
while(part) {
|
||||
|
@ -850,6 +851,10 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
|
|||
if(part->fluid && part->phystype == PART_PHYS_FLUID){
|
||||
writestruct(wd, DATA, "SPHFluidSettings", 1, part->fluid);
|
||||
}
|
||||
|
||||
for(a=0; a<MAX_MTEX; a++) {
|
||||
if(part->mtex[a]) writestruct(wd, DATA, "MTex", 1, part->mtex[a]);
|
||||
}
|
||||
}
|
||||
part= part->id.next;
|
||||
}
|
||||
|
|
|
@ -360,6 +360,7 @@ static int buttons_context_path_texture(ButsContextPath *path)
|
|||
Lamp *la;
|
||||
Brush *br;
|
||||
World *wo;
|
||||
ParticleSystem *psys;
|
||||
Tex *tex;
|
||||
PointerRNA *ptr= &path->ptr[path->len-1];
|
||||
int orig_len = path->len;
|
||||
|
@ -392,6 +393,18 @@ static int buttons_context_path_texture(ButsContextPath *path)
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
/* try particles */
|
||||
if((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) {
|
||||
psys= path->ptr[path->len-1].data;
|
||||
|
||||
if(psys && psys->part && GS(psys->part->id.name)==ID_PA) {
|
||||
tex= give_current_particle_texture(psys->part);
|
||||
|
||||
RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
|
||||
path->len++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* try material */
|
||||
if(buttons_context_path_material(path)) {
|
||||
ma= path->ptr[path->len-1].data;
|
||||
|
@ -733,6 +746,12 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
|
|||
if(br)
|
||||
CTX_data_pointer_set(result, &br->id, &RNA_BrushTextureSlot, &br->mtex);
|
||||
}
|
||||
else if((ptr=get_pointer_type(path, &RNA_ParticleSystem))) {
|
||||
ParticleSettings *part= ((ParticleSystem *)ptr->data)->part;
|
||||
|
||||
if(part)
|
||||
CTX_data_pointer_set(result, &part->id, &RNA_ParticleSettingsTextureSlot, part->mtex[(int)part->texact]);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,9 @@ static void set_texture_context(bContext *C, SpaceButs *sbuts)
|
|||
case BCONTEXT_WORLD:
|
||||
sbuts->texture_context = SB_TEXC_WORLD;
|
||||
break;
|
||||
case BCONTEXT_PARTICLE:
|
||||
sbuts->texture_context = SB_TEXC_PARTICLES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -281,6 +281,7 @@ static void buttons_area_listener(ScrArea *sa, wmNotifier *wmn)
|
|||
case ND_PARTICLE:
|
||||
if (wmn->action == NA_EDITED)
|
||||
buttons_area_redraw(sa, BCONTEXT_PARTICLE);
|
||||
sbuts->preview= 1;
|
||||
break;
|
||||
case ND_DRAW:
|
||||
buttons_area_redraw(sa, BCONTEXT_OBJECT);
|
||||
|
|
|
@ -142,7 +142,7 @@ typedef struct ParticleSettings {
|
|||
struct EffectorWeights *effector_weights;
|
||||
|
||||
int flag;
|
||||
short type, from, distr;
|
||||
short type, from, distr, texact;
|
||||
/* physics modes */
|
||||
short phystype, rotmode, avemode, reactevent;
|
||||
short draw, draw_as, draw_size, childtype;
|
||||
|
@ -155,7 +155,7 @@ typedef struct ParticleSettings {
|
|||
short adapt_angle, adapt_pix;
|
||||
|
||||
short disp, omat, interpolation, rotfrom, integrator;
|
||||
short kink, kink_axis;
|
||||
short kink, kink_axis, rt2;
|
||||
|
||||
/* billboards */
|
||||
short bb_align, bb_uv_split, bb_anim, bb_split_offset;
|
||||
|
@ -169,7 +169,7 @@ typedef struct ParticleSettings {
|
|||
/* general values */
|
||||
float sta, end, lifetime, randlife;
|
||||
float timetweak, jitfac, eff_hair, grid_rand;
|
||||
int totpart, userjit, grid_res, rt;
|
||||
int totpart, userjit, grid_res;
|
||||
|
||||
/* initial velocity factors */
|
||||
float normfac, obfac, randfac, partfac, tanfac, tanphase, reactfac;
|
||||
|
@ -208,6 +208,8 @@ typedef struct ParticleSettings {
|
|||
/* keyed particles */
|
||||
int keyed_loops;
|
||||
|
||||
struct MTex *mtex[18]; /* MAX_MTEX */
|
||||
|
||||
struct Group *dup_group;
|
||||
struct ListBase dupliweights;
|
||||
struct Group *eff_group; // deprecated
|
||||
|
@ -508,4 +510,25 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in
|
|||
#define PTARGET_MODE_FRIEND 1
|
||||
#define PTARGET_MODE_ENEMY 2
|
||||
|
||||
/* mapto */
|
||||
/* init */
|
||||
#define PAMAP_INIT 15
|
||||
#define PAMAP_TIME (1<<0) /* emission time */
|
||||
#define PAMAP_LIFE (1<<1) /* life time */
|
||||
#define PAMAP_DENS (1<<2) /* density */
|
||||
#define PAMAP_SIZE (1<<3) /* physical size */
|
||||
/* reset */
|
||||
#define PAMAP_IVEL (1<<5) /* initial velocity */
|
||||
/* physics */
|
||||
#define PAMAP_PHYSICS 3136
|
||||
#define PAMAP_FIELD (1<<6) /* force fields */
|
||||
#define PAMAP_GRAVITY (1<<10)
|
||||
#define PAMAP_DAMP (1<<11)
|
||||
/* children */
|
||||
#define PAMAP_CHILD 912
|
||||
#define PAMAP_CLUMP (1<<7)
|
||||
#define PAMAP_KINK (1<<8)
|
||||
#define PAMAP_ROUGH (1<<9)
|
||||
#define PAMAP_LENGTH (1<<4)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -636,6 +636,7 @@ typedef struct SpaceSound {
|
|||
#define SB_TEXC_MAT_OR_LAMP 0
|
||||
#define SB_TEXC_WORLD 1
|
||||
#define SB_TEXC_BRUSH 2
|
||||
#define SB_TEXC_PARTICLES 3
|
||||
|
||||
/* sbuts->align */
|
||||
#define BUT_FREE 0
|
||||
|
|
|
@ -77,9 +77,9 @@ typedef struct MTex {
|
|||
float densfac, scatterfac, reflfac;
|
||||
|
||||
/* particles */
|
||||
float timefac, lengthfac, clumpfac;
|
||||
float kinkfac, roughfac, padensfac;
|
||||
float lifefac, sizefac, ivelfac, pvelfac;
|
||||
float timefac, lengthfac, clumpfac, dampfac;
|
||||
float kinkfac, roughfac, padensfac, gravityfac;
|
||||
float lifefac, sizefac, ivelfac, fieldfac;
|
||||
|
||||
/* lamp */
|
||||
float shadowfac;
|
||||
|
|
|
@ -354,6 +354,7 @@ extern StructRNA RNA_ParticleHairKey;
|
|||
extern StructRNA RNA_ParticleInstanceModifier;
|
||||
extern StructRNA RNA_ParticleKey;
|
||||
extern StructRNA RNA_ParticleSettings;
|
||||
extern StructRNA RNA_ParticleSettingsTextureSlot;
|
||||
extern StructRNA RNA_SPHFluidSettings;
|
||||
extern StructRNA RNA_ParticleSystem;
|
||||
extern StructRNA RNA_ParticleSystemModifier;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
|
||||
#include "rna_internal.h"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_cloth_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
|
@ -38,6 +39,7 @@
|
|||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_boid_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
|
||||
#include "WM_types.h"
|
||||
#include "WM_api.h"
|
||||
|
@ -106,6 +108,7 @@ EnumPropertyItem part_hair_ren_as_items[] = {
|
|||
#include "BKE_modifier.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_pointcache.h"
|
||||
#include "BKE_texture.h"
|
||||
|
||||
/* use for object space hair get/set */
|
||||
static void rna_ParticleHairKey_location_object_info(PointerRNA *ptr, ParticleSystemModifierData **psmd_pt, ParticleData **pa_pt)
|
||||
|
@ -753,6 +756,28 @@ static char *rna_ParticleSystem_path(PointerRNA *ptr)
|
|||
return BLI_sprintfN("particle_systems[\"%s\"]", psys->name);
|
||||
}
|
||||
|
||||
static void rna_ParticleSettings_mtex_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
|
||||
{
|
||||
ParticleSettings *part= (ParticleSettings*)ptr->data;
|
||||
rna_iterator_array_begin(iter, (void*)part->mtex, sizeof(MTex*), MAX_MTEX, 0, NULL);
|
||||
}
|
||||
|
||||
static PointerRNA rna_ParticleSettings_active_texture_get(PointerRNA *ptr)
|
||||
{
|
||||
ParticleSettings *part= (ParticleSettings*)ptr->data;
|
||||
Tex *tex;
|
||||
|
||||
tex= give_current_particle_texture(part);
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_Texture, tex);
|
||||
}
|
||||
|
||||
static void rna_ParticleSettings_active_texture_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
ParticleSettings *part= (ParticleSettings*)ptr->data;
|
||||
|
||||
set_current_particle_texture(part, value.data);
|
||||
}
|
||||
|
||||
/* irritating string functions for each index :/ */
|
||||
static void rna_ParticleVGroup_name_get_0(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 0); }
|
||||
static void rna_ParticleVGroup_name_get_1(PointerRNA *ptr, char *value) { psys_vg_name_get__internal(ptr, value, 1); }
|
||||
|
@ -1095,6 +1120,230 @@ static void rna_def_fluid_settings(BlenderRNA *brna)
|
|||
|
||||
}
|
||||
|
||||
static void rna_def_particle_settings_mtex(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem texco_items[] = {
|
||||
{TEXCO_GLOB, "GLOBAL", 0, "Global", "Uses global coordinates for the texture coordinates"},
|
||||
{TEXCO_OBJECT, "OBJECT", 0, "Object", "Uses linked object's coordinates for texture coordinates"},
|
||||
{TEXCO_UV, "UV", 0, "UV", "Uses UV coordinates for texture coordinates"},
|
||||
{TEXCO_ORCO, "ORCO", 0, "Generated", "Uses the original undeformed coordinates of the object"},
|
||||
{TEXCO_STRAND, "STRAND", 0, "Strand / Particle", "Uses normalized strand texture coordinate (1D) or particle age (X) and trail position (Y)"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem prop_mapping_items[] = {
|
||||
{MTEX_FLAT, "FLAT", 0, "Flat", "Maps X and Y coordinates directly"},
|
||||
{MTEX_CUBE, "CUBE", 0, "Cube", "Maps using the normal vector"},
|
||||
{MTEX_TUBE, "TUBE", 0, "Tube", "Maps with Z as central axis"},
|
||||
{MTEX_SPHERE, "SPHERE", 0, "Sphere", "Maps with Z as central axis"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem prop_x_mapping_items[] = {
|
||||
{0, "NONE", 0, "None", ""},
|
||||
{1, "X", 0, "X", ""},
|
||||
{2, "Y", 0, "Y", ""},
|
||||
{3, "Z", 0, "Z", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem prop_y_mapping_items[] = {
|
||||
{0, "NONE", 0, "None", ""},
|
||||
{1, "X", 0, "X", ""},
|
||||
{2, "Y", 0, "Y", ""},
|
||||
{3, "Z", 0, "Z", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
static EnumPropertyItem prop_z_mapping_items[] = {
|
||||
{0, "NONE", 0, "None", ""},
|
||||
{1, "X", 0, "X", ""},
|
||||
{2, "Y", 0, "Y", ""},
|
||||
{3, "Z", 0, "Z", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
srna= RNA_def_struct(brna, "ParticleSettingsTextureSlot", "TextureSlot");
|
||||
RNA_def_struct_sdna(srna, "MTex");
|
||||
RNA_def_struct_ui_text(srna, "Particle Settings Texture Slot", "Texture slot for textures in a Particle Settings datablock");
|
||||
|
||||
prop= RNA_def_property(srna, "texture_coords", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "texco");
|
||||
RNA_def_property_enum_items(prop, texco_items);
|
||||
RNA_def_property_ui_text(prop, "Texture Coordinates", "Texture coordinates used to map the texture onto the background");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "object");
|
||||
RNA_def_property_struct_type(prop, "Object");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Object", "Object to use for mapping with Object texture coordinates");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "uvname");
|
||||
RNA_def_property_ui_text(prop, "UV Layer", "UV layer to use for mapping with UV texture coordinates");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "mapping_x", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "projx");
|
||||
RNA_def_property_enum_items(prop, prop_x_mapping_items);
|
||||
RNA_def_property_ui_text(prop, "X Mapping", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "mapping_y", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "projy");
|
||||
RNA_def_property_enum_items(prop, prop_y_mapping_items);
|
||||
RNA_def_property_ui_text(prop, "Y Mapping", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "mapping_z", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "projz");
|
||||
RNA_def_property_enum_items(prop, prop_z_mapping_items);
|
||||
RNA_def_property_ui_text(prop, "Z Mapping", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, prop_mapping_items);
|
||||
RNA_def_property_ui_text(prop, "Mapping", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
/* map to */
|
||||
prop= RNA_def_property(srna, "use_map_time", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_TIME);
|
||||
RNA_def_property_ui_text(prop, "Emission Time", "Affect the emission time of the particles");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_life", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_LIFE);
|
||||
RNA_def_property_ui_text(prop, "Life Time", "Affect the life time of the particles");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_density", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_DENS);
|
||||
RNA_def_property_ui_text(prop, "Density", "Affect the density of the particles");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_size", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_SIZE);
|
||||
RNA_def_property_ui_text(prop, "Size", "Affect the particle size");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_velocity", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_IVEL);
|
||||
RNA_def_property_ui_text(prop, "Initial Velocity", "Affect the particle initial velocity");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_field", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_FIELD);
|
||||
RNA_def_property_ui_text(prop, "Force Field", "Affect the particle force fields");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_gravity", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_GRAVITY);
|
||||
RNA_def_property_ui_text(prop, "Gravity", "Affect the particle gravity");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_damp", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_DAMP);
|
||||
RNA_def_property_ui_text(prop, "Damp", "Affect the particle velocity damping");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_clump", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_CLUMP);
|
||||
RNA_def_property_ui_text(prop, "Clump", "Affect the child clumping");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_kink", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_KINK);
|
||||
RNA_def_property_ui_text(prop, "Kink", "Affect the child kink");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_rough", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_ROUGH);
|
||||
RNA_def_property_ui_text(prop, "Rough", "Affect the child rough");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
|
||||
|
||||
prop= RNA_def_property(srna, "use_map_length", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "mapto", PAMAP_LENGTH);
|
||||
RNA_def_property_ui_text(prop, "Length", "Affect the child hair length");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
|
||||
|
||||
|
||||
/* influence factors */
|
||||
prop= RNA_def_property(srna, "time_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "timefac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Emission Time Factor", "Amount texture affects particle emission time");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "life_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "lifefac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Life Time Factor", "Amount texture affects particle life time");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "density_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "padensfac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Density Factor", "Amount texture affects particle density");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "size_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "sizefac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Size Factor", "Amount texture affects physical particle size");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "velocity_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "ivelfac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Velocity Factor", "Amount texture affects particle initial velocity");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
|
||||
prop= RNA_def_property(srna, "field_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "fieldfac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Field Factor", "Amount texture affects particle force fields");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "gravity_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "gravityfac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Gravity Factor", "Amount texture affects particle gravity");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
prop= RNA_def_property(srna, "damp_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "dampfac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Damp Factor", "Amount texture affects particle damping");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_reset");
|
||||
|
||||
|
||||
prop= RNA_def_property(srna, "length_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "lengthfac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Length Factor", "Amount texture affects child hair length");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
|
||||
|
||||
prop= RNA_def_property(srna, "clump_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "clumpfac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Clump Factor", "Amount texture affects child clump");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
|
||||
|
||||
prop= RNA_def_property(srna, "kink_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "kinkfac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Kink Factor", "Amount texture affects child kink");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
|
||||
|
||||
prop= RNA_def_property(srna, "rough_factor", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "roughfac");
|
||||
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
|
||||
RNA_def_property_ui_text(prop, "Rough Factor", "Amount texture affects child roughness");
|
||||
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
|
||||
}
|
||||
|
||||
static void rna_def_particle_settings(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
|
@ -1219,6 +1468,9 @@ static void rna_def_particle_settings(BlenderRNA *brna)
|
|||
RNA_def_struct_ui_text(srna, "Particle Settings", "Particle settings, reusable by multiple particle systems");
|
||||
RNA_def_struct_ui_icon(srna, ICON_PARTICLE_DATA);
|
||||
|
||||
rna_def_mtex_common(brna, srna, "rna_ParticleSettings_mtex_begin", "rna_ParticleSettings_active_texture_get",
|
||||
"rna_ParticleSettings_active_texture_set", "ParticleSettingsTextureSlot", "ParticleSettingsTextureSlots", "rna_Particle_reset");
|
||||
|
||||
/* fluid particle type can't be checked from the type value in rna as it's not shown in the menu */
|
||||
prop= RNA_def_property(srna, "is_fluid", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
|
@ -2487,6 +2739,7 @@ void RNA_def_particle(BlenderRNA *brna)
|
|||
rna_def_particle(brna);
|
||||
rna_def_particle_dupliweight(brna);
|
||||
rna_def_particle_system(brna);
|
||||
rna_def_particle_settings_mtex(brna);
|
||||
rna_def_particle_settings(brna);
|
||||
}
|
||||
|
||||
|
|
|
@ -765,6 +765,14 @@ static EnumPropertyItem *rna_SpaceProperties_texture_context_itemf(bContext *C,
|
|||
tmp.icon = ICON_MATERIAL;
|
||||
RNA_enum_item_add(&item, &totitem, &tmp);
|
||||
}
|
||||
|
||||
if(ob->particlesystem.first) {
|
||||
tmp.value = SB_TEXC_PARTICLES;
|
||||
tmp.description = "Show Particle Textures";
|
||||
tmp.identifier = "PARTICLE";
|
||||
tmp.icon = ICON_PARTICLES;
|
||||
RNA_enum_item_add(&item, &totitem, &tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if(scene && scene->world) {
|
||||
|
|
|
@ -185,6 +185,20 @@ void rna_TextureSlot_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
|||
case ID_BR:
|
||||
WM_main_add_notifier(NC_BRUSH, id);
|
||||
break;
|
||||
case ID_PA:
|
||||
{
|
||||
MTex *mtex= ptr->data;
|
||||
int recalc = OB_RECALC_DATA;
|
||||
|
||||
if(mtex->mapto & PAMAP_INIT)
|
||||
recalc |= PSYS_RECALC_RESET;
|
||||
if(mtex->mapto & PAMAP_CHILD)
|
||||
recalc |= PSYS_RECALC_CHILD;
|
||||
|
||||
DAG_id_tag_update(id, recalc);
|
||||
WM_main_add_notifier(NC_OBJECT|ND_PARTICLE|NA_EDITED, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue