From d1246969ed59ac36ffa332c283fb9d89f365a2b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Fri, 9 Jan 2015 15:58:18 +0100 Subject: Curve-based control for "roughness" (noise displacement) of child hair. --- .../scripts/startup/bl_ui/properties_particle.py | 30 ++++++++----- source/blender/blenkernel/BKE_particle.h | 1 + source/blender/blenkernel/intern/particle.c | 20 +++++++++ source/blender/blenkernel/intern/particle_child.c | 52 ++++++++++++++++------ source/blender/blenloader/intern/readfile.c | 3 ++ source/blender/blenloader/intern/writefile.c | 2 + source/blender/makesdna/DNA_particle_types.h | 1 + source/blender/makesrna/intern/rna_particle.c | 35 +++++++++++++++ 8 files changed, 120 insertions(+), 24 deletions(-) diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py index c5723ea4c71..b36ddab4762 100644 --- a/release/scripts/startup/bl_ui/properties_particle.py +++ b/release/scripts/startup/bl_ui/properties_particle.py @@ -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) diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index cb766082467..b0b605e40ca 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -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); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 1001dde2561..2f0fbbb45ea 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -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); diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c index 68e11c9368e..d7976699011 100644 --- a/source/blender/blenkernel/intern/particle_child.c +++ b/source/blender/blenkernel/intern/particle_child.c @@ -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); + } } } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 10bdfbd70e7..be1311249ee 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 81f4c16cea1..1de2b6b267a 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -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) { diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 6d119b039bd..b5ba7fa1649 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -234,6 +234,7 @@ typedef struct ParticleSettings { /* keyed particles */ int keyed_loops; struct CurveMapping *clumpcurve; + struct CurveMapping *roughcurve; /* hair dynamics */ float bending_random; diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 6540604199d..8a9be88b3b1 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -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); -- cgit v1.2.3