TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Spline.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  */
18 
19 #ifndef TRINITYSERVER_SPLINE_H
20 #define TRINITYSERVER_SPLINE_H
21 
22 #include "MovementTypedefs.h"
23 #include <G3D/Vector3.h>
24 #include <limits>
25 
26 namespace Movement {
27 
29 {
30 public:
31  typedef int index_type;
32  typedef std::vector<Vector3> ControlArray;
33 
35  {
41  };
42 
43 protected:
44  ControlArray points;
45 
46  index_type index_lo;
47  index_type index_hi;
48 
50  bool cyclic;
51 
52  enum{
53  // could be modified, affects segment length evaluation precision
54  // lesser value saves more performance in cost of lover precision
55  // minimal value is 1
56  // client's value is 20, blizzs use 2-3 steps to compute length
58  };
59  static_assert(STEPS_PER_SEGMENT > 0, "STEPS_PER_SEGMENT shouldn't be lesser than 1");
60 
61 protected:
62  void EvaluateLinear(index_type, float, Vector3&) const;
63  void EvaluateCatmullRom(index_type, float, Vector3&) const;
64  void EvaluateBezier3(index_type, float, Vector3&) const;
65  typedef void (SplineBase::*EvaluationMethtod)(index_type, float, Vector3&) const;
66  static EvaluationMethtod evaluators[ModesEnd];
67 
68  void EvaluateDerivativeLinear(index_type, float, Vector3&) const;
69  void EvaluateDerivativeCatmullRom(index_type, float, Vector3&) const;
70  void EvaluateDerivativeBezier3(index_type, float, Vector3&) const;
71  static EvaluationMethtod derivative_evaluators[ModesEnd];
72 
73  float SegLengthLinear(index_type) const;
74  float SegLengthCatmullRom(index_type) const;
75  float SegLengthBezier3(index_type) const;
76  typedef float (SplineBase::*SegLenghtMethtod)(index_type) const;
77  static SegLenghtMethtod seglengths[ModesEnd];
78 
79  void InitLinear(const Vector3*, index_type, index_type);
80  void InitCatmullRom(const Vector3*, index_type, index_type);
81  void InitBezier3(const Vector3*, index_type, index_type);
82  typedef void (SplineBase::*InitMethtod)(const Vector3*, index_type, index_type);
83  static InitMethtod initializers[ModesEnd];
84 
85  void UninitializedSpline() const { ABORT();}
86 
87 public:
88 
89  explicit SplineBase() : index_lo(0), index_hi(0), m_mode(UninitializedMode), cyclic(false) { }
90 
95  void evaluate_percent(index_type Idx, float u, Vector3& c) const {(this->*evaluators[m_mode])(Idx, u, c);}
96 
101  void evaluate_derivative(index_type Idx, float u, Vector3& hermite) const {(this->*derivative_evaluators[m_mode])(Idx, u, hermite);}
102 
104  index_type first() const { return index_lo;}
105  index_type last() const { return index_hi;}
106 
107  bool empty() const { return index_lo == index_hi;}
108  EvaluationMode mode() const { return (EvaluationMode)m_mode;}
109  bool isCyclic() const { return cyclic;}
110 
111  const ControlArray& getPoints() const { return points; }
112  index_type getPointCount() const { return index_type(points.size()); }
113  const Vector3& getPoint(index_type i) const { return points[i]; }
114 
116  void init_spline(const Vector3 * controls, index_type count, EvaluationMode m);
117  void init_cyclic_spline(const Vector3 * controls, index_type count, EvaluationMode m, index_type cyclic_point);
118 
121  template<class Init> inline void init_spline_custom(Init& initializer)
122  {
123  initializer(m_mode, cyclic, points, index_lo, index_hi);
124  }
125 
126  void clear();
127 
129  float SegLength(index_type i) const { return (this->*seglengths[m_mode])(i);}
130 
131  std::string ToString() const;
132 };
133 
134 template<typename length_type>
135 class Spline : public SplineBase
136 {
137 public:
138  typedef length_type LengthType;
139  typedef std::vector<length_type> LengthArray;
140 protected:
141 
142  LengthArray lengths;
143 
144  index_type computeIndexInBounds(length_type length) const;
145 public:
146 
147  explicit Spline(){ }
148 
151  void evaluate_percent(float t, Vector3 & c) const;
152 
155  void evaluate_derivative(float t, Vector3& hermite) const;
156 
160  void evaluate_percent(index_type Idx, float u, Vector3& c) const { SplineBase::evaluate_percent(Idx, u, c);}
161 
165  void evaluate_derivative(index_type Idx, float u, Vector3& c) const { SplineBase::evaluate_derivative(Idx, u, c);}
166 
167  // Assumes that t in range [0, 1]
168  index_type computeIndexInBounds(float t) const;
169  void computeIndex(float t, index_type& out_idx, float& out_u) const;
170 
172  void init_spline(const Vector3 * controls, index_type count, EvaluationMode m) { SplineBase::init_spline(controls, count, m);}
173  void init_cyclic_spline(const Vector3 * controls, index_type count, EvaluationMode m, index_type cyclic_point) { SplineBase::init_cyclic_spline(controls, count, m, cyclic_point);}
174 
176  void initLengths();
177 
180  template<class T> inline void initLengths(T& cacher)
181  {
182  index_type i = index_lo;
183  lengths.resize(index_hi+1);
184  length_type prev_length = 0, new_length = 0;
185  while (i < index_hi)
186  {
187  new_length = cacher(*this, i);
188  // length overflowed, assign to max positive value
189  if (new_length < 0)
191  lengths[++i] = new_length;
192 
193  ASSERT(prev_length <= new_length);
194  prev_length = new_length;
195  }
196  }
197 
199  length_type length() const { return lengths[index_hi];}
201  length_type length(index_type first, index_type last) const { return lengths[last]-lengths[first];}
202  length_type length(index_type Idx) const { return lengths[Idx];}
203 
204  void set_length(index_type i, length_type length) { lengths[i] = length;}
205  void clear();
206 };
207 
208 }
209 
210 #include "SplineImpl.h"
211 
212 #endif // TRINITYSERVER_SPLINE_H
length_type length(index_type first, index_type last) const
Definition: Spline.h:201
void init_spline(const Vector3 *controls, index_type count, EvaluationMode m)
Definition: Spline.h:172
void initLengths()
Definition: SplineImpl.h:79
void evaluate_percent(float t, Vector3 &c) const
Definition: SplineImpl.h:21
EvaluationMode
Definition: Spline.h:34
length_type LengthType
Definition: Spline.h:138
void computeIndex(float t, index_type &out_idx, float &out_u) const
Definition: SplineImpl.h:64
#define false
Definition: CascPort.h:18
void initLengths(T &cacher)
Definition: Spline.h:180
uint8 m_mode
Definition: Spline.h:49
T max(const T &x, const T &y)
Definition: g3dmath.h:320
std::vector< Vector3 > ControlArray
Definition: Spline.h:32
Definition: Vector3.h:58
Definition: Spline.h:36
LengthArray lengths
Definition: Spline.h:142
Definition: Spline.h:40
void evaluate_derivative(index_type Idx, float u, Vector3 &c) const
Definition: Spline.h:165
string ToString(int i)
Definition: strutil.h:491
Definition: Unit.h:409
length_type length() const
Definition: Spline.h:199
Definition: Spline.h:28
void evaluate_percent(index_type Idx, float u, Vector3 &c) const
Definition: Spline.h:160
void init_cyclic_spline(const Vector3 *controls, index_type count, EvaluationMode m, index_type cyclic_point)
Definition: Spline.h:173
Spline()
Definition: Spline.h:147
int index_type
Definition: Spline.h:31
index_type index_lo
Definition: Spline.h:46
ControlArray points
Definition: Spline.h:44
length_type length(index_type Idx) const
Definition: Spline.h:202
bool cyclic
Definition: Spline.h:50
index_type index_hi
Definition: Spline.h:47
Definition: Spline.h:135
void set_length(index_type i, length_type length)
Definition: Spline.h:204
#define ABORT
Definition: Errors.h:56
uint8_t uint8
Definition: Define.h:152
#define ASSERT
Definition: Errors.h:55
void clear()
Definition: SplineImpl.h:91
index_type computeIndexInBounds(length_type length) const
Definition: SplineImpl.h:37
std::vector< length_type > LengthArray
Definition: Spline.h:139
void evaluate_derivative(float t, Vector3 &hermite) const
Definition: SplineImpl.h:29