Character control and animation transition sample
Posted: Sun May 25, 2008 3:13 pm
Hi there, this is my class with some hard code to demo new animation feature in Irrlicht 1.4 called: Animation Transitions
http://www.irrlicht3d.org/wiki/index.ph ... tionSystem
To use these classes:
1. Create a new instance in your main
2. Init new character
3. In render loop, try to call
4. On any event, such as mouse click on terrain try to set
Happy Irrlicht Coding !
http://www.irrlicht3d.org/wiki/index.ph ... tionSystem
We have 2 files here, named CCharacter.h and CCharacter.cpp, I have been using ninja free model at:How To Use The New Animation System
This tutorial will show you how to use the new animation system in Irrlicht 1.4
Note: this only applies with bone based formats (eg b3d, ms3d, x)
Transitions
Transitions are for blending from one animation into another. eg when a characters stops running, instead of just jumping to an idle animation, if you use a transition it will blend the animations together and make it look natural.
To use it, call:
Node->setTransitionTime( TimeOfBlendInSeconds );
Joint control will automatically be enabled (the blending needs it), so you must also call:
Node->animateJoints();
Before the drawAll
Code: Select all
http://www.psionic3d.co.uk/downloads/ninja.zip
1. Create a new instance in your main
Code: Select all
//Main character
CCharacter* viethero;
Code: Select all
//Setup viethero character
viethero = new CCharacter(game->getDevice(),game->getSceneManager(),game->getVideoDriver(),"Media\\Model\\Ninja\\ninja.b3d");
viethero->setPosition(irr::core::vector3df(1275.0f, 60.0f, 2675.0f));
Code: Select all
//Control main character
viethero->move(targetPoint);
Code: Select all
targetPoint = collisionPoint;
viethero->walk();
Code: Select all
/*
***********************************************
* Character control
* *********************************************
* file name: CCharacter.h
* encoding: UTF-8
* tab size: 8
* indentation: 4
* created on: 8:55 PM 3/17/2008
* init by: Do Quoc Khanh - doqkhanh
* created by: FOSP Team
* copyright: FOS Project
*/
#pragma once
#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
class CCharacter : public irr::scene::IAnimationEndCallBack
{
private:
float fSpeed;
scene::IAnimatedMeshSceneNode* node;
public:
enum eAttacktype{
MagicAttack,
PowerAttack,
DownswipeAttack
};
enum eState{
Run,
Walk,
Attack,
Idle
};
eAttacktype curAttackType;
eState curState;
eState oldState;
public:
CCharacter(IrrlichtDevice* device, irr::scene::ISceneManager *smgr,irr::video::IVideoDriver *videodriver, char* meshPath);
~CCharacter(void);
void setState(eState newState);
void setPosition(core::vector3df pos);
void setRotate(core::vector3df rot);
core::vector3df getPosition();
core::vector3df getRotate();
eState getState();
irr::scene::IAnimatedMeshSceneNode* getMesh();
irr::scene::IAnimatedMeshSceneNode* getNode();
void run();
void walk();
void attack(eAttacktype);
void idle();
void move(core::vector3df pos);
void update();
void remove();
void OnAnimationEnd(IAnimatedMeshSceneNode* node);
};
Code: Select all
/*
***********************************************
* Character control
* *********************************************
* file name: CCharacter.h
* encoding: UTF-8
* tab size: 8
* indentation: 4
* created on: 9:03 PM 3/17/2008
* init by: Do Quoc Khanh - doqkhanh
* created by: FOSP Team
* copyright: FOS Project
*/
#include "CCharacter.h"
#include <irrlicht.h>
#define ANIMATION_SPEED 5
irr::scene::IAnimatedMeshSceneNode* CCharacter::getMesh()
{
return node;
}
CCharacter::CCharacter(IrrlichtDevice* device, irr::scene::ISceneManager *smgr,irr::video::IVideoDriver *videodriver, char* meshPath)
{
node = smgr->addAnimatedMeshSceneNode(smgr->getMesh(meshPath));
node->setMaterialFlag(video::EMF_LIGHTING, false);
fSpeed = 0.4f;
curState = CCharacter::eState::Idle;
oldState = CCharacter::eState::Idle;
curAttackType = CCharacter::eAttacktype::MagicAttack;
node->setJointMode(irr::scene::EJUOR_CONTROL);
node->setTransitionTime(0.5);
idle();
}
CCharacter::~CCharacter(void)
{
node->remove();
}
void CCharacter::setState(eState newState)
{
oldState = curState;
curState = newState;
}
void CCharacter::setPosition(core::vector3df pos)
{
node->setPosition(pos);
}
void CCharacter::setRotate(core::vector3df rot)
{
node->setRotation(rot);
}
core::vector3df CCharacter::getPosition()
{
return node->getPosition();
}
core::vector3df CCharacter::getRotate()
{
return node->getRotation();
}
CCharacter::eState CCharacter::getState()
{
return curState;
}
void CCharacter::run()
{
setState(CCharacter::eState::Run);
node->setAnimationSpeed(ANIMATION_SPEED);
node->setLoopMode(true);
node->setFrameLoop(1,14);
}
void CCharacter::walk()
{
setState(CCharacter::eState::Walk);
node->setAnimationSpeed(ANIMATION_SPEED);
node->setLoopMode(true);
node->setFrameLoop(1,14);
}
void CCharacter::idle()
{
setState(CCharacter::eState::Idle);
node->setAnimationSpeed(ANIMATION_SPEED);
node->setLoopMode(true);
node->setFrameLoop(206,300);
}
void CCharacter::attack(eAttacktype attackType)
{
setState(CCharacter::eState::Attack);
switch (attackType)
{
case eAttacktype::PowerAttack :
{
node->setAnimationSpeed(ANIMATION_SPEED);
node->setLoopMode(false);
node->setFrameLoop(45,59);
node->setAnimationEndCallback(this);
return;
}
case eAttacktype::DownswipeAttack:
{
node->setAnimationSpeed(ANIMATION_SPEED);
node->setLoopMode(false);
node->setFrameLoop(60,68);
node->setAnimationEndCallback(this);
return;
}
case eAttacktype::MagicAttack:
{
node->setAnimationSpeed(ANIMATION_SPEED);
node->setLoopMode(false);
node->setFrameLoop(69,72);
node->setAnimationEndCallback(this);
return;
}
}
}
core::vector3df faceTarget(irr::core::vector3df targetpos, irr::core::vector3df nodepos) {
core::vector3df posDiff = targetpos - nodepos;
f32 degree = nodepos.Y; //keep current rotation if nothing to do
posDiff.normalize();
if (posDiff.X != 0.0f || posDiff.Z != 0.0f)
degree = atan2(posDiff.X,posDiff.Z) * core::RADTODEG;
return core::vector3df(0,degree,0);
}
void moveto(irr::scene::ISceneNode *node, //node to move
irr::core::vector3df vel) //velocity vector
{
irr::core::matrix4 m;
m.setRotationDegrees(node->getRotation());
m.transformVect(vel);
node->setPosition(node->getPosition() + vel);
node->updateAbsolutePosition();
}
void CCharacter::move(core::vector3df pos)
{
// Avoid complex operation in next step
if(getState() != CCharacter::eState::Walk && getState() != CCharacter::eState::Run)
return;
if (node->getPosition().getDistanceFrom(pos) < 4)
{
idle();
}
else
{
node->setRotation( faceTarget(pos, node->getPosition()) );
moveto(node, core::vector3df(0,0,fSpeed));
}
this->node->animateJoints() ;
}
void CCharacter::update()
{
//Do nothing
}
void CCharacter::OnAnimationEnd(IAnimatedMeshSceneNode* node)
{
idle();
}
void CCharacter::remove()
{
node->remove();
}
irr::scene::IAnimatedMeshSceneNode* CCharacter::getNode()
{
return node;
}