Merge pull request #7925 from super626/transition

Animation3D
This commit is contained in:
minggo 2014-09-09 14:39:15 +08:00
commit 1ee9cebebd
6 changed files with 158 additions and 45 deletions

View File

@ -25,11 +25,15 @@
#include "3d/CCAnimate3D.h"
#include "3d/CCSprite3D.h"
#include "3d/CCSkeleton3D.h"
#include "3d/CCMeshSkin.h"
#include "platform/CCFileUtils.h"
NS_CC_BEGIN
std::unordered_map<Sprite3D*, Animate3D*> Animate3D::s_fadeInAnimates;
std::unordered_map<Sprite3D*, Animate3D*> Animate3D::s_fadeOutAnimates;
std::unordered_map<Sprite3D*, Animate3D*> Animate3D::s_runningAnimates;
float Animate3D::_transTime = 0.1f;
//create Animate3D using Animation.
Animate3D* Animate3D::create(Animation3D* animation)
{
@ -107,6 +111,40 @@ void Animate3D::startWithTarget(Node *target)
{
CCLOG("warning: no animation finde for the skeleton");
}
auto runningAction = s_runningAnimates.find(sprite);
if (runningAction != s_runningAnimates.end())
{
//make the running action fade out
auto action = (*runningAction).second;
if (action != this)
{
s_fadeOutAnimates[sprite] = action;
action->_state = Animate3D::Animate3DState::FadeOut;
action->_accTransTime = 0.0f;
action->_weight = 1.0f;
action->_lastTime = 0.f;
s_fadeInAnimates[sprite] = this;
_accTransTime = 0.0f;
_state = Animate3D::Animate3DState::FadeIn;
_weight = 0.f;
_lastTime = 0.f;
}
}
else
{
s_runningAnimates[sprite] = this;
_state = Animate3D::Animate3DState::Running;
_weight = 1.0f;
}
}
void Animate3D::stop()
{
removeFromMap();
ActionInterval::stop();
}
//! called every frame with it's delta time. DON'T override unless you know what you are doing.
@ -117,7 +155,40 @@ void Animate3D::step(float dt)
void Animate3D::update(float t)
{
if (_target && _weight > 0.f)
if (_target)
{
if (_state == Animate3D::Animate3DState::FadeIn && _lastTime > 0.f)
{
_accTransTime += (t - _lastTime) * getDuration();
_weight = _accTransTime / _transTime;
if (_weight >= 1.0f)
{
_accTransTime = _transTime;
_weight = 1.0f;
_state = Animate3D::Animate3DState::Running;
Sprite3D* sprite = static_cast<Sprite3D*>(_target);
s_fadeInAnimates.erase(sprite);
s_runningAnimates[sprite] = this;
}
}
else if (_state == Animate3D::Animate3DState::FadeOut && _lastTime > 0.f)
{
_accTransTime += (t - _lastTime) * getDuration();
_weight = 1 - _accTransTime / _transTime;
if (_weight <= 0.0f)
{
_accTransTime = _transTime;
_weight = 0.0f;
Sprite3D* sprite = static_cast<Sprite3D*>(_target);
s_fadeOutAnimates.erase(sprite);
}
}
_lastTime = t;
if (_weight > 0.0f)
{
float transDst[3], rotDst[4], scaleDst[3];
float* trans = nullptr, *rot = nullptr, *scale = nullptr;
@ -146,7 +217,7 @@ void Animate3D::update(float t)
bone->setAnimationValue(trans, rot, scale, this, _weight);
}
}
}
}
float Animate3D::getSpeed() const
@ -172,12 +243,32 @@ Animate3D::Animate3D()
, _last(1.f)
, _animation(nullptr)
, _playReverse(false)
, _state(Animate3D::Animate3DState::Running)
, _accTransTime(0.0f)
, _lastTime(0.0f)
{
}
Animate3D::~Animate3D()
{
removeFromMap();
CC_SAFE_RELEASE(_animation);
}
void Animate3D::removeFromMap()
{
//remove this action from map
if (_target)
{
Sprite3D* sprite = static_cast<Sprite3D*>(_target);
if (_state == Animate3D::Animate3DState::FadeIn)
s_fadeInAnimates.erase(sprite);
else if (_state == Animate3D::Animate3DState::FadeOut)
s_fadeOutAnimates.erase(sprite);
else
s_runningAnimates.erase(sprite);
}
}
NS_CC_END

View File

