Project

General

Profile

« Previous | Next » 

Revision 775e675d

Added by Leszek Koltunski almost 5 years ago

Further simplifications for object movement - remove from it a reference to the Object altogether.

View differences:

src/main/java/org/distorted/magic/RubikRenderer.java
30 30
import org.distorted.library.mesh.MeshFlat;
31 31
import org.distorted.library.message.EffectListener;
32 32
import org.distorted.object.RubikCube;
33
import org.distorted.object.RubikCubeMovement;
34 33

  
35 34
import javax.microedition.khronos.egl.EGLConfig;
36 35
import javax.microedition.khronos.opengles.GL10;
......
112 111
       mNewCube.recomputeScaleFactor(mScreenWidth, mScreenHeight);
113 112
       }
114 113

  
115
     RubikCubeMovement movement = new RubikCubeMovement(mNewCube);
116
     mView.setMovement(movement);
117

  
118 114
     mIsSolved = true;
119 115
     }
120 116

  
src/main/java/org/distorted/magic/RubikSurfaceView.java
34 34
import android.widget.ImageButton;
35 35
import android.widget.LinearLayout;
36 36

  
37
import org.distorted.library.type.Static2D;
37 38
import org.distorted.library.type.Static4D;
39
import org.distorted.object.RubikCube;
38 40
import org.distorted.object.RubikCubeMovement;
39 41

  
40 42
///////////////////////////////////////////////////////////////////////////////////////////////////
41 43

  
42 44
public class RubikSurfaceView extends GLSurfaceView
43 45
{
46
    // Moving the finger from the middle of the vertical screen to the right edge will rotate a
47
    // given face by SWIPING_SENSITIVITY/2 degrees.
48
    private final static int SWIPING_SENSITIVITY  = 240;
49

  
44 50
    // Moving the finger by 1/12 the distance of min(scrWidth,scrHeight) will start a Rotation.
45 51
    private final static int ROTATION_SENSITIVITY =  12;
46 52

  
......
307 313
        axisY /= axisL;
308 314
        axisZ /= axisL;
309 315

  
310
        float ratio = axisL/mScreenMin;
316
        float ratio = axisL;
311 317
        ratio = ratio - (int)ratio;     // the cos() is only valid in (0,Pi)
312 318

  
313 319
        float cosA = (float)Math.cos(Math.PI*ratio);
......
319 325
      return new Static4D(0f, 0f, 0f, 1f);
320 326
      }
321 327

  
322
///////////////////////////////////////////////////////////////////////////////////////////////////
323

  
324
    void setMovement(RubikCubeMovement movement)
325
      {
326
      mMovement = movement;
327
      }
