29 #ifndef __MATH_CURVE_H__
30 #define __MATH_CURVE_H__
40 template<
class type >
54 virtual bool IsDone(
const float time )
const;
83 float GetSpeed(
const float time )
const;
92 template<
class type >
103 template<
class type >
115 template<
class type >
119 i = IndexForTime( time );
120 times.Insert( time, i );
121 values.Insert( value, i );
133 template<
class type >
137 i = IndexForTime( time );
138 if ( i >=
values.Num() ) {
152 template<
class type >
164 template<
class type >
174 template<
class type >
176 return ( time >= times[ times.Num() - 1 ] );
184 template<
class type >
190 value = GetCurrentFirstDerivative( time );
191 for ( speed = 0.0
f, i = 0; i < value.GetDimension(); i++ ) {
192 speed += value[
i] * value[
i];
202 template<
class type >
208 temp[0] = (
float *) _alloca16( order *
sizeof(
float ) );
209 temp[1] = (
float *) _alloca16( order *
sizeof(
float ) );
212 temp[0][0] = 0.5f * delta * ( GetSpeed( t0 ) + GetSpeed( t1 ) );
214 for ( i = 2, m = 1; i <=
order; i++, m *= 2, delta *= 0.5f ) {
218 for ( j = 1; j <= m; j++ ) {
219 sum += GetSpeed( t0 + delta * ( j - 0.5
f ) );
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 );
228 for ( j = 0; j <
i; j++ ) {
229 temp[0][
j] = temp[1][
j];
232 return temp[0][order-1];
240 template<
class type >
243 for (
int i = i0;
i <
i1;
i++ ) {
244 length += RombergIntegral( times[
i], times[i+1], 5 );
254 template<
class type >
257 int index = IndexForTime( time );
259 length += RombergIntegral( times[
i], times[i+1], 5 );
261 length += RombergIntegral( times[index], time, 5 );
270 template<
class type >
273 float *accumLength, totalLength, len0, len1,
t, diff;
275 if ( length <= 0.0
f ) {
279 accumLength = (
float *) _alloca16(
values.Num() *
sizeof(
float ) );
281 for ( index = 0; index <
values.Num() - 1; index++ ) {
282 totalLength += GetLengthBetweenKnots( index, index + 1 );
283 accumLength[
index] = totalLength;
284 if ( length < accumLength[index] ) {
289 if ( index >=
values.Num() - 1 ) {
290 return times[times.Num() - 1];
295 len1 = accumLength[0];
297 len0 = length - accumLength[index-1];
298 len1 = accumLength[
index] - accumLength[index-1];
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;
308 t -= diff / GetSpeed( times[index] + t );
318 template<
class type >
323 for ( i = 0; i <=
n; i++ ) {
324 times[
i] = i * totalTime /
n;
334 template<
class type >
339 length = (
float *) _alloca16(
values.Num() *
sizeof(
float ) );
341 for ( i = 0; i <
values.Num() - 1; i++ ) {
342 length[
i] = GetLengthBetweenKnots( i, i + 1 );
343 totalLength += length[
i];
345 scale = totalTime / totalLength;
346 for ( t = 0.0
f, i = 0; i < times.Num() - 1; i++ ) {
348 t += scale * length[
i];
350 times[times.Num() - 1] = totalTime;
359 template<
class type >
361 for (
int i = 0;
i < times.Num();
i++ ) {
362 times[
i] += deltaTime;
372 template<
class type >
374 for (
int i = 0;
i <
values.Num();
i++ ) {
387 template<
class type >
391 if ( currentIndex >= 0 && currentIndex <= times.Num() ) {
393 if ( currentIndex == 0 ) {
394 if ( time <= times[currentIndex] ) {
397 }
else if ( currentIndex == times.Num() ) {
398 if ( time > times[currentIndex-1] ) {
401 }
else if ( time > times[currentIndex-1] && time <= times[currentIndex] ) {
403 }
else if ( time > times[currentIndex] && ( currentIndex+1 == times.Num() || time <= times[currentIndex+1] ) ) {
417 if ( time == times[offset+mid] ) {
419 }
else if ( time > times[offset+mid] ) {
428 currentIndex = offset+
res;
439 template<
class type >
445 }
else if ( index > n ) {
458 template<
class type >
460 int n = times.Num()-1;
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] );
480 template<
class type >
490 void Basis(
const int order,
const float t,
float *bvals )
const;
500 template<
class type >
511 template<
class type >
517 bvals = (
float *) _alloca16( this->
values.Num() *
sizeof(
float ) );
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];
534 template<
class type >
540 bvals = (
float *) _alloca16( this->
values.Num() *
sizeof(
float ) );
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];
547 d = ( this->times[this->times.Num()-1] - this->times[0] );
548 return ( (
float) (this->values.Num()-1) / d ) *
v;
558 template<
class type >
564 bvals = (
float *) _alloca16( this->
values.Num() *
sizeof(
float ) );
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];
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;
582 template<
class type >
585 float *
c, c1, c2,
s, o, ps, po;
593 c = (
float *) _alloca16( (d+1) *
sizeof(
float ) );
594 s = (
float) ( t - this->times[0] ) / ( this->times[this->times.Num()-1] - this->times[0] );
599 for ( i = 1; i < d; i++ ) {
602 for ( i = 1; i < d; i++ ) {
606 for ( j = i+1; j <= d; j++ ) {
611 bvals[
i] = c[d] * ps;
614 for ( i = d-1; i >= 0; i-- ) {
628 template<
class type >
632 Basis( order-1, t, bvals+1 );
634 for ( i = 0; i < order-1; i++ ) {
635 bvals[
i] -= bvals[i+1];
646 template<
class type >
650 BasisFirstDerivative( order-1, t, bvals+1 );
652 for ( i = 0; i < order-1; i++ ) {
653 bvals[
i] -= bvals[i+1];
667 template<
class type >
678 void Basis(
const float t,
float *bvals )
const;
688 template<
class type >
700 template<
class type >
704 Basis( time, bvals );
705 return ( bvals[0] * this->
values[0] + bvals[1] * this->
values[1] + bvals[2] * this->
values[2] );
715 template<
class type >
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;
731 template<
class type >
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 );
747 template<
class type >
749 float s1 = (
float) ( t - this->times[0] ) / ( this->times[2] - this->times[0] );
751 bvals[0] = s2 - 2.0f * s1 + 1.0f;
752 bvals[1] = -2.0f * s2 + 2.0f * s1;
763 template<
class type >
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;
778 template<
class type >
796 template<
class type >
807 void Basis(
const float t,
float *bvals )
const;
817 template<
class type >
829 template<
class type >
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] );
844 template<
class type >
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;
860 template<
class type >
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 );
876 template<
class type >
878 float s1 = (
float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] );
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;
894 template<
class type >
896 float s1 = (
float) ( t - this->times[0] ) / ( this->times[3] - this->times[0] );
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;
911 template<
class type >
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;
929 template<
class type >
937 virtual bool IsDone(
const float time )
const;
959 template<
class type >
961 boundaryType = BT_FREE;
972 template<
class type >
977 if ( boundaryType == BT_CLOSED ) {
984 else if ( index > n ) {
985 if ( boundaryType == BT_CLOSED ) {
1002 template<
class type >
1004 int n = this->times.Num()-1;
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()] );
1011 return this->times[0] + index * ( this->times[1] - this->times[0] );
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()];
1019 return this->times[
n] + ( index -
n ) * ( this->times[n] - this->times[n-1] );
1022 return this->times[
index];
1032 template<
class type >
1034 if ( boundaryType == BT_CLAMPED ) {
1036 return this->times[0];
1038 else if ( t >= this->times[this->times.Num()-1] ) {
1039 return this->times[this->times.Num()-1];
1050 template<
class type >
1052 return ( boundaryType != BT_CLOSED && time >= this->times[ this->times.Num() - 1 ] );
1065 template<
class type >
1081 void Setup(
void )
const;
1092 template<
class type >
1103 template<
class type >
1105 float clampedTime = this->ClampedTime( time );
1106 int i = this->IndexForTime( clampedTime );
1107 float s = time - this->TimeForIndex( i );
1109 return ( this->
values[i] + s * (
b[i] + s * (
c[i] + s * d[i] ) ) );
1119 template<
class type >
1121 float clampedTime = this->ClampedTime( time );
1122 int i = this->IndexForTime( clampedTime );
1123 float s = time - this->TimeForIndex( i );
1125 return (
b[i] + s * ( 2.0
f *
c[i] + 3.0
f * s * d[i] ) );
1135 template<
class type >
1137 float clampedTime = this->ClampedTime( time );
1138 int i = this->IndexForTime( clampedTime );
1139 float s = time - this->TimeForIndex( i );
1141 return ( 2.0
f *
c[i] + 6.0
f * s * d[i] );
1149 template<
class type >
1151 if ( this->changed ) {
1152 switch( this->boundaryType ) {
1157 this->changed =
false;
1166 template<
class type >
1170 float *d0, *d1, *beta, *gamma;
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 ) );
1180 for ( i = 0; i < this->
values.Num() - 1; i++ ) {
1181 d0[
i] = this->times[i+1] - this->times[
i];
1184 for ( i = 1; i < this->
values.Num() - 1; i++ ) {
1185 d1[
i] = this->times[i+1] - this->times[i-1];
1188 for ( i = 1; i < this->
values.Num() - 1; i++ ) {
1190 inv = 1.0f / ( d0[i-1] * d0[
i] );
1191 alpha[
i] = inv * sum;
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] );
1204 beta[this->values.Num() - 1] = 1.0f;
1205 delta[this->values.Num() - 1] = this->values[0] - this->values[0];
1207 b.AssureSize( this->values.Num() );
1208 c.AssureSize( this->values.Num() );
1209 d.AssureSize( this->values.Num() );
1211 c[this->values.Num() - 1] = this->values[0] - this->values[0];
1213 for ( i = this->values.Num() - 2; i >= 0; i-- ) {
1214 c[
i] = delta[
i] - gamma[
i] *
c[i+1];
1216 b[
i] = inv * ( this->values[i+1] - this->values[
i] ) - ( 1.0
f / 3.0
f ) * d0[
i] * ( c[i+1] + 2.0f * c[
i] );
1217 d[
i] = ( 1.0f / 3.0f ) * inv * ( c[i+1] - c[i] );
1226 template<
class type >
1230 float *d0, *d1, *beta, *gamma;
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 ) );
1240 for ( i = 0; i < this->
values.Num() - 1; i++ ) {
1241 d0[
i] = this->times[i+1] - this->times[
i];
1244 for ( i = 1; i < this->
values.Num() - 1; i++ ) {
1245 d1[
i] = this->times[i+1] - this->times[i-1];
1249 alpha[0] = 3.0f * ( inv - 1.0f ) * ( this->
values[1] - this->
values[0] );
1250 inv = 1.0f / d0[this->
values.Num() - 2];
1253 for ( i = 1; i < this->
values.Num() - 1; i++ ) {
1255 inv = 1.0f / ( d0[i-1] * d0[
i] );
1256 alpha[
i] = inv * sum;
1259 beta[0] = 2.0f * d0[0];
1261 inv = 1.0f / beta[0];
1262 delta[0] = inv * alpha[0];
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] );
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] );
1275 b.AssureSize( this->
values.Num() );
1276 c.AssureSize( this->
values.Num() );
1277 d.AssureSize( this->
values.Num() );
1281 for ( i = this->
values.Num() - 2; i >= 0; i-- ) {
1282 c[
i] = delta[
i] - gamma[
i] *
c[i+1];
1284 b[
i] = inv * ( this->
values[i+1] - this->
values[
i] ) - ( 1.0
f / 3.0
f ) * d0[
i]* ( c[i+1] + 2.0f * c[
i] );
1285 d[
i] = ( 1.0f / 3.0f ) * inv * ( c[i+1] - c[i] );
1294 template<
class type >
1302 d0 = (
float *) _alloca16( ( this->
values.Num() - 1 ) *
sizeof(
float ) );
1306 b.AssureSize( this->
values.Num() );
1307 c.AssureSize( this->
values.Num() );
1308 d.AssureSize( this->
values.Num() );
1310 for ( i = 0; i < this->
values.Num() - 1; i++ ) {
1311 d0[
i] = this->times[i+1] - this->times[
i];
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];
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];
1328 for ( i = 1; i <= this->
values.Num() - 2; i++ ) {
1330 c1 = 1.0f / d0[i-1];
1334 c1 = 1.0f / d0[this->
values.Num() - 2];
1339 for ( i = 0; i < this->
values[0].GetDimension(); i++ ) {
1340 for ( j = 0; j < this->
values.Num(); j++ ) {
1344 for ( j = 0; j < this->
values.Num(); j++ ) {
1349 for ( i = 0; i < this->
values.Num() - 1; i++ ) {
1351 b[
i] = c0 * ( this->
values[i + 1] - this->
values[
i] ) - ( 1.0
f / 3.0
f ) * (
c[i+1] + 2.0f *
c[
i] ) * d0[i];
1352 d[
i] = ( 1.0f / 3.0f ) * c0 * (
c[i + 1] -
c[i] );
1366 template<
class type >
1377 void Basis(
const int index,
const float t,
float *bvals )
const;
1387 template<
class type >
1398 template<
class type >
1401 float bvals[4], clampedTime;
1404 if ( this->times.Num() == 1 ) {
1408 clampedTime = this->ClampedTime( time );
1409 i = this->IndexForTime( clampedTime );
1410 Basis( i-1, clampedTime, bvals );
1412 for ( j = 0; j < 4; j++ ) {
1414 v += bvals[
j] * this->ValueForIndex( k );
1426 template<
class type >
1429 float bvals[4], d, clampedTime;
1432 if ( this->times.Num() == 1 ) {
1436 clampedTime = this->ClampedTime( time );
1437 i = this->IndexForTime( clampedTime );
1438 BasisFirstDerivative( i-1, clampedTime, bvals );
1440 for ( j = 0; j < 4; j++ ) {
1442 v += bvals[
j] * this->ValueForIndex( k );
1444 d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
1455 template<
class type >
1458 float bvals[4], d, clampedTime;
1461 if ( this->times.Num() == 1 ) {
1465 clampedTime = this->ClampedTime( time );
1466 i = this->IndexForTime( clampedTime );
1467 BasisSecondDerivative( i-1, clampedTime, bvals );
1469 for ( j = 0; j < 4; j++ ) {
1471 v += bvals[
j] * this->ValueForIndex( k );
1473 d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
1474 return v / ( d * d );
1484 template<
class type >
1486 float s = (
float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
1487 bvals[0] = ( ( -s + 2.0f ) * s - 1.0
f ) * s * 0.5f;
1488 bvals[1] = ( ( ( 3.0f * s - 5.0f ) * s ) * s + 2.0f ) * 0.5
f;
1489 bvals[2] = ( ( -3.0f * s + 4.0f ) * s + 1.0
f ) * s * 0.5f;
1490 bvals[3] = ( ( s - 1.0f ) * s * s ) * 0.5f;
1500 template<
class type >
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.5
f;
1504 bvals[1] = ( 4.5f * s - 5.0f ) * s;
1505 bvals[2] = ( -4.5 * s + 4.0f ) * s + 0.5
f;
1506 bvals[3] = 1.5f * s * s -
s;
1516 template<
class type >
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;
1537 template<
class type >
1559 void Basis(
const int index,
const float t,
float *bvals )
const;
1569 template<
class type >
1581 template<
class type >
1585 i = this->IndexForTime( time );
1586 this->times.Insert( time, i );
1587 this->
values.Insert( value, i );
1588 tension.Insert( 0.0
f, i );
1589 continuity.Insert( 0.0
f, i );
1590 bias.Insert( 0.0
f, i );
1602 template<
class type >
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 );
1622 template<
class type >
1625 float bvals[4], clampedTime;
1628 if ( this->times.Num() == 1 ) {
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 );
1650 template<
class type >
1653 float bvals[4], d, clampedTime;
1656 if ( this->times.Num() == 1 ) {
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 );
1668 d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
1679 template<
class type >
1682 float bvals[4], d, clampedTime;
1685 if ( this->times.Num() == 1 ) {
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 );
1697 d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
1698 return v / ( d * d );
1706 template<
class type >
1708 float dt, omt, omc, opc, omb, opb, adj, s0, s1;
1711 delta = this->ValueForIndex( index + 1 ) - this->ValueForIndex( index );
1712 dt = this->TimeForIndex( index + 1 ) - this->TimeForIndex( index );
1714 omt = 1.0f - tension[
index];
1715 omc = 1.0f - continuity[
index];
1716 opc = 1.0f + continuity[
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;
1724 t0 = s1 * delta + s0 * ( this->ValueForIndex( index ) - this->ValueForIndex( index - 1 ) );
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;
1736 t1 = s1 * ( this->ValueForIndex( index + 2 ) - this->ValueForIndex( index + 1 ) ) + s0 * delta;
1746 template<
class type >
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;
1750 bvals[1] = ( ( -2.0f * s + 3.0f ) * s ) *
s;
1751 bvals[2] = ( ( s - 2.0f ) * s ) * s +
s;
1752 bvals[3] = ( ( s - 1.0f ) * s ) *
s;
1762 template<
class type >
1764 float s = (
float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
1765 bvals[0] = ( 6.0f * s - 6.0f ) * s;
1766 bvals[1] = ( -6.0f * s + 6.0f ) * s;
1767 bvals[2] = ( 3.0f * s - 4.0f ) * s + 1.0
f;
1768 bvals[3] = ( 3.0f * s - 2.0f ) * s;
1778 template<
class type >
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;
1797 template<
class type >
1823 template<
class type >
1835 template<
class type >
1841 if ( this->times.Num() == 1 ) {
1845 clampedTime = this->ClampedTime( time );
1846 i = this->IndexForTime( clampedTime );
1848 for ( j = 0; j <
order; j++ ) {
1849 k = i + j - ( order >> 1 );
1850 v += Basis( k-2, order, clampedTime ) * this->ValueForIndex( k );
1862 template<
class type >
1868 if ( this->times.Num() == 1 ) {
1872 clampedTime = this->ClampedTime( time );
1873 i = this->IndexForTime( clampedTime );
1875 for ( j = 0; j <
order; j++ ) {
1876 k = i + j - ( order >> 1 );
1877 v += BasisFirstDerivative( k-2, order, clampedTime ) * this->ValueForIndex( k );
1889 template<
class type >
1895 if ( this->times.Num() == 1 ) {
1899 clampedTime = this->ClampedTime( time );
1900 i = this->IndexForTime( clampedTime );
1902 for ( j = 0; j <
order; j++ ) {
1903 k = i + j - ( order >> 1 );
1904 v += BasisSecondDerivative( k-2, order, clampedTime ) * this->ValueForIndex( k );
1916 template<
class type >
1919 if ( this->TimeForIndex( index ) < t &&
t <= this->TimeForIndex( index + 1 ) ) {
1926 float d1 = this->TimeForIndex( index+order-1 ) - this->TimeForIndex( index );
1928 sum += (
float) ( t - this->TimeForIndex( index ) ) * Basis( index, order-1, t ) / d1;
1931 float d2 = this->TimeForIndex( index+order ) - this->TimeForIndex( index+1 );
1933 sum += (
float) ( this->TimeForIndex( index+order ) -
t ) * Basis( index+1, order-1, t ) / d2;
1946 template<
class type >
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 ) );
1959 template<
class type >
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 ) );
1974 template<
class type >
1985 void Basis(
const int index,
const float t,
float *bvals )
const;
1995 template<
class type >
2007 template<
class type >
2010 float bvals[4], clampedTime;
2013 if ( this->times.Num() == 1 ) {
2017 clampedTime = this->ClampedTime( time );
2018 i = this->IndexForTime( clampedTime );
2019 Basis( i-1, clampedTime, bvals );
2021 for ( j = 0; j < 4; j++ ) {
2023 v += bvals[
j] * this->ValueForIndex( k );
2035 template<
class type >
2038 float bvals[4], d, clampedTime;
2041 if ( this->times.Num() == 1 ) {
2045 clampedTime = this->ClampedTime( time );
2046 i = this->IndexForTime( clampedTime );
2047 BasisFirstDerivative( i-1, clampedTime, bvals );
2049 for ( j = 0; j < 4; j++ ) {
2051 v += bvals[
j] * this->ValueForIndex( k );
2053 d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
2064 template<
class type >
2067 float bvals[4], d, clampedTime;
2070 if ( this->times.Num() == 1 ) {
2074 clampedTime = this->ClampedTime( time );
2075 i = this->IndexForTime( clampedTime );
2076 BasisSecondDerivative( i-1, clampedTime, bvals );
2078 for ( j = 0; j < 4; j++ ) {
2080 v += bvals[
j] * this->ValueForIndex( k );
2082 d = ( this->TimeForIndex( i ) - this->TimeForIndex( i-1 ) );
2083 return v / ( d * d );
2093 template<
class type >
2095 float s = (
float) ( t - this->TimeForIndex( index ) ) / ( this->TimeForIndex( index+1 ) - this->TimeForIndex( index ) );
2096 bvals[0] = ( ( ( -s + 3.0f ) * s - 3.0
f ) * s + 1.0f ) * ( 1.0
f / 6.0
f );
2097 bvals[1] = ( ( ( 3.0f * s - 6.0f ) * s ) * s + 4.0f ) * ( 1.0
f / 6.0
f );
2098 bvals[2] = ( ( ( -3.0f * s + 3.0f ) * s + 3.0
f ) * s + 1.0f ) * ( 1.0
f / 6.0
f );
2099 bvals[3] = ( s * s *
s ) * ( 1.0
f / 6.0
f );
2109 template<
class type >
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;
2125 template<
class type >
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;
2143 template<
class type >
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;
2164 template<
class type >
2175 template<
class type >
2180 float *bvals = (
float *) _alloca16( this->
order *
sizeof(
float) );
2182 if ( this->times.Num() == 1 ) {
2186 clampedTime = this->ClampedTime( time );
2187 i = this->IndexForTime( clampedTime );
2188 Basis( i-1, this->
order, clampedTime, bvals );
2190 for ( j = 0; j < this->
order; j++ ) {
2191 k = i + j - ( this->order >> 1 );
2192 v += bvals[
j] * this->ValueForIndex( k );
2204 template<
class type >
2209 float *bvals = (
float *) _alloca16( this->
order *
sizeof(
float) );
2211 if ( this->times.Num() == 1 ) {
2215 clampedTime = this->ClampedTime( time );
2216 i = this->IndexForTime( clampedTime );
2217 BasisFirstDerivative( i-1, this->
order, clampedTime, bvals );
2219 for ( j = 0; j < this->
order; j++ ) {
2220 k = i + j - ( this->order >> 1 );
2221 v += bvals[
j] * this->ValueForIndex( k );
2233 template<
class type >
2238 float *bvals = (
float *) _alloca16( this->
order *
sizeof(
float) );
2240 if ( this->times.Num() == 1 ) {
2244 clampedTime = this->ClampedTime( time );
2245 i = this->IndexForTime( clampedTime );
2246 BasisSecondDerivative( i-1, this->
order, clampedTime, bvals );
2248 for ( j = 0; j < this->
order; j++ ) {
2249 k = i + j - ( this->order >> 1 );
2250 v += bvals[
j] * this->ValueForIndex( k );
2262 template<
class type >
2267 bvals[order-1] = 1.0f;
2268 for ( r = 2; r <=
order; r++ ) {
2270 bvals[order -
r] = 0.0f;
2271 for ( s = order - r + 1; s <
order; s++ ) {
2273 omega = (
float) ( t - this->TimeForIndex( i ) ) / ( this->TimeForIndex( i + r - 1 ) - this->TimeForIndex( i ) );
2274 bvals[s - 1] += ( 1.0f - omega ) * bvals[s];
2287 template<
class type >
2291 Basis( index, order-1, t, bvals+1 );
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 ) );
2297 bvals[
i] *= (
float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) );
2307 template<
class type >
2311 BasisFirstDerivative( index, order-1, t, bvals+1 );
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 ) );
2317 bvals[
i] *= (
float) ( order - 1) / ( this->TimeForIndex( index + i + (order-1) - 2 ) - this->TimeForIndex( index + i - 2 ) );
2329 template<
class type >
2336 virtual int AddValue(
const float time,
const type &value,
const float weight );
2355 template<
class type >
2367 template<
class type >
2371 i = this->IndexForTime( time );
2372 this->times.Insert( time, i );
2373 this->
values.Insert( value, i );
2386 template<
class type >
2390 i = this->IndexForTime( time );
2391 this->times.Insert( time, i );
2392 this->
values.Insert( value, i );
2404 template<
class type >
2407 float w,
b, *bvals, clampedTime;
2410 if ( this->times.Num() == 1 ) {
2414 bvals = (
float *) _alloca16( this->
order *
sizeof(
float) );
2416 clampedTime = this->ClampedTime( time );
2417 i = this->IndexForTime( clampedTime );
2418 this->Basis( i-1, this->
order, clampedTime, bvals );
2421 for ( j = 0; j < this->
order; j++ ) {
2422 k = i + j - ( this->order >> 1 );
2423 b = bvals[
j] * WeightForIndex( k );
2425 v += b * this->ValueForIndex( k );
2437 template<
class type >
2440 float w, wb, wd1,
b, d1, *bvals, *d1vals, clampedTime;
2443 if ( this->times.Num() == 1 ) {
2447 bvals = (
float *) _alloca16( this->
order *
sizeof(
float) );
2448 d1vals = (
float *) _alloca16( this->
order *
sizeof(
float) );
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 );
2456 for ( j = 0; j < this->
order; j++ ) {
2457 k = i + j - ( this->order >> 1 );
2458 w = WeightForIndex( k );
2463 v = this->ValueForIndex( k );
2467 return ( wb * vd1 - vb * wd1 ) / ( wb * wb );
2477 template<
class type >
2480 float w, wb, wd1, wd2,
b, d1, d2, *bvals, *d1vals, *d2vals, clampedTime;
2481 type v, vb, vd1, vd2;
2483 if ( this->times.Num() == 1 ) {
2487 bvals = (
float *) _alloca16( this->
order *
sizeof(
float) );
2488 d1vals = (
float *) _alloca16( this->
order *
sizeof(
float) );
2489 d2vals = (
float *) _alloca16( this->
order *
sizeof(
float) );
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 );
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 );
2507 v = this->ValueForIndex( k );
2512 return ( ( wb * wb ) * ( wb * vd2 - vb * wd2 ) - ( wb * vd1 - vb * wd1 ) * 2.0
f * wb * wd1 ) / ( wb * wb * wb * wb );
2522 template<
class type >
2532 }
else if ( index > n ) {
virtual boundary_t GetBoundaryType(void) const
void Translate(const type &translation)
virtual type GetCurrentValue(const float time) const
GLboolean GLenum GLenum GLvoid * values
GLsizei const GLfloat * value
virtual type GetCurrentFirstDerivative(const float time) const
type GetValue(const int index) const
void SetupClamped(void) const
type ValueForIndex(const int index) const
assert(prefInfo.fullscreenBtn)
virtual type GetCurrentFirstDerivative(const float time) const
virtual int AddValue(const float time, const type &value)
void SetupFree(void) const
void BasisSecondDerivative(const int index, const float t, float *bvals) const
GLenum GLenum GLenum GLenum GLenum scale
bool LU_Factor(int *index, float *det=NULL)
virtual int GetOrder(void) const
float WeightForIndex(const int index) const
virtual void SetBoundaryType(const boundary_t bt)
virtual type GetCurrentFirstDerivative(const float time) const
virtual type GetCurrentSecondDerivative(const float time) const
void SetConstantSpeed(const float totalTime)
void BasisSecondDerivative(const float t, float *bvals) const
void SetupClosed(void) const
static float Sqrt(float x)
virtual type GetCurrentSecondDerivative(const float time) const
type * GetValueAddress(const int index)
GLuint GLuint GLsizei GLenum type
void BasisFirstDerivative(const float t, float *bvals) const
GLclampf GLclampf GLclampf alpha
virtual type GetCurrentFirstDerivative(const float time) const
virtual float GetCloseTime(void)
void ShiftTime(const float deltaTime)
idCurve_NaturalCubicSpline(void)
float TimeForIndex(const int index) const
virtual void RemoveIndex(const int index)
idList< float > continuity
virtual void SetCloseTime(const float t)
virtual void SetOrder(const int i)
float ClampedTime(const float t) const
void Basis(const int index, const float t, float *bvals) const
GLdouble GLdouble GLint GLint order
float GetLengthForTime(const float time) const
GLubyte GLubyte GLubyte GLubyte w
virtual type GetCurrentSecondDerivative(const float time) const
float BasisFirstDerivative(const int index, const int order, const float t) const
virtual void RemoveIndex(const int index)
float RombergIntegral(const float t0, const float t1, const int order) const
float GetTimeForLength(const float length, const float epsilon=0.1f) const
idCurve_CatmullRomSpline(void)
float BasisSecondDerivative(const int index, const int order, const float t) const
virtual type GetCurrentSecondDerivative(const float time) const
virtual type GetCurrentValue(const float time) const
static float Fabs(float f)
void BasisFirstDerivative(const int index, const float t, float *bvals) const
void Basis(const int order, const float t, float *bvals) const
virtual type GetCurrentFirstDerivative(const float time) const
idCurve_CubicBezier(void)
virtual type GetCurrentSecondDerivative(const float time) const
virtual type GetCurrentValue(const float time) const
type ValueForIndex(const int index) const
int IndexForTime(const float time) const
virtual bool IsDone(const float time) const
virtual type GetCurrentValue(const float time) const
virtual type GetCurrentFirstDerivative(const float time) const
void Basis(const float t, float *bvals) const
float GetSpeed(const float time) const
void BasisFirstDerivative(const int index, const float t, float *bvals) const
virtual type GetCurrentValue(const float time) const
float GetTime(const int index) const
void BasisSecondDerivative(const float t, float *bvals) const
virtual type GetCurrentValue(const float time) const
virtual void RemoveIndex(const int index)
virtual type GetCurrentFirstDerivative(const float time) const
GLdouble GLdouble GLdouble r
virtual int AddValue(const float time, const type &value)
void BasisFirstDerivative(const float t, float *bvals) const
virtual type GetCurrentValue(const float time) const
virtual bool IsDone(const float time) const
bool RemoveIndex(int index)
void LU_Solve(idVecX &x, const idVecX &b, const int *index) const
idCurve_QuadraticBezier(void)
void SetData(int rows, int columns, float *data)
virtual type GetCurrentFirstDerivative(const float time) const
virtual int AddValue(const float time, const type &value)
void BasisSecondDerivative(const int order, const float t, float *bvals) const
GLsizei const GLcharARB const GLint * length
idCurve_KochanekBartelsSpline(void)
void SetData(int length, float *data)
void Basis(const int index, const float t, float *bvals) const
virtual type GetCurrentFirstDerivative(const float time) const
void MakeUniform(const float totalTime)
void TangentsForIndex(const int index, type &t0, type &t1) const
virtual type GetCurrentSecondDerivative(const float time) const
virtual type GetCurrentSecondDerivative(const float time) const
virtual type GetCurrentValue(const float time) const
float GetLengthBetweenKnots(const int i0, const int i1) const
float TimeForIndex(const int index) const
void BasisSecondDerivative(const int index, const float t, float *bvals) const
virtual type GetCurrentSecondDerivative(const float time) const
int GetNumValues(void) const
float Basis(const int index, const int order, const float t) const
virtual type GetCurrentValue(const float time) const
void BasisFirstDerivative(const int order, const float t, float *bvals) const
void SetValue(const int index, const type &value)
virtual type GetCurrentSecondDerivative(const float time) const
void Basis(const float t, float *bvals) const