Browse Source

Separated the Spline Mathematical aspect from the Component into a new Spline class under Math. No angelscript or lua bindings as of yet as I'm unsure how to go about adding the templated class in a suitable manner.

Old Spline class has been renamed to SplinePath as is build using child nodes of its parent node. To facilitate the functionality a method has been added to Node to allows you to specify the index position of where to add the child Node as that impacts the curve.  DebugGeometry was added which shows the nodes that currently make up the SplinePath and the curve.

Added CScriptArray to PODVector convertor.
Alex Parlett 11 years ago
parent
commit
7aa0d8acc9

+ 1 - 1
Bin/Data/UI/EditorIcons.xml

@@ -127,7 +127,7 @@
         <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
         <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
         <attribute name="Image Rect" value="96 16 110 30" />
         <attribute name="Image Rect" value="96 16 110 30" />
     </element>
     </element>
-    <element type="Spline">
+    <element type="SplinePath">
         <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
         <attribute name="Texture" value="Texture2D;Textures/EditorIcons.png" />
         <attribute name="Image Rect" value="96 16 110 30" />
         <attribute name="Image Rect" value="96 16 110 30" />
     </element>
     </element>

+ 4 - 0
Source/Engine/LuaScript/pkgs/LogicLuaAPI.pkg

@@ -0,0 +1,4 @@
+$pfile "Scene/SplinePath.pkg"
+
+$using namespace Urho3D;
+$#pragma warning(disable:4800)

+ 2 - 4
Source/Engine/LuaScript/pkgs/Scene/Spline.pkg → Source/Engine/LuaScript/pkgs/Scene/SplinePath.pkg

@@ -1,11 +1,11 @@
-$#include "Spline.h"
+$#include "SplinePath.h"
 
 
 enum InterpolationMode
 enum InterpolationMode
 {
 {
     BEZIER_CURVE
     BEZIER_CURVE
 };
 };
 
 
