Re: Chaining Animations?
Posted: Sun Aug 28, 2011 3:29 pm
Seriously just put some effort in it yourself and write what you need. Sudi gave you some code that is close to your problem you just need to modify it a bit to get what you want.
Official forum of the Irrlicht Engine
https://irrlicht.sourceforge.io/forum/
Did you even read the code at all i posted?thoma91 wrote:Thank you Sudi for your example, but it's still not, what I'm looking for.
This changes animations by pressing keys.
I need automatic change, after one animation is finished/played.
The problem is, when I set up a second animation, the first one gets ignored.
Even if there's an if condition before it, like this:So the first animation has to be played, before the second could start, but only the second one is played.Code: Select all
...
Sudi, and others: could you help me solving this?
This is a disrespect for the helpers. Sudi has spent probably about half an hour or more to create a simplified and easy to understand working example especially for you and you seem not to have spent even 15 minutes testing it. From your explanations the code does exactly what you`re trying to do. Please, soon or later you`ll need to put some time and efforts on your side, and there`s just no way around that. Of course it`s ok to ask for help, but if you wanna your project to keep going, you`ll need to slowly start learning.thoma91 wrote:So the first animation has to be played, before the second could start, but only the second one is played.
Sudi, and others: could you help me solving this?
Yes, it works of course.Sudi wrote: Just as an example you could add a next field to each animation and when set it plays this next animation when the animation finishes.....
Code: Select all
playanimation(1); // takes hit
onanimationend(); // I want to end that animation
playanimation(2); // walks
Code: Select all
void playanimation(int n)
{
if(n==1)
{
if(!animationrunning) // animationrunning is a global variable, starting value is false
{
setanimation(1);
}
else
{
//hasnext=true; // hasnext is a global variable, starting value is false
//setanimation(2);
}
}
else if(n==2)
{
if(!animationrunning)
{
setanimation(2);
}
else
{
//
}
}
}
Code: Select all
void setanimation(int n)
{
if(n==1)
{
node->setFrameLoop(272,288);
node->setLoopMode(false);
animationrunning=true;
}
else if(n==2)
{
node->setFrameLoop(0,24);
node->setLoopMode(true);
animationrunning=true;
}
}
Code: Select all
void onanimationend()
{
if(animationrunning)
{
node->setAnimationEndCallback(0); // I want to end that animation
animationrunning=false;
}
else
{
}
}
Code: Select all
class CAnimationController : public irr::scene::IAnimationEndCallBackCode: Select all
void OnAnimationEnd(irr::scene::IAnimatedMeshSceneNode* node);Code: Select all
void onanimationend()
{
if(animationrunning)
{
node->setAnimationEndCallback(0); // I want to end that animation
animationrunning=false;
}
else
{
}
}Code: Select all
void OnAnimationEnd() // you cannot simply change this name, because Irrlicht calls this function by exactly this name
{
if (animationRunning) // or animation_running, I myself would call it maybe IsAnimRunning or sth alike
{
node->setAnimationEndCallback(0); // the callback won`t be used for a while, nullify it
animationRunning = false;
}
else
{
}
}oh really??Sudi wrote:@thoma91
I think the big problem here is that you don't understand at all what my code was doing and when it was doing it and thats bc you know to little about programming structures and even the language. You should really get some good tutorial about classes and certain structures.Bc for example the OnAnimationEnd is called from inside irrlicht not from myself. its an interface callback which is triggered when the last frame of animation is reached. The example code you showed assumes that code is not running in a straight line of time and that irrlicht is rendering in a different thread maybe?
What?serengeor wrote:oh really??Sudi wrote:@thoma91
I think the big problem here is that you don't understand at all what my code was doing and when it was doing it and thats bc you know to little about programming structures and even the language. You should really get some good tutorial about classes and certain structures.Bc for example the OnAnimationEnd is called from inside irrlicht not from myself. its an interface callback which is triggered when the last frame of animation is reached. The example code you showed assumes that code is not running in a straight line of time and that irrlicht is rendering in a different thread maybe?
I thought it just updates the animations in the smgr->drawAll() (not exactly in it but rather w/e it calls to do so).
Code: Select all
#ifndef CANIMATIONCONTROLLER_H
#define CANIMATIONCONTROLLER_H
#include <IAnimatedMeshSceneNode.h>
#include <irrMap.h>
class CAnimationController : public irr::scene::IAnimationEndCallBack
{
public:
struct Animation
{
Animation()
{
name = "";
start = 0;
end = 1;
looping = false;
}
Animation(const irr::c8* n, const irr::u32& s, const irr::u32& e, const bool& loop)
{
name = n;
start = s;
end = e;
looping = loop;
}
Animation(const Animation& other)
{
name = other.name;
start = other.start;
end = other.end;
looping = other.looping;
}
irr::core::stringc name;
irr::u32 start;
irr::u32 end;
bool looping;
};
CAnimationController();
virtual ~CAnimationController();
//!Set the node that should be controlled
void setAnimatedMeshNode(irr::scene::IAnimatedMeshSceneNode* node);
//!Add an animation to the controller
void addAnimation(const irr::c8* name, const irr::u32& start, const irr::u32& end, const bool& loop = false);
//!Plays an animation when the previous ones finished. Animations chain up
void playAnimation(const irr::c8* name);
//!Plays this animation directly after the last one and clears the animation chain
void playAnimationNext(const irr::c8* name);
//!Plays this animation directly and clears the animation chain
void playAnimationNow(const irr::c8* name);
void OnAnimationEnd(irr::scene::IAnimatedMeshSceneNode* node);
protected:
void setAnimation(const Animation& anim);
irr::core::map<irr::core::stringc, Animation> animations;
Animation currentAnimation;
irr::core::array<Animation> nextAnimation;
irr::scene::IAnimatedMeshSceneNode*animatedNnode;
bool animationRunning;
};
#endif // CANIMATIONCONTROLLER_H
Code: Select all
/*
Copyright (C) 2011 Daniel Sudmann
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Daniel Sudmann suddani@googlemail.com
*/
#include "CAnimationController.h"
CAnimationController::CAnimationController()
{
animatedNnode = 0;
animationRunning = false;
}
CAnimationController::~CAnimationController()
{
if (animatedNnode)
{
animatedNnode->setAnimationEndCallback(0);
animatedNnode->drop();
}
animatedNnode = 0;
}
void CAnimationController::OnAnimationEnd(irr::scene::IAnimatedMeshSceneNode *node)
{
animationRunning = false;
if ((nextAnimation.size() > 0 || currentAnimation.looping) && animatedNnode)
{
if (nextAnimation.size() > 0 )
{
setAnimation(nextAnimation[0]);
nextAnimation.erase(0);
}
else
setAnimation(currentAnimation);
}
}
void CAnimationController::addAnimation(const irr::c8 *name, const irr::u32 &start, const irr::u32 &end, const bool& loop)
{
animations[name] = Animation(name, start, end, loop);
}
void CAnimationController::setAnimatedMeshNode(irr::scene::IAnimatedMeshSceneNode *node)
{
if (animatedNnode == node)
return;
nextAnimation.clear();
animationRunning = false;
if (animatedNnode)
{
animatedNnode->setAnimationEndCallback(0);
animatedNnode->drop();
}
animatedNnode = node;
if (animatedNnode)
{
animatedNnode->grab();
currentAnimation.start = 0;
currentAnimation.end = animatedNnode->getEndFrame(); //There is no way to get the actual frame count...
animatedNnode->setAnimationEndCallback(this);
}
}
void CAnimationController::playAnimation(const irr::c8 *name)
{
if (animations.find(name) == 0)
return;
if (animationRunning)
{
nextAnimation.push_back(animations[name]);
}
else
setAnimation(animations[name]);
}
void CAnimationController::playAnimationNext(const irr::c8* name)
{
if (animations.find(name) == 0)
return;
nextAnimation.clear();
if (animationRunning)
{
nextAnimation.push_back(animations[name]);
}
else
setAnimation(animations[name]);
}
void CAnimationController::playAnimationNow(const irr::c8* name)
{
if (animations.find(name) == 0)
return;
nextAnimation.clear();
setAnimation(animations[name]);
}
void CAnimationController::setAnimation(const Animation& anim)
{
printf("change Animation to %s\n", anim.name.c_str());
currentAnimation = anim;
animatedNnode->setFrameLoop(currentAnimation.start, currentAnimation.end);
animatedNnode->setCurrentFrame(currentAnimation.start);
animatedNnode->setLoopMode(false);
animationRunning = true;
}Code: Select all
/*
Copyright (C) 2011 Daniel Sudmann
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Daniel Sudmann suddani@googlemail.com
*/
#include "CAnimationController.h"
#include <irrlicht.h>
struct events : irr::IEventReceiver
{
bool OnEvent(const irr::SEvent& event)
{
if (event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
{
if (event.KeyInput.Key == irr::KEY_KEY_Q)
{
controller.playAnimation("idle");
}
else if (event.KeyInput.Key == irr::KEY_KEY_W)
{
controller.playAnimation("crouch");
}
else if (event.KeyInput.Key == irr::KEY_KEY_E)
{
controller.playAnimation("stand");
}
else if (event.KeyInput.Key == irr::KEY_KEY_R)
{
controller.playAnimation("idle");
controller.playAnimation("crouch");
controller.playAnimation("stand");
controller.playAnimation("idle");
}
else if (event.KeyInput.Key == irr::KEY_ESCAPE)
{
device->closeDevice();
}
}
return false;
}
CAnimationController controller;
irr::IrrlichtDevice* device;
};
int main()
{
irr::IrrlichtDevice* device = irr::createDevice(irr::video::EDT_OPENGL);
irr::scene::IAnimatedMeshSceneNode* dwarf = device->getSceneManager()->addAnimatedMeshSceneNode(device->getSceneManager()->getMesh("dwarf.x")); //change to fit your media path
dwarf->setMaterialFlag(irr::video::EMF_LIGHTING, false);
dwarf->setLoopMode(false);
printf("Total frames: %i\n", dwarf->getEndFrame());
device->getSceneManager()->addCameraSceneNodeFPS();
events event;
event.device = device;
event.controller.setAnimatedMeshNode(dwarf);
printf("!!!Total frames: %i\n", dwarf->getEndFrame());
event.controller.addAnimation("crouch", 0, 20);
event.controller.addAnimation("idle", 21, 30, true);
event.controller.addAnimation("stand", 31, 54);
device->setEventReceiver(&event);
while (device->run())
{
device->getVideoDriver()->beginScene();
device->getSceneManager()->drawAll();
device->getVideoDriver()->endScene();
}
device->drop();
return 0;
}
Never mind I read it the wrong way around.Sudi wrote: What?
Code: Select all
void CAnimationController::playAnimation(const irr::c8 *name)
{
if (animations.find(name) == 0)
return;
if (animationRunning && name != "hurt")
{
nextAnimation.push_back(animations[name]);
}
else if (animationRunning && name == "hurt")
{
setAnimation(animations[name]);
}
else if (!animationRunning)
{
setAnimation(animations[name]);
}
}
Code: Select all
CAnimationController::playAnimationNowCode: Select all
//!Plays an animation when the previous ones finished. Animations chain up
void playAnimation(const irr::c8* name);
//!Plays this animation directly after the last one and clears the animation chain
void playAnimationNext(const irr::c8* name);
//!Plays this animation directly and clears the animation chain
void playAnimationNow(const irr::c8* name);