rigidbody: Avoid unnecessary simulation updates
authorSergej Reich <sergej.reich@googlemail.com>
Fri, 15 Feb 2013 23:48:36 +0000 (23:48 +0000)
committerSergej Reich <sergej.reich@googlemail.com>
Fri, 15 Feb 2013 23:48:36 +0000 (23:48 +0000)
Now we flag the world for update on frame change and only call
BKE_rigidbody_do_simulation() when needed.

source/blender/blenkernel/intern/rigidbody.c
source/blender/blenkernel/intern/scene.c
source/blender/makesdna/DNA_rigidbody_types.h

index 055ada3..9ae8242 100644 (file)
@@ -1223,6 +1223,8 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
        BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
        cache = rbw->pointcache;
 
+       rbw->flag &= ~RBW_FLAG_FRAME_UPDATE;
+
        /* 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_countlist(&rbw->group->gobject)) {
                cache->flag |= PTCACHE_OUTDATED;
index 13e050f..269751e 100644 (file)
@@ -1089,6 +1089,15 @@ static void scene_depsgraph_hack(Scene *scene, Scene *scene_parent)
 
 }
 
+static void scene_flag_rbw_recursive(Scene *scene)
+{
+       if (scene->set)
+               scene_flag_rbw_recursive(scene->set);
+
+       if (BKE_scene_check_rigidbody_active(scene))
+               scene->rigidbody_world->flag |= RBW_FLAG_FRAME_UPDATE;
+}
+
 static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent)
 {
        Base *base;
@@ -1106,8 +1115,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
         */
        // XXX: this position may still change, objects not being updated correctly before simulation is run
        // NOTE: current position is so that rigidbody sim affects other objects
-       // FIXME: this now gets executed on every update, not just frame change now!!!
-       if (BKE_scene_check_rigidbody_active(scene)) {
+       if (BKE_scene_check_rigidbody_active(scene) && scene->rigidbody_world->flag & RBW_FLAG_FRAME_UPDATE) {
                /* we use frame time of parent (this is "scene" itself for top-level of sets recursion), 
                 * as that is the active scene controlling all timing in file at the moment
                 */
@@ -1230,6 +1238,9 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
        tag_main_idcode(bmain, ID_MA, FALSE);
        tag_main_idcode(bmain, ID_LA, FALSE);
 
+       /* flag rigid body worlds for update */
+       scene_flag_rbw_recursive(sce);
+
        /* BKE_object_handle_update() on all objects, groups and sets */
        scene_update_tagged_recursive(bmain, sce, sce);
 
index ca70313..1636f2f 100644 (file)
@@ -80,7 +80,9 @@ typedef enum eRigidBodyWorld_Flag {
        /* sim data needs to be rebuilt */
        RBW_FLAG_NEEDS_REBUILD          = (1 << 1),
        /* usse split impulse when stepping the simulation */
-       RBW_FLAG_USE_SPLIT_IMPULSE      = (1 << 2)
+       RBW_FLAG_USE_SPLIT_IMPULSE      = (1 << 2),
+       /* need to step simulation after frame update */
+       RBW_FLAG_FRAME_UPDATE           = (1 << 3)
 } eRigidBodyWorld_Flag;
 
 /* ******************************** */