-class Spline : public Component
+class SplinePath : public Component
 {
 {
     void SetInterpolationMode(InterpolationMode interpolationMode);
     void SetInterpolationMode(InterpolationMode interpolationMode);
     void SetSpeed(float speed);
     void SetSpeed(float speed);
@@ -15,8 +15,6 @@ class Spline : public Component
     float GetSpeed() const;
     float GetSpeed() const;
     Vector3 GetPosition() const;
     Vector3 GetPosition() const;
     
     
-    void Push(const Vector3& controlPoint);
-    void Pop();
     Vector3 GetPoint(float factor) const;    
     Vector3 GetPoint(float factor) const;    
     
     
     void Move(float timeStep);
     void Move(float timeStep);

+ 0 - 1
Source/Engine/LuaScript/pkgs/SceneLuaAPI.pkg

@@ -2,7 +2,6 @@ $pfile "Scene/Serializable.pkg"
 $pfile "Scene/Component.pkg"
 $pfile "Scene/Component.pkg"
 $pfile "Scene/Node.pkg"
 $pfile "Scene/Node.pkg"
 $pfile "Scene/Scene.pkg"
 $pfile "Scene/Scene.pkg"
-$pfile "Scene/Spline.pkg"
 
 
 $using namespace Urho3D;
 $using namespace Urho3D;
 $#pragma warning(disable:4800)
 $#pragma warning(disable:4800)

+ 40 - 0
Source/Engine/Math/Spline.cpp

@@ -0,0 +1,40 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "Precompiled.h"
+#include "Spline.h"
+
+namespace Urho3D
+{
+
+const char* interpolationModeNames[] =
+{
+    "Bezier",
+    0
+};
+
+template<> InterpolationMode Variant::Get<InterpolationMode>() const
+{
+    return (InterpolationMode) GetInt();
+}
+
+}

+ 215 - 0
Source/Engine/Math/Spline.h

@@ -0,0 +1,215 @@
+// Copyright (c) 2008-2013 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include "Variant.h"
+#include "Vector2.h"
+#include "Vector3.h"
+#include "Vector4.h"
+#include "Color.h"
+
+namespace Urho3D
+{
+
+enum InterpolationMode
+{
+    BEZIER_CURVE = 0
+};
+
+/// Spline class to get a point on it based off the interpolation mode.
+template<typename T>
+class URHO3D_API Spline
+{
+public:
+    /// Ctor.
+    Spline() :
+    interpolationMode_(BEZIER_CURVE)
+    {
+    }
+
+    /// Ctor.
+    Spline(InterpolationMode mode) :
+    interpolationMode_(mode)
+    {
+    }
+
+    /// Ctor.
+    Spline(const PODVector<T>& knots, InterpolationMode mode = BEZIER_CURVE) :
+    interpolationMode_(mode),
+    knots_(knots)
+    {
+    }
+
+    /// Ctor.
+    Spline(const Spline& rhs) :
+    interpolationMode_(rhs.interpolationMode_),
+    knots_(rhs.knots_)
+    {
+    }
+
+    /// Dtor.
+    ~Spline()
+    {
+        Clear();
+    }
+
+    /// Return the ImplementationMode.
+    InterpolationMode GetInterpolationMode() const
+    { 
+        return interpolationMode_; 
+    }
+
+    /// Return the Knots of the Spline.
+    const PODVector<T>& GetKnots() const
+    { 
+        return knots_; 
+    }
+
+    /// Return the Knot at the specific index.
+    const T GetKnot(unsigned index) const
+    {
+        return knots_[index];
+    }
+
+    /// Return the T of the point of the Spline at f from 0.f - 1.f.
+    T GetPoint(float f) const
+    {
+        if (knots_.Size() < 2)
+            return knots_.Size() == 1 ? knots_[0] : T();
+
+        if (f > 1.f)
+            f = 1.f;
+        else if (f < 0.f)
+            f = 0.f;
+
+        switch (interpolationMode_)
+        {
+        case BEZIER_CURVE:
+        default:
+            return BezierInterpolation(knots_, f);
+        }
+    }
+
+    /// Set the InterpolationMode of the Spline.
+    void SetInterpolationMode(InterpolationMode interpolationMode) 
+    { 
+        interpolationMode_ = interpolationMode; 
+    }
+
+    /// Set the Knots of the Spline.
+    void SetKnots(const PODVector<T>& knots) 
+    { 
+        knots_ = knots_; 
+    }
+
+    /// Add a Knot to the end of the Spline.
+    void AddKnot(const T& knot)
+    {
+        knots_.Push(knot);
+    }
+
+    /// Add a Knot to the Spline at a specific index.
+    void AddKnot(const T& knot, unsigned index)
+    {
+        knots_.Insert(index, knot);
+    }
+
+    /// Remove the last Knot on the Spline.
+    void RemoveKnot() 
+    { 
+        knots_.Pop(); 
+    }
+
+    /// Remove the Knot at the specific index.
+    void RemoveKnot(unsigned index)
+    {
+        knots_.Erase(index);
+    }
+
+    /// Clear the Spline.
+    void Clear()
+    {
+        knots_.Clear();
+    }
+
+private:
+    /// Perform Bezier Interpolation on the Spline.
+    T BezierInterpolation(const PODVector<T>& knots, float t) const
+    {
+        if (knots.Size() == 2)
+        {
+            return LinearInterpolation(knots[0], knots[1], t);
+        }
+        else
+        {
+            PODVector<T> interpolatedKnots;
+            for (unsigned i = 1; i < knots.Size(); i++)
+            {
+                interpolatedKnots.Push(LinearInterpolation(knots[i - 1], knots[i], t));
+            }
+            return BezierInterpolation(interpolatedKnots, t);
+        }
+    }
+
+    /// Empty LinearInterpolation for Android or IOS implementations that don't support C++11 and the static_assert.
+    T LinearInterpolation(const T& lhs, const T& rhs, float t) const
+    {
+        return T();
+    }
+
+    /// InterpolationMode.
+    InterpolationMode interpolationMode_;
+    /// Knots on the Spline.
+    PODVector<T> knots_;
+};
+
+/// Specialized LinearInterpolation for float.
+template<> float Urho3D::Spline<float>::LinearInterpolation(const float& lhs, const float& rhs, float t) const
+{
+    return Lerp(lhs, rhs, t);
+}
+
+/// Specialized LinearInterpolation for Vector2.
+template<> Vector2 Urho3D::Spline<Vector2>::LinearInterpolation(const Vector2& lhs, const Vector2& rhs, float t) const
+{
+    return lhs.Lerp(rhs, t);
+}
+
+/// Specialized LinearInterpolation for Vector3.
+template<> Vector3 Urho3D::Spline<Vector3>::LinearInterpolation(const Vector3& lhs, const Vector3& rhs, float t) const
+{
+    return lhs.Lerp(rhs, t);
+}
+
+/// Specialized LinearInterpolation for Vector4.
+template<> Vector4 Urho3D::Spline<Vector4>::LinearInterpolation(const Vector4& lhs, const Vector4& rhs, float t) const
+{
+    return lhs.Lerp(rhs, t);
+}
+
+/// Specialized LinearInterpolation for Color.
+template<> Color Urho3D::Spline<Color>::LinearInterpolation(const Color& lhs, const Color& rhs, float t) const
+{
+    return lhs.Lerp(rhs, t);
+}
+
+}

+ 11 - 1
Source/Engine/Scene/Node.cpp

@@ -534,6 +534,11 @@ Node* Node::CreateChild(const String& name, CreateMode mode, unsigned id)
 }
 }
 
 
 void Node::AddChild(Node* node)
 void Node::AddChild(Node* node)
+{
+    AddChild(node, children_.Size());
+}
+
+void Node::AddChild(Node* node, unsigned index)
 {
 {
     // Check for illegal or redundant parent assignment
     // Check for illegal or redundant parent assignment
     if (!node || node == this || node->parent_ == this)
     if (!node || node == this || node->parent_ == this)
@@ -547,8 +552,13 @@ void Node::AddChild(Node* node)
         parent = parent->parent_;
         parent = parent->parent_;
     }
     }
 
 
+    if (index < 0)
+        index = 0;
+    if (index > children_.Size())
+        index = children_.Size();
+
     // Add first, then remove from old parent, to ensure the node does not get deleted
     // Add first, then remove from old parent, to ensure the node does not get deleted
