Browse Source

Change cycle mode to wrap mode in AttributeAnimation, add ONCE mode make can play animation then auto remove it. remove PINGPONG mode (now PINGPONG mode is just for sprite animation).

Aster Jian 11 years ago
parent
commit
0b9ff78dcc

+ 7 - 7
Source/Engine/LuaScript/pkgs/Scene/AttributeAnimation.pkg

@@ -1,10 +1,10 @@
 $#include "AttributeAnimation.h"
 $#include "AttributeAnimation.h"
 
 
-enum CycleMode
+enum WrapMode
 {
 {
-    CM_LOOP = 0,
-    CM_CLAMP,
-    CM_PINGPONG,
+    WM_LOOP = 0,
+    WM_ONCE,
+    WM_CLAMP,
 };
 };
 
 
 class AttributeAnimation : public Resource
 class AttributeAnimation : public Resource
@@ -12,15 +12,15 @@ class AttributeAnimation : public Resource
     AttributeAnimation();
     AttributeAnimation();
     virtual ~AttributeAnimation();
     virtual ~AttributeAnimation();
     
     
-    void SetCycleMode(CycleMode cycleMode);
+    void SetWrapMode(WrapMode wrapMode);
     void SetValueType(VariantType valueType);
     void SetValueType(VariantType valueType);
     bool SetKeyFrame(float time, const Variant& value);
     bool SetKeyFrame(float time, const Variant& value);
     void SetEventFrame(float time, const StringHash& eventType, const VariantMap& eventData = VariantMap());
     void SetEventFrame(float time, const StringHash& eventType, const VariantMap& eventData = VariantMap());
     
     
-    CycleMode GetCycleMode() const;
+    WrapMode GetWrapMode() const;
     VariantType GetValueType() const;
     VariantType GetValueType() const;
 
 
-    tolua_property__get_set CycleMode cycleMode;
+    tolua_property__get_set WrapMode wrapMode;
     tolua_property__get_set VariantType valueType;
     tolua_property__get_set VariantType valueType;
 };
 };
 
 

+ 8 - 1
Source/Engine/Scene/Animatable.cpp

@@ -297,8 +297,15 @@ void Animatable::UpdateAttributeAnimations(float timeStep)
     if (!animationEnabled_)
     if (!animationEnabled_)
         return;
         return;
 
 
+    Vector<String> finishedNames;
     for (HashMap<String, SharedPtr<AttributeAnimationInstance> >::ConstIterator i = attributeAnimationInstances_.Begin(); i != attributeAnimationInstances_.End(); ++i)
     for (HashMap<String, SharedPtr<AttributeAnimationInstance> >::ConstIterator i = attributeAnimationInstances_.Begin(); i != attributeAnimationInstances_.End(); ++i)
-        i->second_->Update(timeStep);
+    {
+        if (i->second_->Update(timeStep))
+            finishedNames.Push(i->second_->GetAttributeInfo().name_);
+    }
+
+    for (unsigned i = 0; i < finishedNames.Size(); ++i)
+        SetAttributeAnimation(finishedNames[i], 0);
 }
 }
 
 
 bool Animatable::IsAnimatedNetworkAttribute(const AttributeInfo& attrInfo) const
 bool Animatable::IsAnimatedNetworkAttribute(const AttributeInfo& attrInfo) const

+ 18 - 24
Source/Engine/Scene/AttributeAnimation.cpp

