Project

General

Profile

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

magiccube / src / main / java / org / distorted / bandaged / BandagedCreatorRenderer.java @ 61a7b812

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube 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
// Magic Cube 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 Magic Cube.  If not, see <http://www.gnu.org/licenses/>.                           //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19

    
20
package org.distorted.bandaged;
21

    
22
import javax.microedition.khronos.egl.EGLConfig;
23
import javax.microedition.khronos.opengles.GL10;
24

    
25
import android.opengl.GLSurfaceView;
26

    
27
import org.distorted.dialogs.RubikDialogSaveBandaged;
28
import org.distorted.library.main.DistortedLibrary;
29
import org.distorted.library.main.DistortedNode;
30
import org.distorted.library.main.DistortedScreen;
31

    
32
import org.distorted.library.type.Static3D;
33
import org.distorted.library.type.Static4D;
34

    
35
///////////////////////////////////////////////////////////////////////////////////////////////////
36

    
37
public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, DistortedLibrary.ExceptionListener
38
{
39
   private static final int DURATION = 1000;
40

    
41
   static final int COLOR_DEFAULT = 0xffffff55;
42
   static final int COLOR_MARKED  = 0xffff0000;
43

    
44
   static final float SCREEN_RATIO = 0.5f;
45
   static final float OBJECT_SIZE  = 3.0f;
46

    
47
   private final float[][] POSITIONS = new float[][]
48
        {
49
          {-1,  1,  1},
50
          {-1,  1,  0},
51
          {-1,  1, -1},
52
          {-1,  0,  1},
53
          {-1,  0,  0},
54
          {-1,  0, -1},
55
          {-1, -1,  1},
56
          {-1, -1,  0},
57
          {-1, -1, -1},
58
          { 0, -1,  1},
59
          { 0, -1,  0},
60
          { 0,  1,  1},
61
          { 0,  1,  0},
62
          { 0,  1, -1},
63
          { 0,  0,  1},
64
          { 0,  0, -1},
65
          { 1,  1,  1},
66
          { 1,  1,  0},
67
          { 1,  1, -1},
68
          { 1,  0,  1},
69
          { 1,  0,  0},
70
          { 1, -1,  1},
71
          { 1,  0, -1},
72
          { 1, -1, -1},
73
          { 1, -1,  0},
74
          { 0, -1, -1},
75
        };
76

    
77
   private final BandagedCreatorView mView;
78
   private final DistortedScreen mScreen;
79
   private final Static3D mScale;
80
   private final BandagedCubit[] mCubits;
81
   private final Static4D mQuatT, mQuatA;
82

    
83
   private boolean mInitialPhase;
84
   private long mStartTime;
85
   private float mScaleValue;
86
   private float mX, mY, mZ, mW;
87
   private boolean mResetQuats, mSetQuatT, mResettingObject;
88

    
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90

    
91
   BandagedCreatorRenderer(BandagedCreatorView v)
92
     {
93
     final float BRIGHTNESS = 0.333f;
94

    
95
     mQuatT = new Static4D(0,0,0,1);
96
     mQuatA = new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
97

    
98
     mView = v;
99

    
100
     mResetQuats     = false;
101
     mSetQuatT       = false;
102
     mResettingObject= false;
103

    
104
     mScreen = new DistortedScreen();
105
     mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
106
     mScale = new Static3D(1,1,1);
107
     mCubits= createCubits();
108
     }
109

    
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111

    
112
   private boolean isAdjacent(float[] pos1, float[] pos2)
113
     {
114
     int len1 = pos1.length/3;
115
     int len2 = pos2.length/3;
116

    
117
     for(int i=0; i<len1; i++)
118
       for(int j=0; j<len2; j++)
119
         {
120
         float d0 = pos1[3*i  ] - pos2[3*j  ];
121
         float d1 = pos1[3*i+1] - pos2[3*j+1];
122
         float d2 = pos1[3*i+2] - pos2[3*j+2];
123

    
124
         if( d0*d0 + d1*d1 + d2*d2 == 1 ) return true;
125
         }
126

    
127
     return false;
128
     }
129

    
130
///////////////////////////////////////////////////////////////////////////////////////////////////
131

    
132
   private BandagedCubit[] createCubits()
133
     {
134
     int len = POSITIONS.length;
135
     BandagedCubit[] cubits = new BandagedCubit[len];
136

    
137
     for(int c=0; c<len; c++)
138
       {
139
       cubits[c] = new BandagedCubit(POSITIONS[c],mQuatT,mQuatA,mScale,COLOR_DEFAULT);
140
       }
141

    
142
     return cubits;
143
     }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

    
147
   private void resetObject()
148
     {
149
     mView.resetCubits();
150

    
151
     int len = POSITIONS.length;
152

    
153
     for(int c=0; c<len; c++)
154
       {
155
       if( !mCubits[c].isAttached() )
156
         {
157
         mCubits[c].attach();
158
         mScreen.attach(mCubits[c].getNode());
159
         }
160
       if( mCubits[c].getPosition().length>3 )
161
         {
162
         mCubits[c].reset(mScaleValue);
163
         }
164
       }
165
     }
166

    
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

    
169
   @Override
170
   public void onDrawFrame(GL10 glUnused)
171
     {
172
     long time = System.currentTimeMillis();
173
     mScreen.render(time);
174

    
175
     if( mSetQuatT )
176
       {
177
       mSetQuatT = false;
178
       mQuatT.set(mX,mY,mZ,mW);
179
       }
180

    
181
     if( mResetQuats )
182
       {
183
       mResetQuats = false;
184

    
185
       float qx = mQuatT.get0();
186
       float qy = mQuatT.get1();
187
       float qz = mQuatT.get2();
188
       float qw = mQuatT.get3();
189

    
190
       float rx = mQuatA.get0();
191
       float ry = mQuatA.get1();
192
       float rz = mQuatA.get2();
193
       float rw = mQuatA.get3();
194

    
195
       float tx = rw*qx - rz*qy + ry*qz + rx*qw;
196
       float ty = rw*qy + rz*qx + ry*qw - rx*qz;
197
       float tz = rw*qz + rz*qw - ry*qx + rx*qy;
198
       float tw = rw*qw - rz*qz - ry*qy - rx*qx;
199

    
200
       mQuatT.set(0f, 0f, 0f, 1f);
201
       mQuatA.set(tx, ty, tz, tw);
202
       }
203

    
204
     if( mResettingObject )
205
       {
206
       boolean done = continueResetting(time);
207
       if( done ) mResettingObject = false;
208
       }
209
     }
210

    
211
///////////////////////////////////////////////////////////////////////////////////////////////////
212

    
213
   @Override
214
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
215
      {
216
      final float Q = SCREEN_RATIO/OBJECT_SIZE;
217
      mScaleValue = width<height ? Q*width : Q*height;
218

    
219
      mScreen.detachAll();
220
      int len = POSITIONS.length;
221

    
222
      for(int i=0; i<len; i++)
223
        if( mCubits[i].isAttached() )
224
          {
225
          mCubits[i].scaleMove(mScaleValue);
226
          mCubits[i].setTexture(COLOR_DEFAULT);
227
          DistortedNode node = mCubits[i].getNode();
228
          mScreen.attach(node);
229
          }
230

    
231
      mScale.set( mScaleValue,mScaleValue,mScaleValue );
232
      mView.setScreenSize(width,height);
233
      mScreen.resize(width,height);
234
      }
235

    
236
///////////////////////////////////////////////////////////////////////////////////////////////////
237

    
238
   @Override
239
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
240
      {
241
      DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
242
      }
243

    
244
///////////////////////////////////////////////////////////////////////////////////////////////////
245

    
246
   public void distortedException(Exception ex)
247
     {
248
     android.util.Log.e("CREATOR", "unexpected exception: "+ex.getMessage() );
249
     }
250

    
251
///////////////////////////////////////////////////////////////////////////////////////////////////
252

    
253
   public BandagedCubit[] getCubits()
254
     {
255
     return mCubits;
256
     }
257

    
258
///////////////////////////////////////////////////////////////////////////////////////////////////
259

    
260
   public DistortedScreen getScreen()
261
     {
262
     return mScreen;
263
     }
264

    
265
///////////////////////////////////////////////////////////////////////////////////////////////////
266

    
267
   public void tryConnectingCubits(int index1, int index2)
268
     {
269
     if( index1!=index2 )
270
       {
271
       float[] pos1 = mCubits[index1].getPosition();
272
       float[] pos2 = mCubits[index2].getPosition();
273

    
274
       if( isAdjacent(pos1,pos2) )
275
         {
276
         mCubits[index2].join(pos1,mScaleValue);
277
         mCubits[index1].detach();
278
         mScreen.detach(mCubits[index1].getNode());
279
         }
280
       }
281
     }
282

    
283
///////////////////////////////////////////////////////////////////////////////////////////////////
284

    
285
   public Static4D getQuatAccu()
286
     {
287
     return mQuatA;
288
     }
289

    
290
///////////////////////////////////////////////////////////////////////////////////////////////////
291

    
292
   public void setQuatTemp(float x, float y, float z, float w)
293
     {
294
     mX = x;
295
     mY = y;
296
     mZ = z;
297
     mW = w;
298

    
299
     mSetQuatT = true;
300
     }
301

    
302
///////////////////////////////////////////////////////////////////////////////////////////////////
303

    
304
   public void resetQuats()
305
     {
306
     mResetQuats = true;
307
     }
308

    
309
///////////////////////////////////////////////////////////////////////////////////////////////////
310

    
311
   public boolean isBusy()
312
     {
313
     return mResettingObject;
314
     }
315

    
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317

    
318
   public void saveObject()
319
     {
320
     BandagedCreatorActivity act = (BandagedCreatorActivity)mView.getContext();
321
     RubikDialogSaveBandaged saveDiag = new RubikDialogSaveBandaged();
322
     saveDiag.show(act.getSupportFragmentManager(), null);
323
     }
324

    
325
///////////////////////////////////////////////////////////////////////////////////////////////////
326

    
327
   public void setupReset()
328
     {
329
     mResettingObject = true;
330
     mInitialPhase    = true;
331
     mStartTime       = System.currentTimeMillis();
332
     }
333

    
334
///////////////////////////////////////////////////////////////////////////////////////////////////
335

    
336
   public boolean continueResetting(long time)
337
     {
338
     long diff = time-mStartTime;
339
     float quotient = ((float)diff)/DURATION;
340

    
341
     if( mInitialPhase && quotient>0.5f )
342
       {
343
       mInitialPhase=false;
344
       resetObject();
345
       }
346

    
347
     double angle = 2*Math.PI*quotient*quotient*(3-2*quotient);
348

    
349
     float sinA = (float)Math.sin(angle);
350
     float cosA = (float)Math.cos(angle);
351

    
352
     mQuatT.set(0, -sinA, 0, cosA);
353

    
354
     return quotient>1.0f;
355
     }
356
}
(2-2/11)