Merged changes in the trunk up to revision 42116.
[blender.git] / source / blender / blenkernel / intern / scene.c
index a22743e0bf37c1a9d728945952e734c85483091e..33fb15faa56c1bda15e5505519284745e0abbadc 100644 (file)
@@ -1,8 +1,4 @@
-/*  scene.c
- *  
- * 
- * $Id$
- *
+/*
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -48,6 +44,7 @@
 
 #include "DNA_anim_types.h"
 #include "DNA_group_types.h"
+#include "DNA_node_types.h"
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
@@ -56,6 +53,7 @@
 #include "BLI_math.h"
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
+#include "BLI_callbacks.h"
 
 #include "BKE_anim.h"
 #include "BKE_animsys.h"
@@ -75,6 +73,8 @@
 
 #include "BKE_sound.h"
 
+#include "RE_engine.h"
+
 //XXX #include "BIF_previewrender.h"
 //XXX #include "BIF_editseq.h"
 
@@ -129,7 +129,7 @@ Scene *copy_scene(Scene *sce, int type)
                scen->r.layers= lb;
        }
        else {
-               scen= copy_libblock(sce);
+               scen= copy_libblock(&sce->id);
                BLI_duplicatelist(&(scen->base), &(sce->base));
                
                clear_id_newpoins();
@@ -354,9 +354,11 @@ Scene *add_scene(const char *name)
        sce->r.mblur_samples= 1;
        sce->r.filtertype= R_FILTER_MITCH;
        sce->r.size= 50;
-       sce->r.planes= 24;
-       sce->r.imtype= R_PNG;
-       sce->r.quality= 90;
+
+       sce->r.im_format.planes= R_IMF_PLANES_RGB;
+       sce->r.im_format.imtype= R_IMF_IMTYPE_PNG;
+       sce->r.im_format.quality= 90;
+
        sce->r.displaymode= R_OUTPUT_AREA;
        sce->r.framapto= 100;
        sce->r.images= 100;
@@ -435,7 +437,7 @@ Scene *add_scene(const char *name)
        sce->toolsettings->skgen_resolution = 100;
        sce->toolsettings->skgen_threshold_internal     = 0.01f;
        sce->toolsettings->skgen_threshold_external     = 0.01f;
-       sce->toolsettings->skgen_angle_limit                    = 45.0f;
+       sce->toolsettings->skgen_angle_limit                    = 45.0f;
        sce->toolsettings->skgen_length_ratio                   = 1.3f;
        sce->toolsettings->skgen_length_limit                   = 1.5f;
        sce->toolsettings->skgen_correlation_limit              = 0.98f;
@@ -476,12 +478,14 @@ Scene *add_scene(const char *name)
        sce->r.ffcodecdata.audio_mixrate = 44100;
        sce->r.ffcodecdata.audio_volume = 1.0f;
        sce->r.ffcodecdata.audio_bitrate = 192;
+       sce->r.ffcodecdata.audio_channels = 2;
 
        BLI_strncpy(sce->r.engine, "BLENDER_RENDER", sizeof(sce->r.engine));
 
-       sce->audio.distance_model = 2.0;
-       sce->audio.doppler_factor = 1.0;
-       sce->audio.speed_of_sound = 343.3;
+       sce->audio.distance_model = 2.0f;
+       sce->audio.doppler_factor = 1.0f;
+       sce->audio.speed_of_sound = 343.3f;
+       sce->audio.volume = 1.0f;
 
        BLI_strncpy(sce->r.pic, U.renderdir, sizeof(sce->r.pic));
 
@@ -489,7 +493,7 @@ Scene *add_scene(const char *name)
        sce->r.osa= 8;
 
        /* note; in header_info.c the scene copy happens..., if you add more to renderdata it has to be checked there */
-       scene_add_render_layer(sce);
+       scene_add_render_layer(sce, NULL);
        
        /* game data */
        sce->gm.stereoflag = STEREO_NOSTEREO;
@@ -519,6 +523,23 @@ Scene *add_scene(const char *name)
        sce->gm.flag = GAME_DISPLAY_LISTS;
        sce->gm.matmode = GAME_MAT_MULTITEX;
 
