Revision 649544b8
Added by Leszek Koltunski about 9 years ago
| src/main/java/org/distorted/library/type/Dynamic.java | ||
|---|---|---|
| 102 | 102 |
|
| 103 | 103 |
protected Vector<VectorNoise> vn; |
| 104 | 104 |
protected float[] mFactor; |
| 105 |
protected float[][] baseV; |
|
| 106 |
private float[] buffer; |
|
| 107 |
|
|
| 108 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 109 |
// the coefficients of the X(t), Y(t) and Z(t) polynomials: X(t) = ax*T^3 + bx*T^2 + cx*t + dx etc. |
|
| 110 |
// (tangent) is the vector tangent to the path. |
|
| 111 |
// (cached) is the original vector from vv (copied here so when interpolating we can see if it is |
|
| 112 |
// still valid and if not - rebuild the Cache |
|
| 113 |
|
|
| 114 |
protected class VectorCache |
|
| 115 |
{
|
|
| 116 |
float[] a; |
|
| 117 |
float[] b; |
|
| 118 |
float[] c; |
|
| 119 |
float[] d; |
|
| 120 |
float[] tangent; |
|
| 121 |
float[] cached; |
|
| 122 |
|
|
| 123 |
VectorCache(int dim) |
|
| 124 |
{
|
|
| 125 |
a = new float[dim]; |
|
| 126 |
b = new float[dim]; |
|
| 127 |
c = new float[dim]; |
|
| 128 |
d = new float[dim]; |
|
| 129 |
tangent = new float[dim]; |
|
| 130 |
cached = new float[dim]; |
|
| 131 |
} |
|
| 132 |
} |
|
| 133 |
|
|
| 134 |
protected Vector<VectorCache> vc; |
|
| 135 |
protected VectorCache tmp1, tmp2; |
|
| 105 | 136 |
|
| 106 | 137 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 107 | 138 |
// hide this from Javadoc |
| 108 | 139 |
|
| 109 |
Dynamic() |
|
| 140 |
protected Dynamic() |
|
| 141 |
{
|
|
| 142 |
} |
|
| 143 |
|
|
| 144 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 145 |
|
|
| 146 |
protected Dynamic(int duration, float count, int dimension) |
|
| 110 | 147 |
{
|
| 148 |
vc = new Vector<>(); |
|
| 149 |
vn = null; |
|
| 150 |
numPoints = 0; |
|
| 151 |
cacheDirty = false; |
|
| 152 |
mMode = MODE_LOOP; |
|
| 153 |
mDuration = duration; |
|
| 154 |
mCount = count; |
|
| 155 |
mDimension = dimension; |
|
| 156 |
|
|
| 157 |
baseV = new float[mDimension][mDimension]; |
|
| 158 |
buffer= new float[mDimension]; |
|
| 111 | 159 |
} |
| 112 | 160 |
|
| 113 | 161 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 194 | 242 |
} |
| 195 | 243 |
} |
| 196 | 244 |
|
| 245 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 246 |
// debugging only |
|
| 247 |
|
|
| 248 |
private void printBase(String str) |
|
| 249 |
{
|
|
| 250 |
String s; |
|
| 251 |
float t; |
|
| 252 |
|
|
| 253 |
for(int i=0; i<mDimension; i++) |
|
| 254 |
{
|
|
| 255 |
s = ""; |
|
| 256 |
|
|
| 257 |
for(int j=0; j<mDimension; j++) |
|
| 258 |
{
|
|
| 259 |
t = ((int)(1000*baseV[i][j]))/(1000.0f); |
|
| 260 |
s+=(" "+t);
|
|
| 261 |
} |
|
| 262 |
android.util.Log.e("dynamic", str+" base "+i+" : " + s);
|
|
| 263 |
} |
|
| 264 |
} |
|
| 265 |
|
|
| 266 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 267 |
// debugging only |
|
| 268 |
|
|
| 269 |
private void checkBase() |
|
| 270 |
{
|
|
| 271 |
float tmp; |
|
| 272 |
|
|
| 273 |
for(int i=0; i<mDimension; i++) |
|
| 274 |
for(int j=i+1; j<mDimension; j++) |
|
| 275 |
{
|
|
| 276 |
tmp = 0.0f; |
|
| 277 |
|
|
| 278 |
for(int k=0; k<mDimension; k++) |
|
| 279 |
{
|
|
| 280 |
tmp += baseV[i][k]*baseV[j][k]; |
|
| 281 |
} |
|
| 282 |
|
|
| 283 |
android.util.Log.e("dynamic", "vectors "+i+" and "+j+" : "+tmp);
|
|
| 284 |
} |
|
| 285 |
|
|
| 286 |
for(int i=0; i<mDimension; i++) |
|
| 287 |
{
|
|
| 288 |
tmp = 0.0f; |
|
| 289 |
|
|
| 290 |
for(int k=0; k<mDimension; k++) |
|
| 291 |
{
|
|
| 292 |
tmp += baseV[i][k]*baseV[i][k]; |
|
| 293 |
} |
|
| 294 |
|
|
| 295 |
android.util.Log.e("dynamic", "length of vector "+i+" : "+Math.sqrt(tmp));
|
|
| 296 |
} |
|
| 297 |
} |
|
| 298 |
|
|
| 299 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 300 |
// helper function in case we are interpolating through exactly 2 points |
|
| 301 |
|
|
| 302 |
protected void computeOrthonormalBase2(Static1D curr, Static1D next) |
|
| 303 |
{
|
|
| 304 |
switch(mDimension) |
|
| 305 |
{
|
|
| 306 |
case 1: baseV[0][0] = (next.x-curr.x); |
|
| 307 |
break; |
|
| 308 |
case 2: Static2D curr2 = (Static2D)curr; |
|
| 309 |
Static2D next2 = (Static2D)next; |
|
| 310 |
baseV[0][0] = (next2.x-curr2.x); |
|
| 311 |
baseV[0][1] = (next2.y-curr2.y); |
|
| 312 |
break; |
|
| 313 |
case 3: Static3D curr3 = (Static3D)curr; |
|
| 314 |
Static3D next3 = (Static3D)next; |
|
| 315 |
baseV[0][0] = (next3.x-curr3.x); |
|
| 316 |
baseV[0][1] = (next3.y-curr3.y); |
|
| 317 |
baseV[0][2] = (next3.z-curr3.z); |
|
| 318 |
break; |
|
| 319 |
case 4: Static4D curr4 = (Static4D)curr; |
|
| 320 |
Static4D next4 = (Static4D)next; |
|
| 321 |
baseV[0][0] = (next4.x-curr4.x); |
|
| 322 |
baseV[0][1] = (next4.y-curr4.y); |
|
| 323 |
baseV[0][2] = (next4.z-curr4.z); |
|
| 324 |
baseV[0][3] = (next4.w-curr4.w); |
|
| 325 |
break; |
|
| 326 |
case 5: Static5D curr5 = (Static5D)curr; |
|
| 327 |
Static5D next5 = (Static5D)next; |
|
| 328 |
baseV[0][0] = (next5.x-curr5.x); |
|
| 329 |
baseV[0][1] = (next5.y-curr5.y); |
|
| 330 |
baseV[0][2] = (next5.z-curr5.z); |
|
| 331 |
baseV[0][3] = (next5.w-curr5.w); |
|
| 332 |
baseV[0][4] = (next5.v-curr5.v); |
|
| 333 |
break; |
|
| 334 |
default: throw new RuntimeException("Unsupported dimension");
|
|
| 335 |
} |
|
| 336 |
|
|
| 337 |
if( baseV[0][0] == 0.0f ) |
|
| 338 |
{
|
|
| 339 |
baseV[1][0] = 1.0f; |
|
| 340 |
baseV[1][1] = 0.0f; |
|
| 341 |
} |
|
| 342 |
else |
|
| 343 |
{
|
|
| 344 |
baseV[1][0] = 0.0f; |
|
| 345 |
baseV[1][1] = 1.0f; |
|
| 346 |
} |
|
| 347 |
|
|
| 348 |
for(int i=2; i<mDimension; i++) |
|
| 349 |
{
|
|
| 350 |
baseV[1][i] = 0.0f; |
|
| 351 |
} |
|
| 352 |
|
|
| 353 |
computeOrthonormalBase(); |
|
| 354 |
} |
|
| 355 |
|
|
| 356 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 357 |
// helper function in case we are interpolating through more than 2 points |
|
| 358 |
|
|
| 359 |
protected void computeOrthonormalBaseMore(float time,VectorCache vc) |
|
| 360 |
{
|
|
| 361 |
for(int i=0; i<mDimension; i++) |
|
| 362 |
{
|
|
| 363 |
baseV[0][i] = (3*vc.a[i]*time+2*vc.b[i])*time+vc.c[i]; |
|
| 364 |
baseV[1][i] = 6*vc.a[i]*time+2*vc.b[i]; |
|
| 365 |
} |
|
| 366 |
|
|
| 367 |
computeOrthonormalBase(); |
|
| 368 |
} |
|
| 369 |
|
|
| 370 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 371 |
// When this function gets called, baseV[0] and baseV[1] should have been filled with two mDimension-al |
|
| 372 |
// vectors. This function then fills the rest of the baseV array with a mDimension-al Orthonormal base. |
|
| 373 |
// (mDimension-2 vectors, pairwise orthogonal to each other and to the original 2). The function always |
|
| 374 |
// leaves base[0] alone but generally speaking must adjust base[1] to make it orthogonal to base[0]! |
|
| 375 |
// The whole baseV is then used to compute Noise. |
|
| 376 |
// |
|
| 377 |
// When computing noise of a point travelling along a N-dimensional path, there are three cases: |
|
| 378 |
// a) we may be interpolating through 1 point, i.e. standing in place - nothing to do in this case |
|
| 379 |
// b) we may be interpolating through 2 points, i.e. travelling along a straight line between them - |
|
| 380 |
// then pass the velocity vector in baseV[0] and anything linearly independent in base[1]. |
|
| 381 |
// The output will then be discontinuous in dimensions>2 (sad corollary from the Hairy Ball Theorem) |
|
| 382 |
// but we don't care - we are travelling along a straight line, so velocity (aka baseV[0]!) does |
|
| 383 |
// not change. |
|
| 384 |
// c) we may be interpolating through more than 2 points. Then interpolation formulas ensure the path |
|
| 385 |
// will never be a straight line, even locally -> we can pass in baseV[0] and baseV[1] the velocity |
|
| 386 |
// and the acceleration (first and second derivatives of the path) which are then guaranteed to be |
|
| 387 |
// linearly independent. Then we can ensure this is continuous in dimensions <=4. This leaves |
|
| 388 |
// dimension 5 (ATM WAVE is 5-dimensional) discontinuous -> WAVE will suffer from chaotic noise. |
|
| 389 |
// |
|
| 390 |
// Bear in mind here the 'normal' in 'orthonormal' means 'length equal to the length of the original |
|
| 391 |
// velocity vector' (rather than the standard 1) |
|
| 392 |
|
|
| 393 |
protected void computeOrthonormalBase() |
|
| 394 |
{
|
|
| 395 |
int non_zeros=0; |
|
| 396 |
int last_non_zero=-1; |
|
| 397 |
float value; |
|
| 398 |
for(int i=0; i<mDimension; i++) |
|
| 399 |
{
|
|
| 400 |
value = baseV[0][i]; |
|
| 401 |
|
|
| 402 |
if( value != 0.0f ) |
|
| 403 |
{
|
|
| 404 |
non_zeros++; |
|
| 405 |
last_non_zero=i; |
|
| 406 |
} |
|
| 407 |
} |
|
| 408 |
// velocity is the 0 vector -> two consecutive points we are interpolating |
|
| 409 |
if( non_zeros==0 ) // through are identical -> no noise, set the base to 0 vectors. |
|
| 410 |
{
|
|
| 411 |
for(int i=0; i<mDimension-1; i++) |
|
| 412 |
for(int j=0; j<mDimension; j++) |
|
| 413 |
baseV[i+1][j]= 0.0f; |
|
| 414 |
} |
|
| 415 |
else |
|
| 416 |
{
|
|
| 417 |
for(int i=0; i<mDimension-1; i++) |
|
| 418 |
for(int j=0; j<mDimension; j++) |
|
| 419 |
{
|
|
| 420 |
if( (i<last_non_zero && j==i) || (i>=last_non_zero && j==i+1) ) |
|
| 421 |
baseV[i+1][j]= baseV[0][last_non_zero]; |
|
| 422 |
else |
|
| 423 |
baseV[i+1][j]= 0.0f; |
|
| 424 |
} |
|
| 425 |
|
|
| 426 |
// That's it if velocity vector is already one of the standard orthonormal |
|
| 427 |
// vectors. Otherwise (i.e. non_zeros>1) velocity is linearly independent |
|
| 428 |
// to what's in baseV right now and we can use (modified!) Gram-Schmidt. |
|
| 429 |
// |
|
| 430 |
// b[0] = b[0] |
|
| 431 |
// b[1] = b[1] - (<b[1],b[0]>/<b[0],b[0]>)*b[0] |
|
| 432 |
// b[2] = b[2] - (<b[2],b[0]>/<b[0],b[0]>)*b[0] - (<b[2],b[1]>/<b[1],b[1]>)*b[1] |
|
| 433 |
// b[3] = b[3] - (<b[3],b[0]>/<b[0],b[0]>)*b[0] - (<b[3],b[1]>/<b[1],b[1]>)*b[1] - (<b[3],b[2]>/<b[2],b[2]>)*b[2] |
|
| 434 |
// |
|
| 435 |
// then b[i] = b[i] / |b[i]| |
|
| 436 |
|
|
| 437 |
if( non_zeros>1 ) |
|
| 438 |
{
|
|
| 439 |
float tmp; |
|
| 440 |
|
|
| 441 |
for(int i=1; i<mDimension; i++) |
|
| 442 |
{
|
|
| 443 |
buffer[i-1]=0.0f; |
|
| 444 |
|
|
| 445 |
for(int k=0; k<mDimension; k++) |
|
| 446 |
{
|
|
| 447 |
value = baseV[i-1][k]; |
|
| 448 |
buffer[i-1] += value*value; |
|
| 449 |
} |
|
| 450 |
|
|
| 451 |
for(int j=0; j<i; j++) |
|
| 452 |
{
|
|
| 453 |
tmp = 0.0f; |
|
| 454 |
|
|
| 455 |
for(int k=0;k<mDimension; k++) |
|
| 456 |
{
|
|
| 457 |
tmp += baseV[i][k]*baseV[j][k]; |
|
| 458 |
} |
|
| 459 |
|
|
| 460 |
tmp /= buffer[j]; |
|
| 461 |
|
|
| 462 |
for(int k=0;k<mDimension; k++) |
|
| 463 |
{
|
|
| 464 |
baseV[i][k] -= tmp*baseV[j][k]; |
|
| 465 |
} |
|
| 466 |
} |
|
| 467 |
} |
|
| 468 |
|
|
| 469 |
buffer[mDimension-1]=0.0f; |
|
| 470 |
for(int k=0; k<mDimension; k++) |
|
| 471 |
{
|
|
| 472 |
value = baseV[mDimension-1][k]; |
|
| 473 |
buffer[mDimension-1] += value*value; |
|
| 474 |
} |
|
| 475 |
|
|
| 476 |
for(int i=1; i<mDimension; i++) |
|
| 477 |
{
|
|
| 478 |
tmp = (float)Math.sqrt(buffer[0]/buffer[i]); |
|
| 479 |
|
|
| 480 |
for(int k=0;k<mDimension; k++) |
|
| 481 |
{
|
|
| 482 |
baseV[i][k] *= tmp; |
|
| 483 |
} |
|
| 484 |
} |
|
| 485 |
} |
|
| 486 |
} |
|
| 487 |
|
|
| 488 |
//printBase("end");
|
|
| 489 |
//checkBase(); |
|
| 490 |
} |
|
| 491 |
|
|
| 197 | 492 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 198 | 493 |
// internal debugging only! |
| 199 | 494 |
|
| src/main/java/org/distorted/library/type/Dynamic1D.java | ||
|---|---|---|
| 29 | 29 |
|
| 30 | 30 |
public class Dynamic1D extends Dynamic implements Data1D |
| 31 | 31 |
{
|
| 32 |
|
|
| 33 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 34 |
// the coefficients of the X(t) polynomials: X(t) = ax*T^3 + bx*T^2 + cx*t + dx etc. |
|
| 35 |
// (x) is the vector tangent to the path. |
|
| 36 |
// (vx) is the original vector from vv (copied here so when interpolating we can see if it is |
|
| 37 |
// still valid and if not - rebuild the Cache |
|
| 38 |
|
|
| 39 |
private class VectorCache |
|
| 40 |
{
|
|
| 41 |
float ax, bx, cx, dx; |
|
| 42 |
|
|
| 43 |
float x; |
|
| 44 |
float vx; |
|
| 45 |
} |
|
| 46 |
|
|
| 47 |
private Vector<VectorCache> vc; |
|
| 48 |
private VectorCache tmp1, tmp2; |
|
| 49 |
|
|
| 50 | 32 |
private Vector<Static1D> vv; |
| 51 | 33 |
private Static1D prev, curr, next; |
| 52 | 34 |
|
| ... | ... | |
| 75 | 57 |
|
| 76 | 58 |
if( q>1 ) |
| 77 | 59 |
{
|
| 78 |
tmp1.x = nx+px/q;
|
|
| 60 |
tmp1.tangent[0] = nx+px/q;
|
|
| 79 | 61 |
} |
| 80 | 62 |
else |
| 81 | 63 |
{
|
| 82 |
tmp1.x = px+nx*q;
|
|
| 64 |
tmp1.tangent[0] = px+nx*q;
|
|
| 83 | 65 |
} |
| 84 | 66 |
} |
| 85 | 67 |
else |
| 86 | 68 |
{
|
| 87 |
tmp1.x = 0.0f;
|
|
| 69 |
tmp1.tangent[0] = 0.0f;
|
|
| 88 | 70 |
} |
| 89 | 71 |
} |
| 90 | 72 |
|
| ... | ... | |
| 97 | 79 |
tmp1= vc.elementAt(0); |
| 98 | 80 |
curr= vv.elementAt(0); |
| 99 | 81 |
|
| 100 |
tmp1.ax = 0.0f;
|
|
| 101 |
tmp1.bx = 0.0f;
|
|
| 102 |
tmp1.cx = curr.x;
|
|
| 103 |
tmp1.dx = 0.0f;
|
|
| 82 |
tmp1.a[0] = 0.0f;
|
|
| 83 |
tmp1.b[0] = 0.0f;
|
|
| 84 |
tmp1.c[0] = curr.x;
|
|
| 85 |
tmp1.d[0] = 0.0f;
|
|
| 104 | 86 |
} |
| 105 | 87 |
else if( numPoints==2 ) |
| 106 | 88 |
{
|
| ... | ... | |
| 109 | 91 |
curr= vv.elementAt(0); |
| 110 | 92 |
next= vv.elementAt(1); |
| 111 | 93 |
|
| 112 |
tmp1.ax = 0.0f;
|
|
| 113 |
tmp1.bx = 0.0f;
|
|
| 114 |
tmp1.cx = next.x - curr.x;
|
|
| 115 |
tmp1.dx = curr.x;
|
|
| 94 |
tmp1.a[0] = 0.0f;
|
|
| 95 |
tmp1.b[0] = 0.0f;
|
|
| 96 |
tmp1.c[0] = next.x - curr.x;
|
|
| 97 |
tmp1.d[0] = curr.x;
|
|
| 116 | 98 |
|
| 117 |
tmp2.ax = 0.0f;
|
|
| 118 |
tmp2.bx = 0.0f;
|
|
| 119 |
tmp2.cx = curr.x - next.x;
|
|
| 120 |
tmp2.dx = next.x;
|
|
| 99 |
tmp2.a[0] = 0.0f;
|
|
| 100 |
tmp2.b[0] = 0.0f;
|
|
| 101 |
tmp2.c[0] = curr.x - next.x;
|
|
| 102 |
tmp2.d[0] = next.x;
|
|
| 121 | 103 |
} |
| 122 | 104 |
else |
| 123 | 105 |
{
|
| ... | ... | |
| 134 | 116 |
curr= vv.elementAt(i); |
| 135 | 117 |
next= vv.elementAt(n); |
| 136 | 118 |
|
| 137 |
tmp1.vx = curr.x;
|
|
| 119 |
tmp1.cached[0] = curr.x;
|
|
| 138 | 120 |
|
| 139 |
tmp1.ax = 2*curr.x + tmp1.x - 2*next.x + tmp2.x;
|
|
| 140 |
tmp1.bx = -3*curr.x - 2*tmp1.x + 3*next.x - tmp2.x;
|
|
| 141 |
tmp1.cx = tmp1.x;
|
|
| 142 |
tmp1.dx = curr.x;
|
|
| 121 |
tmp1.a[0] = 2*curr.x + tmp1.tangent[0] - 2*next.x + tmp2.tangent[0];
|
|
| 122 |
tmp1.b[0] = -3*curr.x - 2*tmp1.tangent[0] + 3*next.x - tmp2.tangent[0];
|
|
| 123 |
tmp1.c[0] = tmp1.tangent[0];
|
|
| 124 |
tmp1.d[0] = curr.x;
|
|
| 143 | 125 |
} |
| 144 | 126 |
} |
| 145 | 127 |
|
| ... | ... | |
| 154 | 136 |
*/ |
| 155 | 137 |
public Dynamic1D() |
| 156 | 138 |
{
|
| 157 |
this(0,0.5f); |
|
| 139 |
super(0,0.5f,1); |
|
| 140 |
vv = new Vector<>(); |
|
| 158 | 141 |
} |
| 159 | 142 |
|
| 160 | 143 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 169 | 152 |
*/ |
| 170 | 153 |
public Dynamic1D(int duration, float count) |
| 171 | 154 |
{
|
| 155 |
super(duration,count,1); |
|
| 172 | 156 |
vv = new Vector<>(); |
| 173 |
vc = new Vector<>(); |
|
| 174 |
vn = null; |
|
| 175 |
numPoints = 0; |
|
| 176 |
cacheDirty = false; |
|
| 177 |
mMode = MODE_LOOP; |
|
| 178 |
mDuration = duration; |
|
| 179 |
mCount = count; |
|
| 180 |
mDimension = 1; |
|
| 181 | 157 |
} |
| 182 | 158 |
|
| 183 | 159 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 237 | 213 |
{
|
| 238 | 214 |
case 0: |
| 239 | 215 |
case 1: break; |
| 240 |
case 2: vc.add(new VectorCache()); |
|
| 241 |
vc.add(new VectorCache()); |
|
| 242 |
vc.add(new VectorCache()); |
|
| 216 |
case 2: vc.add(new VectorCache(1));
|
|
| 217 |
vc.add(new VectorCache(1));
|
|
| 218 |
vc.add(new VectorCache(1));
|
|
| 243 | 219 |
cacheDirty = true; |
| 244 | 220 |
break; |
| 245 |
default:vc.add(new VectorCache()); |
|
| 221 |
default:vc.add(new VectorCache(1));
|
|
| 246 | 222 |
cacheDirty = true; |
| 247 | 223 |
} |
| 248 | 224 |
|
| ... | ... | |
| 269 | 245 |
{
|
| 270 | 246 |
case 0: |
| 271 | 247 |
case 1: break; |
| 272 |
case 2: vc.add(new VectorCache()); |
|
| 273 |
vc.add(new VectorCache()); |
|
| 274 |
vc.add(new VectorCache()); |
|
| 248 |
case 2: vc.add(new VectorCache(1));
|
|
| 249 |
vc.add(new VectorCache(1));
|
|
| 250 |
vc.add(new VectorCache(1));
|
|
| 275 | 251 |
cacheDirty = true; |
| 276 | 252 |
break; |
| 277 |
default:vc.add(location,new VectorCache()); |
|
| 253 |
default:vc.add(location,new VectorCache(1));
|
|
| 278 | 254 |
cacheDirty = true; |
| 279 | 255 |
} |
| 280 | 256 |
|
| ... | ... | |
| 437 | 413 |
next = vv.elementAt(vecNext); |
| 438 | 414 |
tmp2 = vc.elementAt(vecNext); |
| 439 | 415 |
|
| 440 |
if( tmp2.vx!=next.x ) recomputeCache();
|
|
| 416 |
if( tmp2.cached[0]!=next.x ) recomputeCache();
|
|
| 441 | 417 |
} |
| 442 | 418 |
|
| 443 | 419 |
if( vn!=null ) |
| ... | ... | |
| 446 | 422 |
} |
| 447 | 423 |
|
| 448 | 424 |
tmp1 = vc.elementAt(vecCurr); |
| 449 |
buffer[offset] = ((tmp1.ax*time+tmp1.bx)*time+tmp1.cx)*time+tmp1.dx;
|
|
| 425 |
buffer[offset] = ((tmp1.a[0]*time+tmp1.b[0])*time+tmp1.c[0])*time+tmp1.d[0];
|
|
| 450 | 426 |
break; |
| 451 | 427 |
} |
| 452 | 428 |
} |
| src/main/java/org/distorted/library/type/Dynamic2D.java | ||
|---|---|---|
| 29 | 29 |
|
| 30 | 30 |
public class Dynamic2D extends Dynamic implements Data2D |
| 31 | 31 |
{
|
| 32 |
|
|
| 33 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 34 |
// the coefficients of the X(t), Y(t) polynomials: X(t) = ax*T^3 + bx*T^2 + cx*t + dx etc. |
|
| 35 |
// (x,y) is the vector tangent to the path. |
|
| 36 |
// (vx,vy) is the original vector from vv (copied here so when interpolating we can see if it is |
|
| 37 |
// still valid and if not - rebuild the Cache |
|
| 38 |
|
|
| 39 |
private class VectorCache |
|
| 40 |
{
|
|
| 41 |
float ax, bx, cx, dx; |
|
| 42 |
float ay, by, cy, dy; |
|
| 43 |
|
|
| 44 |
float x,y; |
|
| 45 |
float vx,vy; |
|
| 46 |
} |
|
| 47 |
|
|
| 48 |
private Vector<VectorCache> vc; |
|
| 49 |
private VectorCache tmp1, tmp2; |
|
| 50 |
|
|
| 51 | 32 |
private Vector<Static2D> vv; |
| 52 | 33 |
private Static2D prev, curr, next; |
| 53 | 34 |
|
| ... | ... | |
| 78 | 59 |
|
| 79 | 60 |
if( q>1 ) |
| 80 | 61 |
{
|
| 81 |
tmp1.x = nx+px/q;
|
|
| 82 |
tmp1.y = ny+py/q;
|
|
| 62 |
tmp1.tangent[0] = nx+px/q;
|
|
| 63 |
tmp1.tangent[1] = ny+py/q;
|
|
| 83 | 64 |
} |
| 84 | 65 |
else |
| 85 | 66 |
{
|
| 86 |
tmp1.x = px+nx*q;
|
|
| 87 |
tmp1.y = py+ny*q;
|
|
| 67 |
tmp1.tangent[0] = px+nx*q;
|
|
| 68 |
tmp1.tangent[1] = py+ny*q;
|
|
| 88 | 69 |
} |
| 89 | 70 |
} |
| 90 | 71 |
else |
| 91 | 72 |
{
|
| 92 |
tmp1.x = 0.0f;
|
|
| 93 |
tmp1.y = 0.0f;
|
|
| 73 |
tmp1.tangent[0] = 0.0f;
|
|
| 74 |
tmp1.tangent[1] = 0.0f;
|
|
| 94 | 75 |
} |
| 95 | 76 |
} |
| 96 | 77 |
|
| ... | ... | |
| 103 | 84 |
tmp1= vc.elementAt(0); |
| 104 | 85 |
curr= vv.elementAt(0); |
| 105 | 86 |
|
| 106 |
tmp1.ax = tmp1.ay = 0.0f;
|
|
| 107 |
tmp1.bx = tmp1.by = 0.0f;
|
|
| 108 |
tmp1.cx = curr.x;
|
|
| 109 |
tmp1.cy = curr.y;
|
|
| 110 |
tmp1.dx = tmp1.dy = 0.0f;
|
|
| 87 |
tmp1.a[0] = tmp1.a[1] = 0.0f;
|
|
| 88 |
tmp1.b[0] = tmp1.b[1] = 0.0f;
|
|
| 89 |
tmp1.c[0] = curr.x;
|
|
| 90 |
tmp1.c[1] = curr.y;
|
|
| 91 |
tmp1.d[0] = tmp1.d[1] = 0.0f;
|
|
| 111 | 92 |
} |
| 112 | 93 |
else if( numPoints==2 ) |
| 113 | 94 |
{
|
| ... | ... | |
| 116 | 97 |
curr= vv.elementAt(0); |
| 117 | 98 |
next= vv.elementAt(1); |
| 118 | 99 |
|
| 119 |
tmp1.ax = tmp1.ay = 0.0f;
|
|
| 120 |
tmp1.bx = tmp1.by = 0.0f;
|
|
| 121 |
tmp1.cx = next.x - curr.x;
|
|
| 122 |
tmp1.cy = next.y - curr.y;
|
|
| 123 |
tmp1.dx = curr.x;
|
|
| 124 |
tmp1.dy = curr.y;
|
|
| 100 |
tmp1.a[0] = tmp1.a[1] = 0.0f;
|
|
| 101 |
tmp1.b[0] = tmp1.b[1] = 0.0f;
|
|
| 102 |
tmp1.c[0] = next.x - curr.x;
|
|
| 103 |
tmp1.c[1] = next.y - curr.y;
|
|
| 104 |
tmp1.d[0] = curr.x;
|
|
| 105 |
tmp1.d[1] = curr.y;
|
|
| 125 | 106 |
|
| 126 |
tmp2.ax = tmp2.ay = 0.0f;
|
|
| 127 |
tmp2.bx = tmp2.by = 0.0f;
|
|
| 128 |
tmp2.cx = curr.x - next.x;
|
|
| 129 |
tmp2.cy = curr.y - next.y;
|
|
| 130 |
tmp2.dx = next.x;
|
|
| 131 |
tmp2.dy = next.y;
|
|
| 107 |
tmp2.a[0] = tmp2.a[1] = 0.0f;
|
|
| 108 |
tmp2.b[0] = tmp2.b[1] = 0.0f;
|
|
| 109 |
tmp2.c[0] = curr.x - next.x;
|
|
| 110 |
tmp2.c[1] = curr.y - next.y;
|
|
| 111 |
tmp2.d[0] = next.x;
|
|
| 112 |
tmp2.d[1] = next.y;
|
|
| 132 | 113 |
} |
| 133 | 114 |
else |
| 134 | 115 |
{
|
| ... | ... | |
| 145 | 126 |
curr= vv.elementAt(i); |
| 146 | 127 |
next= vv.elementAt(n); |
| 147 | 128 |
|
| 148 |
tmp1.vx = curr.x;
|
|
| 149 |
tmp1.vy = curr.y;
|
|
| 150 |
|
|
| 151 |
tmp1.ax = 2*curr.x + tmp1.x - 2*next.x + tmp2.x;
|
|
| 152 |
tmp1.bx = -3*curr.x - 2*tmp1.x + 3*next.x - tmp2.x;
|
|
| 153 |
tmp1.cx = tmp1.x;
|
|
| 154 |
tmp1.dx = curr.x;
|
|
| 155 |
|
|
| 156 |
tmp1.ay = 2*curr.y + tmp1.y - 2*next.y + tmp2.y;
|
|
| 157 |
tmp1.by = -3*curr.y - 2*tmp1.y + 3*next.y - tmp2.y;
|
|
| 158 |
tmp1.cy = tmp1.y;
|
|
| 159 |
tmp1.dy = curr.y;
|
|
| 129 |
tmp1.cached[0] = curr.x;
|
|
| 130 |
tmp1.cached[1] = curr.y;
|
|
| 131 |
|
|
| 132 |
tmp1.a[0] = 2*curr.x + tmp1.tangent[0] - 2*next.x + tmp2.tangent[0];
|
|
| 133 |
tmp1.b[0] = -3*curr.x - 2*tmp1.tangent[0] + 3*next.x - tmp2.tangent[0];
|
|
| 134 |
tmp1.c[0] = tmp1.tangent[0];
|
|
| 135 |
tmp1.d[0] = curr.x;
|
|
| 136 |
|
|
| 137 |
tmp1.a[1] = 2*curr.y + tmp1.tangent[1] - 2*next.y + tmp2.tangent[1];
|
|
| 138 |
tmp1.b[1] = -3*curr.y - 2*tmp1.tangent[1] + 3*next.y - tmp2.tangent[1];
|
|
| 139 |
tmp1.c[1] = tmp1.tangent[1];
|
|
| 140 |
tmp1.d[1] = curr.y;
|
|
| 160 | 141 |
} |
| 161 | 142 |
} |
| 162 | 143 |
|
| ... | ... | |
| 171 | 152 |
*/ |
| 172 | 153 |
public Dynamic2D() |
| 173 | 154 |
{
|
| 174 |
this(0,0.5f); |
|
| 155 |
super(0,0.5f,2); |
|
| 156 |
vv = new Vector<>(); |
|
| 175 | 157 |
} |
| 176 | 158 |
|
| 177 | 159 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 186 | 168 |
*/ |
| 187 | 169 |
public Dynamic2D(int duration, float count) |
| 188 | 170 |
{
|
| 171 |
super(duration,count,2); |
|
| 189 | 172 |
vv = new Vector<>(); |
| 190 |
vc = new Vector<>(); |
|
| 191 |
vn = null; |
|
| 192 |
numPoints = 0; |
|
| 193 |
cacheDirty = false; |
|
| 194 |
mMode = MODE_LOOP; |
|
| 195 |
mDuration = duration; |
|
| 196 |
mCount = count; |
|
| 197 |
mDimension = 2; |
|
| 198 | 173 |
} |
| 199 | 174 |
|
| 200 | 175 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 254 | 229 |
{
|
| 255 | 230 |
case 0: |
| 256 | 231 |
case 1: break; |
| 257 |
case 2: vc.add(new VectorCache()); |
|
| 258 |
vc.add(new VectorCache()); |
|
| 259 |
vc.add(new VectorCache()); |
|
| 232 |
case 2: vc.add(new VectorCache(2));
|
|
| 233 |
vc.add(new VectorCache(2));
|
|
| 234 |
vc.add(new VectorCache(2));
|
|
| 260 | 235 |
break; |
| 261 |
default:vc.add(new VectorCache()); |
|
| 236 |
default:vc.add(new VectorCache(2));
|
|
| 262 | 237 |
} |
| 263 | 238 |
|
| 264 | 239 |
numPoints++; |
| ... | ... | |
| 285 | 260 |
{
|
| 286 | 261 |
case 0: |
| 287 | 262 |
case 1: break; |
| 288 |
case 2: vc.add(new VectorCache()); |
|
| 289 |
vc.add(new VectorCache()); |
|
| 290 |
vc.add(new VectorCache()); |
|
| 263 |
case 2: vc.add(new VectorCache(2));
|
|
| 264 |
vc.add(new VectorCache(2));
|
|
| 265 |
vc.add(new VectorCache(2));
|
|
| 291 | 266 |
break; |
| 292 |
default:vc.add(location,new VectorCache()); |
|
| 267 |
default:vc.add(location,new VectorCache(2));
|
|
| 293 | 268 |
} |
| 294 | 269 |
|
| 295 | 270 |
numPoints++; |
| ... | ... | |
| 417 | 392 |
{
|
| 418 | 393 |
time = noise(time,0); |
| 419 | 394 |
|
| 420 |
float dx2 = next.x-curr.x;
|
|
| 421 |
float dy2 = next.y-curr.y;
|
|
| 395 |
baseV[0][0] = next.x-curr.x;
|
|
| 396 |
baseV[0][1] = next.y-curr.y;
|
|
| 422 | 397 |
|
| 423 |
buffer[offset ] = dx2*time + curr.x +dy2*mFactor[0];
|
|
| 424 |
buffer[offset+1] = dy2*time + curr.y -dx2*mFactor[0];
|
|
| 398 |
buffer[offset ] = baseV[0][0]*time + curr.x +baseV[0][0]*mFactor[0];
|
|
| 399 |
buffer[offset+1] = baseV[0][1]*time + curr.y -baseV[0][1]*mFactor[0];
|
|
| 425 | 400 |
} |
| 426 | 401 |
else |
| 427 | 402 |
{
|
| ... | ... | |
| 468 | 443 |
next = vv.elementAt(vecNext); |
| 469 | 444 |
tmp2 = vc.elementAt(vecNext); |
| 470 | 445 |
|
| 471 |
if( tmp2.vx!=next.x || tmp2.vy!=next.y ) recomputeCache();
|
|
| 446 |
if( tmp2.cached[0]!=next.x || tmp2.cached[1]!=next.y ) recomputeCache();
|
|
| 472 | 447 |
} |
| 473 |
|
|
| 448 |
|
|
| 449 |
tmp1 = vc.elementAt(vecCurr); |
|
| 450 |
|
|
| 474 | 451 |
if( vn!=null ) |
| 475 | 452 |
{
|
| 476 | 453 |
time = noise(time,vecCurr); |
| 477 |
tmp1 = vc.elementAt(vecCurr); |
|
| 478 |
|
|
| 479 |
float dx2 = (3*tmp1.ax*time+2*tmp1.bx)*time + tmp1.cx; |
|
| 480 |
float dy2 = (3*tmp1.ay*time+2*tmp1.by)*time + tmp1.cy; |
|
| 454 |
|
|
| 455 |
baseV[0][0] = (3*tmp1.a[0]*time+2*tmp1.b[0])*time + tmp1.c[0]; |
|
| 456 |
baseV[0][1] = (3*tmp1.a[1]*time+2*tmp1.b[1])*time + tmp1.c[1]; |
|
| 481 | 457 |
|
| 482 |
buffer[offset ]= ((tmp1.ax*time+tmp1.bx)*time+tmp1.cx)*time+tmp1.dx +dy2*mFactor[0];
|
|
| 483 |
buffer[offset+1]= ((tmp1.ay*time+tmp1.by)*time+tmp1.cy)*time+tmp1.dy -dx2*mFactor[0];
|
|
| 458 |
buffer[offset ]= ((tmp1.a[0]*time+tmp1.b[0])*time+tmp1.c[0])*time+tmp1.d[0] +baseV[0][0]*mFactor[0];
|
|
| 459 |
buffer[offset+1]= ((tmp1.a[1]*time+tmp1.b[1])*time+tmp1.c[1])*time+tmp1.d[1] -baseV[0][1]*mFactor[0];
|
|
| 484 | 460 |
} |
| 485 | 461 |
else |
| 486 | 462 |
{
|
| 487 |
tmp1 = vc.elementAt(vecCurr); |
|
| 488 |
buffer[offset ]= ((tmp1.ax*time+tmp1.bx)*time+tmp1.cx)*time+tmp1.dx; |
|
| 489 |
buffer[offset+1]= ((tmp1.ay*time+tmp1.by)*time+tmp1.cy)*time+tmp1.dy; |
|
| 463 |
buffer[offset ]= ((tmp1.a[0]*time+tmp1.b[0])*time+tmp1.c[0])*time+tmp1.d[0]; |
|
| 464 |
buffer[offset+1]= ((tmp1.a[1]*time+tmp1.b[1])*time+tmp1.c[1])*time+tmp1.d[1]; |
|
| 490 | 465 |
} |
| 491 | 466 |
|
| 492 | 467 |
break; |
| src/main/java/org/distorted/library/type/Dynamic3D.java | ||
|---|---|---|
| 29 | 29 |
|
| 30 | 30 |
public class Dynamic3D extends Dynamic implements Data3D |
| 31 | 31 |
{
|
| 32 |
|
|
| 33 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 34 |
// the coefficients of the X(t), Y(t) and Z(t) polynomials: X(t) = ax*T^3 + bx*T^2 + cx*t + dx etc. |
|
| 35 |
// (x,y,z) is the vector tangent to the path. |
|
| 36 |
// (vx,vy,vz) is the original vector from vv (copied here so when interpolating we can see if it is |
|
| 37 |
// still valid and if not - rebuild the Cache |
|
| 38 |
|
|
| 39 |
private class VectorCache |
|
| 40 |
{
|
|
| 41 |
float ax, bx, cx, dx; |
|
| 42 |
float ay, by, cy, dy; |
|
| 43 |
float az, bz, cz, dz; |
|
| 44 |
|
|
| 45 |
float x,y,z; |
|
| 46 |
float vx,vy,vz; |
|
| 47 |
} |
|
| 48 |
|
|
| 49 |
private Vector<VectorCache> vc; |
|
| 50 |
private VectorCache tmp1, tmp2; |
|
| 51 |
|
|
| 52 | 32 |
private Vector<Static3D> vv; |
| 53 | 33 |
private Static3D prev, curr, next; |
| 54 | 34 |
|
| 55 |
private float vec1X,vec1Y,vec1Z; // vector perpendicular to v(t) and in the same plane as v(t) and a(t) (for >2 points only, in case of 2 points this is calculated differently) |
|
| 56 |
private float vec2X,vec2Y,vec2Z; // vector perpendicular to v(t0 and to vec1. |
|
| 57 |
|
|
| 58 | 35 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 59 | 36 |
// no array bounds checking! |
| 60 | 37 |
|
| ... | ... | |
| 84 | 61 |
|
| 85 | 62 |
if( q>1 ) |
| 86 | 63 |
{
|
| 87 |
tmp1.x = nx+px/q;
|
|
| 88 |
tmp1.y = ny+py/q;
|
|
| 89 |
tmp1.z = nz+pz/q;
|
|
| 64 |
tmp1.tangent[0] = nx+px/q;
|
|
| 65 |
tmp1.tangent[1] = ny+py/q;
|
|
| 66 |
tmp1.tangent[2] = nz+pz/q;
|
|
| 90 | 67 |
} |
| 91 | 68 |
else |
| 92 | 69 |
{
|
| 93 |
tmp1.x = px+nx*q;
|
|
| 94 |
tmp1.y = py+ny*q;
|
|
| 95 |
tmp1.z = pz+nz*q;
|
|
| 70 |
tmp1.tangent[0] = px+nx*q;
|
|
| 71 |
tmp1.tangent[1] = py+ny*q;
|
|
| 72 |
tmp1.tangent[2] = pz+nz*q;
|
|
| 96 | 73 |
} |
| 97 | 74 |
} |
| 98 | 75 |
else |
| 99 | 76 |
{
|
| 100 |
tmp1.x = 0.0f;
|
|
| 101 |
tmp1.y = 0.0f;
|
|
| 102 |
tmp1.z = 0.0f;
|
|
| 77 |
tmp1.tangent[0] = 0.0f;
|
|
| 78 |
tmp1.tangent[1] = 0.0f;
|
|
| 79 |
tmp1.tangent[2] = 0.0f;
|
|
| 103 | 80 |
} |
| 104 | 81 |
} |
| 105 | 82 |
|
| ... | ... | |
| 112 | 89 |
tmp1= vc.elementAt(0); |
| 113 | 90 |
curr= vv.elementAt(0); |
| 114 | 91 |
|
| 115 |
tmp1.ax = tmp1.ay = tmp1.az = 0.0f;
|
|
| 116 |
tmp1.bx = tmp1.by = tmp1.bz = 0.0f;
|
|
| 117 |
tmp1.cx = curr.x;
|
|
| 118 |
tmp1.cy = curr.y;
|
|
| 119 |
tmp1.cz = curr.z;
|
|
| 120 |
tmp1.dx = tmp1.dy = tmp1.dz = 0.0f;
|
|
| 92 |
tmp1.a[0] = tmp1.a[1] = tmp1.a[2] = 0.0f;
|
|
| 93 |
tmp1.b[0] = tmp1.b[1] = tmp1.b[2] = 0.0f;
|
|
| 94 |
tmp1.c[0] = curr.x;
|
|
| 95 |
tmp1.c[1] = curr.y;
|
|
| 96 |
tmp1.c[2] = curr.z;
|
|
| 97 |
tmp1.d[0] = tmp1.d[1] = tmp1.d[2] = 0.0f;
|
|
| 121 | 98 |
} |
| 122 | 99 |
else if( numPoints==2 ) |
| 123 | 100 |
{
|
| ... | ... | |
| 126 | 103 |
curr= vv.elementAt(0); |
| 127 | 104 |
next= vv.elementAt(1); |
| 128 | 105 |
|
| 129 |
tmp1.ax = tmp1.ay = tmp1.az = 0.0f;
|
|
| 130 |
tmp1.bx = tmp1.by = tmp1.bz = 0.0f;
|
|
| 131 |
tmp1.cx = next.x - curr.x;
|
|
| 132 |
tmp1.cy = next.y - curr.y;
|
|
| 133 |
tmp1.cz = next.z - curr.z;
|
|
| 134 |
tmp1.dx = curr.x;
|
|
| 135 |
tmp1.dy = curr.y;
|
|
| 136 |
tmp1.dz = curr.z;
|
|
| 106 |
tmp1.a[0] = tmp1.a[1] = tmp1.a[2] = 0.0f;
|
|
| 107 |
tmp1.b[0] = tmp1.b[1] = tmp1.b[2] = 0.0f;
|
|
| 108 |
tmp1.c[0] = next.x - curr.x;
|
|
| 109 |
tmp1.c[1] = next.y - curr.y;
|
|
| 110 |
tmp1.c[2] = next.z - curr.z;
|
|
| 111 |
tmp1.d[0] = curr.x;
|
|
| 112 |
tmp1.d[1] = curr.y;
|
|
| 113 |
tmp1.d[2] = curr.z;
|
|
| 137 | 114 |
|
| 138 |
tmp2.ax = tmp2.ay = tmp2.az = 0.0f;
|
|
| 139 |
tmp2.bx = tmp2.by = tmp2.bz = 0.0f;
|
|
| 140 |
tmp2.cx = curr.x - next.x;
|
|
| 141 |
tmp2.cy = curr.y - next.y;
|
|
| 142 |
tmp2.cz = curr.z - next.z;
|
|
| 143 |
tmp2.dx = next.x;
|
|
| 144 |
tmp2.dy = next.y;
|
|
| 145 |
tmp2.dz = next.z;
|
|
| 115 |
tmp2.a[0] = tmp2.a[1] = tmp2.a[2] = 0.0f;
|
|
| 116 |
tmp2.b[0] = tmp2.b[1] = tmp2.b[2] = 0.0f;
|
|
| 117 |
tmp2.c[0] = curr.x - next.x;
|
|
| 118 |
tmp2.c[1] = curr.y - next.y;
|
|
| 119 |
tmp2.c[2] = curr.z - next.z;
|
|
| 120 |
tmp2.d[0] = next.x;
|
|
| 121 |
tmp2.d[1] = next.y;
|
|
| 122 |
tmp2.d[2] = next.z;
|
|
| 146 | 123 |
} |
| 147 | 124 |
else |
| 148 | 125 |
{
|
| ... | ... | |
| 159 | 136 |
curr= vv.elementAt(i); |
| 160 | 137 |
next= vv.elementAt(n); |
| 161 | 138 |
|
| 162 |
tmp1.vx = curr.x;
|
|
| 163 |
tmp1.vy = curr.y;
|
|
| 164 |
tmp1.vz = curr.z;
|
|
| 139 |
tmp1.cached[0] = curr.x;
|
|
| 140 |
tmp1.cached[1] = curr.y;
|
|
| 141 |
tmp1.cached[2] = curr.z;
|
|
| 165 | 142 |
|
| 166 |
tmp1.ax = 2*curr.x + tmp1.x - 2*next.x + tmp2.x;
|
|
| 167 |
tmp1.bx = -3*curr.x - 2*tmp1.x + 3*next.x - tmp2.x;
|
|
| 168 |
tmp1.cx = tmp1.x;
|
|
| 169 |
tmp1.dx = curr.x;
|
|
| 143 |
tmp1.a[0] = 2*curr.x + tmp1.tangent[0] - 2*next.x + tmp2.tangent[0];
|
|
| 144 |
tmp1.b[0] = -3*curr.x - 2*tmp1.tangent[0] + 3*next.x - tmp2.tangent[0];
|
|
| 145 |
tmp1.c[0] = tmp1.tangent[0];
|
|
| 146 |
tmp1.d[0] = curr.x;
|
|
| 170 | 147 |
|
| 171 |
tmp1.ay = 2*curr.y + tmp1.y - 2*next.y + tmp2.y;
|
|
| 172 |
tmp1.by = -3*curr.y - 2*tmp1.y + 3*next.y - tmp2.y;
|
|
| 173 |
tmp1.cy = tmp1.y;
|
|
| 174 |
tmp1.dy = curr.y;
|
|
| 148 |
tmp1.a[1] = 2*curr.y + tmp1.tangent[1] - 2*next.y + tmp2.tangent[1];
|
|
| 149 |
tmp1.b[1] = -3*curr.y - 2*tmp1.tangent[1] + 3*next.y - tmp2.tangent[1];
|
|
| 150 |
tmp1.c[1] = tmp1.tangent[1];
|
|
| 151 |
tmp1.d[1] = curr.y;
|
|
| 175 | 152 |
|
| 176 |
tmp1.az = 2*curr.z + tmp1.z - 2*next.z + tmp2.z;
|
|
| 177 |
tmp1.bz = -3*curr.z - 2*tmp1.z + 3*next.z - tmp2.z;
|
|
| 178 |
tmp1.cz = tmp1.z;
|
|
| 179 |
tmp1.dz = curr.z;
|
|
| 153 |
tmp1.a[2] = 2*curr.z + tmp1.tangent[2] - 2*next.z + tmp2.tangent[2];
|
|
| 154 |
tmp1.b[2] = -3*curr.z - 2*tmp1.tangent[2] + 3*next.z - tmp2.tangent[2];
|
|
| 155 |
tmp1.c[2] = tmp1.tangent[2];
|
|
| 156 |
tmp1.d[2] = curr.z;
|
|
| 180 | 157 |
} |
| 181 | 158 |
} |
| 182 | 159 |
|
| 183 | 160 |
cacheDirty = false; |
| 184 | 161 |
} |
| 185 | 162 |
|
| 186 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 187 |
// v is the speed vector (i.e. position p(t) differentiated by time) |
|
| 188 |
// a is the acceleration vector (differentiate once more) |
|
| 189 |
// now what we are doing is compute vec1{X,Y,Z} to be a vector perpendicular to v and in the same plane as both v and a.
|
|
| 190 |
// vec2{X,Y,Z} would be (v)x(vec1).
|
|
| 191 |
// |
|
| 192 |
// vec1 = a-delta*v where delta = (v*a)/|v|^2 (see Gram-Schmidt) |
|
| 193 |
|
|
| 194 |
private void setUpVectors(float time,VectorCache vc) |
|
| 195 |
{
|
|
| 196 |
if( vc!=null ) |
|
| 197 |
{
|
|
| 198 |
float vx = (3*vc.ax*time+2*vc.bx)*time+vc.cx; |
|
| 199 |
float vy = (3*vc.ay*time+2*vc.by)*time+vc.cy; |
|
| 200 |
float vz = (3*vc.az*time+2*vc.bz)*time+vc.cz; |
|
| 201 |
|
|
| 202 |
float ax = 6*vc.ax*time+2*vc.bx; |
|
| 203 |
float ay = 6*vc.ay*time+2*vc.by; |
|
| 204 |
float az = 6*vc.az*time+2*vc.bz; |
|
| 205 |
|
|
| 206 |
float v_sq = vx*vx+vy*vy+vz*vz; |
|
| 207 |
float delta = (vx*ax+vy*ay+vz*az)/v_sq; |
|
| 208 |
|
|
| 209 |
vec1X = ax-delta*vx; |
|
| 210 |
vec1Y = ay-delta*vy; |
|
| 211 |
vec1Z = az-delta*vz; |
|
| 212 |
|
|
| 213 |
vec2X = vy*vec1Z-vz*vec1Y; |
|
| 214 |
vec2Y = vz*vec1X-vx*vec1Z; |
|
| 215 |
vec2Z = vx*vec1Y-vy*vec1X; |
|
| 216 |
|
|
| 217 |
float len1 = (float)Math.sqrt(v_sq/(vec1X*vec1X+vec1Y*vec1Y+vec1Z*vec1Z)); |
|
| 218 |
float len2 = (float)Math.sqrt(v_sq/(vec2X*vec2X+vec2Y*vec2Y+vec2Z*vec2Z)); |
|
| 219 |
|
|
| 220 |
vec1X*=len1; |
|
| 221 |
vec1Y*=len1; |
|
| 222 |
vec1Z*=len1; |
|
| 223 |
|
|
| 224 |
vec2X*=len2; |
|
| 225 |
vec2Y*=len2; |
|
| 226 |
vec2Z*=len2; |
|
| 227 |
} |
|
| 228 |
else |
|
| 229 |
{
|
|
| 230 |
curr = vv.elementAt(0); |
|
| 231 |
next = vv.elementAt(1); |
|
| 232 |
|
|
| 233 |
float vx = (next.x-curr.x); |
|
| 234 |
float vy = (next.y-curr.y); |
|
| 235 |
float vz = (next.z-curr.z); |
|
| 236 |
|
|
| 237 |
float b = (float)Math.sqrt(vx*vx+vy*vy); |
|
| 238 |
|
|
| 239 |
if( b>0.0f ) |
|
| 240 |
{
|
|
| 241 |
vec1X = vx*vz/b; |
|
| 242 |
vec1Y = vy*vz/b; |
|
| 243 |
vec1Z = -b; |
|
| 244 |
|
|
| 245 |
vec2X = vy*vec1Z-vz*vec1Y; |
|
| 246 |
vec2Y = vz*vec1X-vx*vec1Z; |
|
| 247 |
vec2Z = vx*vec1Y-vy*vec1X; |
|
| 248 |
|
|
| 249 |
float len2 = (float)Math.sqrt((vx*vx+vy*vy+vz*vz)/(vec2X*vec2X+vec2Y*vec2Y+vec2Z*vec2Z)); |
|
| 250 |
|
|
| 251 |
vec2X*=len2; |
|
| 252 |
vec2Y*=len2; |
|
| 253 |
vec2Z*=len2; |
|
| 254 |
} |
|
| 255 |
else |
|
| 256 |
{
|
|
| 257 |
vec1X = vz; |
|
| 258 |
vec1Y = 0.0f; |
|
| 259 |
vec1Z = 0.0f; |
|
| 260 |
|
|
| 261 |
vec2X = 0.0f; |
|
| 262 |
vec2Y = vz; |
|
| 263 |
vec2Z = 0.0f; |
|
| 264 |
} |
|
| 265 |
} |
|
| 266 |
} |
|
| 267 |
|
|
| 268 | 163 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 269 | 164 |
// PUBLIC API |
| 270 | 165 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 273 | 168 |
*/ |
| 274 | 169 |
public Dynamic3D() |
| 275 | 170 |
{
|
| 276 |
this(0,0.5f); |
|
| 171 |
super(0,0.5f,3); |
|
| 172 |
vv = new Vector<>(); |
|
| 277 | 173 |
} |
| 278 | 174 |
|
| 279 | 175 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 288 | 184 |
*/ |
| 289 | 185 |
public Dynamic3D(int duration, float count) |
| 290 | 186 |
{
|
| 187 |
super(duration,count,3); |
|
| 291 | 188 |
vv = new Vector<>(); |
| 292 |
vc = new Vector<>(); |
|
| 293 |
vn = null; |
|
| 294 |
numPoints = 0; |
|
| 295 |
cacheDirty = false; |
|
| 296 |
mMode = MODE_LOOP; |
|
| 297 |
mDuration = duration; |
|
| 298 |
mCount = count; |
|
| 299 |
mDimension = 3; |
|
| 300 | 189 |
} |
| 301 | 190 |
|
| 302 | 191 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| ... | ... | |
| 355 | 244 |
switch(numPoints) |
| 356 | 245 |
{
|
| 357 | 246 |
case 0: break; |
| 358 |
case 1: setUpVectors(0.0f,null);
|
|
| 247 |
case 1: computeOrthonormalBase2(vv.elementAt(0),v);
|
|
| 359 | 248 |
break; |
| 360 |
case 2: vc.add(new VectorCache()); |
|
| 361 |
vc.add(new VectorCache()); |
|
| 362 |
vc.add(new VectorCache()); |
|
| 249 |
case 2: vc.add(new VectorCache(3));
|
|
| 250 |
vc.add(new VectorCache(3));
|
|
| 251 |
vc.add(new VectorCache(3));
|
|
| 363 | 252 |
break; |
| 364 |
default:vc.add(new VectorCache()); |
|
| 253 |
default:vc.add(new VectorCache(3));
|
|
| 365 | 254 |
} |
| 366 | 255 |
|
| 367 | 256 |
numPoints++; |
| ... | ... | |
| 387 | 276 |
switch(numPoints) |
| 388 | 277 |
{
|
| 389 | 278 |
case 0: break; |
| 390 |
case 1: setUpVectors(0.0f,null);
|
|
| 279 |
case 1: computeOrthonormalBase2(vv.elementAt(0),v);
|
|
| 391 | 280 |
break; |
| 392 |
case 2: vc.add(new VectorCache()); |
|
| 393 |
vc.add(new VectorCache()); |
|
| 394 |
vc.add(new VectorCache()); |
|
| 281 |
case 2: vc.add(new VectorCache(3));
|
|
| 282 |
vc.add(new VectorCache(3));
|
|
| 283 |
vc.add(new VectorCache(3));
|
|
| 395 | 284 |
break; |
| 396 |
default:vc.add(location,new VectorCache()); |
|
| 285 |
default:vc.add(location,new VectorCache(3));
|
|
| 397 | 286 |
} |
| 398 | 287 |
|
| 399 | 288 |
numPoints++; |
| ... | ... | |
| 425 | 314 |
case 1: |
| 426 | 315 |
case 2: break; |
| 427 | 316 |
case 3: vc.removeAllElements(); |
| 428 |
setUpVectors(0.0f,null);
|
|
| 317 |
computeOrthonormalBase2(vv.elementAt(0),vv.elementAt(1));
|
|
| 429 | 318 |
break; |
| 430 | 319 |
default:vc.remove(n); |
| 431 | 320 |
} |
| ... | ... | |
| 464 | 353 |
case 1: |
| 465 | 354 |
case 2: break; |
| 466 | 355 |
case 3: vc.removeAllElements(); |
| 467 |
setUpVectors(0.0f,null);
|
|
| 356 |
computeOrthonormalBase2(vv.elementAt(0),vv.elementAt(1));
|
|
| 468 | 357 |
break; |
| 469 | 358 |
default:vc.removeElementAt(location); |
| 470 | 359 |
} |
| ... | ... | |
| 525 | 414 |
{
|
| 526 | 415 |
time = noise(time,0); |
| 527 | 416 |
|
| 528 |
buffer[offset ] = (next.x-curr.x)*time + curr.x + (vec1X*mFactor[0] + vec2X*mFactor[1]);
|
|
| 529 |
buffer[offset+1] = (next.y-curr.y)*time + curr.y + (vec1Y*mFactor[0] + vec2Y*mFactor[1]);
|
|
| 530 |
buffer[offset+2] = (next.z-curr.z)*time + curr.z + (vec1Z*mFactor[0] + vec2Z*mFactor[1]);
|
|
| 417 |
buffer[offset ] = (next.x-curr.x)*time + curr.x + (baseV[0][0]*mFactor[0] + baseV[1][0]*mFactor[1]);
|
|
| 418 |
buffer[offset+1] = (next.y-curr.y)*time + curr.y + (baseV[0][1]*mFactor[0] + baseV[1][1]*mFactor[1]);
|
|
| 419 |
buffer[offset+2] = (next.z-curr.z)*time + curr.z + (baseV[0][2]*mFactor[0] + baseV[1][2]*mFactor[1]);
|
|
| 531 | 420 |
} |
| 532 | 421 |
else |
| 533 | 422 |
{
|
| ... | ... | |
| 575 | 464 |
next = vv.elementAt(vecNext); |
| 576 | 465 |
tmp2 = vc.elementAt(vecNext); |
| 577 | 466 |
|
| 578 |
if( tmp2.vx!=next.x || tmp2.vy!=next.y || tmp2.vz!=next.z ) recomputeCache();
|
|
| 467 |
if( tmp2.cached[0]!=next.x || tmp2.cached[1]!=next.y || tmp2.cached[2]!=next.z ) recomputeCache();
|
|
| 579 | 468 |
} |
| 580 | 469 |
|
| 581 | 470 |
tmp1 = vc.elementAt(vecCurr); |
| ... | ... | |
| 584 | 473 |
{
|
| 585 | 474 |
time = noise(time,vecCurr); |
| 586 | 475 |
|
| 587 |
setUpVectors(time,tmp1);
|
|
| 476 |
computeOrthonormalBaseMore(time,tmp1);
|
|
| 588 | 477 |
|
| 589 |
buffer[offset ]= ((tmp1.ax*time+tmp1.bx)*time+tmp1.cx)*time+tmp1.dx + (vec1X*mFactor[0] + vec2X*mFactor[1]);
|
|
| 590 |
buffer[offset+1]= ((tmp1.ay*time+tmp1.by)*time+tmp1.cy)*time+tmp1.dy + (vec1Y*mFactor[0] + vec2Y*mFactor[1]);
|
|
| 591 |
buffer[offset+2]= ((tmp1.az*time+tmp1.bz)*time+tmp1.cz)*time+tmp1.dz + (vec1Z*mFactor[0] + vec2Z*mFactor[1]);
|
|
| 478 |
buffer[offset ]= ((tmp1.a[0]*time+tmp1.b[0])*time+tmp1.c[0])*time+tmp1.d[0] + (baseV[0][0]*mFactor[0] + baseV[1][0]*mFactor[1]);
|
|
| 479 |
buffer[offset+1]= ((tmp1.a[1]*time+tmp1.b[1])*time+tmp1.c[1])*time+tmp1.d[1] + (baseV[0][1]*mFactor[0] + baseV[1][1]*mFactor[1]);
|
|
| 480 |
buffer[offset+2]= ((tmp1.a[2]*time+tmp1.b[2])*time+tmp1.c[2])*time+tmp1.d[2] + (baseV[0][2]*mFactor[0] + baseV[1][2]*mFactor[1]);
|
|
| 592 | 481 |
} |
| 593 | 482 |
else |
| 594 | 483 |
{
|
| 595 |
buffer[offset ]= ((tmp1.ax*time+tmp1.bx)*time+tmp1.cx)*time+tmp1.dx;
|
|
| 596 |
buffer[offset+1]= ((tmp1.ay*time+tmp1.by)*time+tmp1.cy)*time+tmp1.dy;
|
|
| 597 |
buffer[offset+2]= ((tmp1.az*time+tmp1.bz)*time+tmp1.cz)*time+tmp1.dz;
|
|
| 484 |
buffer[offset ]= ((tmp1.a[0]*time+tmp1.b[0])*time+tmp1.c[0])*time+tmp1.d[0];
|
|
| 485 |
buffer[offset+1]= ((tmp1.a[1]*time+tmp1.b[1])*time+tmp1.c[1])*time+tmp1.d[1];
|
|
| 486 |
buffer[offset+2]= ((tmp1.a[2]*time+tmp1.b[2])*time+tmp1.c[2])*time+tmp1.d[2];
|
|
| 598 | 487 |
} |
| 599 | 488 |
|
| 600 | 489 |
break; |
| src/main/java/org/distorted/library/type/Dynamic4D.java | ||
|---|---|---|
| 29 | 29 |
|
| 30 | 30 |
public class Dynamic4D extends Dynamic implements Data4D |
| 31 | 31 |
{
|
| 32 |
|
|
| 33 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 34 |
// the coefficients of the X(t), Y(t), Z(t), W(t) polynomials: X(t) = ax*T^3 + bx*T^2 + cx*t + dx etc. |
|
| 35 |
// (x,y,z,w) is the vector tangent to the path. |
|
| 36 |
// (vx,vy,vz,vw) is the original vector from vv (copied here so when interpolating we can see if it is |
|
| 37 |
// still valid and if not - rebuild the Cache |
|
| 38 |
|
|
| 39 |
private class VectorCache |
|
| 40 |
{
|
|
| 41 |
float ax, bx, cx, dx; |
|
| 42 |
float ay, by, cy, dy; |
|
| 43 |
float az, bz, cz, dz; |
|
| 44 |
float aw, bw, cw, dw; |
|
| 45 |
|
|
| 46 |
float x,y,z,w; |
|
| 47 |
float vx,vy,vz,vw; |
|
| 48 |
} |
|
| 49 |
|
|
| 50 |
private Vector<VectorCache> vc; |
|
| 51 |
private VectorCache tmp1, tmp2; |
|
| 52 |
|
|
| 53 | 32 |
private Vector<Static4D> vv; |
| 54 | 33 |
private Static4D prev, curr, next; |
| 55 | 34 |
|
| 56 |
private float vec1X,vec1Y,vec1Z,vec1W; // vector perpendicular to v(t) and in the same plane as v(t) and a(t) (for >2 points only, in case of 2 points this is calculated differently) |
|
| 57 |
private float vec2X,vec2Y,vec2Z,vec2W; // vector perpendicular to v(t) and to vec1. |
|
| 58 |
private float vec3X,vec3Y,vec3Z,vec3W; // vector perpendicular to v(t) and to vec1. |
|
| 59 |
|
|
| 60 | 35 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 61 | 36 |
// no array bounds checking! |
| 62 | 37 |
|
| ... | ... | |
| 88 | 63 |
|
| 89 | 64 |
if( q>1 ) |
| 90 | 65 |
{
|
| 91 |
tmp1.x = nx+px/q;
|
|
| 92 |
tmp1.y = ny+py/q;
|
|
| 93 |
tmp1.z = nz+pz/q;
|
|
| 94 |
tmp1.w = nw+pw/q;
|
|
| 66 |
tmp1.tangent[0] = nx+px/q;
|
|
| 67 |
tmp1.tangent[1] = ny+py/q;
|
|
| 68 |
tmp1.tangent[2] = nz+pz/q;
|
|
| 69 |
tmp1.tangent[3] = nw+pw/q;
|
|
| 95 | 70 |
} |
| 96 | 71 |
else |
| 97 | 72 |
{
|
| 98 |
tmp1.x = px+nx*q;
|
|
| 99 |
tmp1.y = py+ny*q;
|
|
| 100 |
tmp1.z = pz+nz*q;
|
|
| 101 |
tmp1.w = pw+nw*q;
|
|
| 73 |
tmp1.tangent[0] = px+nx*q;
|
|
| 74 |
tmp1.tangent[1] = py+ny*q;
|
|
| 75 |
tmp1.tangent[2] = pz+nz*q;
|
|
| 76 |
tmp1.tangent[3] = pw+nw*q;
|
|
| 102 | 77 |
} |
| 103 | 78 |
} |
| 104 | 79 |
else |
| 105 | 80 |
{
|
| 106 |
tmp1.x = 0.0f;
|
|
| 107 |
tmp1.y = 0.0f;
|
|
| 108 |
tmp1.z = 0.0f;
|
|
| 109 |
tmp1.w = 0.0f;
|
|
| 81 |
tmp1.tangent[0] = 0.0f;
|
|
| 82 |
tmp1.tangent[1] = 0.0f;
|
|
| 83 |
tmp1.tangent[2] = 0.0f;
|
|
| 84 |
tmp1.tangent[3] = 0.0f;
|
|
| 110 | 85 |
} |
| 111 | 86 |
} |
| 112 | 87 |
|
| ... | ... | |
| 119 | 94 |
tmp1= vc.elementAt(0); |
| 120 | 95 |
curr= vv.elementAt(0); |
| 121 | 96 |
|
| 122 |
tmp1.ax = tmp1.ay = tmp1.az = tmp1.aw = 0.0f;
|
|
| 123 |
tmp1.bx = tmp1.by = tmp1.bz = tmp1.bw = 0.0f;
|
|
| 124 |
tmp1.cx = curr.x;
|
|
| 125 |
tmp1.cy = curr.y;
|
|
| 126 |
tmp1.cz = curr.z;
|
|
| 127 |
tmp1.cw = curr.w;
|
|
| 128 |
tmp1.dx = tmp1.dy = tmp1.dz = tmp1.dw = 0.0f;
|
|
| 97 |
tmp1.a[0] = tmp1.a[1] = tmp1.a[2] = tmp1.a[3] = 0.0f;
|
|
| 98 |
tmp1.b[0] = tmp1.b[1] = tmp1.b[2] = tmp1.b[3] = 0.0f;
|
|
| 99 |
tmp1.c[0] = curr.x;
|
|
| 100 |
tmp1.c[1] = curr.y;
|
|
| 101 |
tmp1.c[2] = curr.z;
|
|
| 102 |
tmp1.c[3] = curr.w;
|
|
| 103 |
tmp1.d[0] = tmp1.d[1] = tmp1.d[3] = tmp1.d[3] = 0.0f;
|
|
| 129 | 104 |
} |
| 130 | 105 |
else if( numPoints==2 ) |
| 131 | 106 |
{
|
| ... | ... | |
| 134 | 109 |
curr= vv.elementAt(0); |
| 135 | 110 |
next= vv.elementAt(1); |
| 136 | 111 |
|
| 137 |
tmp1.ax = tmp1.ay = tmp1.az = tmp1.aw = 0.0f;
|
|
| 138 |
tmp1.bx = tmp1.by = tmp1.bz = tmp1.bw = 0.0f;
|
|
| 139 |
tmp1.cx = next.x - curr.x;
|
|
| 140 |
tmp1.cy = next.y - curr.y;
|
|
| 141 |
tmp1.cz = next.z - curr.z;
|
|
| 142 |
tmp1.cw = next.w - curr.w;
|
|
| 143 |
tmp1.dx = curr.x;
|
|
| 144 |
tmp1.dy = curr.y;
|
|
| 145 |
tmp1.dz = curr.z;
|
|
| 146 |
tmp1.dw = curr.w;
|
|
| 112 |
tmp1.a[0] = tmp1.a[1] = tmp1.a[2] = tmp1.a[3] = 0.0f;
|
|
| 113 |
tmp1.b[0] = tmp1.b[1] = tmp1.b[2] = tmp1.b[3] = 0.0f;
|
|
| 114 |
tmp1.c[0] = next.x - curr.x;
|
|
| 115 |
tmp1.c[1] = next.y - curr.y;
|
|
| 116 |
tmp1.c[2] = next.z - curr.z;
|
|
| 117 |
tmp1.c[3] = next.w - curr.w;
|
|
| 118 |
tmp1.d[0] = curr.x;
|
|
| 119 |
tmp1.d[1] = curr.y;
|
|
| 120 |
tmp1.d[2] = curr.z;
|
|
| 121 |
tmp1.d[3] = curr.w;
|
|
| 147 | 122 |
|
| 148 |
tmp2.ax = tmp2.ay = tmp2.az = tmp2.aw = 0.0f;
|
|
| 149 |
tmp2.bx = tmp2.by = tmp2.bz = tmp2.bw = 0.0f;
|
|
| 150 |
tmp2.cx = curr.x - next.x;
|
|
| 151 |
tmp2.cy = curr.y - next.y;
|
|
| 152 |
tmp2.cz = curr.z - next.z;
|
|
| 153 |
tmp2.cw = curr.w - next.w;
|
|
| 154 |
tmp2.dx = next.x;
|
|
| 155 |
tmp2.dy = next.y;
|
|
| 156 |
tmp2.dz = next.z;
|
|
| 157 |
tmp2.dw = next.w;
|
|
| 123 |
tmp2.a[0] = tmp2.a[1] = tmp2.a[2] = tmp2.a[3] = 0.0f;
|
|
| 124 |
tmp2.b[0] = tmp2.b[1] = tmp2.b[2] = tmp2.b[3] = 0.0f;
|
|
| 125 |
tmp2.c[0] = curr.x - next.x;
|
|
| 126 |
tmp2.c[1] = curr.y - next.y;
|
|
| 127 |
tmp2.c[2] = curr.z - next.z;
|
|
| 128 |
tmp2.c[3] = curr.w - next.w;
|
|
| 129 |
tmp2.d[0] = next.x;
|
|
| 130 |
tmp2.d[1] = next.y;
|
|
| 131 |
tmp2.d[2] = next.z;
|
|
| 132 |
tmp2.d[3] = next.w;
|
|
| 158 | 133 |
} |
| 159 | 134 |
else |
| 160 | 135 |
{
|
| ... | ... | |
| 171 | 146 |
curr= vv.elementAt(i); |
| 172 | 147 |
next= vv.elementAt(n); |
| 173 | 148 |
|
| 174 |
tmp1.vx = curr.x;
|
|
| 175 |
tmp1.vy = curr.y;
|
|
| 176 |
tmp1.vz = curr.z;
|
|
| 177 |
tmp1.vw = curr.w;
|
|
| 149 |
tmp1.cached[0] = curr.x;
|
|
| 150 |
tmp1.cached[1] = curr.y;
|
|
| 151 |
tmp1.cached[2] = curr.z;
|
|
| 152 |
tmp1.cached[3] = curr.w;
|
|
| 178 | 153 |
|
| 179 |
tmp1.ax = 2*curr.x + tmp1.x - 2*next.x + tmp2.x;
|
|
| 180 |
tmp1.bx = -3*curr.x - 2*tmp1.x + 3*next.x - tmp2.x;
|
|
| 181 |
tmp1.cx = tmp1.x;
|
|
| 182 |
tmp1.dx = curr.x;
|
|
| 154 |
tmp1.a[0] = 2*curr.x + tmp1.tangent[0] - 2*next.x + tmp2.tangent[0];
|
|
| 155 |
tmp1.b[0] = -3*curr.x - 2*tmp1.tangent[0] + 3*next.x - tmp2.tangent[0];
|
|
| 156 |
tmp1.c[0] = tmp1.tangent[0];
|
|
| 157 |
tmp1.d[0] = curr.x;
|
|
| 183 | 158 |
|
| 184 |
tmp1.ay = 2*curr.y + tmp1.y - 2*next.y + tmp2.y;
|
|
| 185 |
tmp1.by = -3*curr.y - 2*tmp1.y + 3*next.y - tmp2.y;
|
|
| 186 |
tmp1.cy = tmp1.y;
|
|
| 187 |
tmp1.dy = curr.y;
|
|
| 159 |
tmp1.a[1] = 2*curr.y + tmp1.tangent[1] - 2*next.y + tmp2.tangent[1];
|
|
| 160 |
tmp1.b[1] = -3*curr.y - 2*tmp1.tangent[1] + 3*next.y - tmp2.tangent[1];
|
|
| 161 |
tmp1.c[1] = tmp1.tangent[1];
|
|
| 162 |
tmp1.d[1] = curr.y;
|
|
| 188 | 163 |
|
| 189 |
tmp1.az = 2*curr.z + tmp1.z - 2*next.z + tmp2.z;
|
|
| 190 |
tmp1.bz = -3*curr.z - 2*tmp1.z + 3*next.z - tmp2.z;
|
|
| 191 |
tmp1.cz = tmp1.z;
|
|
| 192 |
tmp1.dz = curr.z;
|
|
| 164 |
tmp1.a[2] = 2*curr.z + tmp1.tangent[2] - 2*next.z + tmp2.tangent[2];
|
|
| 165 |
tmp1.b[2] = -3*curr.z - 2*tmp1.tangent[2] + 3*next.z - tmp2.tangent[2];
|
|
| 166 |
tmp1.c[2] = tmp1.tangent[2];
|
|
| 167 |
tmp1.d[2] = curr.z;
|
|
| 193 | 168 |
|
| 194 |
tmp1.aw = 2*curr.w + tmp1.w - 2*next.w + tmp2.w;
|
|
| 195 |
tmp1.bw = -3*curr.w - 2*tmp1.w + 3*next.w - tmp2.w;
|
|
| 196 |
tmp1.cw = tmp1.w;
|
|
| 197 |
tmp1.dw = curr.w;
|
|
| 169 |
tmp1.a[3] = 2*curr.w + tmp1.tangent[3] - 2*next.w + tmp2.tangent[3];
|
|
| 170 |
tmp1.b[3] = -3*curr.w - 2*tmp1.tangent[3] + 3*next.w - tmp2.tangent[3];
|
|
| 171 |
tmp1.c[3] = tmp1.tangent[3];
|
|
| 172 |
tmp1.d[3] = curr.w;
|
|
| 198 | 173 |
} |
| 199 | 174 |
} |
| 200 | 175 |
|
| 201 | 176 |
cacheDirty = false; |
| 202 | 177 |
} |
| 203 | 178 |
|
| 204 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
|
| 205 |
// v is the speed vector (i.e. position p(t) differentiated by time) |
|
| 206 |
// a is the acceleration vector (differentiate once more) |
|
| 207 |
// |
|
| 208 |
// Now we construct orthogonal basis with Gram-Schmidt: |
|
| 209 |
// vec1 = a-delta*v where delta = (v*a)/|v|^2 |
|
| 210 |
// vec2 = (0,0,1,0) - coeff1*(vx,vy,vz,vw) - coeff2*(vec1x,vec1y,vec1z,vec1w) where coeff1 = vz/|v|^2, coeff2 = vec1Z/|vec1|^2 |
|
| 211 |
// vec3 = (0,0,0,1) - coeff1*(vx,vy,vz,vw) - coeff2*(vec1x,vec1y,vec1z,vec1w) - coeff3*(vec2x,vec2y,vec2z,vec2w) where coeff1 = vw/|v|^2, coeff2 = vec1W/|vec1|^2, coeff3 = vec2W/|vec2|^2 |
|
| 212 |
|
|
| 213 |
private void setUpVectors(float time,VectorCache vc) |
|
| 214 |
{
|
|
| 215 |
if( vc!=null ) |
|
| 216 |
{
|
|
| 217 |
float vx = (3*vc.ax*time+2*vc.bx)*time+vc.cx; |
|
| 218 |
float vy = (3*vc.ay*time+2*vc.by)*time+vc.cy; |
|
| 219 |
float vz = (3*vc.az*time+2*vc.bz)*time+vc.cz; |
|
| 220 |
float vw = (3*vc.aw*time+2*vc.bw)*time+vc.cw; |
|
| 221 |
|
|
| 222 |
float ax = 6*vc.ax*time+2*vc.bx; |
|
| 223 |
float ay = 6*vc.ay*time+2*vc.by; |
|
| 224 |
float az = 6*vc.az*time+2*vc.bz; |
|
| 225 |
float aw = 6*vc.aw*time+2*vc.bw; |
|
| 226 |
|
|
| 227 |
float v_sq = vx*vx+vy*vy+vz*vz+vw*vw; |
|
| 228 |
float delta = (vx*ax+vy*ay+vz*az+vw*aw)/v_sq; |
|
| 229 |
|
|
| 230 |
vec1X = ax-delta*vx; |
|
| 231 |
vec1Y = ay-delta*vy; |
|
| 232 |
vec1Z = az-delta*vz; |
|
| 233 |
vec1W = aw-delta*vw; |
|
| 234 |
|
|
| 235 |
float vec1_sq = vec1X*vec1X+vec1Y*vec1Y+vec1Z*vec1Z+vec1W*vec1W; |
|
| 236 |
|
|
| 237 |
// construct vec2 and vec3. Cross product does not work in 4th dimension! |
|
| 238 |
float coeff21 = vz/v_sq; |
|
| 239 |
float coeff22 = vec1Z/vec1_sq; |
|
| 240 |
vec2X = 0.0f - coeff21*vx - coeff22*vec1X; |
|
| 241 |
vec2Y = 0.0f - coeff21*vy - coeff22*vec1Y; |
|
| 242 |
vec2Z = 1.0f - coeff21*vz - coeff22*vec1Z; |
|
| 243 |
vec2W = 0.0f - coeff21*vw - coeff22*vec1W; |
|
| 244 |
|
|
| 245 |
float vec2_sq = vec2X*vec2X+vec2Y*vec2Y+vec2Z*vec2Z+vec2W*vec2W; |
|
| 246 |
float coeff31 = vw/v_sq; |
|
| 247 |
float coeff32 = vec1W/vec1_sq; |
|
| 248 |
float coeff33 = vec2W/vec2_sq; |
|
| 249 |
vec3X = 0.0f - coeff31*vx - coeff32*vec1X - coeff33*vec2X; |
|
| 250 |
vec3Y = 0.0f - coeff31*vy - coeff32*vec1Y - coeff33*vec2Y; |
|
| 251 |
vec3Z = 0.0f - coeff31*vz - coeff32*vec1Z - coeff33*vec2Z; |
|
| 252 |
vec3W = 1.0f - coeff31*vw - coeff32*vec1W - coeff33*vec2W; |
|
| 253 |
|
|
| 254 |
float vec3_sq = vec3X*vec3X+vec3Y*vec3Y+vec3Z*vec3Z+vec3W*vec3W; |
|
| 255 |
|
|
| 256 |
float len1 = (float)Math.sqrt(v_sq/vec1_sq); |
|
| 257 |
float len2 = (float)Math.sqrt(v_sq/vec2_sq); |
|
| 258 |
float len3 = (float)Math.sqrt(v_sq/vec3_sq); |
|
| 259 |
|
|
| 260 |
vec1X*=len1; |
|
| 261 |
vec1Y*=len1; |
|
| 262 |
vec1Z*=len1; |
|
| 263 |
vec1W*=len1; |
|
| 264 |
|
|
| 265 |
vec2X*=len2; |
|
| 266 |
vec2Y*=len2; |
|
| 267 |
vec2Z*=len2; |
|
| 268 |
vec2W*=len2; |
|
| 269 |
|
|
| 270 |
vec3X*=len3; |
|
| 271 |
vec3Y*=len3; |
|
| 272 |
vec3Z*=len3; |
|
| 273 |
vec3W*=len3; |
|
| 274 |
} |
|
| 275 |
else |
|
| 276 |
{
|
|
| 277 |
curr = vv.elementAt(0); |
|
| 278 |
next = vv.elementAt(1); |
|
| 279 |
|
|
| 280 |
float vx = (next.x-curr.x); |
|
| 281 |
float vy = (next.y-curr.y); |
|
| 282 |
float vz = (next.z-curr.z); |
|
| 283 |
float vw = (next.w-curr.w); |
|
| 284 |
|
|
| 285 |
float b = (float)Math.sqrt(vx*vx+vy*vy+vz*vz); |
|
| 286 |
|
|
| 287 |
if( b>0.0f ) |
|
| 288 |
{
|
|
| 289 |
vec1X = vx*vw/b; |
|
| 290 |
vec1Y = vy*vw/b; |
|
| 291 |
vec1Z = vz*vw/b; |
|
| 292 |
vec1W = -b; |
|
| 293 |
|
|
| 294 |
float v_sq = vx*vx+vy*vy+vz*vz+vw*vw; |
|
| 295 |
float vec1_sq = vec1X*vec1X+vec1Y*vec1Y+vec1Z*vec1Z+vec1W*vec1W; |
|
| 296 |
|
|
| 297 |
// construct vec2 and vec3. Cross product does not work in 4th dimension! |
|
| 298 |
float coeff21 = vz/v_sq; |
|
| 299 |
float coeff22 = vec1Z/vec1_sq; |
|
| 300 |
vec2X = 0.0f - coeff21*vx - coeff22*vec1X; |
|
| 301 |
vec2Y = 0.0f - coeff21*vy - coeff22*vec1Y; |
|
| 302 |
vec2Z = 1.0f - coeff21*vz - coeff22*vec1Z; |
|
| 303 |
vec2W = 0.0f - coeff21*vw - coeff22*vec1W; |
|
| 304 |
|
|
| 305 |
float vec2_sq = vec2X*vec2X+vec2Y*vec2Y+vec2Z*vec2Z+vec2W*vec2W; |
|
| 306 |
float coeff31 = vw/v_sq; |
|
| 307 |
float coeff32 = vec1W/vec1_sq; |
|
| 308 |
float coeff33 = vec2W/vec2_sq; |
|
| 309 |
vec3X = 0.0f - coeff31*vx - coeff32*vec1X - coeff33*vec2X; |
|
| 310 |
vec3Y = 0.0f - coeff31*vy - coeff32*vec1Y - coeff33*vec2Y; |
|
| 311 |
vec3Z = 0.0f - coeff31*vz - coeff32*vec1Z - coeff33*vec2Z; |
|
| 312 |
vec3W = 1.0f - coeff31*vw - coeff32*vec1W - coeff33*vec2W; |
|
| 313 |
|
|
| 314 |
float vec3_sq = vec3X*vec3X+vec3Y*vec3Y+vec3Z*vec3Z+vec3W*vec3W; |
|
| 315 |
|
|
| 316 |
float len1 = (float)Math.sqrt(v_sq/vec1_sq); |
|
| 317 |
float len2 = (float)Math.sqrt(v_sq/vec2_sq); |
|
| 318 |
float len3 = (float)Math.sqrt(v_sq/vec3_sq); |
|
| 319 |
|
|
| 320 |
vec1X*=len1; |
|
| 321 |
vec1Y*=len1; |
|
| 322 |
vec1Z*=len1; |
|
| 323 |
vec1W*=len1; |
|
| 324 |
|
|
| 325 |
vec2X*=len2; |
|
| 326 |
vec2Y*=len2; |
|
| 327 |
vec2Z*=len2; |
|
| 328 |
vec2W*=len2; |
|
| 329 |
|
|
| 330 |
vec3X*=len3; |
|
| 331 |
vec3Y*=len3; |
|
| 332 |
vec3Z*=len3; |
|
| 333 |
vec3W*=len3; |
|
| 334 |
} |
|
| 335 |
else |
|
| 336 |
{
|
|
| 337 |
vec1X = vw; |
|
| 338 |
vec1Y = 0.0f; |
|
| 339 |
vec1Z = 0.0f; |
|
| 340 |
vec1W = 0.0f; |
|
| 341 |
|
|
| 342 |
vec2X = 0.0f; |
|
| 343 |
vec2Y = vw; |
|
| 344 |
vec2Z = 0.0f; |
|
| 345 |
vec2W = 0.0f; |
|
| 346 |
|
|
| 347 |
vec3X = 0.0f; |
|
| 348 |
vec3Y = 0.0f; |
|
| 349 |
vec3Z = vw; |
|
| 350 |
vec3W = 0.0f; |
|
| 351 |
} |
|
| 352 |
} |
|
| 353 |
} |
|
| 354 |
|
|
| 355 | 179 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
| 356 | 180 |
// PUBLIC API |
| 357 | 181 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
Also available in: Unified diff
Completely redesign Noise in the Dynamics and move all the complexity to the parent class.
something does not work with it now :)