Project

General

Profile

« Previous | Next » 

Revision 12ad3fca

Added by Leszek Koltunski about 4 years ago

Progress with object Movement - almost finished.

View differences:

src/main/java/org/distorted/effect/scramble/ScrambleEffect.java
308 308

  
309 309
    mObject.solve();
310 310

  
311
    mNumAxis    = mObject.getNumAxis();
311
    mNumAxis    = mObject.getRotationAxis().length;
312 312
    mBasicAngle = mObject.getBasicAngle();
313 313

  
314 314
    int numScrambles = renderer.getNumScrambles();
src/main/java/org/distorted/magic/RubikSurfaceView.java
27 27
import android.view.MotionEvent;
28 28

  
29 29
import org.distorted.library.type.Static2D;
30
import org.distorted.library.type.Static3D;
30 31
import org.distorted.library.type.Static4D;
31 32
import org.distorted.object.RubikObject;
32 33
import org.distorted.object.RubikObjectMovement;
......
59 60
    private RubikRenderer mRenderer;
60 61
    private RubikObjectMovement mMovement;
61 62
    private boolean mDragging, mBeginningRotation, mContinuingRotation;
62
    private float mX, mY;
63 63
    private int mScreenWidth, mScreenHeight, mScreenMin;
64 64

  
65
    private float mX, mY;
66
    private float mStartRotX, mStartRotY;
67
    private float mAxisX, mAxisY;
68

  
65 69
    private static Static4D mQuatCurrent    = new Static4D(0,0,0,1);
66 70
    private static Static4D mQuatAccumulated= new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
67 71
    private static Static4D mTempCurrent    = new Static4D(0,0,0,1);
......
74 78
      mScreenWidth = width;
75 79
      mScreenHeight= height;
76 80

  
77
      mScreenMin = width<height ? width:height;
81
      mScreenMin = Math.min(width, height);
78 82
      }
79 83

  
80 84
///////////////////////////////////////////////////////////////////////////////////////////////////
......
146 150
      return new Static4D(0f, 0f, 0f, 1f);
147 151
      }
148 152

  
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

  
155
    private void setUpDragOrRotate(float x, float y)
156
      {
157
      Static4D touchPoint1 = new Static4D(x, y, 0, 0);
158
      Static4D rotatedTouchPoint1= rotateVectorByInvertedQuat(touchPoint1, mQuatAccumulated);
159
      Static4D rotatedCamera= rotateVectorByInvertedQuat(CAMERA_POINT, mQuatAccumulated);
160

  
161
      if( mMovement!=null && mMovement.faceTouched(rotatedTouchPoint1,rotatedCamera) )
162
        {
163
        mDragging           = false;
164
        mBeginningRotation  = mRenderer.canRotate();
165
        mContinuingRotation = false;
166
        }
167
      else
168
        {
169
        mDragging           = mRenderer.canDrag();
170
        mBeginningRotation  = false;
171
        mContinuingRotation = false;
172
        }
173
      }
174

  
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176
// cast the 3D axis we are currently rotating along to the 2D in-screen-surface axis
177

  
178
    private void computeCurrentAxis(Static3D axis)
179
      {
180
      Static4D axis4D = new Static4D(axis.get0(), axis.get1(), axis.get2(), 0);
181
      Static4D result = rotateVectorByQuat(axis4D, mQuatAccumulated);
182

  
183
      mAxisX =result.get0();
184
      mAxisY =result.get1();
185

  
186
      float len = (float)Math.sqrt(mAxisX*mAxisX + mAxisY*mAxisY);
187
      mAxisX /= len;
188
      mAxisY /= len;
189

  
190
      android.util.Log.e("axis", "axis 2D: "+mAxisX+" , "+mAxisY);
191
      }
192

  
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194

  
195
    private float continueRotation(float dx, float dy)
196
      {
197
      float alpha = dx*mAxisX + dy*mAxisY;
198
      float x = dx - alpha*mAxisX;
199
      float y = dy - alpha*mAxisY;
200

  
201
      float len = (float)Math.sqrt(x*x + y*y);
202

  
203

  
204

  
205
      return len;
206
      }
207

  
149 208
///////////////////////////////////////////////////////////////////////////////////////////////////
150 209
// return quat1*quat2
151 210

  
......
220 279
        }
221 280
      }
222 281

  
223
///////////////////////////////////////////////////////////////////////////////////////////////////
224

  
225
    private void setUpDragOrRotate(float x, float y)
