diff --git a/.gitignore b/.gitignore index 9309668d..a38f0748 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ /active_project /test/assets/assets.db /test/products/ +_codeql_detected_source_root diff --git a/runtime/render/adaptor/src/assets/AnimationAsset.cpp b/runtime/render/adaptor/src/assets/AnimationAsset.cpp index d83dcb38..05230fca 100644 --- a/runtime/render/adaptor/src/assets/AnimationAsset.cpp +++ b/runtime/render/adaptor/src/assets/AnimationAsset.cpp @@ -36,7 +36,7 @@ namespace sky { archive.LoadValue(channelSize); channel.rotation.time.resize(channelSize / sizeof(float)); - archive.LoadValue(reinterpret_cast(channel.position.time.data()), channelSize); + archive.LoadValue(reinterpret_cast(channel.rotation.time.data()), channelSize); archive.LoadValue(channelSize); channel.rotation.keys.resize(channelSize / sizeof(Quaternion)); diff --git a/runtime/render/animation/include/animation/core/AnimationInterpolation.h b/runtime/render/animation/include/animation/core/AnimationInterpolation.h index c9308ad6..f1be773c 100644 --- a/runtime/render/animation/include/animation/core/AnimationInterpolation.h +++ b/runtime/render/animation/include/animation/core/AnimationInterpolation.h @@ -20,7 +20,7 @@ namespace sky { template T AnimInterpolateLinear(const T &vk, const T &vk1, float t) { - return (1 - t) * vk + t * vk1; + return vk * (1 - t) + vk1 * t; } Quaternion AnimSphericalLinear(const Quaternion &vk, const Quaternion &vk1, float t); @@ -38,22 +38,31 @@ namespace sky { } } - const T vk1 = {}; - const T vk2 = {}; - float t = 0.f; + if (k == 0) { + return data.keys[0]; + } + + if (k >= data.time.size()) { + return data.keys[data.keys.size() - 1]; + } + + const T &vk1 = data.keys[k - 1]; + const T &vk2 = data.keys[k]; + float t = (param.timePoint - data.time[k - 1]) / (data.time[k] - data.time[k - 1]); switch (param.interpolation) { case Interpolation::STEP: return vk1; - break; case Interpolation::CUBIC_SPLINE: // not supported yet. case Interpolation::LINEAR: if constexpr (std::is_same_v) { - return SphericalLinear(vk1, vk2, t); + return AnimSphericalLinear(vk1, vk2, t); } else { return AnimInterpolateLinear(vk1, vk2, t); } } + SKY_ASSERT(false); + return data.keys[0]; } } // namespace sky \ No newline at end of file diff --git a/runtime/render/animation/include/animation/core/AnimationNodeChannel.h b/runtime/render/animation/include/animation/core/AnimationNodeChannel.h index b295f6b9..2e2b7a1b 100644 --- a/runtime/render/animation/include/animation/core/AnimationNodeChannel.h +++ b/runtime/render/animation/include/animation/core/AnimationNodeChannel.h @@ -22,6 +22,12 @@ namespace sky { AnimChannelData rotation; }; + struct AnimNodeSampleResult : AnimSampleResult { + Vector3 position = {0.f, 0.f, 0.f}; + Vector3 scale = {1.f, 1.f, 1.f}; + Quaternion rotation = {}; + }; + class AnimationNodeChannel : public AnimationChannel { public: explicit AnimationNodeChannel(const Name &name) : AnimationChannel(name) {} diff --git a/runtime/render/animation/src/croe/AnimationInterpolation.cpp b/runtime/render/animation/src/croe/AnimationInterpolation.cpp index bf3ee3bd..0bdc801c 100644 --- a/runtime/render/animation/src/croe/AnimationInterpolation.cpp +++ b/runtime/render/animation/src/croe/AnimationInterpolation.cpp @@ -23,10 +23,10 @@ namespace sky { } return { - k1 * vk.x + k2 * vk1.x, k1 * vk.w + k2 * vk1.w, - k1 * vk.z + k2 * vk1.z, - k1 * vk.w + k2 * vk1.w + k1 * vk.x + k2 * vk1.x, + k1 * vk.y + k2 * vk1.y, + k1 * vk.z + k2 * vk1.z }; } diff --git a/runtime/render/animation/src/croe/AnimationNodeChannel.cpp b/runtime/render/animation/src/croe/AnimationNodeChannel.cpp index 324a22d5..c3ab92c4 100644 --- a/runtime/render/animation/src/croe/AnimationNodeChannel.cpp +++ b/runtime/render/animation/src/croe/AnimationNodeChannel.cpp @@ -16,6 +16,20 @@ namespace sky { void AnimationNodeChannel::Sample(const SampleParam ¶m, const AnimSampleResultPtr &ptr) { + auto *result = static_cast(ptr.Get()); + SKY_ASSERT(result != nullptr); + if (result == nullptr) { + return; + } + if (!position.time.empty()) { + result->position = AnimSampleChannel(position, param); + } + if (!scale.time.empty()) { + result->scale = AnimSampleChannel(scale, param); + } + if (!rotation.time.empty()) { + result->rotation = AnimSampleChannel(rotation, param); + } } } // namespace sky \ No newline at end of file