diff options
Diffstat (limited to 'intern/cycles/blender')
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 30 | ||||
-rw-r--r-- | intern/cycles/blender/blender_camera.cpp | 66 | ||||
-rw-r--r-- | intern/cycles/blender/blender_mesh.cpp | 69 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 98 | ||||
-rw-r--r-- | intern/cycles/blender/blender_session.cpp | 11 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.cpp | 7 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 9 | ||||
-rw-r--r-- | intern/cycles/blender/blender_util.h | 12 |
8 files changed, 224 insertions, 78 deletions
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 0ed08589327..8480b0a5256 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -94,6 +94,29 @@ class CyclesRender_PT_integrator(CyclesButtonsPanel, Panel): col.prop(cscene, "blur_glossy") +class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel): + bl_label = "Motion Blur" + bl_options = {'DEFAULT_CLOSED'} + + @classmethod + def poll(cls, context): + return False + + def draw_header(self, context): + rd = context.scene.render + + self.layout.prop(rd, "use_motion_blur", text="") + + def draw(self, context): + layout = self.layout + + rd = context.scene.render + layout.active = rd.use_motion_blur + + row = layout.row() + row.prop(rd, "motion_blur_shutter") + + class CyclesRender_PT_film(CyclesButtonsPanel, Panel): bl_label = "Film" @@ -202,10 +225,10 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel): col.prop(rl, "use_pass_combined") col.prop(rl, "use_pass_z") col.prop(rl, "use_pass_normal") + col.prop(rl, "use_pass_vector") + col.prop(rl, "use_pass_uv") col.prop(rl, "use_pass_object_index") col.prop(rl, "use_pass_material_index") - col.prop(rl, "use_pass_emit") - col.prop(rl, "use_pass_environment") col.prop(rl, "use_pass_ambient_occlusion") col.prop(rl, "use_pass_shadow") @@ -227,6 +250,9 @@ class CyclesRender_PT_layers(CyclesButtonsPanel, Panel): row.prop(rl, "use_pass_transmission_indirect", text="Indirect", toggle=True) row.prop(rl, "use_pass_transmission_color", text="Color", toggle=True) + col.prop(rl, "use_pass_emit", text="Emission") + col.prop(rl, "use_pass_environment") + class Cycles_PT_post_processing(CyclesButtonsPanel, Panel): bl_label = "Post Processing" diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index a21b22bc35a..55a32d8fc10 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -35,6 +35,7 @@ struct BlenderCamera { float ortho_scale; float lens; + float shuttertime; float aperturesize; uint apertureblades; @@ -64,6 +65,7 @@ static void blender_camera_init(BlenderCamera *bcam) bcam->sensor_width = 32.0f; bcam->sensor_height = 18.0f; bcam->sensor_fit = BlenderCamera::AUTO; + bcam->shuttertime = 1.0f; } static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera) @@ -132,6 +134,28 @@ static void blender_camera_from_object(BlenderCamera *bcam, BL::Object b_ob) } } +static Transform blender_camera_matrix(const Transform& tfm, CameraType type) +{ + Transform result; + + if(type == CAMERA_ENVIRONMENT) { + /* make it so environment camera needs to be pointed in the direction + of the positive x-axis to match an environment texture, this way + it is looking at the center of the texture */ + result = tfm * + make_transform( 0.0f, -1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f, + -1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f); + } + else { + /* note the blender camera points along the negative z-axis */ + result = tfm * transform_scale(1.0f, 1.0f, -1.0f); + } + + return transform_clear_scale(result); +} + static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int height) { /* copy camera to compare later */ @@ -224,24 +248,11 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->bladesrotation = bcam->aperturerotation; /* transform */ - cam->matrix = bcam->matrix; - - if(bcam->type == CAMERA_ENVIRONMENT) { - /* make it so environment camera needs to be pointed in the direction - of the positive x-axis to match an environment texture, this way - it is looking at the center of the texture */ - cam->matrix = cam->matrix * - make_transform( 0.0f, -1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - -1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f); - } - else { - /* note the blender camera points along the negative z-axis */ - cam->matrix = cam->matrix * transform_scale(1.0f, 1.0f, -1.0f); - } - - cam->matrix = transform_clear_scale(cam->matrix); + cam->matrix = blender_camera_matrix(bcam->matrix, bcam->type); + cam->motion.pre = cam->matrix; + cam->motion.post = cam->matrix; + cam->use_motion = false; + cam->shuttertime = bcam->shuttertime; /* set update flag */ if(cam->modified(prevcam)) @@ -260,6 +271,7 @@ void BlenderSync::sync_camera(BL::Object b_override, int width, int height) bcam.pixelaspect.x = r.pixel_aspect_x(); bcam.pixelaspect.y = r.pixel_aspect_y(); + bcam.shuttertime = r.motion_blur_shutter(); /* camera object */ BL::Object b_ob = b_scene.camera(); @@ -277,6 +289,23 @@ void BlenderSync::sync_camera(BL::Object b_override, int width, int height) blender_camera_sync(cam, &bcam, width, height); } +void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion) +{ + Camera *cam = scene->camera; + + Transform tfm = get_transform(b_ob.matrix_world()); + tfm = blender_camera_matrix(tfm, cam->type); + + if(tfm != cam->matrix) { + if(motion == -1) + cam->motion.pre = tfm; + else + cam->motion.post = tfm; + + cam->use_motion = true; + } +} + /* Sync 3D View Camera */ void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height) @@ -288,6 +317,7 @@ void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int bcam.nearclip = b_v3d.clip_start(); bcam.farclip = b_v3d.clip_end(); bcam.lens = b_v3d.lens(); + bcam.shuttertime = b_scene.render().motion_blur_shutter(); if(b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA) { /* camera view */ diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 7caa6b3d511..f77e6551de0 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -33,30 +33,6 @@ CCL_NAMESPACE_BEGIN /* Find/Add */ -static bool mesh_need_attribute(Scene *scene, Mesh *mesh, Attribute::Standard std) -{ - if(std == Attribute::STD_NONE) - return false; - - foreach(uint shader, mesh->used_shaders) - if(scene->shaders[shader]->attributes.find(std)) - return true; - - return false; -} - -static bool mesh_need_attribute(Scene *scene, Mesh *mesh, ustring name) -{ - if(name == ustring()) - return false; - - foreach(uint shader, mesh->used_shaders) - if(scene->shaders[shader]->attributes.find(name)) - return true; - - return false; -} - static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders) { /* create vertices */ @@ -66,7 +42,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< mesh->verts.push_back(get_float3(v->co())); /* create vertex normals */ - Attribute *attr_N = mesh->attributes.add(Attribute::STD_VERTEX_NORMAL); + Attribute *attr_N = mesh->attributes.add(ATTR_STD_VERTEX_NORMAL); float3 *N = attr_N->data_float3(); for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++N) @@ -94,8 +70,8 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< /* create generated coordinates. todo: we should actually get the orco coordinates from modifiers, for now we use texspace loc/size which is available in the api. */ - if(mesh_need_attribute(scene, mesh, Attribute::STD_GENERATED)) { - Attribute *attr = mesh->attributes.add(Attribute::STD_GENERATED); + if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) { + Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED); float3 loc = get_float3(b_mesh.texspace_location()); float3 size = get_float3(b_mesh.texspace_size()); @@ -118,7 +94,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< BL::Mesh::tessface_vertex_colors_iterator l; for(b_mesh.tessface_vertex_colors.begin(l); l != b_mesh.tessface_vertex_colors.end(); ++l) { - if(!mesh_need_attribute(scene, mesh, ustring(l->name().c_str()))) + if(!mesh->need_attribute(scene, ustring(l->name().c_str()))) continue; Attribute *attr = mesh->attributes.add( @@ -150,10 +126,10 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< BL::Mesh::tessface_uv_textures_iterator l; for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) { - Attribute::Standard std = (l->active_render())? Attribute::STD_UV: Attribute::STD_NONE; + AttributeStandard std = (l->active_render())? ATTR_STD_UV: ATTR_STD_NONE; ustring name = ustring(l->name().c_str()); - if(!(mesh_need_attribute(scene, mesh, name) || mesh_need_attribute(scene, mesh, std))) + if(!(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std))) continue; Attribute *attr; @@ -329,5 +305,38 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool holdout, bool object_updated) return mesh; } +void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion) +{ + /* todo: displacement, subdivision */ + BL::ID b_ob_data = b_ob.data(); + size_t size = mesh->verts.size(); + + /* skip objects without deforming modifiers. this is not a totally reliable, + * would need a more extensive check to see which objects are animated */ + if(!size || !ccl::object_is_deform_modified(b_ob, b_scene, preview)) + return; + + /* get derived mesh */ + BL::Mesh b_mesh = object_to_mesh(b_ob, b_scene, true, !preview); + + if(b_mesh) { + BL::Mesh::vertices_iterator v; + AttributeStandard std = (motion == -1)? ATTR_STD_MOTION_PRE: ATTR_STD_MOTION_POST; + Attribute *attr_M = mesh->attributes.add(std); + float3 *M = attr_M->data_float3(); + size_t i = 0, size = mesh->verts.size(); + + for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end() && i < size; ++v, M++, i++) + *M = get_float3(v->co()); + + /* if number of vertices changed, or if coordinates stayed the same, drop it */ + if(i != size || memcmp(M, &mesh->verts[0], sizeof(float3)*size) == 0) + mesh->attributes.remove(std); + + /* free derived mesh */ + object_remove_mesh(b_data, b_mesh); + } +} + CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 96faee19af4..b1cd778c6d3 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -16,6 +16,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "camera.h" #include "graph.h" #include "light.h" #include "mesh.h" @@ -188,11 +189,12 @@ void BlenderSync::sync_background_light() /* Object */ -void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag) +void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm, uint layer_flag, int motion) { /* light is handled separately */ if(object_is_light(b_ob)) { - sync_light(b_parent, b_index, b_ob, tfm); + if(!motion) + sync_light(b_parent, b_index, b_ob, tfm); return; } @@ -200,9 +202,31 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, if(!object_is_mesh(b_ob)) return; - /* test if we need to sync */ + /* key to lookup object */ ObjectKey key(b_parent, b_index, b_ob); Object *object; + + /* motion vector case */ + if(motion) { + object = object_map.find(key); + + if(object) { + if(tfm != object->tfm) { + if(motion == -1) + object->motion.pre = tfm; + else + object->motion.post = tfm; + + object->use_motion = true; + } + + sync_mesh_motion(b_ob, object->mesh, motion); + } + + return; + } + + /* test if we need to sync */ bool object_updated = false; if(object_map.sync(&object, b_ob, b_parent, key)) @@ -219,6 +243,9 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, object->name = b_ob.name().c_str(); object->pass_id = b_ob.pass_index(); object->tfm = tfm; + object->motion.pre = tfm; + object->motion.post = tfm; + object->use_motion = false; /* visibility flags for both parent */ object->visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL; @@ -238,16 +265,18 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob, /* Object Loop */ -void BlenderSync::sync_objects(BL::SpaceView3D b_v3d) +void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion) { /* layer data */ uint scene_layer = render_layer.scene_layer; - /* prepare for sync */ - light_map.pre_sync(); - mesh_map.pre_sync(); - object_map.pre_sync(); - mesh_synced.clear(); + if(!motion) { + /* prepare for sync */ + light_map.pre_sync(); + mesh_map.pre_sync(); + object_map.pre_sync(); + mesh_synced.clear(); + } /* object loop */ BL::Scene::objects_iterator b_ob; @@ -270,7 +299,7 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d) bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render(); if(!(b_dup->hide() || dup_hide)) - sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer); + sync_object(*b_ob, b_index, b_dup_ob, tfm, ob_layer, motion); b_index++; } @@ -296,21 +325,50 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d) if(!hide) { /* object itself */ Transform tfm = get_transform(b_ob->matrix_world()); - sync_object(*b_ob, 0, *b_ob, tfm, ob_layer); + sync_object(*b_ob, 0, *b_ob, tfm, ob_layer, motion); } } } - sync_background_light(); + if(!motion) { + sync_background_light(); + + /* handle removed data and modified pointers */ + if(light_map.post_sync()) + scene->light_manager->tag_update(scene); + if(mesh_map.post_sync()) + scene->mesh_manager->tag_update(scene); + if(object_map.post_sync()) + scene->object_manager->tag_update(scene); + mesh_synced.clear(); + } +} + +void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override) +{ + if(scene->need_motion() == Scene::MOTION_NONE) + return; + + /* get camera object here to deal with camera switch */ + BL::Object b_cam = b_scene.camera(); + if(b_override) + b_cam = b_override; + + /* go back and forth one frame */ + int frame = b_scene.frame_current(); + + for(int motion = -1; motion <= 1; motion += 2) { + scene_frame_set(b_scene, frame + motion); + + /* camera object */ + if(b_cam) + sync_camera_motion(b_cam, motion); + + /* mesh objects */ + sync_objects(b_v3d, motion); + } - /* handle removed data and modified pointers */ - if(light_map.post_sync()) - scene->light_manager->tag_update(scene); - if(mesh_map.post_sync()) - scene->mesh_manager->tag_update(scene); - if(object_map.post_sync()) - scene->object_manager->tag_update(scene); - mesh_synced.clear(); + scene_frame_set(b_scene, frame); } CCL_NAMESPACE_END diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index 5ece7aa26e2..f79b9995165 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -91,7 +91,7 @@ void BlenderSession::create_session() /* create sync */ sync = new BlenderSync(b_data, b_scene, scene, !background); - sync->sync_data(b_v3d); + sync->sync_data(b_v3d, b_engine.camera_override()); if(b_rv3d) sync->sync_view(b_v3d, b_rv3d, width, height); @@ -130,6 +130,8 @@ static PassType get_pass_type(BL::RenderPass b_pass) return PASS_OBJECT_ID; case BL::RenderPass::type_UV: return PASS_UV; + case BL::RenderPass::type_VECTOR: + return PASS_MOTION; case BL::RenderPass::type_MATERIAL_INDEX: return PASS_MATERIAL_ID; @@ -168,7 +170,6 @@ static PassType get_pass_type(BL::RenderPass b_pass) case BL::RenderPass::type_REFRACTION: case BL::RenderPass::type_SPECULAR: case BL::RenderPass::type_REFLECTION: - case BL::RenderPass::type_VECTOR: case BL::RenderPass::type_MIST: return PASS_NONE; } @@ -209,6 +210,8 @@ void BlenderSession::render() BL::RenderPass b_pass(*b_pass_iter); PassType pass_type = get_pass_type(b_pass); + if(pass_type == PASS_MOTION && scene->integrator->motion_blur) + continue; if(pass_type != PASS_NONE) Pass::add(pass_type, passes); } @@ -219,7 +222,7 @@ void BlenderSession::render() scene->film->tag_update(scene); /* update scene */ - sync->sync_data(b_v3d, b_iter->name().c_str()); + sync->sync_data(b_v3d, b_engine.camera_override(), b_iter->name().c_str()); /* update session */ int samples = sync->get_layer_samples(); @@ -310,7 +313,7 @@ void BlenderSession::synchronize() } /* data and camera synchronize */ - sync->sync_data(b_v3d); + sync->sync_data(b_v3d, b_engine.camera_override()); if(b_rv3d) sync->sync_view(b_v3d, b_rv3d, width, height); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index 41cd200d003..24cf10bc028 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -121,19 +121,21 @@ bool BlenderSync::sync_recalc() return recalc; } -void BlenderSync::sync_data(BL::SpaceView3D b_v3d, const char *layer) +void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const char *layer) { sync_render_layers(b_v3d, layer); sync_integrator(); sync_film(); sync_shaders(); sync_objects(b_v3d); + sync_motion(b_v3d, b_override); } /* Integrator */ void BlenderSync::sync_integrator() { + BL::RenderSettings r = b_scene.render(); PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); experimental = (RNA_enum_get(&cscene, "feature_set") != 0); @@ -160,6 +162,9 @@ void BlenderSync::sync_integrator() integrator->layer_flag = render_layer.layer; integrator->sample_clamp = get_float(cscene, "sample_clamp"); +#ifdef __MOTION__ + integrator->motion_blur = (!preview && r.use_motion_blur()); +#endif if(integrator->modified(previntegrator)) integrator->tag_update(scene); diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index ab8e4bd8d00..acdcea1ef9b 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -54,7 +54,7 @@ public: /* sync */ bool sync_recalc(); - void sync_data(BL::SpaceView3D b_v3d, const char *layer = 0); + void sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const char *layer = 0); void sync_camera(BL::Object b_override, int width, int height); void sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height); int get_layer_samples() { return render_layer.samples; } @@ -69,7 +69,8 @@ private: /* sync */ void sync_lamps(); void sync_materials(); - void sync_objects(BL::SpaceView3D b_v3d); + void sync_objects(BL::SpaceView3D b_v3d, int motion = 0); + void sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override); void sync_film(); void sync_integrator(); void sync_view(); @@ -79,9 +80,11 @@ private: void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree); Mesh *sync_mesh(BL::Object b_ob, bool holdout, bool object_updated); - void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag); + void sync_object(BL::Object b_parent, int b_index, BL::Object b_object, Transform& tfm, uint layer_flag, int motion); void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm); void sync_background_light(); + void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion); + void sync_camera_motion(BL::Object b_ob, int motion); /* util */ void find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader); diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 67f3a3ab7d9..9184e14bc76 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -49,8 +49,10 @@ void RE_engine_update_progress(struct RenderEngine *engine, float progress); void engine_tag_redraw(void *engine); void engine_tag_update(void *engine); int rna_Object_is_modified(void *ob, void *scene, int settings); +int rna_Object_is_deform_modified(void *ob, void *scene, int settings); void BLI_timestr(double _time, char *str); void rna_ColorRamp_eval(void *coba, float position, float color[4]); +void rna_Scene_frame_set(void *scene, int frame, float subframe); } @@ -94,6 +96,16 @@ static inline bool object_is_modified(BL::Object self, BL::Scene scene, bool pre return rna_Object_is_modified(self.ptr.data, scene.ptr.data, (preview)? (1<<0): (1<<1))? true: false; } +static inline bool object_is_deform_modified(BL::Object self, BL::Scene scene, bool preview) +{ + return rna_Object_is_deform_modified(self.ptr.data, scene.ptr.data, (preview)? (1<<0): (1<<1))? true: false; +} + +static inline void scene_frame_set(BL::Scene scene, int frame) +{ + rna_Scene_frame_set(scene.ptr.data, frame, 0.0f); +} + /* Utilities */ static inline Transform get_transform(BL::Array<float, 16> array) |