Small particle effectors update:

* Greetings from farsthary: particle rotation is now taken into account for particle effector direction.
** This gives all kinds of new possibilities as he shows in his blog http://farsthary.wordpress.com/2011/02/08/vortex-particle-simple-tut/.
**The only modification I made to his patch was to use the actual rotated particle direction as the effector direction as this defaults to the particle velocity vector, so no actual new options are needed.
* I also added an "effector amount" setting for particle effectors so that only a part of the particles can be considered as effectors. This makes it possible to create simple "farsthary vortexes" with only one particle system.
* Also some tiny reorganization of the falloff min/max values for a nicer ui.
This commit is contained in:
Janne Karhu 2011-02-12 17:54:24 +00:00
parent d909e61d99
commit 0a83817672
6 changed files with 48 additions and 27 deletions

View File

@ -1061,12 +1061,16 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, bpy.types.Panel):
part = context.particle_system.settings
layout.prop(part, "use_self_effect")
row = layout.row()
row.prop(part, "use_self_effect")
row.prop(part, "effector_amount", text="Amount")
split = layout.split(percentage=0.2)
split.label(text="Type 1:")
split.prop(part.force_field_1, "type", text="")
basic_force_field_settings_ui(self, context, part.force_field_1)
if part.force_field_1.type != 'NONE':
layout.label(text="Falloff:")
basic_force_field_falloff_ui(self, context, part.force_field_1)
if part.force_field_1.type != 'NONE':
@ -1076,6 +1080,8 @@ class PARTICLE_PT_force_fields(ParticleButtonsPanel, bpy.types.Panel):
split.label(text="Type 2:")
split.prop(part.force_field_2, "type", text="")
basic_force_field_settings_ui(self, context, part.force_field_2)
if part.force_field_2.type != 'NONE':
layout.label(text="Falloff:")
basic_force_field_falloff_ui(self, context, part.force_field_2)

View File

@ -263,19 +263,24 @@ def basic_force_field_falloff_ui(self, context, field):
col = split.column()
col.prop(field, "z_direction", text="")
col.prop(field, "use_min_distance", text="Use Minimum")
col.prop(field, "use_max_distance", text="Use Maximum")
col = split.column()
col.prop(field, "falloff_power", text="Power")
sub = col.column()
split = layout.split()
col = split.column()
row = col.row(align=True)
row.prop(field, "use_min_distance", text="")
sub = row.row()
sub.active = field.use_min_distance
sub.prop(field, "distance_min", text="Distance")
sub = col.column()
sub.prop(field, "distance_min", text="Minimum")
col = split.column()
row = col.row(align=True)
row.prop(field, "use_max_distance", text="")
sub = row.row()
sub.active = field.use_max_distance
sub.prop(field, "distance_max", text="Distance")
sub.prop(field, "distance_max", text="Maximum")
def register():

View File

@ -651,11 +651,15 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
// eff->flag |= PE_VELOCITY_TO_IMPULSE;
//}
VECCOPY(efd->loc, state.co);
VECCOPY(efd->nor, state.vel);
if(real_velocity) {
VECCOPY(efd->vel, state.vel);
}
copy_v3_v3(efd->loc, state.co);
/* rather than use the velocity use rotated x-axis (defaults to velocity) */
efd->nor[0] = 1.f;
efd->nor[1] = efd->nor[2] = 0.f;
mul_qt_v3(state.rot, efd->nor);
if(real_velocity)
copy_v3_v3(efd->vel, state.vel);
efd->size = pa->size;
}
@ -720,7 +724,7 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin
return ret;
}
static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int *tot, int *p)
static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoint *point, int *tot, int *p, int *step)
{
if(eff->pd->shape == PFIELD_SHAPE_POINTS) {
efd->index = p;
@ -753,6 +757,13 @@ static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoin
*p= point->index % eff->psys->totpart;
*tot= *p + 1;
}
if(eff->psys->part->effector_amount) {
int totpart = eff->psys->totpart;
int amount = eff->psys->part->effector_amount;
*step = (totpart > amount) ? totpart/amount : 1;
}
}
else {
*p = 0;
@ -990,7 +1001,7 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we
*/
EffectorCache *eff;
EffectorData efd;
int p=0, tot = 1;
int p=0, tot = 1, step = 1;
/* Cycle through collected objects, get total of (1/(gravity_strength * dist^gravity_power)) */
/* Check for min distance here? (yes would be cool to add that, ton) */
@ -998,9 +1009,9 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we
if(effectors) for(eff = effectors->first; eff; eff=eff->next) {
/* object effectors were fully checked to be OK to evaluate! */
get_effector_tot(eff, &efd, point, &tot, &p);
get_effector_tot(eff, &efd, point, &tot, &p, &step);
for(; p<tot; p++) {
for(; p<tot; p+=step) {
if(get_effector_data(eff, &efd, point, 0)) {
efd.falloff= effector_falloff(eff, &efd, point, weights);

View File

@ -3498,8 +3498,6 @@ static void default_particle_settings(ParticleSettings *part)
part->normfac= 1.0f;
part->reactshape=1.0f;
part->mass=1.0;
part->size=0.05;
part->childsize=1.0;

View File

@ -169,14 +169,14 @@ typedef struct ParticleSettings {
/* general values */
float sta, end, lifetime, randlife;
float timetweak, jitfac, eff_hair, grid_rand;
int totpart, userjit, grid_res;
int totpart, userjit, grid_res, effector_amount;
/* initial velocity factors */
float normfac, obfac, randfac, partfac, tanfac, tanphase, reactfac;
float ob_vel[3];
float avefac, phasefac, randrotfac, randphasefac;
/* physical properties */
float mass, size, randsize, reactshape;
float mass, size, randsize;
/* global physical properties */
float acc[3], dragfac, brownfac, dampfac;
/* length */

View File

@ -1965,6 +1965,13 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Grid Randomness", "Add random offset to the grid locations");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop= RNA_def_property(srna, "effector_amount", PROP_INT, PROP_UNSIGNED);
/* in theory PROP_ANIMATABLE perhaps should be cleared, but animating this can give some interesting results! */
RNA_def_property_range(prop, 0, 10000); /* 10000 effectors will bel SLOW, but who knows */
RNA_def_property_ui_range(prop, 0, 100, 1, 0);
RNA_def_property_ui_text(prop, "Effector Amount", "How many particles are effectors (0 is all particles)");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
/* initial velocity factors */
prop= RNA_def_property(srna, "normal_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "normfac");//optional if prop names are the same
@ -2073,12 +2080,6 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Random Size", "Give the particle size a random variation");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
prop= RNA_def_property(srna, "reaction_shape", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "reactshape");
RNA_def_property_range(prop, 0.0f, 10.0f);
RNA_def_property_ui_text(prop, "Shape", "Power of reaction strength dependence on distance to target");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
/* global physical properties */
prop= RNA_def_property(srna, "drag_factor", PROP_FLOAT, PROP_NONE);