Project

General

Profile

« Previous | Next » 

Revision 8be29dfc

Added by Leszek Koltunski over 5 years ago

Improve the Rubik App - beginnings of rotation.

View differences:

src/main/java/org/distorted/examples/rubik/RubikRenderer.java
24 24
import android.graphics.Paint;
25 25
import android.opengl.GLSurfaceView;
26 26

  
27
import org.distorted.library.effect.EffectName;
28 27
import org.distorted.library.effect.MatrixEffectMove;
29 28
import org.distorted.library.effect.MatrixEffectQuaternion;
29
import org.distorted.library.effect.MatrixEffectRotate;
30 30
import org.distorted.library.effect.MatrixEffectScale;
31
import org.distorted.library.effect.PostprocessEffectGlow;
32 31
import org.distorted.library.effect.VertexEffectSink;
33 32
import org.distorted.library.main.Distorted;
34 33
import org.distorted.library.main.DistortedEffects;
35 34
import org.distorted.library.main.DistortedScreen;
36 35
import org.distorted.library.main.DistortedTexture;
37 36
import org.distorted.library.mesh.MeshCubes;
37
import org.distorted.library.type.Dynamic1D;
38 38
import org.distorted.library.type.Static1D;
39 39
import org.distorted.library.type.Static3D;
40 40
import org.distorted.library.type.Static4D;
......
48 48
{
49 49
            static final int NUM_CUBES =   3;
50 50
    private static final int SIZE      = 200;
51

  
52 51
    private static final float CUBE_SCREEN_RATIO = 0.5f;
53 52

  
53
    private static final Static3D VectX = new Static3D(1,0,0);
54
    private static final Static3D VectY = new Static3D(0,1,0);
55
    private static final Static3D VectZ = new Static3D(0,0,1);
56

  
54 57
    private GLSurfaceView mView;
55 58
    private DistortedTexture mTexture;
56 59
    private DistortedScreen mScreen;
57 60
    private Static3D mMove, mScale, mCenter;
58 61
    private MeshCubes[][][] mCubes;
59 62
    private DistortedEffects[][][] mEffects;
63
    private Static4D[][][] mQuatScramble;
64
    private Static3D[][][] mRotationAxis;
65
    private Dynamic1D[][][] mRotationAngle;
66
    private Static1D mRotationAngleStatic;
67
    private int mRotAxis;
68
    private int mRotRow;
60 69

  
61 70
    private int mScreenWidth, mScreenHeight;
62
    private int mLastRow, mLastCol, mLastSli;
63

  
64
    private Static1D mGlowRadius;
65
    private Static4D mGlowColor;
66 71

  
67 72
    private Static4D mQuatCurrent, mQuatAccumulated;
68 73
    private Static4D mTempCurrent, mTempAccumulated;
......
86 91
      mEffects = new DistortedEffects[NUM_CUBES][NUM_CUBES][NUM_CUBES];
87 92
      Static3D[][][] cubeVectors = new Static3D[NUM_CUBES][NUM_CUBES][NUM_CUBES];
88 93

  
94
      mQuatScramble = new Static4D[NUM_CUBES][NUM_CUBES][NUM_CUBES];
95
      mRotationAxis = new Static3D[NUM_CUBES][NUM_CUBES][NUM_CUBES];
96
      mRotationAngle= new Dynamic1D[NUM_CUBES][NUM_CUBES][NUM_CUBES];
97

  
89 98
      float sinkDegree = 3.0f - 1.7f/NUM_CUBES; // f(1)=1.3, f(inf)=3
90 99

  
91 100
      VertexEffectSink sink = new VertexEffectSink( new Static1D(sinkDegree),
......
95 104
      mScale = new Static3D(1,1,1);
96 105
      mCenter= new Static3D(0,0,0);
97 106

  
98
      mLastRow = mLastCol = mLastSli = 0;
99

  
100
      mGlowRadius = new Static1D(5);
101
      mGlowColor  = new Static4D(1.0f,1.0f,1.0f,0.6f);
107
      mRotationAngleStatic = new Static1D(0);
108
      mRotAxis= RubikSurfaceView.VECTN;
102 109

  
103 110
      MatrixEffectMove       move  = new MatrixEffectMove(mMove);
104 111
      MatrixEffectScale      scale = new MatrixEffectScale(mScale);
......
143 150
              tmpBottom= (y==            0 ? mapBottom:mapBlack);
144 151

  
145 152
              mCubes[x][y][z] = new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom);
146

  
147 153
              cubeVectors[x][y][z] = new Static3D( SIZE*(x-nc), SIZE*(y-nc), SIZE*(z-nc) );
154
              mQuatScramble[x][y][z] = new Static4D(0,0,0,1);
155
              mRotationAngle[x][y][z] = new Dynamic1D();
156
              mRotationAxis[x][y][z] = new Static3D(1,0,0);
148 157

  
149 158
              mEffects[x][y][z] = new DistortedEffects();
150 159
              mEffects[x][y][z].apply(sink);
......
152 161
              mEffects[x][y][z].apply(scale);
153 162
              mEffects[x][y][z].apply(quat1);
154 163
              mEffects[x][y][z].apply(quat2);
164
              mEffects[x][y][z].apply( new MatrixEffectRotate( mRotationAngle[x][y][z], mRotationAxis[x][y][z], mCenter));
165
              mEffects[x][y][z].apply( new MatrixEffectQuaternion(mQuatScramble[x][y][z], mCenter));
155 166
              mEffects[x][y][z].apply( new MatrixEffectMove(cubeVectors[x][y][z]) );
156 167
              }
