Project

General

Profile

« Previous | Next » 

Revision 4a014840

Added by Leszek Koltunski 6 months ago

progress with Ghost rotations.

View differences:

src/main/java/org/distorted/objectlib/main/TwistyLayerRotations.java
10 10
package org.distorted.objectlib.main;
11 11

  
12 12
import org.distorted.library.effect.VertexEffectRotate;
13
import org.distorted.library.main.DistortedEffects;
13 14
import org.distorted.library.message.EffectListener;
14 15
import org.distorted.library.type.Dynamic1D;
15 16
import org.distorted.library.type.Static1D;
......
30 31
  private int mCurrentRotAxis;
31 32

  
32 33
  private final int mMaxNumLayers;
33
  private final int mGhostAngle;
34 34
  private final Static3D mRotationAxis;
35 35
  private final VertexEffectRotate mRotateEffect;
36 36
  private final Dynamic1D mRotationAngle;
37 37
  private final Static1D mRotationAngleStatic, mRotationAngleMiddle, mRotationAngleFinal;
38 38
  private final TwistyObject mParent;
39 39

  
40
  // ghost angle
41
  private final float mGhostAngle;
42
  private final int mNumLayer0;
43
  private final boolean[] mGhostIsUp;
44
  private int mUpLeft, mUpRight;
45
  private final int mNumLeft, mNumRight;
46
  private VertexEffectRotate mGhostEffect1;
47
  private Static1D mGhostAngleN;
48
  private int mGhostN;
49

  
40 50
///////////////////////////////////////////////////////////////////////////////////////////////////
41 51

  
42
  TwistyLayerRotations(TwistyObject parent, int maxLayers, int ghostAngle)
52
  TwistyLayerRotations(TwistyObject parent, Static3D ax, int[] numLayers, int ghostAngle, DistortedEffects effect)
43 53
    {
44 54
    mParent = parent;
55
    mGhostAngle = (float)(Math.PI*ghostAngle/180);
56

  
57
    int maxLayers = -1;
58
    for(int numLayer : numLayers) if(maxLayers<numLayer) maxLayers = numLayer;
45 59
    mMaxNumLayers = maxLayers;
46
    mGhostAngle = ghostAngle;
60
    mNumLayer0 = numLayers[0];
61
    mGhostIsUp = (mGhostAngle==0) ? null : new boolean[mNumLayer0];
62
    mUpLeft = mUpRight = 0;
63
    mNumLeft = mNumLayer0/2;
64
    mNumRight= mNumLayer0-mNumLeft;
47 65

  
48 66
    mRotationState = STATE_NOTHING;
49 67

  
......
54 72
    mRotationAngle= new Dynamic1D();
55 73
    mRotationAxis = new Static3D(1,0,0);
56 74
    mRotateEffect = new VertexEffectRotate(mRotationAngle, mRotationAxis, CENTER);
75

  
76
    effect.apply(mRotateEffect);
77

  
78
    if( mGhostAngle!=0 )
79
      {
80
      mGhostN = 0;
81
      Static1D ghostAngle1= new Static1D( (float)(Math.PI*mGhostAngle/180) );
82
      mGhostAngleN= new Static1D(0);
83
      VertexEffectRotate ghostEffectN = new VertexEffectRotate(mGhostAngleN, ax, CENTER);
84
      mGhostEffect1 = new VertexEffectRotate( ghostAngle1, ax, CENTER);
85
      effect.apply(ghostEffectN);
86
      effect.apply(mGhostEffect1);
87
      }
57 88
    }
58 89

  
90
///////////////////////////////////////////////////////////////////////////////////////////////////
91
// GHOST
59 92
///////////////////////////////////////////////////////////////////////////////////////////////////
60 93

  
61
  private int computeNearestAngle(int basicAngle, float angle, float speed)
94
  private boolean angleIsGhost(int angle, int basicAngle)
62 95
    {
63
    int nearestAngle = 360/basicAngle;
64
    int tmp = (int)((angle+nearestAngle/2)/nearestAngle);
65
    if( angle< -(nearestAngle*0.5) ) tmp-=1;
96
    return angle%(360/basicAngle)!=0;
97
    }
66 98

  
67
    if( tmp!=0 ) return nearestAngle*tmp;
99
///////////////////////////////////////////////////////////////////////////////////////////////////
68 100

  
69
    return speed> 1.2f ? nearestAngle*(angle>0 ? 1:-1) : 0;
101
  private int computeGhostAngle(int row, int basicAngle, float angle, float speed)
