Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-03-10 03:36:09 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-03-10 08:27:19 +0300
commit78c2063685cb6e0d0bcb895cf4eb70686455d596 (patch)
tree70f7010f9a960f087b3e5b842874a919a4e0860d /intern/cycles/util
parent267d8923265a284c5d9a462e1d86305d613fcad8 (diff)
Cycles: support arbitrary number of motion blur steps for cameras.
Diffstat (limited to 'intern/cycles/util')
-rw-r--r--intern/cycles/util/util_transform.cpp22
-rw-r--r--intern/cycles/util/util_transform.h66
-rw-r--r--intern/cycles/util/util_vector.h12
3 files changed, 41 insertions, 59 deletions
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) {