Project

General

Profile

Download (13.6 KB) Statistics
| Branch: | Tag: | Revision:

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ 42772cff

1 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4 ffd744be Leszek Koltunski
// This file is part of Distorted.                                                               //
5 0c52af30 Leszek Koltunski
//                                                                                               //
6 ffd744be Leszek Koltunski
// Distorted is free software: you can redistribute it and/or modify                             //
7 0c52af30 Leszek Koltunski
// 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 ffd744be Leszek Koltunski
// Distorted is distributed in the hope that it will be useful,                                  //
12 0c52af30 Leszek Koltunski
// 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 ffd744be Leszek Koltunski
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.magic;
21
22
import android.opengl.GLSurfaceView;
23
24 584f7954 Leszek Koltunski
import org.distorted.effect.SizeChangeEffect;
25 2ecf0c21 Leszek Koltunski
import org.distorted.effect.SolveEffect;
26 3b12e641 Leszek Koltunski
import org.distorted.effect.ScrambleEffect;
27 0c52af30 Leszek Koltunski
import org.distorted.library.effect.VertexEffectSink;
28 9208e27b Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
29 e1111500 Leszek Koltunski
import org.distorted.library.main.DistortedLibrary;
30 0c52af30 Leszek Koltunski
import org.distorted.library.main.DistortedScreen;
31 9208e27b Leszek Koltunski
import org.distorted.library.main.DistortedTexture;
32 39fb9047 Leszek Koltunski
import org.distorted.library.mesh.MeshFlat;
33 0c52af30 Leszek Koltunski
import org.distorted.library.message.EffectListener;
34
import org.distorted.library.type.Static4D;
35
36
import javax.microedition.khronos.egl.EGLConfig;
37
import javax.microedition.khronos.opengles.GL10;
38
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40
41 9208e27b Leszek Koltunski
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
42 0c52af30 Leszek Koltunski
{
43
    private static final float CUBE_SCREEN_RATIO = 0.5f;
44
    private static final float CAMERA_DISTANCE   = 0.6f;  // 0.6 of the length of max(scrHeight,scrWidth)
45 9208e27b Leszek Koltunski
    public  static final int TEXTURE_SIZE = 600;
46 0c52af30 Leszek Koltunski
47
    private RubikSurfaceView mView;
48
    private DistortedScreen mScreen;
49
    private Static4D mQuatCurrent, mQuatAccumulated;
50
    private Static4D mTempCurrent, mTempAccumulated;
51
    private float mCubeSizeInScreenSpace;
52 3b12e641 Leszek Koltunski
    private int mNextCubeSize, mScrambleCubeNum;
53 2ecf0c21 Leszek Koltunski
    private long mRotationFinishedID, mSizeChangeEffectID, mSolveEffectID, mScrambleEffectID;
54 3b12e641 Leszek Koltunski
    private boolean mFinishRotation, mRemoveRotation, mFinishDragCurrent, mFinishDragAccumulated, mSolveCube, mScrambleCube;
55 2ecf0c21 Leszek Koltunski
    private boolean mCanRotate, mCanDrag, mCanScramble, mCanSolve;
56 434f2f5a Leszek Koltunski
    private RubikCube mOldCube, mNewCube;
57 d1484aba Leszek Koltunski
    private int mScreenWidth, mScreenHeight;
58 39fb9047 Leszek Koltunski
    private MeshFlat mMesh;
59 42772cff Leszek Koltunski
    private int[] mPos;
60
    private int[] mType;
61 9208e27b Leszek Koltunski
62 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
63
64
    RubikRenderer(RubikSurfaceView v)
65
      {
66
      mView = v;
67
68
      mScreen = new DistortedScreen();
69
70 434f2f5a Leszek Koltunski
      mOldCube = null;
71
      mNewCube = null;
72
73 0c52af30 Leszek Koltunski
      mTempCurrent     = new Static4D(0,0,0,1);
74 ee5c2ae1 Leszek Koltunski
      mTempAccumulated = new Static4D(0,0,0,1);
75 0c52af30 Leszek Koltunski
      mQuatCurrent     = new Static4D(0,0,0,1);
76 ee5c2ae1 Leszek Koltunski
      mQuatAccumulated = new Static4D(0,0,0,1);
77 0c52af30 Leszek Koltunski
78 d1484aba Leszek Koltunski
      mScreenWidth = mScreenHeight = 0;
79 3b12e641 Leszek Koltunski
      mScrambleCubeNum = 0;
80 d1484aba Leszek Koltunski
81 0c52af30 Leszek Koltunski
      mFinishRotation        = false;
82
      mRemoveRotation        = false;
83
      mFinishDragCurrent     = false;
84
      mFinishDragAccumulated = false;
85 584f7954 Leszek Koltunski
      mSolveCube             = false;
86 3b12e641 Leszek Koltunski
      mScrambleCube          = false;
87 0c52af30 Leszek Koltunski
88 2ecf0c21 Leszek Koltunski
      mCanRotate   = true;
89
      mCanDrag     = true;
90
      mCanScramble = true;
91
      mCanSolve    = true;
92 9208e27b Leszek Koltunski
93 42772cff Leszek Koltunski
      mPos  = new int[RubikSettingsEnum.LENGTH];
94
      mType = new int[RubikSettingsEnum.LENGTH];
95 3b12e641 Leszek Koltunski
96 42772cff Leszek Koltunski
      for (int i=0; i<RubikSettingsEnum.LENGTH; i++)
97
        {
98
        mPos[i] = 1000;
99
        }
100 aa8b36aa Leszek Koltunski
101 39fb9047 Leszek Koltunski
      mMesh= new MeshFlat(20,20);
102 34747dd1 Leszek Koltunski
      mNextCubeSize =RubikActivity.getSize();
103 0c52af30 Leszek Koltunski
      }
104
105
///////////////////////////////////////////////////////////////////////////////////////////////////
106
// various things are done here delayed, 'after the next render' as not to be done mid-render and
107
// cause artifacts.
108
109 aa8b36aa Leszek Koltunski
    @Override
110 0c52af30 Leszek Koltunski
    public void onDrawFrame(GL10 glUnused) 
111
      {
112
      mScreen.render( System.currentTimeMillis() );
113
114
      if( mFinishDragCurrent )
115
        {
116
        mFinishDragCurrent = false;
117
        mQuatCurrent.set(mTempCurrent);
118
        }
119
120
      if( mFinishDragAccumulated )
121
        {
122
        mFinishDragAccumulated = false;
123
        mQuatAccumulated.set(mTempAccumulated);
124
        }
125
126
      if( mFinishRotation )
127
        {
128
        mCanRotate = false;
129
        mFinishRotation=false;
130 434f2f5a Leszek Koltunski
        mRotationFinishedID = mNewCube.finishRotationNow(this);
131 0c52af30 Leszek Koltunski
        }
132
133
      if( mRemoveRotation )
134
        {
135
        mRemoveRotation=false;
136 f647630d Leszek Koltunski
        mNewCube.removeRotationNow();
137 0c52af30 Leszek Koltunski
        mCanRotate = true;
138
        }
139 34998c9d Leszek Koltunski
140
      if( mNextCubeSize!=0 )
141
        {
142
        createCubeNow(mNextCubeSize);
143 434f2f5a Leszek Koltunski
144 34747dd1 Leszek Koltunski
        mCanDrag   = false;
145
        mCanRotate = false;
146 34998c9d Leszek Koltunski
        mNextCubeSize = 0;
147 34747dd1 Leszek Koltunski
148 086a24d0 Leszek Koltunski
        sizeChangeEffect();
149 34998c9d Leszek Koltunski
        }
150 584f7954 Leszek Koltunski
151
      if( mSolveCube )
152
        {
153 2ecf0c21 Leszek Koltunski
        mSolveCube   = false;
154
        mCanDrag     = false;
155
        mCanRotate   = false;
156
        mCanScramble = false;
157
        mCanSolve    = false;
158
        solveCubeNow();
159 584f7954 Leszek Koltunski
        }
160 3b12e641 Leszek Koltunski
161
      if( mScrambleCube )
162
        {
163
        mScrambleCube = false;
164
        mCanDrag      = false;
165
        mCanRotate    = false;
166 2ecf0c21 Leszek Koltunski
        mCanScramble  = false;
167
        mCanSolve     = false;
168 3b12e641 Leszek Koltunski
        scrambleCubeNow();
169
        }
170 0c52af30 Leszek Koltunski
      }
171
172
///////////////////////////////////////////////////////////////////////////////////////////////////
173 aa8b36aa Leszek Koltunski
174
   @Override
175
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
176
      {
177
      if( mNewCube!=null ) mNewCube.createTexture();
178
179
      float cameraDistance = CAMERA_DISTANCE*(width>height ? width:height);
180
      float fovInDegrees   = computeFOV(cameraDistance,height);
181
182
      mScreen.setProjection( fovInDegrees, 0.1f);
183
      mView.setScreenSize(width,height);
184
      mView.setCameraDist(cameraDistance);
185
      mScreen.resize(width, height);
186
187
      recomputeScaleFactor(width,height);
188
189
      mScreenHeight = height;
190
      mScreenWidth  = width;
191
      }
192
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194
195
   @Override
196
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
197
      {
198
      VertexEffectSink.enable();
199 584f7954 Leszek Koltunski
      SizeChangeEffect.enableEffects();
200 3b12e641 Leszek Koltunski
      ScrambleEffect.enableEffects();
201 2ecf0c21 Leszek Koltunski
      SolveEffect.enableEffects();
202 aa8b36aa Leszek Koltunski
203
      try
204
        {
205
        DistortedLibrary.onCreate(mView.getContext());
206
        }
207
      catch(Exception ex)
208
        {
209
        android.util.Log.e("Rubik", ex.getMessage() );
210
        }
211
      }
212
213
///////////////////////////////////////////////////////////////////////////////////////////////////
214 0c52af30 Leszek Koltunski
215 f647630d Leszek Koltunski
   public void effectFinished(final long effectID)
216 0c52af30 Leszek Koltunski
     {
217 2ecf0c21 Leszek Koltunski
     if(      effectID == mRotationFinishedID )
218 434f2f5a Leszek Koltunski
       {
219
       mRemoveRotation = true;
220
       }
221 2ecf0c21 Leszek Koltunski
     else if( effectID == mSizeChangeEffectID )
222 434f2f5a Leszek Koltunski
       {
223 2ecf0c21 Leszek Koltunski
       mCanRotate   = true;
224
       mCanDrag     = true;
225 34747dd1 Leszek Koltunski
       }
226 2ecf0c21 Leszek Koltunski
     else if( effectID == mSolveEffectID )
227 584f7954 Leszek Koltunski
       {
228 2ecf0c21 Leszek Koltunski
       mCanRotate   = true;
229
       mCanDrag     = true;
230
       mCanSolve    = true;
231
       mCanScramble = true;
232 584f7954 Leszek Koltunski
       }
233 2ecf0c21 Leszek Koltunski
     else if( effectID == mScrambleEffectID   )
234 3b12e641 Leszek Koltunski
       {
235 2ecf0c21 Leszek Koltunski
       mCanRotate   = true;
236
       mCanDrag     = true;
237
       mCanSolve    = true;
238
       mCanScramble = true;
239 3b12e641 Leszek Koltunski
       }
240 34747dd1 Leszek Koltunski
     }
241 f291130e Leszek Koltunski
242 34747dd1 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
243 f291130e Leszek Koltunski
244 086a24d0 Leszek Koltunski
   private void sizeChangeEffect()
245 34747dd1 Leszek Koltunski
     {
246
     try
247
       {
248 42772cff Leszek Koltunski
       SizeChangeEffect effect = SizeChangeEffect.create(mType[0]);
249
       mSizeChangeEffectID = effect.start(mPos[0],mScreen,mOldCube,mNewCube,this);
250 34747dd1 Leszek Koltunski
       }
251
     catch(Exception ex)
252
       {
253 086a24d0 Leszek Koltunski
       android.util.Log.e("Renderer", "failed to create SizeChangeEffect, exception: "+ex.getMessage());
254 f291130e Leszek Koltunski
255 086a24d0 Leszek Koltunski
       if( mOldCube!=null ) mScreen.detach(mOldCube);
256
       mScreen.attach(mNewCube);
257
       mCanRotate = true;
258
       mCanDrag   = true;
259 434f2f5a Leszek Koltunski
       }
260 0c52af30 Leszek Koltunski
     }
261
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263 34747dd1 Leszek Koltunski
264 aa8b36aa Leszek Koltunski
   private float computeFOV(float cameraDistance, int screenHeight)
265
     {
266
     double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) );
