Selaa lähdekoodia

Added simple rotation smoothing for FollowingCameraComponent.

Signed-off-by: Michał Pełka <[email protected]>
Michał Pełka 2 vuotta sitten
vanhempi
commit
de278cd987

+ 21 - 3
Project/Gem/Source/KrakenCamera/FollowingCameraComponent.cpp

@@ -40,7 +40,7 @@ namespace AppleKraken
                     ->Attribute(AZ::Edit::Attributes::Category, "AppleKraken")
                     ->DataElement(AZ::Edit::UIHandlers::CheckBox, &FollowingCameraComponent::m_isActive, "Active", "")
                     ->DataElement(AZ::Edit::UIHandlers::EntityId, &FollowingCameraComponent::m_target, "Target", "Entity of the followed object")
-                    ->DataElement(AZ::Edit::UIHandlers::Default, &FollowingCameraComponent::m_target, "SmoothingLength", "Number of past transform used to smooth")
+                    ->DataElement(AZ::Edit::UIHandlers::Default, &FollowingCameraComponent::m_smoothingBuffer, "SmoothingLength", "Number of past transform used to smooth")
                     ->DataElement(AZ::Edit::UIHandlers::Default, &FollowingCameraComponent::m_zoomSpeed, "Zoom Speed", "Zoom speed")
                     ->DataElement(AZ::Edit::UIHandlers::Default, &FollowingCameraComponent::m_rotationSpeed, "Rotation Speed", "Rotation Speed");
             }
@@ -84,15 +84,18 @@ namespace AppleKraken
         EBUS_EVENT_ID_RESULT(target_world_transform, m_target, AZ::TransformBus, GetWorldTM);
 
         m_lastTransforms.push_back(AZStd::make_pair(target_world_transform.GetTranslation(), deltaTime));
+        m_lastRotations.push_back(AZStd::make_pair(target_world_transform.GetRotation(), deltaTime));
+
         if (m_lastTransforms.size() > m_smoothingBuffer){
             m_lastTransforms.pop_front();
+            m_lastRotations.pop_front();
         }
         AZ::Vector3 translation = SmoothTranslation();
-
+        AZ::Quaternion quat = SmoothRotation();
         AZ::Transform filtered_transform =
             {
                 translation,
-                AZ::Quaternion::CreateRotationZ(target_world_transform.GetEulerRadians().GetZ()),
+                AZ::Quaternion::CreateRotationZ(quat.GetEulerRadians().GetZ()),
                 target_world_transform.GetUniformScale()
             };
 
@@ -112,6 +115,7 @@ namespace AppleKraken
 
         EBUS_EVENT_ID(GetEntityId(), AZ::TransformBus, SetWorldTM, filtered_transform * modified_transform);
 
+
     }
 
     AZ::Vector3 FollowingCameraComponent::SmoothTranslation() const
@@ -125,6 +129,20 @@ namespace AppleKraken
         return sum/normalization;
     }
 
+    AZ::Quaternion FollowingCameraComponent::SmoothRotation() const
+    {
+        // Smoothing is done by taking an exponential map. Note that the exponential map is the same thing as 'ScaledAxisAngle'
+        // for 3D rotations. This map can be treated as linear space locally.
+        // In that linear space the average is computed. It should give a pleasant experience for slow-moving objects.
+        float normalization{0};
+        AZ::Vector3 sum{0};
+        for (const auto& p : m_lastRotations){
+            sum += p.second * (p.first.ConvertToScaledAxisAngle());
+            normalization+=p.second;
+        }
+        return AZ::Quaternion::CreateFromScaledAxisAngle(sum/normalization);
+    }
+
     bool FollowingCameraComponent::OnInputChannelEventFiltered(const AzFramework::InputChannel& inputChannel)
     {
         if (!m_isActive)

+ 3 - 3
Project/Gem/Source/KrakenCamera/FollowingCameraComponent.h

@@ -46,6 +46,8 @@ namespace AppleKraken
 
         AZ::Vector3 SmoothTranslation() const;
 
+        AZ::Quaternion SmoothRotation() const;
+
         bool m_isActive = true;
 
         AZ::Transform m_initialPose;
@@ -54,12 +56,9 @@ namespace AppleKraken
 
         float m_rotationChange = 0.0f;
         float m_rotationChange2 = 0.0f;
-
-
         float m_zoomChange = 0.0f;
 
         int m_smoothingBuffer = 30;
-
         float m_zoomSpeed = 0.06f;
         float m_rotationSpeed = 0.05f;
 
@@ -68,6 +67,7 @@ namespace AppleKraken
 
 
         AZStd::deque<AZStd::pair<AZ::Vector3,float>> m_lastTransforms;
+        AZStd::deque<AZStd::pair<AZ::Quaternion,float>> m_lastRotations;
 
     };
 }