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:
authorAlexander Gavrilov <angavrilov@gmail.com>2021-01-09 22:24:48 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2021-02-02 23:03:16 +0300
commit78ff8526808a4fbc3d261155b1e6f873247ff8ce (patch)
treee154dc0541c268c64947ddef87ae4a4f34ebf8ec /source/blender/blenkernel/intern/effect.c
parent64a963486f7b20f8db480be9cb894eb28e79ac57 (diff)
Force Fields: implement early filtering by the Affect flags.
Most fields have Affect Location and Rotation options that switch off their effect, but they are only checked as the last step after the force is already computed. It is more efficient to check it when building the list of field objects, just like zero weight. It is also possible to check the strength-related fields for 0. As an aside, this adds Location to Texture fields (they don't handle rotation) and both Location & Rotation checkboxes to Fluid Flow. Boid and Curve Guide remain without options for now as they are completely different from others. Differential Revision: https://developer.blender.org/D10087
Diffstat (limited to 'source/blender/blenkernel/intern/effect.c')
-rw-r--r--source/blender/blenkernel/intern/effect.c81
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);
}
}