1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #pragma once
24 
25 #include "../Container/Ptr.h"
26 #include "../Core/Variant.h"
27 #include "../Container/Vector.h"
28 #include "../Core/Spline.h"
29 #include "../Graphics/DebugRenderer.h"
30 #include "../Math/MathDefs.h"
31 #include "../Math/Vector3.h"
32 #include "../Scene/Component.h"
33 #include "../Scene/Node.h"
34 
35 namespace Urho3D
36 {
37 
38 /// Spline for creating smooth movement based on Speed along a set of Control Points modified by the Interpolation Mode.
39 class URHO3D_API SplinePath : public Component
40 {
41     URHO3D_OBJECT(SplinePath, Component)
42 
43 public:
44     /// Construct an Empty SplinePath.
45     SplinePath(Context* context);
46 
47     /// Destructor.
~SplinePath()48     virtual ~SplinePath() { };
49     /// Register object factory.
50     static void RegisterObject(Context* context);
51 
52     /// Apply Attributes to the SplinePath.
53     virtual void ApplyAttributes();
54     /// Draw the Debug Geometry.
55     virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
56 
57     /// Add a Node to the SplinePath as a Control Point.
58     void AddControlPoint(Node* point, unsigned index = M_MAX_UNSIGNED);
59     /// Remove a Node Control Point from the SplinePath.
60     void RemoveControlPoint(Node* point);
61     /// Clear the Control Points from the SplinePath.
62     void ClearControlPoints();
63 
64     /// Set the Interpolation Mode.
65     void SetInterpolationMode(InterpolationMode interpolationMode);
66 
67     /// Set the movement Speed.
SetSpeed(float speed)68     void SetSpeed(float speed) { speed_ = speed; }
69 
70     /// Set the controlled Node's position on the SplinePath.
71     void SetPosition(float factor);
72     /// Set the Node to be moved along the SplinePath.
73     void SetControlledNode(Node* controlled);
74 
75     /// Get the Interpolation Mode.
GetInterpolationMode()76     InterpolationMode GetInterpolationMode() const { return spline_.GetInterpolationMode(); }
77 
78     /// Get the movement Speed.
GetSpeed()79     float GetSpeed() const { return speed_; }
80 
81     /// Get the length of SplinePath;
GetLength()82     float GetLength() const { return length_; }
83 
84     /// Get the parent Node's last position on the spline.
GetPosition()85     Vector3 GetPosition() const { return GetPoint(traveled_); }
86 
87     /// Get the controlled Node.
GetControlledNode()88     Node* GetControlledNode() const { return controlledNode_; }
89 
90     /// Get a point on the SplinePath from 0.f to 1.f where 0 is the start and 1 is the end.
91     Vector3 GetPoint(float factor) const;
92 
93     /// Move the controlled Node to the next position along the SplinePath based off the Speed value.
94     void Move(float timeStep);
95     /// Reset movement along the path.
96     void Reset();
97 
98     /// Returns whether the movement along the SplinePath is complete.
IsFinished()99     bool IsFinished() const { return traveled_ >= 1.0f; }
100 
101     /// Set Control Point Node IDs attribute.
102     void SetControlPointIdsAttr(const VariantVector& value);
103 
104     /// Return Control Point Node IDs attribute.
GetControlPointIdsAttr()105     const VariantVector& GetControlPointIdsAttr() const { return controlPointIdsAttr_; }
106 
107     /// Set Controlled Node ID attribute.
108     void SetControlledIdAttr(unsigned value);
109 
110     /// Get Controlled Node ID attribute.
GetControlledIdAttr()111     unsigned GetControlledIdAttr() const { return controlledIdAttr_; }
112 
113 protected:
114     /// Listener to manage Control Point movement.
115     virtual void OnMarkedDirty(Node* point);
116     /// Listener to manage Control Point enabling.
117     virtual void OnNodeSetEnabled(Node* point);
118 
119 private:
120     /// Update the Node IDs of the Control Points.
121     void UpdateNodeIds();
122     /// Calculate the length of the SplinePath. Used for movement calculations.
123     void CalculateLength();
124 
125     /// The Control Points of the Spline.
126     Spline spline_;
127     /// The Speed of movement along the Spline.
128     float speed_;
129     /// Amount of time that has elapsed while moving.
130     float elapsedTime_;
131     /// The fraction of the SplinePath covered.
132     float traveled_;
133     /// The length of the SplinePath.
134     float length_;
135     /// Whether the Control Point IDs are dirty.
136     bool dirty_;
137     /// Node to be moved along the SplinePath.
138     WeakPtr<Node> controlledNode_;
139     /// Control Points for the SplinePath.
140     Vector<WeakPtr<Node> > controlPoints_;
141     /// Control Point ID's for the SplinePath.
142     mutable VariantVector controlPointIdsAttr_;
143     /// Controlled ID for the SplinePath.
144     mutable unsigned controlledIdAttr_;
145 };
146 }
147