Project

General

Profile

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

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

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 64975793 Leszek Koltunski
import org.distorted.effect.BaseEffect;
25 0c52af30 Leszek Koltunski
import org.distorted.library.effect.VertexEffectSink;
26 9208e27b Leszek Koltunski
import org.distorted.library.main.DistortedEffects;
27 e1111500 Leszek Koltunski
import org.distorted.library.main.DistortedLibrary;
28 0c52af30 Leszek Koltunski
import org.distorted.library.main.DistortedScreen;
29 9208e27b Leszek Koltunski
import org.distorted.library.main.DistortedTexture;
30 39fb9047 Leszek Koltunski
import org.distorted.library.mesh.MeshFlat;
31 0c52af30 Leszek Koltunski
import org.distorted.library.message.EffectListener;
32
import org.distorted.library.type.Static4D;
33
34
import javax.microedition.khronos.egl.EGLConfig;
35
import javax.microedition.khronos.opengles.GL10;
36
37
///////////////////////////////////////////////////////////////////////////////////////////////////
38
39 9208e27b Leszek Koltunski
public class RubikRenderer implements GLSurfaceView.Renderer, EffectListener
40 0c52af30 Leszek Koltunski
{
41
    private static final float CUBE_SCREEN_RATIO = 0.5f;
42
    private static final float CAMERA_DISTANCE   = 0.6f;  // 0.6 of the length of max(scrHeight,scrWidth)
43 9208e27b Leszek Koltunski
    public  static final int TEXTURE_SIZE = 600;
44 0c52af30 Leszek Koltunski
45
    private RubikSurfaceView mView;
46
    private DistortedScreen mScreen;
47
    private Static4D mQuatCurrent, mQuatAccumulated;
48
    private Static4D mTempCurrent, mTempAccumulated;
49
    private float mCubeSizeInScreenSpace;
50 3b12e641 Leszek Koltunski
    private int mNextCubeSize, mScrambleCubeNum;
51 64975793 Leszek Koltunski
    private long mRotationFinishedID;
52
    private long[] mEffectID;
53 3b12e641 Leszek Koltunski
    private boolean mFinishRotation, mRemoveRotation, mFinishDragCurrent, mFinishDragAccumulated, mSolveCube, mScrambleCube;
54 2ecf0c21 Leszek Koltunski
    private boolean mCanRotate, mCanDrag, mCanScramble, mCanSolve;
55 434f2f5a Leszek Koltunski
    private RubikCube mOldCube, mNewCube;
56 d1484aba Leszek Koltunski
    private int mScreenWidth, mScreenHeight;
57 39fb9047 Leszek Koltunski
    private MeshFlat mMesh;
58 9208e27b Leszek Koltunski
59 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
60
61
    RubikRenderer(RubikSurfaceView v)
62
      {
63
      mView = v;
64
65
      mScreen = new DistortedScreen();
66
67 434f2f5a Leszek Koltunski
      mOldCube = null;
68
      mNewCube = null;
69
70 0c52af30 Leszek Koltunski
      mTempCurrent     = new Static4D(0,0,0,1);
71 ee5c2ae1 Leszek Koltunski
      mTempAccumulated = new Static4D(0,0,0,1);
72 0c52af30 Leszek Koltunski
      mQuatCurrent     = new Static4D(0,0,0,1);
73 ee5c2ae1 Leszek Koltunski
      mQuatAccumulated = new Static4D(0,0,0,1);
74 0c52af30 Leszek Koltunski
75 d1484aba Leszek Koltunski
      mScreenWidth = mScreenHeight = 0;
76 3b12e641 Leszek Koltunski
      mScrambleCubeNum = 0;
77 d1484aba Leszek Koltunski
78 0c52af30 Leszek Koltunski
      mFinishRotation        = false;
79
      mRemoveRotation        = false;
80
      mFinishDragCurrent     = false;
81
      mFinishDragAccumulated = false;
82 584f7954 Leszek Koltunski
      mSolveCube             = false;
83 3b12e641 Leszek Koltunski
      mScrambleCube          = false;
84 0c52af30 Leszek Koltunski
85 2ecf0c21 Leszek Koltunski
      mCanRotate   = true;
86
      mCanDrag     = true;
87
      mCanScramble = true;
88
      mCanSolve    = true;
89 9208e27b Leszek Koltunski
90 64975793 Leszek Koltunski
      mEffectID = new long[BaseEffect.Type.LENGTH];
91
92 39fb9047 Leszek Koltunski
      mMesh= new MeshFlat(20,20);
93 34747dd1 Leszek Koltunski
      mNextCubeSize =RubikActivity.getSize();
94 0c52af30 Leszek Koltunski
      }
95
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97
// various things are done here delayed, 'after the next render' as not to be done mid-render and
98
// cause artifacts.
99
100 aa8b36aa Leszek Koltunski
    @Override
101 0c52af30 Leszek Koltunski
    public void onDrawFrame(GL10 glUnused) 
102
      {
103
      mScreen.render( System.currentTimeMillis() );
104
105
      if( mFinishDragCurrent )
106
        {
107
        mFinishDragCurrent = false;
108
        mQuatCurrent.set(mTempCurrent);
109
        }
110
111
      if( mFinishDragAccumulated )
112
        {
113
        mFinishDragAccumulated = false;
114
        mQuatAccumulated.set(mTempAccumulated);
115
        }
116
117
      if( mFinishRotation )
118
        {
119
        mCanRotate = false;
120
        mFinishRotation=false;
121 434f2f5a Leszek Koltunski
        mRotationFinishedID = mNewCube.finishRotationNow(this);
122 0c52af30 Leszek Koltunski
        }
123
124
      if( mRemoveRotation )
125
        {
126
        mRemoveRotation=false;
127 f647630d Leszek Koltunski
        mNewCube.removeRotationNow();
128 0c52af30 Leszek Koltunski
        mCanRotate = true;
129
        }
130 34998c9d Leszek Koltunski
131
      if( mNextCubeSize!=0 )
132
        {
133
        createCubeNow(mNextCubeSize);
134 34747dd1 Leszek Koltunski
        mCanDrag   = false;
135
        mCanRotate = false;
136 34998c9d Leszek Koltunski
        mNextCubeSize = 0;
137 64975793 Leszek Koltunski
        doEffectNow(0);
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 64975793 Leszek Koltunski
        doEffectNow(1);
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 64975793 Leszek Koltunski
        doEffectNow(2);
158 3b12e641 Leszek Koltunski
        }
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 64975793 Leszek Koltunski
      BaseEffect.Type.enableEffects();
189 aa8b36aa Leszek Koltunski
190
      try
191
        {
192
        DistortedLibrary.onCreate(mView.getContext());
193
        }
194
      catch(Exception ex)
195
        {
196
        android.util.Log.e("Rubik", ex.getMessage() );
197
        }
198
      }
199
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201 0c52af30 Leszek Koltunski
202 f647630d Leszek Koltunski
   public void effectFinished(final long effectID)
203 0c52af30 Leszek Koltunski
     {
204 2ecf0c21 Leszek Koltunski
     if(      effectID == mRotationFinishedID )
205 434f2f5a Leszek Koltunski
       {
206
       mRemoveRotation = true;
207
       }
208 64975793 Leszek Koltunski
     else if( effectID == mEffectID[0] )
209 434f2f5a Leszek Koltunski
       {
210 2ecf0c21 Leszek Koltunski
       mCanRotate   = true;
211
       mCanDrag     = true;
212 34747dd1 Leszek Koltunski
       }
213 64975793 Leszek Koltunski
     else if( effectID == mEffectID[1] )
214 584f7954 Leszek Koltunski
       {
215 2ecf0c21 Leszek Koltunski
       mCanRotate   = true;
216
       mCanDrag     = true;
217
       mCanSolve    = true;
218
       mCanScramble = true;
219 584f7954 Leszek Koltunski
       }
220 64975793 Leszek Koltunski
     else if( effectID == mEffectID[2] )
221 3b12e641 Leszek Koltunski
       {
222 2ecf0c21 Leszek Koltunski
       mCanRotate   = true;
223
       mCanDrag     = true;
224
       mCanSolve    = true;
225
       mCanScramble = true;
226 3b12e641 Leszek Koltunski
       }
227 34747dd1 Leszek Koltunski
     }
228 f291130e Leszek Koltunski
229 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
230 34747dd1 Leszek Koltunski
231 aa8b36aa Leszek Koltunski
   private float computeFOV(float cameraDistance, int screenHeight)
232
     {
233
     double halfFOVInRadians = Math.atan( screenHeight/(2*cameraDistance) );
234
     return (float)(2*halfFOVInRadians*(180/Math.PI));
235
     }
236 34747dd1 Leszek Koltunski
237 aa8b36aa Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
238
// no this will not race with onDrawFrame
239 0c52af30 Leszek Koltunski
240 aa8b36aa Leszek Koltunski
   void finishRotation()
241
     {
242
     mFinishRotation = true;
243
     }
244 0c52af30 Leszek Koltunski
245
///////////////////////////////////////////////////////////////////////////////////////////////////
246
247 f291130e Leszek Koltunski
   boolean createCube(int newSize)
248 34998c9d Leszek Koltunski
     {
249 34747dd1 Leszek Koltunski
     if( mCanDrag && mCanRotate && (mNewCube==null || newSize != mNewCube.getSize()) )
250 f291130e Leszek Koltunski
       {
251
       mNextCubeSize = newSize;
252
       return true;
253
       }
254
255
     return false;
256 34998c9d Leszek Koltunski
     }
257
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259
260 ce0c7ca8 Leszek Koltunski
   private void recomputeScaleFactor(int screenWidth, int screenHeight)
261 8197c92d Leszek Koltunski
     {
262 ce0c7ca8 Leszek Koltunski
     mCubeSizeInScreenSpace = CUBE_SCREEN_RATIO*(screenWidth>screenHeight ? screenHeight:screenWidth);
263 434f2f5a Leszek Koltunski
264 ce0c7ca8 Leszek Koltunski
     if( mNewCube!=null )
265
       {
266
       mNewCube.recomputeScaleFactor(screenWidth, screenHeight, mCubeSizeInScreenSpace);
267
       }
268
     }
269 9208e27b Leszek Koltunski
270 ce0c7ca8 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
271 d1484aba Leszek Koltunski
272 ce0c7ca8 Leszek Koltunski
   void scrambleCube(int num)
273
     {
274
     if( mCanScramble )
275 e56c3711 Leszek Koltunski
       {
276 ce0c7ca8 Leszek Koltunski
       mScrambleCube = true;
277
       mScrambleCubeNum = num;
278 8197c92d Leszek Koltunski
       }
279
     }
280 0c52af30 Leszek Koltunski
281 d1484aba Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
282
283 ce0c7ca8 Leszek Koltunski
   void solveCube()
284 d1484aba Leszek Koltunski
     {
285 ce0c7ca8 Leszek Koltunski
     if( mCanSolve )
286 34747dd1 Leszek Koltunski
       {
287 ce0c7ca8 Leszek Koltunski
       mSolveCube = true;
288 34747dd1 Leszek Koltunski
       }
289 d1484aba Leszek Koltunski
     }
290
291 0c52af30 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
292
293 ce0c7ca8 Leszek Koltunski
   private void createCubeNow(int newSize)
294 8197c92d Leszek Koltunski
     {
295 ce0c7ca8 Leszek Koltunski
     if( mOldCube!=null ) mOldCube.releaseResources();
296
     mOldCube = mNewCube;
297
298
     DistortedTexture texture = new DistortedTexture(TEXTURE_SIZE,TEXTURE_SIZE);
299
     DistortedEffects effects = new DistortedEffects();
300
301
     mNewCube = new RubikCube(newSize, mQuatCurrent, mQuatAccumulated, texture, mMesh, effects);
302
     mNewCube.createTexture();
303
304
     if( mScreenWidth!=0 )
305 2ecf0c21 Leszek Koltunski
       {
306 ce0c7ca8 Leszek Koltunski
       recomputeScaleFactor(mScreenWidth,mScreenHeight);
307 2ecf0c21 Leszek Koltunski
       }
308 3b12e641 Leszek Koltunski
     }
309
310
///////////////////////////////////////////////////////////////////////////////////////////////////
311
312 64975793 Leszek Koltunski
   private void doEffectNow(int index)
313 3b12e641 Leszek Koltunski
     {
314 64975793 Leszek Koltunski
     mEffectID[index] = BaseEffect.Type.getType(index).startEffect(this);
315 3b12e641 Leszek Koltunski
316 64975793 Leszek Koltunski
     if( mEffectID[index] == -1 )
317
       {
318 3b12e641 Leszek Koltunski
       mCanRotate = true;
319
       mCanDrag   = true;
320
       }
321 f548942f Leszek Koltunski
     }
322
323
///////////////////////////////////////////////////////////////////////////////////////////////////
324 8197c92d Leszek Koltunski
325 64975793 Leszek Koltunski
   float returnCubeSizeInScreenSpace()
326 584f7954 Leszek Koltunski
     {
327 64975793 Leszek Koltunski
     return mCubeSizeInScreenSpace;
328 584f7954 Leszek Koltunski
     }
329
330
///////////////////////////////////////////////////////////////////////////////////////////////////
331
332 64975793 Leszek Koltunski
   boolean canRotate()
333 f548942f Leszek Koltunski
     {
334 64975793 Leszek Koltunski
     return mCanRotate;
335
     }
336 584f7954 Leszek Koltunski
337 64975793 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
338
339
   boolean canDrag()
340
     {
341
     return mCanDrag;
342 8197c92d Leszek Koltunski
     }
343 0c52af30 Leszek Koltunski
344
///////////////////////////////////////////////////////////////////////////////////////////////////
345
346 64975793 Leszek Koltunski
   public RubikCube getCube()
347 8197c92d Leszek Koltunski
     {
348 64975793 Leszek Koltunski
     return mNewCube;
349 8197c92d Leszek Koltunski
     }
350
351
///////////////////////////////////////////////////////////////////////////////////////////////////
352
353 64975793 Leszek Koltunski
   public RubikCube getOldCube()
354 8197c92d Leszek Koltunski
     {
355 64975793 Leszek Koltunski
     return mOldCube;
356 8197c92d Leszek Koltunski
     }
357
358 434f2f5a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
359
360 64975793 Leszek Koltunski
   public DistortedScreen getScreen()
361 434f2f5a Leszek Koltunski
     {
362 64975793 Leszek Koltunski
     return mScreen;
363 434f2f5a Leszek Koltunski
     }
364
365 8197c92d Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
366
367 64975793 Leszek Koltunski
   public int getNumScrambles()
368 8197c92d Leszek Koltunski
     {
369 64975793 Leszek Koltunski
     return mScrambleCubeNum;
370 8197c92d Leszek Koltunski
     }
371 0c52af30 Leszek Koltunski
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373
374 8197c92d Leszek Koltunski
   void setQuatCurrent(Static4D current)
375
     {
376
     mTempCurrent.set(current);
377
     mFinishDragCurrent = true;
378
     }
379 0c52af30 Leszek Koltunski
380
///////////////////////////////////////////////////////////////////////////////////////////////////
381
382 8197c92d Leszek Koltunski
   void setQuatAccumulated(Static4D accumulated)
383
     {
384
     mTempAccumulated.set(accumulated);
385
     mFinishDragAccumulated = true;
386
     }
387 0c52af30 Leszek Koltunski
}