Project

General

Profile

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

library / src / main / java / org / distorted / library / type / Dynamic5D.java @ 43b28f5b

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
    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++) computeVelocity(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] = mConvexity*( 2*curr.x +   tmp1.tangent[0] - 2*next.x + tmp2.tangent[0]);
166
        tmp1.b[0] = mConvexity*(-3*curr.x - 2*tmp1.tangent[0] + 3*next.x - tmp2.tangent[0]);
167
        tmp1.c[0] = mConvexity*(tmp1.tangent[0]) + (1.0f-mConvexity)*(next.x-curr.x);
168
        tmp1.d[0] = curr.x;
169
      
170
        tmp1.a[1] = mConvexity*( 2*curr.y +   tmp1.tangent[1] - 2*next.y + tmp2.tangent[1]);
171
        tmp1.b[1] = mConvexity*(-3*curr.y - 2*tmp1.tangent[1] + 3*next.y - tmp2.tangent[1]);
172
        tmp1.c[1] = mConvexity*(tmp1.tangent[1]) + (1.0f-mConvexity)*(next.y-curr.y);
173
        tmp1.d[1] = curr.y;
174
      
175
        tmp1.a[2] = mConvexity*( 2*curr.z +   tmp1.tangent[2] - 2*next.z + tmp2.tangent[2]);
176
        tmp1.b[2] = mConvexity*(-3*curr.z - 2*tmp1.tangent[2] + 3*next.z - tmp2.tangent[2]);
177
        tmp1.c[2] = mConvexity*(tmp1.tangent[2]) + (1.0f-mConvexity)*(next.z-curr.z);
178
        tmp1.d[2] = curr.z;
179
        
180
        tmp1.a[3] = mConvexity*( 2*curr.w +   tmp1.tangent[3] - 2*next.w + tmp2.tangent[3]);
181
        tmp1.b[3] = mConvexity*(-3*curr.w - 2*tmp1.tangent[3] + 3*next.w - tmp2.tangent[3]);
182
        tmp1.c[3] = mConvexity*(tmp1.tangent[3]) + (1.0f-mConvexity)*(next.w-curr.w);
183
        tmp1.d[3] = curr.w;
184
        
185
        tmp1.a[4] = mConvexity*( 2*curr.v +   tmp1.tangent[4] - 2*next.v + tmp2.tangent[4]);
186
        tmp1.b[4] = mConvexity*(-3*curr.v - 2*tmp1.tangent[4] + 3*next.v - tmp2.tangent[4]);
187
        tmp1.c[4] = mConvexity*(tmp1.tangent[4]) + (1.0f-mConvexity)*(next.v-curr.v);
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
 * Constructor setting the speed of interpolation and the number of revolutions.
210
 *
211
 * What constitutes 'one revolution' depends on the MODE:
212
 * {@link Dynamic#MODE_LOOP}, {@link Dynamic#MODE_PATH} or {@link Dynamic#MODE_JUMP}.
213
 *
214
 * @param duration number of milliseconds it takes to do one revolution.
215
 * @param count    number of revolutions we will do. Count<=0 means 'infinite'.
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
  synchronized void interpolate(float[] buffer, int offset, float time)
462
    {  
463
    switch(numPoints)
464
      {
465
      case 0: buffer[offset  ] = 0.0f;
466
              buffer[offset+1] = 0.0f;
467
              buffer[offset+2] = 0.0f;
468
              buffer[offset+3] = 0.0f;
469
              buffer[offset+4] = 0.0f;
470
              break;
471
      case 1: curr = vv.elementAt(0);
472
              buffer[offset  ] = curr.x;
473
              buffer[offset+1] = curr.y;
474
              buffer[offset+2] = curr.z;
475
              buffer[offset+3] = curr.w;
476
              buffer[offset+4] = curr.v;
477
              break;
478
      case 2: curr = vv.elementAt(0);
479
              next = vv.elementAt(1);
480

    
481
              int segment2= (int)(2*time);
482

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

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

    
493
                time = noise(time,0);
494

    
495
                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]);
496
                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]);