-    children_.Push(SharedPtr<Node>(node));
+    children_.Insert(index, SharedPtr<Node>(node));
     node->Remove();
     node->Remove();
 
 
     // Add to the scene if not added yet
     // Add to the scene if not added yet

+ 2 - 0
Source/Engine/Scene/Node.h

@@ -142,6 +142,8 @@ public:
     Node* CreateChild(const String& name = String::EMPTY, CreateMode mode = REPLICATED, unsigned id = 0);
     Node* CreateChild(const String& name = String::EMPTY, CreateMode mode = REPLICATED, unsigned id = 0);
     /// Add a child scene node.
     /// Add a child scene node.
     void AddChild(Node* node);
     void AddChild(Node* node);
+    /// Add a child scene node at a specific index.
+    void AddChild(Node* node, unsigned index);
     /// Remove a child scene node.
     /// Remove a child scene node.
     void RemoveChild(Node* node);
     void RemoveChild(Node* node);
     /// Remove all child scene nodes.
     /// Remove all child scene nodes.

+ 4 - 3
Source/Engine/Scene/Scene.cpp

@@ -1,5 +1,5 @@
 //
 //
-// Copyright (c) 2008-2014 the Urho3D project.
+// Copyright (c) 2008-2013 the Urho3D project.
 //
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
 // of this software and associated documentation files (the "Software"), to deal
@@ -21,6 +21,7 @@
 //
 //
 
 
 #include "Precompiled.h"
 #include "Precompiled.h"
+#include "Component.h"
 #include "Context.h"
 #include "Context.h"
 #include "CoreEvents.h"
 #include "CoreEvents.h"
 #include "File.h"
 #include "File.h"
@@ -31,8 +32,8 @@
 #include "Scene.h"
 #include "Scene.h"
 #include "SceneEvents.h"
 #include "SceneEvents.h"
 #include "SmoothedTransform.h"
 #include "SmoothedTransform.h"
-#include "Spline.h"
 #include "UnknownComponent.h"
 #include "UnknownComponent.h"
+#include "SplinePath.h"
 #include "WorkQueue.h"
 #include "WorkQueue.h"
 #include "XMLFile.h"
 #include "XMLFile.h"
 
 
@@ -962,8 +963,8 @@ void RegisterSceneLibrary(Context* context)
     Node::RegisterObject(context);
     Node::RegisterObject(context);
     Scene::RegisterObject(context);
     Scene::RegisterObject(context);
     SmoothedTransform::RegisterObject(context);
     SmoothedTransform::RegisterObject(context);
-    Spline::RegisterObject(context);
     UnknownComponent::RegisterObject(context);
     UnknownComponent::RegisterObject(context);
+    SplinePath::RegisterObject(context);
 }
 }
 
 
 }
 }

+ 0 - 228
Source/Engine/Scene/Spline.cpp

