Browse Source

Added network replication of instant set weight / set time position commands for AnimationController.
Increased precision of speed and fade time in Animationcontroller network replication.

Lasse Öörni 14 years ago
parent
commit
a6cc202b3c
2 changed files with 91 additions and 18 deletions
  1. 72 17
      Engine/Graphics/AnimationController.cpp
  2. 19 1
      Engine/Graphics/AnimationController.h

+ 72 - 17
Engine/Graphics/AnimationController.cpp

@@ -27,6 +27,7 @@
 #include "AnimationController.h"
 #include "AnimationState.h"
 #include "Context.h"
+#include "Log.h"
 #include "MemoryBuffer.h"
 #include "Profiler.h"
 #include "ResourceCache.h"
@@ -40,8 +41,10 @@ static String noBoneName;
 static const unsigned char CTRL_STARTBONE = 0x1;
 static const unsigned char CTRL_LOOPED = 0x2;
 static const unsigned char CTRL_NLERP = 0x4;
-static const unsigned char CTRL_REVERSE = 0x8;
+static const unsigned char CTRL_SETTIME = 0x8;
+static const unsigned char CTRL_SETWEIGHT = 0x10;
 static const float EXTRA_ANIM_FADEOUT_TIME = 0.1f;
+static const float COMMAND_DURATION = 0.25f;
 
 OBJECTTYPESTATIC(AnimationController);
 
@@ -115,6 +118,12 @@ void AnimationController::Update(float timeStep)
                 remove = true;
         }
         
