Project

General

Profile

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

magiccube / src / main / java / org / distorted / magic / RubikRenderer.java @ ce0c7ca8

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