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:
Diffstat (limited to 'source/blender/blenkernel/intern/effect.c')
-rw-r--r--source/blender/blenkernel/intern/effect.c266
1 files changed, 150 insertions, 116 deletions
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 7e506570b7e..bb4cf1c5753 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -74,6 +74,7 @@
#include "BKE_smoke.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_physics.h"
#include "DEG_depsgraph_query.h"
#include "RE_render_ext.h"
@@ -135,9 +136,8 @@ PartDeflect *object_add_collision_fields(int type)
return pd;
}
-/* ***************** PARTICLES ***************** */
+/************************ PARTICLES ***************************/
-/* -------------------------- Effectors ------------------ */
void free_partdeflect(PartDeflect *pd)
{
if (!pd)
@@ -149,111 +149,7 @@ void free_partdeflect(PartDeflect *pd)
MEM_freeN(pd);
}
-static EffectorCache *new_effector_cache(struct Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
-{
- EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
- eff->depsgraph = depsgraph;
- eff->scene = scene;
- eff->ob = ob;
- eff->psys = psys;
- eff->pd = pd;
- eff->frame = -1;
- return eff;
-}
-static void add_object_to_effectors(ListBase **effectors, struct Depsgraph *depsgraph, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation)
-{
- EffectorCache *eff = NULL;
-
- if ( ob == ob_src )
- return;
-
- if (for_simulation) {
- if (weights->weight[ob->pd->forcefield] == 0.0f )
- return;
-
- if (ob->pd->shape == PFIELD_SHAPE_POINTS && !ob->derivedFinal )
- return;
- }
-
- if (*effectors == NULL)
- *effectors = MEM_callocN(sizeof(ListBase), "effectors list");
-
- eff = new_effector_cache(depsgraph, scene, ob, NULL, ob->pd);
-
- /* make sure imat is up to date */
- invert_m4_m4(ob->imat, ob->obmat);
-
- BLI_addtail(*effectors, eff);
-}
-static void add_particles_to_effectors(ListBase **effectors, struct Depsgraph *depsgraph, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation)
-{
- ParticleSettings *part= psys->part;
-
- if ( !psys_check_enabled(ob, psys, G.is_rendering) )
- return;
-
- if ( psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0)
- return;
-
- if ( part->pd && part->pd->forcefield && (!for_simulation || weights->weight[part->pd->forcefield] != 0.0f)) {
- if (*effectors == NULL)
- *effectors = MEM_callocN(sizeof(ListBase), "effectors list");
-
- BLI_addtail(*effectors, new_effector_cache(depsgraph, scene, ob, psys, part->pd));
- }
-
- if (part->pd2 && part->pd2->forcefield && (!for_simulation || weights->weight[part->pd2->forcefield] != 0.0f)) {
- if (*effectors == NULL)
- *effectors = MEM_callocN(sizeof(ListBase), "effectors list");
-
- BLI_addtail(*effectors, new_effector_cache(depsgraph, scene, ob, psys, part->pd2));
- }
-}
-
-/* returns ListBase handle with objects taking part in the effecting */
-ListBase *pdInitEffectors(
- struct Depsgraph *depsgraph, Scene *scene, Object *ob_src, ParticleSystem *psys_src,
- EffectorWeights *weights, bool for_simulation)
-{
- Base *base = BKE_collection_or_layer_objects(depsgraph, scene, NULL, weights->group);
- ListBase *effectors = NULL;
-
- for (; base; base = base->next) {
- if (base->object->pd && base->object->pd->forcefield) {
- add_object_to_effectors(&effectors, depsgraph, scene, weights, base->object, ob_src, for_simulation);
- }
-
- if (base->object->particlesystem.first) {
- ParticleSystem *psys= base->object->particlesystem.first;
-
- for (; psys; psys=psys->next) {
- add_particles_to_effectors(&effectors, depsgraph, scene, weights, base->object, psys, psys_src, for_simulation);
- }
- }
- }
-
- if (for_simulation) {
- pdPrecalculateEffectors(depsgraph, effectors);
- }
-
- return effectors;
-}
-
-void pdEndEffectors(ListBase **effectors)
-{
- if (*effectors) {
- EffectorCache *eff = (*effectors)->first;
-
- for (; eff; eff=eff->next) {
- if (eff->guide_data)
- MEM_freeN(eff->guide_data);
- }
-
- BLI_freelistN(*effectors);
- MEM_freeN(*effectors);
- *effectors = NULL;
- }
-}
+/******************** EFFECTOR RELATIONS ***********************/
static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *eff)
{
@@ -296,12 +192,150 @@ static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *ef
}
}
-void pdPrecalculateEffectors(struct Depsgraph *depsgraph, ListBase *effectors)
+static void add_effector_relation(ListBase *relations, Object *ob, ParticleSystem *psys, PartDeflect *pd)
+{
+ EffectorRelation *relation = MEM_callocN(sizeof(EffectorRelation), "EffectorRelation");
+ relation->ob = ob;
+ relation->psys = psys;
+ relation->pd = pd;
+
+ BLI_addtail(relations, relation);
+}
+
+static void add_effector_evaluation(ListBase **effectors, Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
{
- if (effectors) {
- EffectorCache *eff = effectors->first;
- for (; eff; eff=eff->next)
- precalculate_effector(depsgraph, eff);
+ if (*effectors == NULL) {
+ *effectors = MEM_callocN(sizeof(ListBase), "effector effectors");
+ }
+
+ EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
+ eff->depsgraph = depsgraph;
+ eff->scene = scene;
+ eff->ob = ob;
+ eff->psys = psys;
+ eff->pd = pd;
+ eff->frame = -1;
+ BLI_addtail(*effectors, eff);
+
+ precalculate_effector(depsgraph, eff);
+}
+
+/* Create list of effector relations in the collection or entire scene.
+ * This is used by the depsgraph to build relations, as well as faster
+ * lookup of effectors during evaluation. */
+ListBase *BKE_effector_relations_create(
+ Depsgraph *depsgraph,
+ ViewLayer *view_layer,
+ Collection *collection)
+{
+ Base *base = BKE_collection_or_layer_objects(view_layer, collection);
+ const bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+ const int base_flag = (for_render) ? BASE_ENABLED_RENDER : BASE_ENABLED_VIEWPORT;
+
+ ListBase *relations = MEM_callocN(sizeof(ListBase), "effector relations");
+
+ for (; base; base = base->next) {
+ if (!(base->flag & base_flag)) {
+ continue;
+ }
+
+ Object *ob = base->object;
+
+ if (ob->pd && ob->pd->forcefield) {
+ add_effector_relation(relations, ob, NULL, ob->pd);
+ }
+
+ for (ParticleSystem *psys = ob->particlesystem.first; psys; psys = psys->next) {
+ ParticleSettings *part = psys->part;
+
+ if (psys_check_enabled(ob, psys, for_render)) {
+ if (part->pd && part->pd->forcefield) {
+ add_effector_relation(relations, ob, psys, part->pd);
+ }
+ if (part->pd2 && part->pd2->forcefield) {
+ add_effector_relation(relations, ob, psys, part->pd2);
+ }
+ }
+ }
+ }
+
+ return relations;
+}
+
+void BKE_effector_relations_free(ListBase *lb)
+{
+ if (lb) {
+ BLI_freelistN(lb);
+ MEM_freeN(lb);
+ }
+}
+
+/* Create effective list of effectors from relations built beforehand. */
+ListBase *BKE_effectors_create(
+ Depsgraph *depsgraph,
+ Object *ob_src,
+ ParticleSystem *psys_src,
+ EffectorWeights *weights)
+{
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ ListBase *relations = DEG_get_effector_relations(depsgraph, weights->group);
+ ListBase *effectors = NULL;
+
+ if (!relations) {
+ return NULL;
+ }
+
+ for (EffectorRelation *relation = relations->first; relation; relation = relation->next) {
+ /* Get evaluated object. */
+ Object *ob = (Object*)DEG_get_evaluated_id(depsgraph, &relation->ob->id);
+
+ if (relation->psys) {
+ /* Get evaluated particle system. */
+ ParticleSystem *psys = BLI_findstring(&ob->particlesystem,
+ relation->psys->name, offsetof(ParticleSystem, name));
+ ParticleSettings *part = psys->part;
+
+ if (psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0) {
+ continue;
+ }
+
+ PartDeflect *pd = (relation->pd == relation->psys->part->pd) ? part->pd : part->pd2;
+ if (weights->weight[pd->forcefield] == 0.0f) {
+ continue;
+ }
+
+ add_effector_evaluation(&effectors, depsgraph, scene, ob, psys, pd);
+ }
+ else {
+ /* Object effector. */
+ if (ob == ob_src) {
+ continue;
+ }
+ else if (weights->weight[ob->pd->forcefield] == 0.0f) {
+ continue;
+ }
+ else if (ob->pd->shape == PFIELD_SHAPE_POINTS && !ob->derivedFinal) {
+ continue;
+ }
+
+ add_effector_evaluation(&effectors, depsgraph, scene, ob, NULL, ob->pd);
+ }
+ }
+
+ return effectors;
+}
+
+void BKE_effectors_free(ListBase *lb)
+{
+ if (lb) {
+ for (EffectorCache *eff = lb->first; eff; eff = eff->next) {
+ if (eff->guide_data) {
+ MEM_freeN(eff->guide_data);
+ }
+ }
+
+ BLI_freelistN(lb);
+ MEM_freeN(lb);
}
}
@@ -392,7 +426,7 @@ static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, Effect
return visibility;
if (!colls)
- colls = get_collider_cache(eff->scene, eff->ob, NULL);
+ colls = BKE_collider_cache_create(eff->depsgraph, eff->ob, NULL);
if (!colls)
return visibility;
@@ -430,7 +464,7 @@ static float eff_calc_visibility(ListBase *colliders, EffectorCache *eff, Effect
}
if (!colliders)
- free_collider_cache(&colls);
+ BKE_collider_cache_free(&colls);
return visibility;
}
@@ -960,7 +994,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected
}
}
-/* -------- pdDoEffectors() --------
+/* -------- BKE_effectors_apply() --------
* generic force/speed system, now used for particles and softbodies
* scene = scene where it runs in, for time and stuff
* lb = listbase with objects that take part in effecting
@@ -973,7 +1007,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected
* flags = only used for softbody wind now
* guide = old speed of particle
*/
-void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *weights, EffectedPoint *point, float *force, float *impulse)
+void BKE_effectors_apply(ListBase *effectors, ListBase *colliders, EffectorWeights *weights, EffectedPoint *point, float *force, float *impulse)
{
/*
* Modifies the force on a particle according to its