Advertisement
Guest User

cppanimating.cpp

a guest
Jul 30th, 2016
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.44 KB | None | 0 0
  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. vector<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.     vector<Animation*>::iterator it;
  47.     for (it = animations.begin(); it != animations.end(); ++it)
  48.     {
  49.         SAFE_DELETE(*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[animations.size()]->sequence == pSequence)
  63.             {
  64.                 if (animations[animations.size()]->speed == pSpeed)
  65.                 {
  66.                     // No change to blend time, so don't alter this?
  67.                     animations[animations.size()]->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.     for (int i = 0; i < animations.size(); ++i)
  103.     {
  104.         Animation* animation = animations[i];
  105.  
  106.         // Lock the matrix before the first sequence is applied
  107.         if (doanimation == false)
  108.         {
  109.             doanimation = true;
  110.             entity->LockMatrix();
  111.         }
  112.  
  113.         // Calculate blend value
  114.         blend = (currenttime - animation->blendstart) / (animation->blendfinish - animation->blendstart);
  115.         blend = Math::Min(1.0, blend);
  116.  
  117.         if (animation->mode == false)
  118.         {
  119.             frame = currenttime * animation->speed + frameoffset;
  120.         }
  121.         else
  122.         {
  123.             frame = (currenttime - animation->blendstart) * animation->speed;
  124.  
  125.             // If a certain frame was specified, call the hook early and remove it
  126.             if (animation->endFrame != NULL)
  127.             {
  128.                 if (frame > animation->endFrame)
  129.                 {
  130.                     //animation->endHook();
  131.                     animation->endFrame = NULL;
  132.                     //animation->endHook = NULL;
  133.  
  134.                 }
  135.             }
  136.  
  137.             if (frame >= (animation->length - 1))
  138.             {
  139.                 frame = animation->length - 1;
  140.                 maxanim = i + 1;
  141.                 if (animation->endOfSequenceReached == false)
  142.                 {
  143.                     DevMsg("AnimationManager: endOfSequenceReached.");
  144.                     animation->endOfSequenceReached = true;
  145.                 }
  146.             }
  147.         } // if (animation->mode)
  148.  
  149.           // Apply the animation
  150.         if (animation->sequence != S_NULL)
  151.         {
  152.             entity->SetAnimationFrame(frame, blend, animation->sequence, true);
  153.         }
  154.  
  155.         // If this animation is blended in 100%, all previous looping animation sequences can be dropped
  156.         if (blend >= 1.0)
  157.         {
  158.             maxanim = Math::Max(maxanim, i);
  159.         }
  160.     } // forloop
  161.  
  162.       // Unlock entity matrix if any animations were applied
  163.     if (doanimation == true)
  164.     {
  165.         entity->UnlockMatrix();
  166.     }
  167.  
  168.     // Clear blended out animation - moved this out of the loop to prevent jittering
  169.     if (maxanim > -1)
  170.     {
  171.         for (int n = 0; n < animations.size(); ++n) {
  172.             Animation* completedanimation = animations[n];
  173.  
  174.             if (n < maxanim)
  175.             {
  176.                 if (completedanimation->mode == false || completedanimation->endOfSequenceReached == true)
  177.                 {
  178.                     DevMsg("AnimationManager: Removing completedanimation. " + to_string(animations.size()));
  179.                     animations.erase(animations.begin() + n);
  180.                 }
  181.             }
  182.             else
  183.             {
  184.                 //DevMsg("AnimationManager:Break.");
  185.                 break;
  186.             }
  187.         }
  188.     }
  189. }
  190.  
  191. // The test entity:
  192. PuppeteerAnimating::PuppeteerAnimating(Entity* pEntity) : Puppeteer(pEntity)
  193. {
  194.     Start();
  195. }
  196.  
  197. PuppeteerAnimating::~PuppeteerAnimating()
  198. {
  199.     SAFE_DELETE(animationmanager);
  200. }
  201.  
  202. void PuppeteerAnimating::Start()
  203. {
  204.     animationmanager = new AnimationManager(entity);
  205. }
  206.  
  207. void PuppeteerAnimating::Use(Entity* pCaller)
  208. {
  209.     DevMsg("use");
  210.     //animationmanager->SetAnimationSequence("Run", 0.04);
  211.     animationmanager->SetAnimationSequence("Death", 0.04, 300, true);
  212.     animationmanager->SetAnimationSequence("Attack1", 0.05, 300, true);
  213.     animationmanager->SetAnimationSequence("Attack2", 0.05, 300, true);
  214. }
  215.  
  216.  
  217. void PuppeteerAnimating::Draw(Camera* camera)
  218. {
  219.     animationmanager->Update();
  220. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement