[Bf-blender-cvs] [78ff8526808] master: Force Fields: implement early filtering by the Affect flags.

Alexander Gavrilov noreply at git.blender.org
Tue Feb 2 21:04:08 CET 2021


Commit: 78ff8526808a4fbc3d261155b1e6f873247ff8ce
Author: Alexander Gavrilov
Date:   Sat Jan 9 22:24:48 2021 +0300
Branches: master
https://developer.blender.org/rB78ff8526808a4fbc3d261155b1e6f873247ff8ce

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

===================================================================

M	release/scripts/startup/bl_ui/properties_physics_field.py
M	source/blender/blenkernel/BKE_effect.h
M	source/blender/blenkernel/intern/cloth.c
M	source/blender/blenkernel/intern/dynamicpaint.c
M	source/blender/blenkernel/intern/effect.c
M	source/blender/blenkernel/intern/fluid.c
M	source/blender/blenkernel/intern/particle_system.c
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/blenkernel/intern/softbody.c

===================================================================

diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py
index c8c49ee02b0..7e017b121b3 100644
--- a/release/scripts/startup/bl_ui/properties_physics_field.py
+++ b/release/scripts/startup/bl_ui/properties_physics_field.py
@@ -118,6 +118,9 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel):
 
             col.prop(field, "strength")
 
+            sub = col.column(heading="Affect")
+            sub.prop(field, "apply_to_location", text="Location")
+
             col = flow.column()
             col.prop(field, "texture_nabla")
             col.prop(field, "use_object_coords")
@@ -128,6 +131,10 @@ class PHYSICS_PT_field_settings(PhysicButtonsPanel, Panel):
             col.prop(field, "strength")
             col.prop(field, "flow")
 
+            sub = col.column(heading="Affect")
+            sub.prop(field, "apply_to_location", text="Location")
+            sub.prop(field, "apply_to_rotation", text="Rotation")
+
             col = flow.column()
             col.prop(field, "source_object")
             col.prop(field, "use_smoke_density")
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 3cba47afc46..231a4563630 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -121,7 +121,8 @@ void BKE_effector_relations_free(struct ListBase *lb);
 struct ListBase *BKE_effectors_create(struct Depsgraph *depsgraph,
                                       struct Object *ob_src,
                                       struct ParticleSystem *psys_src,
-                                      struct EffectorWeights *weights);
+                                      struct EffectorWeights *weights,
+                                      bool use_rotation);
 void BKE_effectors_apply(struct ListBase *effectors,
                          struct ListBase *colliders,
                          struct EffectorWeights *weights,
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index c2d6d5c7594..09bd397cc78 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -285,7 +285,7 @@ static int do_step_cloth(
     mul_m4_v3(ob->obmat, verts->xconst);
   }
 
-  effectors = BKE_effectors_create(depsgraph, ob, NULL, clmd->sim_parms->effector_weights);
+  effectors = BKE_effectors_create(depsgraph, ob, NULL, clmd->sim_parms->effector_weights, false);
 
   if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH) {
     cloth_update_verts(ob, clmd, result);
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 811a27c9f3f..31860bbe0b4 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -5156,7 +5156,8 @@ static int dynamicPaint_prepareEffectStep(struct Depsgraph *depsgraph,
 
   /* Init force data if required */
   if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
-    ListBase *effectors = BKE_effectors_create(depsgraph, ob, NULL, surface->effector_weights);
+    ListBase *effectors = BKE_effectors_create(
+        depsgraph, ob, NULL, surface->effector_weights, false);
 
     /* allocate memory for force data (dir vector + strength) */
     *force = MEM_mallocN(sizeof(float[4]) * sData->total_points, "PaintEffectForces");
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);
     }
   }
 
diff --git a/source/blender/blenkernel/intern/fluid.c b/source/blender/blenkernel/intern/fluid.c
index 59248e5f9f8..7fe009d51ca 100644
--- a/source/blender/blenkernel/intern/fluid.c
+++ b/source/blender/blenkernel/intern/fluid.c
@@ -3225,7 +3225,7 @@ static void update_effectors(
   ListBase *effectors;
   /* make sure smoke flow influence is 0.0f */
   fds->effector_weights->weight[PFIELD_FLUIDFLOW] = 0.0f;
-  effectors = BKE_effectors_create(depsgraph, ob, NULL, fds->effector_weights);
+  effectors = BKE_effectors_create(depsgraph, ob, NULL, fds->effector_weights, false);
 
   if (effectors) {
     /* Precalculate wind forces. */
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 55d4043f96c..c727a144c87 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1400,8 +1400,9 @@ void psys_update_particle_tree(ParticleSystem *psys, float cfra)
 static void psys_update_effectors(ParticleSimulationData *sim)
 {
   BKE_effectors_free(sim->psys->effectors);
+  bool use_rotation = (sim->psys->part->flag & PART_ROT_DYN) != 0;
   sim->psys->effectors = BKE_effectors_create(
-      sim->depsgraph, sim->ob, sim->psys, sim->psys->part->effector_weights);
+      sim->depsgraph, sim->ob, sim->psys, sim->psys->part->effector_weights, use_rotation);
   precalc_guides(sim, sim->psys->effectors);
 }
 
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 586aeb274a5..19078446009 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1720,7 +1720,7 @@ static void rigidbody_update_sim_ob(
     ListBase *effectors;
 
     /* get effectors present in the group specified by effector_weights */
-    effectors = BKE_effectors_create(depsgraph, ob, NULL, effector_weights);
+    effectors = BKE_effectors_create(depsgraph, ob, NULL, effector_weigh

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list