497
                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]);
498
                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]);
499
                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]);
500
                }
501
              else
502
                {
503
                buffer[offset  ] = (next.x-curr.x)*time + curr.x;
504
                buffer[offset+1] = (next.y-curr.y)*time + curr.y;
505
                buffer[offset+2] = (next.z-curr.z)*time + curr.z;
506
                buffer[offset+3] = (next.w-curr.w)*time + curr.w;
507
                buffer[offset+4] = (next.v-curr.v)*time + curr.v;
508
                }
509
                
510
              break;
511
      default:float t = time;
512
              int vecCurr, segment;
513

    
514
              switch(mMode)
515
                {
516
                case MODE_LOOP: time = time*numPoints;
517
                                segment = (int)time;
518
                                vecCurr = segment;
519
                                break;
520
                case MODE_PATH: segment = (int)(2*t*(numPoints-1));
521

    
522
                                if( t<=0.5f )  // this has to be <= (otherwise when effect ends at t=0.5, then time=1.0
523
                                  {            // and end position is slightly not equal to the end point => might not get autodeleted!
524
                                  time = 2*t*(numPoints-1);
525
                                  vecCurr = segment;
526
                                  }
527
                                else
528
                                  {
529
                                  time = 2*(1-t)*(numPoints-1);
530
                                  vecCurr = 2*numPoints-3-segment;
531
                                  }
532
                                break;
533
                case MODE_JUMP: time = time*(numPoints-1);
534
                                segment = (int)time;
535
                                vecCurr = segment;
536
                                break;
537
                default       : vecCurr = 0;
538
                                segment = 0;
539
                }
540

    
541
              if( vecCurr>=0 && vecCurr<numPoints )
542
                {
543
                if( cacheDirty ) recomputeCache();  // recompute cache if we have added or remove vectors since last computation
544
                else if( mSegment!= segment )       // ...or if we have just passed a vector and the vector we are currently flying to has changed
545
                  {
546
                  int vecNext= getNext(vecCurr,t);
547
                  next = vv.elementAt(vecNext);
548
                  tmp2 = vc.elementAt(vecNext);
549

    
550
                  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();
551
                  }
552

    
553
                if( mSegment!= segment && vn!=null ) vn.elementAt(vecCurr).computeNoise();
554

    
555
                mSegment = segment;
556

    
557
                time = time-vecCurr;
558
            
559
                tmp1 = vc.elementAt(vecCurr);
560
               
561
                if( vn!=null )
562
                  {
563
                  time = noise(time,vecCurr);
564
              
565
                  computeOrthonormalBaseMore(time,tmp1);
566

    
567
                  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]);
568
                  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]);
569
                  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]);
570
                  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]);
571
                  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]);
572
                  }
573
                else
574
                  {
575
                  buffer[offset  ]= ((tmp1.a[0]*time+tmp1.b[0])*time+tmp1.c[0])*time+tmp1.d[0];
576
                  buffer[offset+1]= ((tmp1.a[1]*time+tmp1.b[1])*time+tmp1.c[1])*time+tmp1.d[1];
577
                  buffer[offset+2]= ((tmp1.a[2]*time+tmp1.b[2])*time+tmp1.c[2])*time+tmp1.d[2];
578
                  buffer[offset+3]= ((tmp1.a[3]*time+tmp1.b[3])*time+tmp1.c[3])*time+tmp1.d[3];
579
                  buffer[offset+4]= ((tmp1.a[4]*time+tmp1.b[4])*time+tmp1.c[4])*time+tmp1.d[4];
580
                  }
581
 
582
                break;
583
                }
584
      }
585
    }  
586

    
587
  }
588
///////////////////////////////////////////////////////////////////////////////////////////////////
589
//
(11-11/18)