diff options
author | Sergey Sharybin <sergey@blender.org> | 2020-08-04 13:08:09 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey@blender.org> | 2020-08-04 13:08:09 +0300 |
commit | 778f0aca5263f9fd37ef1f7a1162af0328630cf8 (patch) | |
tree | 7a8ac9bc98b1c3986db73ebb7e8e7e4560536d02 /intern | |
parent | 03c2439d96e8f366646bf20095514c057593aa24 (diff) | |
parent | 8d3b8bc83589eccee10fcc0da4233b3adcf0cdde (diff) |
Merge branch 'blender-v2.90-release'
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | intern/cycles/test/util_transform_test.cpp | 53 | ||||
-rw-r--r-- | intern/cycles/util/util_math_float4.h | 18 | ||||
-rw-r--r-- | intern/cycles/util/util_transform.cpp | 28 | ||||
-rw-r--r-- | intern/cycles/util/util_transform.h | 11 |
5 files changed, 108 insertions, 3 deletions
diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt index 6dcc7f7b3dd..07b345baff8 100644 --- a/intern/cycles/test/CMakeLists.txt +++ b/intern/cycles/test/CMakeLists.txt @@ -112,3 +112,4 @@ set_source_files_properties(util_avxf_avx_test.cpp PROPERTIES COMPILE_FLAGS "${C CYCLES_TEST(util_avxf_avx "cycles_util;bf_intern_numaapi;${OPENIMAGEIO_LIBRARIES};${BOOST_LIBRARIES}") set_source_files_properties(util_avxf_avx2_test.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_AVX2_KERNEL_FLAGS}") CYCLES_TEST(util_avxf_avx2 "cycles_util;bf_intern_numaapi;${OPENIMAGEIO_LIBRARIES};${BOOST_LIBRARIES}") +CYCLES_TEST(util_transform "cycles_util;${OPENIMAGEIO_LIBRARIES};${BOOST_LIBRARIES}") diff --git a/intern/cycles/test/util_transform_test.cpp b/intern/cycles/test/util_transform_test.cpp new file mode 100644 index 00000000000..58ce0fdfee4 --- /dev/null +++ b/intern/cycles/test/util_transform_test.cpp @@ -0,0 +1,53 @@ +/* + * Copyright 2011-2020 Blender Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "testing/testing.h" + +#include "util/util_transform.h" +#include "util/util_vector.h" + +CCL_NAMESPACE_BEGIN + +TEST(transform_motion_decompose, Degenerated) +{ + // Simple case: single degenerated matrix. + { + vector<Transform> motion = {transform_scale(0.0f, 0.0f, 0.0f)}; + vector<DecomposedTransform> decomp(motion.size()); + transform_motion_decompose(decomp.data(), motion.data(), motion.size()); + EXPECT_TRUE(transform_decomposed_isfinite_safe(&decomp[0])); + } + + // Copy from previous to current. + { + vector<Transform> motion = {transform_rotate(M_PI_4_F, make_float3(1.0f, 1.0f, 1.0f)), + transform_scale(0.0f, 0.0f, 0.0f)}; + vector<DecomposedTransform> decomp(motion.size()); + transform_motion_decompose(decomp.data(), motion.data(), motion.size()); + EXPECT_NEAR(len(decomp[1].x - decomp[0].x), 0.0f, 1e-6f); + } + + // Copy from next to current. + { + vector<Transform> motion = {transform_scale(0.0f, 0.0f, 0.0f), + transform_rotate(M_PI_4_F, make_float3(1.0f, 1.0f, 1.0f))}; + vector<DecomposedTransform> decomp(motion.size()); + transform_motion_decompose(decomp.data(), motion.data(), motion.size()); + EXPECT_NEAR(len(decomp[0].x - decomp[1].x), 0.0f, 1e-6f); + } +} + +CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_math_float4.h b/intern/cycles/util/util_math_float4.h index cd4b3e3b74c..ec5328adb31 100644 --- a/intern/cycles/util/util_math_float4.h +++ b/intern/cycles/util/util_math_float4.h @@ -477,6 +477,24 @@ ccl_device_inline float4 safe_divide_float4_float(const float4 a, const float b) return (b != 0.0f) ? a / b : make_float4(0.0f, 0.0f, 0.0f, 0.0f); } +ccl_device_inline bool isfinite4_safe(float4 v) +{ + return isfinite_safe(v.x) && isfinite_safe(v.y) && isfinite_safe(v.z) && isfinite_safe(v.w); +} + +ccl_device_inline float4 ensure_finite4(float4 v) +{ + if (!isfinite_safe(v.x)) + v.x = 0.0f; + if (!isfinite_safe(v.y)) + v.y = 0.0f; + if (!isfinite_safe(v.z)) + v.z = 0.0f; + if (!isfinite_safe(v.w)) + v.w = 0.0f; + return v; +} + CCL_NAMESPACE_END #endif /* __UTIL_MATH_FLOAT4_H__ */ diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp index 101122740d7..6417752f704 100644 --- a/intern/cycles/util/util_transform.cpp +++ b/intern/cycles/util/util_transform.cpp @@ -269,17 +269,17 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf /* extract scale and shear first */ float3 scale, shear; scale.x = len(colx); - colx /= scale.x; + colx = safe_divide_float3_float(colx, scale.x); shear.z = dot(colx, coly); coly -= shear.z * colx; scale.y = len(coly); - coly /= scale.y; + coly = safe_divide_float3_float(coly, scale.y); shear.y = dot(colx, colz); colz -= shear.y * colx; shear.x = dot(coly, colz); colz -= shear.x * coly; scale.z = len(colz); - colz /= scale.z; + colz = safe_divide_float3_float(colz, scale.z); transform_set_column(&M, 0, colx); transform_set_column(&M, 1, coly); @@ -300,6 +300,7 @@ static void transform_decompose(DecomposedTransform *decomp, const Transform *tf void transform_motion_decompose(DecomposedTransform *decomp, const Transform *motion, size_t size) { + /* Decompose and correct rotation. */ for (size_t i = 0; i < size; i++) { transform_decompose(decomp + i, motion + i); @@ -310,6 +311,27 @@ void transform_motion_decompose(DecomposedTransform *decomp, const Transform *mo decomp[i].x = -decomp[i].x; } } + + /* Copy rotation to decomposed transform where scale is degenerate. This avoids weird object + * rotation interpolation when the scale goes to 0 for a time step. + * + * Note that this is very simple and naive implementation, which only deals with degenerated + * scale happening only on one frame. It is possible to improve it further by interpolating + * rotation into s degenerated range using rotation from timesteps from adjacent non-degenerated + * time steps. */ + for (size_t i = 0; i < size; i++) { + const float3 scale = make_float3(decomp[i].y.w, decomp[i].z.w, decomp[i].w.w); + if (!is_zero(scale)) { + continue; + } + + if (i > 0) { + decomp[i].x = decomp[i - 1].x; + } + else if (i < size - 1) { + decomp[i].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 d0a6264d5cf..d8bbd389aa6 100644 --- a/intern/cycles/util/util_transform.h +++ b/intern/cycles/util/util_transform.h @@ -466,6 +466,17 @@ ccl_device void transform_motion_array_interpolate(Transform *tfm, transform_compose(tfm, &decomp); } +ccl_device_inline bool transform_isfinite_safe(Transform *tfm) +{ + return isfinite4_safe(tfm->x) && isfinite4_safe(tfm->y) && isfinite4_safe(tfm->z); +} + +ccl_device_inline bool transform_decomposed_isfinite_safe(DecomposedTransform *decomp) +{ + return isfinite4_safe(decomp->x) && isfinite4_safe(decomp->y) && isfinite4_safe(decomp->z) && + isfinite4_safe(decomp->w); +} + #ifndef __KERNEL_GPU__ class BoundBox2D; |