Curve-based control for "roughness" (noise displacement) of child hair.

This commit is contained in:
Lukas Tönne 2015-01-09 15:58:18 +01:00
parent c86d55d5e7
commit d1246969ed
8 changed files with 120 additions and 24 deletions

@ -1196,20 +1196,28 @@ class PARTICLE_PT_children(ParticleButtonsPanel, Panel):
sub.prop(part, "child_parting_max", text="Max")
col = split.column()
col.label(text="Roughness:")
sub = col.column(align=True)
sub.prop(part, "roughness_1", text="Uniform")
sub.prop(part, "roughness_1_size", text="Size")
col.prop(part, "use_roughness_curve")
if part.use_roughness_curve:
sub = col.column()
sub.template_curve_mapping(part, "roughness_curve")
sub.prop(part, "roughness_1", text="Roughness")
sub.prop(part, "roughness_1_size", text="Size")
else:
col.label(text="Roughness:")
sub = col.column(align=True)
sub.prop(part, "roughness_endpoint", "Endpoint")
sub.prop(part, "roughness_end_shape")
sub = col.column(align=True)
sub.prop(part, "roughness_1", text="Uniform")
sub.prop(part, "roughness_1_size", text="Size")
sub = col.column(align=True)
sub.prop(part, "roughness_2", text="Random")
sub.prop(part, "roughness_2_size", text="Size")
sub.prop(part, "roughness_2_threshold", slider=True)
sub = col.column(align=True)
sub.prop(part, "roughness_endpoint", "Endpoint")
sub.prop(part, "roughness_end_shape")
sub = col.column(align=True)
sub.prop(part, "roughness_2", text="Random")
sub.prop(part, "roughness_2_size", text="Size")
sub.prop(part, "roughness_2_threshold", slider=True)
layout.row().label(text="Kink:")
layout.row().prop(part, "kink", expand=True)

@ -340,6 +340,7 @@ int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct Pa
/* child paths */
void BKE_particlesettings_clump_curve_init(struct ParticleSettings *part);
void BKE_particlesettings_rough_curve_init(struct ParticleSettings *part);
void psys_apply_child_modifiers(struct ParticleThreadContext *ctx, struct ListBase *modifiers,
struct ChildParticle *cpa, struct ParticleTexture *ptex, const float orco[3], const float ornor[3], float hairmat[4][4],
struct ParticleCacheKey *keys, struct ParticleCacheKey *parent_keys);

