Depsgraph: remove EvaluationContext, pass Depsgraph instead.
[blender.git] / source / blender / blenkernel / intern / rigidbody.c
index b8873cca0fbeff1fefbeaae70cb7c515c326d76f..ab8f9dcb2e4b02566287079adfa48abb4d468c69 100644 (file)
@@ -55,9 +55,9 @@
 #include "DNA_scene_types.h"
 
 #include "BKE_cdderivedmesh.h"
-#include "BKE_depsgraph.h"
 #include "BKE_effect.h"
 #include "BKE_global.h"
+#include "BKE_group.h"
 #include "BKE_library.h"
 #include "BKE_library_query.h"
 #include "BKE_mesh.h"
@@ -93,26 +93,30 @@ void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
 
        if (rbw->physics_world) {
                /* free physics references, we assume that all physics objects in will have been added to the world */
-               GroupObject *go;
                if (rbw->constraints) {
-                       for (go = rbw->constraints->gobject.first; go; go = go->next) {
-                               if (go->ob && go->ob->rigidbody_constraint) {
-                                       RigidBodyCon *rbc = go->ob->rigidbody_constraint;
-
-                                       if (rbc->physics_constraint)
+                       FOREACH_GROUP_OBJECT_BEGIN(rbw->constraints, object)
+                       {
+                               if (object->rigidbody_constraint) {
+                                       RigidBodyCon *rbc = object->rigidbody_constraint;
+                                       if (rbc->physics_constraint) {
                                                RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+                                       }
                                }
                        }
+                       FOREACH_GROUP_OBJECT_END;
                }
-               if (rbw->group) {
-                       for (go = rbw->group->gobject.first; go; go = go->next) {
-                               if (go->ob && go->ob->rigidbody_object) {
-                                       RigidBodyOb *rbo = go->ob->rigidbody_object;
 
-                                       if (rbo->physics_object)
+               if (rbw->group) {
+                       FOREACH_GROUP_OBJECT_BEGIN(rbw->group, object)
+                       {
+                               if (object->rigidbody_object) {
+                                       RigidBodyOb *rbo = object->rigidbody_object;
+                                       if (rbo->physics_object) {
                                                RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
+                                       }
                                }
                        }
+                       FOREACH_GROUP_OBJECT_END;
                }
                /* free dynamics world */
                RB_dworld_delete(rbw->physics_world);
@@ -1133,7 +1137,6 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
        RigidBodyWorld *rbw = scene->rigidbody_world;
        RigidBodyOb *rbo = ob->rigidbody_object;
        RigidBodyCon *rbc;
-       GroupObject *go;
        int i;
 
        if (rbw) {
@@ -1153,8 +1156,8 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
 
                /* remove object from rigid body constraints */
                if (rbw->constraints) {
-                       for (go = rbw->constraints->gobject.first; go; go = go->next) {
-                               Object *obt = go->ob;
+                       FOREACH_GROUP_OBJECT_BEGIN(rbw->constraints, obt)
+                       {
                                if (obt && obt->rigidbody_constraint) {
                                        rbc = obt->rigidbody_constraint;
                                        if (ELEM(ob, rbc->ob1, rbc->ob2)) {
@@ -1162,6 +1165,7 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
                                        }
                                }
                        }
+                       FOREACH_GROUP_OBJECT_END;
                }
        }
 
@@ -1195,20 +1199,22 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
 /* Update object array and rigid body count so they're in sync with the rigid body group */
 static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
 {
-       GroupObject *go;
        int i, n;
 
-       n = BLI_listbase_count(&rbw->group->gobject);
+       n = BLI_listbase_count(&rbw->group->view_layer->object_bases);
 
        if (rbw->numbodies != n) {
                rbw->numbodies = n;
                rbw->objects = realloc(rbw->objects, sizeof(Object *) * rbw->numbodies);
        }
 
-       for (go = rbw->group->gobject.first, i = 0; go; go = go->next, i++) {
-               Object *ob = go->ob;
-               rbw->objects[i] = ob;
+       i = 0;
+       FOREACH_GROUP_OBJECT_BEGIN(rbw->group, object)
+       {
+               rbw->objects[i] = object;
+               i++;
        }
+       FOREACH_GROUP_OBJECT_END;
 }
 
 static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
@@ -1231,7 +1237,7 @@ static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
        rigidbody_update_ob_array(rbw);
 }
 
-static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo)
+static void rigidbody_update_sim_ob(struct Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo)
 {
        float loc[3];
        float rot[4];
@@ -1279,7 +1285,7 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o
                ListBase *effectors;
 
                /* get effectors present in the group specified by effector_weights */
-               effectors = pdInitEffectors(scene, ob, NULL, effector_weights, true);
+               effectors = pdInitEffectors(depsgraph, scene, ob, NULL, effector_weights, true);
                if (effectors) {
                        float eff_force[3] = {0.0f, 0.0f, 0.0f};
                        float eff_loc[3], eff_vel[3];
@@ -1320,10 +1326,8 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o
  *
  * \param rebuild Rebuild entire simulation
  */
-static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool rebuild)
+static void rigidbody_update_simulation(struct Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, bool rebuild)
 {
-       GroupObject *go;
-
        /* update world */
        if (rebuild)
                BKE_rigidbody_validate_sim_world(scene, rbw, true);
@@ -1336,28 +1340,26 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool
         * Memory management needs redesign here, this is just a dirty workaround.
         */
        if (rebuild && rbw->constraints) {
-               for (go = rbw->constraints->gobject.first; go; go = go->next) {
-                       Object *ob = go->ob;
-                       if (ob) {
-                               RigidBodyCon *rbc = ob->rigidbody_constraint;
-                               if (rbc && rbc->physics_constraint) {
-                                       RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
-                                       RB_constraint_delete(rbc->physics_constraint);
-                                       rbc->physics_constraint = NULL;
-                               }
+               FOREACH_GROUP_OBJECT_BEGIN(rbw->constraints, ob)
+               {
+                       RigidBodyCon *rbc = ob->rigidbody_constraint;
+                       if (rbc && rbc->physics_constraint) {
+                               RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
+                               RB_constraint_delete(rbc->physics_constraint);
+                               rbc->physics_constraint = NULL;
                        }
                }
+               FOREACH_GROUP_OBJECT_END;
        }
 
        /* update objects */
-       for (go = rbw->group->gobject.first; go; go = go->next) {
-               Object *ob = go->ob;
-
-               if (ob && ob->type == OB_MESH) {
+       FOREACH_GROUP_OBJECT_BEGIN(rbw->group, ob)
+       {
+               if (ob->type == OB_MESH) {
                        /* validate that we've got valid object set up here... */
                        RigidBodyOb *rbo = ob->rigidbody_object;
                        /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
-                       BKE_object_where_is_calc(scene, ob);
+                       BKE_object_where_is_calc(depsgraph, scene, ob);
 
                        if (rbo == NULL) {
                                /* Since this object is included in the sim group but doesn't have
@@ -1391,65 +1393,62 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, bool
                        }
 
                        /* update simulation object... */
-                       rigidbody_update_sim_ob(scene, rbw, ob, rbo);
+                       rigidbody_update_sim_ob(depsgraph, scene, rbw, ob, rbo);
                }
        }
+       FOREACH_GROUP_OBJECT_END;
        
        /* update constraints */
        if (rbw->constraints == NULL) /* no constraints, move on */
                return;
-       for (go = rbw->constraints->gobject.first; go; go = go->next) {
-               Object *ob = go->ob;
 
-               if (ob) {
-                       /* validate that we've got valid object set up here... */
-                       RigidBodyCon *rbc = ob->rigidbody_constraint;
-                       /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
-                       BKE_object_where_is_calc(scene, ob);
+       FOREACH_GROUP_OBJECT_BEGIN(rbw->constraints, ob)
+       {
+               /* validate that we've got valid object set up here... */
+               RigidBodyCon *rbc = ob->rigidbody_constraint;
+               /* update transformation matrix of the object so we don't get a frame of lag for simple animations */
+               BKE_object_where_is_calc(depsgraph, scene, ob);
 
-                       if (rbc == NULL) {
-                               /* Since this object is included in the group but doesn't have
-                                * constraint settings (perhaps it was added manually), add!
-                                */
-                               ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED);
-                               rigidbody_validate_sim_constraint(rbw, ob, true);
+               if (rbc == NULL) {
+                       /* Since this object is included in the group but doesn't have
+                        * constraint settings (perhaps it was added manually), add!
+                        */
+                       ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED);
+                       rigidbody_validate_sim_constraint(rbw, ob, true);
 
-                               rbc = ob->rigidbody_constraint;
+                       rbc = ob->rigidbody_constraint;
+               }
+               else {
+                       /* perform simulation data updates as tagged */
+                       if (rebuild) {
+                               /* World has been rebuilt so rebuild constraint */
+                               rigidbody_validate_sim_constraint(rbw, ob, true);
                        }
-                       else {
-                               /* perform simulation data updates as tagged */
-                               if (rebuild) {
-                                       /* World has been rebuilt so rebuild constraint */
-                                       rigidbody_validate_sim_constraint(rbw, ob, true);
-                               }
-                               else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
-                                       rigidbody_validate_sim_constraint(rbw, ob, false);
-                               }
-                               rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
+                       else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
+                               rigidbody_validate_sim_constraint(rbw, ob, false);
                        }
+                       rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
                }
        }
+       FOREACH_GROUP_OBJECT_END;
 }
 
 static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw)
 {
-       GroupObject *go;
-
-       for (go = rbw->group->gobject.first; go; go = go->next) {
-               Object *ob = go->ob;
-
-               if (ob) {
-                       RigidBodyOb *rbo = ob->rigidbody_object;
-                       /* reset kinematic state for transformed objects */
-                       if (rbo && (ob->flag & SELECT) && (G.moving & G_TRANSFORM_OBJ)) {
-                               RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
-                               RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
-                               /* deactivate passive objects so they don't interfere with deactivation of active objects */
-                               if (rbo->type == RBO_TYPE_PASSIVE)
-                                       RB_body_deactivate(rbo->physics_object);
-                       }
+       FOREACH_GROUP_BASE_BEGIN(rbw->group, base)
+       {
+               Object *ob = base->object;
+               RigidBodyOb *rbo = ob->rigidbody_object;
+               /* Reset kinematic state for transformed objects. */
+               if (rbo && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) {
+                       RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
+                       RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
+                       /* Deactivate passive objects so they don't interfere with deactivation of active objects. */
+                       if (rbo->type == RBO_TYPE_PASSIVE)
+                               RB_body_deactivate(rbo->physics_object);
                }
        }
+       FOREACH_GROUP_BASE_END
 }
 
 bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
@@ -1564,7 +1563,7 @@ void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
 
 /* Rebuild rigid body world */
 /* NOTE: this needs to be called before frame update to work correctly */
-void BKE_rigidbody_rebuild_world(Scene *scene, float ctime)
+void BKE_rigidbody_rebuild_world(struct Depsgraph *depsgraph, Scene *scene, float ctime)
 {
        RigidBodyWorld *rbw = scene->rigidbody_world;
        PointCache *cache;
@@ -1576,14 +1575,14 @@ void BKE_rigidbody_rebuild_world(Scene *scene, float ctime)
        cache = rbw->pointcache;
 
        /* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */
-       if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->gobject)) {
+       if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->view_layer->object_bases)) {
                cache->flag |= PTCACHE_OUTDATED;
        }
 
        if (ctime == startframe + 1 && rbw->ltime == startframe) {
                if (cache->flag & PTCACHE_OUTDATED) {
                        BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
-                       rigidbody_update_simulation(scene, rbw, true);
+                       rigidbody_update_simulation(depsgraph, scene, rbw, true);
                        BKE_ptcache_validate(cache, (int)ctime);
                        cache->last_exact = 0;
                        cache->flag &= ~PTCACHE_REDO_NEEDED;
@@ -1592,7 +1591,7 @@ void BKE_rigidbody_rebuild_world(Scene *scene, float ctime)
 }
 
 /* Run RigidBody simulation for the specified physics world */
-void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
+void BKE_rigidbody_do_simulation(struct Depsgraph *depsgraph, Scene *scene, float ctime)
 {
        float timestep;
        RigidBodyWorld *rbw = scene->rigidbody_world;
@@ -1630,14 +1629,14 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
        }
 
        /* advance simulation, we can only step one frame forward */
-       if (can_simulate) {
+       if (ctime == rbw->ltime + 1) {
                /* write cache for first frame when on second frame */
                if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
                        BKE_ptcache_write(&pid, startframe);
                }
 
                /* update and validate simulation */
-               rigidbody_update_simulation(scene, rbw, false);
+               rigidbody_update_simulation(depsgraph, scene, rbw, false);
 
                /* calculate how much time elapsed since last step in seconds */
                timestep = 1.0f / (float)FPS * (ctime - rbw->ltime) * rbw->time_scale;
@@ -1681,8 +1680,8 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
 void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
 bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; }
 void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
-void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) {}
-void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {}
+void BKE_rigidbody_rebuild_world(struct Depsgraph *depsgraph, Scene *scene, float ctime) {}
+void BKE_rigidbody_do_simulation(struct Depsgraph *depsgraph, Scene *scene, float ctime) {}
 
 #ifdef __GNUC__
 #  pragma GCC diagnostic pop
@@ -1693,29 +1692,29 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {}
 /* -------------------- */
 /* Depsgraph evaluation */
 
-void BKE_rigidbody_rebuild_sim(EvaluationContext *UNUSED(eval_ctx),
+void BKE_rigidbody_rebuild_sim(struct Depsgraph *depsgraph,
                                Scene *scene)
 {
        float ctime = BKE_scene_frame_get(scene);
        DEG_debug_print_eval_time(__func__, scene->id.name, scene, ctime);
        /* rebuild sim data (i.e. after resetting to start of timeline) */
        if (BKE_scene_check_rigidbody_active(scene)) {
-               BKE_rigidbody_rebuild_world(scene, ctime);
+               BKE_rigidbody_rebuild_world(depsgraph, scene, ctime);
        }
 }
 
-void BKE_rigidbody_eval_simulation(EvaluationContext *UNUSED(eval_ctx),
+void BKE_rigidbody_eval_simulation(struct Depsgraph *depsgraph,
                                    Scene *scene)
 {
        float ctime = BKE_scene_frame_get(scene);
        DEG_debug_print_eval_time(__func__, scene->id.name, scene, ctime);
        /* evaluate rigidbody sim */
        if (BKE_scene_check_rigidbody_active(scene)) {
-               BKE_rigidbody_do_simulation(scene, ctime);
+               BKE_rigidbody_do_simulation(depsgraph, scene, ctime);
        }
 }
 
-void BKE_rigidbody_object_sync_transforms(EvaluationContext *UNUSED(eval_ctx),
+void BKE_rigidbody_object_sync_transforms(struct Depsgraph *UNUSED(depsgraph),
                                           Scene *scene,
                                           Object *ob)
 {