Project

General

Profile

Download (20.8 KB) Statistics
| Branch: | Revision:

library / src / main / java / org / distorted / library / type / Dynamic5D.java @ c0e4d5cf

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.library.type;
21

    
22
import java.util.Vector;
23

    
24
///////////////////////////////////////////////////////////////////////////////////////////////////
25
/** 
26
* A 5-dimensional implementation of the Dynamic class to interpolate between a list
27
* of Static5Ds.
28
*/
29

    
30
public class Dynamic5D extends Dynamic implements Data5D
31
  {
32
  private Vector<Static5D> vv;
33
  private Static5D prev, curr, next;
34

    
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36
// no array bounds checking!
37
  
38
  private void computeVelocity(int c)
39
    {
40
    int p = c>0 ? c-1: numPoints-1;
41
    int n = c<numPoints-1 ? c+1: 0;
42
    
43
    prev = vv.elementAt(p);
44
    curr = vv.elementAt(c);
45
    next = vv.elementAt(n);
46

    
47
    tmpCache1 = vc.elementAt(c);
48
    
49
    float px = curr.x - prev.x;
50
    float py = curr.y - prev.y;
51
    float pz = curr.z - prev.z;
52
    float pw = curr.w - prev.w;
53
    float pv = curr.v - prev.v;
54
    float nx = next.x - curr.x;
55
    float ny = next.y - curr.y;
56
    float nz = next.z - curr.z;
57
    float nw = next.w - curr.w;
58
    float nv = next.v - curr.v;
59
     
60
    float d = nx*nx+ny*ny+nz*nz+nw*nw+nv*nv;
61
    
62
    if( d>0 )
63
      {
64
      float q = (float)Math.sqrt((px*px+py*py+pz*pz+pw*pw+pv*pv)/d);
65
      
66
      if( q>1 )
67
        {
68
        tmpCache1.velocity[0] = nx+px/q;
69
        tmpCache1.velocity[1] = ny+py/q;
70
        tmpCache1.velocity[2] = nz+pz/q;
71
        tmpCache1.velocity[3] = nw+pw/q;
72
        tmpCache1.velocity[4] = nv+pv/q;
73
        }
74
      else
75
        {
76
        tmpCache1.velocity[0] = px+nx*q;
77
        tmpCache1.velocity[1] = py+ny*q;
78
        tmpCache1.velocity[2] = pz+nz*q;
79
        tmpCache1.velocity[3] = pw+nw*q;
80
        tmpCache1.velocity[4] = pv+nv*q;
81
        }
82
      }
83
    else
84
      {
85
      tmpCache1.velocity[0] = 0.0f;
86
      tmpCache1.velocity[1] = 0.0f;
87
      tmpCache1.velocity[2] = 0.0f;
88
      tmpCache1.velocity[3] = 0.0f;
89
      tmpCache1.velocity[4] = 0.0f;
90
      }
91
    }
92
    
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94
  
95
  private void recomputeCache()
96
    {  
97
    if( numPoints==1 )
98
      {
99
      tmpCache1 = vc.elementAt(0);
100
      curr= vv.elementAt(0);
101
        
102
      tmpCache1.a[0] = tmpCache1.a[1] = tmpCache1.a[2] = tmpCache1.a[3] = tmpCache1.a[4] = 0.0f;
103
      tmpCache1.b[0] = tmpCache1.b[1] = tmpCache1.b[2] = tmpCache1.b[3] = tmpCache1.b[4] = 0.0f;
104
      tmpCache1.c[0] = curr.x;
105
      tmpCache1.c[1] = curr.y;
106
      tmpCache1.c[2] = curr.z;
107
      tmpCache1.c[3] = curr.w;
108
      tmpCache1.c[4] = curr.v;
109
      tmpCache1.d[0] = tmpCache1.d[1] = tmpCache1.d[2] = tmpCache1.d[3] = tmpCache1.d[4] = 0.0f;
110
      }
111
    else if( numPoints==2 )
112
      {
113
      tmpCache1 = vc.elementAt(0);
114
      tmpCache2 = vc.elementAt(1);
115
      curr= vv.elementAt(0);
116
      next= vv.elementAt(1);
117
      
118
      tmpCache1.a[0] = tmpCache1.a[1] = tmpCache1.a[2] = tmpCache1.a[3] = tmpCache1.a[4] = 0.0f;
119
      tmpCache1.b[0] = tmpCache1.b[1] = tmpCache1.b[2] = tmpCache1.b[3] = tmpCache1.b[4] = 0.0f;
120
      tmpCache1.c[0] = next.x - curr.x;
121
      tmpCache1.c[1] = next.y - curr.y;
122
      tmpCache1.c[2] = next.z - curr.z;
123
      tmpCache1.c[3] = next.w - curr.w;
124
      tmpCache1.c[4] = next.v - curr.v;
125
      tmpCache1.d[0] = curr.x;
126
      tmpCache1.d[1] = curr.y;
127
      tmpCache1.d[2] = curr.z;
128
      tmpCache1.d[3] = curr.w;
129
      tmpCache1.d[4] = curr.v;
130
      
131
      tmpCache2.a[0] = tmpCache2.a[1] = tmpCache2.a[2] = tmpCache2.a[3] = tmpCache2.a[4] = 0.0f;
132
      tmpCache2.b[0] = tmpCache2.b[1] = tmpCache2.b[2] = tmpCache2.b[3] = tmpCache2.b[4] = 0.0f;
133
      tmpCache2.c[0] = curr.x - next.x;
134
      tmpCache2.c[1] = curr.y - next.y;
135
      tmpCache2.c[2] = curr.z - next.z;
136
      tmpCache2.c[3] = curr.w - next.w;
137
      tmpCache2.c[4] = curr.v - next.v;
138
      tmpCache2.d[0] = next.x;
139
      tmpCache2.d[1] = next.y;
140
      tmpCache2.d[2] = next.z;
141
      tmpCache2.d[3] = next.w;
142
      tmpCache2.d[4] = next.v;
143
      }
144
    else
145
      {
146
      int i, n;  
147
      
148
      for(i=0; i<numPoints; i++) computeVelocity(i);
149
   
150
      for(i=0; i<numPoints; i++)
151
        {
152
        n = i<numPoints-1 ? i+1:0;  
153
      
154
        tmpCache1 = vc.elementAt(i);
155
        tmpCache2 = vc.elementAt(n);
156
        curr= vv.elementAt(i);
157
        next= vv.elementAt(n);
158
      
159
        tmpCache1.cached[0] = curr.x;
160
        tmpCache1.cached[1] = curr.y;
161
        tmpCache1.cached[2] = curr.z;
162
        tmpCache1.cached[3] = curr.w;
163
        tmpCache1.cached[4] = curr.v;
164
        
165
        tmpCache1.a[0] = mConvexity*( 2*curr.x +   tmpCache1.velocity[0] - 2*next.x + tmpCache2.velocity[0]);
166
        tmpCache1.b[0] = mConvexity*(-3*curr.x - 2* tmpCache1.velocity[0] + 3*next.x - tmpCache2.velocity[0]);
167
        tmpCache1.c[0] = mConvexity*(tmpCache1.velocity[0]) + (1.0f-mConvexity)*(next.x-curr.x);
168
        tmpCache1.d[0] = curr.x;
169
      
170
        tmpCache1.a[1] = mConvexity*( 2*curr.y +   tmpCache1.velocity[1] - 2*next.y + tmpCache2.velocity[1]);
171
        tmpCache1.b[1] = mConvexity*(-3*curr.y - 2* tmpCache1.velocity[1] + 3*next.y - tmpCache2.velocity[1]);
172
        tmpCache1.c[1] = mConvexity*(tmpCache1.velocity[1]) + (1.0f-mConvexity)*(next.y-curr.y);
173
        tmpCache1.d[1] = curr.y;
174
      
175
        tmpCache1.a[2] = mConvexity*( 2*curr.z +   tmpCache1.velocity[2] - 2*next.z + tmpCache2.velocity[2]);
176
        tmpCache1.b[2] = mConvexity*(-3*curr.z - 2* tmpCache1.velocity[2] + 3*next.z - tmpCache2.velocity[2]);
177
        tmpCache1.c[2] = mConvexity*(tmpCache1.velocity[2]) + (1.0f-mConvexity)*(next.z-curr.z);
178
        tmpCache1.d[2] = curr.z;
179
        
180
        tmpCache1.a[3] = mConvexity*( 2*curr.w +   tmpCache1.velocity[3] - 2*next.w + tmpCache2.velocity[3]);
181
        tmpCache1.b[3] = mConvexity*(-3*curr.w - 2* tmpCache1.velocity[3] + 3*next.w - tmpCache2.velocity[3]);
182
        tmpCache1.c[3] = mConvexity*(tmpCache1.velocity[3]) + (1.0f-mConvexity)*(next.w-curr.w);
183
        tmpCache1.d[3] = curr.w;
184
        
185
        tmpCache1.a[4] = mConvexity*( 2*curr.v +   tmpCache1.velocity[4] - 2*next.v + tmpCache2.velocity[4]);
186
        tmpCache1.b[4] = mConvexity*(-3*curr.v - 2* tmpCache1.velocity[4] + 3*next.v - tmpCache2.velocity[4]);
187
        tmpCache1.c[4] = mConvexity*(tmpCache1.velocity[4]) + (1.0f-mConvexity)*(next.v-curr.v);
188
        tmpCache1.d[4] = curr.v;
189

    
190
        if( mSpeedMode==SPEED_MODE_SEGMENT_CONSTANT ) smoothOutSegment(tmpCache1);
191
        }
192
      }
193
   
194
    cacheDirty = false;
195
    }
196

    
197
///////////////////////////////////////////////////////////////////////////////////////////////////
198
// PUBLIC API
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
/**
201
 * Default constructor.
202
 */
203
  public Dynamic5D()
204
    {
205
    super(0,0.5f,5);
206
    vv = new Vector<>();
207
    }
208

    
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210
/**
211
 * Constructor setting the speed of interpolation and the number of revolutions.
212
 *
213
 * What constitutes 'one revolution' depends on the MODE:
214
 * {@link Dynamic#MODE_LOOP}, {@link Dynamic#MODE_PATH} or {@link Dynamic#MODE_JUMP}.
215
 *
216
 * @param duration number of milliseconds it takes to do one revolution.
217
 * @param count    number of revolutions we will do. Count<=0 means 'infinite'.
218
 */
219
  public Dynamic5D(int duration, float count)
220
    {
221
    super(duration,count,5);
222
    vv = new Vector<>();
223
    }
224

    
225
///////////////////////////////////////////////////////////////////////////////////////////////////
226
/**
227
 * Returns the location'th Static5D.
228
 *   
229
 * @param location the index of the Point we are interested in.
230
 * @return The Static5D, if 0<=location&lt;getNumPoints(), or null otherwise.
231
 */  
232
  public synchronized Static5D getPoint(int location)
233
    {
234
    return (location>=0 && location<numPoints) ? vv.elementAt(location) : null;  
235
    }
236
  
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238
/**
239
 * Resets the location'th Point.
240
 * 
241
 * @param location the index of the Point we are setting.
242
 * @param x New value of its first float.
243
 */
244
  public synchronized void setPoint(int location, float x, float y, float z, float w, float v)
245
    {
246
    if( location>=0 && location<numPoints )
247
      {
248
      curr = vv.elementAt(location);
249
   
250
      if( curr!=null )
251
        {
252
        curr.set(x,y,z,w,v);
253
        cacheDirty=true;
254
        }
255
      }
256
    }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259
/**
260
 * Adds a new Static5D to the end of our list of Points to interpolate through.
261
 * <p>   
262
 * Only a reference to the Point gets added to the List; this means that one can add a Point 
263
 * here, and later on {@link Static5D#set(float,float,float,float,float)} it to some new value and
264
 * the change will be seamlessly reflected in the interpolated path.  
265
 * <p>
266
 * A Point can be added multiple times.
267
 *   
268
 * @param v The Point to add.
269
 */    
270
  public synchronized void add(Static5D v)
271
    {
272
    if( v!=null )
273
      {
274
      vv.add(v);
275
        
276
      if( vn!=null ) vn.add(new VectorNoise());
277
       
278
      switch(numPoints)
279
        {
280
        case 0: break;
281
        case 1: computeOrthonormalBase2(vv.elementAt(0),v);
282
                break;
283
        case 2: vc.add(new VectorCache());
284
                vc.add(new VectorCache());
285
                vc.add(new VectorCache());
286
                break;
287
        default:vc.add(new VectorCache());
288
        }
289

    
290
      numPoints++;
291
      cacheDirty = true;
292
      }
293
    }
294

    
295
///////////////////////////////////////////////////////////////////////////////////////////////////
296
/**
297
 * Adds a new Static5D to the location'th place in our List of Points to interpolate through.
298
 *   
299
 * @param location Index in our List to add the new Point at.
300
 * @param v The Static5D to add.
301
 */  
302
  public synchronized void add(int location, Static5D v)
303
    {
304
    if( v!=null )
305
      {
306
      vv.add(location, v);
307
      
308
      if( vn!=null ) vn.add(new VectorNoise());
309
      
310
      switch(numPoints)
311
        {
312
        case 0: break;
313
        case 1: computeOrthonormalBase2(vv.elementAt(0),v);
314
                break;
315
        case 2: vc.add(new VectorCache());
316
                vc.add(new VectorCache());
317
                vc.add(new VectorCache());
318
                break;
319
        default:vc.add(location,new VectorCache());
320
        }
321

    
322
      numPoints++;
323
      cacheDirty = true;
324
      }
325
    }
326
  
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328
/**
329
 * Removes all occurrences of Point v from the List of Points to interpolate through.  
330
 * 
331
 * @param v The Point to remove.
332
 * @return <code>true</code> if we have removed at least one Point.
333
 */
334
  public synchronized boolean remove(Static5D v)
335
    {
336
    int n = vv.indexOf(v);
337
    boolean found = false;
338
   
339
    while( n>=0 ) 
340
      {
341
      vv.remove(n);
342
     
343
      if( vn!=null ) vn.remove(0);
344
     
345
      switch(numPoints)
346
        {
347
        case 0:
348
        case 1: 
349
        case 2: break;
350
        case 3: vc.removeAllElements();
351
                computeOrthonormalBase2(vv.elementAt(0),vv.elementAt(1));
352
                break;
353
        default:vc.remove(n);
354
        }
355

    
356
      numPoints--;
357
      found = true;
358
      n = vv.indexOf(v);
359
      }
360
   
361
    if( found ) 
362
      {
363
      cacheDirty=true;
364
      }
365
   
366
    return found;
367
    }
368

    
369
///////////////////////////////////////////////////////////////////////////////////////////////////
370
/**
371
 * Removes a location'th Point from the List of Points we interpolate through.
372
 * 
373
 * @param location index of the Point we want to remove. 
374
 * @return <code>true</code> if location is valid, i.e. if 0<=location&lt;getNumPoints().
375
 */
376
  public synchronized boolean remove(int location)
377
    {
378
    if( location>=0 && location<numPoints ) 
379
      {
380
      vv.removeElementAt(location);
381
       
382
      if( vn!=null ) vn.remove(0);
383
      
384
      switch(numPoints)
385
        {
386
        case 0:
387
        case 1: 
388
        case 2: break;
389
        case 3: vc.removeAllElements();
390
                computeOrthonormalBase2(vv.elementAt(0),vv.elementAt(1));
391
                break;
392
        default:vc.removeElementAt(location);
393
        }
394

    
395
      numPoints--;
396
      cacheDirty = true; 
397
      return true;
398
      }
399

    
400
    return false;
401
    }
402
  
403
///////////////////////////////////////////////////////////////////////////////////////////////////
404
/**
405
 * Removes all Points.
406
 */
407
  public synchronized void removeAll()
408
    {
409
    numPoints = 0;
410
    vv.removeAllElements();
411
    vc.removeAllElements();
412
    cacheDirty = false;
413
   
414
    if( vn!=null ) vn.removeAllElements();
415
    }
416

    
417
///////////////////////////////////////////////////////////////////////////////////////////////////
418
/**
419
 * Sets the 'smoothness' of interpolation.
420
 * <p>
421
 * When Noise=0 (the default), we interpolate between our Points through the most smooth path possible.
422
 * Increasing noise makes the Dynamic increasingly deviate from this path, pseudo-randomly speeding
423
 * up and slowing down, etc.
424
 *
425
 * @param noise The noise level. Permitted range: 0 <= noise <= 1.
426
 */
427

    
428
  public synchronized void setNoise(Static5D noise)
429
    {
430
    if( vn==null )
431
      {
432
      vn = new Vector<>();
433
      for(int i=0; i<numPoints; i++) vn.add(new VectorNoise());
434

    
435
      if( mDimension>=2 )
436
        {
437
        mFactor = new float[mDimension-1];
438
        }
439

    
440
      mNoise = new float[mDimension];
441
      }
442

    
443
    if( noise.x<0.0f ) noise.x = 0.0f;
444
    if( noise.x>1.0f ) noise.x = 1.0f;
445
    if( noise.y<0.0f ) noise.y = 0.0f;
446
    if( noise.y>1.0f ) noise.y = 1.0f;
447
    if( noise.z<0.0f ) noise.z = 0.0f;
448
    if( noise.z>1.0f ) noise.z = 1.0f;
449
    if( noise.w<0.0f ) noise.w = 0.0f;
450
    if( noise.w>1.0f ) noise.w = 1.0f;
451
    if( noise.v<0.0f ) noise.v = 0.0f;
452
    if( noise.v>1.0f ) noise.v = 1.0f;
453

    
454
    mNoise[0] = noise.x;
455
    mNoise[1] = noise.y;
456
    mNoise[2] = noise.z;
457
    mNoise[3] = noise.w;
458
    mNoise[4] = noise.v;
459
    }
460

    
461
///////////////////////////////////////////////////////////////////////////////////////////////////
462

    
463
  synchronized void interpolate(float[] buffer, int offset, float time)
464
    {  
465
    switch(numPoints)
466
      {
467
      case 0: buffer[offset  ] = 0.0f;
468
              buffer[offset+1] = 0.0f;
469
              buffer[offset+2] = 0.0f;
470
              buffer[offset+3] = 0.0f;
471
              buffer[offset+4] = 0.0f;
472
              break;
473
      case 1: curr = vv.elementAt(0);
474
              buffer[offset  ] = curr.x;
475
              buffer[offset+1] = curr.y;
476
              buffer[offset+2] = curr.z;
477
              buffer[offset+3] = curr.w;
478
              buffer[offset+4] = curr.v;
479
              break;
480
      case 2: curr = vv.elementAt(0);
481
              next = vv.elementAt(1);
482

    
483
              int segment= (int)(2*time);
484

    
485
              if( mMode==MODE_LOOP || mMode==MODE_PATH ) time = (time>0.5f ? 2-2*time : 2*time);
486

    
487
              if( vn!=null )
488
                {
489
                if( segment != mSegment )
490
                  {
491
                  if(mMode!=MODE_JUMP || mSegment==1) vn.elementAt(0).computeNoise();
492
                  mSegment = segment;
493
                  }
494

    
495
                time = noise(time,0);
496

    
497
                buffer[offset  ] = (next.x-curr.x)*time + curr.x + (baseV[1][0]*mFactor[0] + baseV[2][0]*mFactor[1] + baseV[3][0]*mFactor[2] + baseV[4][0]*mFactor[3]);
498
                buffer[offset+1] = (next.y-curr.y)*time + curr.y + (baseV[1][1]*mFactor[0] + baseV[2][1]*mFactor[1] + baseV[3][1]*mFactor[2] + baseV[4][1]*mFactor[3]);
499
                buffer[offset+2] = (next.z-curr.z)*time + curr.z + (baseV[1][2]*mFactor[0] + baseV[2][2]*mFactor[1] + baseV[3][2]*mFactor[2] + baseV[4][2]*mFactor[3]);
500
                buffer[offset+3] = (next.w-curr.w)*time + curr.w + (baseV[1][3]*mFactor[0] + baseV[2][3]*mFactor[1] + baseV[3][3]*mFactor[2] + baseV[4][3]*mFactor[3]);
501
                buffer[offset+4] = (next.v-curr.v)*time + curr.v + (baseV[1][4]*mFactor[0] + baseV[2][4]*mFactor[1] + baseV[3][4]*mFactor[2] + baseV[4][4]*mFactor[3]);
502
                }
503
              else
504
                {
505
                buffer[offset  ] = (next.x-curr.x)*time + curr.x;
506
                buffer[offset+1] = (next.y-curr.y)*time + curr.y;
507
                buffer[offset+2] = (next.z-curr.z)*time + curr.z;
508
                buffer[offset+3] = (next.w-curr.w)*time + curr.w;
509
                buffer[offset+4] = (next.v-curr.v)*time + curr.v;
510
                }
511
                
512
              break;
513
      default:computeSegmentAndTime(time);
514

    
515
              if( mTmpVec>=0 && mTmpVec<numPoints )
516
                {
517
                if( cacheDirty ) recomputeCache();  // recompute cache if we have added or remove vectors since last computation
518
                else if( mSegment!= mTmpSeg )       // ...or if we have just passed a vector and the vector we are currently flying to has changed
519
                  {
520
                  int vecNext = getNext(mTmpVec,time);
521
                  next = vv.elementAt(vecNext);
522
                  tmpCache2 = vc.elementAt(vecNext);
523

    
524
                  if( tmpCache2.cached[0]!=next.x || tmpCache2.cached[1]!=next.y || tmpCache2.cached[2]!=next.z || tmpCache2.cached[3]!=next.w || tmpCache2.cached[4]!=next.v ) recomputeCache();
525
                  }
526

    
527
                if( mSegment!= mTmpSeg && vn!=null ) vn.elementAt(mTmpVec).computeNoise();
528

    
529
                mSegment = mTmpSeg;
530
                time = mTmpTime-mTmpVec;
531
                tmpCache1 = vc.elementAt(mTmpVec);
532
                if( mSpeedMode==SPEED_MODE_SEGMENT_CONSTANT ) time = smoothSpeed(time, tmpCache1);
533

    
534
                if( vn!=null )
535
                  {
536
                  time = noise(time,mTmpVec);
537
              
538
                  computeOrthonormalBaseMore(time, tmpCache1);
539

    
540
                  buffer[offset  ]= ((tmpCache1.a[0]*time+ tmpCache1.b[0])*time+ tmpCache1.c[0])*time+ tmpCache1.d[0] + (baseV[1][0]*mFactor[0] + baseV[2][0]*mFactor[1] + baseV[3][0]*mFactor[2] + baseV[4][0]*mFactor[3]);
541
                  buffer[offset+1]= ((tmpCache1.a[1]*time+ tmpCache1.b[1])*time+ tmpCache1.c[1])*time+ tmpCache1.d[1] + (baseV[1][1]*mFactor[0] + baseV[2][1]*mFactor[1] + baseV[3][1]*mFactor[2] + baseV[4][1]*mFactor[3]);
542
                  buffer[offset+2]= ((tmpCache1.a[2]*time+ tmpCache1.b[2])*time+ tmpCache1.c[2])*time+ tmpCache1.d[2] + (baseV[1][2]*mFactor[0] + baseV[2][2]*mFactor[1] + baseV[3][2]*mFactor[2] + baseV[4][2]*mFactor[3]);
543
                  buffer[offset+3]= ((tmpCache1.a[3]*time+ tmpCache1.b[3])*time+ tmpCache1.c[3])*time+ tmpCache1.d[3] + (baseV[1][3]*mFactor[0] + baseV[2][3]*mFactor[1] + baseV[3][3]*mFactor[2] + baseV[4][3]*mFactor[3]);
544
                  buffer[offset+4]= ((tmpCache1.a[4]*time+ tmpCache1.b[4])*time+ tmpCache1.c[4])*time+ tmpCache1.d[4] + (baseV[1][4]*mFactor[0] + baseV[2][4]*mFactor[1] + baseV[3][4]*mFactor[2] + baseV[4][4]*mFactor[3]);
545
                  }
546
                else
547
                  {
548
                  buffer[offset  ]= ((tmpCache1.a[0]*time+ tmpCache1.b[0])*time+ tmpCache1.c[0])*time+ tmpCache1.d[0];
549
                  buffer[offset+1]= ((tmpCache1.a[1]*time+ tmpCache1.b[1])*time+ tmpCache1.c[1])*time+ tmpCache1.d[1];
550
                  buffer[offset+2]= ((tmpCache1.a[2]*time+ tmpCache1.b[2])*time+ tmpCache1.c[2])*time+ tmpCache1.d[2];
551
                  buffer[offset+3]= ((tmpCache1.a[3]*time+ tmpCache1.b[3])*time+ tmpCache1.c[3])*time+ tmpCache1.d[3];
552
                  buffer[offset+4]= ((tmpCache1.a[4]*time+ tmpCache1.b[4])*time+ tmpCache1.c[4])*time+ tmpCache1.d[4];
553
                  }
554
 
555
                break;
556
                }
557
      }
558
    }  
559

    
560
  }
561
///////////////////////////////////////////////////////////////////////////////////////////////////
562
//
(11-11/18)