157 168
            }
......
242 253
              mScreen.attach(mTexture,mEffects[x][y][z],mCubes[x][y][z]);
243 254
              }
244 255

  
245
      PostprocessEffectGlow.enable();
246 256
      VertexEffectSink.enable();
247 257

  
248 258
      try
......
283 293

  
284 294
    void addNewRotation(int vector, int row )
285 295
      {
286
      String vect="?";
296
      Static3D axis = VectX;
287 297

  
288 298
      switch(vector)
289 299
        {
290
        case RubikSurfaceView.VECTX: vect="X"; break;
291
        case RubikSurfaceView.VECTY: vect="Y"; break;
292
        case RubikSurfaceView.VECTZ: vect="Z"; break;
300
        case RubikSurfaceView.VECTX: axis = VectX; break;
301
        case RubikSurfaceView.VECTY: axis = VectY; break;
302
        case RubikSurfaceView.VECTZ: axis = VectZ; break;
293 303
        }
294 304

  
295
      android.util.Log.e("rubik", "added new rotation (row="+row+" vector: "+vect+")");
305
      mRotAxis = vector;
306
      mRotRow  = row;
307

  
308
      mRotationAngleStatic.set1(0.0f);
309

  
310
      for(int x = 0; x< NUM_CUBES; x++)
311
        for(int y = 0; y< NUM_CUBES; y++)
312
          for(int z = 0; z< NUM_CUBES; z++)
313
            if( x==0 || x==NUM_CUBES-1 || y==0 || y==NUM_CUBES-1 || z==0 || z==NUM_CUBES-1 )
314
              {
315
              if( belongsToRotation(x,y,z,vector,row) )
316
                {
317
                mRotationAxis[x][y][z].set(axis);
318
                mRotationAngle[x][y][z].add(mRotationAngleStatic);
319
                }
320
              }
296 321
      }
297 322

  
298 323
///////////////////////////////////////////////////////////////////////////////////////////////////
299 324

  
300 325
    void continueRotation(float angle)
301 326
      {
302
      android.util.Log.e("rubik", "rotating by angle: "+ (((float)((int)(angle*100.0f)))/100.0f) );
327
      mRotationAngleStatic.set1(120.0f*angle/mScreenMin);
303 328
      }
304 329

  
305 330
///////////////////////////////////////////////////////////////////////////////////////////////////
306 331

  
307 332
    void finishRotation()
308 333
      {
309
      android.util.Log.e("rubik", "finishing rotation");
310
      }
334
      float nearestAngle = (mRotationAngleStatic.get1()+45.0f)/90.0f;
335
      if( nearestAngle<0 ) nearestAngle-=1.0f;
336
      int nearestAngleInDegrees = 90*(4-((int)nearestAngle+4)%4);
337
      double nearestAngleInRadians = nearestAngleInDegrees*Math.PI/180;
338
      float sinA = (float)Math.sin(nearestAngleInRadians*0.5);
339
      float cosA = (float)Math.cos(nearestAngleInRadians*0.5);
311 340

  
312
///////////////////////////////////////////////////////////////////////////////////////////////////
341
      mRotationAngleStatic.set1(0);
313 342

  
314
    float getScreenWidth()