328

  
329 328
///////////////////////////////////////////////////////////////////////////////////////////////////
330 329
// PUBLIC API
331 330
///////////////////////////////////////////////////////////////////////////////////////////////////
......
338 337
        {
339 338
        mInScrambleMode = false;
340 339
        mRenderer = new RubikRenderer(this);
340
        mMovement = new RubikCubeMovement();
341 341

  
342 342
        final ActivityManager activityManager     = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
343 343
        final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
......
352 352
    public boolean onTouchEvent(MotionEvent event)
353 353
      {
354 354
      int action = event.getAction();
355
      float x = event.getX() - mScreenWidth*0.5f;
356
      float y = mScreenHeight*0.5f -event.getY();
355
      float x = (event.getX() - mScreenWidth*0.5f)/mScreenMin;
356
      float y = (mScreenHeight*0.5f -event.getY())/mScreenMin;
357 357

  
358 358
      switch(action)
359 359
         {
360 360
         case MotionEvent.ACTION_DOWN: mX = x;
361 361
                                       mY = y;
362
                                       mLastTouchedFace = mMovement.faceTouched(mQuatAccumulated,mCameraDistance, x, y);
362
                                       mLastTouchedFace = mMovement.faceTouched(mQuatAccumulated,mCameraDistance/mScreenMin, x, y);
363 363

  
364 364
                                       if( mLastTouchedFace != RubikCubeMovement.NONE )
365 365
                                         {
......
379 379
                                         mTempCurrent.set(quatFromDrag(mX-x,y-mY));
380 380
                                         mRenderer.setQuatCurrentOnNextRender();
381 381

  
382
                                         int minimumDist = (mScreenMin*mScreenMin)/(DIRECTION_SENSITIVITY*DIRECTION_SENSITIVITY);
383

  
384
                                         if( (mX-x)*(mX-x) + (mY-y)*(mY-y) > minimumDist )
382
                                         if( (mX-x)*(mX-x) + (mY-y)*(mY-y) > 1.0f/(DIRECTION_SENSITIVITY*DIRECTION_SENSITIVITY) )
385 383
                                           {
386 384
                                           mX = x;
387 385
                                           mY = y;
......
393 391
                                         }
394 392
                                       if( mBeginningRotation )
395 393
                                         {
396
                                         int minimumDistToStartRotating = (mScreenMin*mScreenMin)/(ROTATION_SENSITIVITY*ROTATION_SENSITIVITY);
397

  
398
                                         if( (mX-x)*(mX-x)+(mY-y)*(mY-y) > minimumDistToStartRotating )
394
                                         if( (mX-x)*(mX-x)+(mY-y)*(mY-y) > 1.0f/(ROTATION_SENSITIVITY*ROTATION_SENSITIVITY) )
399 395
                                           {
400
                                           mMovement.addNewRotation(mQuatAccumulated,mLastTouchedFace, x, y);
396
                                           Static2D rot = mMovement.newRotation(mQuatAccumulated,mLastTouchedFace, x, y);
397
                                           RubikCube cube = mRenderer.getCube();
398

  
399
                                           cube.addNewRotation( (int)rot.get1(), (int)(cube.getSize()*rot.get2()) );
400

  
401 401
                                           mBeginningRotation = false;
402 402
                                           mContinuingRotation= true;
403 403
                                           }
404 404
                                         }
405 405
                                       else if( mContinuingRotation )
406 406
                                         {
407
                                         mMovement.continueRotation(mQuatAccumulated,mLastTouchedFace, x, y, mScreenMin);
407
                                         float angle = mMovement.continueRotation(mQuatAccumulated,mLastTouchedFace, x, y);
408

  
409
                                         mRenderer.getCube().continueRotation(SWIPING_SENSITIVITY*angle);
408 410
                                         }
409 411
                                       break;
410 412
         case MotionEvent.ACTION_UP  : if( mDragging )
src/main/java/org/distorted/object/RubikCube.java
45 45

  
46 46
public class RubikCube extends DistortedNode
47 47
{
48
    private static final float CUBE_SCREEN_RATIO = 0.5f;
48
            static final float CUBE_SCREEN_RATIO = 0.5f;
49 49
    private static final int POST_ROTATION_MILLISEC = 500;
50 50
    private static final int TEXTURE_SIZE = 100;
51 51

  
......
74 74
    private int mSize;
75 75

  
76 76
    private DistortedTexture mNodeTexture;
77
    private float mCubeSizeInScreenSpace;
78 77

  
79 78
///////////////////////////////////////////////////////////////////////////////////////////////////
80 79

  
......
212 211
      mCurrentPosition[x][y][z].set3(roundedZ);
213 212
      }
214 213

  
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216

  
217
    void addNewRotation(int vector, int row )
218
      {
219
      Static3D axis = VectX;
220

  
221
      switch(vector)
222
        {
223
        case VECTX: axis = VectX; break;
224
        case VECTY: axis = VectY; break;
225
        case VECTZ: axis = VectZ; break;
226
        }
227

  
228
      mRotAxis = vector;
229
      mRotRow  = row;
230

  
231
      mRotationAngleStatic.set1(0.0f);
232

  
233
      for(int x=0; x<mSize; x++)
234
        for(int y=0; y<mSize; y++)
235
          for(int z=0; z<mSize; z++)
236
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
237
              {
238
              if( belongsToRotation(x,y,z,vector,mRotRow) )
239
                {
240
                mRotationAxis[x][y][z].set(axis);
241
                mRotationAngle[x][y][z].add(mRotationAngleStatic);
242
                }
243
              }
244
      }
245

  
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247

  
248
    void continueRotation(float angleInDegrees)
249
      {
250
      mRotationAngleStatic.set1(angleInDegrees);
251
      }
252

  
253
///////////////////////////////////////////////////////////////////////////////////////////////////
254

  
255
    float returnCubeSizeInScreenSpace()
256
      {
257
      return mCubeSizeInScreenSpace;
258
      }
259

  
260 214
///////////////////////////////////////////////////////////////////////////////////////////////////
261 215
// PUBLIC API
262 216
///////////////////////////////////////////////////////////////////////////////////////////////////
......
372 326
            }
373 327
      }
374 328

  
329
///////////////////////////////////////////////////////////////////////////////////////////////////
330

  
331
    public void addNewRotation(int vector, int row )
332
      {
333
      Static3D axis = VectX;
334

  
335
      switch(vector)
336
        {
337
        case VECTX: axis = VectX; break;
338
        case VECTY: axis = VectY; break;
339
        case VECTZ: axis = VectZ; break;
340
        }
341

  
342
      mRotAxis = vector;
343
      mRotRow  = row;
344

  
345
      mRotationAngleStatic.set1(0.0f);
346

  
347
      for(int x=0; x<mSize; x++)
348
        for(int y=0; y<mSize; y++)
349
          for(int z=0; z<mSize; z++)
350
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
351
              {
352
              if( belongsToRotation(x,y,z,vector,mRotRow) )
353
                {
354
                mRotationAxis[x][y][z].set(axis);
355
                mRotationAngle[x][y][z].add(mRotationAngleStatic);
356
                }
357
              }
358
      }
359

  
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361

  
362
    public void continueRotation(float angleInDegrees)
363
      {
364
      mRotationAngleStatic.set1(angleInDegrees);
365
      }
366

  
375 367
///////////////////////////////////////////////////////////////////////////////////////////////////
376 368

  
377 369
    public Static4D getRotationQuat()
......
496 488

  
497 489
    public void recomputeScaleFactor(int screenWidth, int screenHeight)
498 490
      {
499
      mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(screenWidth>screenHeight ? screenHeight:screenWidth);
500

  
501 491
      int texW = mNodeTexture.getWidth();
502 492
      int texH = mNodeTexture.getHeight();
503 493

  
......
516 506
        mNodeScale.set(factor,factor,factor);
517 507
        }
518 508

  
519
      float scaleFactor = (mCubeSizeInScreenSpace/(TEXTURE_SIZE*mSize)) * (float)texW/(screenWidth>screenHeight ? screenHeight:screenWidth);
509
      float scaleFactor = (CUBE_SCREEN_RATIO*texW/(TEXTURE_SIZE*mSize));
520 510

  
521 511
      mMove.set( texW*0.5f , texH*0.5f , 0.0f );
522 512
      mScale.set(scaleFactor,scaleFactor,scaleFactor);
src/main/java/org/distorted/object/RubikCubeMovement.java
19 19

  
20 20
package org.distorted.object;
21 21

  
22
import org.distorted.library.type.Static2D;
22 23
import org.distorted.library.type.Static4D;
23 24
import org.distorted.magic.RubikSurfaceView;
24 25

  
......
36 37

  
37 38
    private static final int[] VECT = {RubikCube.VECTX,RubikCube.VECTY,RubikCube.VECTZ};
38 39

  
39
    // Moving the finger from the middle of the vertical screen to the right edge will rotate a
40
    // given face by SWIPING_SENSITIVITY/2 degrees.
41
    private final static int SWIPING_SENSITIVITY  = 240;
42

  
43
    private RubikCube mCube;
44
    private float[] mPoint, mCamera, mTouchPointCastOntoFace, mDiff, mTouchPoint; // all in screen space
40
    private float[] mPoint, mCamera, mTouchPointCastOntoFace, mDiff, mTouchPoint;
45 41
    private int mRotationVect;
46 42

  
47 43
///////////////////////////////////////////////////////////////////////////////////////////////////
......
51 47
      return (y>x) ? (y>=-x) : (y< -x);
52 48
      }
53 49

  
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

  
56
    private boolean faceIsVisible(int face, float cubeHalfSize)
57
      {
58
      int sign = retFaceSign(face);
59
      int zAxis= retFaceZaxis(face);
60

  
61
      return sign*mCamera[zAxis] > cubeHalfSize;
62
      }
63

  
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65

  
66
    private void convertTouchPointToScreenSpace(Static4D accumulated, float x, float y)
67
      {
68
      Static4D touchPoint = new Static4D(x, y, 0, 0);
69
      Static4D rotatedTouchPoint= RubikSurfaceView.rotateVectorByInvertedQuat(touchPoint, accumulated);
70

  
71
      mPoint[0] = rotatedTouchPoint.get1();
72
      mPoint[1] = rotatedTouchPoint.get2();
73
      mPoint[2] = rotatedTouchPoint.get3();
74
      }
75

  
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

  
78
    private void convertCameraPointToScreenSpace(Static4D accumulated, float cameraDistance)
79
      {
80
      Static4D cameraPoint = new Static4D(0, 0, cameraDistance, 0);
81
      Static4D rotatedCamera= RubikSurfaceView.rotateVectorByInvertedQuat(cameraPoint, accumulated);
82

  
83
      mCamera[0] = rotatedCamera.get1();
84
      mCamera[1] = rotatedCamera.get2();
85
      mCamera[2] = rotatedCamera.get3();
86
      }
87

  
88
///////////////////////////////////////////////////////////////////////////////////////////////////
89
// given precomputed mCamera and mPoint, respectively camera and touch point positions in ScreenSpace,
90
// cast this touch point onto the surface defined by the 'face' and write the cast coords to 'output'.
91
// Center of the 'face' = (0,0), third coord always +- cubeHalfSize.
92

  
93
    private void castTouchPointOntoFace(int face, float cubeHalfSize, float[] output)
94
      {
95
      int sign = retFaceSign(face);
96
      int zAxis= retFaceZaxis(face);
97
      float diff = mPoint[zAxis]-mCamera[zAxis];
98

  
99
      float ratio =  diff!=0.0f ? (sign*cubeHalfSize-mCamera[zAxis])/diff : 0.0f;
100

  
101
      output[0] = (mPoint[0]-mCamera[0])*ratio + mCamera[0];
102
      output[1] = (mPoint[1]-mCamera[1])*ratio + mCamera[1];
103
      output[2] = (mPoint[2]-mCamera[2])*ratio + mCamera[2];
104
      }
105

  
106 50
///////////////////////////////////////////////////////////////////////////////////////////////////
107 51

  
108 52
    private int retFaceSign(int face)
......
172 116
      }