@@ -33,17 +33,17 @@
 namespace Urho3D
 namespace Urho3D
 {
 {
 
 
-const char* cycleModeNames[] = 
+const char* wrapModeNames[] = 
 {
 {
     "Loop",
     "Loop",
+    "Once",
     "Clamp",
     "Clamp",
-    "Pingpong",
     0
     0
 };
 };
 
 
 AttributeAnimation::AttributeAnimation(Context* context) :
 AttributeAnimation::AttributeAnimation(Context* context) :
     Resource(context),
     Resource(context),
-    cycleMode_(CM_LOOP),
+    wrapMode_(WM_LOOP),
     valueType_(VAR_NONE),
     valueType_(VAR_NONE),
     isInterpolatable_(false),
     isInterpolatable_(false),
     beginTime_(M_INFINITY),
     beginTime_(M_INFINITY),
@@ -85,13 +85,13 @@ bool AttributeAnimation::LoadXML(const XMLElement& source)
     valueType_ = VAR_NONE;
     valueType_ = VAR_NONE;
     eventFrames_.Clear();
     eventFrames_.Clear();
 
 
-    String cycleModeString = source.GetAttribute("cycleMode");
-    cycleMode_ = CM_LOOP;
-    for (int i = 0; i <= CM_PINGPONG; ++i)
+    String wrapModeString = source.GetAttribute("wrapMode");
+    wrapMode_ = WM_LOOP;
+    for (int i = 0; i <= WM_CLAMP; ++i)
     {
     {
-        if (cycleModeString == cycleModeNames[i])
+        if (wrapModeString == wrapModeNames[i])
         {
         {
-            cycleMode_ = (CycleMode)i;
+            wrapMode_ = (WrapMode)i;
             break;
             break;
         }
         }
     }
     }
@@ -124,7 +124,7 @@ bool AttributeAnimation::LoadXML(const XMLElement& source)
 
 
 bool AttributeAnimation::SaveXML(XMLElement& dest) const
 bool AttributeAnimation::SaveXML(XMLElement& dest) const
 {
 {
-    dest.SetAttribute("cycleMode", cycleModeNames[cycleMode_]);
+    dest.SetAttribute("wrapMode", wrapModeNames[wrapMode_]);
     dest.SetAttribute("valueType", Variant::GetTypeName(valueType_));
     dest.SetAttribute("valueType", Variant::GetTypeName(valueType_));
 
 
     for (unsigned i = 0; i < keyFrames_.Size(); ++i)
     for (unsigned i = 0; i < keyFrames_.Size(); ++i)
@@ -152,9 +152,9 @@ void AttributeAnimation::SetObjectAnimation(ObjectAnimation* objectAnimation)
     objectAnimation_ = objectAnimation;
     objectAnimation_ = objectAnimation;
 }
 }
 
 
-void AttributeAnimation::SetCycleMode(CycleMode cycleMode)
+void AttributeAnimation::SetWrapMode(WrapMode wrapMode)
 {
 {
-    cycleMode_ = cycleMode;
+    wrapMode_ = wrapMode;
 }
 }
 
 
 void AttributeAnimation::SetValueType(VariantType valueType)
 void AttributeAnimation::SetValueType(VariantType valueType)
@@ -230,27 +230,21 @@ ObjectAnimation* AttributeAnimation::GetObjectAnimation() const
     return objectAnimation_;
     return objectAnimation_;
 }
 }
 
 
