Project

General

Profile

Download (12.4 KB) Statistics
| Branch: | Revision:

examples / src / main / java / org / distorted / examples / rubik / RubikCube.java @ e3900503

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of DistortedLibrary.                                                               //
5
//                                                                                               //
6
// DistortedLibrary is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// DistortedLibrary is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with DistortedLibrary.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.examples.rubik;
21

    
22
import java.util.Random;
23

    
24
import android.graphics.Bitmap;
25
import android.graphics.Canvas;
26
import android.graphics.Paint;
27

    
28
import org.distorted.library.effect.MatrixEffectMove;
29
import org.distorted.library.effect.MatrixEffectQuaternion;
30
import org.distorted.library.effect.MatrixEffectRotate;
31
import org.distorted.library.effect.MatrixEffectScale;
32
import org.distorted.library.effect.VertexEffectSink;
33
import org.distorted.library.main.DistortedEffects;
34
import org.distorted.library.main.DistortedNode;
35
import org.distorted.library.main.DistortedScreen;
36
import org.distorted.library.main.DistortedTexture;
37
import org.distorted.library.mesh.MeshCubes;
38
import org.distorted.library.message.EffectListener;
39
import org.distorted.library.type.Dynamic1D;
40
import org.distorted.library.type.Static1D;
41
import org.distorted.library.type.Static3D;
42
import org.distorted.library.type.Static4D;
43

    
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45

    
46
class RubikCube
47
{
48
    private static final int VECTX = 0;
49
    private static final int VECTY = 1;
50
    private static final int VECTZ = 2;
51

    
52
    private static final int ROTATION_MILLISEC = 1500;
53
    private static final int TEXTURE_SIZE = 100;
54

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

    
59
    private static Random mRnd = new Random(0);
60

    
61
    private DistortedNode[][][] mNodes;
62
    private MeshCubes[][][] mCubes;
63
    private DistortedEffects[][][] mEffects;
64
    private Static3D[][][] mRotationAxis;
65
    private Dynamic1D[][][] mRotationAngle;
66
    private DistortedTexture mTexture;
67
    private int mSize;
68

    
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70

    
71
    RubikCube(int size, Static3D move, Static3D scale)
72
      {
73
      mSize = size;
74

    
75
      mTexture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
76

    
77
      mNodes          = new DistortedNode[mSize][mSize][mSize];
78
      mCubes          = new MeshCubes[mSize][mSize][mSize];
79
      mEffects        = new DistortedEffects[mSize][mSize][mSize];
80
      mRotationAxis   = new Static3D[mSize][mSize][mSize];
81
      mRotationAngle  = new Dynamic1D[mSize][mSize][mSize];
82

    
83
      Static3D[][][] cubeVectors = new Static3D[mSize][mSize][mSize];
84

    
85
      Static3D center = new Static3D(TEXTURE_SIZE*0.5f, TEXTURE_SIZE*0.5f, TEXTURE_SIZE*0.5f);
86
      Static4D region = new Static4D(0,0,0, TEXTURE_SIZE*0.72f);
87

    
88
      VertexEffectSink        sinkEffect = new VertexEffectSink( new Static1D(getSinkStrength()), center, region );
89
      MatrixEffectMove        moveEffect = new MatrixEffectMove(move);
90
      MatrixEffectScale      scaleEffect = new MatrixEffectScale(scale);
91
      MatrixEffectQuaternion  quatEffect = new MatrixEffectQuaternion( initializeQuat(), center);
92

    
93
      // 3x2 bitmap = 6 squares:
94
      //
95
      // RED     GREEN   BLUE
96
      // YELLOW  WHITE   BROWN
97

    
98
      final float ze = 0.0f;
99
      final float ot = 1.0f/3.0f;
100
      final float tt = 2.0f/3.0f;
101
      final float oh = 1.0f/2.0f;
102
      final float of = 1.0f/40.0f;
103

    
104
      final Static4D mapFront = new Static4D(ze,oh, ze+ot,oh+oh);
105
      final Static4D mapBack  = new Static4D(tt,ze, tt+ot,ze+oh);
106
      final Static4D mapLeft  = new Static4D(ot,ze, ot+ot,ze+oh);
107
      final Static4D mapRight = new Static4D(ze,ze, ze+ot,ze+oh);
108
      final Static4D mapTop   = new Static4D(tt,oh, tt+ot,oh+oh);
109
      final Static4D mapBottom= new Static4D(ot,oh, ot+ot,oh+oh);
110

    
111
      final Static4D mapBlack = new Static4D(ze,ze, ze+of,ze+of);
112

    
113
      Static4D tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom;
114
      float nc = 0.5f*(mSize-1);
115
      int vertices = (int)(24.0f/mSize + 2.0f);
116

    
117
      for(int x = 0; x< mSize; x++)
118
        for(int y = 0; y< mSize; y++)
119
          for(int z = 0; z< mSize; z++)
120
            {
121
            if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 ) // only the external walls
122
              {
123
              tmpLeft  = (x==       0 ? mapLeft  :mapBlack);
124
              tmpRight = (x== mSize-1 ? mapRight :mapBlack);
125
              tmpFront = (z== mSize-1 ? mapFront :mapBlack);
126
              tmpBack  = (z==       0 ? mapBack  :mapBlack);
127
              tmpTop   = (y== mSize-1 ? mapTop   :mapBlack);
128
              tmpBottom= (y==       0 ? mapBottom:mapBlack);
129

    
130
              mCubes[x][y][z]           = new MeshCubes(vertices,vertices,vertices, tmpFront, tmpBack, tmpLeft, tmpRight, tmpTop, tmpBottom);
131
              cubeVectors[x][y][z]      = new Static3D( TEXTURE_SIZE*(x-nc), TEXTURE_SIZE*(y-nc), TEXTURE_SIZE*(z-nc) );
132
              mRotationAngle[x][y][z]   = new Dynamic1D();
133
              mRotationAxis[x][y][z]    = new Static3D(1,0,0);
134

    
135
              mRotationAngle[x][y][z].add(new Static1D(0.0f));
136
              mRotationAngle[x][y][z].add(new Static1D(0.0f));
137

    
138
              mEffects[x][y][z] = new DistortedEffects();
139
              mEffects[x][y][z].apply(sinkEffect);
140
              mEffects[x][y][z].apply(moveEffect);
141
              mEffects[x][y][z].apply(scaleEffect);
142
              mEffects[x][y][z].apply(quatEffect);
143
              mEffects[x][y][z].apply( new MatrixEffectRotate( mRotationAngle[x][y][z], mRotationAxis[x][y][z], center));
144
              mEffects[x][y][z].apply( new MatrixEffectMove(cubeVectors[x][y][z]) );
145
              }
146
            }
147
      }
