SHARE
TWEET

cppanimating.cpp (std::list)

a guest Jul 29th, 2016 72 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /************************************************************************
  2. *   Copyright (c) 2014-2016, rHetorical Studios. All rights reserved.   *
  3. *                                                                       *
  4. *       This product contains software technology licensed from         *
  5. *               Leadwerks Software. All Rights Reserved.                *
  6. ************************************************************************/
  7.  
  8. #include "../Core/base.h"
  9. #include "puppeteeranimating.h"
  10.  
  11. class Animation
  12. {
  13. public:
  14.     Animation() {};
  15.     virtual ~Animation() {};
  16.  
  17.     long blendstart;
  18.     long blendfinish;
  19.     float blendtime;
  20.     std::string sequence;
  21.     long length;
  22.     float speed;
  23.     bool mode;
  24.     long starttime;
  25.     bool endOfSequenceReached = false;
  26.     void endHook() {};
  27.     int endFrame;
  28. };
  29.  
  30. list<Animation*> animations;
  31.  
  32. AnimationManager::AnimationManager(Entity* pEntity)
  33. {
  34.     if (pEntity == NULL)
  35.     {
  36.         Debug::Error("AnimationManager: Entity cannot be nil.");
  37.     }
  38.  
  39.     entity = pEntity;
  40.     frameoffset = Math::Random(0, 1000);
  41.  
  42. }
  43.  
  44. AnimationManager::~AnimationManager()
  45. {
  46.     for (auto it = animations.begin(); it != animations.end();)
  47.     {
  48.         SAFE_DELETE(*it);
  49.         it = animations.erase(it);
  50.     }
  51.  
  52.     ClearAnimations();
  53. }
  54.  
  55. void AnimationManager::SetAnimationSequence(std::string pSequence, const float pSpeed, const float pBlendTime, const bool pMode, void EndHook(), int pEndFrame)
  56. {
  57.     // Check for redundant animation descriptor
  58.     if (pMode == false)
  59.     {
  60.         if (animations.size() > 0)
  61.         {
  62.             if (animations.back()->sequence == pSequence)
  63.             {
  64.                 if (animations.back()->speed == pSpeed)
  65.                 {
  66.                     // No change to blend time, so don't alter this?
  67.                     animations.back()->blendtime = pBlendTime;
  68.                     return;
  69.                 }
  70.             }
  71.         }
  72.     }
  73.  
  74.     // Create new animation descriptor and add to animation stack
  75.     Animation* animation = new Animation();
  76.     animation->blendstart = Time::GetCurrent();
  77.     animation->blendfinish = animation->blendstart + pBlendTime;
  78.     animation->sequence = pSequence;
  79.     animation->length = entity->GetAnimationLength(animation->sequence, true);
  80.     animation->speed = pSpeed;
  81.     animation->mode = pMode;
  82.     animation->starttime = animation->blendstart;
  83.     //animation->endHook = EndHook();
  84.     animation->endOfSequenceReached = false;
  85.     animation->endFrame = pEndFrame;
  86.  
  87.     animations.push_back(animation);
  88. }
  89.  
  90. void AnimationManager::ClearAnimations()
  91. {
  92.     animations.clear();
  93. }
  94.  
  95. void AnimationManager::Update()
  96. {
  97.     long blend;
  98.     long frame;
  99.     bool doanimation = false;
  100.     long currenttime = Time::GetCurrent();
  101.     int maxanim = -1;
  102.  
  103.     int i = -1;
  104.     for (const auto& animation : animations)
  105.     {
  106.         ++i;
  107.  
  108.         // Lock the matrix before the first sequence is applied
  109.         if (doanimation == false)
  110.         {
  111.             doanimation = true;
  112.             entity->LockMatrix();
  113.         }
  114.  
  115.         // Calculate blend value
  116.         blend = (currenttime - animation->blendstart) / (animation->blendfinish - animation->blendstart);
  117.         blend = Math::Min(1.0, blend);
  118.  
  119.         if (animation->mode == false)
  120.         {
  121.             frame = currenttime * animation->speed + frameoffset;
  122.         }
  123.         else
  124.         {
  125.             frame = (currenttime - animation->blendstart) * animation->speed;
  126.  
  127.             // If a certain frame was specified, call the hook early and remove it
  128.             if (animation->endFrame != NULL)
  129.             {
  130.                 if (frame > animation->endFrame)
  131.                 {
  132.                     //animation->endHook();
  133.                     animation->endFrame = NULL;
  134.                     //animation->endHook = NULL;
  135.  
  136.                 }
  137.             }
  138.  
  139.             if (frame >= (animation->length - 1))
  140.             {
  141.                 frame = animation->length - 1;
  142.                 maxanim = i + 1;
  143.                 if (animation->endOfSequenceReached == false)
  144.                 {
  145.                     DevMsg("AnimationManager: endOfSequenceReached.");
  146.                     animation->endOfSequenceReached = true;
  147.                 }
  148.             }
  149.         } // if (animation->mode)
  150.  
  151.           // Apply the animation
  152.         if (animation->sequence != S_NULL)
  153.         {
  154.             entity->SetAnimationFrame(frame, blend, animation->sequence, true);
  155.         }
  156.  
  157.         // If this animation is blended in 100%, all previous looping animation sequences can be dropped
  158.         if (blend >= 1.0)
  159.         {
  160.             maxanim = Math::Max(maxanim, i);
  161.         }
  162.     } // forloop
  163.  
  164.       // Unlock entity matrix if any animations were applied
  165.     if (doanimation == true)
  166.     {
  167.         entity->UnlockMatrix();
  168.     }
  169.  
  170.     // Clear blended out animation - moved this out of the loop to prevent jittering
  171.     if (maxanim > -1)
  172.     {
  173.         int n = -1;
  174.         for (auto it = animations.begin(); it != animations.end();) {
  175.             ++n;
  176.             if (n < maxanim)
  177.             {
  178.                 Animation* completedanimation = *it;
  179.                 if (completedanimation->mode == false || completedanimation->endOfSequenceReached == true)
  180.                 {
  181.                     DevMsg("AnimationManager: Removing completedanimation.");
  182.                     it = animations.erase(it);
  183.                 }
  184.                 else { ++it; }
  185.             }
  186.             else
  187.             {
  188.                 //DevMsg("AnimationManager:Break.");
  189.                 break;
  190.             }
  191.         }
  192.     }
  193. }
  194.  
  195. // The test entity:
  196. PuppeteerAnimating::PuppeteerAnimating(Entity* pEntity) : Puppeteer(pEntity)
  197. {
  198.     Start();
  199. }
  200.  
  201. PuppeteerAnimating::~PuppeteerAnimating()
  202. {
  203.     SAFE_DELETE(animationmanager);
  204. }
  205.  
  206. void PuppeteerAnimating::Start()
  207. {
  208.     animationmanager = new AnimationManager(entity);
  209. }
  210.  
  211. void PuppeteerAnimating::Use(Entity* pCaller)
  212. {
  213.     DevMsg("use");
  214.     //animationmanager->SetAnimationSequence("Run", 0.04);
  215.     animationmanager->SetAnimationSequence("Death", 0.04, 300, true);
  216. }
  217.  
  218.  
  219. void PuppeteerAnimating::Draw(Camera* camera)
  220. {
  221.     animationmanager->Update();
  222. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top