TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
G3D::SplineBase Class Reference

#include <Spline.h>

Public Member Functions

 SplineBase ()
 
virtual ~SplineBase ()
 
float getFinalInterval () const
 
float duration () const
 
void computeIndex (float s, int &i, float &u) const
 

Static Public Member Functions

static Matrix4 computeBasis ()
 

Public Attributes

Array< float > time
 
SplineExtrapolationMode extrapolationMode
 
float finalInterval
 
SplineInterpolationMode interpolationMode
 

Protected Member Functions

void computeIndexInBounds (float s, int &i, float &u) const
 

Detailed Description

Common implementation code for all G3D::Spline template parameters

Constructor & Destructor Documentation

G3D::SplineBase::SplineBase ( )
inline
46  :
48  finalInterval(-1),
SplineExtrapolationMode extrapolationMode
Definition: Spline.h:33
Definition: SplineExtrapolationMode.h:67
float finalInterval
Definition: Spline.h:42
Definition: SplineExtrapolationMode.h:34
SplineInterpolationMode interpolationMode
Definition: Spline.h:44
virtual G3D::SplineBase::~SplineBase ( )
inlinevirtual
51 {}

Member Function Documentation

Matrix4 G3D::SplineBase::computeBasis ( )
static

Computes the derivative spline basis from the control point version.

22  {
23  // The standard Catmull-Rom spline basis (e.g., Watt & Watt p108)
24  // is for [u^3 u^2 u^1 u^0] * B * [p[0] p[1] p[2] p[3]]^T.
25  // We need a basis formed for:
26  //
27  // U * C * [2*p'[1] p[1] p[2] 2*p'[2]]^T
28  //
29  // U * C * [p2-p0 p1 p2 p3-p1]^T
30  //
31  // To make this transformation, compute the differences of columns in C:
32  // For [p0 p1 p2 p3]
33  Matrix4 basis =
34  Matrix4( -1, 3, -3, 1,
35  2, -5, 4, -1,
36  -1, 0, 1, 0,
37  0, 2, 0, 0) * 0.5f;
38 
39  // For [-p0 p1 p2 p3]^T
40  basis.setColumn(0, -basis.column(0));
41 
42  // For [-p0 p1 p2 p3-p1]^T
43  basis.setColumn(1, basis.column(1) + basis.column(3));
44 
45  // For [p2-p0 p1 p2 p3-p1]^T
46  basis.setColumn(2, basis.column(2) - basis.column(0));
47 
48  return basis;
49 }

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::SplineBase::computeIndex ( float  s,
int &  i,
float &  u 
) const

Given a time s, finds i and 0 <= u < 1 such that s = time[i] * u + time[i + 1] * (1 - u). Note that i may be outside the bounds of the time and control arrays; use getControl to handle wraparound and extrapolation issues.

This function takes expected O(1) time for control points with uniform time sampled control points or for uniformly distributed random time samples, but may take O( log time.size() ) time in the worst case.

Called from evaluate().

90  {
91  int N = time.size();
92  debugAssertM(N > 0, "No control points");
93  float t0 = time[0];
94  float tn = time[N - 1];
95 
96  if (N < 2) {
97  // No control points to work with
98  i = 0;
99  u = 0.0;
101  float fi = getFinalInterval();
102 
103  // Cyclic spline
104  if ((s < t0) || (s >= tn + fi)) {
105  // Cyclic, off the bottom or top
106 
107  // Compute offset and reduce to the in-bounds case
108 
109  float d = duration();
110  // Number of times we wrapped around the cyclic array
111  int wraps = iFloor((s - t0) / d);
112 
113  debugAssert(s - d * wraps >= t0);
114  debugAssert(s - d * wraps < tn + getFinalInterval());
115 
116  computeIndex(s - d * wraps, i, u);
117  i += wraps * N;
118 
119  } else if (s >= tn) {
120  debugAssert(s < tn + fi);
121  // Cyclic, off the top but before the end of the last interval
122  i = N - 1;
123  u = (s - tn) / fi;
124 
125  } else {
126  // Cyclic, in bounds
127  computeIndexInBounds(s, i, u);
128  }
129 
130  } else {
131  // Non-cyclic
132 
133  if (s < t0) {
134  // Non-cyclic, off the bottom. Assume points are spaced
135  // following the first time interval.
136 
137  float dt = time[1] - t0;
138  float x = (s - t0) / dt;
139  i = iFloor(x);
140  u = x - i;
141 
142  } else if (s >= tn) {
143  // Non-cyclic, off the top. Assume points are spaced following
144  // the last time interval.
145 
146  float dt = tn - time[N - 2];
147  float x = N - 1 + (s - tn) / dt;
148  i = iFloor(x);
149  u = x - i;
150 
151  } else {
152  // In bounds, non-cyclic. Assume a regular
153  // distribution (which gives O(1) for uniform spacing)
154  // and then binary search to handle the general case
155  // efficiently.
156  computeIndexInBounds(s, i, u);
157 
158  } // if in bounds
159  } // extrapolation Mode
160 }
void computeIndex(float s, int &i, float &u) const
Definition: SplineBase.cpp:90
void computeIndexInBounds(float s, int &i, float &u) const
Definition: SplineBase.cpp:61
SplineExtrapolationMode extrapolationMode
Definition: Spline.h:33
Definition: SplineExtrapolationMode.h:34
int iFloor(double fValue)
Definition: g3dmath.h:603
Array< float > time
Definition: Spline.h:26
#define debugAssertM(exp, message)
Definition: debugAssert.h:161
float getFinalInterval() const
Definition: SplineBase.cpp:6
#define debugAssert(exp)
Definition: debugAssert.h:160
int size() const
Definition: Array.h:430
float duration() const
Definition: SplineBase.cpp:52
G3D::int16 x
Definition: Vector2int16.h:37

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void G3D::SplineBase::computeIndexInBounds ( float  s,
int &  i,
float &  u 
) const
protected