-float AttributeAnimation::CalculateScaledTime(float currentTime) const
+float AttributeAnimation::CalculateScaledTime(float currentTime, bool& finished) const
 {
 {
-    switch (cycleMode_)
+    switch (wrapMode_)
     {
     {
-    case CM_LOOP:
+    case WM_LOOP:
         {
         {
             float span = endTime_ - beginTime_;
             float span = endTime_ - beginTime_;
             return beginTime_ + fmodf(currentTime - beginTime_, span);
             return beginTime_ + fmodf(currentTime - beginTime_, span);
         }
         }
 
 
-    case CM_CLAMP:
-        return Clamp(currentTime, beginTime_, endTime_);
+    case WM_ONCE:
+        finished = (currentTime >= endTime_);
 
 
-    case CM_PINGPONG:
-        {
-            float span = endTime_ - beginTime_;
-            float doubleSpan = span * 2.0f;
-            float fract = fmodf(currentTime - beginTime_, doubleSpan);
-            return (fract < span) ? beginTime_ + fract : beginTime_ + doubleSpan - fract;
-        }
-        break;
+    case WM_CLAMP:
+        return Clamp(currentTime, beginTime_, endTime_);
     }
     }
 
 
     return beginTime_;
     return beginTime_;

+ 13 - 13
Source/Engine/Scene/AttributeAnimation.h

@@ -31,15 +31,15 @@ namespace Urho3D
 class ObjectAnimation;
 class ObjectAnimation;
 class XMLElement;
 class XMLElement;
 
 
-/// Cycle mode.
-enum CycleMode
+/// Animation wrap mode.
+enum WrapMode
 {
 {
     /// Loop mode.
     /// Loop mode.
-    CM_LOOP = 0,
+    WM_LOOP = 0,
+    /// Play once then remove.
+    WM_ONCE,
     /// Clamp mode.
     /// Clamp mode.
-    CM_CLAMP,
-    /// Pingpong Mode.
-    CM_PINGPONG,
+    WM_CLAMP,
 };
 };
 
 
 /// Attribute key frame
 /// Attribute key frame
@@ -86,8 +86,8 @@ public:
 
 
     /// Set object animation.
     /// Set object animation.
     void SetObjectAnimation(ObjectAnimation* objectAnimation);
     void SetObjectAnimation(ObjectAnimation* objectAnimation);
-    /// Set cycle mode.
-    void SetCycleMode(CycleMode cycleMode);
+    /// Set wrap mode.
+    void SetWrapMode(WrapMode warpMode);
     /// Set value type.
     /// Set value type.
     void SetValueType(VariantType valueType);
     void SetValueType(VariantType valueType);
     /// Set key frame.
     /// Set key frame.
@@ -97,8 +97,8 @@ public:
 
 
     /// Return object animation.
     /// Return object animation.
     ObjectAnimation* GetObjectAnimation() const;
     ObjectAnimation* GetObjectAnimation() const;
-    /// Return cycle mode.
-    CycleMode GetCycleMode() const { return cycleMode_; }
+    /// Return wrap mode.
+    WrapMode GetWrapMode() const { return wrapMode_; }
     /// Return value type.
     /// Return value type.
     VariantType GetValueType() const { return valueType_; }
     VariantType GetValueType() const { return valueType_; }
     /// Is interpolatable.
     /// Is interpolatable.
@@ -108,7 +108,7 @@ public:
     /// Return end time.
     /// Return end time.
     float GetEndTime() const { return endTime_; }
     float GetEndTime() const { return endTime_; }
     /// Calculate scaled time.
     /// Calculate scaled time.
-    float CalculateScaledTime(float currentTime) const;
+    float CalculateScaledTime(float currentTime, bool& finished) const;
     /// Return all key frames.
     /// Return all key frames.
     const Vector<AttributeKeyFrame>& GetKeyFrames() const { return keyFrames_; }
     const Vector<AttributeKeyFrame>& GetKeyFrames() const { return keyFrames_; }
     /// Has event frames.
     /// Has event frames.
@@ -120,8 +120,8 @@ protected:
 
 
     /// Object animation.
     /// Object animation.
     WeakPtr<ObjectAnimation> objectAnimation_;
     WeakPtr<ObjectAnimation> objectAnimation_;
-    /// Cycle mode.
-    CycleMode cycleMode_;
+    /// Wrap mode.
+    WrapMode wrapMode_;
     /// Value type.
     /// Value type.
     VariantType valueType_;
     VariantType valueType_;
     /// Is interpolatable.
     /// Is interpolatable.

+ 13 - 11
Source/Engine/Scene/AttributeAnimationInstance.cpp

@@ -56,18 +56,20 @@ AttributeAnimationInstance::~AttributeAnimationInstance()
 {
 {
 }
 }
 
 
-void AttributeAnimationInstance::Update(float timeStep)
+bool AttributeAnimationInstance::Update(float timeStep)
 {
 {
     if (!attributeAnimation_)
     if (!attributeAnimation_)
-        return;
+        return true;
     
     
     currentTime_ += timeStep * speed_;
     currentTime_ += timeStep * speed_;
     
     
     const Vector<AttributeKeyFrame>& keyFrames = attributeAnimation_->GetKeyFrames();
     const Vector<AttributeKeyFrame>& keyFrames = attributeAnimation_->GetKeyFrames();
     if (keyFrames.Size() < 2)
     if (keyFrames.Size() < 2)
-        return;
+        return true;
+
+    bool finished = false;
+    float scaledTime = attributeAnimation_->CalculateScaledTime(currentTime_, finished);
 
 
-    float scaledTime = attributeAnimation_->CalculateScaledTime(currentTime_);
     for (unsigned i = 1; i < keyFrames.Size(); ++i)
     for (unsigned i = 1; i < keyFrames.Size(); ++i)
     {
     {
         const AttributeKeyFrame& currKeyFrame = keyFrames[i];
         const AttributeKeyFrame& currKeyFrame = keyFrames[i];
@@ -85,9 +87,9 @@ void AttributeAnimationInstance::Update(float timeStep)
     if (attributeAnimation_->HasEventFrames())
     if (attributeAnimation_->HasEventFrames())
     {
     {
         Vector<const AttributeEventFrame*> eventFrames;
         Vector<const AttributeEventFrame*> eventFrames;
-        switch (attributeAnimation_->GetCycleMode())
+        switch (attributeAnimation_->GetWrapMode())
         {
         {
-        case CM_LOOP:
+        case WM_LOOP:
             if (lastScaledTime_ < scaledTime)
             if (lastScaledTime_ < scaledTime)
                 attributeAnimation_->GetEventFrames(lastScaledTime_, scaledTime, eventFrames);
                 attributeAnimation_->GetEventFrames(lastScaledTime_, scaledTime, eventFrames);
             else
             else
@@ -96,12 +98,10 @@ void AttributeAnimationInstance::Update(float timeStep)
                 attributeAnimation_->GetEventFrames(attributeAnimation_->GetBeginTime(), scaledTime, eventFrames);
                 attributeAnimation_->GetEventFrames(attributeAnimation_->GetBeginTime(), scaledTime, eventFrames);
             }
             }
             break;
             break;
-        case CM_CLAMP:
-            attributeAnimation_->GetEventFrames(lastScaledTime_, scaledTime, eventFrames);
-            break;
 
 
-        case CM_PINGPONG:
-            // Not implement
+        case WM_ONCE:
+        case WM_CLAMP:
+            attributeAnimation_->GetEventFrames(lastScaledTime_, scaledTime, eventFrames);
             break;
             break;
         }
         }
 
 
@@ -110,6 +110,8 @@ void AttributeAnimationInstance::Update(float timeStep)
     }
     }
 
 
     lastScaledTime_ = scaledTime;
     lastScaledTime_ = scaledTime;
+
+    return finished;
 }
 }
 
 
 Animatable* AttributeAnimationInstance::GetAnimatable() const
 Animatable* AttributeAnimationInstance::GetAnimatable() const

+ 2 - 2
Source/Engine/Scene/AttributeAnimationInstance.h

@@ -42,8 +42,8 @@ public:
     /// Destruct.
     /// Destruct.
     ~AttributeAnimationInstance();
     ~AttributeAnimationInstance();
 
 
-    /// Update.
-    void Update(float timeStep);
+    /// Update (if animaiton finished return true).
+    bool Update(float timeStep);
     /// Set speed.
     /// Set speed.
     void SetSpeed(float speed) { speed_ = speed; }
     void SetSpeed(float speed) { speed_ = speed; }
     /// Return animatable.
     /// Return animatable.

+ 6 - 6
Source/Engine/Script/SceneAPI.cpp

@@ -37,14 +37,14 @@ namespace Urho3D
 
 
 static void RegisterAttributeAnimation(asIScriptEngine* engine)
 static void RegisterAttributeAnimation(asIScriptEngine* engine)
 {
 {
-    engine->RegisterEnum("CycleMode");
-    engine->RegisterEnumValue("CycleMode", "CM_LOOP", CM_LOOP);
-    engine->RegisterEnumValue("CycleMode", "CM_CLAMP", CM_CLAMP);
-    engine->RegisterEnumValue("CycleMode", "CM_PINGPONG", CM_PINGPONG);
+    engine->RegisterEnum("WrapMode");
+    engine->RegisterEnumValue("WrapMode", "WM_LOOP", WM_LOOP);
+    engine->RegisterEnumValue("WrapMode", "WM_ONCE", WM_ONCE);
+    engine->RegisterEnumValue("WrapMode", "WM_CLAMP", WM_CLAMP);
 
 
     RegisterResource<AttributeAnimation>(engine, "AttributeAnimation");
     RegisterResource<AttributeAnimation>(engine, "AttributeAnimation");
-    engine->RegisterObjectMethod("AttributeAnimation", "void set_cycleMode(CycleMode)", asMETHOD(AttributeAnimation, SetCycleMode), asCALL_THISCALL);
-    engine->RegisterObjectMethod("AttributeAnimation", "CycleMode get_cycleMode() const", asMETHOD(AttributeAnimation, GetCycleMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AttributeAnimation", "void set_wrapMode(WrapMode)", asMETHOD(AttributeAnimation, SetWrapMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("AttributeAnimation", "WrapMode get_wrapMode() const", asMETHOD(AttributeAnimation, GetWrapMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("AttributeAnimation", "void set_valueType(VariantType)", asMETHOD(AttributeAnimation, SetValueType), asCALL_THISCALL);
     engine->RegisterObjectMethod("AttributeAnimation", "void set_valueType(VariantType)", asMETHOD(AttributeAnimation, SetValueType), asCALL_THISCALL);
     engine->RegisterObjectMethod("AttributeAnimation", "VariantType get_valueType() const", asMETHOD(AttributeAnimation, GetValueType), asCALL_THISCALL);
     engine->RegisterObjectMethod("AttributeAnimation", "VariantType get_valueType() const", asMETHOD(AttributeAnimation, GetValueType), asCALL_THISCALL);
     engine->RegisterObjectMethod("AttributeAnimation", "void SetKeyFrame(float, const Variant&)", asMETHOD(AttributeAnimation, SetKeyFrame), asCALL_THISCALL);
     engine->RegisterObjectMethod("AttributeAnimation", "void SetKeyFrame(float, const Variant&)", asMETHOD(AttributeAnimation, SetKeyFrame), asCALL_THISCALL);

+ 0 - 3
Source/Engine/Script/Urho2DAPI.cpp

@@ -133,13 +133,10 @@ static void RegisterAnimation2D(asIScriptEngine* engine)
 
 
 static void RegisterAnimatedSprite2D(asIScriptEngine* engine)
 static void RegisterAnimatedSprite2D(asIScriptEngine* engine)
 {
 {
-    /*
-	// Alreay registered in AttributeAnimation
     engine->RegisterEnum("CycleMode");
     engine->RegisterEnum("CycleMode");
     engine->RegisterEnumValue("CycleMode", "CM_LOOP", CM_LOOP);
     engine->RegisterEnumValue("CycleMode", "CM_LOOP", CM_LOOP);
     engine->RegisterEnumValue("CycleMode", "CM_CLAMP", CM_CLAMP);
     engine->RegisterEnumValue("CycleMode", "CM_CLAMP", CM_CLAMP);
     engine->RegisterEnumValue("CycleMode", "CM_PINGPONG", CM_PINGPONG);
     engine->RegisterEnumValue("CycleMode", "CM_PINGPONG", CM_PINGPONG);
-    */
 
 
     RegisterStaticSprite2D<AnimatedSprite2D>(engine, "AnimatedSprite2D");
     RegisterStaticSprite2D<AnimatedSprite2D>(engine, "AnimatedSprite2D");
     engine->RegisterObjectMethod("AnimatedSprite2D", "void set_speed(float)", asMETHOD(AnimatedSprite2D, SetSpeed), asCALL_THISCALL);
     engine->RegisterObjectMethod("AnimatedSprite2D", "void set_speed(float)", asMETHOD(AnimatedSprite2D, SetSpeed), asCALL_THISCALL);

+ 8 - 1
Source/Engine/Urho2D/AnimatedSprite2D.cpp

@@ -36,7 +36,14 @@ namespace Urho3D
 {
 {
 
 
 extern const char* URHO2D_CATEGORY;
 extern const char* URHO2D_CATEGORY;
-extern const char* cycleModeNames[];
+
+const char* cycleModeNames[] = 
+{
+    "Loop",
+    "Clamp",
+    "Pingpong",
+    0
+};
 
 
 template<> CycleMode Variant::Get<CycleMode>() const
 template<> CycleMode Variant::Get<CycleMode>() const
 {
 {

+ 11 - 1
Source/Engine/Urho2D/AnimatedSprite2D.h

@@ -22,7 +22,6 @@
 
 
 #pragma once
 #pragma once
 
 
-#include "AttributeAnimation.h"
 #include "StaticSprite2D.h"
 #include "StaticSprite2D.h"
 
 
 namespace Urho3D
 namespace Urho3D
@@ -30,6 +29,17 @@ namespace Urho3D
 
 
 class Animation2D;
 class Animation2D;
 
 
+/// Cycle mode.
+enum CycleMode
+{
+    /// Loop mode.
+    CM_LOOP = 0,
+    /// Clamp mode.
+    CM_CLAMP,
+    /// Pingpong Mode.
+    CM_PINGPONG,
+};
+
 /// Animated sprite component.
 /// Animated sprite component.
 class URHO3D_API AnimatedSprite2D : public StaticSprite2D
 class URHO3D_API AnimatedSprite2D : public StaticSprite2D
 {
 {