267
     return (float)(2*halfFOVInRadians*(180/Math.PI));
268
     }
269 34747dd1 Leszek Koltunski
270 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
271
// no this will not race with onDrawFrame
272 0c52af30 Leszek Koltunski
273 aa8b36aa Leszek Koltunski
   void finishRotation()
274
     {
275
     mFinishRotation = true;
276
     }
277 0c52af30 Leszek Koltunski
278 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
279 0c52af30 Leszek Koltunski
280 42772cff Leszek Koltunski
   void setPos(int index, int pos)
281 a7012218 Leszek Koltunski
     {
282 42772cff Leszek Koltunski
     if( index>=0 && index<RubikSettingsEnum.LENGTH )  mPos[index] = pos;
283 a7012218 Leszek Koltunski
     }
284
285 3b12e641 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
286
287 42772cff Leszek Koltunski
   void setType(int index, int type)
288 3b12e641 Leszek Koltunski
     {
289 42772cff Leszek Koltunski
     if( index>=0 && index<RubikSettingsEnum.LENGTH )  mType[index] = type;
290 3b12e641 Leszek Koltunski
     }
291
292 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
293
294 f291130e Leszek Koltunski
   boolean createCube(int newSize)
295 34998c9d Leszek Koltunski
     {
296 34747dd1 Leszek Koltunski
     if( mCanDrag && mCanRotate && (mNewCube==null || newSize != mNewCube.getSize()) )
297 f291130e Leszek Koltunski
       {
298
       mNextCubeSize = newSize;
299
       return true;
300
       }
301
302
     return false;
303 34998c9d Leszek Koltunski
     }
