diff options
Diffstat (limited to 'source/blender/blenkernel/intern/effect.c')
-rw-r--r-- | source/blender/blenkernel/intern/effect.c | 81 |
1 files changed, 72 insertions, 9 deletions
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 13e9bb1bf24..4104b6080c5 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -270,11 +270,71 @@ void BKE_effector_relations_free(ListBase *lb) } } +/* Check that the force field isn't disabled via its flags. */ +static bool is_effector_enabled(PartDeflect *pd, bool use_rotation) +{ + switch (pd->forcefield) { + case PFIELD_BOID: + case PFIELD_GUIDE: + return true; + + case PFIELD_TEXTURE: + return (pd->flag & PFIELD_DO_LOCATION) != 0 && pd->tex != NULL; + + default: + if (use_rotation) { + return (pd->flag & (PFIELD_DO_LOCATION | PFIELD_DO_ROTATION)) != 0; + } + else { + return (pd->flag & PFIELD_DO_LOCATION) != 0; + } + } +} + +/* Check that the force field won't have zero effect due to strength settings. */ +static bool is_effector_nonzero_strength(PartDeflect *pd) +{ + if (pd->f_strength != 0.0f) { + return true; + } + + if (pd->forcefield == PFIELD_TEXTURE) { + return false; + } + + if (pd->f_noise > 0.0f || pd->f_flow != 0.0f) { + return true; + } + + switch (pd->forcefield) { + case PFIELD_BOID: + case PFIELD_GUIDE: + return true; + + case PFIELD_VORTEX: + return pd->shape != PFIELD_SHAPE_POINT; + + case PFIELD_DRAG: + return pd->f_damp != 0.0f; + + default: + return false; + } +} + +/* Check if the force field will affect its user. */ +static bool is_effector_relevant(PartDeflect *pd, EffectorWeights *weights, bool use_rotation) +{ + return (weights->weight[pd->forcefield] != 0.0f) && is_effector_enabled(pd, use_rotation) && + is_effector_nonzero_strength(pd); +} + /* Create effective list of effectors from relations built beforehand. */ ListBase *BKE_effectors_create(Depsgraph *depsgraph, Object *ob_src, ParticleSystem *psys_src, - EffectorWeights *weights) + EffectorWeights *weights, + bool use_rotation) { Scene *scene = DEG_get_evaluated_scene(depsgraph); ListBase *relations = DEG_get_effector_relations(depsgraph, weights->group); @@ -299,7 +359,8 @@ ListBase *BKE_effectors_create(Depsgraph *depsgraph, } PartDeflect *pd = (relation->pd == relation->psys->part->pd) ? part->pd : part->pd2; - if (weights->weight[pd->forcefield] == 0.0f) { + + if (!is_effector_relevant(pd, weights, use_rotation)) { continue; } @@ -310,7 +371,7 @@ ListBase *BKE_effectors_create(Depsgraph *depsgraph, if (ob == ob_src) { continue; } - if (weights->weight[ob->pd->forcefield] == 0.0f) { + if (!is_effector_relevant(ob->pd, weights, use_rotation)) { continue; } if (ob->pd->shape == PFIELD_SHAPE_POINTS && BKE_object_get_evaluated_mesh(ob) == NULL) { @@ -903,7 +964,9 @@ static void do_texture_effector(EffectorCache *eff, madd_v3_v3fl(force, efd->nor, fac); } - add_v3_v3(total_force, force); + if (eff->pd->flag & PFIELD_DO_LOCATION) { + add_v3_v3(total_force, force); + } } static void do_physical_effector(EffectorCache *eff, EffectorData *efd, @@ -918,6 +981,7 @@ static void do_physical_effector(EffectorCache *eff, float strength = pd->f_strength; float damp = pd->f_damp; float noise_factor = pd->f_noise; + float flow_falloff = efd->falloff; if (noise_factor > 0.0f) { strength += wind_func(rng, noise_factor); @@ -1027,6 +1091,7 @@ static void do_physical_effector(EffectorCache *eff, break; case PFIELD_FLUIDFLOW: zero_v3(force); + flow_falloff = 0; #ifdef WITH_FLUID if (pd->f_source) { float density; @@ -1036,8 +1101,7 @@ static void do_physical_effector(EffectorCache *eff, influence *= density; } mul_v3_fl(force, influence); - /* apply flow */ - madd_v3_v3fl(total_force, point->vel, -pd->f_flow * influence); + flow_falloff = influence; } } #endif @@ -1047,9 +1111,8 @@ static void do_physical_effector(EffectorCache *eff, if (pd->flag & PFIELD_DO_LOCATION) { madd_v3_v3fl(total_force, force, 1.0f / point->vel_to_sec); - if (ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG, PFIELD_FLUIDFLOW) == 0 && - pd->f_flow != 0.0f) { - madd_v3_v3fl(total_force, point->vel, -pd->f_flow * efd->falloff); + if (!ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG) && pd->f_flow != 0.0f) { + madd_v3_v3fl(total_force, point->vel, -pd->f_flow * flow_falloff); } } |