Project

General

Profile

« Previous | Next » 

Revision 470820a7

Added by Leszek Koltunski over 4 years ago

Begin porting RubikCube to the new SingleMesh library. This will make rendering much faster - e.g. in case of Cube 5, instead of 98 renders of individual Cubits, there will be one render of the whole Mesh.

View differences:

src/main/java/org/distorted/objects/Cubit.java
27 27
import org.distorted.library.effect.MatrixEffectQuaternion;
28 28
import org.distorted.library.effect.MatrixEffectRotate;
29 29
import org.distorted.library.main.DistortedEffects;
30
import org.distorted.library.main.DistortedNode;
31
import org.distorted.library.mesh.MeshBase;
32 30
import org.distorted.library.message.EffectListener;
33 31
import org.distorted.library.type.Dynamic1D;
34 32
import org.distorted.library.type.Static1D;
......
41 39
class Cubit
42 40
  {
43 41
  private static final int POST_ROTATION_MILLISEC = 500;
44
  private static final Static3D matrCenter = new Static3D(0,0,0);
42
  private static final Static3D MATRIX_CENTER = new Static3D(0,0,0);
45 43

  
46 44
  private final Static3D mOrigPosition;
47 45

  
48 46
  private RubikObject mParent;
49
  private MeshBase mMesh;
50 47
  private Static3D mRotationAxis;
51 48
  private MatrixEffectRotate mRotateEffect;
52 49
  private Static3D mCurrentPosition;
53 50
  private int mNumAxis;
54 51
  private Dynamic1D mRotationAngle;
55 52

  
56
  DistortedNode mNode;
57 53
  DistortedEffects mEffect;
58 54
  Static4D mQuatScramble;
59 55
  float[] mRotationRow;
60 56

  
57
///////////////////////////////////////////////////////////////////////////////////////////////////
58

  
59
  Cubit(RubikObject parent, Static3D position)
60
    {
61
    float x = position.get0();
62
    float y = position.get1();
63
    float z = position.get2();
64

  
65
    Static3D vector = new Static3D(x,y,z);
66

  
67
    mParent          = parent;
68
    mOrigPosition    = new Static3D(x,y,z);
69
    mQuatScramble    = new Static4D(0,0,0,1);
70
    mRotationAngle   = new Dynamic1D();
71
    mRotationAxis    = new Static3D(1,0,0);
72
    mCurrentPosition = position;
73
    mRotateEffect    = new MatrixEffectRotate(mRotationAngle, mRotationAxis, MATRIX_CENTER);
74

  
75
    mNumAxis     = mParent.ROTATION_AXIS.length;
76
    mRotationRow = new float[mNumAxis];
77
    computeRotationRow();
78

  
79
    mEffect = new DistortedEffects();
80
    mEffect.apply( new MatrixEffectMove(vector) );
81
    mEffect.apply( new MatrixEffectQuaternion(mQuatScramble, MATRIX_CENTER));
82
    mEffect.apply(mRotateEffect);
83
    mEffect.apply(mParent.mQuatAEffect);
84
    mEffect.apply(mParent.mQuatCEffect);
85
    mEffect.apply(mParent.mScaleEffect);
86
    }
87

  
61 88
///////////////////////////////////////////////////////////////////////////////////////////////////
62 89
// Because of quatMultiplication, errors can accumulate - so to avoid this, we
63 90
// correct the value of the 'scramble' quat to what it should be - one of the legal quats from the
......
163 190
      }
164 191
    }
165 192

  
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167

  
168
  Cubit(RubikObject parent, MeshBase mesh, Static3D position)
