Patch #34204: [Render Animation] Fails with "Error: Specified sample_fmt is not suppo...
[blender.git] / source / blender / blenkernel / intern / scene.c
index 6dba03c..131fb38 100644 (file)
@@ -290,6 +290,9 @@ void BKE_scene_free(Scene *sce)
 {
        Base *base;
 
+       /* check all sequences */
+       BKE_sequencer_clear_scene_in_allseqs(G.main, sce);
+
        base = sce->base.first;
        while (base) {
                base->object->id.us--;
@@ -359,10 +362,7 @@ void BKE_scene_free(Scene *sce)
                sce->toolsettings = NULL;
        }
        
-       if (sce->theDag) {
-               free_forest(sce->theDag);
-               MEM_freeN(sce->theDag);
-       }
+       DAG_scene_free(sce);
        
        if (sce->nodetree) {
                ntreeFreeTree(sce->nodetree);
@@ -435,7 +435,7 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
        sce->r.postsat = 1.0;
 
        sce->r.bake_mode = 1;    /* prevent to include render stuff here */
-       sce->r.bake_filter = 2;
+       sce->r.bake_filter = 16;
        sce->r.bake_osa = 5;
        sce->r.bake_flag = R_BAKE_CLEAR;
        sce->r.bake_normal_space = R_BAKE_SPACE_TANGENT;
@@ -649,12 +649,11 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
        }
 
        /* sort baselist */
-       DAG_scene_sort(bmain, scene);
+       DAG_scene_relations_rebuild(bmain, scene);
        
        /* ensure dags are built for sets */
-       for (sce = scene->set; sce; sce = sce->set)
-               if (sce->theDag == NULL)
-                       DAG_scene_sort(bmain, sce);
+       for (sce = scene; sce; sce = sce->set)
+               DAG_scene_relations_update(bmain, sce);
 
        /* copy layers and flags from bases to objects */
        for (base = scene->base.first; base; base = base->next) {
@@ -697,9 +696,6 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce)
                if (sce1->set == sce)
                        sce1->set = NULL;
        
-       /* check all sequences */
-       BKE_sequencer_clear_scene_in_allseqs(bmain, sce);
-
        /* check render layer nodes in other scenes */
        clear_scene_in_nodes(bmain, sce);
        
@@ -764,7 +760,9 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
                        else {
                                if (*base && fase != F_DUPLI) {
                                        *base = (*base)->next;
-                                       if (*base) *ob = (*base)->object;
+                                       if (*base) {
+                                               *ob = (*base)->object;
+                                       }
                                        else {
                                                if (fase == F_SCENE) {
                                                        /* (*scene) is finished, now do the set */
@@ -781,7 +779,9 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
                                }
                        }
                        
-                       if (*base == NULL) fase = F_START;
+                       if (*base == NULL) {
+                               fase = F_START;
+                       }
                        else {
                                if (fase != F_DUPLI) {
                                        if ( (*base)->object->transflag & OB_DUPLI) {
@@ -1085,13 +1085,22 @@ static void scene_depsgraph_hack(Scene *scene, Scene *scene_parent)
 
 }
 
-static void scene_flag_rbw_recursive(Scene *scene)
+static void scene_rebuild_rbw_recursive(Scene *scene, float ctime)
 {
        if (scene->set)
-               scene_flag_rbw_recursive(scene->set);
+               scene_rebuild_rbw_recursive(scene->set, ctime);
 
        if (BKE_scene_check_rigidbody_active(scene))
-               scene->rigidbody_world->flag |= RBW_FLAG_FRAME_UPDATE;
+               BKE_rigidbody_rebuild_world(scene, ctime);
+}
+
+static void scene_do_rb_simulation_recursive(Scene *scene, float ctime)
+{
+       if (scene->set)
+               scene_do_rb_simulation_recursive(scene->set, ctime);
+
+       if (BKE_scene_check_rigidbody_active(scene))
+               BKE_rigidbody_do_simulation(scene, ctime);
 }
 
 static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scene_parent)
@@ -1105,27 +1114,11 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
        if (scene->set)
                scene_update_tagged_recursive(bmain, scene->set, scene_parent);
        
-       /* run rigidbody sim 
-        * - calculate/read values from cache into RBO's, to get flushed 
-        *   later when objects are evaluated (if they're tagged for eval)
-        */
-       // 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
-       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
-                */
-               float ctime = BKE_scene_frame_get(scene_parent);
-               
-               /* however, "scene" contains the rigidbody world needed for eval... */
-               BKE_rigidbody_do_simulation(scene, ctime);
-       }
-       
        /* scene objects */
        for (base = scene->base.first; base; base = base->next) {
                Object *ob = base->object;
                
-               BKE_object_handle_update_ex(scene_parent, scene->rigidbody_world, ob);
+               BKE_object_handle_update_ex(scene_parent, ob, scene->rigidbody_world);
                
                if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP))
                        group_handle_recalc_and_update(scene_parent, ob, ob->dup_group);
@@ -1150,9 +1143,15 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
 /* this is called in main loop, doing tagged updates before redraw */
 void BKE_scene_update_tagged(Main *bmain, Scene *scene)
 {
+       Scene *sce_iter;
+       
        /* keep this first */
        BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
 
+       /* (re-)build dependency graph if needed */
+       for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set)
+               DAG_scene_relations_update(bmain, sce_iter);
+
        /* flush recalc flags to dependencies */
        DAG_ids_flush_tagged(bmain);
 
@@ -1193,6 +1192,12 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
 {
        float ctime = BKE_scene_frame_get(sce);
        Scene *sce_iter;
+       
+       /* rebuild rigid body worlds before doing the actual frame update
+        * this needs to be done on start frame but animation playback usually starts one frame later
+        * we need to do it here to avoid rebuilding the world on every simulation change, which can be very expensive
+        */
+       scene_rebuild_rbw_recursive(sce, ctime);
 
        /* keep this first */
        BLI_callback_exec(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_PRE);
@@ -1203,10 +1208,8 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
        /* clear animation overrides */
        /* XXX TODO... */
 
-       for (sce_iter = sce; sce_iter; sce_iter = sce_iter->set) {
-               if (sce_iter->theDag == NULL)
-                       DAG_scene_sort(bmain, sce_iter);
-       }
+       for (sce_iter = sce; sce_iter; sce_iter = sce_iter->set)
+               DAG_scene_relations_update(bmain, sce_iter);
 
        /* flush recalc flags to dependencies, if we were only changing a frame
         * this would not be necessary, but if a user or a script has modified
@@ -1234,8 +1237,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);
+       /* run rigidbody sim */
+       /* NOTE: current position is so that rigidbody sim affects other objects, might change in the future */
+       scene_do_rb_simulation_recursive(sce, ctime);
 
        /* BKE_object_handle_update() on all objects, groups and sets */
        scene_update_tagged_recursive(bmain, sce, sce);