Project

General

Profile

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

examples / src / main / java / org / distorted / examples / dynamic / DynamicSurfaceView.java @ 87006e8d

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.examples.dynamic;
21

    
22
import android.app.ActivityManager;
23
import android.content.Context;
24
import android.content.pm.ConfigurationInfo;
25
import android.graphics.Rect;
26
import android.opengl.GLSurfaceView;
27
import android.view.MotionEvent;
28
import android.util.AttributeSet;
29
import android.graphics.Canvas;
30
import android.graphics.Paint.Style;
31
import android.graphics.Paint;
32

    
33
import org.distorted.library.type.Dynamic;
34
import org.distorted.library.type.Dynamic1D;
35
import org.distorted.library.type.Dynamic2D;
36
import org.distorted.library.type.Dynamic3D;
37
import org.distorted.library.type.Static1D;
38
import org.distorted.library.type.Static2D;
39
import org.distorted.library.type.Static3D;
40

    
41
import java.lang.ref.WeakReference;
42

    
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44

    
45
public class DynamicSurfaceView extends GLSurfaceView
46
    {
47
    public static final int DIM_1D   = 0; 
48
    public static final int DIM_2D   = 1; 
49
    public static final int DIM_3DXY = 2; 
50
    public static final int DIM_3DXZ = 3; 
51

    
52
    static final int NUM_POINTS = 250;
53
    private static final Object lock = new Object();
54

    
55
    private WeakReference<DynamicActivity> mAct;
56

    
57
    private static int halfScreenHeight=0;
58
    private static int halfScreenWidth =0;
59

    
60
    private Dynamic1D di1D;
61
    private Dynamic2D di2D;
62
    private Dynamic3D di3D;
63
    
64
    private Paint mPaint;
65
    private int mMoving;
66
    private int mDuration;
67
    private int mPosition;
68
    private long mDiffTime, mLastTime, mStartTime;
69
    private float mNoise0, mNoise1, mNoise2;
70
    private float mCount;
71

    
72
    private int mSize1, mSize2, mSizeT, mAvg;
73
    private float mFontHeight;
74

    
75
    private int currentDim= DIM_2D;
76
    
77
    private Static1D p1D;
78
    private Static2D p2D;
79
    private Static3D p3D;
80

    
81
    private Static1D p1N;
82
    private Static2D p2N;
83
    private Static3D p3N;
84

    
85
    private float[] mPoints = new float[3*NUM_POINTS];
86
    private boolean mRunning;
87

    
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89
    
90
    public DynamicSurfaceView(Context context, AttributeSet attrs)
91
      {
92
      super(context, attrs);
93

    
94
      DynamicActivity act = (DynamicActivity)context;
95
      mAct = new WeakReference<>(act);
96

    
97
      mPaint = new Paint();
98
      mPaint.setStyle(Style.FILL);
99
      mPaint.setAntiAlias(true);
100

    
101
      mMoving = -1;
102
      mDuration = 10000;
103
      mCount    = 0.0f;
104
      mPosition = 0;
105
      mNoise0   = 0.0f;
106
      mNoise1   = 0.0f;
107
      mNoise2   = 0.0f;
108
      mDiffTime = -1;
109
      mLastTime = -1;
110
      mStartTime= -1;
111

    
112
      mRunning = false;
113

    
114
      clearPoints();
115

    
116
      di1D = new Dynamic1D(mDuration,mCount);
117
      p1N  = new Static1D(mNoise0);
118
      di2D = new Dynamic2D(mDuration,mCount);
119
      p2N  = new Static2D(mNoise0,mNoise1);
120
      di3D = new Dynamic3D(mDuration,mCount);
121
      p3N  = new Static3D(mNoise0,mNoise1,mNoise2);
122

    
123
      di1D.setAccessType(Dynamic.ACCESS_TYPE_SEQUENTIAL);
124
      di2D.setAccessType(Dynamic.ACCESS_TYPE_SEQUENTIAL);
125
      di3D.setAccessType(Dynamic.ACCESS_TYPE_SEQUENTIAL);
126

    
127
      if(!isInEditMode())
128
        {
129
        setFocusable(true);
130
        setFocusableInTouchMode(true);
131
        DynamicRenderer mRenderer = new DynamicRenderer(this);
132
        final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
133
        final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
134
        setEGLContextClientVersion( (configurationInfo.reqGlEsVersion>>16) >= 3 ? 3:2 );
135
        setRenderer(mRenderer);
136
        }
137
      }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
    public void onSurfaceChanged(int width,int height)
142
      {
143
      mAvg = (width+height)/2;
144

    
145
      mSize1 = mAvg/150;
146
      mSize2 = mAvg/50;
147
      mSizeT = mAvg/30;
148

    
149
      mPaint.setTextSize(mSizeT);
150
      mPaint.setTextAlign(Paint.Align.CENTER);
151

    
152
      final Rect textBounds = new Rect();
153
      String text = "1";
154
      mPaint.getTextBounds(text, 0, text.length(), textBounds);
155
      mFontHeight = textBounds.exactCenterY();
156

    
157
      clearPoints();
158
      }
159

    
160
///////////////////////////////////////////////////////////////////////////////////////////////////
161

    
162
    public static void setHalfWidth(int hw)
163
      {
164
      halfScreenWidth = hw;
165
      }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
    public static void setHalfHeight(int hh)
170
      {
171
      halfScreenHeight = hh;
172
      }
173

    
174
///////////////////////////////////////////////////////////////////////////////////////////////////
175

    
176
    public void setMode(int mode)
177
      {
178
      di1D.setMode(mode);  
179
      di2D.setMode(mode);
180
      di3D.setMode(mode);
181
      }
182

    
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

    
185
    public void setDuration(int duration)
186
      {
187
      mDuration = duration;
188
      
189
      di1D.setDuration(duration);
190
      di2D.setDuration(duration);
191
      di3D.setDuration(duration);
192
      }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
    public void setCount(float count)
197
      {
198
      mCount = count;
199

    
200
      di1D.setCount(count);
201
      di2D.setCount(count);
202
      di3D.setCount(count);
203
      }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

    
207
    public void setNoise(float noise0, float noise1, float noise2)
208
      {
209
      mNoise0 = noise0;
210
      mNoise1 = noise1;
211
      mNoise2 = noise2;
212

    
213
      p1N.set(mNoise0);
214
      p2N.set(mNoise0,mNoise1);
215
      p3N.set(mNoise0,mNoise1,mNoise2);
216

    
217
      di1D.setNoise(p1N);
218
      di2D.setNoise(p2N);
219
      di3D.setNoise(p3N);
220
      }
221
    
222
///////////////////////////////////////////////////////////////////////////////////////////////////
223

    
224
    public void setDimension(int dim)
225
      {
226
      if( currentDim != dim )
227
        {
228
        if( !(currentDim==DIM_3DXY && dim==DIM_3DXZ) && !(currentDim==DIM_3DXZ && dim==DIM_3DXY) )
229
          {
230
          resetPoints();
231
          }
232

    
233
        currentDim = dim;
234
        }
235
      }
236
    
237
///////////////////////////////////////////////////////////////////////////////////////////////////
238
    
239
    public void drawCurve(Canvas c, long time)
240
      {
241
      if( mLastTime<0 )
242
        {
243
        mLastTime = time;
244
        }
245
      else
246
        {
247
        mDiffTime = time - mLastTime;
248
        }
249

    
250
      synchronized(lock)
251
        {
252
        switch(currentDim)
253
          {
254
          case DIM_1D: drawHorizontalAxis(c,"x");
255
                       drawPath(c,di1D,1,time);
256
                       drawRedPoints1D(c);
257
                       break;
258
          case DIM_2D: drawHorizontalAxis(c,"x");
259
                       drawVerticalAxis  (c,"y");
260
                       drawPath(c,di2D,1,time);
261
                       drawRedPoints2D(c);
262
                       break;
263
          default    : drawHorizontalAxis(c,"x");
264
                       drawVerticalAxis  (c, currentDim==DIM_3DXY ? "y" : "z" );
265
                       drawPath(c,di3D,(currentDim==DIM_3DXY ? 1:2),time);
266
                       drawRedPoints3D(c);
267
                       break;
268
          }
269
        }
270

    
271
      mLastTime = time;
272
      }
273

    
274
///////////////////////////////////////////////////////////////////////////////////////////////////
275

    
276
    private void clearPoints()
277
      {
278
      for(int i=0; i<3*NUM_POINTS; i++)
279
         {
280
         mPoints[i] = -100000.0f;
281
         }
282
      }
283

    
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285

    
286
    public void resetPoints()
287
      {
288
      synchronized(lock)
289
        {
290
        clearPoints();
291

    
292
        switch(currentDim)
293
          {
294
          case DIM_1D  : di1D.removeAll(); break;
295
          case DIM_2D  : di2D.removeAll(); break;
296
          case DIM_3DXY:
297
          case DIM_3DXZ: di3D.removeAll(); break;
298
          }
299

    
300
        DynamicActivity act = mAct.get();
301
        act.setNumRedPoints(0);
302
        act.clearPoints();
303
        }
304
      }
305

    
306
///////////////////////////////////////////////////////////////////////////////////////////////////
307

    
308
    public void startDynamic()
309
      {
310
      mRunning = true;
311
      mLastTime= -1;
312
      mStartTime = System.currentTimeMillis();
313

    
314
      clearPoints();
315
      di1D.resetToBeginning();
316
      di2D.resetToBeginning();
317
      di3D.resetToBeginning();
318
      }
319

    
320
///////////////////////////////////////////////////////////////////////////////////////////////////
321

    
322
    public void stopDynamic()
323
      {
324
      mRunning = false;
325
      }
326

    
327
///////////////////////////////////////////////////////////////////////////////////////////////////
328

    
329
    private void drawHorizontalAxis(Canvas c, String label)
330
      {
331
      mPaint.setColor(0xff000000);
332

    
333
      c.drawLine(0, halfScreenHeight, halfScreenWidth*2, halfScreenHeight, mPaint);
334
      c.drawText( label, 0.95f*halfScreenWidth*2, halfScreenHeight + mSizeT , mPaint);
335
      }
336

    
337

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

    
340
    private void drawVerticalAxis(Canvas c, String label)
341
      {
342
      mPaint.setColor(0xff000000);
343

    
344
      c.drawLine(halfScreenWidth, 0, halfScreenWidth, halfScreenHeight*2, mPaint);
345
      c.drawText(label, halfScreenWidth + mSizeT,                mSizeT , mPaint);
346
      }
347

    
348
///////////////////////////////////////////////////////////////////////////////////////////////////
349

    
350
    private void drawPath(Canvas c, Dynamic dyn, int index, long time)
351
      {
352
      int len = dyn.getNumPoints();
353

    
354
      if( len>=2 )
355
        {
356
        if( mRunning )
357
          {
358
          if ( ++mPosition >= NUM_POINTS ) mPosition=0;
359

    
360
          if( dyn.getDimension()==1 )
361
            {
362
            mPoints[3*mPosition+index] = halfScreenHeight;
363
            }
364

    
365
          if( dyn.get(mPoints,3*mPosition, time-mStartTime, mDiffTime) )
366
            {
367
            stopDynamic();
368
            }
369

    
370
          addNewSpeedPoint(time);
371
          }
372

    
373
        for(int i=0; i<NUM_POINTS; i++)
374
          {
375
          int color = i<=mPosition ? 0xff - (mPosition           -i)*0xff/(NUM_POINTS-1)
376
                                   : 0xff - (mPosition+NUM_POINTS-i)*0xff/(NUM_POINTS-1);
377

    
378
          mPaint.setColor( 0xffffff + ((color&0xff)<<24) );
379
          c.drawCircle(mPoints[3*i], mPoints[3*i+index] , mSize1, mPaint );
380
          }
381
        }
382
      }
383

    
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385

    
386
    private void drawRedPoints1D(Canvas c)
387
      {
388
      int len = di1D.getNumPoints();
389

    
390
      for(int curr=0; curr<len; curr++)
391
        {
392
        p1D = di1D.getPoint(curr);
393
        drawRedPoint(c,curr+"", p1D.get1(), halfScreenHeight);
394
        }
395
      }
396

    
397
///////////////////////////////////////////////////////////////////////////////////////////////////
398

    
399
    private void drawRedPoints2D(Canvas c)
400
      {
401
      int len = di2D.getNumPoints();
402

    
403
      for(int curr=0; curr<len; curr++)
404
        {
405
        p2D = di2D.getPoint(curr);
406
        drawRedPoint(c,curr+"", p2D.get1(), p2D.get2());
407
        }
408
      }
409

    
410
///////////////////////////////////////////////////////////////////////////////////////////////////
411

    
412
    private void drawRedPoints3D(Canvas c)
413
      {
414
      int len = di3D.getNumPoints();
415

    
416
      for(int curr=0; curr<len; curr++)
417
        {
418
        p3D = di3D.getPoint(curr);
419
        drawRedPoint(c,curr+"", p3D.get1(), currentDim==DIM_3DXY ? p3D.get2():p3D.get3());
420
        }
421
      }
422

    
423
///////////////////////////////////////////////////////////////////////////////////////////////////
424

    
425
    private void drawRedPoint(Canvas c, String label, float width, float height)
426
      {
427
      mPaint.setColor(0xffff0000);
428
      c.drawCircle( width, height, mSize2, mPaint);
429
      mPaint.setColor(0xffffffff);
430
      c.drawText(label, width,height-mFontHeight, mPaint);
431
      }
432

    
433
///////////////////////////////////////////////////////////////////////////////////////////////////
434

    
435
    private void addNewPoint(int x, int y)
436
      {
437
      float gx,gy,gz;
438
      int len;
439
      
440
      switch(currentDim)
441
        {
442
        case DIM_1D: len = di1D.getNumPoints();
443
                
444
                     for(int g=0; g<len; g++)
445
                       {
446
                       p1D = di1D.getPoint(g);  
447
                       gx = p1D.get1();
448
                                    
449
                       if( (x-gx)*(x-gx) < (mAvg*mAvg/100) )
450
                         {
451
                         mMoving = g;
452
                         break;
453
                         }
454
                       }
455
                     if( mMoving <0 )
456
                       {
457
                       synchronized(lock)
458
                         {
459
                         di1D.add(new Static1D(x));
460
                         mAct.get().setNumRedPoints(len+1);
461
                         }
462
                       }
463
                     break;
464
        case DIM_2D: len = di2D.getNumPoints();
465
                                 
466
                     for(int g=0; g<len; g++)
467
                       {
468
                       p2D = di2D.getPoint(g);  
469
                       gx = p2D.get1();
470
                       gy = p2D.get2();
471
                                    
472
                       if( (x-gx)*(x-gx) + (y-gy)*(y-gy) < (mAvg*mAvg/100) )
473
                         {
474
                         mMoving = g;
475
                         break;
476
                         }
477
                       }
478
                     if( mMoving <0 )
479
                       {
480
                       synchronized(lock)
481
                         {
482
                         di2D.add(new Static2D(x,y));
483
                         mAct.get().setNumRedPoints(len+1);
484
                         }
485
                       }
486
                     break;
487
        default    : len = di3D.getNumPoints();
488
                                 
489
                     for(int g=0; g<len; g++)
490
                       {
491
                       p3D = di3D.getPoint(g);  
492
                       gx = p3D.get1();
493
                       gy = p3D.get2();
494
                       gz = p3D.get3();
495
                               
496
                     if( currentDim==DIM_3DXY )
497
                       {
498
                       if( (x-gx)*(x-gx) + (y-gy)*(y-gy) < (mAvg*mAvg/100) )
499
                         {
500
                         mMoving = g;
501
                         break;
502
                         }
503
                       }
504
                     if( currentDim==DIM_3DXZ )
505
                       {
506
                       if( (x-gx)*(x-gx) + (y-gz)*(y-gz) < (mAvg*mAvg/100) )
507
                         {
508
                         mMoving = g;
509
                         break;
510
                         }
511
                       }
512
                     }
513
                   if( mMoving <0 )
514
                     { 
515
                     synchronized(lock)
516
                       {
517
                       if( currentDim==DIM_3DXY ) di3D.add(new Static3D(x,y, halfScreenHeight));
518
                       if( currentDim==DIM_3DXZ ) di3D.add(new Static3D(x, halfScreenHeight,y));
519
                       mAct.get().setNumRedPoints(len+1);
520
                       }
521
                     }
522
                   break; 
523
        }
524
      }
525
    
526
///////////////////////////////////////////////////////////////////////////////////////////////////
527

    
528
    private void addNewSpeedPoint(long time)
529
      {
530
      int prev = mPosition-1;
531
      if( prev<0 ) prev = NUM_POINTS-1;
532

    
533
      float xdiff = mPoints[3*prev  ]-mPoints[3*mPosition  ];
534
      float ydiff = mPoints[3*prev+1]-mPoints[3*mPosition+1];
535
      float zdiff = mPoints[3*prev+2]-mPoints[3*mPosition+2];
536

    
537
      float dist = (float)Math.sqrt( xdiff*xdiff + ydiff*ydiff + zdiff*zdiff );
538
      float speed= mDiffTime<=0 ? 0: dist / mDiffTime;
539
      float timepoint = ((float)(time-mStartTime))/mDuration;
540

    
541
      if( dist<1000.0f )   // otherwise this is a very first call; do not send it!
542
        {
543
        mAct.get().addPoint( timepoint - (int)timepoint, speed );
544
        }
545
      }
546

    
547
///////////////////////////////////////////////////////////////////////////////////////////////////
548

    
549
    @Override
550
    public boolean onTouchEvent(MotionEvent event)
551
      {
552
      int action = event.getAction();
553
      int xDown, yDown;
554

    
555
      switch(action)
556
        {
557
        case MotionEvent.ACTION_DOWN: xDown = (int)event.getX();
558
                                      yDown = (int)event.getY();
559
                                      
560
                                      addNewPoint(xDown,yDown);
561
                                    
562
                                      break;
563
        case MotionEvent.ACTION_MOVE: if( mMoving >=0 )
564
                                        {
565
                                        xDown = (int)event.getX();
566
                                        yDown = (int)event.getY();
567
                                        
568
                                        switch(currentDim)
569
                                          {
570
                                          case DIM_1D  : di1D.setPoint(mMoving, xDown);
571
                                                         break;
572
                                          case DIM_2D  : di2D.setPoint(mMoving, xDown, yDown);
573
                                                         break;
574
                                          case DIM_3DXY: di3D.setPoint(mMoving, xDown, yDown, (int)di3D.getPoint(mMoving).get3());
575
                                                         break;
576
                                          case DIM_3DXZ: di3D.setPoint(mMoving, xDown, (int)di3D.getPoint(mMoving).get2(), yDown);
577
                                                         break;
578
                                          }
579
                                        }                           
580
                                      break;
581
        case MotionEvent.ACTION_UP  : mMoving = -1;
582
                                      break;
583
        }
584
            
585
      return true;
586
      }
587
  }
(4-4/4)