+       sce->gm.obstacleSimulation= OBSTSIMULATION_NONE;
+       sce->gm.levelHeight = 2.f;
+
+       sce->gm.recastData.cellsize = 0.3f;
+       sce->gm.recastData.cellheight = 0.2f;
+       sce->gm.recastData.agentmaxslope = M_PI/2;
+       sce->gm.recastData.agentmaxclimb = 0.9f;
+       sce->gm.recastData.agentheight = 2.0f;
+       sce->gm.recastData.agentradius = 0.6f;
+       sce->gm.recastData.edgemaxlen = 12.0f;
+       sce->gm.recastData.edgemaxerror = 1.3f;
+       sce->gm.recastData.regionminsize = 8.f;
+       sce->gm.recastData.regionmergesize = 20.f;
+       sce->gm.recastData.vertsperpoly = 6;
+       sce->gm.recastData.detailsampledist = 6.0f;
+       sce->gm.recastData.detailsamplemaxerror = 1.0f;
+
        sound_create_scene(sce);
 
        return sce;
@@ -795,6 +816,8 @@ int scene_camera_switch_update(Scene *scene)
                scene->camera= camera;
                return 1;
        }
+#else
+       (void)scene;
 #endif
        return 0;
 }
@@ -897,15 +920,20 @@ int scene_check_setscene(Main *bmain, Scene *sce)
 }
 
 /* This function is needed to cope with fractional frames - including two Blender rendering features
-* mblur (motion blur that renders 'subframes' and blurs them together), and fields rendering. */
-
-/* see also bsystem_time in object.c */
+ * mblur (motion blur that renders 'subframes' and blurs them together), and fields rendering. 
+ */
 float BKE_curframe(Scene *scene)
 {
-       float ctime = scene->r.cfra;
-       ctime+= scene->r.subframe;
-       ctime*= scene->r.framelen;      
+       return BKE_frame_to_ctime(scene, scene->r.cfra);
+}
 
+/* This function is used to obtain arbitrary fractional frames */
+float BKE_frame_to_ctime(Scene *scene, const float frame)
+{
+       float ctime = frame;
+       ctime += scene->r.subframe;
+       ctime *= scene->r.framelen;     
+       
        return ctime;
 }
 
@@ -921,7 +949,7 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
        
        /* scene itself */
        if (scene->adt && scene->adt->drivers.first) {
-               BKE_animsys_evaluate_animdata(&scene->id, scene->adt, ctime, ADT_RECALC_DRIVERS);
+               BKE_animsys_evaluate_animdata(scene, &scene->id, scene->adt, ctime, ADT_RECALC_DRIVERS);
        }
        
        /* world */
@@ -931,7 +959,7 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
                AnimData *adt= BKE_animdata_from_id(wid);
                
                if (adt && adt->drivers.first)
-                       BKE_animsys_evaluate_animdata(wid, adt, ctime, ADT_RECALC_DRIVERS);
+                       BKE_animsys_evaluate_animdata(scene, wid, adt, ctime, ADT_RECALC_DRIVERS);
        }
        
        /* nodes */
@@ -940,7 +968,7 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
                AnimData *adt= BKE_animdata_from_id(nid);
                
                if (adt && adt->drivers.first)
-                       BKE_animsys_evaluate_animdata(nid, adt, ctime, ADT_RECALC_DRIVERS);
+                       BKE_animsys_evaluate_animdata(scene, nid, adt, ctime, ADT_RECALC_DRIVERS);
        }
 }
 
@@ -971,34 +999,52 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
        
        /* scene drivers... */
        scene_update_drivers(bmain, scene);
+
+       /* update sound system animation */
+       sound_update_scene(scene);
 }
 
 /* this is called in main loop, doing tagged updates before redraw */
 void scene_update_tagged(Main *bmain, Scene *scene)
 {
+       /* keep this first */
+       BLI_exec_cb(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
+
+       /* flush recalc flags to dependencies */
        DAG_ids_flush_tagged(bmain);
 
        scene->physics_settings.quick_cache_step= 0;
 
        /* update all objects: drivers, matrices, displists, etc. flags set
-          by depgraph or manual, no layer check here, gets correct flushed */
+          by depgraph or manual, no layer check here, gets correct flushed
 
+          in the future this should handle updates for all datablocks, not
+          only objects and scenes. - brecht */
        scene_update_tagged_recursive(bmain, scene, scene);
 
-       /* recalc scene animation data here (for sequencer) */
+       /* extra call here to recalc scene animation (for sequencer) */
        {
                AnimData *adt= BKE_animdata_from_id(&scene->id);
                float ctime = BKE_curframe(scene);
                
                if (adt && (adt->recalc & ADT_RECALC_ANIM))
-                       BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, 0);
+                       BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, 0);
        }
        
