From 78c2063685cb6e0d0bcb895cf4eb70686455d596 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 10 Mar 2018 01:36:09 +0100 Subject: Cycles: support arbitrary number of motion blur steps for cameras. --- intern/cycles/util/util_transform.cpp | 22 ++++++------ intern/cycles/util/util_transform.h | 66 ++++++++++------------------------- intern/cycles/util/util_vector.h | 12 +++++++ 3 files changed, 41 insertions(+), 59 deletions(-) (limited to 'intern/cycles/util') diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp index e4e0d627497..206c3da23eb 100644 --- a/intern/cycles/util/util_transform.cpp +++ b/intern/cycles/util/util_transform.cpp @@ -261,18 +261,18 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z); } -void transform_motion_decompose(DecomposedMotionTransform *decomp, const MotionTransform *motion, const Transform *mid) +void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size) { - transform_decompose(&decomp->pre, &motion->pre); - transform_decompose(&decomp->mid, mid); - transform_decompose(&decomp->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->pre.x, decomp->mid.x) < 0.0f) - decomp->pre.x = -decomp->pre.x; - if(dot(decomp->mid.x, decomp->post.x) < 0.0f) - decomp->mid.x = -decomp->mid.x; + for(size_t i = 0; i < size; i++) { + transform_decompose(decomp + i, motion + i); + + if(i > 0) { + /* 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[i-1].x, decomp[i].x) < 0.0f) + decomp[i-1].x = -decomp[i-1].x; + } + } } Transform transform_from_viewplane(BoundBox2D& viewplane) diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h index 12f8405f233..ade74364876 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -409,58 +409,28 @@ ccl_device_inline void transform_compose(Transform *tfm, const DecomposedTransfo tfm->z = make_float4(dot(rotation_z, scale_x), dot(rotation_z, scale_y), dot(rotation_z, scale_z), decomp->y.z); } -ccl_device void transform_motion_interpolate(Transform *tfm, const ccl_global DecomposedMotionTransform *motion, float t) +/* Interpolate from array of decomposed transforms. */ +ccl_device void transform_motion_array_interpolate(Transform *tfm, + const ccl_global DecomposedTransform *motion, + uint numsteps, + float time) { - DecomposedTransform decomp; - - /* linear interpolation for rotation and scale */ - if(t < 0.5f) { - t *= 2.0f; - - decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t); - decomp.y = (1.0f - t)*motion->pre.y + t*motion->mid.y; - 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; + /* Figure out which steps we need to interpolate. */ + int maxstep = numsteps-1; + int step = min((int)(time*maxstep), maxstep-1); + float t = time*maxstep - step; - decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t); - decomp.y = (1.0f - t)*motion->mid.y + t*motion->post.y; - decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z; - decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w; - } - - /* compose rotation, translation, scale into matrix */ - transform_compose(tfm, &decomp); -} + const ccl_global DecomposedTransform *a = motion + step; + const ccl_global DecomposedTransform *b = motion + step + 1; -ccl_device void transform_motion_interpolate_constant(Transform *tfm, ccl_constant DecomposedMotionTransform *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 - * just shearing perhaps? */ + /* Interpolate rotation, translation and scale. */ DecomposedTransform decomp; + decomp.x = quat_interpolate(a->x, b->x, t); + decomp.y = (1.0f - t)*a->y + t*b->y; + decomp.z = (1.0f - t)*a->z + t*b->z; + decomp.w = (1.0f - t)*a->w + t*b->w; - /* linear interpolation for rotation and scale */ - if(t < 0.5f) { - t *= 2.0f; - - decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t); - decomp.y = (1.0f - t)*motion->pre.y + t*motion->mid.y; - 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.y = (1.0f - t)*motion->mid.y + t*motion->post.y; - decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z; - decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w; - } - - /* compose rotation, translation, scale into matrix */ + /* Compose rotation, translation, scale into matrix. */ transform_compose(tfm, &decomp); } @@ -479,7 +449,7 @@ ccl_device_inline bool operator==(const MotionTransform& A, const MotionTransfor } float4 transform_to_quat(const Transform& tfm); -void transform_motion_decompose(DecomposedMotionTransform *decomp, const MotionTransform *motion, const Transform *mid); +void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size); Transform transform_from_viewplane(BoundBox2D& viewplane); #endif diff --git a/intern/cycles/util/util_vector.h b/intern/cycles/util/util_vector.h index 625c19c7c46..e98e4e34181 100644 --- a/intern/cycles/util/util_vector.h +++ b/intern/cycles/util/util_vector.h @@ -215,6 +215,18 @@ public: return data_; } + T* resize(size_t newsize, const T& value) + { + size_t oldsize = size(); + resize(newsize); + + for(size_t i = oldsize; i < size(); i++) { + data_[i] = value; + } + + return data_; + } + void clear() { if(data_ != NULL) { -- cgit v1.2.3