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:
authorSergey Sharybin <sergey.vfx@gmail.com>2018-02-15 14:33:44 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2018-02-15 14:33:44 +0300
commit2589f55a55bc9682111ab266bb89d8f08713f374 (patch)
tree6634689ec50057bc782a2c9430ae1059712b0254 /source/blender/blenkernel/intern
parent9d2a699a90d5ce7b976e76f6e1b5c260306b5218 (diff)
parent6d4022f61980ba46efd391dcfe96dd88a8db8deb (diff)
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/particle.c72
-rw-r--r--source/blender/blenkernel/intern/particle_child.c177
-rw-r--r--source/blender/blenkernel/intern/particle_system.c5
-rw-r--r--source/blender/blenkernel/intern/smoke.c2
-rw-r--r--source/blender/blenkernel/intern/texture.c1
5 files changed, 235 insertions, 22 deletions
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index ef2ed9e2b65..ff70e71edd4 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -413,6 +413,8 @@ void BKE_particlesettings_free(ParticleSettings *part)
curvemapping_free(part->clumpcurve);
if (part->roughcurve)
curvemapping_free(part->roughcurve);
+ if (part->twistcurve)
+ curvemapping_free(part->twistcurve);
free_partdeflect(part->pd);
free_partdeflect(part->pd2);
@@ -2144,6 +2146,7 @@ static bool psys_thread_context_init_path(
ctx->vg_rough1 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH1);
ctx->vg_rough2 = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGH2);
ctx->vg_roughe = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_ROUGHE);
+ ctx->vg_twist = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_TWIST);
if (psys->part->flag & PART_CHILD_EFFECT)
ctx->vg_effector = psys_cache_vgroup(ctx->dm, psys, PSYS_VG_EFFECTOR);
@@ -2162,6 +2165,13 @@ static bool psys_thread_context_init_path(
else {
ctx->roughcurve = NULL;
}
+ if ((part->child_flag & PART_CHILD_USE_TWIST_CURVE) && part->twistcurve) {
+ ctx->twistcurve = curvemapping_copy(part->twistcurve);
+ curvemapping_changed_all(ctx->twistcurve);
+ }
+ else {
+ ctx->twistcurve = NULL;
+ }
return true;
}
@@ -2306,7 +2316,19 @@ static void psys_thread_create_path(ParticleTask *task, struct ChildParticle *cp
/* get the original coordinates (orco) for texture usage */
cpa_from = part->from;
- cpa_num = pa->num;
+
+ /*
+ * NOTE: Should in theory be the same as:
+ cpa_num = psys_particle_dm_face_lookup(
+ ctx->sim.psmd->dm_final,
+ ctx->sim.psmd->dm_deformed,
+ pa->num, pa->fuv,
+ NULL);
+ */
+ cpa_num = (ELEM(pa->num_dmcache, DMCACHE_ISCHILD, DMCACHE_NOTFOUND))
+ ? pa->num
+ : pa->num_dmcache;
+
/* XXX hack to avoid messed up particle num and subsequent crash (#40733) */
if (cpa_num > ctx->sim.psmd->dm_final->getNumTessFaces(ctx->sim.psmd->dm_final))
cpa_num = 0;
@@ -3349,6 +3371,18 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
part->roughcurve = cumap;
}
+void BKE_particlesettings_twist_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->twistcurve = cumap;
+}
+
/**
* Only copy internal data of ParticleSettings ID from source to already allocated/initialized destination.
* You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
@@ -3371,6 +3405,9 @@ void BKE_particlesettings_copy_data(
if (part_src->roughcurve) {
part_dst->roughcurve = curvemapping_copy(part_src->roughcurve);
}
+ if (part_src->twistcurve) {
+ part_dst->twistcurve = curvemapping_copy(part_src->twistcurve);
+ }
part_dst->boids = boid_copy_settings(part_src->boids);
@@ -3490,6 +3527,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink_freq = ptex->kink_amp =
ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
+ ptex->twist = 1.0f;
ptex->length = 1.0f - part->randlength * psys_frand(psys, child_index + 26);
ptex->length *= part->clength_thres < psys_frand(psys, child_index + 27) ? part->clength : 1.0f;
@@ -3542,6 +3580,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
SET_PARTICLE_TEXTURE(PAMAP_KINK_AMP, ptex->kink_amp, mtex->kinkampfac);
SET_PARTICLE_TEXTURE(PAMAP_KINK_FREQ, ptex->kink_freq, mtex->kinkfac);
SET_PARTICLE_TEXTURE(PAMAP_DENS, ptex->exist, mtex->padensfac);
+ SET_PARTICLE_TEXTURE(PAMAP_TWIST, ptex->twist, mtex->twistfac);
}
}
@@ -3567,6 +3606,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
ptex->gravity = ptex->field = ptex->length = ptex->clump = ptex->kink_freq = ptex->kink_amp =
ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
+ ptex->twist = 1.0f;
ptex->time = (float)(pa - sim->psys->particles) / (float)sim->psys->totpart;
@@ -3641,6 +3681,7 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
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);
+ SET_PARTICLE_TEXTURE(PAMAP_TWIST, ptex->twist, mtex->twistfac);
}
}
@@ -3732,6 +3773,8 @@ static void get_child_modifier_parameters(ParticleSettings *part, ParticleThread
ptex->roughe *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_roughe);
if (ctx->vg_effector)
ptex->effector *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_effector);
+ if (ctx->vg_twist)
+ ptex->twist *= psys_interpolate_value_from_verts(ctx->dm, cpa_from, cpa_num, cpa_fuv, ctx->vg_twist);
}
/* get's hair (or keyed) particles state at the "path time" specified in state->time */
void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *state, const bool vel)
@@ -3937,7 +3980,18 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
copy_particle_key(&tstate, state, 1);
/* apply different deformations to the child path */
- do_child_modifiers(NULL, sim, &ptex, par->co, par->vel, par->rot, par_orco, cpa, orco, hairmat, state, t);
+ ParticleChildModifierContext modifier_ctx = {NULL};
+ modifier_ctx.thread_ctx = NULL;
+ modifier_ctx.sim = sim;
+ modifier_ctx.ptex = &ptex;
+ modifier_ctx.cpa = cpa;
+ modifier_ctx.orco = orco;
+ modifier_ctx.par_co = par->co;
+ modifier_ctx.par_vel = par->vel;
+ modifier_ctx.par_rot = par->rot;
+ modifier_ctx.par_orco = par_orco;
+ modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL;
+ do_child_modifiers(&modifier_ctx, hairmat, state, t);
/* try to estimate correct velocity */
if (vel) {
@@ -4040,7 +4094,19 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
CLAMP(t, 0.0f, 1.0f);
unit_m4(mat);
- do_child_modifiers(NULL, sim, NULL, key1->co, key1->vel, key1->rot, par_orco, cpa, cpa->fuv, mat, state, t);
+ ParticleChildModifierContext modifier_ctx = {NULL};
+ modifier_ctx.thread_ctx = NULL;
+ modifier_ctx.sim = sim;
+ modifier_ctx.ptex = NULL;
+ modifier_ctx.cpa = cpa;
+ modifier_ctx.orco = cpa->fuv;
+ modifier_ctx.par_co = key1->co;
+ modifier_ctx.par_vel = key1->vel;
+ modifier_ctx.par_rot = key1->rot;
+ modifier_ctx.par_orco = par_orco;
+ modifier_ctx.parent_keys = psys->childcache ? psys->childcache[p - totpart] : NULL;
+
+ do_child_modifiers(&modifier_ctx, mat, state, t);
if (psys->lattice_deform_data)
calc_latt_deform(psys->lattice_deform_data, state->co, psys->lattice_strength);
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
index bc4c32f5805..8cdd668b7e7 100644
--- a/source/blender/blenkernel/intern/particle_child.c
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -235,6 +235,15 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co
kink_base[part->kink_axis] = 1.0f;
mul_mat3_m4_v3(ctx->sim.ob->obmat, kink_base);
+ /* Fill in invariant part of modifier context. */
+ ParticleChildModifierContext modifier_ctx = {NULL};
+ modifier_ctx.thread_ctx = ctx;
+ modifier_ctx.sim = &ctx->sim;
+ modifier_ctx.ptex = ptex;
+ modifier_ctx.cpa = cpa;
+ modifier_ctx.orco = orco;
+ modifier_ctx.parent_keys = parent_keys;
+
for (k = 0, key = keys; k < end_index; k++, key++) {
float par_time;
float *par_co, *par_vel, *par_rot;
@@ -274,8 +283,14 @@ static void do_kink_spiral(ParticleThreadContext *ctx, ParticleTexture *ptex, co
do_kink_spiral_deform((ParticleKey *)key, dir, kink, spiral_time, kink_freq, kink_shape, kink_amp, spiral_start);
}
- /* apply different deformations to the child path */
- do_child_modifiers(ctx, &ctx->sim, ptex, par_co, par_vel, par_rot, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, par_time);
+ /* Fill in variant part of modifier context. */
+ modifier_ctx.par_co = par_co;
+ modifier_ctx.par_vel = par_vel;
+ modifier_ctx.par_rot = par_rot;
+ modifier_ctx.par_orco = parent_orco;
+
+ /* Apply different deformations to the child path/ */
+ do_child_modifiers(&modifier_ctx, hairmat, (ParticleKey *)key, par_time);
}
totlen = 0.0f;
@@ -331,19 +346,33 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod
keys->segments = totkeys - 1;
}
else {
- ParticlePathIterator iter;
+ /* Fill in invariant part of modifier context. */
+ ParticleChildModifierContext modifier_ctx = {NULL};
+ modifier_ctx.thread_ctx = ctx;
+ modifier_ctx.sim = &ctx->sim;
+ modifier_ctx.ptex = ptex;
+ modifier_ctx.cpa = cpa;
+ modifier_ctx.orco = orco;
+ modifier_ctx.parent_keys = parent_keys;
totkeys = ctx->segments + 1;
max_length = ptex->length;
+ printf("%f\n", ptex->twist);
for (k = 0, key = keys; k < totkeys; k++, key++) {
- ParticleKey *par;
-
+ ParticlePathIterator iter;
psys_path_iter_get(&iter, keys, totkeys, parent_keys, k);
- par = (ParticleKey *)iter.parent_key;
- /* apply different deformations to the child path */
- do_child_modifiers(ctx, &ctx->sim, ptex, par->co, par->vel, iter.parent_rotation, parent_orco, cpa, orco, hairmat, (ParticleKey *)key, iter.time);
+ ParticleKey *par = (ParticleKey *)iter.parent_key;
+
+ /* Fill in variant part of modifier context. */
+ modifier_ctx.par_co = par->co;
+ modifier_ctx.par_vel = par->vel;
+ modifier_ctx.par_rot = iter.parent_rotation;
+ modifier_ctx.par_orco = parent_orco;
+
+ /* Apply different deformations to the child path. */
+ do_child_modifiers(&modifier_ctx, hairmat, (ParticleKey *)key, iter.time);
}
}
@@ -662,10 +691,100 @@ static void do_rough_curve(const float loc[3], float mat[4][4], float time, floa
madd_v3_v3fl(state->co, mat[2], fac * rough[2]);
}
-void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim, ParticleTexture *ptex,
- const float par_co[3], const float par_vel[3], const float par_rot[4], const float par_orco[3],
- ChildParticle *cpa, const float orco[3], float mat[4][4], ParticleKey *state, float t)
+static int twist_num_segments(const ParticleChildModifierContext *modifier_ctx)
+{
+ ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx;
+ return (thread_ctx != NULL) ? thread_ctx->segments
+ : modifier_ctx->sim->psys->part->draw_step;
+}
+
+static void twist_get_axis(const ParticleChildModifierContext *modifier_ctx,
+ const float time, float r_axis[3])
+{
+ const int num_segments = twist_num_segments(modifier_ctx);
+ const int index = clamp_i(time * num_segments, 0, num_segments);
+ if (index > 0) {
+ sub_v3_v3v3(r_axis,
+ modifier_ctx->parent_keys[index].co,
+ modifier_ctx->parent_keys[index - 1].co);
+ }
+ else {
+ sub_v3_v3v3(r_axis,
+ modifier_ctx->parent_keys[index + 1].co,
+ modifier_ctx->parent_keys[index].co);
+ }
+}
+
+static float curvemapping_integrate_clamped(CurveMapping *curve,
+ float start, float end, float step)
+{
+ float integral = 0.0f;
+ float x = start;
+ while (x < end) {
+ float y = curvemapping_evaluateF(curve, 0, x);
+ y = clamp_f(y, 0.0f, 1.0f);
+ /* TODO(sergey): Clamp last step to end. */
+ integral += y * step;
+ x += step;
+ }
+ return integral;
+}
+
+static void do_twist(const ParticleChildModifierContext *modifier_ctx,
+ ParticleKey *state, const float time)
+{
+ ParticleThreadContext *thread_ctx = modifier_ctx->thread_ctx;
+ ParticleSimulationData *sim = modifier_ctx->sim;
+ ParticleTexture *ptex = modifier_ctx->ptex;
+ ParticleSettings *part = sim->psys->part;
+ /* Early output checks. */
+ if (part->childtype != PART_CHILD_PARTICLES) {
+ /* Interpolated children behave weird with twist. */
+ return;
+ }
+ if (part->twist == 0.0f) {
+ /* No twist along the strand. */
+ return;
+ }
+ /* Dependent on whether it's threaded update or not, curve comes
+ * from different places.
+ */
+ CurveMapping *twist_curve = NULL;
+ if (part->child_flag & PART_CHILD_USE_TWIST_CURVE) {
+ twist_curve = (thread_ctx != NULL) ? thread_ctx->twistcurve
+ : part->twistcurve;
+ }
+ /* Axis of rotation. */
+ float axis[3];
+ twist_get_axis(modifier_ctx, time, axis);
+ /* Angle of rotation. */
+ float angle = part->twist;
+ if (ptex != NULL) {
+ angle *= (ptex->twist - 0.5f) * 2.0f;
+ }
+ if (twist_curve != NULL) {
+ const int num_segments = twist_num_segments(modifier_ctx);
+ angle *= curvemapping_integrate_clamped(twist_curve,
+ 0.0f, time,
+ 1.0f / num_segments);
+ }
+ else {
+ angle *= time;
+ }
+ /* Perform rotation around parent curve. */
+ float vec[3];
+ sub_v3_v3v3(vec, state->co, modifier_ctx->par_co);
+ rotate_v3_v3v3fl(state->co, vec, axis, angle * 2.0f * M_PI);
+ add_v3_v3(state->co, modifier_ctx->par_co);
+}
+
+void do_child_modifiers(const ParticleChildModifierContext *modifier_ctx,
+ float mat[4][4], ParticleKey *state, float t)
{
+ ParticleThreadContext *ctx = modifier_ctx->thread_ctx;
+ ParticleSimulationData *sim = modifier_ctx->sim;
+ ParticleTexture *ptex = modifier_ctx->ptex;
+ ChildParticle *cpa = modifier_ctx->cpa;
ParticleSettings *part = sim->psys->part;
CurveMapping *clumpcurve = NULL, *roughcurve = NULL;
int i = cpa - sim->psys->child;
@@ -694,6 +813,8 @@ void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim,
rough_end *= ptex->roughe;
}
+ do_twist(modifier_ctx, state, t);
+
if (part->flag & PART_CHILD_EFFECT)
/* state is safe to cast, since only co and vel are used */
guided = do_guides(sim->eval_ctx, sim->psys->part, sim->psys->effectors, (ParticleKey *)state, cpa->parent, t);
@@ -702,25 +823,43 @@ void do_child_modifiers(ParticleThreadContext *ctx, ParticleSimulationData *sim,
float orco_offset[3];
float clump;
- sub_v3_v3v3(orco_offset, orco, par_orco);
- clump = do_clump(state, par_co, t, orco_offset, part->clumpfac, part->clumppow, ptex ? ptex->clump : 1.f,
- part->child_flag & PART_CHILD_USE_CLUMP_NOISE, part->clump_noise_size, clumpcurve);
+ sub_v3_v3v3(orco_offset, modifier_ctx->orco, modifier_ctx->par_orco);
+ clump = do_clump(state,
+ modifier_ctx->par_co,
+ t,
+ orco_offset,
+ part->clumpfac,
+ part->clumppow,
+ ptex ? ptex->clump : 1.0f,
+ part->child_flag & PART_CHILD_USE_CLUMP_NOISE,
+ part->clump_noise_size,
+ clumpcurve);
if (kink_freq != 0.f) {
kink_amp *= (1.f - kink_amp_clump * clump);
- do_kink(state, par_co, par_vel, par_rot, t, kink_freq, part->kink_shape,
- kink_amp, part->kink_flat, part->kink, part->kink_axis,
- sim->ob->obmat, smooth_start);
+ do_kink(state,
+ modifier_ctx->par_co,
+ modifier_ctx->par_vel,
+ modifier_ctx->par_rot,
+ t,
+ kink_freq,
+ part->kink_shape,
+ kink_amp,
+ part->kink_flat,
+ part->kink,
+ part->kink_axis,
+ sim->ob->obmat,
+ smooth_start);
}
}
if (roughcurve) {
- do_rough_curve(orco, mat, t, rough1, part->rough1_size, roughcurve, state);
+ do_rough_curve(modifier_ctx->orco, mat, t, rough1, part->rough1_size, roughcurve, state);
}
else {
if (rough1 > 0.f)
- do_rough(orco, mat, t, rough1, part->rough1_size, 0.0, state);
+ do_rough(modifier_ctx->orco, mat, t, rough1, part->rough1_size, 0.0, state);
if (rough2 > 0.f) {
float vec[3];
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 0fcc918a069..8171f3e7812 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -499,6 +499,8 @@ void psys_thread_context_free(ParticleThreadContext *ctx)
MEM_freeN(ctx->vg_rough2);
if (ctx->vg_roughe)
MEM_freeN(ctx->vg_roughe);
+ if (ctx->vg_twist)
+ MEM_freeN(ctx->vg_twist);
if (ctx->sim.psys->lattice_deform_data) {
end_latt_deform(ctx->sim.psys->lattice_deform_data);
@@ -521,6 +523,9 @@ void psys_thread_context_free(ParticleThreadContext *ctx)
if (ctx->roughcurve != NULL) {
curvemapping_free(ctx->roughcurve);
}
+ if (ctx->twistcurve != NULL) {
+ curvemapping_free(ctx->twistcurve);
+ }
}
static void initialize_particle_texture(ParticleSimulationData *sim, ParticleData *pa, int p)
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 9f9818127bc..4ab7b76aaab 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -1287,6 +1287,8 @@ static void emit_from_particles(
curvemapping_changed_all(psys->part->clumpcurve);
if ((psys->part->child_flag & PART_CHILD_USE_ROUGH_CURVE) && psys->part->roughcurve)
curvemapping_changed_all(psys->part->roughcurve);
+ if ((psys->part->child_flag & PART_CHILD_USE_TWIST_CURVE) && psys->part->twistcurve)
+ curvemapping_changed_all(psys->part->twistcurve);
/* initialize particle cache */
if (psys->part->type == PART_HAIR) {
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index fcedd880615..71b90641e02 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -412,6 +412,7 @@ void BKE_texture_mtex_default(MTex *mtex)
mtex->kinkfac = 1.0f;
mtex->kinkampfac = 1.0f;
mtex->roughfac = 1.0f;
+ mtex->twistfac = 1.0f;
mtex->padensfac = 1.0f;
mtex->lifefac = 1.0f;
mtex->sizefac = 1.0f;