@@ -1,228 +0,0 @@
-//
-// Copyright (c) 2008-2014 the Urho3D project.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-//
-
-#include "Precompiled.h"
-#include "Context.h"
-#include "Log.h"
-#include "Node.h"
-#include "Scene.h"
-#include "Spline.h"
-
-#include "DebugNew.h"
-
-namespace Urho3D
-{
-
-extern const char* LOGIC_CATEGORY;
-
-static const char* interpolationModeNames[] =
-{
-    "Bezier",
-    0
-};
-
-Spline::Spline(Context* context) :
-    Component(context),
-    interpolationMode_(BEZIER_CURVE),
-    speed_(1.f),
-    elapsedTime_(0.f),
-    length_(0.f),
-    traveled_(0.f),
-    dirty_(false)
-{
-}
-
-void Spline::RegisterObject(Context* context)
-{
-    context->RegisterFactory<Spline>(LOGIC_CATEGORY);
-
-    ATTRIBUTE(Spline, VAR_FLOAT, "Speed", speed_, 1.f, AM_FILE);
-    ENUM_ATTRIBUTE(Spline, "Interpolation Mode", interpolationMode_, interpolationModeNames, BEZIER_CURVE, AM_FILE);
-    ATTRIBUTE(Spline, VAR_FLOAT, "Traveled", traveled_, 0.f, AM_FILE | AM_NOEDIT);
-    ATTRIBUTE(Spline, VAR_FLOAT, "Elapsed Time", elapsedTime_, 0.f, AM_FILE | AM_NOEDIT);
-    ACCESSOR_ATTRIBUTE(Spline, VAR_VARIANTVECTOR, "Control Points", GetControlPointsAttr, SetControlPointsAttr, VariantVector, Variant::emptyVariantVector, AM_FILE);
-}
-
-void Spline::SetControlPoints(const PODVector<Vector3>& controlPoints)
-{
-    controlPoints_ = controlPoints;
-
-    // We can calculate the length here because all the control points have changed so it shouldn't be too expensive.
-    CalculateLength();
-}
-
-void Spline::SetPosition(float factor)
-{
-    float t = factor;
-
-    if (t < 0.f)
-        t = 0.0f;
-    else if (t > 1.0f)
-        t = 1.0f;
-
-    traveled_ = t;
-}
-
-Vector3 Spline::GetPosition() const
-{
-    return GetPoint(traveled_);
-}
-
-Vector3 Spline::GetPoint(float factor) const
-{
-    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);
-
-    // Calculate the length at the next move so we don't recalculate the entire length multiple times if more than one control point is changed.
-    dirty_ = true;
-}
-
-void Spline::Pop()
-{
-    controlPoints_.Pop();
-
-    // Calculate the length at the next move so we don't recalculate the entire length multiple times if more than one control point is changed.
-    dirty_ = true;
-}
-
-void Spline::Move(float timeStep)
-{
-    if (dirty_)
-        CalculateLength();
-
-    if (traveled_ >= 1.0f || length_ <= 0.0f)
-        return;
-
-    elapsedTime_ += timeStep;
-
-    // Calculate where we should be on the spline based on length, speed and time. If that is less than the set traveled_ don't move till caught up.
-    float distanceCovered = elapsedTime_ * speed_;
-    traveled_ = distanceCovered / length_;
-
-    switch (interpolationMode_)
-    {
-    case BEZIER_CURVE:
-        if (controlPoints_.Size() < 2)
-        {
-            LOGERRORF("Spline on Node[%d,%s] in Bezier Curve mode attempted with less than two control points.", GetNode()->GetID(), GetNode()->GetName().CString());
-            return;
-        }
-        GetNode()->SetPosition(BezierMove(controlPoints_,traveled_));
-        break;
-    }
-}
-
-void Spline::Reset()
-{
-    traveled_ = 0.f;
-    elapsedTime_ = 0.f;
-}
-
-Urho3D::VariantVector Spline::GetControlPointsAttr() const
-{
-    VariantVector ret;
-    // Store number of points first for editing
-    ret.Push(controlPoints_.Size());
-    for (unsigned i = 0; i < controlPoints_.Size(); i++)
-        ret.Push(controlPoints_[i]);
-    return ret;
-}
-
-void Spline::SetControlPointsAttr(VariantVector value)
-{
-    controlPoints_.Clear();
-    unsigned index = 0;
-    unsigned numPoints = index < value.Size() ? value[index++].GetUInt() : 0;
-    // Prevent negative value being assigned from the editor
-    if (numPoints > M_MAX_INT)
-        numPoints = 0;
-    for (unsigned i = 0; i < numPoints; ++i)
-    {
-        Vector3 point = index < value.Size() ? value[index++].GetVector3() : Vector3::ZERO;
-        controlPoints_.Push(point);
-    }
-
-    CalculateLength();
-}
-
-void Spline::CalculateLength()
-{
-    if (dirty_)
-        dirty_ = false;
-
-    length_ = 0.f;
-
-    if (controlPoints_.Size() <= 0)
-    {
-        return;
-    }
-
-    switch (interpolationMode_)
-    {
-    case BEZIER_CURVE:
-        Vector3 a = controlPoints_[0];
-        for (float f = 0.000f; f <= 1.000f; f += 0.001f)
-        {
-            Vector3 b = BezierMove(controlPoints_, f);
-            length_ += Abs((a - b).Length());
-            a = b;
-        }
-        break;
-    }
-}
-
-Vector3 Spline::BezierMove(const PODVector<Vector3>& controlPoints, float t) const
-{
-    if (controlPoints.Size() == 2)
-    {
-        return controlPoints[0].Lerp(controlPoints[1], t);
-    }
-    else
-    {
-        PODVector<Vector3> newControlPoints;
-        for (unsigned i = 1; i < controlPoints.Size(); i++)
-        {
-            newControlPoints.Push(controlPoints[i - 1].Lerp(controlPoints[i], t));
-        }
-        return BezierMove(newControlPoints, t);
-    }
-}
-
-}

+ 218 - 0
Source/Engine/Scene/SplinePath.cpp

