Browse Source

Changed Spline::Move to use timeStep passed in from update events.
Added method to get an arbitary position along the Spline by specifying the factor "t" from 0.f - 1.f.

Alex Parlett 12 years ago
parent
commit
0210c3ffdf
3 changed files with 41 additions and 19 deletions
  1. 36 15
      Source/Engine/Scene/Spline.cpp
  2. 3 3
      Source/Engine/Scene/Spline.h
  3. 2 1
      Source/Engine/Script/SceneAPI.cpp

+ 36 - 15
Source/Engine/Scene/Spline.cpp

@@ -26,7 +26,6 @@
 #include "Node.h"
 #include "Scene.h"
 #include "Spline.h"
-#include "Timer.h"
 
 namespace Urho3D
 {
@@ -37,7 +36,6 @@ Spline::Spline(Context* context) :
     Component(context),
     interpolationMode_(BEZIER_CURVE),
     speed_(1.f),
-    startTime_(-1.f),
     elapsedTime_(0.f),
     length_(0.f),
     traveled_(0.f),
@@ -53,10 +51,9 @@ void Spline::RegisterObject(Context* context)
     ATTRIBUTE(Spline, VAR_FLOAT, "Speed", speed_, 1.f, AM_FILE);
     ATTRIBUTE(Spline, VAR_INT, "Interpolation Mode", interpolationMode_, BEZIER_CURVE, AM_FILE);
     ATTRIBUTE(Spline, VAR_FLOAT, "Traveled", traveled_, 0.f, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(Spline, VAR_FLOAT, "Start Time", startTime_, -1.f, AM_FILE | AM_NOEDIT);
     ATTRIBUTE(Spline, VAR_FLOAT, "Elapsed Time", elapsedTime_, 0.f, AM_FILE | AM_NOEDIT);
     ATTRIBUTE(Spline, VAR_FLOAT, "Length", length_, 0.f, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(Spline, VAR_BOOL, "Attached", attached_, false, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE(Spline, VAR_BOOL, "Attached", attached_, false, AM_FILE);
 }
 
 void Spline::SetControlPoints(const Vector<Vector3> controlPoints)
@@ -69,6 +66,25 @@ void Spline::SetInterpolationMode(InterpolationMode interpolationMode)
     interpolationMode_ = interpolationMode;
 }
 
+Vector3 Spline::GetPosition(float factor)
+{
+    float t = factor;
+
+    if (t < 0.f)
+        t = 0.0f;
+    else if (t > 1.0f)
+        t = 1.0f;
+
+    switch (interpolationMode_)
+    {
+    case BEZIER_CURVE:
+        return BezierMove(controlPoints_, t);
+
+    default:
+        return Vector3::ZERO;
+    }
+}
+
 void Spline::Push(const Vector3& controlPoint)
 {
     controlPoints_.Push(controlPoint);
@@ -84,22 +100,29 @@ void Spline::Attach()
     if (controlPoints_.Size() > 0)
     {
         CalculateLength();
-
-        GetNode()->SetPosition(BezierMove(controlPoints_,traveled_));
+        
+        switch (interpolationMode_)
+        {
+        case BEZIER_CURVE:
+            if (controlPoints_.Size() < 2)
+            {
+                LOGERRORF("Spline on Node[%d,%s] in Beizer Curve mode attempted with less than two control points.", GetNode()->GetID(), GetNode()->GetName().CString());
+                return;
+            }
+            GetNode()->SetPosition(BezierMove(controlPoints_, traveled_));
+            break;
+        }
 
         attached_ = true;
     }
 }
 
-void Spline::Move()
+void Spline::Move(float timeStep)
 {
-    if (!attached_ || traveled_ >= 1.0f)
+    if (!attached_ || traveled_ >= 1.0f || length_ <= 0.0f)
         return;
 
-    if (startTime_ <= -1.f)
-        startTime_ = GetSubsystem<Time>()->GetElapsedTime();
-
-    elapsedTime_ += GetSubsystem<Time>()->GetElapsedTime() - startTime_;
+    elapsedTime_ += timeStep;
 
     float distanceCovered = elapsedTime_ * speed_;
     traveled_ = distanceCovered / length_;
@@ -120,14 +143,12 @@ void Spline::Move()
 void Spline::Detach()
 {
     attached_ = false;
-    startTime_ = -1.f;
 }
 
 void Spline::Reset()
 {
     attached_ = false;
     traveled_ = 0.f;
-    startTime_ = -1.f;
     elapsedTime_ = 0.f;
 }
 
@@ -161,7 +182,7 @@ void Spline::CalculateLength()
         for (float f = 0.000f; f <= 1.000f; f += 0.001f)
         {
             Vector3 b = BezierMove(controlPoints_, f);
-            length_ += (a - b).Length();
+            length_ += Abs((a - b).Length());
             a = b;
         }
         break;

+ 3 - 3
Source/Engine/Scene/Spline.h

@@ -57,6 +57,8 @@ public:
     InterpolationMode GetInterpolationMode() const { return interpolationMode_; }
     /// Get the movement Speed.
     float GetSpeed() const { return speed_; }
+    /// Get a position on the spine from 0.f to 1.f where 0 is the start and 1 is the end.
+    Vector3 GetPosition(float factor);
 
     /// Add a Control Point to the end.
     void Push(const Vector3& controlPoint);
@@ -66,7 +68,7 @@ public:
     /// Attach the Parent to the path at the position it was at last or at the start if after Reset was called or no movement has occurred.
     void Attach();
     /// Move the parent node to the next position along the Spline based off the Speed value.
-    void Move();
+    void Move(float timeStep);
     /// Detach the Parent from the path. Movement is not reset.
     void Detach();
     /// Reset movement along the path.
@@ -92,8 +94,6 @@ private:
     /// The Speed of movement along the Spline.
     float speed_;
 
-    /// The time when movement started along the Spline.
-    float startTime_;
     /// Amount of time that has elapsed while moving.
     float elapsedTime_;
     /// The fraction of the Spline covered.

+ 2 - 1
Source/Engine/Script/SceneAPI.cpp

@@ -237,10 +237,11 @@ static void RegisterSpline(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Spline", "InterpolationMode get_interpolationMode() const", asMETHOD(Spline, GetInterpolationMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("Spline", "void set_speed(float)", asMETHOD(Spline, SetSpeed), asCALL_THISCALL);
     engine->RegisterObjectMethod("Spline", "float get_speed() const", asMETHOD(Spline, GetSpeed), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Spline", "Vector3 GetPosition(float)", asMETHOD(Spline, GetPosition), asCALL_THISCALL);
     engine->RegisterObjectMethod("Spline", "void Push(const Vector3&in)", asMETHOD(Spline, Push), asCALL_THISCALL);
     engine->RegisterObjectMethod("Spline", "void Pop()", asMETHOD(Spline, Pop), asCALL_THISCALL);
     engine->RegisterObjectMethod("Spline", "void Attach()", asMETHOD(Spline, Attach), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Spline", "void Move()", asMETHOD(Spline, Move), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Spline", "void Move(float)", asMETHOD(Spline, Move), asCALL_THISCALL);
     engine->RegisterObjectMethod("Spline", "void Detach()", asMETHOD(Spline, Detach), asCALL_THISCALL);
     engine->RegisterObjectMethod("Spline", "void Reset()", asMETHOD(Spline, Reset), asCALL_THISCALL);
     engine->RegisterObjectMethod("Spline", "bool IsFinished() const", asMETHOD(Spline, IsFinished), asCALL_THISCALL);