doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Curve.h
Go to the documentation of this file.
1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #ifndef __MATH_CURVE_H__
30 #define __MATH_CURVE_H__
31 
32 /*
33 ===============================================================================
34 
35  Curve base template.
36 
37 ===============================================================================
38 */
39 
40 template< class type >
41 class idCurve {
42 public:
43  idCurve( void );
44  virtual ~idCurve( void );
45 
46  virtual int AddValue( const float time, const type &value );
47  virtual void RemoveIndex( const int index ) { values.RemoveIndex(index); times.RemoveIndex(index); changed = true; }
48  virtual void Clear( void ) { values.Clear(); times.Clear(); currentIndex = -1; changed = true; }
49 
50  virtual type GetCurrentValue( const float time ) const;
51  virtual type GetCurrentFirstDerivative( const float time ) const;
52  virtual type GetCurrentSecondDerivative( const float time ) const;
53 
54  virtual bool IsDone( const float time ) const;
55 
56  int GetNumValues( void ) const { return values.Num(); }
57  void SetValue( const int index, const type &value ) { values[index] = value; changed = true; }
58  type GetValue( const int index ) const { return values[index]; }
59  type * GetValueAddress( const int index ) { return &values[index]; }
60  float GetTime( const int index ) const { return times[index]; }
61 
62  float GetLengthForTime( const float time ) const;
63  float GetTimeForLength( const float length, const float epsilon = 0.1f ) const;
64  float GetLengthBetweenKnots( const int i0, const int i1 ) const;
65 
66  void MakeUniform( const float totalTime );
67  void SetConstantSpeed( const float totalTime );
68  void ShiftTime( const float deltaTime );
69  void Translate( const type &translation );
70 
71 protected:
72 
73  idList<float> times; // knots
74  idList<type> values; // knot values
75 
76  mutable int currentIndex; // cached index for fast lookup
77  mutable bool changed; // set whenever the curve changes
78 
79  int IndexForTime( const float time ) const;
80  float TimeForIndex( const int index ) const;
81  type ValueForIndex( const int index ) const;
82 
83  float GetSpeed( const float time ) const;
84  float RombergIntegral( const float t0, const float t1, const int order ) const;
85 };
86 
87 /*
88 ====================
89 idCurve::idCurve
90 ====================
91 */
92 template< class type >
93 ID_INLINE idCurve<type>::idCurve( void ) {
94  currentIndex = -1;
95  changed = false;
96 }
97 
98 /*
99 ====================
100 idCurve::~idCurve
101 ====================
102 */
103 template< class type >
104 ID_INLINE idCurve<type>::~idCurve( void ) {
105 }
106 
107 /*
108 ====================
109 idCurve::AddValue
110 
111  add a timed/value pair to the spline
112  returns the index to the inserted pair
113 ====================
114 */
115 template< class type >
116 ID_INLINE int idCurve<type>::AddValue( const float time, const type &value ) {
117  int i;
118 
119  i = IndexForTime( time );
120  times.Insert( time, i );
121  values.Insert( value, i );
122  changed = true;
123  return i;
124 }
125 
126 /*
127 ====================
128 idCurve::GetCurrentValue
129 
130  get the value for the given time
131 ====================
132 */
133 template< class type >
134 ID_INLINE type idCurve<type>::GetCurrentValue( const float time ) const {
135  int i;
136 
137  i = IndexForTime( time );
138  if ( i >= values.Num() ) {
139  return values[values.Num() - 1];
140  } else {
141  return values[i];
142  }
143 }
144 
145 /*
146 ====================
147 idCurve::GetCurrentFirstDerivative
148 
149  get the first derivative for the given time
150 ====================
151 */
152 template< class type >
153 ID_INLINE type idCurve<type>::GetCurrentFirstDerivative( const float time ) const {
154  return ( values[0] - values[0] );
155 }
156 
157 /*
158 ====================
159 idCurve::GetCurrentSecondDerivative
160 
161  get the second derivative for the given time
162 ====================
163 */
164 template< class type >
165 ID_INLINE type idCurve<type>::GetCurrentSecondDerivative( const float time ) const {
166  return ( values[0] - values[0] );
167 }
168 
169 /*
170 ====================
171 idCurve::IsDone
172 ====================
173 */
174 template< class type >
175 ID_INLINE bool idCurve<type>::IsDone( const float time ) const {
176  return ( time >= times[ times.Num() - 1 ] );
177 }
178 
179 /*
180 ====================
181 idCurve::GetSpeed
182 ====================
183 */
184 template< class type >
185 ID_INLINE float idCurve<type>::GetSpeed( const float time ) const {
186  int i;
187  float speed;
188  type value;
189 
190  value = GetCurrentFirstDerivative( time );
191  for ( speed = 0.0f, i = 0; i < value.GetDimension(); i++ ) {
192  speed += value[i] * value[i];
193  }
194  return idMath::Sqrt( speed );
195 }
196 
197 /*
198 ====================
199 idCurve::RombergIntegral
200 ====================
201 */
202 template< class type >
203 ID_INLINE float idCurve<type>::RombergIntegral( const float t0, const float t1, const int order ) const {
204  int i, j, k, m, n;
205  float sum, delta;
206  float *temp[2];
207 
208  temp[0] = (float *) _alloca16( order * sizeof( float ) );
209  temp[1] = (float *) _alloca16( order * sizeof( float ) );
210 
211  delta = t1 - t0;
212  temp[0][0] = 0.5f * delta * ( GetSpeed( t0 ) + GetSpeed( t1 ) );
213 
214  for ( i = 2, m = 1; i <= order; i++, m *= 2, delta *= 0.5f ) {
215 
216  // approximate using the trapezoid rule
217  sum = 0.0f;
218  for ( j = 1; j <= m; j++ ) {
219  sum += GetSpeed( t0 + delta * ( j - 0.5f ) );
220  }
221 
222  // Richardson extrapolation
223  temp[1][0] = 0.5f * ( temp[0][0] + delta * sum );
224  for ( k = 1, n = 4; k < i; k++, n *= 4 ) {
225  temp[1][k] = ( n * temp[1][k-1] - temp[0][k-1] ) / ( n - 1 );
226  }
227 
228  for ( j = 0; j < i; j++ ) {
229  temp[0][j] = temp[1][j];
230  }
231  }
232  return temp[0][order-1];
233 }
234 
235 /*
236 ====================
237 idCurve::GetLengthBetweenKnots
238 ====================
239 */
240 template< class type >
241 ID_INLINE float idCurve<type>::GetLengthBetweenKnots( const int i0, const int i1 ) const {
242  float length = 0.0f;
243  for ( int i = i0; i < i1; i++ ) {
244  length += RombergIntegral( times[i], times[i+1], 5 );
245  }
246  return length;
247 }
248 
249 /*
250 ====================
251 idCurve::GetLengthForTime
252 ====================
253 */
254 template< class type >
255 ID_INLINE float idCurve<type>::GetLengthForTime( const float time ) const {
256  float length = 0.0f;
257  int index = IndexForTime( time );
258  for ( int i = 0; i < index; i++ ) {
259  length += RombergIntegral( times[i], times[i+1], 5 );
260  }
261  length += RombergIntegral( times[index], time, 5 );
262  return length;
263 }
264 
265 /*
266 ====================
267 idCurve::GetTimeForLength
268 ====================
269 */
270 template< class type >
271 ID_INLINE float idCurve<type>::GetTimeForLength( const float length, const float epsilon ) const {
272  int i, index;
273  float *accumLength, totalLength, len0, len1, t, diff;
274 
275  if ( length <= 0.0f ) {
276  return times[0];
277  }
278 
279  accumLength = (float *) _alloca16( values.Num() * sizeof( float ) );
280  totalLength = 0.0f;
281  for ( index = 0; index < values.Num() - 1; index++ ) {
282  totalLength += GetLengthBetweenKnots( index, index + 1 );
283  accumLength[index] = totalLength;
284  if ( length < accumLength[index] ) {
285  break;
286  }
287  }
288 
289  if ( index >= values.Num() - 1 ) {
290  return times[times.Num() - 1];
291  }
292 
293  if ( index == 0 ) {
294  len0 = length;
295  len1 = accumLength[0];
296  } else {
297  len0 = length - accumLength[index-1];
298  len1 = accumLength[index] - accumLength[index-1];
299  }
300 
301  // invert the arc length integral using Newton's method
302  t = ( times[index+1] - times[index] ) * len0 / len1;
303  for ( i = 0; i < 32; i++ ) {
304  diff = RombergIntegral( times[index], times[index] + t, 5 ) - len0;
305  if ( idMath::Fabs( diff ) <= epsilon ) {
306  return times[index] + t;
307  }
308  t -= diff / GetSpeed( times[index] + t );
309  }
310  return times[index] + t;
311 }
312 
313 /*
314 ====================
315 idCurve::MakeUniform
316 ====================
317 */
318 template< class type >
319 ID_INLINE void idCurve<type>::MakeUniform( const float totalTime ) {
320  int i, n;
321 
322  n = times.Num() - 1;
323  for ( i = 0; i <= n; i++ ) {
324  times[i] = i * totalTime / n;
325  }
326  changed = true;
327 }
328 
329 /*
330 ====================
331 idCurve::SetConstantSpeed
332 ====================
333 */
334 template< class type >
335 ID_INLINE void idCurve<type>::SetConstantSpeed( const float totalTime ) {
336  int i;
337  float *length, totalLength, scale, t;
338 
339  length = (float *) _alloca16( values.Num() * sizeof( float ) );
340  totalLength = 0.0f;
341  for ( i = 0; i < values.Num() - 1; i++ ) {
342  length[i] = GetLengthBetweenKnots( i, i + 1 );
343  totalLength += length[i];
344  }
345  scale = totalTime / totalLength;
346  for ( t = 0.0f, i = 0; i < times.Num() - 1; i++ ) {
347  times[i] = t;
348  t += scale * length[i];
349  }
350  times[times.Num() - 1] = totalTime;
351  changed = true;
352 }
353 
354 /*
355 ====================
356 idCurve::ShiftTime
357 ====================
358 */
359 template< class type >
360 ID_INLINE void idCurve<type>::ShiftTime( const float deltaTime ) {
361  for ( int i = 0; i < times.Num(); i++ ) {
362  times[i] += deltaTime;
363  }
364  changed = true;
365 }
366 
367 /*
368 ====================
369 idCurve::Translate
370 ====================
371 */
372 template< class type >
373 ID_INLINE void idCurve<type>::Translate( const type &translation ) {
374  for ( int i = 0; i < values.Num(); i++ ) {
375  values[i] += translation;
376  }
377  changed = true;
378 }
379 
380 /*
381 ====================
382 idCurve::IndexForTime
383 
384  find the index for the first time greater than or equal to the given time
385 ====================
386 */
387 template< class type >
388 ID_INLINE int idCurve<type>::IndexForTime( const float time ) const {
389  int len, mid, offset, res;
390 
391  if ( currentIndex >= 0 && currentIndex <= times.Num() ) {
392  // use the cached index if it is still valid
393  if ( currentIndex == 0 ) {
394  if ( time <= times[currentIndex] ) {
395  return currentIndex;
396  }
397  } else if ( currentIndex == times.Num() ) {
398  if ( time > times[currentIndex-1] ) {
399  return currentIndex;
400  }
401  } else if ( time > times[currentIndex-1] && time <= times[currentIndex] ) {
402  return currentIndex;
403  } else if ( time > times[currentIndex] && ( currentIndex+1 == times.Num() || time <= times[currentIndex+1] ) ) {
404  // use the next index
405  currentIndex++;
406  return currentIndex;
407  }
408  }
409 
410  // use binary search to find the index for the given time
411  len = times.Num();
412  mid = len;
413  offset = 0;
414  res = 0;
415  while( mid > 0 ) {
416  mid = len >> 1;
417  if ( time == times[offset+mid] ) {
418  return offset+mid;
419  } else if ( time > times[offset+mid] ) {
420  offset += mid;
421  len -= mid;
422  res = 1;
423  } else {
424  len -= mid;
425  res = 0;
426  }
427  }
428  currentIndex = offset+res;
429  return currentIndex;
430 }
431 
432 /*
433 ====================
434 idCurve::ValueForIndex
435 
436  get the value for the given time
437 ====================
438 */
439 template< class type >
440 ID_INLINE type idCurve<type>::ValueForIndex( const int index ) const {
441  int n = values.Num()-1;
442 
443  if ( index < 0 ) {
444  return values[0] + index * ( values[1] - values[0] );
445  } else if ( index > n ) {
446  return values[n] + ( index - n ) * ( values[n] - values[n-1] );
447  }
448  return values[index];
449 }
450 
451 /*
452 ====================
453 idCurve::TimeForIndex
454 
455  get the value for the given time
456 ====================
457 */
458 template< class type >
459 ID_INLINE float idCurve<type>::TimeForIndex( const int index ) const {
460  int n = times.Num()-1;
461 
462  if ( index < 0 ) {
463  return times[0] + index * ( times[1] - times[0] );
464  } else if ( index > n ) {
465  return times[n] + ( index - n ) * ( times[n] - times[n-1] );
466  }
467  return times[index];
468 }
469 
470 
471 /*
472 ===============================================================================
473 
474  Bezier Curve template.
475  The degree of the polynomial equals the number of knots minus one.
476 
477 ===============================================================================
478 */
479 
480 template< class type >
481 class idCurve_Bezier : public idCurve<type> {
482 public:
483  idCurve_Bezier( void );
484 
485  virtual type GetCurrentValue( const float time ) const;
486  virtual type GetCurrentFirstDerivative( const float time ) const;
487  virtual type GetCurrentSecondDerivative( const float time ) const;
488 
489 protected:
490  void Basis( const int order, const float t, float *bvals ) const;
491  void BasisFirstDerivative( const int order, const float t, float *bvals ) const;
492  void BasisSecondDerivative( const int order, const float t, float *bvals ) const;
493 };
494 
495 /*
496 ====================
497 idCurve_Bezier::idCurve_Bezier
498 ====================
499 */
500 template< class type >
502 }
503 
504 /*
505 ====================
506 idCurve_Bezier::GetCurrentValue
507 
508  get the value for the given time
509 ====================
510 */
511 template< class type >
512 ID_INLINE type idCurve_Bezier<type>::GetCurrentValue( const float time ) const {
513  int i;
514  float *bvals;
515  type v;
516 
517  bvals = (float *) _alloca16( this->values.Num() * sizeof( float ) );
518 
519  Basis( this->values.Num(), time, bvals );
520  v = bvals[0] * this->values[0];
521  for ( i = 1; i < this->values.Num(); i++ ) {
522  v += bvals[i] * this->values[i];
523  }
524  return v;
525 }
526 
527 /*
528 ====================
529 idCurve_Bezier::GetCurrentFirstDerivative
530 
531  get the first derivative for the given time
532 ====================
533 */
534 template< class type >
535 ID_INLINE type idCurve_Bezier<type>::GetCurrentFirstDerivative( const float time ) const {
536  int i;
537  float *bvals, d;
538  type v;
539 
540  bvals = (float *) _alloca16( this->values.Num() * sizeof( float ) );
541 
542  BasisFirstDerivative( this->values.Num(), time, bvals );
543  v = bvals[0] * this->values[0];
544  for ( i = 1; i < this->values.Num(); i++ ) {
545  v += bvals[i] * this->values[i];
546  }
547  d = ( this->times[this->times.Num()-1] - this->times[0] );
548  return ( (float) (this->values.Num()-1) / d ) * v;
549 }
550 
551 /*
552 ====================
553 idCurve_Bezier::GetCurrentSecondDerivative
554 
555  get the second derivative for the given time
556 ====================
557 */
558 template< class type >
559 ID_INLINE type idCurve_Bezier<type>::GetCurrentSecondDerivative( const float time ) const {
560  int i;
561  float *bvals, d;
562  type v;
563 
564  bvals = (float *) _alloca16( this->values.Num() * sizeof( float ) );
565 
566  BasisSecondDerivative( this->values.Num(), time, bvals );
567  v = bvals[0] * this->values[0];
568  for ( i = 1; i < this->values.Num(); i++ ) {
569  v += bvals[i] * this->values[i];
570  }
571  d = ( this->times[this->times.Num()-1] - this->times[0] );
572  return ( (float) (this->values.Num()-2) * (this->values.Num()-1) / ( d * d ) ) * v;
573 }
574 
575 /*
576 ====================
577 idCurve_Bezier::Basis
578 
579  bezier basis functions
580 ====================
581 */
582 template< class type >
583 ID_INLINE void idCurve_Bezier<type>::Basis( const int order, const float t, float *bvals ) const {
584  int i, j, d;
585  float *c, c1, c2, s, o, ps, po;
586 
587  bvals[0] = 1.0f;
588  d = order - 1;
589  if ( d <= 0 ) {
590  return;
591  }
592 
593  c = (float *) _alloca16( (d+1) * sizeof( float ) );
594  s = (float) ( t - this->times[0] ) / ( this->times[this->times.Num()-1] - this->times[0] );
595  o = 1.0f - s;
596  ps = s;
597  po = o;
598 
599  for ( i = 1; i < d; i++ ) {
600  c[i] = 1.0f;
601  }
602  for ( i = 1; i < d; i++ ) {
603  c[i-1] = 0.0f;
604  c1 = c[i];
605  c[i] = 1.0f;
606  for ( j = i+1; j <= d; j++ ) {
607  c2 = c[j];
608  c[j] = c1 + c[j-1];
609  c1 = c2;
610  }
611  bvals[i] = c[d] * ps;
612  ps *= s;
613  }
614  for ( i = d-1; i >= 0; i-- ) {
615  bvals[i] *= po;
616  po *= o;
617  }
618  bvals[d] = ps;
619 }
620 
621 /*
622 ====================
623 idCurve_Bezier::BasisFirstDerivative
624 
625  first derivative of bezier basis functions
626 ====================
627 */
628 template< class type >
629 ID_INLINE void idCurve_Bezier<type>::BasisFirstDerivative( const int order, const float t, float *bvals ) const {
630  int i;
631 
632  Basis( order-1, t, bvals+1 );
633  bvals[0] = 0.0f;
634  for ( i = 0; i < order-1; i++ ) {
635  bvals[i] -= bvals[i+1];
636  }
637 }
638 
639 /*
640 ====================
641 idCurve_Bezier::BasisSecondDerivative
642 
643  second derivative of bezier basis functions
644 ====================
645 */
646 template< class type >
647 ID_INLINE void idCurve_Bezier<type>::BasisSecondDerivative( const int order, const float t, float *bvals ) const {
648  int i;
649 
650  BasisFirstDerivative( order-1, t, bvals+1 );
651  bvals[0] = 0.0f;
652  for ( i = 0; i < order-1; i++ ) {
653  bvals[i] -= bvals[i+1];
654  }
655 }
656 
657 
658 /*
659 ===============================================================================
660 
661  Quadratic Bezier Curve template.
662  Should always have exactly three knots.
663 
664 ===============================================================================
665 */
666 
667 template< class type >
668 class idCurve_QuadraticBezier : public idCurve<type> {
669 
670 public:
671  idCurve_QuadraticBezier( void );
672 
673  virtual type GetCurrentValue( const float time ) const;
674  virtual type GetCurrentFirstDerivative( const float time ) const;
675  virtual type GetCurrentSecondDerivative( const float time ) const;
676 
677 protected:
678  void Basis( const float t, float *bvals ) const;
679  void BasisFirstDerivative( const float t, float *bvals ) const;
680  void BasisSecondDerivative( const float t, float *bvals ) const;
681 };
682 
683 /*
684 ====================
685 idCurve_QuadraticBezier::idCurve_QuadraticBezier
686 ====================
687 */
688 template< class type >
690 }
691 
692 
693 /*
694 ====================
695 idCurve_QuadraticBezier::GetCurrentValue
696 
697  get the value for the given time
698 ====================
699 */
700 template< class type >
701 ID_INLINE type idCurve_QuadraticBezier<type>::GetCurrentValue( const float time ) const {
702  float bvals[3];
703  assert( this->values.Num() == 3 );
704  Basis( time, bvals );
705  return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] );
706 }
707 
708 /*
709 ====================
710 idCurve_QuadraticBezier::GetCurrentFirstDerivative
711 
712  get the first derivative for the given time
713 ====================
714 */
715 template< class type >
717  float bvals[3], d;
718  assert( this->values.Num() == 3 );
719  BasisFirstDerivative( time, bvals );
720  d = ( this->times[2] - this->times[0] );
721  return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] ) / d;
722 }
723 
724 /*
725 ====================
726 idCurve_QuadraticBezier::GetCurrentSecondDerivative
727 
728  get the second derivative for the given time
729 ====================
730 */
731 template< class type >
733  float bvals[3], d;
734  assert( this->values.Num() == 3 );
735  BasisSecondDerivative( time, bvals );
736  d = ( this->times[2] - this->times[0] );
737  return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] ) / ( d * d );
738 }
739 
740 /*
741 ====================
742 idCurve_QuadraticBezier::Basis
743 
744  quadratic bezier basis functions
745 ====================
746 */
747 template< class type >
748 ID_INLINE void idCurve_QuadraticBezier<type>::Basis( const float t, float *bvals ) const {
749  float s1 = (float) ( t - this->times[0] ) / ( this->times[2] - this->times[0] );
750  float s2 = s1 * s1;
751  bvals[0] = s2 - 2.0f * s1 + 1.0f;
752  bvals[1] = -2.0f * s2 + 2.0f * s1;
753  bvals[2] = s2;
754 }
755 
756 /*
757 ====================
758 idCurve_QuadraticBezier::BasisFirstDerivative
759 
760  first derivative of quadratic bezier basis functions
761 ====================
762 */
763 template< class type >
764 ID_INLINE void idCurve_QuadraticBezier<type>::BasisFirstDerivative( const float t, float *bvals ) const {
765  float s1 = (float) ( t - this->times[0] ) / ( this->times[2] - this->times[0] );
766  bvals[0] = 2.0f * s1 - 2.0f;
767  bvals[1] = -4.0f * s1 + 2.0f;
768  bvals[2] = 2.0f * s1;
769 }
770 
771 /*
772 ====================
773 idCurve_QuadraticBezier::BasisSecondDerivative
774 
775  second derivative of quadratic bezier basis functions
776 ====================
777 */
778 template< class type >
779 ID_INLINE void idCurve_QuadraticBezier<type>::BasisSecondDerivative( const float t, float *bvals ) const {
780 // float s1 = (float) ( t - this->times[0] ) / ( this->times[2] - this->times[0] );
781  bvals[0] = 2.0f;
782  bvals[1] = -4.0f;
783  bvals[2] = 2.0f;
784 }
785 
786 
787 /*
788 ===============================================================================
789 
790  Cubic Bezier Curve template.
791  Should always have exactly four knots.
792 
793 ===============================================================================
794 */
795 
796 template< class type >
797 class idCurve_CubicBezier : public idCurve<type> {
798 
799 public:
800  idCurve_CubicBezier( void );
801 
802  virtual type GetCurrentValue( const float time ) const;
803  virtual type GetCurrentFirstDerivative( const float time ) const;
804  virtual type GetCurrentSecondDerivative( const float time ) const;
805 
806 protected:
807  void Basis( const float t, float *bvals ) const;
808  void BasisFirstDerivative( const float t, float *bvals ) const;
809  void BasisSecondDerivative( const float t, float *bvals ) const;
810 };
811 
812 /*
813 ====================
814 idCurve_CubicBezier::idCurve_CubicBezier
815 ====================
816 */
817 template< class type >
819 }
820 
821 
822 /*
823 ====================
824 idCurve_CubicBezier::GetCurrentValue
825 
826  get the value for the given time
827 ====================
828 */
829 template< class type >
830 ID_INLINE type idCurve_CubicBezier<type>::GetCurrentValue( const float time ) const {
831  float bvals[4];
832  assert( this->values.Num() == 4 );
833  Basis( time, bvals );
834  return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] + bvals[3] * this->values[3] );
835 }
836 
837 /*
838 ====================
839 idCurve_CubicBezier::GetCurrentFirstDerivative
840 
841  get the first derivative for the given time
842 ====================
843 */
844 template< class type >
845 ID_INLINE type idCurve_CubicBezier<type>::GetCurrentFirstDerivative( const float time ) const {
846  float bvals[4], d;
847  assert( this->values.Num() == 4 );
848  BasisFirstDerivative( time, bvals );
849  d = ( this->times[3] - this->times[0] );
850  return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] + bvals[3] * this->values[3] ) / d;
851 }
852 
853 /*
854 ====================
855 idCurve_CubicBezier::GetCurrentSecondDerivative
856 
857  get the second derivative for the given time
858 ====================
859 */
860 template< class type >
861 ID_INLINE type idCurve_CubicBezier<type>::GetCurrentSecondDerivative( const float time ) const {
862  float bvals[4], d;
863  assert( this->values.Num() == 4 );
864  BasisSecondDerivative( time, bvals );
865  d = ( this->times[3] - this->times[0] );
866  return ( bvals[0] * this->values[0] + bvals[1] * this->values[1] + bvals[2] * this->values[2] + bvals[3] * this->values[3] ) / ( d * d );
867 }
868 
869 /*
870 ====================
871 idCurve_CubicBezier::Basis
872 
873  cubic bezier basis functions
874 ====================
875 */
876 template< class type >
877 ID_INLINE void idCurve_CubicBezier<type>::Basis( const float t, float *bvals ) const {
878  float s1 = (float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] );
879  float s2 = s1 * s1;
880  float s3 = s2 * s1;
881  bvals[0] = -s3 + 3.0f * s2 - 3.0f * s1 + 1.0f;
882  bvals[1] = 3.0f * s3 - 6.0f * s2 + 3.0f * s1;
883  bvals[2] = -3.0f * s3 + 3.0f * s2;
884  bvals[3] = s3;
885 }
886 
887 /*
888 ====================
889 idCurve_CubicBezier::BasisFirstDerivative
890 
891  first derivative of cubic bezier basis functions
892 ====================
893 */
894 template< class type >
895 ID_INLINE void idCurve_CubicBezier<type>::BasisFirstDerivative( const float t, float *bvals ) const {
896  float s1 = (float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] );
897  float s2 = s1 * s1;
898  bvals[0] = -3.0f * s2 + 6.0f * s1 - 3.0f;
899  bvals[1] = 9.0f * s2 - 12.0f * s1 + 3.0f;
900  bvals[2] = -9.0f * s2 + 6.0f * s1;
901  bvals[3] = 3.0f * s2;
902 }
903 
904 /*
905 ====================
906 idCurve_CubicBezier::BasisSecondDerivative
907 
908  second derivative of cubic bezier basis functions
909 ====================
910 */
911 template< class type >
912 ID_INLINE void idCurve_CubicBezier<type>::BasisSecondDerivative( const float t, float *bvals ) const {
913  float s1 = (float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] );
914  bvals[0] = -6.0f * s1 + 6.0f;
915  bvals[1] = 18.0f * s1 - 12.0f;
916  bvals[2] = -18.0f * s1 + 6.0f;
917  bvals[3] = 6.0f * s1;
918 }
919 
920 
921 /*
922 ===============================================================================
923 
924  Spline base template.
925 
926 ===============================================================================
927 */
928 
929 template< class type >
930 class idCurve_Spline : public idCurve<type> {
931 
932 public:
934 
935  idCurve_Spline( void );
936 
937  virtual bool IsDone( const float time ) const;
938 
939  virtual void SetBoundaryType( const boundary_t bt ) { boundaryType = bt; this->changed = true; }
940  virtual boundary_t GetBoundaryType( void ) const { return boundaryType; }
941 
942  virtual void SetCloseTime( const float t ) { closeTime = t; this->changed = true; }
943  virtual float GetCloseTime( void ) { return boundaryType == BT_CLOSED ? closeTime : 0.0f; }
944 
945 protected:
947  float closeTime;
948 
949  type ValueForIndex( const int index ) const;
950  float TimeForIndex( const int index ) const;
951  float ClampedTime( const float t ) const;
952 };
953 
954 /*
955 ====================
956 idCurve_Spline::idCurve_Spline
957 ====================
958 */
959 template< class type >
961  boundaryType = BT_FREE;
962  closeTime = 0.0f;
963 }
964 
965 /*
966 ====================
967 idCurve_Spline::ValueForIndex
968 
969  get the value for the given time
970 ====================
971 */
972 template< class type >
973 ID_INLINE type idCurve_Spline<type>::ValueForIndex( const int index ) const {
974  int n = this->values.Num()-1;
975 
976  if ( index < 0 ) {
977  if ( boundaryType == BT_CLOSED ) {
978  return this->values[ this->values.Num() + index % this->values.Num() ];
979  }
980  else {
981  return this->values[0] + index * ( this->values[1] - this->values[0] );
982  }
983  }
984  else if ( index > n ) {
985  if ( boundaryType == BT_CLOSED ) {
986  return this->values[ index % this->values.Num() ];
987  }
988  else {
989  return this->values[n] + ( index - n ) * ( this->values[n] - this->values[n-1] );
990  }
991  }
992  return this->values[index];
993 }
994 
995 /*
996 ====================
997 idCurve_Spline::TimeForIndex
998 
999  get the value for the given time
1000 ====================
1001 */
1002 template< class type >
1003 ID_INLINE float idCurve_Spline<type>::TimeForIndex( const int index ) const {
1004  int n = this->times.Num()-1;
1005 
1006  if ( index < 0 ) {
1007  if ( boundaryType == BT_CLOSED ) {
1008  return ( index / this->times.Num() ) * ( this->times[n] + closeTime ) - ( this->times[n] + closeTime - this->times[this->times.Num() + index % this->times.Num()] );
1009  }
1010  else {
1011  return this->times[0] + index * ( this->times[1] - this->times[0] );
1012  }
1013  }
1014  else if ( index > n ) {
1015  if ( boundaryType == BT_CLOSED ) {
1016  return ( index / this->times.Num() ) * ( this->times[n] + closeTime ) + this->times[index % this->times.Num()];
1017  }
1018  else {
1019  return this->times[n] + ( index - n ) * ( this->times[n] - this->times[n-1] );
1020  }
1021  }
1022  return this->times[index];
1023 }
1024 
1025 /*
1026 ====================
1027 idCurve_Spline::ClampedTime
1028 
1029  return the clamped time based on the boundary type
1030 ====================
1031 */
1032 template< class type >
1033 ID_INLINE float idCurve_Spline<type>::ClampedTime( const float t ) const {
1034  if ( boundaryType == BT_CLAMPED ) {
1035  if ( t < this->times[0] ) {
1036  return this->times[0];
1037  }
1038  else if ( t >= this->times[this->times.Num()-1] ) {
1039  return this->times[this->times.Num()-1];
1040  }
1041  }
1042  return t;
1043 }
1044 
1045 /*
1046 ====================
1047 idCurve_Spline::IsDone
1048 ====================
1049 */
1050 template< class type >
1051 ID_INLINE bool idCurve_Spline<type>::IsDone( const float time ) const {
1052  return ( boundaryType != BT_CLOSED && time >= this->times[ this->times.Num() - 1 ] );
1053 }
1054 
1055 
1056 /*
1057 ===============================================================================
1058 
1059  Cubic Interpolating Spline template.
1060  The curve goes through all the knots.
1061 
1062 ===============================================================================
1063 */
1064 
1065 template< class type >
1067 public:
1069 
1070  virtual void Clear( void ) { idCurve_Spline<type>::Clear(); this->values.Clear(); b.Clear(); c.Clear(); d.Clear(); }
1071 
1072  virtual type GetCurrentValue( const float time ) const;
1073  virtual type GetCurrentFirstDerivative( const float time ) const;
1074  virtual type GetCurrentSecondDerivative( const float time ) const;
1075 
1076 protected:
1077  mutable idList<type>b;
1078  mutable idList<type>c;
1079  mutable idList<type>d;
1080 
1081  void Setup( void ) const;
1082  void SetupFree( void ) const;
1083  void SetupClamped( void ) const;
1084  void SetupClosed( void ) const;
1085 };
1086 
1087 /*
1088 ====================
1089 idCurve_NaturalCubicSpline::idCurve_NaturalCubicSpline
1090 ====================
1091 */
1092 template< class type >
1094 }
1095 
1096 /*
1097 ====================
1098 idCurve_NaturalCubicSpline::GetCurrentValue
1099 
1100  get the value for the given time
1101 ====================
1102 */
1103 template< class type >
1104 ID_INLINE type idCurve_NaturalCubicSpline<type>::GetCurrentValue( const float time ) const {
1105  float clampedTime = this->ClampedTime( time );
1106  int i = this->IndexForTime( clampedTime );
1107  float s = time - this->TimeForIndex( i );
1108  Setup();
1109  return ( this->values[i] + s * ( b[i] + s * ( c[i] + s * d[i] ) ) );
1110 }
1111 
1112 /*
1113 ====================
1114 idCurve_NaturalCubicSpline::GetCurrentFirstDerivative
1115 
1116  get the first derivative for the given time
1117 ====================
1118 */
1119 template< class type >
1121  float clampedTime = this->ClampedTime( time );
1122  int i = this->IndexForTime( clampedTime );
1123  float s = time - this->TimeForIndex( i );
1124  Setup();
1125  return ( b[i] + s * ( 2.0f * c[i] + 3.0f * s * d[i] ) );
1126 }
1127 
1128 /*
1129 ====================
1130 idCurve_NaturalCubicSpline::GetCurrentSecondDerivative
1131 
1132  get the second derivative for the given time
1133 ====================
1134 */
1135 template< class type >
1137  float clampedTime = this->ClampedTime( time );
1138  int i = this->IndexForTime( clampedTime );
1139  float s = time - this->TimeForIndex( i );
1140  Setup();
1141  return ( 2.0f * c[i] + 6.0f * s * d[i] );
1142 }
1143 
1144 /*
1145 ====================
1146 idCurve_NaturalCubicSpline::Setup
1147 ====================
1148 */
1149 template< class type >
1150 ID_INLINE void idCurve_NaturalCubicSpline<type>::Setup( void ) const {
1151  if ( this->changed ) {
1152  switch( this->boundaryType ) {
1153  case idCurve_Spline<type>::BT_FREE: SetupFree(); break;
1154  case idCurve_Spline<type>::BT_CLAMPED: SetupClamped(); break;
1155  case idCurve_Spline<type>::BT_CLOSED: SetupClosed(); break;
1156  }
1157  this->changed = false;
1158  }
1159 }
1160 
1161 /*
1162 ====================
1163 idCurve_NaturalCubicSpline::SetupFree
1164 ====================
1165 */
1166 template< class type >
1167 ID_INLINE void idCurve_NaturalCubicSpline<type>::SetupFree( void ) const {
1168  int i;
1169  float inv;
1170  float *d0, *d1, *beta, *gamma;
1171  type *alpha, *delta;
1172 
1173  d0 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) );
1174  d1 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) );
1175  alpha = (type *) _alloca16( ( this->values.Num() - 1 ) * sizeof( type ) );
1176  beta = (float *) _alloca16( this->values.Num() * sizeof( float ) );
1177  gamma = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) );
1178  delta = (type *) _alloca16( this->values.Num() * sizeof( type ) );
1179 
1180  for ( i = 0; i < this->values.Num() - 1; i++ ) {
1181  d0[i] = this->times[i+1] - this->times[i];
1182  }
1183 
1184  for ( i = 1; i < this->values.Num() - 1; i++ ) {
1185  d1[i] = this->times[i+1] - this->times[i-1];
1186  }
1187 
1188  for ( i = 1; i < this->values.Num() - 1; i++ ) {
1189  type sum = 3.0f * ( d0[i-1] * this->values[i+1] - d1[i] * this->values[i] + d0[i] * this->values[i-1] );
1190  inv = 1.0f / ( d0[i-1] * d0[i] );
1191  alpha[i] = inv * sum;
1192  }
1193 
1194  beta[0] = 1.0f;
1195  gamma[0] = 0.0f;
1196  delta[0] = this->values[0] - this->values[0];
1197 
1198  for ( i = 1; i < this->values.Num() - 1; i++ ) {
1199  beta[i] = 2.0f * d1[i] - d0[i-1] * gamma[i-1];
1200  inv = 1.0f / beta[i];
1201  gamma[i] = inv * d0[i];
1202  delta[i] = inv * ( alpha[i] - d0[i-1] * delta[i-1] );
1203  }
1204  beta[this->values.Num() - 1] = 1.0f;
1205  delta[this->values.Num() - 1] = this->values[0] - this->values[0];
1206 
1207  b.AssureSize( this->values.Num() );
1208  c.AssureSize( this->values.Num() );
1209  d.AssureSize( this->values.Num() );
1210 
1211  c[this->values.Num() - 1] = this->values[0] - this->values[0];
1212 
1213  for ( i = this->values.Num() - 2; i >= 0; i-- ) {
1214  c[i] = delta[i] - gamma[i] * c[i+1];
1215  inv = 1.0f / d0[i];
1216  b[i] = inv * ( this->values[i+1] - this->values[i] ) - ( 1.0f / 3.0f ) * d0[i] * ( c[i+1] + 2.0f * c[i] );
1217  d[i] = ( 1.0f / 3.0f ) * inv * ( c[i+1] - c[i] );
1218  }
1219 }
1220 
1221 /*
1222 ====================
1223 idCurve_NaturalCubicSpline::SetupClamped
1224 ====================
1225 */
1226 template< class type >
1228  int i;
1229  float inv;
1230  float *d0, *d1, *beta, *gamma;
1231  type *alpha, *delta;
1232 
1233  d0 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) );
1234  d1 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) );
1235  alpha = (type *) _alloca16( ( this->values.Num() - 1 ) * sizeof( type ) );
1236  beta = (float *) _alloca16( this->values.Num() * sizeof( float ) );
1237  gamma = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) );
1238  delta = (type *) _alloca16( this->values.Num() * sizeof( type ) );
1239 
1240  for ( i = 0; i < this->values.Num() - 1; i++ ) {
1241  d0[i] = this->times[i+1] - this->times[i];
1242  }
1243 
1244  for ( i = 1; i < this->values.Num() - 1; i++ ) {
1245  d1[i] = this->times[i+1] - this->times[i-1];
1246  }
1247 
1248  inv = 1.0f / d0[0];
1249  alpha[0] = 3.0f * ( inv - 1.0f ) * ( this->values[1] - this->values[0] );
1250  inv = 1.0f / d0[this->values.Num() - 2];
1251  alpha[this->values.Num() - 1] = 3.0f * ( 1.0f - inv ) * ( this->values[this->values.Num() - 1] - this->values[this->values.Num() - 2] );
1252 
1253  for ( i = 1; i < this->values.Num() - 1; i++ ) {
1254  type sum = 3.0f * ( d0[i-1] * this->values[i+1] - d1[i] * this->values[i] + d0[i] * this->values[i-1] );
1255  inv = 1.0f / ( d0[i-1] * d0[i] );
1256  alpha[i] = inv * sum;
1257  }
1258 
1259  beta[0] = 2.0f * d0[0];
1260  gamma[0] = 0.5f;
1261  inv = 1.0f / beta[0];
1262  delta[0] = inv * alpha[0];
1263 
1264  for ( i = 1; i < this->values.Num() - 1; i++ ) {
1265  beta[i] = 2.0f * d1[i] - d0[i-1] * gamma[i-1];
1266  inv = 1.0f / beta[i];
1267  gamma[i] = inv * d0[i];
1268  delta[i] = inv * ( alpha[i] - d0[i-1] * delta[i-1] );
1269  }
1270 
1271  beta[this->values.Num() - 1] = d0[this->values.Num() - 2] * ( 2.0f - gamma[this->values.Num() - 2] );
1272  inv = 1.0f / beta[this->values.Num() - 1];
1273  delta[this->values.Num() - 1] = inv * ( alpha[this->values.Num() - 1] - d0[this->values.Num() - 2] * delta[this->values.Num() - 2] );
1274 
1275  b.AssureSize( this->values.Num() );
1276  c.AssureSize( this->values.Num() );
1277  d.AssureSize( this->values.Num() );
1278 
1279  c[this->values.Num() - 1] = delta[this->values.Num() - 1];
1280 
1281  for ( i = this->values.Num() - 2; i >= 0; i-- ) {
1282  c[i] = delta[i] - gamma[i] * c[i+1];
1283  inv = 1.0f / d0[i];
1284  b[i] = inv * ( this->values[i+1] - this->values[i] ) - ( 1.0f / 3.0f ) * d0[i]* ( c[i+1] + 2.0f * c[i] );
1285  d[i] = ( 1.0f / 3.0f ) * inv * ( c[i+1] - c[i] );
1286  }
1287 }
1288 
1289 /*
1290 ====================
1291 idCurve_NaturalCubicSpline::SetupClosed
1292 ====================
1293 */
1294 template< class type >
1296  int i, j;
1297  float c0, c1;
1298  float *d0;
1299  idMatX mat;
1300  idVecX x;
1301 
1302  d0 = (float *) _alloca16( ( this->values.Num() - 1 ) * sizeof( float ) );
1303  x.SetData( this->values.Num(), VECX_ALLOCA( this->values.Num() ) );
1304  mat.SetData( this->values.Num(), this->values.Num(), MATX_ALLOCA( this->values.Num() * this->values.Num() ) );
1305 
1306  b.AssureSize( this->values.Num() );
1307  c.AssureSize( this->values.Num() );
1308  d.AssureSize( this->values.Num() );
1309 
1310  for ( i = 0; i < this->values.Num() - 1; i++ ) {
1311  d0[i] = this->times[i+1] - this->times[i];
1312  }
1313 
1314  // matrix of system
1315  mat[0][0] = 1.0f;
1316  mat[0][this->values.Num() - 1] = -1.0f;
1317  for ( i = 1; i <= this->values.Num() - 2; i++ ) {
1318  mat[i][i-1] = d0[i-1];
1319  mat[i][i ] = 2.0f * ( d0[i-1] + d0[i] );
1320  mat[i][i+1] = d0[i];
1321  }
1322  mat[this->values.Num() - 1][this->values.Num() - 2] = d0[this->values.Num() - 2];
1323  mat[this->values.Num() - 1][0] = 2.0f * ( d0[this->values.Num() - 2] + d0[0] );
1324  mat[this->values.Num() - 1][1] = d0[0];
1325 
1326  // right-hand side
1327  c[0].Zero();
1328  for ( i = 1; i <= this->values.Num() - 2; i++ ) {
1329  c0 = 1.0f / d0[i];
1330  c1 = 1.0f / d0[i-1];
1331  c[i] = 3.0f * ( c0 * ( this->values[i + 1] - this->values[i] ) - c1 * ( this->values[i] - this->values[i - 1] ) );
1332  }
1333  c0 = 1.0f / d0[0];
1334  c1 = 1.0f / d0[this->values.Num() - 2];
1335  c[this->values.Num() - 1] = 3.0f * ( c0 * ( this->values[1] - this->values[0] ) - c1 * ( this->values[0] - this->values[this->values.Num() - 2] ) );
1336 
1337  // solve system for each dimension
1338  mat.LU_Factor( NULL );
1339  for ( i = 0; i < this->values[0].GetDimension(); i++ ) {
1340  for ( j = 0; j < this->values.Num(); j++ ) {
1341  x[j] = c[j][i];
1342  }
1343  mat.LU_Solve( x, x, NULL );
1344  for ( j = 0; j < this->values.Num(); j++ ) {
1345  c[j][i] = x[j];
1346  }
1347  }
1348 
1349  for ( i = 0; i < this->values.Num() - 1; i++ ) {
1350  c0 = 1.0f / d0[i];
1351  b[i] = c0 * ( this->values[i + 1] - this->values[i] ) - ( 1.0f / 3.0f ) * ( c[i+1] + 2.0f * c[i] ) * d0[i];
1352  d[i] = ( 1.0f / 3.0f ) * c0 * ( c[i + 1] - c[i] );
1353  }
1354 }
1355 
1356 
1357 /*
1358 ===============================================================================
1359 
1360  Uniform Cubic Interpolating Spline template.
1361  The curve goes through all the knots.
1362 
1363 ===============================================================================
1364 */
1365 
1366 template< class type >
1368 
1369 public:
1370  idCurve_CatmullRomSpline( void );
1371 
1372  virtual type GetCurrentValue( const float time ) const;
1373  virtual type GetCurrentFirstDerivative( const float time ) const;
1374  virtual type GetCurrentSecondDerivative( const float time ) const;
1375 
1376 protected:
1377  void Basis( const int index, const float t, float *bvals ) const;
1378  void BasisFirstDerivative( const int index, const float t, float *bvals ) const;
1379  void BasisSecondDerivative( const int index, const float t, float *bvals ) const;
1380 };
1381 
1382 /*
1383 ====================
1384 idCurve_CatmullRomSpline::idCurve_CatmullRomSpline
1385 ====================
1386 */
1387 template< class type >
1389 }
1390 
1391 /*
1392 ====================
1393 idCurve_CatmullRomSpline::GetCurrentValue
1394 
1395  get the value for the given time
1396 ====================
1397 */
1398 template< class type >
1399 ID_INLINE type idCurve_CatmullRomSpline<type>::GetCurrentValue( const float time ) const {
1400  int i, j, k;
1401  float bvals[4], clampedTime;
1402  type v;
1403 
1404  if ( this->times.Num() == 1 ) {
1405  return this->values[0];
1406  }
1407 
1408  clampedTime = this->ClampedTime( time );
1409  i = this->IndexForTime( clampedTime );
1410  Basis( i-1, clampedTime, bvals );
1411  v = this->values[0] - this->values[0];
1412  for ( j = 0; j < 4; j++ ) {
1413  k = i + j - 2;
1414  v += bvals[j] * this->ValueForIndex( k );
1415  }
1416  return v;
1417 }
1418 
1419 /*
1420 ====================
1421 idCurve_CatmullRomSpline::GetCurrentFirstDerivative
1422 
1423  get the first derivative for the given time
1424 ====================
1425 */
1426 template< class type >
1428  int i, j, k;
1429  float bvals[4], d, clampedTime;
1430  type v;
1431 
1432  if ( this->times.Num() == 1 ) {
1433  return ( this->values[0] - this->values[0] );
1434  }
1435 
1436  clampedTime = this->ClampedTime( time );
1437  i = this->IndexForTime( clampedTime );
1438  BasisFirstDerivative( i-1, clampedTime, bvals );
1439  v = this->values[0] - this->values[0];
1440  for ( j = 0; j < 4; j++ ) {
1441  k = i + j - 2;
1442  v += bvals[j] * this->ValueForIndex( k );
1443  }
1444  d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
1445  return v / d;
1446 }
1447 
1448 /*
1449 ====================
1450 idCurve_CatmullRomSpline::GetCurrentSecondDerivative
1451 
1452  get the second derivative for the given time
1453 ====================
1454 */
1455 template< class type >
1457  int i, j, k;
1458  float bvals[4], d, clampedTime;
1459  type v;
1460 
1461  if ( this->times.Num() == 1 ) {
1462  return ( this->values[0] - this->values[0] );
1463  }
1464 
1465  clampedTime = this->ClampedTime( time );
1466  i = this->IndexForTime( clampedTime );
1467  BasisSecondDerivative( i-1, clampedTime, bvals );
1468  v = this->values[0] - this->values[0];
1469  for ( j = 0; j < 4; j++ ) {
1470  k = i + j - 2;
1471  v += bvals[j] * this->ValueForIndex( k );
1472  }
1473  d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
1474  return v / ( d * d );
1475 }
1476 
1477 /*
1478 ====================
1479 idCurve_CatmullRomSpline::Basis
1480 
1481  spline basis functions
1482 ====================
1483 */
1484 template< class type >
1485 ID_INLINE void idCurve_CatmullRomSpline<type>::Basis( const int index, const float t, float *bvals ) const {
1486  float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
1487  bvals[0] = ( ( -s + 2.0f ) * s - 1.0f ) * s * 0.5f; // -0.5f s * s * s + s * s - 0.5f * s
1488  bvals[1] = ( ( ( 3.0f * s - 5.0f ) * s ) * s + 2.0f ) * 0.5f; // 1.5f * s * s * s - 2.5f * s * s + 1.0f
1489  bvals[2] = ( ( -3.0f * s + 4.0f ) * s + 1.0f ) * s * 0.5f; // -1.5f * s * s * s - 2.0f * s * s + 0.5f s
1490  bvals[3] = ( ( s - 1.0f ) * s * s ) * 0.5f; // 0.5f * s * s * s - 0.5f * s * s
1491 }
1492 
1493 /*
1494 ====================
1495 idCurve_CatmullRomSpline::BasisFirstDerivative
1496 
1497  first derivative of spline basis functions
1498 ====================
1499 */
1500 template< class type >
1501 ID_INLINE void idCurve_CatmullRomSpline<type>::BasisFirstDerivative( const int index, const float t, float *bvals ) const {
1502  float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
1503  bvals[0] = ( -1.5f * s + 2.0f ) * s - 0.5f; // -1.5f * s * s + 2.0f * s - 0.5f
1504  bvals[1] = ( 4.5f * s - 5.0f ) * s; // 4.5f * s * s - 5.0f * s
1505  bvals[2] = ( -4.5 * s + 4.0f ) * s + 0.5f; // -4.5 * s * s + 4.0f * s + 0.5f
1506  bvals[3] = 1.5f * s * s - s; // 1.5f * s * s - s
1507 }
1508 
1509 /*
1510 ====================
1511 idCurve_CatmullRomSpline::BasisSecondDerivative
1512 
1513  second derivative of spline basis functions
1514 ====================
1515 */
1516 template< class type >
1517 ID_INLINE void idCurve_CatmullRomSpline<type>::BasisSecondDerivative( const int index, const float t, float *bvals ) const {
1518  float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
1519  bvals[0] = -3.0f * s + 2.0f;
1520  bvals[1] = 9.0f * s - 5.0f;
1521  bvals[2] = -9.0f * s + 4.0f;
1522  bvals[3] = 3.0f * s - 1.0f;
1523 }
1524 
1525 
1526 /*
1527 ===============================================================================
1528 
1529  Cubic Interpolating Spline template.
1530  The curve goes through all the knots.
1531  The curve becomes the Catmull-Rom spline if the tension,
1532  continuity and bias are all set to zero.
1533 
1534 ===============================================================================
1535 */
1536 
1537 template< class type >
1539 
1540 public:
1542 
1543  virtual int AddValue( const float time, const type &value );
1544  virtual int AddValue( const float time, const type &value, const float tension, const float continuity, const float bias );
1545  virtual void RemoveIndex( const int index ) { this->values.RemoveIndex(index); this->times.RemoveIndex(index); tension.RemoveIndex(index); continuity.RemoveIndex(index); bias.RemoveIndex(index); }
1546  virtual void Clear( void ) { this->values.Clear(); this->times.Clear(); tension.Clear(); continuity.Clear(); bias.Clear(); this->currentIndex = -1; }
1547 
1548  virtual type GetCurrentValue( const float time ) const;
1549  virtual type GetCurrentFirstDerivative( const float time ) const;
1550  virtual type GetCurrentSecondDerivative( const float time ) const;
1551 
1552 protected:
1556 
1557  void TangentsForIndex( const int index, type &t0, type &t1 ) const;
1558 
1559  void Basis( const int index, const float t, float *bvals ) const;
1560  void BasisFirstDerivative( const int index, const float t, float *bvals ) const;
1561  void BasisSecondDerivative( const int index, const float t, float *bvals ) const;
1562 };
1563 
1564 /*
1565 ====================
1566 idCurve_KochanekBartelsSpline::idCurve_KochanekBartelsSpline
1567 ====================
1568 */
1569 template< class type >
1571 }
1572 
1573 /*
1574 ====================
1575 idCurve_KochanekBartelsSpline::AddValue
1576 
1577  add a timed/value pair to the spline
1578  returns the index to the inserted pair
1579 ====================
1580 */
1581 template< class type >
1582 ID_INLINE int idCurve_KochanekBartelsSpline<type>::AddValue( const float time, const type &value ) {
1583  int i;
1584 
1585  i = this->IndexForTime( time );
1586  this->times.Insert( time, i );
1587  this->values.Insert( value, i );
1588  tension.Insert( 0.0f, i );
1589  continuity.Insert( 0.0f, i );
1590  bias.Insert( 0.0f, i );
1591  return i;
1592 }
1593 
1594 /*
1595 ====================
1596 idCurve_KochanekBartelsSpline::AddValue
1597 
1598  add a timed/value pair to the spline
1599  returns the index to the inserted pair
1600 ====================
1601 */
1602 template< class type >
1603 ID_INLINE int idCurve_KochanekBartelsSpline<type>::AddValue( const float time, const type &value, const float tension, const float continuity, const float bias ) {
1604  int i;
1605 
1606  i = this->IndexForTime( time );
1607  this->times.Insert( time, i );
1608  this->values.Insert( value, i );
1609  this->tension.Insert( tension, i );
1610  this->continuity.Insert( continuity, i );
1611  this->bias.Insert( bias, i );
1612  return i;
1613 }
1614 
1615 /*
1616 ====================
1617 idCurve_KochanekBartelsSpline::GetCurrentValue
1618 
1619  get the value for the given time
1620 ====================
1621 */
1622 template< class type >
1623 ID_INLINE type idCurve_KochanekBartelsSpline<type>::GetCurrentValue( const float time ) const {
1624  int i;
1625  float bvals[4], clampedTime;
1626  type v, t0, t1;
1627 
1628  if ( this->times.Num() == 1 ) {
1629  return this->values[0];
1630  }
1631 
1632  clampedTime = this->ClampedTime( time );
1633  i = this->IndexForTime( clampedTime );
1634  TangentsForIndex( i - 1, t0, t1 );
1635  Basis( i - 1, clampedTime, bvals );
1636  v = bvals[0] * this->ValueForIndex( i - 1 );
1637  v += bvals[1] * this->ValueForIndex( i );
1638  v += bvals[2] * t0;
1639  v += bvals[3] * t1;
1640  return v;
1641 }
1642 
1643 /*
1644 ====================
1645 idCurve_KochanekBartelsSpline::GetCurrentFirstDerivative
1646 
1647  get the first derivative for the given time
1648 ====================
1649 */
1650 template< class type >
1652  int i;
1653  float bvals[4], d, clampedTime;
1654  type v, t0, t1;
1655 
1656  if ( this->times.Num() == 1 ) {
1657  return ( this->values[0] - this->values[0] );
1658  }
1659 
1660  clampedTime = this->ClampedTime( time );
1661  i = this->IndexForTime( clampedTime );
1662  TangentsForIndex( i - 1, t0, t1 );
1663  BasisFirstDerivative( i - 1, clampedTime, bvals );
1664  v = bvals[0] * this->ValueForIndex( i - 1 );
1665  v += bvals[1] * this->ValueForIndex( i );
1666  v += bvals[2] * t0;
1667  v += bvals[3] * t1;
1668  d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
1669  return v / d;
1670 }
1671 
1672 /*
1673 ====================
1674 idCurve_KochanekBartelsSpline::GetCurrentSecondDerivative
1675 
1676  get the second derivative for the given time
1677 ====================
1678 */
1679 template< class type >
1681  int i;
1682  float bvals[4], d, clampedTime;
1683  type v, t0, t1;
1684 
1685  if ( this->times.Num() == 1 ) {
1686  return ( this->values[0] - this->values[0] );
1687  }
1688 
1689  clampedTime = this->ClampedTime( time );
1690  i = this->IndexForTime( clampedTime );
1691  TangentsForIndex( i - 1, t0, t1 );
1692  BasisSecondDerivative( i - 1, clampedTime, bvals );
1693  v = bvals[0] * this->ValueForIndex( i - 1 );
1694  v += bvals[1] * this->ValueForIndex( i );
1695  v += bvals[2] * t0;
1696  v += bvals[3] * t1;
1697  d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
1698  return v / ( d * d );
1699 }
1700 
1701 /*
1702 ====================
1703 idCurve_KochanekBartelsSpline::TangentsForIndex
1704 ====================
1705 */
1706 template< class type >
1707 ID_INLINE void idCurve_KochanekBartelsSpline<type>::TangentsForIndex( const int index, type &t0, type &t1 ) const {
1708  float dt, omt, omc, opc, omb, opb, adj, s0, s1;
1709  type delta;
1710 
1711  delta = this->ValueForIndex( index + 1 ) - this->ValueForIndex( index );
1712  dt = this->TimeForIndex( index + 1 ) - this->TimeForIndex( index );
1713 
1714  omt = 1.0f - tension[index];
1715  omc = 1.0f - continuity[index];
1716  opc = 1.0f + continuity[index];
1717  omb = 1.0f - bias[index];
1718  opb = 1.0f + bias[index];
1719  adj = 2.0f * dt / ( this->TimeForIndex( index + 1 ) - this->TimeForIndex( index - 1 ) );
1720  s0 = 0.5f * adj * omt * opc * opb;
1721  s1 = 0.5f * adj * omt * omc * omb;
1722 
1723  // outgoing tangent at first point
1724  t0 = s1 * delta + s0 * ( this->ValueForIndex( index ) - this->ValueForIndex( index - 1 ) );
1725 
1726  omt = 1.0f - tension[index + 1];
1727  omc = 1.0f - continuity[index + 1];
1728  opc = 1.0f + continuity[index + 1];
1729  omb = 1.0f - bias[index + 1];
1730  opb = 1.0f + bias[index + 1];
1731  adj = 2.0f * dt / ( this->TimeForIndex( index + 2 ) - this->TimeForIndex( index ) );
1732  s0 = 0.5f * adj * omt * omc * opb;
1733  s1 = 0.5f * adj * omt * opc * omb;
1734 
1735  // incoming tangent at second point
1736  t1 = s1 * ( this->ValueForIndex( index + 2 ) - this->ValueForIndex( index + 1 ) ) + s0 * delta;
1737 }
1738 
1739 /*
1740 ====================
1741 idCurve_KochanekBartelsSpline::Basis
1742 
1743  spline basis functions
1744 ====================
1745 */
1746 template< class type >
1747 ID_INLINE void idCurve_KochanekBartelsSpline<type>::Basis( const int index, const float t, float *bvals ) const {
1748  float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
1749  bvals[0] = ( ( 2.0f * s - 3.0f ) * s ) * s + 1.0f; // 2.0f * s * s * s - 3.0f * s * s + 1.0f
1750  bvals[1] = ( ( -2.0f * s + 3.0f ) * s ) * s; // -2.0f * s * s * s + 3.0f * s * s
1751  bvals[2] = ( ( s - 2.0f ) * s ) * s + s; // s * s * s - 2.0f * s * s + s
1752  bvals[3] = ( ( s - 1.0f ) * s ) * s; // s * s * s - s * s
1753 }
1754 
1755 /*
1756 ====================
1757 idCurve_KochanekBartelsSpline::BasisFirstDerivative
1758 
1759  first derivative of spline basis functions
1760 ====================
1761 */
1762 template< class type >
1763 ID_INLINE void idCurve_KochanekBartelsSpline<type>::BasisFirstDerivative( const int index, const float t, float *bvals ) const {
1764  float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
1765  bvals[0] = ( 6.0f * s - 6.0f ) * s; // 6.0f * s * s - 6.0f * s
1766  bvals[1] = ( -6.0f * s + 6.0f ) * s; // -6.0f * s * s + 6.0f * s
1767  bvals[2] = ( 3.0f * s - 4.0f ) * s + 1.0f; // 3.0f * s * s - 4.0f * s + 1.0f
1768  bvals[3] = ( 3.0f * s - 2.0f ) * s; // 3.0f * s * s - 2.0f * s
1769 }
1770 
1771 /*
1772 ====================
1773 idCurve_KochanekBartelsSpline::BasisSecondDerivative
1774 
1775  second derivative of spline basis functions
1776 ====================
1777 */
1778 template< class type >
1779 ID_INLINE void idCurve_KochanekBartelsSpline<type>::BasisSecondDerivative( const int index, const float t, float *bvals ) const {
1780  float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
1781  bvals[0] = 12.0f * s - 6.0f;
1782  bvals[1] = -12.0f * s + 6.0f;
1783  bvals[2] = 6.0f * s - 4.0f;
1784  bvals[3] = 6.0f * s - 2.0f;
1785 }
1786 
1787 
1788 /*
1789 ===============================================================================
1790 
1791  B-Spline base template. Uses recursive definition and is slow.
1792  Use idCurve_UniformCubicBSpline or idCurve_NonUniformBSpline instead.
1793 
1794 ===============================================================================
1795 */
1796 
1797 template< class type >
1798 class idCurve_BSpline : public idCurve_Spline<type> {
1799 
1800 public:
1801  idCurve_BSpline( void );
1802 
1803  virtual int GetOrder( void ) const { return order; }
1804  virtual void SetOrder( const int i ) { assert( i > 0 && i < 10 ); order = i; }
1805 
1806  virtual type GetCurrentValue( const float time ) const;
1807  virtual type GetCurrentFirstDerivative( const float time ) const;
1808  virtual type GetCurrentSecondDerivative( const float time ) const;
1809 
1810 protected:
1811  int order;
1812 
1813  float Basis( const int index, const int order, const float t ) const;
1814  float BasisFirstDerivative( const int index, const int order, const float t ) const;
1815  float BasisSecondDerivative( const int index, const int order, const float t ) const;
1816 };
1817 
1818 /*
1819 ====================
1820 idCurve_BSpline::idCurve_NaturalCubicSpline
1821 ====================
1822 */
1823 template< class type >
1825  order = 4; // default to cubic
1826 }
1827 
1828 /*
1829 ====================
1830 idCurve_BSpline::GetCurrentValue
1831 
1832  get the value for the given time
1833 ====================
1834 */
1835 template< class type >
1836 ID_INLINE type idCurve_BSpline<type>::GetCurrentValue( const float time ) const {
1837  int i, j, k;
1838  float clampedTime;
1839  type v;
1840 
1841  if ( this->times.Num() == 1 ) {
1842  return this->values[0];
1843  }
1844 
1845  clampedTime = this->ClampedTime( time );
1846  i = this->IndexForTime( clampedTime );
1847  v = this->values[0] - this->values[0];
1848  for ( j = 0; j < order; j++ ) {
1849  k = i + j - ( order >> 1 );
1850  v += Basis( k-2, order, clampedTime ) * this->ValueForIndex( k );
1851  }
1852  return v;
1853 }
1854 
1855 /*
1856 ====================
1857 idCurve_BSpline::GetCurrentFirstDerivative
1858 
1859  get the first derivative for the given time
1860 ====================
1861 */
1862 template< class type >
1863 ID_INLINE type idCurve_BSpline<type>::GetCurrentFirstDerivative( const float time ) const {
1864  int i, j, k;
1865  float clampedTime;
1866  type v;
1867 
1868  if ( this->times.Num() == 1 ) {
1869  return this->values[0];
1870  }
1871 
1872  clampedTime = this->ClampedTime( time );
1873  i = this->IndexForTime( clampedTime );
1874  v = this->values[0] - this->values[0];
1875  for ( j = 0; j < order; j++ ) {
1876  k = i + j - ( order >> 1 );
1877  v += BasisFirstDerivative( k-2, order, clampedTime ) * this->ValueForIndex( k );
1878  }
1879  return v;
1880 }
1881 
1882 /*
1883 ====================
1884 idCurve_BSpline::GetCurrentSecondDerivative
1885 
1886  get the second derivative for the given time
1887 ====================
1888 */
1889 template< class type >
1890 ID_INLINE type idCurve_BSpline<type>::GetCurrentSecondDerivative( const float time ) const {
1891  int i, j, k;
1892  float clampedTime;
1893  type v;
1894 
1895  if ( this->times.Num() == 1 ) {
1896  return this->values[0];
1897  }
1898 
1899  clampedTime = this->ClampedTime( time );
1900  i = this->IndexForTime( clampedTime );
1901  v = this->values[0] - this->values[0];
1902  for ( j = 0; j < order; j++ ) {
1903  k = i + j - ( order >> 1 );
1904  v += BasisSecondDerivative( k-2, order, clampedTime ) * this->ValueForIndex( k );
1905  }
1906  return v;
1907 }
1908 
1909 /*
1910 ====================
1911 idCurve_BSpline::Basis
1912 
1913  spline basis function
1914 ====================
1915 */
1916 template< class type >
1917 ID_INLINE float idCurve_BSpline<type>::Basis( const int index, const int order, const float t ) const {
1918  if ( order <= 1 ) {
1919  if ( this->TimeForIndex( index ) < t && t <= this->TimeForIndex( index + 1 ) ) {
1920  return 1.0f;
1921  } else {
1922  return 0.0f;
1923  }
1924  } else {
1925  float sum = 0.0f;
1926  float d1 = this->TimeForIndex( index+order-1 ) - this->TimeForIndex( index );
1927  if ( d1 != 0.0f ) {
1928  sum += (float) ( t - this->TimeForIndex( index ) ) * Basis( index, order-1, t ) / d1;
1929  }
1930 
1931  float d2 = this->TimeForIndex( index+order ) - this->TimeForIndex( index+1 );
1932  if ( d2 != 0.0f ) {
1933  sum += (float) ( this->TimeForIndex( index+order ) - t ) * Basis( index+1, order-1, t ) / d2;
1934  }
1935  return sum;
1936  }
1937 }
1938 
1939 /*
1940 ====================
1941 idCurve_BSpline::BasisFirstDerivative
1942 
1943  first derivative of spline basis function
1944 ====================
1945 */
1946 template< class type >
1947 ID_INLINE float idCurve_BSpline<type>::BasisFirstDerivative( const int index, const int order, const float t ) const {
1948  return ( Basis( index, order-1, t ) - Basis( index+1, order-1, t ) ) *
1949  (float) ( order - 1 ) / ( this->TimeForIndex( index + ( order - 1 ) - 2 ) - this->TimeForIndex( index - 2 ) );
1950 }
1951 
1952 /*
1953 ====================
1954 idCurve_BSpline::BasisSecondDerivative
1955 
1956  second derivative of spline basis function
1957 ====================
1958 */
1959 template< class type >
1960 ID_INLINE float idCurve_BSpline<type>::BasisSecondDerivative( const int index, const int order, const float t ) const {
1961  return ( BasisFirstDerivative( index, order-1, t ) - BasisFirstDerivative( index+1, order-1, t ) ) *
1962  (float) ( order - 1 ) / ( this->TimeForIndex( index + ( order - 1 ) - 2 ) - this->TimeForIndex( index - 2 ) );
1963 }
1964 
1965 
1966 /*
1967 ===============================================================================
1968 
1969  Uniform Non-Rational Cubic B-Spline template.
1970 
1971 ===============================================================================
1972 */
1973 
1974 template< class type >
1976 
1977 public:
1979 
1980  virtual type GetCurrentValue( const float time ) const;
1981  virtual type GetCurrentFirstDerivative( const float time ) const;
1982  virtual type GetCurrentSecondDerivative( const float time ) const;
1983 
1984 protected:
1985  void Basis( const int index, const float t, float *bvals ) const;
1986  void BasisFirstDerivative( const int index, const float t, float *bvals ) const;
1987  void BasisSecondDerivative( const int index, const float t, float *bvals ) const;
1988 };
1989 
1990 /*
1991 ====================
1992 idCurve_UniformCubicBSpline::idCurve_UniformCubicBSpline
1993 ====================
1994 */
1995 template< class type >
1997  this->order = 4; // always cubic
1998 }
1999 
2000 /*
2001 ====================
2002 idCurve_UniformCubicBSpline::GetCurrentValue
2003 
2004  get the value for the given time
2005 ====================
2006 */
2007 template< class type >
2008 ID_INLINE type idCurve_UniformCubicBSpline<type>::GetCurrentValue( const float time ) const {
2009  int i, j, k;
2010  float bvals[4], clampedTime;
2011  type v;
2012 
2013  if ( this->times.Num() == 1 ) {
2014  return this->values[0];
2015  }
2016 
2017  clampedTime = this->ClampedTime( time );
2018  i = this->IndexForTime( clampedTime );
2019  Basis( i-1, clampedTime, bvals );
2020  v = this->values[0] - this->values[0];
2021  for ( j = 0; j < 4; j++ ) {
2022  k = i + j - 2;
2023  v += bvals[j] * this->ValueForIndex( k );
2024  }
2025  return v;
2026 }
2027 
2028 /*
2029 ====================
2030 idCurve_UniformCubicBSpline::GetCurrentFirstDerivative
2031 
2032  get the first derivative for the given time
2033 ====================
2034 */
2035 template< class type >
2037  int i, j, k;
2038  float bvals[4], d, clampedTime;
2039  type v;
2040 
2041  if ( this->times.Num() == 1 ) {
2042  return ( this->values[0] - this->values[0] );
2043  }
2044 
2045  clampedTime = this->ClampedTime( time );
2046  i = this->IndexForTime( clampedTime );
2047  BasisFirstDerivative( i-1, clampedTime, bvals );
2048  v = this->values[0] - this->values[0];
2049  for ( j = 0; j < 4; j++ ) {
2050  k = i + j - 2;
2051  v += bvals[j] * this->ValueForIndex( k );
2052  }
2053  d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
2054  return v / d;
2055 }
2056 
2057 /*
2058 ====================
2059 idCurve_UniformCubicBSpline::GetCurrentSecondDerivative
2060 
2061  get the second derivative for the given time
2062 ====================
2063 */
2064 template< class type >
2066  int i, j, k;
2067  float bvals[4], d, clampedTime;
2068  type v;
2069 
2070  if ( this->times.Num() == 1 ) {
2071  return ( this->values[0] - this->values[0] );
2072  }
2073 
2074  clampedTime = this->ClampedTime( time );
2075  i = this->IndexForTime( clampedTime );
2076  BasisSecondDerivative( i-1, clampedTime, bvals );
2077  v = this->values[0] - this->values[0];
2078  for ( j = 0; j < 4; j++ ) {
2079  k = i + j - 2;
2080  v += bvals[j] * this->ValueForIndex( k );
2081  }
2082  d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
2083  return v / ( d * d );
2084 }
2085 
2086 /*
2087 ====================
2088 idCurve_UniformCubicBSpline::Basis
2089 
2090  spline basis functions
2091 ====================
2092 */
2093 template< class type >
2094 ID_INLINE void idCurve_UniformCubicBSpline<type>::Basis( const int index, const float t, float *bvals ) const {
2095  float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
2096  bvals[0] = ( ( ( -s + 3.0f ) * s - 3.0f ) * s + 1.0f ) * ( 1.0f / 6.0f );
2097  bvals[1] = ( ( ( 3.0f * s - 6.0f ) * s ) * s + 4.0f ) * ( 1.0f / 6.0f );
2098  bvals[2] = ( ( ( -3.0f * s + 3.0f ) * s + 3.0f ) * s + 1.0f ) * ( 1.0f / 6.0f );
2099  bvals[3] = ( s * s * s ) * ( 1.0f / 6.0f );
2100 }
2101 
2102 /*
2103 ====================
2104 idCurve_UniformCubicBSpline::BasisFirstDerivative
2105 
2106  first derivative of spline basis functions
2107 ====================
2108 */
2109 template< class type >
2110 ID_INLINE void idCurve_UniformCubicBSpline<type>::BasisFirstDerivative( const int index, const float t, float *bvals ) const {
2111  float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
2112  bvals[0] = -0.5f * s * s + s - 0.5f;
2113  bvals[1] = 1.5f * s * s - 2.0f * s;
2114  bvals[2] = -1.5f * s * s + s + 0.5f;
2115  bvals[3] = 0.5f * s * s;
2116 }
2117 
2118 /*
2119 ====================
2120 idCurve_UniformCubicBSpline::BasisSecondDerivative
2121 
2122  second derivative of spline basis functions
2123 ====================
2124 */
2125 template< class type >
2126 ID_INLINE void idCurve_UniformCubicBSpline<type>::BasisSecondDerivative( const int index, const float t, float *bvals ) const {
2127  float s = (float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
2128  bvals[0] = -s + 1.0f;
2129  bvals[1] = 3.0f * s - 2.0f;
2130  bvals[2] = -3.0f * s + 1.0f;
2131  bvals[3] = s;
2132 }
2133 
2134 
2135 /*
2136 ===============================================================================
2137 
2138  Non-Uniform Non-Rational B-Spline (NUBS) template.
2139 
2140 ===============================================================================
2141 */
2142 
2143 template< class type >
2145 
2146 public:
2147  idCurve_NonUniformBSpline( void );
2148 
2149  virtual type GetCurrentValue( const float time ) const;
2150  virtual type GetCurrentFirstDerivative( const float time ) const;
2151  virtual type GetCurrentSecondDerivative( const float time ) const;
2152 
2153 protected:
2154  void Basis( const int index, const int order, const float t, float *bvals ) const;
2155  void BasisFirstDerivative( const int index, const int order, const float t, float *bvals ) const;
2156  void BasisSecondDerivative( const int index, const int order, const float t, float *bvals ) const;
2157 };
2158 
2159 /*
2160 ====================
2161 idCurve_NonUniformBSpline::idCurve_NonUniformBSpline
2162 ====================
2163 */
2164 template< class type >
2166 }
2167 
2168 /*
2169 ====================
2170 idCurve_NonUniformBSpline::GetCurrentValue
2171 
2172  get the value for the given time
2173 ====================
2174 */
2175 template< class type >
2176 ID_INLINE type idCurve_NonUniformBSpline<type>::GetCurrentValue( const float time ) const {
2177  int i, j, k;
2178  float clampedTime;
2179  type v;
2180  float *bvals = (float *) _alloca16( this->order * sizeof(float) );
2181 
2182  if ( this->times.Num() == 1 ) {
2183  return this->values[0];
2184  }
2185 
2186  clampedTime = this->ClampedTime( time );
2187  i = this->IndexForTime( clampedTime );
2188  Basis( i-1, this->order, clampedTime, bvals );
2189  v = this->values[0] - this->values[0];
2190  for ( j = 0; j < this->order; j++ ) {
2191  k = i + j - ( this->order >> 1 );
2192  v += bvals[j] * this->ValueForIndex( k );
2193  }
2194  return v;
2195 }
2196 
2197 /*
2198 ====================
2199 idCurve_NonUniformBSpline::GetCurrentFirstDerivative
2200 
2201  get the first derivative for the given time
2202 ====================
2203 */
2204 template< class type >
2206  int i, j, k;
2207  float clampedTime;
2208  type v;
2209  float *bvals = (float *) _alloca16( this->order * sizeof(float) );
2210 
2211  if ( this->times.Num() == 1 ) {
2212  return ( this->values[0] - this->values[0] );
2213  }
2214 
2215  clampedTime = this->ClampedTime( time );
2216  i = this->IndexForTime( clampedTime );
2217  BasisFirstDerivative( i-1, this->order, clampedTime, bvals );
2218  v = this->values[0] - this->values[0];
2219  for ( j = 0; j < this->order; j++ ) {
2220  k = i + j - ( this->order >> 1 );
2221  v += bvals[j] * this->ValueForIndex( k );
2222  }
2223  return v;
2224 }
2225 
2226 /*
2227 ====================
2228 idCurve_NonUniformBSpline::GetCurrentSecondDerivative
2229 
2230  get the second derivative for the given time
2231 ====================
2232 */
2233 template< class type >
2235  int i, j, k;
2236  float clampedTime;
2237  type v;
2238  float *bvals = (float *) _alloca16( this->order * sizeof(float) );
2239 
2240  if ( this->times.Num() == 1 ) {
2241  return ( this->values[0] - this->values[0] );
2242  }
2243 
2244  clampedTime = this->ClampedTime( time );
2245  i = this->IndexForTime( clampedTime );
2246  BasisSecondDerivative( i-1, this->order, clampedTime, bvals );
2247  v = this->values[0] - this->values[0];
2248  for ( j = 0; j < this->order; j++ ) {
2249  k = i + j - ( this->order >> 1 );
2250  v += bvals[j] * this->ValueForIndex( k );
2251  }
2252  return v;
2253 }
2254 
2255 /*
2256 ====================
2257 idCurve_NonUniformBSpline::Basis
2258 
2259  spline basis functions
2260 ====================
2261 */
2262 template< class type >
2263 ID_INLINE void idCurve_NonUniformBSpline<type>::Basis( const int index, const int order, const float t, float *bvals ) const {
2264  int r, s, i;
2265  float omega;
2266 
2267  bvals[order-1] = 1.0f;
2268  for ( r = 2; r <= order; r++ ) {
2269  i = index - r + 1;
2270  bvals[order - r] = 0.0f;
2271  for ( s = order - r + 1; s < order; s++ ) {
2272  i++;
2273  omega = (float) ( t - this->TimeForIndex( i ) ) / ( this->TimeForIndex( i + r - 1 ) - this->TimeForIndex( i ) );
2274  bvals[s - 1] += ( 1.0f - omega ) * bvals[s];
2275  bvals[s] *= omega;
2276  }
2277  }
2278 }
2279 
2280 /*
2281 ====================
2282 idCurve_NonUniformBSpline::BasisFirstDerivative
2283 
2284  first derivative of spline basis functions
2285 ====================
2286 */
2287 template< class type >
2288 ID_INLINE void idCurve_NonUniformBSpline<type>::BasisFirstDerivative( const int index, const int order, const float t, float *bvals ) const {
2289  int i;
2290 
2291  Basis( index, order-1, t, bvals+1 );
2292  bvals[0] = 0.0f;
2293  for ( i = 0; i < order-1; i++ ) {
2294  bvals[i] -= bvals[i+1];
2295  bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) );
2296  }
2297  bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) );
2298 }
2299 
2300 /*
2301 ====================
2302 idCurve_NonUniformBSpline::BasisSecondDerivative
2303 
2304  second derivative of spline basis functions
2305 ====================
2306 */
2307 template< class type >
2308 ID_INLINE void idCurve_NonUniformBSpline<type>::BasisSecondDerivative( const int index, const int order, const float t, float *bvals ) const {
2309  int i;
2310 
2311  BasisFirstDerivative( index, order-1, t, bvals+1 );
2312  bvals[0] = 0.0f;
2313  for ( i = 0; i < order-1; i++ ) {
2314  bvals[i] -= bvals[i+1];
2315  bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) );
2316  }
2317  bvals[i] *= (float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) );
2318 }
2319 
2320 
2321 /*
2322 ===============================================================================
2323 
2324  Non-Uniform Rational B-Spline (NURBS) template.
2325 
2326 ===============================================================================
2327 */
2328 
2329 template< class type >
2331 
2332 public:
2333  idCurve_NURBS( void );
2334 
2335  virtual int AddValue( const float time, const type &value );
2336  virtual int AddValue( const float time, const type &value, const float weight );
2337  virtual void RemoveIndex( const int index ) { this->values.RemoveIndex(index); this->times.RemoveIndex(index); weights.RemoveIndex(index); }
2338  virtual void Clear( void ) { this->values.Clear(); this->times.Clear(); weights.Clear(); this->currentIndex = -1; }
2339 
2340  virtual type GetCurrentValue( const float time ) const;
2341  virtual type GetCurrentFirstDerivative( const float time ) const;
2342  virtual type GetCurrentSecondDerivative( const float time ) const;
2343 
2344 protected:
2346 
2347  float WeightForIndex( const int index ) const;
2348 };
2349 
2350 /*
2351 ====================
2352 idCurve_NURBS::idCurve_NURBS
2353 ====================
2354 */
2355 template< class type >
2357 }
2358 
2359 /*
2360 ====================
2361 idCurve_NURBS::AddValue
2362 
2363  add a timed/value pair to the spline
2364  returns the index to the inserted pair
2365 ====================
2366 */
2367 template< class type >
2368 ID_INLINE int idCurve_NURBS<type>::AddValue( const float time, const type &value ) {
2369  int i;
2370 
2371  i = this->IndexForTime( time );
2372  this->times.Insert( time, i );
2373  this->values.Insert( value, i );
2374  weights.Insert( 1.0f, i );
2375  return i;
2376 }
2377 
2378 /*
2379 ====================
2380 idCurve_NURBS::AddValue
2381 
2382  add a timed/value pair to the spline
2383  returns the index to the inserted pair
2384 ====================
2385 */
2386 template< class type >
2387 ID_INLINE int idCurve_NURBS<type>::AddValue( const float time, const type &value, const float weight ) {
2388  int i;
2389 
2390  i = this->IndexForTime( time );
2391  this->times.Insert( time, i );
2392  this->values.Insert( value, i );
2393  weights.Insert( weight, i );
2394  return i;
2395 }
2396 
2397 /*
2398 ====================
2399 idCurve_NURBS::GetCurrentValue
2400 
2401  get the value for the given time
2402 ====================
2403 */
2404 template< class type >
2405 ID_INLINE type idCurve_NURBS<type>::GetCurrentValue( const float time ) const {
2406  int i, j, k;
2407  float w, b, *bvals, clampedTime;
2408  type v;
2409 
2410  if ( this->times.Num() == 1 ) {
2411  return this->values[0];
2412  }
2413 
2414  bvals = (float *) _alloca16( this->order * sizeof(float) );
2415 
2416  clampedTime = this->ClampedTime( time );
2417  i = this->IndexForTime( clampedTime );
2418  this->Basis( i-1, this->order, clampedTime, bvals );
2419  v = this->values[0] - this->values[0];
2420  w = 0.0f;
2421  for ( j = 0; j < this->order; j++ ) {
2422  k = i + j - ( this->order >> 1 );
2423  b = bvals[j] * WeightForIndex( k );
2424  w += b;
2425  v += b * this->ValueForIndex( k );
2426  }
2427  return v / w;
2428 }
2429 
2430 /*
2431 ====================
2432 idCurve_NURBS::GetCurrentFirstDerivative
2433 
2434  get the first derivative for the given time
2435 ====================
2436 */
2437 template< class type >
2438 ID_INLINE type idCurve_NURBS<type>::GetCurrentFirstDerivative( const float time ) const {
2439  int i, j, k;
2440  float w, wb, wd1, b, d1, *bvals, *d1vals, clampedTime;
2441  type v, vb, vd1;
2442 
2443  if ( this->times.Num() == 1 ) {
2444  return this->values[0];
2445  }
2446 
2447  bvals = (float *) _alloca16( this->order * sizeof(float) );
2448  d1vals = (float *) _alloca16( this->order * sizeof(float) );
2449 
2450  clampedTime = this->ClampedTime( time );
2451  i = this->IndexForTime( clampedTime );
2452  this->Basis( i-1, this->order, clampedTime, bvals );
2453  this->BasisFirstDerivative( i-1, this->order, clampedTime, d1vals );
2454  vb = vd1 = this->values[0] - this->values[0];
2455  wb = wd1 = 0.0f;
2456  for ( j = 0; j < this->order; j++ ) {
2457  k = i + j - ( this->order >> 1 );
2458  w = WeightForIndex( k );
2459  b = bvals[j] * w;
2460  d1 = d1vals[j] * w;
2461  wb += b;
2462  wd1 += d1;
2463  v = this->ValueForIndex( k );
2464  vb += b * v;
2465  vd1 += d1 * v;
2466  }
2467  return ( wb * vd1 - vb * wd1 ) / ( wb * wb );
2468 }
2469 
2470 /*
2471 ====================
2472 idCurve_NURBS::GetCurrentSecondDerivative
2473 
2474  get the second derivative for the given time
2475 ====================
2476 */
2477 template< class type >
2478 ID_INLINE type idCurve_NURBS<type>::GetCurrentSecondDerivative( const float time ) const {
2479  int i, j, k;
2480  float w, wb, wd1, wd2, b, d1, d2, *bvals, *d1vals, *d2vals, clampedTime;
2481  type v, vb, vd1, vd2;
2482 
2483  if ( this->times.Num() == 1 ) {
2484  return this->values[0];
2485  }
2486 
2487  bvals = (float *) _alloca16( this->order * sizeof(float) );
2488  d1vals = (float *) _alloca16( this->order * sizeof(float) );
2489  d2vals = (float *) _alloca16( this->order * sizeof(float) );
2490 
2491  clampedTime = this->ClampedTime( time );
2492  i = this->IndexForTime( clampedTime );
2493  this->Basis( i-1, this->order, clampedTime, bvals );
2494  this->BasisFirstDerivative( i-1, this->order, clampedTime, d1vals );
2495  this->BasisSecondDerivative( i-1, this->order, clampedTime, d2vals );
2496  vb = vd1 = vd2 = this->values[0] - this->values[0];
2497  wb = wd1 = wd2 = 0.0f;
2498  for ( j = 0; j < this->order; j++ ) {
2499  k = i + j - ( this->order >> 1 );
2500  w = WeightForIndex( k );
2501  b = bvals[j] * w;
2502  d1 = d1vals[j] * w;
2503  d2 = d2vals[j] * w;
2504  wb += b;
2505  wd1 += d1;
2506  wd2 += d2;
2507  v = this->ValueForIndex( k );
2508  vb += b * v;
2509  vd1 += d1 * v;
2510  vd2 += d2 * v;
2511  }
2512  return ( ( wb * wb ) * ( wb * vd2 - vb * wd2 ) - ( wb * vd1 - vb * wd1 ) * 2.0f * wb * wd1 ) / ( wb * wb * wb * wb );
2513 }
2514 
2515 /*
2516 ====================
2517 idCurve_NURBS::WeightForIndex
2518 
2519  get the weight for the given index
2520 ====================
2521 */
2522 template< class type >
2523 ID_INLINE float idCurve_NURBS<type>::WeightForIndex( const int index ) const {
2524  int n = weights.Num()-1;
2525 
2526  if ( index < 0 ) {
2527  if ( this->boundaryType == idCurve_Spline<type>::BT_CLOSED ) {
2528  return weights[ weights.Num() + index % weights.Num() ];
2529  } else {
2530  return weights[0] + index * ( weights[1] - weights[0] );
2531  }
2532  } else if ( index > n ) {
2533  if ( this->boundaryType == idCurve_Spline<type>::BT_CLOSED ) {
2534  return weights[ index % weights.Num() ];
2535  } else {
2536  return weights[n] + ( index - n ) * ( weights[n] - weights[n-1] );
2537  }
2538  }
2539  return weights[index];
2540 }
2541 
2542 #endif /* !__MATH_CURVE_H__ */
virtual boundary_t GetBoundaryType(void) const
Definition: Curve.h:940
void Translate(const type &translation)
Definition: Curve.h:373
idCurve_Spline(void)
Definition: Curve.h:960
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:1104
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:2868
GLsizei const GLfloat * value
Definition: glext.h:3614
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:1427
type GetValue(const int index) const
Definition: Curve.h:58
idCurve(void)
Definition: Curve.h:93
float closeTime
Definition: Curve.h:947
void SetupClamped(void) const
Definition: Curve.h:1227
type ValueForIndex(const int index) const
Definition: Curve.h:440
assert(prefInfo.fullscreenBtn)
const GLbyte * weights
Definition: glext.h:3273
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:1120
bool changed
Definition: Curve.h:77
const GLdouble * v
Definition: glext.h:2936
virtual int AddValue(const float time, const type &value)
Definition: Curve.h:1582
void SetupFree(void) const
Definition: Curve.h:1167
void BasisSecondDerivative(const int index, const float t, float *bvals) const
Definition: Curve.h:1779
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:4804
idCurve_Bezier(void)
Definition: Curve.h:501
GLenum GLsizei n
Definition: glext.h:3705
bool LU_Factor(int *index, float *det=NULL)
Definition: Matrix.cpp:3863
virtual int GetOrder(void) const
Definition: Curve.h:1803
float WeightForIndex(const int index) const
Definition: Curve.h:2523
virtual void SetBoundaryType(const boundary_t bt)
Definition: Curve.h:939
#define VECX_ALLOCA(n)
Definition: Vector.h:1432
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:1863
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:1136
idList< type > d
Definition: Curve.h:1079
void SetConstantSpeed(const float totalTime)
Definition: Curve.h:335
void BasisSecondDerivative(const float t, float *bvals) const
Definition: Curve.h:779
case const float
Definition: Callbacks.cpp:62
void SetupClosed(void) const
Definition: Curve.h:1295
static float Sqrt(float x)
Definition: Math.h:302
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:2478
type * GetValueAddress(const int index)
Definition: Curve.h:59
Definition: Curve.h:41
GLuint GLuint GLsizei GLenum type
Definition: glext.h:2845
void BasisFirstDerivative(const float t, float *bvals) const
Definition: Curve.h:895
GLclampf GLclampf GLclampf alpha
Definition: glext.h:2843
idList< float > times
Definition: Curve.h:73
GLdouble s
Definition: glext.h:2935
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:716
GLenum GLsizei len
Definition: glext.h:3472
virtual float GetCloseTime(void)
Definition: Curve.h:943
void ShiftTime(const float deltaTime)
Definition: Curve.h:360
GLenum GLint x
Definition: glext.h:2849
idCurve_NURBS(void)
Definition: Curve.h:2356
int i
Definition: process.py:33
idCurve_NaturalCubicSpline(void)
Definition: Curve.h:1093
GLintptr offset
Definition: glext.h:3113
float TimeForIndex(const int index) const
Definition: Curve.h:1003
void BasisFirstDerivative(const int index, const int order, const float t, float *bvals) const
Definition: Curve.h:2288
virtual void RemoveIndex(const int index)
Definition: Curve.h:2337
idList< float > continuity
Definition: Curve.h:1554
virtual void SetCloseTime(const float t)
Definition: Curve.h:942
virtual void SetOrder(const int i)
Definition: Curve.h:1804
void Basis(const int index, const float t, float *bvals) const
Definition: Curve.h:2094
float ClampedTime(const float t) const
Definition: Curve.h:1033
int currentIndex
Definition: Curve.h:76
void Basis(const int index, const float t, float *bvals) const
Definition: Curve.h:1485
GLfloat bias
Definition: glext.h:3681
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:2234
GLdouble GLdouble GLint GLint order
Definition: qgl.h:339
float GetLengthForTime(const float time) const
Definition: Curve.h:255
GLuint index
Definition: glext.h:3476
const GLubyte * c
Definition: glext.h:4677
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:3454
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:1890
float BasisFirstDerivative(const int index, const int order, const float t) const
Definition: Curve.h:1947
virtual void RemoveIndex(const int index)
Definition: Curve.h:1545
float RombergIntegral(const float t0, const float t1, const int order) const
Definition: Curve.h:203
float GetTimeForLength(const float length, const float epsilon=0.1f) const
Definition: Curve.h:271
idCurve_CatmullRomSpline(void)
Definition: Curve.h:1388
idList< float > bias
Definition: Curve.h:1555
float BasisSecondDerivative(const int index, const int order, const float t) const
Definition: Curve.h:1960
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:861
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:134
static float Fabs(float f)
Definition: Math.h:779
#define NULL
Definition: Lib.h:88
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:2065
#define MATX_ALLOCA(n)
Definition: Matrix.h:1783
virtual void Clear(void)
Definition: Curve.h:48
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:2205
virtual void Clear(void)
Definition: Curve.h:2338
void BasisFirstDerivative(const int index, const float t, float *bvals) const
Definition: Curve.h:1501
void Basis(const int order, const float t, float *bvals) const
Definition: Curve.h:583
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:535
idCurve_CubicBezier(void)
Definition: Curve.h:818
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:1456
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:2405
type ValueForIndex(const int index) const
Definition: Curve.h:973
int IndexForTime(const float time) const
Definition: Curve.h:388
void Zero(void)
Definition: Matrix.h:2291
virtual bool IsDone(const float time) const
Definition: Curve.h:175
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:701
idList< float > tension
Definition: Curve.h:1553
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:153
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:2008
void Basis(const float t, float *bvals) const
Definition: Curve.h:877
float GetSpeed(const float time) const
Definition: Curve.h:185
void Setup(void) const
Definition: Curve.h:1150
void BasisFirstDerivative(const int index, const float t, float *bvals) const
Definition: Curve.h:1763
idCurve_NonUniformBSpline(void)
Definition: Curve.h:2165
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:1623
float GetTime(const int index) const
Definition: Curve.h:60
GLubyte GLubyte b
Definition: glext.h:4662
void BasisSecondDerivative(const float t, float *bvals) const
Definition: Curve.h:912
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:1836
virtual void RemoveIndex(const int index)
Definition: Curve.h:47
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:1651
idList< float > weights
Definition: Curve.h:2345
GLdouble GLdouble GLdouble r
Definition: glext.h:2951
virtual int AddValue(const float time, const type &value)
Definition: Curve.h:2368
void BasisFirstDerivative(const float t, float *bvals) const
Definition: Curve.h:764
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:1399
tuple f
Definition: idal.py:89
void BasisSecondDerivative(const int index, const float t, float *bvals) const
Definition: Curve.h:2126
virtual bool IsDone(const float time) const
Definition: Curve.h:1051
bool RemoveIndex(int index)
Definition: List.h:849
void LU_Solve(idVecX &x, const idVecX &b, const int *index) const
Definition: Matrix.cpp:4308
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:2176
void BasisFirstDerivative(const int index, const float t, float *bvals) const
Definition: Curve.h:2110
idCurve_QuadraticBezier(void)
Definition: Curve.h:689
void SetData(int rows, int columns, float *data)
Definition: Matrix.h:2278
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:845
virtual int AddValue(const float time, const type &value)
Definition: Curve.h:116
void BasisSecondDerivative(const int order, const float t, float *bvals) const
Definition: Curve.h:647
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:2036
idList< type > c
Definition: Curve.h:1078
GLsizei const GLcharARB const GLint * length
Definition: glext.h:3599
void SetData(int length, float *data)
Definition: Vector.h:1756
void Basis(const int index, const float t, float *bvals) const
Definition: Curve.h:1747
virtual type GetCurrentFirstDerivative(const float time) const
Definition: Curve.h:2438
GLint i1
Definition: qgl.h:261
idList< type > values
Definition: Curve.h:74
virtual void Clear(void)
Definition: Curve.h:1546
void MakeUniform(const float totalTime)
Definition: Curve.h:319
void TangentsForIndex(const int index, type &t0, type &t1) const
Definition: Curve.h:1707
GLuint res
Definition: glext.h:5385
GLint j
Definition: qgl.h:264
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:1680
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:165
virtual void Clear(void)
Definition: Curve.h:1070
idCurve_BSpline(void)
Definition: Curve.h:1824
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:512
float GetLengthBetweenKnots(const int i0, const int i1) const
Definition: Curve.h:241
float TimeForIndex(const int index) const
Definition: Curve.h:459
void BasisSecondDerivative(const int index, const float t, float *bvals) const
Definition: Curve.h:1517
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:559
idList< type > b
Definition: Curve.h:1077
int GetNumValues(void) const
Definition: Curve.h:56
float Basis(const int index, const int order, const float t) const
Definition: Curve.h:1917
void Basis(const int index, const int order, const float t, float *bvals) const
Definition: Curve.h:2263
virtual ~idCurve(void)
Definition: Curve.h:104
virtual type GetCurrentValue(const float time) const
Definition: Curve.h:830
void BasisFirstDerivative(const int order, const float t, float *bvals) const
Definition: Curve.h:629
void SetValue(const int index, const type &value)
Definition: Curve.h:57
virtual type GetCurrentSecondDerivative(const float time) const
Definition: Curve.h:732
boundary_t boundaryType
Definition: Curve.h:946
void Basis(const float t, float *bvals) const
Definition: Curve.h:748
GLdouble GLdouble t
Definition: glext.h:2943
void BasisSecondDerivative(const int index, const int order, const float t, float *bvals) const
Definition: Curve.h:2308
void Clear(void)
Definition: List.h:184