169
    {
170
    float x = position.get0();
171
    float y = position.get1();
172
    float z = position.get2();
173

  
174
    Static3D vector = new Static3D(x,y,z);
175

  
176
    mParent          = parent;
177
    mMesh            = mesh;
178
    mOrigPosition    = new Static3D(x,y,z);
179
    mQuatScramble    = new Static4D(0,0,0,1);
180
    mRotationAngle   = new Dynamic1D();
181
    mRotationAxis    = new Static3D(1,0,0);
182
    mCurrentPosition = position;
183
    mRotateEffect    = new MatrixEffectRotate(mRotationAngle, mRotationAxis, matrCenter);
184

  
185
    mNumAxis     = mParent.ROTATION_AXIS.length;
186
    mRotationRow = new float[mNumAxis];
187
    computeRotationRow();
188

  
189
    mEffect = new DistortedEffects();
190
    mEffect.apply( new MatrixEffectMove(vector) );
191
    mEffect.apply( new MatrixEffectQuaternion(mQuatScramble, matrCenter));
192
    mEffect.apply(mRotateEffect);
193
    mEffect.apply(mParent.mQuatAEffect);
194
    mEffect.apply(mParent.mQuatCEffect);
195
    mEffect.apply(mParent.mScaleEffect);
196

  
197
    mNode = new DistortedNode(mParent.mTexture,mEffect,mMesh);
198
    }
199

  
200 193
///////////////////////////////////////////////////////////////////////////////////////////////////
201 194

  
202 195
  void savePreferences(SharedPreferences.Editor editor)
......
357 350
      }
358 351
    }
359 352

  
360
///////////////////////////////////////////////////////////////////////////////////////////////////
361
// all DistortedTextures, DistortedNodes, DistortedFramebuffers, DistortedScreens and all types of
362
// Meshes HAVE TO be markedForDeletion when they are no longer needed- otherwise we have a major
363
// memory leak.
364

  
365
  void releaseResources()
366
    {
367
    mMesh.markForDeletion();
368
    mNode.markForDeletion();
369
    }
370

  
371 353
///////////////////////////////////////////////////////////////////////////////////////////////////
372 354

  
373 355
  void solve()
......
395 377

  
396 378
    return dx*dx + dy*dy + dz*dz;
397 379
    }
398

  
399
///////////////////////////////////////////////////////////////////////////////////////////////////
400

  
401
  int getColorIndex(int face)
402
    {
403
    Static4D texMap = mMesh.getTextureMap(face);
404
    return (int)(texMap.get0() / texMap.get2());
405
    }
406

  
407
///////////////////////////////////////////////////////////////////////////////////////////////////
408

  
409
  MeshBase getMesh()
410
    {
411
    return mMesh;
412
    }
413 380
}
src/main/java/org/distorted/objects/RubikCube.java
232 232
      mMesh.apply(effect12);
233 233
      mMesh.apply(effect13);
234 234
      mMesh.apply(effect14);
235

  
236
      mMesh.mergeEffComponents();
235 237
      }
236 238

  
237
    return mMesh.copy(false);
239
    return mMesh.copy(true);
238 240
    }
239 241

  
240 242
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/objects/RubikObject.java
25 25
import android.graphics.Paint;
26 26

  
27 27
import org.distorted.library.effect.Effect;
28
import org.distorted.library.effect.MatrixEffectMove;
28 29
import org.distorted.library.effect.MatrixEffectQuaternion;
29 30
import org.distorted.library.effect.MatrixEffectScale;
30 31
import org.distorted.library.main.DistortedEffects;
31 32
import org.distorted.library.main.DistortedNode;
32 33
import org.distorted.library.main.DistortedTexture;
33 34
import org.distorted.library.mesh.MeshBase;
35
import org.distorted.library.mesh.MeshJoined;
34 36
import org.distorted.library.mesh.MeshRectangles;
35 37
import org.distorted.library.message.EffectListener;
36 38
import org.distorted.library.type.Static1D;
......
47 49
  private static final int TEXTURE_HEIGHT = 128;
48 50
  final float[] LEGAL_QUATS;
49 51
  final Static3D[] ROTATION_AXIS;
52
  final int NUM_FACES;
50 53

  
51 54
  static float OBJECT_SCREEN_RATIO;
52 55

  
......
59 62
  private Cubit[] mCubits;
60 63
  private int mSize;
61 64
  private RubikObjectList mList;
65
  private MeshBase mMesh;
66
  private DistortedEffects mEffects;
62 67

  
63 68
  float mStart, mStep;
64 69

  
......
85 90
    NUM_CUBITS  = mOrigPos.length;
86 91
    ROTATION_AXIS = getRotationAxis();
