Project

General

Profile

« Previous | Next » 

Revision 649544b8

Added by Leszek Koltunski over 7 years ago

Completely redesign Noise in the Dynamics and move all the complexity to the parent class.

something does not work with it now :)

View differences:

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;

Also available in: Unified diff