315
      {
316
      return mScreenWidth;
343
      float qx=0,qy=0,qz=0;
344

  
345
      switch(mRotAxis)
346
        {
347
        case RubikSurfaceView.VECTX: qx=1; break;
348
        case RubikSurfaceView.VECTY: qy=1; break;
349
        case RubikSurfaceView.VECTZ: qz=1; break;
350
        }
351

  
352
      Static4D quat = new Static4D(qx*sinA, qy*sinA, qz*sinA, cosA);
353

  
354
      for(int x = 0; x< NUM_CUBES; x++)
355
        for(int y = 0; y< NUM_CUBES; y++)
356
          for(int z = 0; z< NUM_CUBES; z++)
357
            if( x==0 || x==NUM_CUBES-1 || y==0 || y==NUM_CUBES-1 || z==0 || z==NUM_CUBES-1 )
358
              {
359
              if( belongsToRotation(x,y,z,mRotAxis,mRotRow) )
360
                {
361
                mRotationAngle[x][y][z].removeAll();
362
                mQuatScramble[x][y][z].set(RubikSurfaceView.quatMultiply(quat,mQuatScramble[x][y][z]));
363
                }
364
              }
317 365
      }
318 366

  
319 367
///////////////////////////////////////////////////////////////////////////////////////////////////
320 368

  
321
    float getScreenHeight()
369
    private boolean belongsToRotation(int x, int y, int z, int vector, int row)
322 370
      {
323
      return mScreenHeight;
371
      switch(vector)
372
        {
373
        case RubikSurfaceView.VECTX: return x==row;
374
        case RubikSurfaceView.VECTY: return y==row;
375
        case RubikSurfaceView.VECTZ: return z==row;
376
        }
377

  
378
      return false;
324 379
      }
325 380

  
326 381
///////////////////////////////////////////////////////////////////////////////////////////////////
327 382

  
328
    void abortLastEffect()
383
    float getScreenWidth()
329 384
      {
330
      mEffects[mLastCol][mLastRow][mLastSli].abortByName(EffectName.GLOW);
385
      return mScreenWidth;
331 386
      }
332 387

  
333 388
///////////////////////////////////////////////////////////////////////////////////////////////////
334 389

  
335
    void applyNewEffect(int col, int row, int sli)
390
    float getScreenHeight()
336 391
      {
337
      mLastCol = col;
338
      mLastRow = row;
339
      mLastSli = sli;
340

  
341
      mEffects[mLastCol][mLastRow][mLastSli].apply(new PostprocessEffectGlow(mGlowRadius,mGlowColor));
392
      return mScreenHeight;
342 393
      }
343 394

  
344 395
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/examples/rubik/RubikSurfaceView.java
51 51

  
52 52
    private boolean mDragging, mRotating;
53 53
    private int mX, mY;
54
    private int mTouchedRow, mTouchedCol, mTouchedSli;
55 54
    private Static4D mQuatCurrent, mQuatAccumulated;
56 55
    private int mRotationVect;
57 56
    private RubikRenderer mRenderer;
......
106 105

  
107 106
                                       if( mLastTouchedFace != NONE )
108 107
                                         {
109
                                         mRenderer.abortLastEffect();
110
                                         mRenderer.applyNewEffect(mTouchedCol, mTouchedRow, mTouchedSli);
111 108
                                         mRotating = true;
112 109
                                         }
113 110
                                       else
......
127 124
                                         if( (mX-x)*(mX-x)+(mY-y)*(mY-y)>minimumToRotate )
128 125
                                           {
129 126
                                           addNewRotation(x,y);
127
                                           mX = x;
128
                                           mY = y;
130 129
                                           mRotating = false;
131 130
                                           }
132 131
                                         }
