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/depsgraph/intern/builder/deg_builder_relations.cc')
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc145
1 files changed, 143 insertions, 2 deletions
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 7d22ec79acc..b5272d3acf2 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -60,6 +60,7 @@ extern "C" {
#include "DNA_meta_types.h"
#include "DNA_movieclip_types.h"
#include "DNA_node_types.h"
+#include "DNA_particle_types.h"
#include "DNA_object_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
@@ -84,6 +85,7 @@ extern "C" {
#include "BKE_modifier.h"
#include "BKE_node.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_rigidbody.h"
#include "BKE_sound.h"
#include "BKE_texture.h"
@@ -292,9 +294,9 @@ void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key,
MEM_freeN(collobjs);
}
-void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, EffectorWeights *eff, bool add_absorption, const char *name)
+void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key, Scene *scene, Object *ob, ParticleSystem *psys, EffectorWeights *eff, bool add_absorption, const char *name)
{
- ListBase *effectors = pdInitEffectors(scene, ob, eff, false);
+ ListBase *effectors = pdInitEffectors(scene, ob, psys, eff, false);
if (effectors) {
for (EffectorCache *eff = (EffectorCache *)effectors->first; eff; eff = eff->next) {
@@ -303,6 +305,21 @@ void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key,
add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name);
}
+ if (eff->psys) {
+ if (eff->ob != ob) {
+ ComponentKey eff_key(&eff->ob->id, DEPSNODE_TYPE_EVAL_PARTICLES);
+ add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name);
+
+ /* TODO: remove this when/if EVAL_PARTICLES is sufficient for up to date particles */
+ ComponentKey mod_key(&eff->ob->id, DEPSNODE_TYPE_GEOMETRY);
+ add_relation(mod_key, key, DEPSREL_TYPE_STANDARD, name);
+ }
+ else if (eff->psys != psys) {
+ OperationKey eff_key(&eff->ob->id, DEPSNODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, eff->psys->name);
+ add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name);
+ }
+ }
+
if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) {
ComponentKey trf_key(&eff->pd->f_source->id, DEPSNODE_TYPE_TRANSFORM);
add_relation(trf_key, key, DEPSREL_TYPE_STANDARD, "Smoke Force Domain");
@@ -465,6 +482,11 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o
}
}
+ /* particle systems */
+ if (ob->particlesystem.first) {
+ build_particles(scene, ob);
+ }
+
/* grease pencil */
if (ob->gpd) {
build_gpencil(&ob->id, ob->gpd);
@@ -1155,6 +1177,125 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
}
}
+void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
+{
+ TimeSourceKey time_src_key;
+ OperationKey obdata_ubereval_key(&ob->id,
+ DEPSNODE_TYPE_GEOMETRY,
+ DEG_OPCODE_GEOMETRY_UBEREVAL);
+
+ /* particle systems */
+ LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
+ ParticleSettings *part = psys->part;
+
+ /* particle settings */
+ build_animdata(&part->id);
+
+ /* this particle system */
+ OperationKey psys_key(&ob->id, DEPSNODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, psys->name);
+
+ /* XXX: if particle system is later re-enabled, we must do full rebuild? */
+ if (!psys_check_enabled(ob, psys, G.is_rendering))
+ continue;
+
+ /* TODO(sergey): Are all particle systems depends on time?
+ * Hair without dynamics i.e.
+ */
+ add_relation(time_src_key, psys_key,
+ DEPSREL_TYPE_TIME,
+ "TimeSrc -> PSys");
+
+ /* TODO(sergey): Currently particle update is just a placeholder,
+ * hook it to the ubereval node so particle system is getting updated
+ * on playback.
+ */
+ add_relation(psys_key,
+ obdata_ubereval_key,
+ DEPSREL_TYPE_OPERATION,
+ "PSys -> UberEval");
+
+#if 0
+ if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) {
+ LINKLIST_FOREACH (ParticleTarget *, pt, &psys->targets) {
+ if (pt->ob && BLI_findlink(&pt->ob->particlesystem, pt->psys - 1)) {
+ node2 = dag_get_node(dag, pt->ob);
+ dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Targets");
+ }
+ }
+ }
+
+ if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
+ node2 = dag_get_node(dag, part->dup_ob);
+ /* note that this relation actually runs in the wrong direction, the problem
+ * is that dupli system all have this (due to parenting), and the render
+ * engine instancing assumes particular ordering of objects in list */
+ dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualization");
+ if (part->dup_ob->type == OB_MBALL)
+ dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualization");
+ }
+
+ if (part->ren_as == PART_DRAW_GR && part->dup_group) {
+ LINKLIST_FOREACH (GroupObject *, go, &part->dup_group->gobject) {
+ node2 = dag_get_node(dag, go->ob);
+ dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Group Visualization");
+ }
+ }
+#endif
+
+ /* collisions */
+ if (part->type != PART_HAIR) {
+ add_collision_relations(psys_key, scene, ob, part->collision_group, ob->lay, true, "Particle Collision");
+ }
+ else if ((psys->flag & PSYS_HAIR_DYNAMICS) && psys->clmd && psys->clmd->coll_parms) {
+ add_collision_relations(psys_key, scene, ob, psys->clmd->coll_parms->group, ob->lay | scene->lay, true, "Hair Collision");
+ }
+
+ /* effectors */
+ add_forcefield_relations(psys_key, scene, ob, psys, part->effector_weights, part->type == PART_HAIR, "Particle Field");
+
+ /* boids */
+ if (part->boids) {
+ LINKLIST_FOREACH (BoidState *, state, &part->boids->states) {
+ LINKLIST_FOREACH (BoidRule *, rule, &state->rules) {
+ Object *ruleob = NULL;
+ if (rule->type == eBoidRuleType_Avoid)
+ ruleob = ((BoidRuleGoalAvoid *)rule)->ob;
+ else if (rule->type == eBoidRuleType_FollowLeader)
+ ruleob = ((BoidRuleFollowLeader *)rule)->ob;
+
+ if (ruleob) {
+ ComponentKey ruleob_key(&ruleob->id, DEPSNODE_TYPE_TRANSFORM);
+ add_relation(ruleob_key, psys_key, DEPSREL_TYPE_TRANSFORM, "Boid Rule");
+ }
+ }
+ }
+ }
+
+ if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
+ ComponentKey dup_ob_key(&part->dup_ob->id, DEPSNODE_TYPE_TRANSFORM);
+ add_relation(dup_ob_key,
+ psys_key,
+ DEPSREL_TYPE_TRANSFORM,
+ "Particle Object Visualization");
+ }
+ }
+
+ /* Particle depends on the object transform, so that channel is to be ready
+ * first.
+ *
+ * TODO(sergey): This relation should be altered once real granular update
+ * is implemented.
+ */
+ ComponentKey transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM);
+ add_relation(transform_key,
+ obdata_ubereval_key,
+ DEPSREL_TYPE_GEOMETRY_EVAL,
+ "Partcile Eval");
+
+ /* pointcache */
+ // TODO...
+}
+
/* Shapekeys */
void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key)
{