304
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306
307 34747dd1 Leszek Koltunski
   private void createCubeNow(int newSize)
308 8197c92d Leszek Koltunski
     {
309 e56c3711 Leszek Koltunski
     if( mOldCube!=null ) mOldCube.releaseResources();
310
     mOldCube = mNewCube;
311 434f2f5a Leszek Koltunski
312 e56c3711 Leszek Koltunski
     DistortedTexture texture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
313
     DistortedEffects effects = new DistortedEffects();
314 9208e27b Leszek Koltunski
315 e56c3711 Leszek Koltunski
     mNewCube = new RubikCube(newSize, mQuatCurrent, mQuatAccumulated, texture, mMesh, effects);
316
     mNewCube.createTexture();
317 d1484aba Leszek Koltunski
318 e56c3711 Leszek Koltunski
     if( mScreenWidth!=0 )
319
       {
320
       recomputeScaleFactor(mScreenWidth,mScreenHeight);
321 8197c92d Leszek Koltunski
       }
322
     }
323 0c52af30 Leszek Koltunski
324 d1484aba Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
325
326 34998c9d Leszek Koltunski
   private void recomputeScaleFactor(int screenWidth, int screenHeight)
327 d1484aba Leszek Koltunski
     {
328
     mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(screenWidth>screenHeight ? screenHeight:screenWidth);
329 34747dd1 Leszek Koltunski
330
     if( mNewCube!=null )
331
       {
332
       mNewCube.recomputeScaleFactor(screenWidth, screenHeight, mCubeSizeInScreenSpace);
333
       }
334 d1484aba Leszek Koltunski
     }