@ -26,6 +26,7 @@
#define __CCANIMATE3D_H__
#include <map>
#include <unordered_map>
#include "3d/CCAnimation3D.h"
#include "3d/3dExport.h"
@ -36,6 +37,7 @@
NS_CC_BEGIN
class Bone3D;
class Sprite3D;
/**
* Animate3D, Animates a Sprite3D given with an Animation3D
*/
@ -57,6 +59,7 @@ public:
//
// Overrides
//
virtual void stop() override;
virtual void step(float dt) override;
virtual void startWithTarget(Node *target) override;
virtual Animate3D* reverse() const override;
@ -72,6 +75,9 @@ public:
float getWeight() const { return _weight; }
void setWeight(float weight);
/** animate transistion time */
static float getTransitionTime() { return _transTime; }
/**get & set play reverse, these are deprecated, use set negative speed instead*/
CC_DEPRECATED_ATTRIBUTE bool getPlayBack() const { return _playReverse; }
CC_DEPRECATED_ATTRIBUTE void setPlayBack(bool reverse) { _playReverse = reverse; }
@ -81,7 +87,16 @@ CC_CONSTRUCTOR_ACCESS:
Animate3D();
virtual ~Animate3D();
void removeFromMap();
protected:
enum class Animate3DState
{
FadeIn,
FadeOut,
Running,
};
Animate3DState _state; //animation state
Animation3D* _animation; //animation data
float _absSpeed; //playing speed
@ -89,7 +104,15 @@ protected:
float _start; //start time 0 - 1, used to generate sub Animate3D
float _last; //last time 0 - 1, used to generate sub Animate3D
bool _playReverse; // is playing reverse
std::map<Bone3D*, Animation3D::Curve*> _boneCurves; //weak ref
static float _transTime; //transition time from one animate3d to another
float _accTransTime; // acculate transition time
float _lastTime; // last t (0 - 1)
std::unordered_map<Bone3D*, Animation3D::Curve*> _boneCurves; //weak ref
//sprite animates
static std::unordered_map<Sprite3D*, Animate3D*> s_fadeInAnimates;
static std::unordered_map<Sprite3D*, Animate3D*> s_fadeOutAnimates;
static std::unordered_map<Sprite3D*, Animate3D*> s_runningAnimates;
};
NS_CC_END

View File

@ -231,6 +231,7 @@ void Bone3D::updateLocalMat()
}
quat = Quaternion(it.localRot.x * weight + quat.x, it.localRot.y * weight + quat.y, it.localRot.z * weight + quat.z, it.localRot.w * weight + quat.w);
}
quat.normalize();
}
}

View File

@ -37,5 +37,6 @@
#include "3d/CCSprite3DMaterial.h"
#include "3d/CCAttachNode.h"
#include "3d/CCMeshVertexIndexData.h"
#include "3d/CCSkeleton3D.h"
#endif

View File

@ -808,7 +808,6 @@ Animate3DTest::Animate3DTest()
, _swim(nullptr)
, _sprite(nullptr)
, _moveAction(nullptr)
, _transTime(0.1f)
, _elapseTransTime(0.f)
{
addSprite3D();
@ -842,28 +841,21 @@ void Animate3DTest::update(float dt)
if (_state == State::HURT_TO_SWIMMING)
{
_elapseTransTime += dt;
float t = _elapseTransTime / _transTime;
if (t >= 1.f)
if (_elapseTransTime >= Animate3D::getTransitionTime())
{
t = 1.f;
_sprite->stopAction(_hurt);
_state = State::SWIMMING;
}
_swim->setWeight(t);
_hurt->setWeight(1.f - t);
}
else if (_state == State::SWIMMING_TO_HURT)
{
_elapseTransTime += dt;
float t = _elapseTransTime / _transTime;
if (t >= 1.f)
if (_elapseTransTime >= Animate3D::getTransitionTime())
{
t = 1.f;
_sprite->stopAction(_swim);
_state = State::HURT;
}
_swim->setWeight(1.f - t);
_hurt->setWeight(t);
}
}
@ -880,8 +872,9 @@ void Animate3DTest::addSprite3D()
if (animation)
{
auto animate = Animate3D::create(animation, 0.f, 1.933f);
sprite->runAction(RepeatForever::create(animate));
_swim = animate;
_swim = RepeatForever::create(animate);
sprite->runAction(_swim);
_swim->retain();
_hurt = Animate3D::create(animation, 1.933f, 2.8f);
_hurt->retain();
@ -910,8 +903,10 @@ void Animate3DTest::reachEndCallBack()
void Animate3DTest::renewCallBack()
{
_sprite->stopActionByTag(101);
//rerun swim action
_sprite->runAction(_swim);
_state = State::HURT_TO_SWIMMING;
_elapseTransTime = 0.0f;
}
void Animate3DTest::onTouchesEnded(const std::vector<Touch*>& touches, Event* event)
@ -928,12 +923,14 @@ void Animate3DTest::onTouchesEnded(const std::vector<Touch*>& touches, Event* ev
//hurt the tortoise
if (_state == State::SWIMMING)
{
_elapseTransTime = 0.0f;
_state = State::SWIMMING_TO_HURT;
_sprite->stopAction(_hurt);
_sprite->runAction(_hurt);
auto delay = DelayTime::create(_hurt->getDuration() - 0.1f);
auto delay = DelayTime::create(_hurt->getDuration() - Animate3D::getTransitionTime());
auto seq = Sequence::create(delay, CallFunc::create(CC_CALLBACK_0(Animate3DTest::renewCallBack, this)), nullptr);
seq->setTag(101);
_sprite->runAction(seq);
_state = State::SWIMMING_TO_HURT;
}
return;
}

View File

@ -219,9 +219,9 @@ protected:
cocos2d::Sprite3D* _sprite;
cocos2d::Animate3D* _swim;
cocos2d::Action* _swim;
cocos2d::Animate3D* _hurt;
float _transTime;
float _elapseTransTime;
State _state;