Assumes that t0 <= s < tn. called by computeIndex.

61  {
62  int N = time.size();
63  float t0 = time[0];
64  float tn = time[N - 1];
65 
66  i = iFloor((N - 1) * (s - t0) / (tn - t0));
67 
68  // Inclusive bounds for binary search
69  int hi = N - 1;
70  int lo = 0;
71 
72  while ((time[i] > s) || (time[i + 1] <= s)) {
73 
74  if (time[i] > s) {
75  // too big
76  hi = i - 1;
77  } else if (time[i + 1] <= s) {
78  // too small
79  lo = i + 1;
80  }
81 
82  i = (hi + lo) / 2;
83  }
84 
85  // Having exited the above loop, i must be correct, so compute u.
86  u = (s - time[i]) / (time[i + 1] - time[i]);
87 }
int iFloor(double fValue)
Definition: g3dmath.h:603
Array< float > time
Definition: Spline.h:26
int size() const
Definition: Array.h:430

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float G3D::SplineBase::duration ( ) const

Returns the amount of time covered by this spline in one period. For a cyclic spline, this contains the final interval.

52  {
53  if (time.size() == 0) {
54  return 0;
55  } else {
56  return time.last() - time[0] + getFinalInterval();
57  }
58 }
const T & last() const
Definition: Array.h:923
Array< float > time
Definition: Spline.h:26
float getFinalInterval() const
Definition: SplineBase.cpp:6
int size() const
Definition: Array.h:430

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float G3D::SplineBase::getFinalInterval ( ) const

See specification for Spline::finalInterval; this handles the non-positive case. Returns 0 if not cyclic.

6  {
8  return 0;
9  } else if (finalInterval <= 0) {
10  int N = time.size();
11  if (N >= 2) {
12  return (time[1] - time[0] + time[N - 1] - time[N - 2]) * 0.5f;
13  } else {
14  return 1.0f;
15  }
16  } else {
17  return finalInterval;
18  }
19 }
SplineExtrapolationMode extrapolationMode
Definition: Spline.h:33
float finalInterval
Definition: Spline.h:42
Definition: SplineExtrapolationMode.h:34
Array< float > time
Definition: Spline.h:26
int size() const
Definition: Array.h:430

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

SplineExtrapolationMode G3D::SplineBase::extrapolationMode

If CYCLIC, then the control points will be assumed to wrap around. If LINEAR, then the tangents at the ends of the spline point to the final control points. If CONSTANT, the end control points will be treated as multiple contol points (so the value remains constant at the ends)

float G3D::SplineBase::finalInterval

For a cyclic spline, this is the time elapsed between the last control point and the first. If less than or equal to zero this is assumed to be:

(time[0] - time[1] + . time[time.size() - 1] - time[time.size() - 2]) / 2.

SplineInterpolationMode G3D::SplineBase::interpolationMode
Array<float> G3D::SplineBase::time

Times at which control points occur. Must have the same number of elements as Spline::control.


The documentation for this class was generated from the following files: