Project

General

Profile

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

library / src / main / java / org / distorted / library / type / Dynamic5D.java @ 75ec369a

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 vec(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
    tmp1 = 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
        tmp1.tangent[0] = nx+px/q;
69
        tmp1.tangent[1] = ny+py/q;
70
        tmp1.tangent[2] = nz+pz/q;
71
        tmp1.tangent[3] = nw+pw/q;
72
        tmp1.tangent[4] = nv+pv/q;
73
        }
74
      else
75
        {
76
        tmp1.tangent[0] = px+nx*q;
77
        tmp1.tangent[1] = py+ny*q;
78
        tmp1.tangent[2] = pz+nz*q;
79
        tmp1.tangent[3] = pw+nw*q;
80
        tmp1.tangent[4] = pv+nv*q;
81
        }
82
      }
83
    else
84
      {
85
      tmp1.tangent[0] = 0.0f;
86
      tmp1.tangent[1] = 0.0f;
87
      tmp1.tangent[2] = 0.0f;
88
      tmp1.tangent[3] = 0.0f;
89
      tmp1.tangent[4] = 0.0f;
90
      }
91
    }
92
    
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94
  
95
  private void recomputeCache()
96
    {  
97
    if( numPoints==1 )
98
      {
99
      tmp1= vc.elementAt(0);
100
      curr= vv.elementAt(0);
101
        
102
      tmp1.a[0] = tmp1.a[1] = tmp1.a[2] = tmp1.a[3] = tmp1.a[4] = 0.0f;
103
      tmp1.b[0] = tmp1.b[1] = tmp1.b[2] = tmp1.b[3] = tmp1.b[4] = 0.0f;
104
      tmp1.c[0] = curr.x;
105
      tmp1.c[1] = curr.y;
106
      tmp1.c[2] = curr.z;
107
      tmp1.c[3] = curr.w;
108
      tmp1.c[4] = curr.v;
109
      tmp1.d[0] = tmp1.d[1] = tmp1.d[2] = tmp1.d[3] = tmp1.d[4] = 0.0f;
110
      }
111
    else if( numPoints==2 )
112
      {
113
      tmp1= vc.elementAt(0);
114
      tmp2= vc.elementAt(1);
115
      curr= vv.elementAt(0);
116
      next= vv.elementAt(1);
117
      
118
      tmp1.a[0] = tmp1.a[1] = tmp1.a[2] = tmp1.a[3] = tmp1.a[4] = 0.0f;
119
      tmp1.b[0] = tmp1.b[1] = tmp1.b[2] = tmp1.b[3] = tmp1.b[4] = 0.0f;
120
      tmp1.c[0] = next.x - curr.x;
121
      tmp1.c[1] = next.y - curr.y;
122
      tmp1.c[2] = next.z - curr.z;
123
      tmp1.c[3] = next.w - curr.w;
124
      tmp1.c[4] = next.v - curr.v;
125
      tmp1.d[0] = curr.x;
126
      tmp1.d[1] = curr.y;
127
      tmp1.d[2] = curr.z;
128
      tmp1.d[3] = curr.w;
129
      tmp1.d[4] = curr.v;
130
      
131
      tmp2.a[0] = tmp2.a[1] = tmp2.a[2] = tmp2.a[3] = tmp2.a[4] = 0.0f;
132
      tmp2.b[0] = tmp2.b[1] = tmp2.b[2] = tmp2.b[3] = tmp2.b[4] = 0.0f;
133
      tmp2.c[0] = curr.x - next.x;
134
      tmp2.c[1] = curr.y - next.y;
135
      tmp2.c[2] = curr.z - next.z;
136
      tmp2.c[3] = curr.w - next.w;
137
      tmp2.c[4] = curr.v - next.v;
138
      tmp2.d[0] = next.x;
139
      tmp2.d[1] = next.y;
140
      tmp2.d[2] = next.z;
141
      tmp2.d[3] = next.w;
142
      tmp2.d[4] = next.v;
143
      }
144
    else
145
      {
146
      int i, n;  
147
      
148
      for(i=0; i<numPoints; i++) vec(i);
149
   
150
      for(i=0; i<numPoints; i++)
151
        {
152
        n = i<numPoints-1 ? i+1:0;  
153
      
154
        tmp1= vc.elementAt(i);
155
        tmp2= vc.elementAt(n);
156
        curr= vv.elementAt(i);
157
        next= vv.elementAt(n);
158
      
159
        tmp1.cached[0] = curr.x;
160
        tmp1.cached[1] = curr.y;
161
        tmp1.cached[2] = curr.z;
162
        tmp1.cached[3] = curr.w;
163
        tmp1.cached[4] = curr.v;
164
        
165
        tmp1.a[0] =  2*curr.x +   tmp1.tangent[0] - 2*next.x + tmp2.tangent[0];
166
        tmp1.b[0] = -3*curr.x - 2*tmp1.tangent[0] + 3*next.x - tmp2.tangent[0];
167
        tmp1.c[0] = tmp1.tangent[0];
168
        tmp1.d[0] = curr.x;
169
      
170
        tmp1.a[1] =  2*curr.y +   tmp1.tangent[1] - 2*next.y + tmp2.tangent[1];
171
        tmp1.b[1] = -3*curr.y - 2*tmp1.tangent[1] + 3*next.y - tmp2.tangent[1];
172
        tmp1.c[1] = tmp1.tangent[1];
173
        tmp1.d[1] = curr.y;
174
      
175
        tmp1.a[2] =  2*curr.z +   tmp1.tangent[2] - 2*next.z + tmp2.tangent[2];
176
        tmp1.b[2] = -3*curr.z - 2*tmp1.tangent[2] + 3*next.z - tmp2.tangent[2];
177
        tmp1.c[2] = tmp1.tangent[2];
178
        tmp1.d[2] = curr.z;
179
        
180
        tmp1.a[3] =  2*curr.w +   tmp1.tangent[3] - 2*next.w + tmp2.tangent[3];
181
        tmp1.b[3] = -3*curr.w - 2*tmp1.tangent[3] + 3*next.w - tmp2.tangent[3];
182
        tmp1.c[3] = tmp1.tangent[3];
183
        tmp1.d[3] = curr.w;
184
        
185
        tmp1.a[4] =  2*curr.v +   tmp1.tangent[4] - 2*next.v + tmp2.tangent[4];
186
        tmp1.b[4] = -3*curr.v - 2*tmp1.tangent[4] + 3*next.v - tmp2.tangent[4];
187
        tmp1.c[4] = tmp1.tangent[4];
188
        tmp1.d[4] = curr.v;
189
        }
190
      }
191
   
192
    cacheDirty = false;
193
    }
