diff options
Diffstat (limited to 'intern')
40 files changed, 417 insertions, 199 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 5f65fd7506b..c3139831ca2 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -519,6 +519,17 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): min=0.0, max=5.0 ) + cls.motion_blur_position = EnumProperty( + name="Motion Blur Position", + default='CENTER', + description="Offset for the shutter's time interval, allows to change the motion blur trails", + items=( + ('START', "Start on Frame", "The shutter opens at the current frame"), + ('CENTER', "Center on Frame", "The shutter is open during the current frame"), + ('END', "End on Frame", "The shutter closes at the current frame"), + ), + ) + @classmethod def unregister(cls): del bpy.types.Scene.cycles diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index ecd98551747..3700da3263e 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -259,11 +259,14 @@ class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout - rd = context.scene.render + scene = context.scene + cscene = scene.cycles + rd = scene.render layout.active = rd.use_motion_blur - row = layout.row() - row.prop(rd, "motion_blur_shutter") + col = layout.column() + col.prop(cscene, "motion_blur_position", text="Position") + col.prop(rd, "motion_blur_shutter") class CyclesRender_PT_film(CyclesButtonsPanel, Panel): diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp index 1cc601ce148..491b5632ed5 100644 --- a/intern/cycles/blender/blender_camera.cpp +++ b/intern/cycles/blender/blender_camera.cpp @@ -36,6 +36,7 @@ struct BlenderCamera { float lens; float shuttertime; + Camera::MotionPosition motion_position; float aperturesize; uint apertureblades; @@ -83,6 +84,7 @@ static void blender_camera_init(BlenderCamera *bcam, BL::RenderSettings b_render bcam->sensor_height = 18.0f; bcam->sensor_fit = BlenderCamera::AUTO; bcam->shuttertime = 1.0f; + bcam->motion_position = Camera::MOTION_POSITION_CENTER; bcam->border.right = 1.0f; bcam->border.top = 1.0f; bcam->pano_viewplane.right = 1.0f; @@ -409,6 +411,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int cam->shuttertime = bcam->shuttertime; cam->fov_pre = cam->fov; cam->fov_post = cam->fov; + cam->motion_position = bcam->motion_position; /* border */ cam->border = bcam->border; @@ -431,6 +434,22 @@ void BlenderSync::sync_camera(BL::RenderSettings b_render, BL::Object b_override bcam.pixelaspect.y = b_render.pixel_aspect_y(); bcam.shuttertime = b_render.motion_blur_shutter(); + PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); + switch(RNA_enum_get(&cscene, "motion_blur_position")) { + case 0: + bcam.motion_position = Camera::MOTION_POSITION_START; + break; + case 1: + bcam.motion_position = Camera::MOTION_POSITION_CENTER; + break; + case 2: + bcam.motion_position = Camera::MOTION_POSITION_END; + break; + default: + bcam.motion_position = Camera::MOTION_POSITION_CENTER; + break; + } + /* border */ if(b_render.use_border()) { bcam.border.left = b_render.border_min_x(); @@ -487,6 +506,11 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings b_render, BlenderCamera bcam; float aspectratio, sensor_size; blender_camera_init(&bcam, b_render); + + /* TODO(sergey): Consider making it a part of blender_camera_init(). */ + bcam.pixelaspect.x = b_render.pixel_aspect_x(); + bcam.pixelaspect.y = b_render.pixel_aspect_y(); + blender_camera_from_object(&bcam, b_engine, b_ob); blender_camera_viewplane(&bcam, width, height, diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 432c4aaa078..11593807a00 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -558,11 +558,20 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time) bool cancel = false; bool use_portal = false; + uint layer_override = get_layer(b_engine.layer_override()); for(; b_sce && !cancel; b_sce = b_sce.background_set()) { + /* Render layer's scene_layer is affected by local view already, + * which is not a desired behavior here. + */ + uint scene_layers = layer_override ? layer_override : get_layer(b_scene.layers()); for(b_sce.object_bases.begin(b_base); b_base != b_sce.object_bases.end() && !cancel; ++b_base) { BL::Object b_ob = b_base->object(); bool hide = (render_layer.use_viewport_visibility)? b_ob.hide(): b_ob.hide_render(); - uint ob_layer = get_layer(b_base->layers(), b_base->layers_local_view(), render_layer.use_localview, object_is_light(b_ob)); + uint ob_layer = get_layer(b_base->layers(), + b_base->layers_local_view(), + render_layer.use_localview, + object_is_light(b_ob), + scene_layers); hide = hide || !(ob_layer & scene_layer); if(!hide) { @@ -676,6 +685,28 @@ void BlenderSync::sync_motion(BL::RenderSettings b_render, Camera prevcam = *(scene->camera); int frame_center = b_scene.frame_current(); + float frame_center_delta = 0.0f; + + if(scene->need_motion() != Scene::MOTION_PASS && + scene->camera->motion_position != Camera::MOTION_POSITION_CENTER) + { + float shuttertime = scene->camera->shuttertime; + if(scene->camera->motion_position == Camera::MOTION_POSITION_END) { + frame_center_delta = -shuttertime * 0.5f; + } + else { + assert(scene->camera->motion_position == Camera::MOTION_POSITION_START); + frame_center_delta = shuttertime * 0.5f; + } + float time = frame_center + frame_center_delta; + int frame = (int)floorf(time); + float subframe = time - frame; + python_thread_state_restore(python_thread_state); + b_engine.frame_set(frame, subframe); + python_thread_state_save(python_thread_state); + sync_camera_motion(b_render, b_cam, width, height, 0.0f); + sync_objects(b_v3d, 0.0f); + } /* always sample these times for camera motion */ motion_times.insert(-1.0f); @@ -695,7 +726,7 @@ void BlenderSync::sync_motion(BL::RenderSettings b_render, shuttertime = scene->camera->shuttertime; /* compute frame and subframe time */ - float time = frame_center + relative_time * shuttertime * 0.5f; + float time = frame_center + frame_center_delta + relative_time * shuttertime * 0.5f; int frame = (int)floorf(time); float subframe = time - frame; diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index 11bb18a888b..2beeaa5e07a 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -107,15 +107,8 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket b_socket) } } -template <class SocketType> -static void set_default_value(ShaderInput *input, - SocketType b_sock, - BL::BlendData b_data, - BL::ID b_id) +static void set_default_value(ShaderInput *input, BL::NodeSocket b_sock, BL::BlendData b_data, BL::ID b_id) { - /* TODO(sergey): Use static assert to check SocketType is either BL::NodeSocket - * or BL::NodeSocketInterface. - */ /* copy values for non linked inputs */ switch(input->type) { case SHADER_SOCKET_FLOAT: { @@ -918,8 +911,7 @@ static void add_nodes(Scene *scene, * Do this even if the node group has no internal tree, * so that links have something to connect to and assert won't fail. */ - int input_index = 0; - for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input, ++input_index) { + for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) { ProxyNode *proxy = new ProxyNode(convert_socket_type(*b_input)); graph->add(proxy); @@ -928,11 +920,7 @@ static void add_nodes(Scene *scene, input_map[b_input->ptr.data] = proxy->inputs[0]; - /* Use default value from corresponding socket interface since it's - * not copied from group to actual group node. - */ - BL::NodeSocketInterface socket_interface = b_group_ntree.inputs[input_index]; - set_default_value(proxy->inputs[0], socket_interface, b_data, b_ntree); + set_default_value(proxy->inputs[0], *b_input, b_data, b_ntree); } for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) { ProxyNode *proxy = new ProxyNode(convert_socket_type(*b_output)); diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index aed1b6de138..986e90c59f7 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -161,7 +161,12 @@ void BlenderSync::sync_data(BL::RenderSettings b_render, mesh_synced.clear(); /* use for objects and motion sync */ - sync_objects(b_v3d); + if(scene->need_motion() == Scene::MOTION_PASS || + scene->need_motion() == Scene::MOTION_NONE || + scene->camera->motion_position == Camera::MOTION_POSITION_CENTER) + { + sync_objects(b_v3d); + } sync_motion(b_render, b_v3d, b_override, diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 165242d0dff..bd1c37a7560 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -196,7 +196,11 @@ static inline uint get_layer(BL::Array<int, 20> array) return layer; } -static inline uint get_layer(BL::Array<int, 20> array, BL::Array<int, 8> local_array, bool use_local, bool is_light = false) +static inline uint get_layer(BL::Array<int, 20> array, + BL::Array<int, 8> local_array, + bool use_local, + bool is_light = false, + uint scene_layers = (1 << 20) - 1) { uint layer = 0; @@ -205,9 +209,13 @@ static inline uint get_layer(BL::Array<int, 20> array, BL::Array<int, 8> local_a layer |= (1 << i); if(is_light) { - /* consider lamps on all local view layers */ - for(uint i = 0; i < 8; i++) - layer |= (1 << (20+i)); + /* Consider light is visible if it was visible without layer + * override, which matches behavior of Blender Internal. + */ + if(layer & scene_layers) { + for(uint i = 0; i < 8; i++) + layer |= (1 << (20+i)); + } } else { for(uint i = 0; i < 8; i++) diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h index ba79f8c88ae..8c32d03135e 100644 --- a/intern/cycles/device/device_memory.h +++ b/intern/cycles/device/device_memory.h @@ -211,7 +211,10 @@ public: T *resize(size_t width, size_t height = 0, size_t depth = 0) { data_size = width * ((height == 0)? 1: height) * ((depth == 0)? 1: depth); - data.resize(data_size); + if(data.resize(data_size) == NULL) { + clear(); + return NULL; + } data_width = width; data_height = height; data_depth = depth; @@ -226,7 +229,9 @@ public: T *copy(T *ptr, size_t width, size_t height = 0, size_t depth = 0) { T *mem = resize(width, height, depth); - memcpy(mem, ptr, memory_size()); + if(mem != NULL) { + memcpy(mem, ptr, memory_size()); + } return mem; } diff --git a/intern/cycles/kernel/geom/geom_bvh_shadow.h b/intern/cycles/kernel/geom/geom_bvh_shadow.h index e4cba99dc96..cb3f75f2a8f 100644 --- a/intern/cycles/kernel/geom/geom_bvh_shadow.h +++ b/intern/cycles/kernel/geom/geom_bvh_shadow.h @@ -59,7 +59,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, float isect_t = tmax; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #if BVH_FEATURE(BVH_INSTANCING) @@ -302,7 +302,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -338,7 +338,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -353,7 +353,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_subsurface.h b/intern/cycles/kernel/geom/geom_bvh_subsurface.h index a73139f9c88..a093b9b55aa 100644 --- a/intern/cycles/kernel/geom/geom_bvh_subsurface.h +++ b/intern/cycles/kernel/geom/geom_bvh_subsurface.h @@ -63,7 +63,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, uint num_hits = 0; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #if defined(__KERNEL_SSE2__) @@ -240,7 +240,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object = subsurface_object; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -278,7 +278,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance pop */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h index 73d79fd78ee..13d118b6d19 100644 --- a/intern/cycles/kernel/geom/geom_bvh_traversal.h +++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h @@ -65,7 +65,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, int object = OBJECT_NONE; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif isect->t = ray->t; @@ -342,7 +342,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t); #endif @@ -378,7 +378,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance pop */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_volume.h b/intern/cycles/kernel/geom/geom_bvh_volume.h index 41c784869f2..656cd6e7a0e 100644 --- a/intern/cycles/kernel/geom/geom_bvh_volume.h +++ b/intern/cycles/kernel/geom/geom_bvh_volume.h @@ -59,7 +59,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif isect->t = ray->t; @@ -267,7 +267,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t); #endif @@ -307,7 +307,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, /* instance pop */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_bvh_volume_all.h b/intern/cycles/kernel/geom/geom_bvh_volume_all.h index b6db36f4b17..8f7e3adae51 100644 --- a/intern/cycles/kernel/geom/geom_bvh_volume_all.h +++ b/intern/cycles/kernel/geom/geom_bvh_volume_all.h @@ -62,7 +62,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #if BVH_FEATURE(BVH_INSTANCING) @@ -230,10 +230,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); #else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -268,10 +268,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -311,10 +311,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -341,7 +341,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -384,7 +384,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, if(num_hits_in_instance) { float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -397,7 +397,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, else { float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h index 9d0a008fff1..ffd2f3b778f 100644 --- a/intern/cycles/kernel/geom/geom_object.h +++ b/intern/cycles/kernel/geom/geom_object.h @@ -428,8 +428,8 @@ ccl_device_inline void qbvh_instance_push(KernelGlobals *kg, ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t) { if(*t != FLT_MAX) { - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - *t *= len(transform_direction(&tfm, 1.0f/(*idir))); + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + *t /= len(transform_direction(&tfm, ray->D)); } *P = ray->P; @@ -441,8 +441,8 @@ ccl_device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac) { - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - *t_fac = len(transform_direction(&tfm, 1.0f/(*idir))); + Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + *t_fac = 1.0f / len(transform_direction(&tfm, ray->D)); *P = ray->P; *dir = bvh_clamp_direction(ray->D); @@ -453,15 +453,21 @@ ccl_device_inline void bvh_instance_pop_factor(KernelGlobals *kg, int object, co #ifdef __OBJECT_MOTION__ /* Transform ray into object space to enter motion blurred object in BVH */ -ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t, Transform *tfm) +ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + ccl_addr_space float *t, + Transform *itfm) { - Transform itfm; - *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm); + object_fetch_transform_motion_test(kg, object, ray->time, itfm); - *P = transform_point(&itfm, ray->P); + *P = transform_point(itfm, ray->P); float len; - *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len)); + *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len)); *idir = bvh_inverse_direction(*dir); if(*t != FLT_MAX) @@ -475,18 +481,24 @@ ccl_device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, c * TODO(sergey): Investigate if passing NULL instead of t1 gets optimized * so we can avoid having this duplication. */ -ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t, float *t1, Transform *tfm) +ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + float *t, + float *t1, + Transform *itfm) { - Transform itfm; - *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm); + object_fetch_transform_motion_test(kg, object, ray->time, itfm); - *P = transform_point(&itfm, ray->P); + *P = transform_point(itfm, ray->P); float len; - *dir = bvh_clamp_direction(normalize_len(transform_direction(&itfm, ray->D), &len)); + *dir = bvh_clamp_direction(normalize_len(transform_direction(itfm, ray->D), &len)); *idir = bvh_inverse_direction(*dir); - if(*t != FLT_MAX) *t *= len; @@ -497,10 +509,18 @@ ccl_device_inline void qbvh_instance_motion_push(KernelGlobals *kg, int object, /* Transorm ray to exit motion blurred object in BVH */ -ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, ccl_addr_space float *t, Transform *tfm) +ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + ccl_addr_space float *t, + Transform *itfm) { - if(*t != FLT_MAX) - *t *= len(transform_direction(tfm, 1.0f/(*idir))); + if(*t != FLT_MAX) { + *t /= len(transform_direction(itfm, ray->D)); + } *P = ray->P; *dir = bvh_clamp_direction(ray->D); @@ -509,10 +529,16 @@ ccl_device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, co /* Same as above, but returns scale factor to apply to multiple intersection distances */ -ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *dir, float3 *idir, float *t_fac, Transform *tfm) +ccl_device_inline void bvh_instance_motion_pop_factor(KernelGlobals *kg, + int object, + const Ray *ray, + float3 *P, + float3 *dir, + float3 *idir, + float *t_fac, + Transform *itfm) { - *t_fac = len(transform_direction(tfm, 1.0f/(*idir))); - + *t_fac /= len(transform_direction(itfm, ray->D)); *P = ray->P; *dir = bvh_clamp_direction(ray->D); *idir = bvh_inverse_direction(*dir); diff --git a/intern/cycles/kernel/geom/geom_qbvh_shadow.h b/intern/cycles/kernel/geom/geom_qbvh_shadow.h index dc37e6ecfa4..4564d5baf5e 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_shadow.h +++ b/intern/cycles/kernel/geom/geom_qbvh_shadow.h @@ -55,7 +55,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, float isect_t = tmax; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif *num_hits = 0; @@ -317,7 +317,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -357,7 +357,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -370,7 +370,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h index d85e1a4691e..fe231720cf7 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_subsurface.h +++ b/intern/cycles/kernel/geom/geom_qbvh_subsurface.h @@ -58,7 +58,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, uint num_hits = 0; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #ifndef __KERNEL_SSE41__ @@ -256,7 +256,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, object = subsurface_object; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -297,7 +297,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance pop. */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect_t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_traversal.h b/intern/cycles/kernel/geom/geom_qbvh_traversal.h index 7e356ea062b..4e1678665c0 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_traversal.h +++ b/intern/cycles/kernel/geom/geom_qbvh_traversal.h @@ -63,7 +63,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, int object = OBJECT_NONE; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #ifndef __KERNEL_SSE41__ @@ -356,7 +356,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, object = kernel_tex_fetch(__prim_object, -primAddr-1); #if BVH_FEATURE(BVH_MOTION) - qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist, &ob_tfm); + qbvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist, &ob_itfm); #else qbvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t, &nodeDist); #endif @@ -395,7 +395,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance pop. */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_volume.h b/intern/cycles/kernel/geom/geom_qbvh_volume.h index d8cfa3a4061..40864471d13 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_volume.h +++ b/intern/cycles/kernel/geom/geom_qbvh_volume.h @@ -54,7 +54,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif #ifndef __KERNEL_SSE41__ @@ -281,7 +281,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t); #endif @@ -322,7 +322,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, /* Instance pop. */ #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t); #endif diff --git a/intern/cycles/kernel/geom/geom_qbvh_volume_all.h b/intern/cycles/kernel/geom/geom_qbvh_volume_all.h index 056ca9a1ad9..75e4c4e8d96 100644 --- a/intern/cycles/kernel/geom/geom_qbvh_volume_all.h +++ b/intern/cycles/kernel/geom/geom_qbvh_volume_all.h @@ -57,7 +57,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, const uint visibility = PATH_RAY_ALL_VISIBILITY; #if BVH_FEATURE(BVH_MOTION) - Transform ob_tfm; + Transform ob_itfm; #endif uint num_hits = 0; @@ -247,10 +247,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) #if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); #else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -285,10 +285,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -328,10 +328,10 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits == max_hits) { #if BVH_FEATURE(BVH_INSTANCING) # if BVH_FEATURE(BVH_MOTION) - float t_fac = len(transform_direction(&ob_tfm, 1.0f/idir)); + float t_fac = 1.0f / len(transform_direction(&ob_itfm, dir)); # else - Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM); - float t_fac = len(transform_direction(&tfm, 1.0f/idir)); + Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM); + float t_fac = 1.0f / len(transform_direction(&itfm, dir)); #endif for(int i = 0; i < num_hits_in_instance; i++) { (isect_array-i-1)->t *= t_fac; @@ -355,7 +355,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(object_flag & SD_OBJECT_HAS_VOLUME) { #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_tfm); + bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect_t, &ob_itfm); #else bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect_t); #endif @@ -400,7 +400,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, if(num_hits_in_instance) { float t_fac; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_tfm); + bvh_instance_motion_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac, &ob_itfm); #else bvh_instance_pop_factor(kg, object, ray, &P, &dir, &idir, &t_fac); #endif @@ -413,7 +413,7 @@ ccl_device uint BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg, else { float ignore_t = FLT_MAX; #if BVH_FEATURE(BVH_MOTION) - bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_tfm); + bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &ignore_t, &ob_itfm); #else bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &ignore_t); #endif diff --git a/intern/cycles/kernel/kernel_path_surface.h b/intern/cycles/kernel/kernel_path_surface.h index fe85a6b6e4b..4485be8a5b3 100644 --- a/intern/cycles/kernel/kernel_path_surface.h +++ b/intern/cycles/kernel/kernel_path_surface.h @@ -150,7 +150,7 @@ ccl_device bool kernel_branched_path_surface_bounce(KernelGlobals *kg, RNG *rng, /* setup ray */ ray->P = ray_offset(ccl_fetch(sd, P), (label & LABEL_TRANSMIT)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng)); - ray->D = bsdf_omega_in; + ray->D = normalize(bsdf_omega_in); ray->t = FLT_MAX; #ifdef __RAY_DIFFERENTIALS__ ray->dP = ccl_fetch(sd, dP); @@ -257,7 +257,7 @@ ccl_device_inline bool kernel_path_surface_bounce(KernelGlobals *kg, ccl_addr_sp /* setup ray */ ray->P = ray_offset(ccl_fetch(sd, P), (label & LABEL_TRANSMIT)? -ccl_fetch(sd, Ng): ccl_fetch(sd, Ng)); - ray->D = bsdf_omega_in; + ray->D = normalize(bsdf_omega_in); if(state->bounce == 0) ray->t -= ccl_fetch(sd, ray_length); /* clipping works through transparent */ diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h index 97bd1b1ac92..c0bf25ac1c7 100644 --- a/intern/cycles/kernel/osl/osl_closures.h +++ b/intern/cycles/kernel/osl/osl_closures.h @@ -72,7 +72,7 @@ void name(RendererServices *, int id, void *data) \ #define CCLOSURE_PREPARE_STATIC(name, classname) static CCLOSURE_PREPARE(name, classname) #define CLOSURE_FLOAT3_PARAM(st, fld) \ - { TypeDesc::TypeVector, reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) } + { TypeDesc::TypeVector, (int)reckless_offsetof(st, fld), NULL, sizeof(OSL::Vec3) } #define TO_VEC3(v) OSL::Vec3(v.x, v.y, v.z) #define TO_COLOR3(v) OSL::Color3(v.x, v.y, v.z) diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index c495ebb35bd..2120c892490 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -411,7 +411,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * sc->data1 = param2; sc->data2 = -stack_load_float(stack, data_node.z); - if(!(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE)) { + if(stack_valid(data_node.y)) { + sc->T = normalize(stack_load_float3(stack, data_node.y)); + } + else if(!(ccl_fetch(sd, type) & PRIMITIVE_ALL_CURVE)) { sc->T = normalize(ccl_fetch(sd, dPdv)); sc->data2 = 0.0f; } diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 127d116e556..88ff7fbb70a 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -29,6 +29,7 @@ CCL_NAMESPACE_BEGIN Camera::Camera() { shuttertime = 1.0f; + motion_position = MOTION_POSITION_CENTER; aperturesize = 0.0f; focaldistance = 10.0f; diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h index 1bedb051112..53bd4f0bc14 100644 --- a/intern/cycles/render/camera.h +++ b/intern/cycles/render/camera.h @@ -32,12 +32,24 @@ class Scene; /* Camera * * The camera parameters are quite standard, tested to be both compatible with - * Renderman, and Blender after remapping. */ + * Renderman, and Blender after remapping. + */ class Camera { public: + /* Specifies an offset for the shutter's time interval. */ + enum MotionPosition { + /* Shutter opens at the current frame. */ + MOTION_POSITION_START, + /* Shutter is fully open at the current frame. */ + MOTION_POSITION_CENTER, + /* Shutter closes at the current frame. */ + MOTION_POSITION_END, + }; + /* motion blur */ float shuttertime; + MotionPosition motion_position; /* depth of field */ float focaldistance; diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp index 7bceb8a8bfa..486ae5b597f 100644 --- a/intern/cycles/render/image.cpp +++ b/intern/cycles/render/image.cpp @@ -69,6 +69,9 @@ void ImageManager::set_extended_image_limits(const DeviceInfo& info) else if((info.type == DEVICE_CUDA || info.type == DEVICE_MULTI) && info.extended_images) { tex_num_images = TEX_EXTENDED_NUM_IMAGES_GPU; } + else if(info.pack_images) { + tex_num_images = TEX_PACKED_NUM_IMAGES; + } } bool ImageManager::set_animation_frame_update(int frame) @@ -447,6 +450,9 @@ bool ImageManager::file_load_image(Image *img, device_vector<uchar4>& tex_img) /* read RGBA pixels */ uchar *pixels = (uchar*)tex_img.resize(width, height, depth); + if(pixels == NULL) { + return false; + } bool cmyk = false; if(in) { @@ -570,6 +576,9 @@ bool ImageManager::file_load_float_image(Image *img, device_vector<float4>& tex_ /* read RGBA pixels */ float *pixels = (float*)tex_img.resize(width, height, depth); + if(pixels == NULL) { + return false; + } bool cmyk = false; if(in) { diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h index bcc58ae951b..c79c152afde 100644 --- a/intern/cycles/render/image.h +++ b/intern/cycles/render/image.h @@ -40,6 +40,13 @@ CCL_NAMESPACE_BEGIN #define TEX_EXTENDED_NUM_IMAGES_CPU 1024 #define TEX_EXTENDED_IMAGE_BYTE_START TEX_EXTENDED_NUM_FLOAT_IMAGES +/* Limitations for packed images. + * + * Technically number of textures is unlimited, but it should in + * fact be in sync with CPU limitations. + */ +#define TEX_PACKED_NUM_IMAGES 1024 + /* color to use when textures are not found */ #define TEX_IMAGE_MISSING_R 1 #define TEX_IMAGE_MISSING_G 0 diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index bb76383c5cf..7ac872b8416 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2358,6 +2358,7 @@ HairBsdfNode::HairBsdfNode() add_input("Offset", SHADER_SOCKET_FLOAT); add_input("RoughnessU", SHADER_SOCKET_FLOAT); add_input("RoughnessV", SHADER_SOCKET_FLOAT); + add_input("Tangent", SHADER_SOCKET_VECTOR); } void HairBsdfNode::compile(SVMCompiler& compiler) diff --git a/intern/cycles/util/util_optimization.h b/intern/cycles/util/util_optimization.h index c951c35fc76..42d3ca69b3a 100644 --- a/intern/cycles/util/util_optimization.h +++ b/intern/cycles/util/util_optimization.h @@ -101,7 +101,7 @@ #ifdef _MSC_VER #include <intrin.h> -#else +#elif (defined(__x86_64__) || defined(__i386__)) #include <x86intrin.h> #endif diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index ba8d04b5c16..f01db64a79b 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -347,7 +347,12 @@ ccl_device_inline Transform transform_quick_inverse(Transform M) * scale can be inverted but what about shearing? */ Transform R; float det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z); - + if(det == 0.0f) { + M.x.x += 1e-8f; + M.y.y += 1e-8f; + M.z.z += 1e-8f; + det = M.x.x*(M.z.z*M.y.y - M.z.y*M.y.z) - M.y.x*(M.z.z*M.x.y - M.z.y*M.x.z) + M.z.x*(M.y.z*M.x.y - M.y.y*M.x.z); + } det = (det != 0.0f)? 1.0f/det: 0.0f; float3 Rx = det*make_float3(M.z.z*M.y.y - M.z.y*M.y.z, M.z.y*M.x.z - M.z.z*M.x.y, M.y.z*M.x.y - M.y.y*M.x.z); diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h index ee1f997721d..623436483a0 100644 --- a/intern/cycles/util/util_vector.h +++ b/intern/cycles/util/util_vector.h @@ -163,7 +163,7 @@ public: util_aligned_free(data); } - void resize(size_t newsize) + T* resize(size_t newsize) { if(newsize == 0) { clear(); @@ -171,7 +171,12 @@ public: else if(newsize != datasize) { if(newsize > capacity) { T *newdata = (T*)util_aligned_malloc(sizeof(T)*newsize, alignment); - if(data) { + if(newdata == NULL) { + /* Allocation failed, likely out of memory. */ + clear(); + return NULL; + } + else if(data) { memcpy(newdata, data, ((datasize < newsize)? datasize: newsize)*sizeof(T)); util_aligned_free(data); } @@ -180,12 +185,15 @@ public: } datasize = newsize; } + return data; } void clear() { - util_aligned_free(data); - data = NULL; + if(data != NULL) { + util_aligned_free(data); + data = NULL; + } datasize = 0; capacity = 0; } diff --git a/intern/elbeem/intern/simulation_object.cpp b/intern/elbeem/intern/simulation_object.cpp index 99c3b170634..f2f928f07dc 100644 --- a/intern/elbeem/intern/simulation_object.cpp +++ b/intern/elbeem/intern/simulation_object.cpp @@ -172,7 +172,7 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob) mpLbm->setParticleTracer( mpParts ); if(mpElbeemSettings) { // set further settings from API struct init - if(mpElbeemSettings->outputPath) this->mOutFilename = string(mpElbeemSettings->outputPath); + this->mOutFilename = string(mpElbeemSettings->outputPath); mpLbm->initDomainTrafo( mpElbeemSettings->surfaceTrafo ); mpLbm->setSmoothing(1.0 * mpElbeemSettings->surfaceSmoothing, 1.0 * mpElbeemSettings->surfaceSmoothing); mpLbm->setIsoSubdivs(mpElbeemSettings->surfaceSubdivs); diff --git a/intern/ghost/intern/GHOST_ContextCGL.h b/intern/ghost/intern/GHOST_ContextCGL.h index 92fdbfc53de..953235669a8 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.h +++ b/intern/ghost/intern/GHOST_ContextCGL.h @@ -128,18 +128,9 @@ public: private: //void initContextCGLEW() - /** The window containing the OpenGL view */ - NSWindow *m_window; - /** The openGL view */ NSOpenGLView *m_openGLView; - const int m_contextProfileMask; - const int m_contextMajorVersion; - const int m_contextMinorVersion; - const int m_contextFlags; - const int m_contextResetNotificationStrategy; - /** The OpenGL drawing context */ NSOpenGLContext *m_openGLContext; diff --git a/intern/ghost/intern/GHOST_ContextCGL.mm b/intern/ghost/intern/GHOST_ContextCGL.mm index 51895e5fa1a..6a9c23ea72b 100644 --- a/intern/ghost/intern/GHOST_ContextCGL.mm +++ b/intern/ghost/intern/GHOST_ContextCGL.mm @@ -58,16 +58,9 @@ GHOST_ContextCGL::GHOST_ContextCGL( int contextFlags, int contextResetNotificationStrategy) : GHOST_Context(stereoVisual, numOfAASamples), - m_window(window), m_openGLView(openGLView), - m_contextProfileMask(contextProfileMask), - m_contextMajorVersion(contextMajorVersion), - m_contextMinorVersion(contextMinorVersion), - m_contextFlags(contextFlags), - m_contextResetNotificationStrategy(contextResetNotificationStrategy), m_openGLContext(nil) { - assert(window != nil); assert(openGLView != nil); } diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp index 9ab1fbdaf54..439b3ba5791 100644 --- a/intern/ghost/intern/GHOST_ContextGLX.cpp +++ b/intern/ghost/intern/GHOST_ContextGLX.cpp @@ -41,6 +41,13 @@ #include <cstring> #include <iostream> +/* needed for intel drivers (works w/ mesa-swrast & nvidia) */ +#define USE_GLXEW_INIT_WORKAROUND + +#ifdef USE_GLXEW_INIT_WORKAROUND +static GLuint _glewStrLen(const GLubyte *s); +static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end); +#endif #ifdef WITH_GLEW_MX GLXEWContext *glxewContext = NULL; @@ -157,10 +164,54 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler); #endif - /* needed so 'GLXEW_ARB_create_context' is valid */ - mxIgnoreNoVersion(1); - initContextGLXEW(); - mxIgnoreNoVersion(0); + + + /* -------------------------------------------------------------------- */ + /* Begin Inline Glew */ + +#ifdef USE_GLXEW_INIT_WORKAROUND + const GLubyte *extStart = (GLubyte *)""; + const GLubyte *extEnd; + if (glXQueryExtension(m_display, NULL, NULL)) { + extStart = (const GLubyte *)glXGetClientString(m_display, GLX_EXTENSIONS); + if ((extStart == NULL) || + (glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)glXGetProcAddressARB( + (const GLubyte *)"glXChooseFBConfig")) == NULL || + (glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddressARB( + (const GLubyte *)"glXCreateContextAttribsARB")) == NULL) + { + extStart = (GLubyte *)""; + } + } + extEnd = extStart + _glewStrLen(extStart); + +#undef GLXEW_ARB_create_context + const bool GLXEW_ARB_create_context = + _glewSearchExtension("GLX_ARB_create_context", extStart, extEnd); +#undef GLXEW_ARB_create_context_profile + const bool GLXEW_ARB_create_context_profile = + _glewSearchExtension("GLX_ARB_create_context_profile", extStart, extEnd); +#undef GLXEW_ARB_create_context_robustness +const bool GLXEW_ARB_create_context_robustness = + _glewSearchExtension("GLX_ARB_create_context_robustness", extStart, extEnd); +#ifdef WITH_GLEW_ES +#undef GLXEW_EXT_create_context_es_profile + const bool GLXEW_EXT_create_context_es_profile = + _glewSearchExtension("GLX_EXT_create_context_es_profile", extStart, extEnd); +#undef GLXEW_EXT_create_context_es2_profile + const bool GLXEW_EXT_create_context_es2_profile = + _glewSearchExtension("GLX_EXT_create_context_es2_profile", extStart, extEnd); +#endif /* WITH_GLEW_ES */ + + /* End Inline Glew */ + /* -------------------------------------------------------------------- */ +#else + /* important to initialize only glxew (_not_ glew), + * since this breaks w/ Mesa's `swrast`, see: T46431 */ + glxewInit(); +#endif /* USE_GLXEW_INIT_WORKAROUND */ + + if (GLXEW_ARB_create_context) { int profileBitCore = m_contextProfileMask & GLX_CONTEXT_CORE_PROFILE_BIT_ARB; @@ -273,6 +324,10 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext() glXMakeCurrent(m_display, m_window, m_context); + // Seems that this has to be called after MakeCurrent, + // which means we cannot use glX extensions until after we create a context + initContextGLXEW(); + initClearGL(); ::glXSwapBuffers(m_display, m_window); @@ -413,3 +468,45 @@ int GHOST_X11_GL_GetAttributes( return i; } + + +/* excuse inlining part of glew */ +#ifdef USE_GLXEW_INIT_WORKAROUND +static GLuint _glewStrLen(const GLubyte *s) +{ + GLuint i = 0; + if (s == NULL) return 0; + while (s[i] != '\0') i++; + return i; +} + +static GLuint _glewStrCLen(const GLubyte *s, GLubyte c) +{ + GLuint i = 0; + if (s == NULL) return 0; + while (s[i] != '\0' && s[i] != c) i++; + return (s[i] == '\0' || s[i] == c) ? i : 0; +} + +static GLboolean _glewStrSame(const GLubyte *a, const GLubyte *b, GLuint n) +{ + GLuint i = 0; + if (a == NULL || b == NULL) + return (a == NULL && b == NULL && n == 0) ? GL_TRUE : GL_FALSE; + while (i < n && a[i] != '\0' && b[i] != '\0' && a[i] == b[i]) i++; + return i == n ? GL_TRUE : GL_FALSE; +} + +static GLboolean _glewSearchExtension(const char *name, const GLubyte *start, const GLubyte *end) +{ + const GLubyte *p; + GLuint len = _glewStrLen((const GLubyte *)name); + p = start; + while (p < end) { + GLuint n = _glewStrCLen(p, ' '); + if (len == n && _glewStrSame((const GLubyte *)name, p, n)) return GL_TRUE; + p += n + 1; + } + return GL_FALSE; +} +#endif /* USE_GLXEW_INIT_WORKAROUND */ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h index 3d6b40ee541..cfddd5b3781 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.h +++ b/intern/ghost/intern/GHOST_SystemCocoa.h @@ -297,9 +297,8 @@ protected: */ GHOST_TInt32 m_cursorDelta_x, m_cursorDelta_y; - /** Multitouch trackpad availability */ - bool m_hasMultiTouchTrackpad; - + /** Temporarily ignore momentum scroll events */ + bool m_ignoreMomentumScroll; }; #endif // __GHOST_SYSTEMCOCOA_H__ diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 37c2ac12315..a3c48ff3b2d 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -284,7 +284,7 @@ extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) * CocoaAppDelegate * ObjC object to capture applicationShouldTerminate, and send quit event **/ -@interface CocoaAppDelegate : NSObject { +@interface CocoaAppDelegate : NSObject <NSFileManagerDelegate> { GHOST_SystemCocoa *systemCocoa; } - (void)setSystemCocoa:(GHOST_SystemCocoa *)sysCocoa; @@ -370,12 +370,11 @@ GHOST_SystemCocoa::GHOST_SystemCocoa() rstring = (char*)malloc( len ); sysctl( mib, 2, rstring, &len, NULL, 0 ); - m_hasMultiTouchTrackpad = false; - free( rstring ); rstring = NULL; m_ignoreWindowSizedMessages = false; + m_ignoreMomentumScroll = false; } GHOST_SystemCocoa::~GHOST_SystemCocoa() @@ -1223,10 +1222,10 @@ bool GHOST_SystemCocoa::handleTabletEvent(void *eventPtr) NSEvent *event = (NSEvent *)eventPtr; switch ([event subtype]) { - case NX_SUBTYPE_TABLET_POINT: + case NSTabletPointEventSubtype: handleTabletEvent(eventPtr, NSTabletPoint); return true; - case NX_SUBTYPE_TABLET_PROXIMITY: + case NSTabletProximityEventSubtype: handleTabletEvent(eventPtr, NSTabletProximity); return true; default: @@ -1390,25 +1389,36 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) } } break; - - /* these events only happen on swiping trackpads or tablets */ - /* warning: using tablet + trackpad at same time frustrates this static variable */ - case NSEventTypeBeginGesture: - m_hasMultiTouchTrackpad = 1; - break; - case NSEventTypeEndGesture: - m_hasMultiTouchTrackpad = 0; - break; - + case NSScrollWheel: { - int *momentum = NULL; + NSEventPhase momentumPhase = NSEventPhaseNone; + NSEventPhase phase = NSEventPhaseNone; + bool hasMultiTouch = false; if ([event respondsToSelector:@selector(momentumPhase)]) - momentum = (int *)[event momentumPhase]; + momentumPhase = [event momentumPhase]; + if ([event respondsToSelector:@selector(phase)]) + phase = [event phase]; + if ([event respondsToSelector:@selector(hasPreciseScrollingDeltas)]) + hasMultiTouch = [event hasPreciseScrollingDeltas]; + + /* when pressing a key while momentum scrolling continues after + * lifting fingers off the trackpad, the action can unexpectedly + * change from e.g. scrolling to zooming. this works around the + * issue by ignoring momentum scroll after a key press */ + if (momentumPhase) + { + if (m_ignoreMomentumScroll) + break; + } + else + { + m_ignoreMomentumScroll = false; + } /* standard scrollwheel case, if no swiping happened, and no momentum (kinetic scroll) works */ - if (!m_hasMultiTouchTrackpad && momentum == NULL) { + if (!hasMultiTouch && momentumPhase == NSEventPhaseNone) { GHOST_TInt32 delta; double deltaF = [event deltaY]; @@ -1424,16 +1434,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) GHOST_TInt32 x, y; double dx; double dy; - + #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 - int phase = [event phase]; - /* with 10.7 nice scrolling deltas are supported */ dx = [event scrollingDeltaX]; dy = [event scrollingDeltaY]; /* however, wacom tablet (intuos5) needs old deltas, it then has momentum and phase at zero */ - if (phase == 0 && momentum==NULL) { + if (phase == NSEventPhaseNone && momentumPhase == NSEventPhaseNone) { dx = [event deltaX]; dy = [event deltaY]; } @@ -1568,6 +1576,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) pushEvent( new GHOST_EventKey([event timestamp] * 1000, GHOST_kEventKeyUp, window, keyCode, 0, NULL) ); //printf("Key up rawCode=0x%x charsIgnoringModifiers=%c keyCode=%u ascii=%i %c utf8=%s\n",[event keyCode],[charsIgnoringModifiers length]>0?[charsIgnoringModifiers characterAtIndex:0]:' ',keyCode,ascii,ascii, utf8_buf); } + m_ignoreMomentumScroll = true; break; case NSFlagsChanged: @@ -1587,6 +1596,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr) } m_modifierMask = modifiers; + m_ignoreMomentumScroll = true; break; default: diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 204d61de3df..38813e14a1b 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -393,16 +393,6 @@ enum { systemCocoa->handleMouseEvent(event); } -- (void)beginGestureWithEvent:(NSEvent *)event -{ - systemCocoa->handleMouseEvent(event); -} - -- (void)endGestureWithEvent:(NSEvent *)event -{ - systemCocoa->handleMouseEvent(event); -} - - (void)tabletPoint:(NSEvent *)event { systemCocoa->handleTabletEvent(event,[event type]); diff --git a/intern/glew-mx/glew-mx.h b/intern/glew-mx/glew-mx.h index 92450d67812..ed17ea4a0e6 100644 --- a/intern/glew-mx/glew-mx.h +++ b/intern/glew-mx/glew-mx.h @@ -95,8 +95,6 @@ MXContext *mxGetCurrentContext (void); void mxMakeCurrentContext(MXContext *ctx); void mxDestroyContext (MXContext *ctx); -void mxIgnoreNoVersion(int ignore); - GLenum glew_chk(GLenum error, const char *file, int line, const char *text); #ifndef NDEBUG diff --git a/intern/glew-mx/intern/glew-mx.c b/intern/glew-mx/intern/glew-mx.c index 78920670f68..6fbb1a7a2e2 100644 --- a/intern/glew-mx/intern/glew-mx.c +++ b/intern/glew-mx/intern/glew-mx.c @@ -34,8 +34,6 @@ #include <stdio.h> #include <stdlib.h> -static int ignore_version = 0; - #define CASE_CODE_RETURN_STR(code) case code: return #code; static const char *get_glew_error_enum_string(GLenum error) @@ -63,7 +61,7 @@ GLenum glew_chk(GLenum error, const char *file, int line, const char *text) const char *code = get_glew_error_enum_string(error); const char *msg = (const char *)glewGetErrorString(error); - if (error == GLEW_ERROR_NO_GL_VERSION && ignore_version) + if (error == GLEW_ERROR_NO_GL_VERSION) return GLEW_OK; #ifndef NDEBUG @@ -144,8 +142,3 @@ void mxDestroyContext(MXContext *ctx) (void)ctx; #endif } - -void mxIgnoreNoVersion(int ignore) -{ - ignore_version = ignore; -} diff --git a/intern/smoke/intern/MERSENNETWISTER.h b/intern/smoke/intern/MERSENNETWISTER.h index 5a9ccf88ae7..42b3fe19686 100644 --- a/intern/smoke/intern/MERSENNETWISTER.h +++ b/intern/smoke/intern/MERSENNETWISTER.h @@ -187,7 +187,7 @@ inline MTRand::uint32 MTRand::randInt() if( left == 0 ) reload(); --left; - register uint32 s1; + uint32 s1; s1 = *pNext++; s1 ^= (s1 >> 11); s1 ^= (s1 << 7) & 0x9d2c5680UL; @@ -232,9 +232,9 @@ inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength ) // in each element are discarded. // Just call seed() if you want to get array from /dev/urandom initialize(19650218UL); - register int i = 1; - register uint32 j = 0; - register int k = ( (uint32)N > seedLength ? (uint32)N : seedLength ); + int i = 1; + uint32 j = 0; + int k = ( (uint32)N > seedLength ? (uint32)N : seedLength ); for( ; k; --k ) { state[i] = @@ -273,9 +273,9 @@ inline void MTRand::seed() if( urandom ) { uint32 bigSeed[N]; - register uint32 *s = bigSeed; - register int i = N; - register bool success = true; + uint32 *s = bigSeed; + int i = N; + bool success = true; while( success && i-- ) success = fread( s++, sizeof(uint32), 1, urandom ); fclose(urandom); @@ -294,9 +294,9 @@ inline void MTRand::initialize( const uint32 seed ) // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. // In previous versions, most significant bits (MSBs) of the seed affect // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. - register uint32 *s = state; - register uint32 *r = state; - register int i = 1; + uint32 *s = state; + uint32 *r = state; + int i = 1; *s++ = seed & 0xffffffffUL; for( ; i < N; ++i ) { @@ -310,8 +310,8 @@ inline void MTRand::reload() { // Generate N new values in state // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) - register uint32 *p = state; - register int i; + uint32 *p = state; + int i; for( i = N - M; i--; ++p ) *p = twist( p[M], p[0], p[1] ); for( i = M; --i; ++p ) @@ -350,9 +350,9 @@ inline MTRand::uint32 MTRand::hash( time_t t, clock_t c ) inline void MTRand::save( uint32* saveArray ) const { - register uint32 *sa = saveArray; - register const uint32 *s = state; - register int i = N; + uint32 *sa = saveArray; + const uint32 *s = state; + int i = N; for( ; i--; *sa++ = *s++ ) {} *sa = left; } @@ -360,9 +360,9 @@ inline void MTRand::save( uint32* saveArray ) const inline void MTRand::load( uint32 *const loadArray ) { - register uint32 *s = state; - register uint32 *la = loadArray; - register int i = N; + uint32 *s = state; + uint32 *la = loadArray; + int i = N; for( ; i--; *s++ = *la++ ) {} left = *la; pNext = &state[N-left]; @@ -371,8 +371,8 @@ inline void MTRand::load( uint32 *const loadArray ) inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) { - register const MTRand::uint32 *s = mtrand.state; - register int i = mtrand.N; + const MTRand::uint32 *s = mtrand.state; + int i = mtrand.N; for( ; i--; os << *s++ << "\t" ) {} return os << mtrand.left; } @@ -380,8 +380,8 @@ inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand ) inline std::istream& operator>>( std::istream& is, MTRand& mtrand ) { - register MTRand::uint32 *s = mtrand.state; - register int i = mtrand.N; + MTRand::uint32 *s = mtrand.state; + int i = mtrand.N; for( ; i--; is >> *s++ ) {} is >> mtrand.left; mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left]; |