335
336 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
337
338 f548942f Leszek Koltunski
   void scrambleCube(int num)
339 8197c92d Leszek Koltunski
     {
340 2ecf0c21 Leszek Koltunski
     if( mCanScramble )
341
       {
342
       mScrambleCube = true;
343
       mScrambleCubeNum = num;
344
       }
345 3b12e641 Leszek Koltunski
     }
346
347
///////////////////////////////////////////////////////////////////////////////////////////////////
348
349
   private void scrambleCubeNow()
350
     {
351
     try
352
       {
353 42772cff Leszek Koltunski
       ScrambleEffect effect = ScrambleEffect.create(mType[2]);
354
       mScrambleEffectID = effect.start(mPos[2],mNewCube,mScrambleCubeNum,this);
355 3b12e641 Leszek Koltunski
       }
356
     catch(Exception ex)
357
       {
358
       android.util.Log.e("Renderer", "failed to create ScrambleEffect, exception: "+ex.getMessage());
359
360
       mCanRotate = true;
361
       mCanDrag   = true;
362
       }
363 f548942f Leszek Koltunski
     }
364
365
///////////////////////////////////////////////////////////////////////////////////////////////////
366 8197c92d Leszek Koltunski
367 2ecf0c21 Leszek Koltunski
   void solveCube()
