diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index abc63d99c74..97d37a8b3f4 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -65,7 +65,7 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float #ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) - transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); + transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time); #endif ray->P = transform_point(&cameratoworld, ray->P); @@ -108,7 +108,7 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa #ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) - transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); + transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time); #endif ray->P = transform_point(&cameratoworld, ray->P); @@ -182,7 +182,7 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra #ifdef __CAMERA_MOTION__ if(kernel_data.cam.have_motion) - transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time); + transform_motion_interpolate(&cameratoworld, (const DecompMotionTransform*)&kernel_data.cam.motion, ray->time); #endif ray->P = transform_point(&cameratoworld, ray->P); diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h index 112bfbb86b5..2b38544e527 100644 --- a/intern/cycles/kernel/kernel_object.h +++ b/intern/cycles/kernel/kernel_object.h @@ -23,9 +23,8 @@ enum ObjectTransform { OBJECT_INVERSE_TRANSFORM = 3, OBJECT_PROPERTIES = 6, OBJECT_TRANSFORM_MOTION_PRE = 8, - OBJECT_TRANSFORM_MOTION_MID = 12, - OBJECT_TRANSFORM_MOTION_POST = 16, - OBJECT_DUPLI = 20 + OBJECT_TRANSFORM_MOTION_POST = 12, + OBJECT_DUPLI = 16 }; __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type) @@ -44,24 +43,19 @@ __device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, #ifdef __OBJECT_MOTION__ __device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time) { - MotionTransform motion; + DecompMotionTransform motion; int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE; - motion.pre.x = kernel_tex_fetch(__objects, offset + 0); - motion.pre.y = kernel_tex_fetch(__objects, offset + 1); - motion.pre.z = kernel_tex_fetch(__objects, offset + 2); - motion.pre.w = kernel_tex_fetch(__objects, offset + 3); + motion.mid.x = kernel_tex_fetch(__objects, offset + 0); + motion.mid.y = kernel_tex_fetch(__objects, offset + 1); + motion.mid.z = kernel_tex_fetch(__objects, offset + 2); + motion.mid.w = kernel_tex_fetch(__objects, offset + 3); - motion.mid.x = kernel_tex_fetch(__objects, offset + 4); - motion.mid.y = kernel_tex_fetch(__objects, offset + 5); - motion.mid.z = kernel_tex_fetch(__objects, offset + 6); - motion.mid.w = kernel_tex_fetch(__objects, offset + 7); - - motion.post.x = kernel_tex_fetch(__objects, offset + 8); - motion.post.y = kernel_tex_fetch(__objects, offset + 9); - motion.post.z = kernel_tex_fetch(__objects, offset + 10); - motion.post.w = kernel_tex_fetch(__objects, offset + 11); + motion.pre_x = kernel_tex_fetch(__objects, offset + 4); + motion.pre_y = kernel_tex_fetch(__objects, offset + 5); + motion.post_x = kernel_tex_fetch(__objects, offset + 6); + motion.post_y = kernel_tex_fetch(__objects, offset + 7); Transform tfm; transform_motion_interpolate(&tfm, &motion, time); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 977fb8c4fd4..a7bf6b28e7e 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -29,7 +29,7 @@ CCL_NAMESPACE_BEGIN /* constants */ -#define OBJECT_SIZE 22 +#define OBJECT_SIZE 18 #define LIGHT_SIZE 4 #define FILTER_TABLE_SIZE 256 #define RAMP_TABLE_SIZE 256 @@ -112,13 +112,9 @@ CCL_NAMESPACE_BEGIN #define __AO__ #define __CAMERA_MOTION__ #define __ANISOTROPIC__ - -#ifndef __KERNEL_CUDA__ #define __OBJECT_MOTION__ #endif -#endif - //#define __SOBOL_FULL_SCREEN__ /* Shader Evaluation */ diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp index 32c273c1248..a78ede979b2 100644 --- a/intern/cycles/render/camera.cpp +++ b/intern/cycles/render/camera.cpp @@ -202,7 +202,7 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene) #ifdef __CAMERA_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { if(use_motion) { - transform_motion_decompose(&kcam->motion, &motion, &matrix); + transform_motion_decompose((DecompMotionTransform*)&kcam->motion, &motion, &matrix); kcam->have_motion = 1; } } diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 25b4d1f08cc..d08cb07fc3c 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -56,7 +56,7 @@ void Object::compute_bounds(bool motion_blur, float shuttertime) BoundBox mbounds = mesh->bounds; if(motion_blur && use_motion) { - MotionTransform decomp; + DecompMotionTransform decomp; transform_motion_decompose(&decomp, &motion, &tfm); bounds = BoundBox::empty; @@ -222,29 +222,29 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene mtfm_post = mtfm_post * itfm; memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4); - memcpy(&objects[offset+16], &mtfm_post, sizeof(float4)*4); + memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4); } #ifdef __OBJECT_MOTION__ else if(need_motion == Scene::MOTION_BLUR) { if(ob->use_motion) { /* decompose transformations for interpolation */ - MotionTransform decomp; + DecompMotionTransform decomp; transform_motion_decompose(&decomp, &ob->motion, &ob->tfm); - memcpy(&objects[offset+8], &decomp, sizeof(float4)*12); + memcpy(&objects[offset+8], &decomp, sizeof(float4)*8); flag |= SD_OBJECT_MOTION; have_motion = true; } else { float4 no_motion = make_float4(FLT_MAX); - memcpy(&objects[offset+8], &no_motion, sizeof(float4)*12); + memcpy(&objects[offset+8], &no_motion, sizeof(float4)*8); } } #endif /* dupli object coords */ - objects[offset+20] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); - objects[offset+21] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f); + objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f); + objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f); /* object flag */ if(ob->use_holdout) diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp index 4eee024990f..ca19146e125 100644 --- a/intern/cycles/util/util_transform.cpp +++ b/intern/cycles/util/util_transform.cpp @@ -246,18 +246,30 @@ static void transform_decompose(Transform *decomp, const Transform *tfm) decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z); } -void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid) +void transform_motion_decompose(DecompMotionTransform *decomp, const MotionTransform *motion, const Transform *mid) { - transform_decompose(&decomp->pre, &motion->pre); + Transform pre, post; + + transform_decompose(&pre, &motion->pre); transform_decompose(&decomp->mid, mid); - transform_decompose(&decomp->post, &motion->post); + transform_decompose(&post, &motion->post); /* ensure rotation around shortest angle, negated quaternions are the same * but this means we don't have to do the check in quat_interpolate */ - if(dot(decomp->mid.x, decomp->post.x) < 0.0f) + if(dot(decomp->mid.x, post.x) < 0.0f) decomp->mid.x = -decomp->mid.x; - if(dot(decomp->pre.x, decomp->mid.x) < 0.0f) - decomp->pre.x = -decomp->pre.x; + if(dot(pre.x, decomp->mid.x) < 0.0f) + pre.x = -pre.x; + + /* drop scale of pre/post */ + pre.y.w = decomp->mid.y.w; + post.y.w = decomp->mid.y.w; + + /* store translation/rotation part of pre/post */ + decomp->pre_x = pre.x; + decomp->pre_y = pre.y; + decomp->post_x = post.x; + decomp->post_y = post.y; } CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index 65162ebf4e6..dbf88cb67a0 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -41,7 +41,9 @@ typedef struct Transform { /* transform decomposed in rotation/translation/scale. we use the same data * structure as Transform, and tightly pack decomposition into it. first the - * rotation (4), then translation (3), then 3x3 scale matrix (9) */ + * rotation (4), then translation (3), then 3x3 scale matrix (9). + * + * For the DecompMotionTransform we drop scale from pre/post. */ typedef struct MotionTransform { Transform pre; @@ -49,6 +51,12 @@ typedef struct MotionTransform { Transform post; } MotionTransform; +typedef struct DecompMotionTransform { + Transform mid; + float4 pre_x, pre_y; + float4 post_x, post_y; +} DecompMotionTransform; + /* Functions */ __device_inline float3 transform_perspective(const Transform *t, const float3 a) @@ -384,7 +392,7 @@ __device_inline void transform_compose(Transform *tfm, const Transform *decomp) /* Disabled for now, need arc-length parametrization for constant speed motion. * #define CURVED_MOTION_INTERPOLATE */ -__device void transform_motion_interpolate(Transform *tfm, const MotionTransform *motion, float t) +__device void transform_motion_interpolate(Transform *tfm, const DecompMotionTransform *motion, float t) { /* possible optimization: is it worth it adding a check to skip scaling? * it's probably quite uncommon to have scaling objects. or can we skip @@ -393,9 +401,9 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform #ifdef CURVED_MOTION_INTERPOLATE /* 3 point bezier curve interpolation for position */ - float3 Ppre = float4_to_float3(motion->pre.y); + float3 Ppre = float4_to_float3(motion->pre_y); float3 Pmid = float4_to_float3(motion->mid.y); - float3 Ppost = float4_to_float3(motion->post.y); + float3 Ppost = float4_to_float3(motion->post_y); float3 Pcontrol = 2.0f*Pmid - 0.5f*(Ppre + Ppost); float3 P = Ppre*t*t + Pcontrol*2.0f*t*(1.0f - t) + Ppost*(1.0f - t)*(1.0f - t); @@ -409,28 +417,27 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform if(t < 0.5f) { t *= 2.0f; - decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t); + decomp.x = quat_interpolate(motion->pre_x, motion->mid.x, t); #ifdef CURVED_MOTION_INTERPOLATE - decomp.y.w = (1.0f - t)*motion->pre.y.w + t*motion->mid.y.w; + decomp.y.w = (1.0f - t)*motion->pre_y.w + t*motion->mid.y.w; #else - decomp.y = (1.0f - t)*motion->pre.y + t*motion->mid.y; + decomp.y = (1.0f - t)*motion->pre_y + t*motion->mid.y; #endif - decomp.z = (1.0f - t)*motion->pre.z + t*motion->mid.z; - decomp.w = (1.0f - t)*motion->pre.w + t*motion->mid.w; } else { t = (t - 0.5f)*2.0f; - decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t); + decomp.x = quat_interpolate(motion->mid.x, motion->post_x, t); #ifdef CURVED_MOTION_INTERPOLATE - decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post.y.w; + decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post_y.w; #else - decomp.y = (1.0f - t)*motion->mid.y + t*motion->post.y; + decomp.y = (1.0f - t)*motion->mid.y + t*motion->post_y; #endif - decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z; - decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w; } + decomp.z = motion->mid.z; + decomp.w = motion->mid.w; + /* compose rotation, translation, scale into matrix */ transform_compose(tfm, &decomp); } @@ -442,7 +449,7 @@ __device_inline bool operator==(const MotionTransform& A, const MotionTransform& return (A.pre == B.pre && A.post == B.post); } -void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid); +void transform_motion_decompose(DecompMotionTransform *decomp, const MotionTransform *motion, const Transform *mid); #endif