194

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

    
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

    
209
/**
210
 * Default constructor.
211
 *
212
 * @param duration number of milliseconds it takes to do a full loop/path from first vector to the
213
 *                 last and back to the first
214
 * @param count    number of loops/paths we will do; mCount = 1.5 means we go from the first vector
215
 *                 to the last, back to first, and to the last again.
216
 */
217
  public Dynamic5D(int duration, float count)
218
    {
219
    super(duration,count,5);
220
    vv = new Vector<>();
221
    }
222

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

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

    
288
      numPoints++;
289
      cacheDirty = true;
290
      }
291
    }
292

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

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

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

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

    
393
      numPoints--;
394
      cacheDirty = true; 
395
      return true;
396
      }
397

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

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

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

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

    
438
      mNoise = new float[mDimension];
439
      }
440

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

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

    
459
///////////////////////////////////////////////////////////////////////////////////////////////////
460
/**
461
 * Writes the results of interpolation between the Points at time 'time' to the passed float buffer.
462
 * <p>
463
 * Since this is a 5-dimensional Dynamic, the resulting interpolated Static5D gets written
464
 * to five locations in the buffer: buffer[offset],...,buffer[offset+4]. 
465
 * 
466
 * @param buffer Float buffer we will write the resulting Static5D to.
467
 * @param offset Offset in the buffer where to write the result.
468
 * @param time Time of interpolation. Time=0.0 would return the first Point, Time=0.5 - the last,
469
 *             time=1.0 - the first again, and time 0.1 would be 1/5 of the way between the first and the last Points.
470
 */    