368 584f7954 Leszek Koltunski
     {
369 2ecf0c21 Leszek Koltunski
     if( mCanSolve )
370
       {
371
       mSolveCube = true;
372
       }
373 584f7954 Leszek Koltunski
     }
374
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376
377 2ecf0c21 Leszek Koltunski
   private void solveCubeNow()
378 f548942f Leszek Koltunski
     {
379 584f7954 Leszek Koltunski
     try
380
       {
381 42772cff Leszek Koltunski
       SolveEffect effect = SolveEffect.create(mType[1]);
382
       mSolveEffectID = effect.start(mPos[1],mScreen,mNewCube,this);
383 584f7954 Leszek Koltunski
       }
384
     catch(Exception ex)
385
       {
386 2ecf0c21 Leszek Koltunski
       android.util.Log.e("Renderer", "failed to create SolveEffect, exception: "+ex.getMessage());
387 584f7954 Leszek Koltunski
388 2ecf0c21 Leszek Koltunski
       mNewCube.solve();    //
389
       mCanRotate = true;   // just solve the cube
390
       mCanDrag   = true;   //
391 584f7954 Leszek Koltunski
       }
392 8197c92d Leszek Koltunski
     }
393 0c52af30 Leszek Koltunski
394
///////////////////////////////////////////////////////////////////////////////////////////////////
395
396 8197c92d Leszek Koltunski
   float returnCubeSizeInScreenSpace()
397
     {
398
     return mCubeSizeInScreenSpace;
399
     }
400
401
///////////////////////////////////////////////////////////////////////////////////////////////////
402
403
   boolean canRotate()
404
     {
405
     return mCanRotate;
406
     }
407
408 434f2f5a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
409
410
   boolean canDrag()
411
     {
412
     return mCanDrag;
413
     }
414
415 8197c92d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
416
417
   RubikCube getCube()
418
     {
419 434f2f5a Leszek Koltunski
     return mNewCube;
420 8197c92d Leszek Koltunski
     }
421 0c52af30 Leszek Koltunski
422
///////////////////////////////////////////////////////////////////////////////////////////////////
423
424 8197c92d Leszek Koltunski
   void setQuatCurrent(Static4D current)
425
     {
426
     mTempCurrent.set(current);
427
     mFinishDragCurrent = true;
428
     }
429 0c52af30 Leszek Koltunski
430
///////////////////////////////////////////////////////////////////////////////////////////////////
431
432 8197c92d Leszek Koltunski
   void setQuatAccumulated(Static4D accumulated)
433
     {
434
     mTempAccumulated.set(accumulated);
435
     mFinishDragAccumulated = true;
436
     }
437 0c52af30 Leszek Koltunski
}