226
      {
227
      Static4D touchPoint1 = new Static4D(x, y, 0, 0);
228
      Static4D rotatedTouchPoint1= rotateVectorByInvertedQuat(touchPoint1, mQuatAccumulated);
229
      Static4D rotatedCamera= rotateVectorByInvertedQuat(CAMERA_POINT, mQuatAccumulated);
230

  
231
      if( mMovement!=null && mMovement.faceTouched(rotatedTouchPoint1,rotatedCamera) )
232
        {
233
        mDragging           = false;
234
        mBeginningRotation  = mRenderer.canRotate();
235
        mContinuingRotation = false;
236
        }
237
      else
238
        {
239
        mDragging           = mRenderer.canDrag();
240
        mBeginningRotation  = false;
241
        mContinuingRotation = false;
242
        }
243
      }
244

  
245 282
///////////////////////////////////////////////////////////////////////////////////////////////////
246 283

  
247 284
    @Override
......
261 298
                                         {
262 299
                                         if( (mX-x)*(mX-x)+(mY-y)*(mY-y) > 1.0f/(ROTATION_SENSITIVITY*ROTATION_SENSITIVITY) )
263 300
                                           {
301
                                           mStartRotX = x;
302
                                           mStartRotY = y;
303

  
264 304
                                           Static4D touchPoint2 = new Static4D(x, y, 0, 0);
265 305
                                           Static4D rotatedTouchPoint2= rotateVectorByInvertedQuat(touchPoint2, mQuatAccumulated);
266 306

  
267 307
                                           Static2D rot = mMovement.newRotation(rotatedTouchPoint2);
268 308
                                           RubikObject object = mRenderer.getObject();
269 309

  
270
                                           object.beginNewRotation( (int)rot.get0(), object.returnRowFromOffset(rot.get1()) );
310
                                           int axis = (int)rot.get0();
311
                                           computeCurrentAxis( object.getRotationAxis()[axis] );
312

  
313
                                           object.beginNewRotation( axis, object.returnRowFromOffset(rot.get1()) );
271 314

  
272 315
                                           if( RubikState.getCurrentState()==RubikState.SOLV )
273 316
                                             {
......
281 324
                                         }
282 325
                                       else if( mContinuingRotation )
283 326
                                         {
284
                                         Static4D touchPoint3 = new Static4D(x, y, 0, 0);
285
                                         Static4D rotatedTouchPoint3= rotateVectorByInvertedQuat(touchPoint3, mQuatAccumulated);
327
                                         //Static4D touchPoint3 = new Static4D(x, y, 0, 0);
328
                                         //Static4D rotatedTouchPoint3= rotateVectorByInvertedQuat(touchPoint3, mQuatAccumulated);
286 329

  
287
                                         float angle = mMovement.continueRotation(rotatedTouchPoint3);
330
                                         float angle = continueRotation(x-mStartRotX,y-mStartRotY);
331
                                         //float angle = mMovement.continueRotation(rotatedTouchPoint3);
288 332
                                         mRenderer.getObject().continueRotation(SWIPING_SENSITIVITY*angle);
289 333
                                         }
290 334
                                       else if( mDragging )
src/main/java/org/distorted/object/RubikCube.java
145 145
    return new VertexEffectSink( new Static1D(strength), center, region );
146 146
    }
147 147

  
148
///////////////////////////////////////////////////////////////////////////////////////////////////
149

  
150
  Static3D[] getRotationAxis()
151
    {
152
    return AXIS;
153
    }
154

  
155 148
///////////////////////////////////////////////////////////////////////////////////////////////////
156 149
// paint only the square with lower-left corner at (face*TEX_H,0) and side length TEX_H
157 150

  
......
207 200
///////////////////////////////////////////////////////////////////////////////////////////////////
208 201
// PUBLIC API
209 202

  
203
  public Static3D[] getRotationAxis()
204
    {
205
    return AXIS;
206
    }
207

  
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

  
210 210
  public int getBasicAngle()
211 211
    {
212 212
    return 4;
src/main/java/org/distorted/object/RubikCubeMovement.java
28 28
    super(RubikCube.AXIS, 2, 0.5f, 0.5f);
29 29
    }
30 30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

  
33
  void fillPossibleRotations(int axis, int[] output)
34
    {
35
    switch(axis)
36
      {
37
      case 0: output[0]=2; output[1]=1; break; // (Z,Y) when looking at LEFT or RIGHT
38
      case 1: output[0]=0; output[1]=2; break; // (X,Z) when looking at BOTTOM or TOP
39
      case 2: output[0]=0; output[1]=1; break; // (X,Y) when looking at FRONT or BACK
40
      }
41
    }
42

  
43 31
///////////////////////////////////////////////////////////////////////////////////////////////////
44 32

  
45 33
  boolean isInsideFace(float[] p)
46 34
    {
47 35
    return ( p[0]<=0.5f && p[0]>=-0.5f && p[1]<=0.5f && p[1]>=-0.5f );
48 36
    }
49

  
50
///////////////////////////////////////////////////////////////////////////////////////////////////
51

  
52
  float returnAngle(float[] v, int[] possible)
53
    {
54
    float angle= (mRotationVect==possible[0] ? v[possible[1]] : -v[possible[0]]);
55
    if( mLastTouchedAxis==2 ) angle = -angle;
56
    return angle;
57
    }
58 37
}
src/main/java/org/distorted/object/RubikObject.java
468 468
     mRotationAngleStatic.set0(0);