@@ -0,0 +1,218 @@
+//
+// Copyright (c) 2008-2013 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "Precompiled.h"
+#include "Context.h"
+#include "ForEach.h"
+#include "Log.h"
+#include "Node.h"
+#include "Scene.h"
+#include "SceneEvents.h"
+#include "SplinePath.h"
+
+namespace Urho3D
+{
+
+extern const char* interpolationModeNames[];
+extern const char* LOGIC_CATEGORY;
+
+SplinePath::SplinePath(Context* context) :
+    Component(context),
+    speed_(1.f),
+    elapsedTime_(0.f),
+    length_(0.f),
+    traveled_(0.f),
+    spline_(BEZIER_CURVE)
+{
+    SubscribeToEvent(E_SCENEPOSTUPDATE, HANDLER(SplinePath, PointsUpdated));
+}
+
+SplinePath::~SplinePath()
+{
+    UnsubscribeFromAllEvents();
+}
+
+void SplinePath::RegisterObject(Context* context)
+{
+    context->RegisterFactory<SplinePath>(LOGIC_CATEGORY);
+
+    ATTRIBUTE(SplinePath, VAR_FLOAT, "Speed", speed_, 1.f, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE(SplinePath, "Interpolation Mode", GetInterpolationMode, SetInterpolationMode, InterpolationMode, interpolationModeNames, BEZIER_CURVE, AM_FILE);
+    ATTRIBUTE(SplinePath, VAR_FLOAT, "Traveled", traveled_, 0.f, AM_FILE | AM_NOEDIT);
+    ATTRIBUTE(SplinePath, VAR_FLOAT, "Elapsed Time", elapsedTime_, 0.f, AM_FILE | AM_NOEDIT);
+}
+
+void SplinePath::ApplyAttributes()
+{
+    SubscribeToEvent(node_->GetScene(), E_NODEADDED, HANDLER(SplinePath, PointAdded));
+    SubscribeToEvent(node_->GetScene(), E_NODEREMOVED, HANDLER(SplinePath, PointRemoved));
+
+    foreach(SharedPtr<Node> child, node_->GetChildren())
+        child->AddListener(this);
+
+    UpdatePoints();
+    CalculateLength();
+}
+
+void SplinePath::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
+{
+    if (debug && node_ && IsEnabledEffective())
+    {
+        if (spline_.GetKnots().Size() > 1)
+        {
+            Vector3 a = spline_.GetPoint(0.f);
+            for (float f = 0.01f; f <= 1.0f; f = f + 0.01f)
+            {
+                Vector3 b = spline_.GetPoint(f);
+                debug->AddLine(a, b, Color::GREEN);
+                a = b;
+            }
+        }
+
+        foreach(SharedPtr<Node> node, node_->GetChildren())
+            debug->AddNode(node);
+    }
+}
+
+void SplinePath::SetInterpolationMode(InterpolationMode interpolationMode) 
+{ 
+    spline_.SetInterpolationMode(interpolationMode); 
+    dirty_ = true;
+}
+
+void SplinePath::SetPosition(float factor)
+{
+    float t = factor;
+
+    if (t < 0.f)
+        t = 0.0f;
+    else if (t > 1.0f)
+        t = 1.0f;
+
+    traveled_ = t;
+}
+
+Vector3 SplinePath::GetPosition() const
+{
+    return GetPoint(traveled_);
+}
+
+Vector3 SplinePath::GetPoint(float factor) const
+{
+    return spline_.GetPoint(factor);
+}
+
+void SplinePath::Move(float timeStep)
+{
+    if (traveled_ >= 1.0f || length_ <= 0.0f)
+        return;
+
+    elapsedTime_ += timeStep;
+
+    // Calculate where we should be on the spline based on length, speed and time. If that is less than the set traveled_ don't move till caught up.
+    float distanceCovered = elapsedTime_ * speed_;
+    traveled_ = distanceCovered / length_;
+
+    GetPoint(traveled_);
+}
+
+void SplinePath::Reset()
+{
+    traveled_ = 0.f;
+    elapsedTime_ = 0.f;
+}
+
+void SplinePath::OnMarkedDirty(Node* node)
+{
+    if (node)
+        dirty_ = true;
+}
+
+void SplinePath::OnNodeSetEnabled(Node* node)
+{
+    if (node)
+        dirty_ = true;
+}
+
+void SplinePath::CalculateLength()
+{
+    if (spline_.GetKnots().Size() <= 0)
+        return;
+
+    length_ = 0.f;
+
+    Vector3 a = spline_.GetKnot(0);
+    for (float f = 0.000f; f <= 1.000f; f += 0.001f)
+    {
+        Vector3 b = spline_.GetPoint(f);
+        length_ += Abs((a - b).Length());
+        a = b;
+    }
+}
+
+void SplinePath::PointAdded(StringHash eventType, VariantMap& eventData)
+{
+    using namespace NodeAdded;
+
+    Node* parent = static_cast<Node*>(eventData[P_PARENT].GetPtr());
+    Node* child = static_cast<Node*>(eventData[P_NODE].GetPtr());
+
+    if (child != NULL && parent != NULL && parent == node_)
+    {
+        child->AddListener(this);
+        dirty_ = true;
+    }
+}
+
+void SplinePath::PointRemoved(StringHash eventType, VariantMap& eventData)
+{
+    using namespace NodeRemoved;
+
+    Node* parent = static_cast<Node*>(eventData[P_PARENT].GetPtr());
+
+    if (parent != NULL && parent == node_)
+        dirty_ = true;
+}
+
+void SplinePath::PointsUpdated(StringHash eventType, VariantMap& eventData)
+{
+    if (dirty_)
+    {
+        UpdatePoints();
+        CalculateLength();
+
+        dirty_ = false;
+    }
+}
+
+void SplinePath::UpdatePoints()
+{
+    spline_.Clear();
+
+    foreach(SharedPtr<Node> node, node_->GetChildren())
+    {
+        if (node->IsEnabled())
+            spline_.AddKnot(node->GetWorldPosition());
+    }
+}
+
+}

+ 27 - 26
Source/Engine/Scene/Spline.h → Source/Engine/Scene/SplinePath.h

@@ -23,49 +23,45 @@
 #pragma once
 #pragma once
 
 
 #include "Component.h"
 #include "Component.h"
+#include "DebugRenderer.h"
 #include "Vector3.h"
 #include "Vector3.h"
+#include "Spline.h"
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {
-/// Interpolation Mode for a Spline.
-enum InterpolationMode
-{
-    BEZIER_CURVE = 0
-};
 
 
 /// Spline for creating smooth movement based on Speed along a set of Control Points modified by the Interpolation Mode.
 /// Spline for creating smooth movement based on Speed along a set of Control Points modified by the Interpolation Mode.
-class URHO3D_API Spline : public Component
+class URHO3D_API SplinePath : public Component
 {
 {
-    OBJECT(Spline)
+    OBJECT(SplinePath)
 
 
 public:
 public:
     /// Construct an Empty Spline.
     /// Construct an Empty Spline.
-    Spline(Context* context);
+    SplinePath(Context* context);
+    /// Destructor.
+    virtual ~SplinePath();
     /// Register object factory.
     /// Register object factory.
     static void RegisterObject(Context* context);
     static void RegisterObject(Context* context);
 
 
-    /// Set the Control Points from an already defined set.
-    void SetControlPoints(const PODVector<Vector3>& controlPoints);
+    /// Apply Attributes to the Node.
+    virtual void ApplyAttributes();
+    /// Draw the Debug Geometry.
+    virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
+
     /// Set the Interpolation Mode.
     /// Set the Interpolation Mode.
-    void SetInterpolationMode(InterpolationMode interpolationMode) { interpolationMode_ = interpolationMode; }
+    void SetInterpolationMode(InterpolationMode interpolationMode);
     /// Set the movement Speed.
     /// Set the movement Speed.
     void SetSpeed(float speed) { speed_ = speed; }
     void SetSpeed(float speed) { speed_ = speed; }
     /// Set the parent node's position on the Spline.
     /// Set the parent node's position on the Spline.
     void SetPosition(float factor);
     void SetPosition(float factor);
 
 
-    /// Get the Control Points.
-    const PODVector<Vector3>& GetControlPoints() const { return controlPoints_; }
     /// Get the Interpolation Mode.
     /// Get the Interpolation Mode.
-    InterpolationMode GetInterpolationMode() const { return interpolationMode_; }
+    InterpolationMode GetInterpolationMode() const { return spline_.GetInterpolationMode(); }
     /// Get the movement Speed.
     /// Get the movement Speed.
     float GetSpeed() const { return speed_; }
     float GetSpeed() const { return speed_; }
     /// Get the parent node's last position on the spline.
     /// Get the parent node's last position on the spline.
     Vector3 GetPosition() const;
     Vector3 GetPosition() const;
 
 
-    /// Add a Control Point to the end.
-    void Push(const Vector3& controlPoint);
-    /// Remove a Control Point from the end.
-    void Pop();
     /// Get a point on the spline from 0.f to 1.f where 0 is the start and 1 is the end.
     /// Get a point on the spline from 0.f to 1.f where 0 is the start and 1 is the end.
     Vector3 GetPoint(float factor) const;
     Vector3 GetPoint(float factor) const;
 
 
@@ -76,19 +72,24 @@ public:
     /// Returns whether the movement along the Spline complete.
     /// Returns whether the movement along the Spline complete.
     bool IsFinished() const { return traveled_ >= 1.0f; }
     bool IsFinished() const { return traveled_ >= 1.0f; }
 
 
-    VariantVector GetControlPointsAttr() const;
-    void SetControlPointsAttr(VariantVector value);
+protected:
+    virtual void OnMarkedDirty(Node* node);
+    virtual void OnNodeSetEnabled(Node* node);
 
 
 private:
 private:
     /// Calculate the length of the Spline. Used for movement calculations.
     /// Calculate the length of the Spline. Used for movement calculations.
     void CalculateLength();
     void CalculateLength();
-    /// Move the parent node along the Spline in Bezier Mode.
-    Vector3 BezierMove(const PODVector<Vector3>& controlPoints, float t) const;
+    /// Handle Points Changed.
+    void PointAdded(StringHash eventType, VariantMap& eventData);
+    /// Handle Points Changed.
+    void PointRemoved(StringHash eventType, VariantMap& eventData);
+    /// Handle Points Changed.
+    void PointsUpdated(StringHash eventType, VariantMap& eventData);
+    /// Update the Point Set
+    void UpdatePoints();
 
 
     /// The Control Points of the Spline.
     /// The Control Points of the Spline.
-    PODVector<Vector3> controlPoints_;
-    /// The Interpolation Mode of the Spline.
-    InterpolationMode interpolationMode_;
+    Spline<Vector3> spline_;
     /// The Speed of movement along the Spline.
     /// The Speed of movement along the Spline.
     float speed_;
     float speed_;
 
 
@@ -98,7 +99,7 @@ private:
     float traveled_;
     float traveled_;
     /// The length of the Spline.
     /// The length of the Spline.
     float length_;
     float length_;
-    /// Whether the length needs to be recalculated. Will only be true after a push or pop.
+    /// Whether the Spline has changed.
     bool dirty_;
     bool dirty_;
 };
 };
 }
 }