......
207 206
      {
208 207
      fillTouchPoint(x,y);
209 208

  
210
      float angle=0.0f;
209
      int sign=1;
211 210
      float cubeHalfSize= mRenderer.returnCubeSize()*0.5f;
212 211
      float A=retA(mLastTouchedFace,cubeHalfSize);
213 212

  
......
219 218
        {
220 219
        case VECTX: switch(mLastTouchedFace)
221 220
                      {
222
                      case FRONT : angle = returnAngle(-diffZ, diffY); break;
223
                      case BACK  : angle = returnAngle( diffZ,-diffY); break;
224
                      case TOP   : angle = returnAngle(-diffY,-diffZ); break;
225
                      case BOTTOM: angle = returnAngle( diffY, diffZ); break;
221
                      case FRONT : sign = returnSign(-diffY); break;
222
                      case BACK  : sign = returnSign( diffY); break;
223
                      case TOP   : sign = returnSign( diffZ); break;
224
                      case BOTTOM: sign = returnSign(-diffZ); break;
226 225
                      }
227 226
                    break;
228 227
        case VECTY: switch(mLastTouchedFace)
229 228
                      {
230
                      case FRONT : angle = returnAngle(-diffZ, diffX); break;
231
                      case BACK  : angle = returnAngle( diffZ,-diffX); break;
232
                      case LEFT  : angle = returnAngle( diffX, diffZ); break;
233
                      case RIGHT : angle = returnAngle(-diffX,-diffZ); break;
229
                      case FRONT : sign = returnSign( diffX); break;
230
                      case BACK  : sign = returnSign(-diffX); break;
231
                      case LEFT  : sign = returnSign( diffZ); break;
232
                      case RIGHT : sign = returnSign(-diffZ); break;
234 233
                      }
235 234
                    break;
236 235
        case VECTZ: switch(mLastTouchedFace)
237 236
                      {
238
                      case TOP   : angle = returnAngle( diffY, diffX); break;
239
                      case BOTTOM: angle = returnAngle(-diffY,-diffX); break;
240
                      case LEFT  : angle = returnAngle(-diffX, diffY); break;
241
                      case RIGHT : angle = returnAngle( diffX,-diffY); break;
237
                      case TOP   : sign = returnSign(-diffX); break;
238
                      case BOTTOM: sign = returnSign( diffX); break;
239
                      case LEFT  : sign = returnSign(-diffY); break;
240
                      case RIGHT : sign = returnSign( diffY); break;
242 241
                      }
243 242
                    break;
244 243
        default   : android.util.Log.e("View", "impossible vector: "+mRotationVect);
245 244
        }
246 245

  
247
      mRenderer.continueRotation(angle);
246
      float dX = mX-x;
247
      float dY = mY-y;
248
      float calibration = (float)Math.sqrt(dX*dX+dY*dY);
249

  
250
      mRenderer.continueRotation(calibration*sign);
248 251
      }
249 252

  
250 253
///////////////////////////////////////////////////////////////////////////////////////////////////
......
258 261

  
259 262
///////////////////////////////////////////////////////////////////////////////////////////////////
260 263

  
261
    private float returnAngle(float diff1, float diff2)
264
    private int returnSign(float diff)
262 265
      {
263
      float len = (float)Math.sqrt(diff1*diff1 + diff2*diff2);
264
      len /= mRenderer.mScreenMin;
265

  
266
      return diff2>0 ? len : -len;
266
      return diff>0 ? 1 : -1;
267 267
      }
268 268

  
269 269
///////////////////////////////////////////////////////////////////////////////////////////////////
......
277 277
///////////////////////////////////////////////////////////////////////////////////////////////////
278 278
// return quat1*quat2
279 279

  
280
    private Static4D quatMultiply( Static4D quat1, Static4D quat2 )
280
    static Static4D quatMultiply( Static4D quat1, Static4D quat2 )
281 281
      {
282 282
      float qx = quat1.get1();
283 283
      float qy = quat1.get2();
......
403 403
          float qY= (mStartY+cubeHalfSize) / (2*cubeHalfSize);
404 404
          float qZ= (mStartZ+cubeHalfSize) / (2*cubeHalfSize);
405 405

  
406
          if( qX==1.0f ) qX-= 0.5f/RubikRenderer.NUM_CUBES;
407
          if( qY==1.0f ) qY-= 0.5f/RubikRenderer.NUM_CUBES;
408
          if( qZ==1.0f ) qZ-= 0.5f/RubikRenderer.NUM_CUBES;
409

  
410
          if( qX<1 && qX>=0 && qY<1 && qY>=0 && qZ<1 && qZ>=0 )
411
            {
412
            mTouchedCol = (int)(qX*RubikRenderer.NUM_CUBES);
413
            mTouchedRow = (int)(qY*RubikRenderer.NUM_CUBES);
414
            mTouchedSli = (int)(qZ*RubikRenderer.NUM_CUBES);
415
            return face;
416
            }
406
          if( qX<=1 && qX>=0 && qY<=1 && qY>=0 && qZ<=1 && qZ>=0 ) return face;
417 407
          }
418 408
        }
419 409

  
420
      mTouchedRow = -1;
421
      mTouchedCol = -1;
422
      mTouchedSli = -1;
423

  
424 410
      return NONE;
425 411
      }
426 412

  

Also available in: Unified diff