148

    
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150
// Initial rotation of the cube. Something semi-random that looks good.
151

    
152
   private Static4D initializeQuat()
153
     {
154
     return new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
155
     }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
   void attachToScreen(DistortedScreen screen)
160
     {
161
     for(int x=0; x<mSize; x++)
162
       for(int y=0; y<mSize; y++)
163
         for(int z=0; z<mSize; z++)
164
           {
165
           if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
166
             {
167
             mNodes[x][y][z] = new DistortedNode(mTexture,mEffects[x][y][z],mCubes[x][y][z]);
168
             screen.attach(mNodes[x][y][z]);
169
             }
170
           }
171
     }
172

    
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174
// all DistortedTextures, DistortedNodes, DistortedFramebuffers, DistortedScreens and all types of
175
// Meshes HAVE TO be markedForDeletion when they are no longer needed- otherwise we have a major
176
// memory leak.
177

    
178
   void releaseResources()
179
     {
180
     mTexture.markForDeletion();
181

    
182
     for(int x=0; x<mSize; x++)
183
       for(int y=0; y<mSize; y++)
184
         for(int z=0; z<mSize; z++)
185
           {
186
           if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
187
             {
188
             mCubes[x][y][z].markForDeletion();
189
             mNodes[x][y][z].markForDeletion();
190
             }
191
           }
192
     }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
   void addRotation(EffectListener listener)
