Project

General

Profile

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

magiccube / src / main / java / org / distorted / bandaged / BandagedCreatorRenderer.java @ e48ad1af

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.app.Activity;
26
import android.opengl.GLSurfaceView;
27
import android.widget.Toast;
28

    
29
import org.distorted.dialogs.RubikDialogSaveBandaged;
30
import org.distorted.library.main.DistortedLibrary;
31
import org.distorted.library.main.DistortedNode;
32
import org.distorted.library.main.DistortedScreen;
33

    
34
import org.distorted.library.type.Static3D;
35
import org.distorted.library.type.Static4D;
36
import org.distorted.objectlib.json.JsonWriter;
37
import org.distorted.objectlib.main.TwistyObject;
38
import org.distorted.objectlib.objects.TwistyBandagedGeneric;
39
import org.json.JSONException;
40

    
41
import java.io.File;
42
import java.io.FileNotFoundException;
43
import java.io.IOException;
44

    
45
///////////////////////////////////////////////////////////////////////////////////////////////////
46

    
47
public class BandagedCreatorRenderer implements GLSurfaceView.Renderer, DistortedLibrary.ExceptionListener
48
{
49
   private static final int DURATION = 1000;
50

    
51
   static final int COLOR_DEFAULT = 0xffffff55;
52
   static final int COLOR_MARKED  = 0xffff0000;
53

    
54
   static final float SCREEN_RATIO = 0.5f;
55
   static final float OBJECT_SIZE  = 3.0f;
56

    
57
   private final float[][] POSITIONS = new float[][]
58
        {
59
          {-1,  1,  1},
60
          {-1,  1,  0},
61
          {-1,  1, -1},
62
          {-1,  0,  1},
63
          {-1,  0,  0},
64
          {-1,  0, -1},
65
          {-1, -1,  1},
66
          {-1, -1,  0},
67
          {-1, -1, -1},
68
          { 0, -1,  1},
69
          { 0, -1,  0},
70
          { 0,  1,  1},
71
          { 0,  1,  0},
72
          { 0,  1, -1},
73
          { 0,  0,  1},
74
          { 0,  0, -1},
75
          { 1,  1,  1},
76
          { 1,  1,  0},
77
          { 1,  1, -1},
78
          { 1,  0,  1},
79
          { 1,  0,  0},
80
          { 1, -1,  1},
81
          { 1,  0, -1},
82
          { 1, -1, -1},
83
          { 1, -1,  0},
84
          { 0, -1, -1},
85
        };
86

    
87
   private final BandagedCreatorView mView;
88
   private final DistortedScreen mScreen;
89
   private final Static3D mScale;
90
   private final BandagedCubit[] mCubits;
91
   private final Static4D mQuatT, mQuatA;
92

    
93
   private boolean mInitialPhase;
94
   private long mStartTime;
95
   private float mScaleValue;
96
   private float mX, mY, mZ, mW;
97
   private boolean mResetQuats, mSetQuatT, mResettingObject;
98

    
99
///////////////////////////////////////////////////////////////////////////////////////////////////
100

    
101
   BandagedCreatorRenderer(BandagedCreatorView v)
102
     {
103
     final float BRIGHTNESS = 0.333f;
104

    
105
     mQuatT = new Static4D(0,0,0,1);
106
     mQuatA = new Static4D(-0.25189602f,0.3546389f,0.009657208f,0.90038127f);
107

    
108
     mView = v;
109

    
110
     mResetQuats     = false;
111
     mSetQuatT       = false;
112
     mResettingObject= false;
113

    
114
     mScreen = new DistortedScreen();
115
     mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
116
     mScale = new Static3D(1,1,1);
117
     mCubits= createCubits();
118
     }
119

    
120
///////////////////////////////////////////////////////////////////////////////////////////////////
121

    
122
   private boolean isAdjacent(float[] pos1, float[] pos2)
123
     {
124
     int len1 = pos1.length/3;
125
     int len2 = pos2.length/3;
126

    
127
     for(int i=0; i<len1; i++)
128
       for(int j=0; j<len2; j++)
129
         {
130
         float d0 = pos1[3*i  ] - pos2[3*j  ];
131
         float d1 = pos1[3*i+1] - pos2[3*j+1];
132
         float d2 = pos1[3*i+2] - pos2[3*j+2];
133

    
134
         if( d0*d0 + d1*d1 + d2*d2 == 1 ) return true;
135
         }
136

    
137
     return false;
138
     }
139

    
140
///////////////////////////////////////////////////////////////////////////////////////////////////
141

    
142
   private BandagedCubit[] createCubits()
143
     {
144
     int len = POSITIONS.length;
145
     BandagedCubit[] cubits = new BandagedCubit[len];
146

    
147
     for(int c=0; c<len; c++)
148
       {
149
       cubits[c] = new BandagedCubit(POSITIONS[c],mQuatT,mQuatA,mScale,COLOR_DEFAULT);
150
       }
151

    
152
     return cubits;
153
     }
154

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156

    
157
   private void resetObject()
158
     {
159
     mView.resetCubits();
160

    
161
     int len = POSITIONS.length;
162

    
163
     for(int c=0; c<len; c++)
164
       {
165
       if( !mCubits[c].isAttached() )
166
         {
167
         mCubits[c].attach();
168
         mScreen.attach(mCubits[c].getNode());
169
         }
170
       if( mCubits[c].getPosition().length>3 )
171
         {
172
         mCubits[c].reset(mScaleValue);
173
         }
174
       }
175
     }
176

    
177
///////////////////////////////////////////////////////////////////////////////////////////////////
178

    
179
   @Override
180
   public void onDrawFrame(GL10 glUnused)
181
     {
182
     long time = System.currentTimeMillis();
183
     mScreen.render(time);
184

    
185
     if( mSetQuatT )
186
       {
187
       mSetQuatT = false;
188
       mQuatT.set(mX,mY,mZ,mW);
189
       }
190

    
191
     if( mResetQuats )
192
       {
193
       mResetQuats = false;
194

    
195
       float qx = mQuatT.get0();
196
       float qy = mQuatT.get1();
197
       float qz = mQuatT.get2();
198
       float qw = mQuatT.get3();
199

    
200
       float rx = mQuatA.get0();
201
       float ry = mQuatA.get1();
202
       float rz = mQuatA.get2();
203
       float rw = mQuatA.get3();
204

    
205
       float tx = rw*qx - rz*qy + ry*qz + rx*qw;
206
       float ty = rw*qy + rz*qx + ry*qw - rx*qz;
207
       float tz = rw*qz + rz*qw - ry*qx + rx*qy;
208
       float tw = rw*qw - rz*qz - ry*qy - rx*qx;
209

    
210
       mQuatT.set(0f, 0f, 0f, 1f);
211
       mQuatA.set(tx, ty, tz, tw);
212
       }
213

    
214
     if( mResettingObject )
215
       {
216
       boolean done = continueResetting(time);
217
       if( done ) mResettingObject = false;
218
       }
219
     }
220

    
221
///////////////////////////////////////////////////////////////////////////////////////////////////
222

    
223
   @Override
224
   public void onSurfaceChanged(GL10 glUnused, int width, int height)
225
      {
226
      final float Q = SCREEN_RATIO/OBJECT_SIZE;
227
      mScaleValue = width<height ? Q*width : Q*height;
228

    
229
      mScreen.detachAll();
230
      int len = POSITIONS.length;
231

    
232
      for(int i=0; i<len; i++)
233
        if( mCubits[i].isAttached() )
234
          {
235
          mCubits[i].scaleMove(mScaleValue);
236
          mCubits[i].setTexture(COLOR_DEFAULT);
237
          DistortedNode node = mCubits[i].getNode();
238
          mScreen.attach(node);
239
          }
240

    
241
      mScale.set( mScaleValue,mScaleValue,mScaleValue );
242
      mView.setScreenSize(width,height);
243
      mScreen.resize(width,height);
244
      }
245

    
246
///////////////////////////////////////////////////////////////////////////////////////////////////
247

    
248
   @Override
249
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
250
      {
251
      DistortedLibrary.onSurfaceCreated(mView.getContext(),this,1);
252
      }
253

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

    
256
   public void distortedException(Exception ex)
257
     {
258
     android.util.Log.e("CREATOR", "unexpected exception: "+ex.getMessage() );
259
     }
260

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

    
263
   public BandagedCubit[] getCubits()
264
     {
265
     return mCubits;
266
     }
267

    
268
///////////////////////////////////////////////////////////////////////////////////////////////////
269

    
270
   public DistortedScreen getScreen()
271
     {
272
     return mScreen;
273
     }
274

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

    
277
   public void tryConnectingCubits(int index1, int index2)
278
     {
279
     if( index1!=index2 )
280
       {
281
       float[] pos1 = mCubits[index1].getPosition();
282
       float[] pos2 = mCubits[index2].getPosition();
283

    
284
       if( isAdjacent(pos1,pos2) )
285
         {
286
         mCubits[index2].join(pos1,mScaleValue);
287
         mCubits[index1].detach();
288
         mScreen.detach(mCubits[index1].getNode());
289
         }
290
       }
291
     }
292

    
293
///////////////////////////////////////////////////////////////////////////////////////////////////
294

    
295
   public Static4D getQuatAccu()
296
     {
297
     return mQuatA;
298
     }
299

    
300
///////////////////////////////////////////////////////////////////////////////////////////////////
301

    
302
   public void setQuatTemp(float x, float y, float z, float w)
303
     {
304
     mX = x;
305
     mY = y;
306
     mZ = z;
307
     mW = w;
308

    
309
     mSetQuatT = true;
310
     }
311

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

    
314
   public void resetQuats()
315
     {
316
     mResetQuats = true;
317
     }
318

    
319
///////////////////////////////////////////////////////////////////////////////////////////////////
320

    
321
   public boolean isBusy()
322
     {
323
     return mResettingObject;
324
     }
325

    
326
///////////////////////////////////////////////////////////////////////////////////////////////////
327

    
328
   public void saveObject()
329
     {
330
     int len = POSITIONS.length;
331
     int numAttached=0;
332

    
333
     for(int i=0; i<len; i++)
334
       if( mCubits[i].isAttached() ) numAttached++;
335

    
336
     float[][] pos = new float[numAttached][];
337
     int attached=0;
338

    
339
     for(int i=0; i<len; i++)
340
       if( mCubits[i].isAttached() )
341
         {
342
         pos[attached++] = mCubits[i].getPosition();
343
         }
344

    
345
     TwistyBandagedGeneric.setPositions(pos);
346
     TwistyObject obj = new TwistyBandagedGeneric();
347
     BandagedCreatorActivity act = (BandagedCreatorActivity) mView.getContext();
348

    
349
     boolean success = createObjectJson(obj,act);
350

    
351
     if( success )
352
       {
353
       act.addObject(obj.getShortName());
354
       }
355
     }
356

    
357
///////////////////////////////////////////////////////////////////////////////////////////////////
358

    
359
   private boolean createObjectJson(TwistyObject object, Activity act)
360
     {
361
     final String name = object.getShortName()+"_object.json";
362
     File file = new File(act.getFilesDir(), name);
363
     String filename = file.getAbsolutePath();
364

    
365
     try
366
       {
367
       JsonWriter writer = JsonWriter.getInstance();
368
       String json = writer.createObjectString(object,24);
369
       writer.write(filename,json);
370
       return true;
371
       }
372
     catch(JSONException ex)
373
       {
374
       act.runOnUiThread(new Runnable()
375
         {
376
         public void run()
377
           {
378
           String message = "JSON Exception saving to \n\n"+filename+"\n\n failed:\n\n"+ex.getMessage();
379
           Toast.makeText(act,message,Toast.LENGTH_LONG).show();
380
           }
381
         });
382

    
383
       return false;
384
       }
385
     catch(FileNotFoundException ex)
386
       {
387
       act.runOnUiThread(new Runnable()
388
         {
389
         public void run()
390
           {
391
           String message = "FileNotFound exception saving to \n\n"+filename+"\n\n failed:\n\n"+ex.getMessage();
392
           Toast.makeText(act,message,Toast.LENGTH_LONG).show();
393
           }
394
         });
395

    
396
       return false;
397
       }
398
     catch(IOException ex)
399
       {
400
       act.runOnUiThread(new Runnable()
401
         {
402
         public void run()
403
           {
404
           String message = "IO exception saving to \n\n"+filename+"\n\n failed:\n\n"+ex.getMessage();
405
           Toast.makeText(act,message,Toast.LENGTH_LONG).show();
406
           }
407
         });
408

    
409
       return false;
410
       }
411
     }
412

    
413
///////////////////////////////////////////////////////////////////////////////////////////////////
414
/*
415
   private void createIcon(TwistyObject object)
416
     {
417
     if( !mIconActive )
418
       {
419
       mIconActive = true;
420

    
421
       ObjectControl control = getControl();
422
       DistortedEffects effects = object.getObjectEffects();
423

    
424
       Static4D defRot = ShapeHexahedron.DEFAULT_ROT;
425
       Static1D halo = new Static1D(5);
426
       control.rotateNow(defRot);
427
       float scale = 1.15f;
428
       control.scaleNow(scale);
429
       Static4D color = new Static4D(0,0,0,1);
430
       PostprocessEffectBorder border = new PostprocessEffectBorder(halo,color);
431
       border.setHaloDepth(false);
432
       effects.apply(border);
433
       String objectName = object.getShortName();
434
       final String name = STORAGE+objectName+".png";
435
       renderer.setSaveIcon(name);
436
       }
437
     }
438
*/
439
///////////////////////////////////////////////////////////////////////////////////////////////////
440

    
441
   public void displaySavingDialog()
442
     {
443
     BandagedCreatorActivity act = (BandagedCreatorActivity)mView.getContext();
444
     RubikDialogSaveBandaged saveDiag = new RubikDialogSaveBandaged();
445
     saveDiag.show(act.getSupportFragmentManager(), null);
446
     }
447

    
448
///////////////////////////////////////////////////////////////////////////////////////////////////
449

    
450
   public void setupReset()
451
     {
452
     mResettingObject = true;
453
     mInitialPhase    = true;
454
     mStartTime       = System.currentTimeMillis();
455
     }
456

    
457
///////////////////////////////////////////////////////////////////////////////////////////////////
458

    
459
   public boolean continueResetting(long time)
460
     {
461
     long diff = time-mStartTime;
462
     float quotient = ((float)diff)/DURATION;
463

    
464
     if( mInitialPhase && quotient>0.5f )
465
       {
466
       mInitialPhase=false;
467
       resetObject();
468
       }
469

    
470
     double angle = 2*Math.PI*quotient*quotient*(3-2*quotient);
471

    
472
     float sinA = (float)Math.sin(angle);
473
     float cosA = (float)Math.cos(angle);
474

    
475
     mQuatT.set(0, -sinA, 0, cosA);
476

    
477
     return quotient>1.0f;
478
     }
479
}
(3-3/12)