469 469
     }
470 470

  
471
///////////////////////////////////////////////////////////////////////////////////////////////////
472

  
473
  public int getNumAxis()
474
    {
475
    return ROTATION_AXIS.length;
476
    }
477

  
478 471
///////////////////////////////////////////////////////////////////////////////////////////////////
479 472

  
480 473
  abstract float getScreenRatio();
......
484 477
  abstract int getNumFaces();
485 478
  abstract void createFaceTexture(Canvas canvas, Paint paint, int face);
486 479
  abstract MeshBase createCubitMesh(int cubit, int vertices);
487
  abstract Static3D[] getRotationAxis();
480
  public abstract Static3D[] getRotationAxis();
488 481
  public abstract int getBasicAngle();
489 482
  public abstract int returnRowFromOffset(float offset);
490 483
  }
src/main/java/org/distorted/object/RubikObjectMovement.java
27 27

  
28 28
public abstract class RubikObjectMovement
29 29
  {
30
  int mRotationVect, mLastTouchedAxis;
31

  
32
  private float[] mPoint, mCamera, mDiff, mTouch;
30
  private int mLastTouchedAxis;
31
  private float[] mPoint, mCamera, mTouch;
33 32
  private float[] mPoint2D, mMove2D;
34 33
  private float[][][] mCastAxis;
35 34
  private int mLastTouchedLR;
36 35
  private int mNumAxis, mNumFacesPerAxis;
37
  private int[] mPossible;
38 36
  private float mDistanceCenterFace3D, mDistanceCenterFace2D;
39 37
  private Static3D[] mAxis;
40 38

  
41 39
///////////////////////////////////////////////////////////////////////////////////////////////////
42 40

  
43 41
  abstract boolean isInsideFace(float[] point);
44
  abstract float returnAngle(float[] vect, int[] possible);
45
  abstract void fillPossibleRotations(int axis, int[] output);
46 42

  
47 43
///////////////////////////////////////////////////////////////////////////////////////////////////
48 44

  
......
50 46
    {
51 47
    mPoint = new float[3];
52 48
    mCamera= new float[3];
53
    mDiff  = new float[3];
54 49
    mTouch = new float[3];
55 50

  
56 51
    mPoint2D = new float[2];
......
61 56
    mNumFacesPerAxis = numFacesPerAxis;
62 57
    mDistanceCenterFace3D = distance3D; // distance from the center of the object to each of its faces
63 58
    mDistanceCenterFace2D = distance2D; // distance from the center of a face to its edge
64
    mPossible = new int[mNumAxis-1];
65 59

  
66 60
    // mCastAxis[1][2]{0,1} are the 2D coords of the 2nd axis cast onto the face defined by the
67 61
    // 1st pair (axis,lr)
......
107 101
///////////////////////////////////////////////////////////////////////////////////////////////////
108 102
// find the casted axis with which our move2D vector forms an angle closest to 90 deg.
109 103

  
110
  private int computeRotationVect(int axis, int lr, float[] move2D)
104
  private int computeRotationIndex(int axis, int lr, float[] move2D)
111 105
    {
112 106
    float cosAngle, minCosAngle = Float.MAX_VALUE;
113 107
    int minIndex=-1;
......
238 232
    output[1] = v0*y0 + v1*y1 + v2*y2;
239 233
    }
240 234

  
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242

  
243
  private String getFaceColor(int axis)
244
    {
245
    switch(axis)
246
      {
247
      case 0: return "yellow (bottom) ";
248
      case 1: return "green (back) ";
249
      case 2: return "blue (right) ";
250
      case 3: return "red (left) ";
251
      }
252

  
253
    return null;
254
    }
255

  
256 235
///////////////////////////////////////////////////////////////////////////////////////////////////
257 236
// PUBLIC API
258 237
///////////////////////////////////////////////////////////////////////////////////////////////////
......
276 255
          castTouchPointOntoFace(mAxis[mLastTouchedAxis], mLastTouchedLR, mTouch);
277 256
          convertTo2Dcoords(mTouch, mAxis[mLastTouchedAxis], mLastTouchedLR, mPoint2D);
278 257

  
279
          if( isInsideFace(mPoint2D) )
280
            {
281
            fillPossibleRotations(mLastTouchedAxis, mPossible);
282
            return true;
283
            }
258
          if( isInsideFace(mPoint2D) ) return true;
284 259
          }
285 260
        }