197
     {
198
     mRnd.setSeed(System.currentTimeMillis());
199

    
200
     int vector = mRnd.nextInt(3);
201
     int rotRow = mRnd.nextInt(mSize);
202

    
203
     boolean first = true;
204
     Static3D axis = VectX;
205

    
206
     switch(vector)
207
       {
208
       case VECTX: axis = VectX; break;
209
       case VECTY: axis = VectY; break;
210
       case VECTZ: axis = VectZ; break;
211
       }
212

    
213
     for(int x=0; x<mSize; x++)
214
       for(int y=0; y<mSize; y++)
215
         for(int z=0; z<mSize; z++)
216
           if( x==0 || x==mSize-1 || y==0 || y==mSize-1 || z==0 || z==mSize-1 )
217
             {
218
             if( belongsToRotation(x,y,z,vector,rotRow) )
219
               {
220
               mRotationAxis[x][y][z].set(axis);
221
               mRotationAngle[x][y][z].makeRunNowFor(ROTATION_MILLISEC);
222
               mRotationAngle[x][y][z].setPoint(1,90.0f);
223

    
224
               if( first )
225
                 {
226
                 first = false;
227
                 mEffects[x][y][z].registerForMessages(listener);
228
                 }
229
               }
230
             }
231
     }
232

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234

    
235
   private boolean belongsToRotation(int x, int y, int z, int vector, int row)
236
     {
237
     switch(vector)
238
       {
239
       case VECTX: return x==row;
240
       case VECTY: return y==row;
241
       case VECTZ: return z==row;
242
       }
243

    
244
     return false;
245
     }
246

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

    
249
   private float getSinkStrength()
250
     {
251
     switch(mSize)
252
       {
253
       case 1 : return 1.1f;
254
       case 2 : return 1.5f;
255
       case 3 : return 1.8f;
256
       case 4 : return 2.0f;
257
       default: return 3.0f - 4.0f/mSize;
258
       }
259
     }
260

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

    
263
   void createTexture()
264
     {
265
     Bitmap bitmap;
266

    
267
     final int S = 128;
268
     final int W = 3*S;
269
     final int H = 2*S;
270
     final int R = S/10;
271
     final int M = S/20;
272

    
273
     Paint paint = new Paint();
274
     bitmap = Bitmap.createBitmap(W,H, Bitmap.Config.ARGB_8888);
275
     Canvas canvas = new Canvas(bitmap);
276

    
277
     paint.setAntiAlias(true);
278
     paint.setTextAlign(Paint.Align.CENTER);
279
     paint.setStyle(Paint.Style.FILL);
280

    
281
     // 3x2 bitmap = 6 squares:
282
     //
283
     // RED     GREEN   BLUE
284
     // YELLOW  WHITE   BROWN
285

    
286
     paint.setColor(0xff000000);                                  // BLACK BACKGROUND
287
     canvas.drawRect(0, 0, W, H, paint);                          //
288

    
289
     paint.setColor(0xffff0000);                                  // RED
290
     canvas.drawRoundRect(    M,   M,   S-M,   S-M, R, R, paint); //
291
     paint.setColor(0xff00ff00);                                  // GREEN
292
     canvas.drawRoundRect(  S+M,   M, 2*S-M,   S-M, R, R, paint); //
293
     paint.setColor(0xff0000ff);                                  // BLUE
294
     canvas.drawRoundRect(2*S+M,   M, 3*S-M,   S-M, R, R, paint); //
295
     paint.setColor(0xffffff00);                                  // YELLOW
296
     canvas.drawRoundRect(    M, S+M,   S-M, 2*S-M, R, R, paint); //
297
     paint.setColor(0xffffffff);                                  // WHITE
298
     canvas.drawRoundRect(  S+M, S+M, 2*S-M, 2*S-M, R, R, paint); //
299
     paint.setColor(0xffb5651d);                                  // BROWN
300
     canvas.drawRoundRect(2*S+M, S+M, 3*S-M, 2*S-M, R, R, paint); //
301

    
302
     mTexture.setTexture(bitmap);
303
     }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

    
307
   float getTextureSize()
308
     {
309
     return TEXTURE_SIZE;
310
     }
311

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

    
314
   int getSize()
315
     {
316
     return mSize;
317
     }
318
}
(2-2/4)