87 92
    OBJECT_SCREEN_RATIO = getScreenRatio();
93
    NUM_FACES = getNumFaces();
88 94

  
89 95
    mSize = size;
90 96
    computeStartAndStep(mOrigPos);
......
106 112

  
107 113
    mCubits = new Cubit[NUM_CUBITS];
108 114
    mTexture = new DistortedTexture();
115
    MeshBase[] cubitMesh = new MeshBase[NUM_CUBITS];
109 116

  
110 117
    for(int i=0; i<NUM_CUBITS; i++)
111 118
      {
112
      MeshBase cubitMesh = createCubitMesh(i);
113
      mCubits[i] = new Cubit(this,cubitMesh,mOrigPos[i]);
114
      textureCubitMesh(cubitMesh,i);
115

  
116
      attach(mCubits[i].mNode);
119
      cubitMesh[i] = createCubitMesh(i);
120
      cubitMesh[i].apply(new MatrixEffectMove(mOrigPos[i]),1,0);
121
      mCubits[i] = new Cubit(this,mOrigPos[i]);
117 122
      }
118 123

  
124
    mMesh = new MeshJoined(cubitMesh);
125

  
126
    resetAllTextureMaps();
127

  
128
    mEffects = new DistortedEffects();
129
    mEffects.apply(mQuatAEffect);
130
    mEffects.apply(mQuatCEffect);
131
    mEffects.apply(mScaleEffect);
132

  
133
    attach( new DistortedNode(mTexture,mEffects,mMesh) );
134

  
119 135
    setupPosition(moves);
120 136

  
121 137
    setProjection(fov, 0.1f);
......
126 142
  private void textureCubitMesh(MeshBase mesh, int cubit)
127 143
    {
128 144
    boolean belongs;
129
    final int numFaces = getNumFaces();
130
    final Static4D[] maps = new Static4D[numFaces];
131
    final float ratio = 1.0f/(numFaces+1);
145
    final Static4D[] maps = new Static4D[NUM_FACES];
146
    final float ratio = 1.0f/(NUM_FACES+1);
132 147

  
133
    if( 2*ROTATION_AXIS.length == numFaces )  // i.e. there are faces on both ends of the axis (cube)
148
    if( 2*ROTATION_AXIS.length == NUM_FACES )  // i.e. there are faces on both ends of the axis (cube)
134 149
      {
135
      for(int i=0; i<numFaces; i++)
150
      for(int i=0; i<NUM_FACES; i++)
136 151
        {
137 152
        belongs = isOnFace(cubit, i/2, i%2==0 ? mSize-1:0 );
138
        maps[i] = new Static4D( (belongs?i:6)*ratio, 0.0f, ratio, 1.0f);
153
        maps[i] = new Static4D( (belongs?i:NUM_FACES)*ratio, 0.0f, ratio, 1.0f);
139 154
        }
140 155
      }
141
    else if( ROTATION_AXIS.length == numFaces )  // just a single face on the right end of an axis (pyraminx)
156
    else if( ROTATION_AXIS.length == NUM_FACES )  // just a single face on the right end of an axis (pyraminx)
142 157
      {
143
      for(int i=0; i<numFaces; i++)
158
      for(int i=0; i<NUM_FACES; i++)
144 159
        {
145 160
        belongs = isOnFace(cubit, i, 0 );
146
        maps[i] = new Static4D( (belongs?i:6)*ratio, 0.0f, ratio, 1.0f);
161
        maps[i] = new Static4D( (belongs?i:NUM_FACES)*ratio, 0.0f, ratio, 1.0f);
147 162
        }
148 163
      }
149 164

  
150
    mesh.setTextureMap(maps);
165
    mesh.setTextureMap(maps,NUM_FACES*cubit);
151 166
    }
152 167

  
153 168
///////////////////////////////////////////////////////////////////////////////////////////////////
......
246 261

  
247 262
  int getCubitFaceColorIndex(int cubit, int face)
248 263
    {
249
    return mCubits[cubit].getColorIndex(face);
264
    Static4D texMap = mMesh.getTextureMap(NUM_FACES*cubit + face);
265
    return (int)(texMap.get0() / texMap.get2());
250 266
    }