173 117

  
174 118
///////////////////////////////////////////////////////////////////////////////////////////////////
175
// PUBLIC API
119

  
120
    private boolean faceIsVisible(int face, float cubeHalfSize)
121
      {
122
      int sign = retFaceSign(face);
123
      int zAxis= retFaceZaxis(face);
124

  
125
      return sign*mCamera[zAxis] > cubeHalfSize;
126
      }
127

  
176 128
///////////////////////////////////////////////////////////////////////////////////////////////////
177 129

  
178
    public RubikCubeMovement(RubikCube cube)
130
    private void convertTouchPointToScreenSpace(Static4D accumulated, float x, float y)
179 131
      {
180
      mCube = cube;
132
      Static4D touchPoint = new Static4D(x, y, 0, 0);
133
      Static4D rotatedTouchPoint= RubikSurfaceView.rotateVectorByInvertedQuat(touchPoint, accumulated);
181 134

  
135
      mPoint[0] = rotatedTouchPoint.get1();
136
      mPoint[1] = rotatedTouchPoint.get2();
137
      mPoint[2] = rotatedTouchPoint.get3();
138
      }
139

  
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

  
142
    private void convertCameraPointToScreenSpace(Static4D accumulated, float cameraDistance)
143
      {
144
      Static4D cameraPoint = new Static4D(0, 0, cameraDistance, 0);
145
      Static4D rotatedCamera= RubikSurfaceView.rotateVectorByInvertedQuat(cameraPoint, accumulated);
146

  
147
      mCamera[0] = rotatedCamera.get1();
148
      mCamera[1] = rotatedCamera.get2();
149
      mCamera[2] = rotatedCamera.get3();
150
      }