+ 14 - 1
Source/Engine/Script/APITemplates.h

@@ -212,6 +212,18 @@ template <class T> Vector<T> ArrayToVector(CScriptArray* arr)
     return dest;
     return dest;
 }
 }
 
 
+/// Template function for array to PODVector conversion.
+template <class T> PODVector<T> ArraytoPODVector(CScriptArray* arr)
+{
+    PODVector<T> dest(arr ? arr->GetSize() : 0);
+    if (arr)
+    {
+        for (unsigned i = 0; i < arr->GetSize(); ++i)
+            dest[i] = *static_cast<T*>(arr->At(i));
+    }
+    return dest;
+}
+
 /// Template function for registering implicit casts between base and subclass.
 /// Template function for registering implicit casts between base and subclass.
 template <class T, class U> void RegisterSubclass(asIScriptEngine* engine, const char* classNameT, const char* classNameU)
 template <class T, class U> void RegisterSubclass(asIScriptEngine* engine, const char* classNameT, const char* classNameU)
 {
 {
@@ -590,7 +602,8 @@ template <class T> void RegisterNode(asIScriptEngine* engine, const char* classN
     engine->RegisterObjectMethod(className, "void Scale(float)", asMETHODPR(T, Scale, (float), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void Scale(float)", asMETHODPR(T, Scale, (float), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void Scale(const Vector3&in)", asMETHODPR(T, Scale, (const Vector3&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void Scale(const Vector3&in)", asMETHODPR(T, Scale, (const Vector3&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "Node@+ CreateChild(const String&in name = String(), CreateMode mode = REPLICATED, uint id = 0)", asMETHODPR(T, CreateChild, (const String&, CreateMode, unsigned), Node*), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "Node@+ CreateChild(const String&in name = String(), CreateMode mode = REPLICATED, uint id = 0)", asMETHODPR(T, CreateChild, (const String&, CreateMode, unsigned), Node*), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "void AddChild(Node@+)", asMETHOD(T, AddChild), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void AddChild(Node@+)", asMETHODPR(T, AddChild, (Node*), void), asCALL_THISCALL);
+    engine->RegisterObjectMethod(className, "void AddChild(Node@+, uint)", asMETHODPR(T, AddChild, (Node*, unsigned), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void RemoveChild(Node@+)", asMETHODPR(T, RemoveChild, (Node*), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void RemoveChild(Node@+)", asMETHODPR(T, RemoveChild, (Node*), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void RemoveAllChildren()", asMETHOD(T, RemoveAllChildren), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void RemoveAllChildren()", asMETHOD(T, RemoveAllChildren), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void RemoveChildren(bool, bool, bool)", asMETHOD(T, RemoveChildren), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void RemoveChildren(bool, bool, bool)", asMETHOD(T, RemoveChildren), asCALL_THISCALL);

+ 50 - 0
Source/Engine/Script/LogicAPI.cpp

@@ -0,0 +1,50 @@
+//
+// Copyright (c) 2008-2014 the Urho3D project.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#include "Precompiled.h"
+#include "APITemplates.h"
+#include "SplinePath.h"
+
+namespace Urho3D
+{
+
+static void RegisterSplinePath(asIScriptEngine* engine)
+{
+    RegisterComponent<SplinePath>(engine, "SplinePath");
+    engine->RegisterObjectMethod("SplinePath", "void set_interpolationMode(InterpolationMode)", asMETHOD(SplinePath, SetInterpolationMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("SplinePath", "InterpolationMode get_interpolationMode() const", asMETHOD(SplinePath, GetInterpolationMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("SplinePath", "void set_speed(float)", asMETHOD(SplinePath, SetSpeed), asCALL_THISCALL);
+    engine->RegisterObjectMethod("SplinePath", "float get_speed() const", asMETHOD(SplinePath, GetSpeed), asCALL_THISCALL);
+    engine->RegisterObjectMethod("SplinePath", "void set_position(float)", asMETHOD(SplinePath, SetPosition), asCALL_THISCALL);
+    engine->RegisterObjectMethod("SplinePath", "Vector3 get_position() const", asMETHOD(SplinePath, GetPosition), asCALL_THISCALL);
+    engine->RegisterObjectMethod("SplinePath", "Vector3 GetPoint(float) const", asMETHOD(SplinePath, GetPoint), asCALL_THISCALL);
+    engine->RegisterObjectMethod("SplinePath", "void Move(float)", asMETHOD(SplinePath, Move), asCALL_THISCALL);
+    engine->RegisterObjectMethod("SplinePath", "void Reset()", asMETHOD(SplinePath, Reset), asCALL_THISCALL);
+    engine->RegisterObjectMethod("SplinePath", "bool get_finished() const", asMETHOD(SplinePath, IsFinished), asCALL_THISCALL);
+}
+
+
+void RegisterLogicAPI(asIScriptEngine* engine)
+{
+    RegisterSplinePath(engine);
+}
+}

+ 8 - 0
Source/Engine/Script/MathAPI.cpp

@@ -26,6 +26,7 @@
 #include "Frustum.h"
 #include "Frustum.h"
 #include "Polyhedron.h"
 #include "Polyhedron.h"
 #include "Ray.h"
 #include "Ray.h"
+#include "Spline.h"
 
 
 #include <angelscript.h>
 #include <angelscript.h>
 
 
@@ -1149,6 +1150,12 @@ static void RegisterColor(asIScriptEngine* engine)
     engine->RegisterObjectProperty("Color", "float a", offsetof(Color, a_));
     engine->RegisterObjectProperty("Color", "float a", offsetof(Color, a_));
 }
 }
 
 
+static void RegisterSpline(asIScriptEngine* engine)
+{
+    engine->RegisterEnum("InterpolationMode");
+    engine->RegisterEnumValue("InterpolationMode", "BEZIER_CURVE", BEZIER_CURVE);
+}
+
 void RegisterMathAPI(asIScriptEngine* engine)
 void RegisterMathAPI(asIScriptEngine* engine)
 {
 {
     RegisterMathFunctions(engine);
     RegisterMathFunctions(engine);
@@ -1166,6 +1173,7 @@ void RegisterMathAPI(asIScriptEngine* engine)
     RegisterPlane(engine);
     RegisterPlane(engine);
     RegisterRay(engine);
     RegisterRay(engine);
     RegisterColor(engine);
     RegisterColor(engine);
+    RegisterSpline(engine);
 }
 }
 
 
 }
 }

+ 0 - 24
Source/Engine/Script/SceneAPI.cpp

@@ -26,7 +26,6 @@
 #include "Scene.h"
 #include "Scene.h"
 #include "SmoothedTransform.h"
 #include "SmoothedTransform.h"
 #include "Sort.h"
 #include "Sort.h"
-#include "Spline.h"
 
 
 namespace Urho3D
 namespace Urho3D
 {
 {
@@ -225,35 +224,12 @@ static void RegisterScene(asIScriptEngine* engine)
     engine->RegisterGlobalFunction("Array<String>@ GetObjectsByCategory(const String&in)", asFUNCTION(GetObjectsByCategory), asCALL_CDECL);
     engine->RegisterGlobalFunction("Array<String>@ GetObjectsByCategory(const String&in)", asFUNCTION(GetObjectsByCategory), asCALL_CDECL);
 }
 }
 
 
-static void RegisterSpline(asIScriptEngine* engine)
-{
-    engine->RegisterEnum("InterpolationMode");
-    engine->RegisterEnumValue("InterpolationMode", "BEZIER_CURVE", BEZIER_CURVE);
-
-    RegisterComponent<Spline>(engine, "Spline", true, false);
-    engine->RegisterObjectMethod("Spline", "void set_controlPoints(Array<Vector3>@+)", asMETHOD(Spline, SetControlPoints), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Spline", "Array<Vector3>@ get_controlPoints() const", asMETHOD(Spline, GetControlPoints), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Spline", "void set_interpolationMode(InterpolationMode)", asMETHOD(Spline, SetInterpolationMode), asCALL_THISCALL);
-    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", "void set_position(float)", asMETHOD(Spline, SetPosition), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Spline", "Vector3 get_position() const", 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", "Vector3 GetPoint(float) const", asMETHOD(Spline, GetPoint), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Spline", "void Move(float)", asMETHOD(Spline, Move), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Spline", "void Reset()", asMETHOD(Spline, Reset), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Spline", "bool get_finished() const", asMETHOD(Spline, IsFinished), asCALL_THISCALL);
-}
-
 void RegisterSceneAPI(asIScriptEngine* engine)
 void RegisterSceneAPI(asIScriptEngine* engine)
 {
 {
     RegisterSerializable(engine);
     RegisterSerializable(engine);
     RegisterNode(engine);
     RegisterNode(engine);
     RegisterSmoothedTransform(engine);
     RegisterSmoothedTransform(engine);
     RegisterScene(engine);
     RegisterScene(engine);
-    RegisterSpline(engine);
 }
 }
 
 
 }
 }

+ 1 - 0
Source/Engine/Script/Script.cpp

@@ -194,6 +194,7 @@ Script::Script(Context* context) :
     RegisterNetworkAPI(scriptEngine_);
     RegisterNetworkAPI(scriptEngine_);
     RegisterPhysicsAPI(scriptEngine_);
     RegisterPhysicsAPI(scriptEngine_);
     RegisterNavigationAPI(scriptEngine_);
     RegisterNavigationAPI(scriptEngine_);
+    RegisterLogicAPI(scriptEngine_);
     RegisterUrho2DAPI(scriptEngine_);
     RegisterUrho2DAPI(scriptEngine_);
     RegisterScriptAPI(scriptEngine_);
     RegisterScriptAPI(scriptEngine_);
     RegisterEngineAPI(scriptEngine_);
     RegisterEngineAPI(scriptEngine_);

+ 2 - 0
Source/Engine/Script/ScriptAPI.h

@@ -53,6 +53,8 @@ void RegisterNetworkAPI(asIScriptEngine* engine);
 void RegisterPhysicsAPI(asIScriptEngine* engine);
 void RegisterPhysicsAPI(asIScriptEngine* engine);
 /// Register the Navigation library to script.
 /// Register the Navigation library to script.
 void RegisterNavigationAPI(asIScriptEngine* engine);
 void RegisterNavigationAPI(asIScriptEngine* engine);
+/// Register the Logic library to script.
+void RegisterLogicAPI(asIScriptEngine* engine);
 /// Register the Urho2D library to script.
 /// Register the Urho2D library to script.
 void RegisterUrho2DAPI(asIScriptEngine* engine);
 void RegisterUrho2DAPI(asIScriptEngine* engine);
 /// Register the Script library to script.
 /// Register the Script library to script.