Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2015-01-09 16:24:19 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2015-01-20 11:30:09 +0300
commitc86d55d5e77674982a5d1760d8b895bb87af44f5 (patch)
tree4096f059a02bb82d3f96587290ddb9d86ebc1ece /source/blender/blenkernel/intern
parent4c82367fd8c69da7d5b1c4f418ed8e09a2747390 (diff)
Curve-based control for child path tapering.
This is an alternative method to the current fixed function with a clump factor and "shape" parameter. This function is quite limited and does not give the desired result in many cases (e.g. long, parallel rasta strands are problematic). So rather than trying to add more parameters there is now a fully user-defined optional curve for setting the tapering shape.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/particle.c38
-rw-r--r--source/blender/blenkernel/intern/particle_child.c19
-rw-r--r--source/blender/blenkernel/intern/particle_system.c2
3 files changed, 48 insertions, 11 deletions
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index efcc0ebca21..1001dde2561 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -64,6 +64,7 @@
#include "BKE_boids.h"
#include "BKE_cloth.h"
+#include "BKE_colortools.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_group.h"
@@ -373,6 +374,10 @@ void BKE_particlesettings_free(ParticleSettings *part)
MTex *mtex;
int a;
BKE_free_animdata(&part->id);
+
+ if (part->clumpcurve)
+ curvemapping_free(part->clumpcurve);
+
free_partdeflect(part->pd);
free_partdeflect(part->pd2);
@@ -1665,7 +1670,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int in
extern void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat,
short type, short axis, float obmat[4][4], int smooth_start);
-extern float do_clump(ParticleKey *state, ParticleKey *par, float time, float clumpfac, float clumppow, float pa_clump);
+extern float do_clump(ParticleKey *state, ParticleKey *par, float time, float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve);
void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
{
@@ -1708,7 +1713,7 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
}
}
-int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
+int do_guides(ParticleSettings *part, ListBase *effectors, ParticleKey *state, int index, float time)
{
EffectorCache *eff;
PartDeflect *pd;
@@ -1777,10 +1782,14 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
mul_v3_fl(vec_to_point, radius);
}
}
+
+ if (part->clumpcurve)
+ curvemapping_changed_all(part->clumpcurve);
+
par.co[0] = par.co[1] = par.co[2] = 0.0f;
copy_v3_v3(key.co, vec_to_point);
do_kink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, 0.f, pd->kink, pd->kink_axis, 0, 0);
- do_clump(&key, &par, guidetime, pd->clump_fac, pd->clump_pow, 1.0f);
+ do_clump(&key, &par, guidetime, pd->clump_fac, pd->clump_pow, 1.0f, part->clumpcurve);
copy_v3_v3(vec_to_point, key.co);
add_v3_v3(vec_to_point, guidevec);
@@ -1979,6 +1988,10 @@ static bool psys_thread_context_init_path(ParticleThreadContext *ctx, ParticleSi
if (psys->part->flag & PART_CHILD_EFFECT)
ctx->vg_effector = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_EFFECTOR);
+ /* prepare curvemapping tables */
+ if (part->clumpcurve)
+ curvemapping_changed_all(part->clumpcurve);
+
return true;
}
@@ -2545,7 +2558,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra)
if (sim->psys->effectors && (psys->part->flag & PART_CHILD_EFFECT) == 0) {
for (k = 0, ca = cache[p]; k <= steps; k++, ca++)
/* ca is safe to cast, since only co and vel are used */
- do_guides(sim->psys->effectors, (ParticleKey *)ca, p, (float)k / (float)steps);
+ do_guides(sim->psys->part, sim->psys->effectors, (ParticleKey *)ca, p, (float)k / (float)steps);
}
/* lattices have to be calculated separately to avoid mixups between effector calculations */
@@ -3141,6 +3154,18 @@ ParticleSettings *psys_new_settings(const char *name, Main *main)
return part;
}
+void BKE_particlesettings_clump_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->clumpcurve = cumap;
+}
+
ParticleSettings *BKE_particlesettings_copy(ParticleSettings *part)
{
ParticleSettings *partn;
@@ -3152,6 +3177,9 @@ ParticleSettings *BKE_particlesettings_copy(ParticleSettings *part)
partn->effector_weights = MEM_dupallocN(part->effector_weights);
partn->fluid = MEM_dupallocN(part->fluid);
+ if (part->clumpcurve)
+ partn->clumpcurve = curvemapping_copy(part->clumpcurve);
+
partn->boids = boid_copy_settings(part->boids);
for (a = 0; a < MAX_MTEX; a++) {
@@ -3604,7 +3632,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
mul_mat3_m4_v3(hairmat, state->vel);
if (sim->psys->effectors && (part->flag & PART_CHILD_GUIDE) == 0) {
- do_guides(sim->psys->effectors, state, p, state->time);
+ do_guides(sim->psys->part, sim->psys->effectors, state, p, state->time);
/* TODO: proper velocity handling */
}
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
index fb261b248dc..68e11c9368e 100644
--- a/source/blender/blenkernel/intern/particle_child.c
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -34,13 +34,14 @@
#include "DNA_material_types.h"
+#include "BKE_colortools.h"
#include "BKE_particle.h"
struct Material;
void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, float freq, float shape, float amplitude, float flat,
short type, short axis, float obmat[4][4], int smooth_start);
-float do_clump(ParticleKey *state, ParticleKey *par, float time, float clumpfac, float clumppow, float pa_clump);
+float do_clump(ParticleKey *state, ParticleKey *par, float time, float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve);
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);
@@ -359,11 +360,19 @@ void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float time, f
copy_v3_v3(state->co, result);
}
-float do_clump(ParticleKey *state, ParticleKey *par, float time, float clumpfac, float clumppow, float pa_clump)
+float do_clump(ParticleKey *state, ParticleKey *par, float time, float clumpfac, float clumppow, float pa_clump, CurveMapping *clumpcurve)
{
float clump = 0.f;
- if (par && clumpfac != 0.0f) {
+ if (!par)
+ return 0.0f;
+
+ if (clumpcurve) {
+ clump = pa_clump * (1.0f - CLAMPIS(curvemapping_evaluateF(clumpcurve, 0, time), 0.0f, 1.0f));
+
+ interp_v3_v3v3(state->co, state->co, par->co, clump);
+ }
+ else if (clumpfac != 0.0f) {
float cpow;
if (clumppow < 0.0f)
@@ -439,10 +448,10 @@ void do_child_modifiers(ParticleSimulationData *sim, ParticleTexture *ptex, Part
if (part->flag & PART_CHILD_EFFECT)
/* state is safe to cast, since only co and vel are used */
- guided = do_guides(sim->psys->effectors, (ParticleKey *)state, cpa->parent, t);
+ guided = do_guides(sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t);
if (guided == 0) {
- float clump = do_clump(state, par, t, part->clumpfac, part->clumppow, ptex ? ptex->clump : 1.f);
+ float clump = do_clump(state, par, t, part->clumpfac, part->clumppow, ptex ? ptex->clump : 1.f, part->clumpcurve);
if (kink_freq != 0.f) {
float kink_amp = part->kink_amp * (1.f - part->kink_amp_clump * clump);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 6e7e341e1cc..8c0840ad651 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2089,7 +2089,7 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa
tkey.time=pa->state.time;
if (part->type != PART_HAIR) {
- if (do_guides(sim->psys->effectors, &tkey, p, time)) {
+ if (do_guides(sim->psys->part, sim->psys->effectors, &tkey, p, time)) {
copy_v3_v3(pa->state.co,tkey.co);
/* guides don't produce valid velocity */
sub_v3_v3v3(pa->state.vel, tkey.co, pa->prev_state.co);