286 261
      }
......
302 277
    mMove2D[0] -= mPoint2D[0];
303 278
    mMove2D[1] -= mPoint2D[1];
304 279

  
305
    mRotationVect= computeRotationVect(mLastTouchedAxis, mLastTouchedLR, mMove2D);
306
    int index = mLastTouchedAxis*mNumFacesPerAxis+mLastTouchedLR;
307
    float offset = computeOffset(mPoint2D, mCastAxis[index][mRotationVect]);
308

  
309
    return new Static2D(mRotationVect,offset);
310
    }
311

  
312
///////////////////////////////////////////////////////////////////////////////////////////////////
313

  
314
  public float continueRotation(Static4D rotatedTouchPoint)
315
    {
316
    mDiff[0] = rotatedTouchPoint.get0()/RubikObject.OBJECT_SCREEN_RATIO - mPoint[0];
317
    mDiff[1] = rotatedTouchPoint.get1()/RubikObject.OBJECT_SCREEN_RATIO - mPoint[1];
318
    mDiff[2] = rotatedTouchPoint.get2()/RubikObject.OBJECT_SCREEN_RATIO - mPoint[2];
280
    int rotIndex = computeRotationIndex(mLastTouchedAxis, mLastTouchedLR, mMove2D);
281
    int index    = mLastTouchedAxis*mNumFacesPerAxis+mLastTouchedLR;
282
    float offset = computeOffset(mPoint2D, mCastAxis[index][rotIndex]);
319 283

  
320
    return (mLastTouchedLR-0.5f)*returnAngle(mDiff, mPossible);
284
    return new Static2D(rotIndex,offset);
321 285
    }
322 286
  }
src/main/java/org/distorted/object/RubikPyraminx.java
208 208
    return new VertexEffectSink( new Static1D(1.3f), center, region );
209 209
    }
210 210

  
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

  
213
  Static3D[] getRotationAxis()
214
    {
215
    return AXIS;
216
    }
217

  
218 211
///////////////////////////////////////////////////////////////////////////////////////////////////
219 212

  
220 213
  void createFaceTexture(Canvas canvas, Paint paint, int face)
......
299 292
///////////////////////////////////////////////////////////////////////////////////////////////////
300 293
// PUBLIC API
301 294

  
295
  public Static3D[] getRotationAxis()
296
    {
297
    return AXIS;
298
    }
299

  
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

  
302 302
  public int getBasicAngle()
303 303
    {
304 304
    return 3;
src/main/java/org/distorted/object/RubikPyraminxMovement.java
33 33
    super(RubikPyraminx.AXIS, 1, SQ2*SQ3/12, SQ3/6);
34 34
    }
35 35

  
36
///////////////////////////////////////////////////////////////////////////////////////////////////
37
// (         0,        1,       0 )  BOTTOM
38
// (         0,  -1.0f/3, 2*SQ2/3 )  BACK
39
// (-SQ2*SQ3/3,  -1.0f/3,  -SQ2/3 )  LEFT
40
// ( SQ2*SQ3/3,  -1.0f/3,  -SQ2/3 )  RIGHT
41

  
42
  void fillPossibleRotations(int axis, int[] output)
43
    {
44
    switch(axis)
45
      {
46
      case 0: output[0]=3; output[1]=1; output[2]=2; break; // (RIGHT,BACK,LEFT) when looking at BOTTOM
47
      case 1: output[0]=2; output[1]=0; output[2]=3; break; // (LEFT,BOTTOM,RIGHT) when looking at BACK
48
      case 2: output[0]=3; output[1]=0; output[2]=1; break; // (RIGHT,BOTTOM,BACK) when looking at LEFT
49
      case 3: output[0]=1; output[1]=0; output[2]=2; break; // (BACK,BOTTOM,LEFT) when looking at RIGHT
50
      }
51
    }
52

  
53 36
///////////////////////////////////////////////////////////////////////////////////////////////////
54 37

  
55 38
  boolean isInsideFace(float[] p)
......
60 43

  
61 44
    return a1 && a2 && a3;
62 45
    }
63

  
64
///////////////////////////////////////////////////////////////////////////////////////////////////
65
// TODO
66

  
67
  float returnAngle(float[] v, int[] possible)
68
    {
69
    /*
70
    float angle= (mRotationVect==possible[0] ? v[possible[1]] : -v[possible[0]]);
71
    if( mLastTouchedAxis==2 ) angle = -angle;
72
    return angle;
73
     */
74

  
75
    return 0;
76
    }
77 46
}

Also available in: Unified diff