102
    {
103
    boolean left = row<mNumLayer0/2;
104

  
105
    if( left )
106
      {
107
      if( angle<0 )  // if we are looking at the 0th axis (x axis) from the front, this is 'up' rot
108
        {
109
        if( mUpRight==mNumRight && !mGhostIsUp[row] )
110
          {
111
          int a = computeGhostAngle(basicAngle,angle,speed);
112
          if( angleIsGhost(a,basicAngle) )
113
            {
114
            changeRow(row,true);
115
            if( mUpLeft==0 ) enableGhostAxis(false);
116
            mUpLeft++;
117

  
118
            if( mUpLeft==mNumLeft )
119
              {
120
              for( int i=0; i<mNumLayer0; i++ ) changeRow(i,false);
121
              mUpLeft = 0;
122
              mUpRight= 0;
123
              changeTotalGhostAngle(1);
124
              }
125
            }
126
          return a;
127
          }
128
        else return computeNearestAngle(basicAngle,angle,speed);
129
        }
130
      else
131
        {
132
        if( mGhostIsUp[row] )
133
          {
134
          int a = computeGhostAngle(basicAngle,angle,speed);
135
          if( angleIsGhost(a,basicAngle) )
136
            {
137
            changeRow(row,false);
138
            if( mUpLeft==1 ) enableGhostAxis(true);
139
            mUpLeft--;
140
            }
141
          return a;
142
          }
143
        else if( mUpLeft==0 && mUpRight==0 )
144
          {
145
          int a = computeGhostAngle(basicAngle,angle,speed);
146
          if( angleIsGhost(a,basicAngle) )
147
            {
148
            mUpLeft = mNumLeft-1;
149
            mUpRight= mNumRight;
150
            for( int i=0; i<mNumLayer0; i++ )
151
              if( i!=row) changeRow(i,true);
152
            if( mNumLeft==1 ) enableGhostAxis(true);
153
            changeTotalGhostAngle(-1);
154
            }
155
          return a;
156
          }
157
        else return computeNearestAngle(basicAngle,angle,speed);
158
        }
159
      }
160
    else
161
      {
162
      if( angle<0 )
163
        {
164
        if( !mGhostIsUp[row] )
165
          {
166
          int a = computeGhostAngle(basicAngle,angle,speed);
167
          if( angleIsGhost(a,basicAngle) )
168
            {
169
            changeRow(row,true);
170
            mUpRight++;
171
            if( mUpRight==mNumRight ) enableGhostAxis(true);
172
            }
173
          return a;
174
          }
175
        else return computeNearestAngle(basicAngle,angle,speed);
176
        }
177
      else
178
        {
179
        if( mGhostIsUp[row] )
180
          {
181
          int a = computeGhostAngle(basicAngle,angle,speed);
182
          if( angleIsGhost(a,basicAngle) )
183
            {
184
            changeRow(row,false);
185
            mUpRight--;
186
            if( mNumRight==1 ) enableGhostAxis(false);
187
            }
188
          return a;
189
          }
190
        else return computeNearestAngle(basicAngle,angle,speed);
191
        }
192
      }
70 193
    }
71 194

  
72 195
///////////////////////////////////////////////////////////////////////////////////////////////////
73 196

  
74
  private float getAngle()
197
  private int computeRowBitmap(boolean[] up)
75 198
    {
76
    int pointNum = mRotationAngle.getNumPoints();
77
    return pointNum>=1 ? mRotationAngle.getPoint(pointNum-1).get0() : 0;
199
    int ret = 0;
200
    int tmp = 1;
201

  
202
    for(int l=0; l<mNumLayer0; l++)
203
      {
204
      if( up[l] ) ret += tmp;
205
      tmp *= 2;
206
      }
207

  
208
    return ret;
209
    }
210

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

  
213
  private void enableGhostAxis(boolean enable)
214
    {
215
    mParent.enableGhostAxis(enable);
216
    }
217

  
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

  
220
  private void changeTotalGhostAngle(int diff)
221
    {
222
    mGhostN += diff;
223
    mGhostN %= 360;
224
    mGhostAngleN.set0(mGhostN*mGhostAngle);
225
    }
226

  
227
///////////////////////////////////////////////////////////////////////////////////////////////////
228

  
229
  private void changeRow(int row, boolean up)
230
    {
231
    mGhostIsUp[row] = up;
232
    int rowBitmap = computeRowBitmap(mGhostIsUp);
233
    mGhostEffect1.setMeshAssociation( rowBitmap , -1);
234
    }
235

  
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237
// TODO
238

  
239
  private int computeGhostAngle(int basicAngle, float angle, float speed)
240
    {
241
    int basicDeg = 360/basicAngle;
242
    int numRot = (int)(angle/basicDeg + 0.5f);
243
    if( angle< -(basicDeg*0.5) ) numRot-=1;
244
    if( numRot==0 && speed>1.1f ) numRot = (angle>0 ? 1:-1);
245
    return basicDeg*numRot;
246
    }
247

  
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249
// END GHOST
250
///////////////////////////////////////////////////////////////////////////////////////////////////
251

  
252
  private int computeNearestAngle(int basicAngle, float angle, float speed)
253
    {
254
    int basicDeg = 360/basicAngle;
255
    int numRot = (int)(angle/basicDeg + 0.5f);
256
    if( angle< -(basicDeg*0.5) ) numRot-=1;
257
    if( numRot==0 && speed>1.1f ) numRot = (angle>0 ? 1:-1);
258
    return basicDeg*numRot;
259
    }