471
  synchronized void interpolate(float[] buffer, int offset, float time)
472
    {  
473
    switch(numPoints)
474
      {
475
      case 0: buffer[offset  ] = 0.0f;
476
              buffer[offset+1] = 0.0f;
477
              buffer[offset+2] = 0.0f;
478
              buffer[offset+3] = 0.0f;
479
              buffer[offset+4] = 0.0f;
480
              break;
481
      case 1: curr = vv.elementAt(0);
482
              buffer[offset  ] = curr.x;
483
              buffer[offset+1] = curr.y;
484
              buffer[offset+2] = curr.z;
485
              buffer[offset+3] = curr.w;
486
              buffer[offset+4] = curr.v;
487
              break;
488
      case 2: curr = vv.elementAt(0);
489
              next = vv.elementAt(1);
490

    
491
              int segment2= (int)(2*time);
492

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

    
495
              if( vn!=null )
496
                {
497
                if( segment2 != mSegment )
498
                  {
499
                  if(mMode!=MODE_JUMP || mSegment==1) vn.elementAt(0).computeNoise();
500
                  mSegment = segment2;
501
                  }
502

    
503
                time = noise(time,0);
504

    
505
                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]);
506
                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]);
507
                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]);
508
                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]);
509
                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]);
510
                }
511
              else
512
                {
513
                buffer[offset  ] = (next.x-curr.x)*time + curr.x;
514
                buffer[offset+1] = (next.y-curr.y)*time + curr.y;
515
                buffer[offset+2] = (next.z-curr.z)*time + curr.z;
516
                buffer[offset+3] = (next.w-curr.w)*time + curr.w;
517
                buffer[offset+4] = (next.v-curr.v)*time + curr.v;
518
                }
519
                
520
              break;
521
      default:float t = time;
522
              int vecCurr, segment;
523

    
524
              switch(mMode)
525
                {
526
                case MODE_LOOP: time = time*numPoints;
527
                                segment = (int)time;
528
                                vecCurr = segment;
529
                                break;
530
                case MODE_PATH: segment = (int)(2*t*(numPoints-1));
531

    
532
                                if( t<0.5f )
533
                                  {
534
                                  time = 2*t*(numPoints-1);
535
                                  vecCurr = segment;
536
                                  }
537
                                else
538
                                  {
539
                                  time = 2*(1-t)*(numPoints-1);
540
                                  vecCurr = 2*numPoints-3-segment;
541
                                  }
542
                                break;
543
                case MODE_JUMP: time = time*(numPoints-1);
544
                                segment = (int)time;
545
                                vecCurr = segment;
546
                                break;
547
                default       : vecCurr = 0;
548
                                segment = 0;
549
                }
550

    
551
              if( vecCurr>=0 && vecCurr<numPoints )