+        // Decrement the command durations
+        if (i->setTimeDuration_ > 0.0f)
+            i->setTimeDuration_ = Max(i->setTimeDuration_ - timeStep, 0.0f);
+        if (i->setWeightDuration_ > 0.0f)
+            i->setWeightDuration_ = Max(i->setWeightDuration_ - timeStep, 0.0f);
+        
         if (remove)
         {
             if (state)
@@ -280,11 +289,18 @@ bool AnimationController::SetStartBone(const String& name, const String& startBo
 
 bool AnimationController::SetTime(const String& name, float time)
 {
-    AnimationState* state = FindAnimationState(name);
-    if (!state)
+    unsigned index;
+    AnimationState* state;
+    FindAnimation(name, index, state);
+    if (index == M_MAX_UNSIGNED || !state)
         return false;
     
+    time = Clamp(time, 0.0f, state->GetLength());
     state->SetTime(time);
+    // Prepare "set time" command for network replication
+    animations_[index].setTime_ = (unsigned short)(time / state->GetLength() * 65535.0f);
+    animations_[index].setTimeDuration_ = COMMAND_DURATION;
+    ++animations_[index].setTimeRevision_;
     return true;
 }
 
@@ -308,10 +324,12 @@ bool AnimationController::SetWeight(const String& name, float weight)
     if (index == M_MAX_UNSIGNED || !state)
         return false;
     
+    weight = Clamp(weight, 0.0f, 1.0f);
     state->SetWeight(weight);
-    // Set the target weight with zero fadetime for network replication
-    animations_[index].targetWeight_ = weight;
-    animations_[index].fadeTime_ = 0.0f;
+    // Prepare "set weight" command for network replication
+    animations_[index].setWeight_ = (unsigned char)(weight * 255.0f);
+    animations_[index].setWeightDuration_ = COMMAND_DURATION;
+    ++animations_[index].setWeightRevision_;
     return true;
 }
 
@@ -485,18 +503,31 @@ void AnimationController::SetNetAnimationsAttr(const PODVector<unsigned char>& v
     {
         --numAnimations;
         
+        unsigned short setTime;
+        unsigned char setTimeRevision;
+        unsigned char setWeight;
+        unsigned char setWeightRevision;
+        
         StringHash animHash = buf.ReadStringHash();
         unsigned char ctrl = buf.ReadUByte();
         StringHash startBoneHash;
         if (ctrl & CTRL_STARTBONE)
             startBoneHash = buf.ReadStringHash();
         unsigned char layer = buf.ReadUByte();
-        float speed = (float)buf.ReadUByte() / 32.0f;
-        if (ctrl & CTRL_REVERSE)
-            speed = -speed;
-        float targetWeight = (float)buf.ReadUByte() / 255.0f;
-        float fadeTime = (float)buf.ReadUByte() / 32.0f;
-        float autoFadeTime = (float)buf.ReadUByte() / 32.0f;
+        float speed = (float)buf.ReadShort() / 2048.0f; // 11 bits of decimal precision, max. 16x playback speed
+        float targetWeight = (float)buf.ReadUByte() / 255.0f; // 8 bits of decimal precision
+        float fadeTime = (float)buf.ReadUByte() / 64.0f; // 6 bits of decimal precision, max. 4 seconds fade time
+        float autoFadeTime = (float)buf.ReadUByte() / 64.0f; // 6 bits of decimal precision, max. 4 seconds fade time
+        if (ctrl & CTRL_SETTIME)
+        {
+            setTimeRevision = buf.ReadUByte();
+            setTime = buf.ReadUShort();
+        }
+        if (ctrl & CTRL_SETWEIGHT)
+        {
+            setWeightRevision = buf.ReadUByte();
+            setWeight = buf.ReadUByte();
+        }
         
         processedAnimations.Insert(animHash);
         
@@ -535,6 +566,18 @@ void AnimationController::SetNetAnimationsAttr(const PODVector<unsigned char>& v
         control.targetWeight_ = targetWeight;
         control.fadeTime_ = fadeTime;
         control.autoFadeTime_ = autoFadeTime;
+        
+        // Apply the time & weight commands now
+        if ((ctrl & CTRL_SETTIME) && setTimeRevision != control.setTimeRevision_)
+        {
+            control.setTimeRevision_ = setTimeRevision;
+            state->SetTime(((float)setTime / 65535.0f) * state->GetLength());
+        }
+        if ((ctrl & CTRL_SETWEIGHT) && setWeightRevision != control.setWeightRevision_)
+        {
+            control.setWeightRevision_ = setWeightRevision;
+            state->SetWeight((float)setWeight / 255.0f);
+        }
     }
     
     // Now set any extra animations to fade out
@@ -597,18 +640,30 @@ const PODVector<unsigned char>& AnimationController::GetNetAnimationsAttr() cons
             ctrl |= CTRL_LOOPED;
         if (state->GetUseNlerp())
             ctrl |= CTRL_NLERP;
-        if (i->speed_ < 0.0f)
-            ctrl |= CTRL_REVERSE;
+        if (i->setTimeDuration_ > 0.0f)
+            ctrl |= CTRL_SETTIME;
+        if (i->setWeightDuration_ > 0.0f)
+            ctrl |= CTRL_SETWEIGHT;
         
         attrBuffer_.WriteStringHash(i->hash_);
         attrBuffer_.WriteUByte(ctrl);
         if (ctrl & CTRL_STARTBONE)
             attrBuffer_.WriteStringHash(startBone->nameHash_);
         attrBuffer_.WriteUByte(state->GetLayer());
-        attrBuffer_.WriteUByte((unsigned char)Clamp(fabsf(i->speed_) * 32.0f, 0.0f, 255.0f));
+        attrBuffer_.WriteShort((short)Clamp(i->speed_ * 2048.0f, -32767.0f, 32767.0f));
         attrBuffer_.WriteUByte((unsigned char)(i->targetWeight_ * 255.0f));
-        attrBuffer_.WriteUByte((unsigned char)Clamp(i->fadeTime_ * 32.0f, 0.0f, 255.0f));
-        attrBuffer_.WriteUByte((unsigned char)Clamp(i->autoFadeTime_ * 32.0f, 0.0f, 255.0f));
+        attrBuffer_.WriteUByte((unsigned char)Clamp(i->fadeTime_ * 64.0f, 0.0f, 255.0f));
+        attrBuffer_.WriteUByte((unsigned char)Clamp(i->autoFadeTime_ * 64.0f, 0.0f, 255.0f));
+        if (ctrl & CTRL_SETTIME)
+        {
+            attrBuffer_.WriteUByte(i->setTimeRevision_);
+            attrBuffer_.WriteUShort(i->setTime_);
+        }
+        if (ctrl & CTRL_SETWEIGHT)
+        {
+            attrBuffer_.WriteUByte(i->setWeightRevision_);
+            attrBuffer_.WriteUByte(i->setWeight_);
+        }
     }
     
     return attrBuffer_.GetBuffer();

+ 19 - 1
Engine/Graphics/AnimationController.h

@@ -38,7 +38,13 @@ struct AnimationControl
         speed_(1.0f),
         targetWeight_(0.0f),
         fadeTime_(0.0f),
-        autoFadeTime_(0.0f)
+        autoFadeTime_(0.0f),
+        setTimeDuration_(0.0f),
+        setWeightDuration_(0.0f),
+        setTime_(0),
+        setTimeRevision_(0),
+        setWeight_(0),
+        setWeightRevision_(0)
     {
     }
 
@@ -52,6 +58,18 @@ struct AnimationControl
     float fadeTime_;
     /// Animation autofade on stop -time, 0 if disabled
     float autoFadeTime_;
+    /// Set time command duration
+    float setTimeDuration_;
+    /// Set weight command duration
+    float setWeightDuration_;
+    /// Set time command
+    unsigned short setTime_;
+    /// Set time command revision
+    unsigned char setTimeRevision_;
+    /// Set weight command
+    unsigned char setWeight_;
+    /// Set weight command revision
+    unsigned char setWeightRevision_;
 };
 
 /// Component that drives an AnimatedModel's animations