/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. // Description : Helper classes with catchup for smoother synchronization, #ifndef CRYINCLUDE_CRYCOMMON_INTERPOLATIONHELPERS_H #define CRYINCLUDE_CRYCOMMON_INTERPOLATIONHELPERS_H #pragma once template struct InterpolateHelper { typedef const T& SetType; typedef const T& GetType; typedef float DeltaType; static DeltaType Delta(const T& a, const T& b) { return b - a; } static DeltaType Interpolate(T& a, const T& b, float dist, float change) { float t = change / dist; a = a + (b - a) * t; return change; } static T GetDefault() { return T(); } static DeltaType GetDefaultTeleport() { return DeltaType(); } static DeltaType GetDefaultSpeed() { return DeltaType(); } }; template > class InterpolatedValue_tpl { public: typedef typename H::SetType SetType; typedef typename H::GetType GetType; typedef typename H::DeltaType DeltaType; InterpolatedValue_tpl(SetType x = H::GetDefault(), DeltaType teleportd = H::GetDefaultTeleport(), DeltaType stepspeed = H::GetDefaultSpeed()) : m_teleportd(teleportd) , m_stepspeed(stepspeed) { Set(m_value = x); } void Set(SetType x) { m_interpolating = false; m_interpolated = x; } void SetGoal(SetType x) { m_interpolating = true; m_value = x; } GetType Get() const{return m_interpolated; } GetType GetGoal() const{return m_value; } bool IsInterpolating() const{return m_interpolating; } DeltaType Update(DeltaType delta) { if (!m_interpolating) { return DeltaType(0); } DeltaType dist = H::Delta(m_interpolated, m_value); DeltaType change = m_stepspeed * delta; if (dist < change || dist > m_teleportd) { Set(GetGoal()); return dist; } return H::Interpolate(m_interpolated, m_value, dist, change); } protected: T m_value; T m_interpolated; bool m_interpolating; DeltaType m_teleportd; DeltaType m_stepspeed; int m_policy; }; //QUAT - normalized quaternion interpolation struct InterpolatedQuatHelper { struct NormalizedQuat { NormalizedQuat(const Quat& q) { m_quat = q.GetNormalized(); } operator Quat(){ return m_quat; } operator const Quat&() const{ return m_quat; } Quat m_quat; }; typedef Quat T; typedef const NormalizedQuat& SetType; typedef const T& GetType; typedef float DeltaType; static DeltaType Delta(const T& a, const T& b) { float cosine = MIN(1.0f, a | b); return 2.0f * fabs_tpl(acos_tpl(cosine)); } static float Interpolate(T& a, const T& b, float dist, float change) { float t = MIN(1.0f, change / dist); a = Quat::CreateSlerp(a, b, t).GetNormalized(); return t * dist; } static T GetDefault() { return Quat::CreateIdentity(); } static DeltaType GetDefaultTeleport() { return gf_PI * 0.25f; } static DeltaType GetDefaultSpeed() { return 1.0f; } }; typedef InterpolatedValue_tpl InterpolatedQuat; //VEC3 struct InterpolatedVec3Helper : public InterpolateHelper { static float Delta(const Vec3& a, const Vec3& b) { return (b - a).len(); } static Vec3 GetDefault() { return Vec3(ZERO); } static float GetDefaultTeleport() { return 0.25f; } static float GetDefaultSpeed() { return 1.0f; } }; typedef InterpolatedValue_tpl InterpolatedVec3; //float struct InterpolatedFloatHelper : public InterpolateHelper { typedef float SetType; typedef float GetType; typedef float DeltaType; static DeltaType Delta(float a, float b) { return b - a; } static DeltaType Interpolate(float& a, float b, float dist, float change) { float t = MIN(1.0f, change / dist); a = a + (b - a) * t; return t * dist; } }; typedef InterpolatedValue_tpl InterpoltedFloat; #endif // CRYINCLUDE_CRYCOMMON_INTERPOLATIONHELPERS_H