Revision 9dacabea
Added by Leszek Koltunski over 4 years ago
src/main/java/org/distorted/library/type/DynamicQuat.java | ||
---|---|---|
63 | 63 |
} |
64 | 64 |
|
65 | 65 |
/////////////////////////////////////////////////////////////////////////////////////////////////// |
66 |
|
|
66 |
|
|
67 | 67 |
private void recomputeCache() |
68 | 68 |
{ |
69 | 69 |
if( numPoints>=2 ) |
70 | 70 |
{ |
71 | 71 |
int i, n; |
72 |
|
|
72 |
Static4D cu,ne; |
|
73 |
VectorCacheQuat vq; |
|
74 |
|
|
73 | 75 |
for(i=0; i<numPoints; i++) |
74 | 76 |
{ |
75 | 77 |
n = i<numPoints-1 ? i+1:0; |
76 | 78 |
|
77 |
tmp1= vc.elementAt(i); |
|
78 |
tmp2= vc.elementAt(n); |
|
79 |
curr= vv.elementAt(i); |
|
80 |
next= vv.elementAt(n); |
|
79 |
vq= vc.elementAt(i); |
|
80 |
cu= vv.elementAt(i); |
|
81 |
ne= vv.elementAt(n); |
|
81 | 82 |
|
82 |
tmp1.vx = curr.x;
|
|
83 |
tmp1.vy = curr.y;
|
|
84 |
tmp1.vz = curr.z;
|
|
85 |
tmp1.vw = curr.w;
|
|
83 |
vq.vx = cu.x;
|
|
84 |
vq.vy = cu.y;
|
|
85 |
vq.vz = cu.z;
|
|
86 |
vq.vw = cu.w;
|
|
86 | 87 |
|
87 |
tmp1.cosOmega = curr.x*next.x + curr.y*next.y + curr.z*next.z + curr.w*next.w;
|
|
88 |
vq.cosOmega = cu.x*ne.x + cu.y*ne.y + cu.z*ne.z + cu.w*ne.w;
|
|
88 | 89 |
|
89 |
if( tmp1.cosOmega<0 && n!=0 ) // do not invert the last quaternion even if we'd have to go the long way around!
|
|
90 |
if( vq.cosOmega<0 && n!=0 ) // do not invert the last quaternion even if we'd have to go the long way around!
|
|
90 | 91 |
{ |
91 |
tmp1.cosOmega = -tmp1.cosOmega;
|
|
92 |
next.x = -next.x;
|
|
93 |
next.y = -next.y;
|
|
94 |
next.z = -next.z;
|
|
95 |
next.w = -next.w;
|
|
92 |
vq.cosOmega = -vq.cosOmega;
|
|
93 |
ne.x = -ne.x;
|
|
94 |
ne.y = -ne.y;
|
|
95 |
ne.z = -ne.z;
|
|
96 |
ne.w = -ne.w;
|
|
96 | 97 |
} |
97 | 98 |
|
98 |
tmp1.sinOmega = (float)Math.sqrt(1-tmp1.cosOmega*tmp1.cosOmega);
|
|
99 |
tmp1.omega = arcCos(tmp1.cosOmega);
|
|
99 |
vq.sinOmega = (float)Math.sqrt(1-vq.cosOmega*vq.cosOmega);
|
|
100 |
vq.omega = arcCos(vq.cosOmega);
|
|
100 | 101 |
} |
101 | 102 |
} |
102 | 103 |
|
... | ... | |
341 | 342 |
buffer[offset+3] = curr.w; |
342 | 343 |
break; |
343 | 344 |
default:float t = time; |
345 |
int vecCurr, segment; |
|
344 | 346 |
float scale0, scale1; |
345 |
|
|
346 |
if( mMode==MODE_JUMP ) time = time*(numPoints-1); |
|
347 |
else if( mMode==MODE_PATH || numPoints==2 ) time = (time<=0.5f) ? 2*time*(numPoints-1) : 2*(1-time)*(numPoints-1); |
|
348 |
else time = time*numPoints; |
|
349 |
|
|
350 |
int vecNext, vecCurr = (int)time; |
|
351 |
time = time-vecCurr; |
|
352 |
|
|
347 |
|
|
348 |
switch(mMode) |
|
349 |
{ |
|
350 |
case MODE_LOOP: time = time*numPoints; |
|
351 |
segment = (int)time; |
|
352 |
vecCurr = segment; |
|
353 |
break; |
|
354 |
case MODE_PATH: if( t>0.5f ) t = 1.0f-t; |
|
355 |
time = 2*t*(numPoints-1); |
|
356 |
segment = (int)(2*t*(numPoints-1)); |
|
357 |
vecCurr = segment; |
|
358 |
break; |
|
359 |
case MODE_JUMP: time = time*(numPoints-1); |
|
360 |
segment = (int)time; |
|
361 |
vecCurr = segment; |
|
362 |
break; |
|
363 |
default : vecCurr = 0; |
|
364 |
segment = 0; |
|
365 |
} |
|
366 |
|
|
353 | 367 |
if( vecCurr>=0 && vecCurr<numPoints ) |
354 | 368 |
{ |
355 |
if( cacheDirty ) recomputeCache(); // recompute cache if we have added or remove vectors since last computation |
|
356 |
|
|
357 |
switch(mMode) |
|
358 |
{ |
|
359 |
case MODE_LOOP: vecNext = vecCurr==numPoints-1 ? 0:vecCurr+1; |
|
360 |
break; |
|
361 |
case MODE_PATH: if( t<0.5f ) vecNext = vecCurr+1; |
|
362 |
else vecNext = vecCurr==0 ? 1 : vecCurr-1; |
|
363 |
break; |
|
364 |
case MODE_JUMP: vecNext = vecCurr==numPoints-1 ? 1:vecCurr+1; |
|
365 |
break; |
|
366 |
default : vecNext = 0; |
|
367 |
} |
|
368 |
|
|
369 |
int vecNext = getNext(vecCurr,t); |
|
370 |
|
|
369 | 371 |
curr = vv.elementAt(vecCurr); |
370 |
next = vv.elementAt(vecNext); |
|
371 | 372 |
tmp1 = vc.elementAt(vecCurr); |
372 |
tmp2 = vc.elementAt(vecNext); |
|
373 |
|
|
374 |
if( tmp2.vx!=next.x || tmp2.vy!=next.y || tmp2.vz!=next.z || tmp2.vw!=next.w ) recomputeCache(); |
|
375 |
|
|
373 |
next = vv.elementAt(vecNext); |
|
374 |
|
|
375 |
if( cacheDirty ) recomputeCache(); // recompute cache if we have added or remove vectors since last computation |
|
376 |
else if( mSegment!= segment ) // ...or if we have just passed a vector and the vector we are currently flying to has changed |
|
377 |
{ |
|
378 |
tmp2 = vc.elementAt(vecNext); |
|
379 |
|
|
380 |
if( tmp2.vx!=next.x || tmp2.vy!=next.y || tmp2.vz!=next.z || tmp2.vw!=next.w ) recomputeCache(); |
|
381 |
} |
|
382 |
|
|
383 |
mSegment = segment; |
|
384 |
|
|
385 |
time = time-vecCurr; |
|
386 |
|
|
376 | 387 |
if( tmp1.sinOmega==0 ) |
377 | 388 |
{ |
378 |
scale0 = 0f;
|
|
379 |
scale1 = 1f;
|
|
389 |
scale0 = 1f;
|
|
390 |
scale1 = 0f;
|
|
380 | 391 |
} |
381 |
else if( tmp1.cosOmega < 0.99 )
|
|
392 |
else if( tmp1.cosOmega < 0.99 ) |
|
382 | 393 |
{ |
383 | 394 |
scale0 = (float)Math.sin( (1f-time)*tmp1.omega ) / tmp1.sinOmega; |
384 | 395 |
scale1 = (float)Math.sin( time *tmp1.omega ) / tmp1.sinOmega; |
385 | 396 |
} |
386 |
else
|
|
397 |
else |
|
387 | 398 |
{ |
388 | 399 |
scale0 = 1f-time; |
389 | 400 |
scale1 = time; |
390 | 401 |
} |
391 | 402 |
|
392 | 403 |
buffer[offset ] = scale0*curr.x + scale1*next.x; |
393 |
buffer[offset+1] = scale0*curr.y + scale1*next.y;
|
|
394 |
buffer[offset+2] = scale0*curr.z + scale1*next.z;
|
|
395 |
buffer[offset+3] = scale0*curr.w + scale1*next.w;
|
|
396 |
|
|
404 |
buffer[offset+1] = scale0*curr.y + scale1*next.y; |
|
405 |
buffer[offset+2] = scale0*curr.z + scale1*next.z; |
|
406 |
buffer[offset+3] = scale0*curr.w + scale1*next.w; |
|
407 |
|
|
397 | 408 |
break; |
398 | 409 |
} |
399 | 410 |
} |
Also available in: Unified diff
library: Fix DynamicQuat
cube app: progress with ScrambleEffects