@ -377,6 +377,8 @@ void BKE_particlesettings_free(ParticleSettings *part)
if (part->clumpcurve)
curvemapping_free(part->clumpcurve);
if (part->roughcurve)
curvemapping_free(part->roughcurve);
free_partdeflect(part->pd);
free_partdeflect(part->pd2);
@ -1785,6 +1787,8 @@ int do_guides(ParticleSettings *part, ListBase *effectors, ParticleKey *state, i
if (part->clumpcurve)
curvemapping_changed_all(part->clumpcurve);
if (part->roughcurve)
curvemapping_changed_all(part->roughcurve);
par.co[0] = par.co[1] = par.co[2] = 0.0f;
copy_v3_v3(key.co, vec_to_point);
@ -1991,6 +1995,8 @@ static bool psys_thread_context_init_path(ParticleThreadContext *ctx, ParticleSi
/* prepare curvemapping tables */
if (part->clumpcurve)
curvemapping_changed_all(part->clumpcurve);
if (part->roughcurve)
curvemapping_changed_all(part->roughcurve);
return true;
}
@ -3166,6 +3172,18 @@ void BKE_particlesettings_clump_curve_init(ParticleSettings *part)
part->clumpcurve = cumap;
}
void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
{
CurveMapping *cumap = curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
cumap->cm[0].curve[0].x = 0.0f;
cumap->cm[0].curve[0].y = 1.0f;
cumap->cm[0].curve[1].x = 1.0f;
cumap->cm[0].curve[1].y = 1.0f;
part->roughcurve = cumap;
}
ParticleSettings *BKE_particlesettings_copy(ParticleSettings *part)
{
ParticleSettings *partn;
@ -3179,6 +3197,8 @@ ParticleSettings *BKE_particlesettings_copy(ParticleSettings *part)
if (part->clumpcurve)
partn->clumpcurve = curvemapping_copy(part->clumpcurve);
if (part->roughcurve)
partn->roughcurve = curvemapping_copy(part->roughcurve);
partn->boids = boid_copy_settings(part->boids);

@ -413,7 +413,7 @@ static void do_rough(const float loc[3], float mat[4][4], float t, float fac, fl
madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
}
static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float shape, ParticleKey *state)
static void do_rough_end(const float loc[3], float mat[4][4], float t, float fac, float shape, ParticleKey *state)
{
float rough[2];
float roughfac;
@ -428,6 +428,27 @@ static void do_rough_end(float *loc, float mat[4][4], float t, float fac, float
madd_v3_v3fl(state->co, mat[1], rough[1]);
}
static void do_rough_curve(const float loc[3], float mat[4][4], float time, float fac, float size, CurveMapping *roughcurve, ParticleKey *state)
{
float rough[3];
float rco[3];
if (!roughcurve)
return;
fac *= CLAMPIS(curvemapping_evaluateF(roughcurve, 0, time), 0.0f, 1.0f);
copy_v3_v3(rco, loc);
mul_v3_fl(rco, time);
rough[0] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[0], rco[1], rco[2], 2, 0, 2);
rough[1] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[1], rco[2], rco[0], 2, 0, 2);
rough[2] = -1.0f + 2.0f * BLI_gTurbulence(size, rco[2], rco[0], rco[1], 2, 0, 2);
madd_v3_v3fl(state->co, mat[0], fac * rough[0]);
madd_v3_v3fl(state->co, mat[1], fac * rough[1]);
madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
}
void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *ptex, ParticleKey *par, float *par_rot, ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t)
{
ParticleSettings *part = sim->psys->part;
@ -462,18 +483,23 @@ void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *ptex, Part
}
}
if (rough1 > 0.f)
do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
if (rough2 > 0.f) {
float vec[3];
psys_frand_vec(sim->psys, i + 27, vec);
do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
if (part->roughcurve) {
do_rough_curve(orco, mat, t, rough1, part->rough1_size, part->roughcurve, state);
}
if (rough_end > 0.f) {
float vec[3];
psys_frand_vec(sim->psys, i + 27, vec);
do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
else {
if (rough1 > 0.f)
do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
if (rough2 > 0.f) {
float vec[3];
psys_frand_vec(sim->psys, i + 27, vec);
do_rough(vec, mat, t, rough2, part->rough2_size, part->rough2_thres, state);
}
if (rough_end > 0.f) {
float vec[3];
psys_frand_vec(sim->psys, i + 27, vec);
do_rough_end(vec, mat, t, rough_end, part->rough_end_shape, state);
}
}
}

@ -3819,6 +3819,9 @@ static void direct_link_particlesettings(FileData *fd, ParticleSettings *part)
part->clumpcurve = newdataadr(fd, part->clumpcurve);
if (part->clumpcurve)
direct_link_curvemapping(fd, part->clumpcurve);
part->roughcurve = newdataadr(fd, part->roughcurve);
if (part->roughcurve)
direct_link_curvemapping(fd, part->roughcurve);
part->effector_weights = newdataadr(fd, part->effector_weights);
if (!part->effector_weights)

@ -1110,6 +1110,8 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase)
if (part->clumpcurve)
write_curvemapping(wd, part->clumpcurve);
if (part->roughcurve)
write_curvemapping(wd, part->roughcurve);
dw = part->dupliweights.first;
for (; dw; dw=dw->next) {

@ -234,6 +234,7 @@ typedef struct ParticleSettings {
/* keyed particles */
int keyed_loops;
struct CurveMapping *clumpcurve;
struct CurveMapping *roughcurve;
/* hair dynamics */
float bending_random;

@ -898,6 +898,29 @@ void rna_ParticleSettings_use_clump_curve_set(PointerRNA *ptr, int value)
}
}
int rna_ParticleSettings_use_roughness_curve_get(PointerRNA *ptr)
{
ParticleSettings *part = ptr->data;
return part->roughcurve != NULL;
}
void rna_ParticleSettings_use_roughness_curve_set(PointerRNA *ptr, int value)
{
ParticleSettings *part = ptr->data;
if (!value) {
if (part->roughcurve) {
curvemapping_free(part->roughcurve);
part->roughcurve = NULL;
}
}
else {
if (!part->roughcurve) {
BKE_particlesettings_rough_curve_init(part);
}
}
}
static void rna_ParticleSystem_name_set(PointerRNA *ptr, const char *value)
{
Object *ob = ptr->id.data;
@ -2912,6 +2935,18 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Shape", "Shape of end point rough");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
prop = RNA_def_property(srna, "use_roughness_curve", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_ParticleSettings_use_roughness_curve_get", "rna_ParticleSettings_use_roughness_curve_set");
RNA_def_property_ui_text(prop, "Use Roughness Curve", "Use a curve to define roughness");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
prop = RNA_def_property(srna, "roughness_curve", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "roughcurve");
RNA_def_property_struct_type(prop, "CurveMapping");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Roughness Curve", "Curve defining roughness");
RNA_def_property_update(prop, 0, "rna_Particle_redo_child");
prop = RNA_def_property(srna, "child_length", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "clength");
RNA_def_property_range(prop, 0.0f, 1.0f);