151

  
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153
// given precomputed mCamera and mPoint, respectively camera and touch point positions in ScreenSpace,
154
// cast this touch point onto the surface defined by the 'face' and write the cast coords to 'output'.
155
// Center of the 'face' = (0,0), third coord always +- cubeHalfSize.
156

  
157
    private void castTouchPointOntoFace(int face, float cubeHalfSize, float[] output)
158
      {
159
      int sign = retFaceSign(face);
160
      int zAxis= retFaceZaxis(face);
161
      float diff = mPoint[zAxis]-mCamera[zAxis];
162

  
163
      float ratio =  diff!=0.0f ? (sign*cubeHalfSize-mCamera[zAxis])/diff : 0.0f;
164

  
165
      output[0] = (mPoint[0]-mCamera[0])*ratio + mCamera[0];
166
      output[1] = (mPoint[1]-mCamera[1])*ratio + mCamera[1];
167
      output[2] = (mPoint[2]-mCamera[2])*ratio + mCamera[2];
168
      }
169

  
170
///////////////////////////////////////////////////////////////////////////////////////////////////
171
// PUBLIC API
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173

  
174
    public RubikCubeMovement()
175
      {
182 176
      mRotationVect = VECT[0];
183 177

  
184 178
      mPoint = new float[3];
......
192 186

  
193 187
    public int faceTouched(Static4D accumulated, float cameraDistance, float x, float y)
194 188
      {
195
      float cubeHalfSize= mCube.returnCubeSizeInScreenSpace()*0.5f;
189
      float cubeHalfSize= RubikCube.CUBE_SCREEN_RATIO*0.5f;
196 190

  
197 191
      convertTouchPointToScreenSpace(accumulated,x,y);
198 192
      convertCameraPointToScreenSpace(accumulated, cameraDistance);
......
216 210

  
217 211
///////////////////////////////////////////////////////////////////////////////////////////////////
218 212

  
219
    public void addNewRotation(Static4D accumulated, int lastTouchedFace, float x, float y)
213
    public Static2D newRotation(Static4D accumulated, int lastTouchedFace, float x, float y)
220 214
      {
221
      float cubeHalfSize= mCube.returnCubeSizeInScreenSpace()*0.5f;
215
      float cubeHalfSize= RubikCube.CUBE_SCREEN_RATIO*0.5f;
222 216

  
223 217
      convertTouchPointToScreenSpace(accumulated,x,y);
224 218
      castTouchPointOntoFace(lastTouchedFace,cubeHalfSize,mDiff);
......
236 230
      mTouchPoint[1] = mPoint[1];
237 231
      mTouchPoint[2] = mPoint[2];
238 232

  
239
      mCube.addNewRotation(mRotationVect, (int)(mCube.getSize()*offset) );
233
      return new Static2D(mRotationVect,offset);
240 234
      }
241 235

  
242 236
///////////////////////////////////////////////////////////////////////////////////////////////////
243 237

  
244
    public void continueRotation(Static4D accumulated, int lastTouchedFace, float x, float y, int scrMin)
238
    public float continueRotation(Static4D accumulated, int lastTouchedFace, float x, float y)
245 239
      {
246 240
      convertTouchPointToScreenSpace(accumulated,x,y);
247 241

  
......
254 248
      int sign = retFaceRotationSign(lastTouchedFace);
255 249
      float angle = (mRotationVect==xAxis ? mDiff[yAxis] : -mDiff[xAxis]);
256 250

  
257
      mCube.continueRotation(SWIPING_SENSITIVITY*sign*angle/scrMin);
251
      return sign*angle;
258 252
      }
259 253
}

Also available in: Unified diff