251 267

  
252 268
///////////////////////////////////////////////////////////////////////////////////////////////////
......
286 302
    {
287 303
    Bitmap bitmap;
288 304

  
289
    final int numColors = getNumFaces();
290

  
291 305
    Paint paint = new Paint();
292
    bitmap = Bitmap.createBitmap( (numColors+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
306
    bitmap = Bitmap.createBitmap( (NUM_FACES+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, Bitmap.Config.ARGB_8888);
293 307
    Canvas canvas = new Canvas(bitmap);
294 308

  
295 309
    paint.setAntiAlias(true);
......
297 311
    paint.setStyle(Paint.Style.FILL);
298 312

  
299 313
    paint.setColor(INTERIOR_COLOR);
300
    canvas.drawRect(0, 0, (numColors+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, paint);
314
    canvas.drawRect(0, 0, (NUM_FACES+1)*TEXTURE_HEIGHT, TEXTURE_HEIGHT, paint);
301 315

  
302
    for(int i=0; i<numColors; i++)
316
    for(int i=0; i<NUM_FACES; i++)
303 317
      {
304 318
      createFaceTexture(canvas, paint, i, i*TEXTURE_HEIGHT, 0, TEXTURE_HEIGHT);
305 319
      }
......
356 370
    {
357 371
    mTexture.markForDeletion();
358 372

  
359
    for(int i=0; i<NUM_CUBITS; i++) mCubits[i].releaseResources();
373
    // TODO ?
360 374
    }
361 375

  
362 376
///////////////////////////////////////////////////////////////////////////////////////////////////
......
400 414
    {
401 415
    for(int i=0; i<NUM_CUBITS; i++)
402 416
      {
403
      textureCubitMesh( mCubits[i].getMesh() , i );
417
      textureCubitMesh( mMesh , i );
404 418
      }
405 419
    }
406 420

  
......
408 422

  
409 423
  public void setTextureMap(int cubit, int face, int newColor)
410 424
    {
411
    final int numFaces = getNumFaces();
412
    final float ratio = 1.0f/(numFaces+1);
413
    final Static4D[] maps = new Static4D[numFaces];
425
    final float ratio = 1.0f/(NUM_FACES+1);
426
    final Static4D[] maps = new Static4D[NUM_FACES];
414 427

  
415 428
    try
416 429
      {
417 430
      maps[face] = new Static4D( newColor*ratio, 0.0f, ratio, 1.0f);
418
      mCubits[cubit].getMesh().setTextureMap(maps);
431
      mMesh.setTextureMap(maps,NUM_FACES*cubit);
419 432
      }
420 433
    catch(ArrayIndexOutOfBoundsException ignored)
421 434
      {
src/main/java/org/distorted/objects/RubikPyraminx.java
225 225
      meshes[i].setEffectAssociation(0,association,0);
226 226
      }
227 227

  
228
    Static4D[] textureMaps = new Static4D[MESHES];
229
    for(int i=0; i<MESHES; i++) textureMaps[i] = new Static4D(i*0.25f,0.0f,0.25f,1.0f);
230 228
    MeshBase result = new MeshJoined(meshes);
231
    result.setTextureMap(textureMaps);
232 229

  
233 230
    Static3D a0 = new Static3D(         0,        1,       0 );
234 231
    Static3D a1 = new Static3D(         0,  -1.0f/3, 2*SQ2/3 );
......
301 298
      result.apply( ROTATION[mRotArray[cubit]] );
302 299
      }
303 300

  
301
    result.mergeEffComponents();
302

  
304 303
    return result;
305 304
    }
306 305

  
......
313 312
    if( kind>=0 )
314 313
      {
315 314
      if( mMeshRotated[kind]==null ) mMeshRotated[kind] = createStaticMesh(cubit);
316
      return mMeshRotated[kind].copy(false);
315
      return mMeshRotated[kind].copy(true);
317 316
      }
318 317
    else
319 318
      {
320 319
      if( mMesh==null ) mMesh = createStaticMesh(cubit);
321
      return mMesh.copy(false);
320
      return mMesh.copy(true);
322 321
      }
323 322
    }
324 323

  

Also available in: Unified diff