260

  
261
///////////////////////////////////////////////////////////////////////////////////////////////////
262

  
263
  private int computeNearestAngle(int axisIndex, int row, int basicAngle, float angle, float speed)
264
    {
265
    if( mGhostAngle==0 || axisIndex!=0 ) return computeNearestAngle(basicAngle,angle,speed);
266
    else                                 return computeGhostAngle(row,basicAngle,angle,speed);
78 267
    }
79 268

  
80 269
///////////////////////////////////////////////////////////////////////////////////////////////////
81 270

  
82
  VertexEffectRotate getEffect()
271
  private float getAngle()
83 272
    {
84
    return mRotateEffect;
273
    int pointNum = mRotationAngle.getNumPoints();
274
    return pointNum>=1 ? mRotationAngle.getPoint(pointNum-1).get0() : 0;
85 275
    }
86 276

  
87 277
///////////////////////////////////////////////////////////////////////////////////////////////////
88 278
// API
89 279
///////////////////////////////////////////////////////////////////////////////////////////////////
280
// the rotation has fully finished (everything including the last mini 'come back'). Delete it.
90 281

  
91
  synchronized float removeRotationNow()
282
  synchronized float removeRotation()
92 283
    {
93 284
    float angle = getAngle();
94 285

  
......
101 292
    }
102 293

  
103 294
///////////////////////////////////////////////////////////////////////////////////////////////////
295
// we have just lifted the finger
104 296

  
105
  long finishRotationNow(EffectListener listener, int basicAngle, float finishAngle, float avgSpeed)
297
  long finishRotation(EffectListener listener, int axisIndex, int row, int basicAngle, float finishAngle, float avgSpeed)
106 298
    {
107
    int nearestAngleInDegrees = computeNearestAngle(basicAngle,finishAngle,avgSpeed);
299
    int nearestAngleInDegrees = computeNearestAngle(axisIndex,row,basicAngle,finishAngle,avgSpeed);
108 300

  
109 301
    mRotationState = STATE_FINISH;
110 302
    float angle = getAngle();
......
124 316
    }
125 317

  
126 318
///////////////////////////////////////////////////////////////////////////////////////////////////
319
// rotation has begun and we have just moved the finger a bit
127 320

  
128 321
  void continueRotation(float angleInDegrees)
129 322
    {
......
131 324
    }
132 325

  
133 326
///////////////////////////////////////////////////////////////////////////////////////////////////
327
// this is 'programmatic' rotation - i.e. for example the one induced by the 'backMove' button.
134 328

  
135
  synchronized long addNewRotation(EffectListener listener, Static3D axis, int axisIndex, int rowBitmap, int angle, long durationMillis )
329
  synchronized long addRotation(EffectListener listener, Static3D axis, int axisIndex, int rowBitmap, int angle, long durationMillis )
136 330
    {
137 331
    int mult = 1;
138 332

  
139 333
    if( mRotationState==STATE_ROTATE ) return 0;
140
    if( mRotationState==STATE_FINISH ) { removeRotationNow(); mult = -1; }
334
    if( mRotationState==STATE_FINISH ) { removeRotation(); mult = -1; }
141 335

  
142 336
    mRotationState = STATE_ROTATE;
143
    mCurrentRotAxis = axisIndex;
144
    mRotRowBitmap= mParent.computeBandagedBitmap(rowBitmap,axisIndex);
337
    mCurrentRotAxis= axisIndex;
338
    mRotRowBitmap  = mParent.computeBandagedBitmap(rowBitmap,axisIndex);
145 339
    mRotationAngleStatic.set0(0.0f);
146 340
    mRotationAxis.set(axis);
147 341
    mRotationAngle.setDuration(durationMillis);
......
155 349
    }
156 350

  
157 351
///////////////////////////////////////////////////////////////////////////////////////////////////
352
// i.e. we just touched the screen, moved it a little bit and the TouchControl has figured out
353
// along which axis we are going to rotate.
158 354

  
159
  synchronized boolean beginNewRotation(Static3D axis, int axisIndex, int row )
355
  synchronized boolean beginRotation(Static3D axis, int axisIndex, int row )
160 356
    {
161 357
    if( mRotationState==STATE_ROTATE ) return false;
162
    if( mRotationState==STATE_FINISH ) removeRotationNow();
358
    if( mRotationState==STATE_FINISH ) removeRotation();
163 359

  
164 360
    mRotationState = STATE_ROTATE;
165
    mCurrentRotAxis = axisIndex;
166
    mRotRowBitmap= mParent.computeBandagedBitmap( (1<<row),axisIndex );
361
    mCurrentRotAxis= axisIndex;
362
    mRotRowBitmap  = mParent.computeBandagedBitmap( (1<<row),axisIndex );
167 363
    mRotationAngleStatic.set0(0.0f);
168 364
    mRotationAxis.set(axis);
169 365
    mRotationAngle.add(mRotationAngleStatic);

Also available in: Unified diff