LCOV - code coverage report
Current view: top level - source/simulation2/helpers - CinemaPath.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 21 125 16.8 %
Date: 2023-01-19 00:18:29 Functions: 4 25 16.0 %

          Line data    Source code
       1             : /* Copyright (C) 2017 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "precompiled.h"
      19             : 
      20             : #include "CinemaPath.h"
      21             : 
      22             : #include <sstream>
      23             : #include <string>
      24             : 
      25             : #include "graphics/Camera.h"
      26             : #include "maths/MathUtil.h"
      27             : #include "maths/Quaternion.h"
      28             : #include "maths/Vector3D.h"
      29             : #include "ps/CLogger.h"
      30             : #include "ps/CStr.h"
      31             : 
      32           2 : CCinemaPath::CCinemaPath(const CCinemaData& data, const TNSpline& spline, const TNSpline& targetSpline)
      33           2 :     : CCinemaData(data), TNSpline(spline), m_TargetSpline(targetSpline), m_TimeElapsed(0.f)
      34             : {
      35             :     // Calculate curves by nodes
      36           2 :     BuildSpline();
      37           2 :     m_TargetSpline.BuildSpline();
      38             : 
      39           2 :     if (m_Orientation == L"target")
      40             :     {
      41           2 :         m_LookAtTarget = true;
      42           2 :         ENSURE(!m_TargetSpline.GetAllNodes().empty());
      43             :     }
      44             : 
      45             :     // Set distortion mode and style
      46           2 :     if (data.m_Mode == L"ease_in")
      47           0 :         DistModePtr = &CCinemaPath::EaseIn;
      48           2 :     else if (data.m_Mode == L"ease_out")
      49           0 :         DistModePtr = &CCinemaPath::EaseOut;
      50           2 :     else if (data.m_Mode == L"ease_inout")
      51           2 :         DistModePtr = &CCinemaPath::EaseInOut;
      52           0 :     else if (data.m_Mode == L"ease_outin")
      53           0 :         DistModePtr = &CCinemaPath::EaseOutIn;
      54             :     else
      55             :     {
      56           0 :         LOGWARNING("Cinematic mode not found for '%s'", data.m_Mode.ToUTF8().c_str());
      57           0 :         DistModePtr = &CCinemaPath::EaseInOut;
      58             :     }
      59             : 
      60           2 :     if (data.m_Style == L"default")
      61           2 :         DistStylePtr = &CCinemaPath::EaseDefault;
      62           0 :     else if (data.m_Style == L"growth")
      63           0 :         DistStylePtr = &CCinemaPath::EaseGrowth;
      64           0 :     else if (data.m_Style == L"expo")
      65           0 :         DistStylePtr = &CCinemaPath::EaseExpo;
      66           0 :     else if (data.m_Style == L"circle")
      67           0 :         DistStylePtr = &CCinemaPath::EaseCircle;
      68           0 :     else if (data.m_Style == L"sine")
      69           0 :         DistStylePtr = &CCinemaPath::EaseSine;
      70             :     else
      71             :     {
      72           0 :         LOGWARNING("Cinematic style not found for '%s'", data.m_Style.ToUTF8().c_str());
      73           0 :         DistStylePtr = &CCinemaPath::EaseDefault;
      74             :     }
      75           2 : }
      76             : 
      77           0 : CVector3D CCinemaPath::GetNodePosition(const int index) const
      78             : {
      79           0 :     return Node[index].Position;
      80             : }
      81             : 
      82           0 : fixed CCinemaPath::GetNodeDuration(const int index) const
      83             : {
      84           0 :     return Node[index].Distance;
      85             : }
      86             : 
      87         101 : fixed CCinemaPath::GetDuration() const
      88             : {
      89         101 :     return MaxDistance;
      90             : }
      91             : 
      92           0 : float CCinemaPath::GetNodeFraction() const
      93             : {
      94           0 :     return (m_TimeElapsed - m_PreviousNodeTime) / Node[m_CurrentNode].Distance.ToFloat();
      95             : }
      96             : 
      97           0 : float CCinemaPath::GetElapsedTime() const
      98             : {
      99           0 :     return m_TimeElapsed;
     100             : }
     101             : 
     102           5 : const CStrW& CCinemaPath::GetName() const
     103             : {
     104           5 :     return m_Name;
     105             : }
     106             : 
     107           0 : void CCinemaPath::SetTimescale(fixed scale)
     108             : {
     109           0 :     m_Timescale = scale;
     110           0 : }
     111             : 
     112           0 : void CCinemaPath::MoveToPointAt(float t, float nodet, const CVector3D& startRotation, CCamera* camera) const
     113             : {
     114           0 :     t = (this->*DistModePtr)(t);
     115             : 
     116           0 :     CVector3D pos = GetPosition(t);
     117             : 
     118           0 :     if (m_LookAtTarget)
     119             :     {
     120           0 :         if (m_TimeElapsed <= m_TargetSpline.MaxDistance.ToFloat())
     121           0 :             camera->LookAt(pos, m_TargetSpline.GetPosition(m_TimeElapsed / m_TargetSpline.MaxDistance.ToFloat()), CVector3D(0, 1, 0));
     122             :         else
     123           0 :             camera->LookAt(pos, m_TargetSpline.GetAllNodes().back().Position, CVector3D(0, 1, 0));
     124             :     }
     125             :     else
     126             :     {
     127           0 :         CVector3D nodeRotation = Node[m_CurrentNode + 1].Rotation;
     128           0 :         CQuaternion start, end;
     129           0 :         start.FromEulerAngles(DEGTORAD(startRotation.X), DEGTORAD(startRotation.Y), DEGTORAD(startRotation.Z));
     130           0 :         end.FromEulerAngles(DEGTORAD(nodeRotation.X), DEGTORAD(nodeRotation.Y), DEGTORAD(nodeRotation.Z));
     131           0 :         start.Slerp(start, end, nodet);
     132             : 
     133           0 :         camera->m_Orientation.SetIdentity();
     134           0 :         camera->m_Orientation.Rotate(start);
     135           0 :         camera->m_Orientation.Translate(pos);
     136             :     }
     137           0 :     camera->UpdateFrustum();
     138           0 : }
     139             : 
     140             : // Distortion mode functions
     141           0 : float CCinemaPath::EaseIn(float t) const
     142             : {
     143           0 :     return (this->*DistStylePtr)(t);
     144             : }
     145             : 
     146           0 : float CCinemaPath::EaseOut(float t) const
     147             : {
     148           0 :     return 1.0f - EaseIn(1.0f-t);
     149             : }
     150             : 
     151           0 : float CCinemaPath::EaseInOut(float t) const
     152             : {
     153           0 :     if (t < m_Switch)
     154           0 :         return EaseIn(1.0f/m_Switch * t) * m_Switch;
     155           0 :     return EaseOut(1.0f/m_Switch * (t-m_Switch)) * m_Switch + m_Switch;
     156             : }
     157             : 
     158           0 : float CCinemaPath::EaseOutIn(float t) const
     159             : {
     160           0 :     if (t < m_Switch)
     161           0 :         return EaseOut(1.0f/m_Switch * t) * m_Switch;
     162           0 :     return EaseIn(1.0f/m_Switch * (t-m_Switch)) * m_Switch + m_Switch;
     163             : }
     164             : 
     165             : // Distortion style functions
     166           0 : float CCinemaPath::EaseDefault(float t) const
     167             : {
     168           0 :     return t;
     169             : }
     170             : 
     171           0 : float CCinemaPath::EaseGrowth(float t) const
     172             : {
     173           0 :     return pow(t, m_Growth);
     174             : }
     175             : 
     176           0 : float CCinemaPath::EaseExpo(float t) const
     177             : {
     178           0 :     if (t == 0)
     179           0 :         return t;
     180           0 :     return powf(m_Growth, 10*(t-1.0f));
     181             : }
     182             : 
     183           0 : float CCinemaPath::EaseCircle(float t) const
     184             : {
     185           0 :     t = -(sqrt(1.0f - t*t) - 1.0f);
     186           0 :     if (m_GrowthCount > 1.0f)
     187             :     {
     188           0 :         --m_GrowthCount;
     189           0 :         return (this->*DistStylePtr)(t);
     190             :     }
     191           0 :     return t;
     192             : }
     193             : 
     194           0 : float CCinemaPath::EaseSine(float t) const
     195             : {
     196           0 :     t = 1.0f - cos(t * (float)M_PI/2);
     197           0 :     if (m_GrowthCount > 1.0f)
     198             :     {
     199           0 :         --m_GrowthCount;
     200           0 :         return (this->*DistStylePtr)(t);
     201             :     }
     202           0 :     return t;
     203             : }
     204             : 
     205           0 : const CCinemaData* CCinemaPath::GetData() const
     206             : {
     207           0 :     return CCinemaData::GetData();
     208             : }
     209             : 
     210           0 : bool CCinemaPath::Validate()
     211             : {
     212           0 :     if (m_TimeElapsed > GetDuration().ToFloat() || m_TimeElapsed < 0.0f)
     213           0 :         return false;
     214             : 
     215             :     // Find current node and past "node time"
     216           0 :     float previousTime = 0.0f, cumulation = 0.0f;
     217             : 
     218             :     // Ignore the last node, since it is a blank (node time values are shifted down one from interface)
     219           0 :     for (size_t i = 0; i < Node.size() - 1; ++i)
     220             :     {
     221           0 :         cumulation += Node[i].Distance.ToFloat();
     222           0 :         if (m_TimeElapsed <= cumulation)
     223             :         {
     224           0 :             m_PreviousNodeTime = previousTime;
     225           0 :             m_PreviousRotation = Node[i].Rotation;
     226           0 :             m_CurrentNode = i; // We're moving toward this next node, so use its rotation
     227           0 :             return true;
     228             :         }
     229           0 :         previousTime += Node[i].Distance.ToFloat();
     230             :     }
     231           0 :     debug_warn("validation of cinema path is wrong\n");
     232           0 :     return false;
     233             : }
     234             : 
     235           0 : bool CCinemaPath::Play(const float deltaRealTime, CCamera* camera)
     236             : {
     237           0 :     m_TimeElapsed += m_Timescale.ToFloat() * deltaRealTime;
     238           0 :     if (!Validate())
     239           0 :         return false;
     240             : 
     241           0 :     MoveToPointAt(m_TimeElapsed / GetDuration().ToFloat(), GetNodeFraction(), m_PreviousRotation, camera);
     242           0 :     return true;
     243             : }
     244             : 
     245           0 : bool CCinemaPath::Empty() const
     246             : {
     247           0 :     return Node.empty();
     248             : }
     249             : 
     250           1 : void CCinemaPath::Reset()
     251             : {
     252           1 :     m_TimeElapsed = 0.0f;
     253           1 : }
     254             : 
     255           0 : fixed CCinemaPath::GetTimescale() const
     256             : {
     257           0 :     return m_Timescale;
     258             : }
     259             : 
     260           0 : const TNSpline& CCinemaPath::GetTargetSpline() const
     261             : {
     262           0 :     return m_TargetSpline;
     263             : }

Generated by: LCOV version 1.13