+       /* quick point cache updates */
        if (scene->physics_settings.quick_cache_step)
                BKE_ptcache_quick_cache_all(bmain, scene);
 
-       /* in the future this should handle updates for all datablocks, not
-          only objects and scenes. - brecht */
+       /* notify editors about recalc */
+       DAG_ids_check_recalc(bmain);
+
+       /* keep this last */
+       BLI_exec_cb(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_POST);
+}
+
+void scene_clear_tagged(Main *bmain, Scene *UNUSED(scene))
+{
+       DAG_ids_clear_recalc(bmain);
 }
 
 /* applies changes right away, does all sets too */
@@ -1006,6 +1052,12 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
 {
        float ctime = BKE_curframe(sce);
        Scene *sce_iter;
+
+       /* keep this first */
+       BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_PRE);
+       BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
+
+       sound_set_cfra(sce->r.cfra);
        
        /* clear animation overrides */
        // XXX TODO...
@@ -1015,6 +1067,10 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
                        DAG_scene_sort(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
+          some datablock before scene_update_tagged was called, we need the flush */
+       DAG_ids_flush_tagged(bmain);
 
        /* Following 2 functions are recursive
         * so dont call within 'scene_update_tagged_recursive' */
@@ -1026,21 +1082,29 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
         * can be overridden by settings from Scene, which owns the Texture through a hierarchy
         * such as Scene->World->MTex/Texture) can still get correctly overridden.
         */
-       BKE_animsys_evaluate_all_animation(bmain, ctime);
+       BKE_animsys_evaluate_all_animation(bmain, sce, ctime);
        /*...done with recusrive funcs */
 
        /* object_handle_update() on all objects, groups and sets */
        scene_update_tagged_recursive(bmain, sce, sce);
+
+       /* keep this last */
+       BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_SCENE_UPDATE_POST);
+       BLI_exec_cb(bmain, &sce->id, BLI_CB_EVT_FRAME_CHANGE_POST);
+
+       DAG_ids_clear_recalc(bmain);
 }
 
 /* return default layer, also used to patch old files */
-void scene_add_render_layer(Scene *sce)
+SceneRenderLayer *scene_add_render_layer(Scene *sce, const char *name)
 {
        SceneRenderLayer *srl;
-//     int tot= 1 + BLI_countlist(&sce->r.layers);
-       
+
+       if(!name)
+               name= "RenderLayer";
+
        srl= MEM_callocN(sizeof(SceneRenderLayer), "new render layer");
-       strcpy(srl->name, "RenderLayer");
+       BLI_strncpy(srl->name, name, sizeof(srl->name));
        BLI_uniquename(&sce->r.layers, srl, "RenderLayer", '.', offsetof(SceneRenderLayer, name), sizeof(srl->name));
        BLI_addtail(&sce->r.layers, srl);
 
@@ -1049,6 +1113,45 @@ void scene_add_render_layer(Scene *sce)
        srl->layflag= 0x7FFF;   /* solid ztra halo edge strand */
        srl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
        FRS_add_freestyle_config( srl );
+
+       return srl;
+}
+
+int scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *srl)
+{
+       const int act= BLI_findindex(&scene->r.layers, srl);
+       Scene *sce;
+
+       if (act == -1) {
+               return 0;
+       }
+       else if ( (scene->r.layers.first == scene->r.layers.last) &&
+                 (scene->r.layers.first == srl))
+       {
+               /* ensure 1 layer is kept */
+               return 0;
+       }
+
+       BLI_remlink(&scene->r.layers, srl);
+       MEM_freeN(srl);
+
+       scene->r.actlay= 0;
+
+       for(sce = bmain->scene.first; sce; sce = sce->id.next) {
+               if(sce->nodetree) {
+                       bNode *node;
+                       for(node = sce->nodetree->nodes.first; node; node = node->next) {
+                               if(node->type==CMP_NODE_R_LAYERS && (Scene*)node->id==scene) {
+                                       if(node->custom1==act)
+                                               node->custom1= 0;
+                                       else if(node->custom1>act)
+                                               node->custom1--;
+                               }
+                       }
+               }
+       }
+
+       return 1;
 }
 
 /* render simplification */
@@ -1108,3 +1211,10 @@ Base *_setlooper_base_step(Scene **sce_iter, Base *base)
 
        return NULL;
 }
+
+int scene_use_new_shading_nodes(Scene *scene)
+{
+       RenderEngineType *type= RE_engines_find(scene->r.engine);
+       return (type && type->flag & RE_USE_SHADING_NODES);
+}
+