552
                {
553
                if( cacheDirty ) recomputeCache();  // recompute cache if we have added or remove vectors since last computation
554
                else if( mSegment!= segment )       // ...or if we have just passed a vector and the vector we are currently flying to has changed
555
                  {
556
                  int vecNext;
557

    
558
                  switch(mMode)
559
                    {
560
                    case MODE_LOOP: vecNext = vecCurr==numPoints-1 ? 0:vecCurr+1;
561
                                    break;
562
                    case MODE_PATH: if( t<0.5f ) vecNext = vecCurr==numPoints-1 ? numPoints-2: vecCurr+1;
563
                                    else         vecNext = vecCurr==0 ? 1 : vecCurr-1;
564
                                    break;
565
                    case MODE_JUMP: vecNext = vecCurr==numPoints-1 ? 1:vecCurr+1;
566
                                    break;
567
                    default       : vecNext = 0;
568
                    }
569

    
570
                  next = vv.elementAt(vecNext);
571
                  tmp2 = vc.elementAt(vecNext);
572

    
573
                  if( tmp2.cached[0]!=next.x || tmp2.cached[1]!=next.y || tmp2.cached[2]!=next.z || tmp2.cached[3]!=next.w || tmp2.cached[4]!=next.v ) recomputeCache();
574
                  }
575

    
576
                if( mSegment!= segment && vn!=null ) vn.elementAt(vecCurr).computeNoise();
577

    
578
                mSegment = segment;
579

    
580
                time = time-vecCurr;
581
            
582
                tmp1 = vc.elementAt(vecCurr);
583
               
584
                if( vn!=null )
585
                  {
586
                  time = noise(time,vecCurr);
587
              
588
                  computeOrthonormalBaseMore(time,tmp1);
589

    
590
                  buffer[offset  ]= ((tmp1.a[0]*time+tmp1.b[0])*time+tmp1.c[0])*time+tmp1.d[0] + (baseV[1][0]*mFactor[0] + baseV[2][0]*mFactor[1] + baseV[3][0]*mFactor[2] + baseV[4][0]*mFactor[3]);
591
                  buffer[offset+1]= ((tmp1.a[1]*time+tmp1.b[1])*time+tmp1.c[1])*time+tmp1.d[1] + (baseV[1][1]*mFactor[0] + baseV[2][1]*mFactor[1] + baseV[3][1]*mFactor[2] + baseV[4][1]*mFactor[3]);
592
                  buffer[offset+2]= ((tmp1.a[2]*time+tmp1.b[2])*time+tmp1.c[2])*time+tmp1.d[2] + (baseV[1][2]*mFactor[0] + baseV[2][2]*mFactor[1] + baseV[3][2]*mFactor[2] + baseV[4][2]*mFactor[3]);
593
                  buffer[offset+3]= ((tmp1.a[3]*time+tmp1.b[3])*time+tmp1.c[3])*time+tmp1.d[3] + (baseV[1][3]*mFactor[0] + baseV[2][3]*mFactor[1] + baseV[3][3]*mFactor[2] + baseV[4][3]*mFactor[3]);
594
                  buffer[offset+4]= ((tmp1.a[4]*time+tmp1.b[4])*time+tmp1.c[4])*time+tmp1.d[4] + (baseV[1][4]*mFactor[0] + baseV[2][4]*mFactor[1] + baseV[3][4]*mFactor[2] + baseV[4][4]*mFactor[3]);
595
                  }
596
                else
597
                  {
598
                  buffer[offset  ]= ((tmp1.a[0]*time+tmp1.b[0])*time+tmp1.c[0])*time+tmp1.d[0];
599
                  buffer[offset+1]= ((tmp1.a[1]*time+tmp1.b[1])*time+tmp1.c[1])*time+tmp1.d[1];
600
                  buffer[offset+2]= ((tmp1.a[2]*time+tmp1.b[2])*time+tmp1.c[2])*time+tmp1.d[2];
601
                  buffer[offset+3]= ((tmp1.a[3]*time+tmp1.b[3])*time+tmp1.c[3])*time+tmp1.d[3];
602
                  buffer[offset+4]= ((tmp1.a[4]*time+tmp1.b[4])*time+tmp1.c[4])*time+tmp1.d[4];
603
                  }
604
 
605
                break;
606
                }
607
      }
608
    }  
609

    
610
  }
611
///////////////////////////////////////////////////////////////////////////////////////////////////
612
//
(11-11/17)