Project

General

Profile

« Previous | Next » 

Revision f404152d

Added by Leszek Koltunski 12 months ago

Introduce 'BandagedObject' - an abstraction and a step towards creator of Bandaged Pyraminxes.

View differences:

src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java
20 20
import javax.microedition.khronos.opengles.GL10;
21 21

  
22 22
import android.app.Activity;
23
import android.app.ActivityManager;
24
import android.content.Context;
25
import android.content.pm.ConfigurationInfo;
26 23
import android.content.res.Resources;
27 24
import android.opengl.GLES31;
28 25
import android.opengl.GLSurfaceView;
......
43 40
import org.distorted.library.type.Static3D;
44 41
import org.distorted.library.type.Static4D;
45 42
import org.distorted.objectlib.json.JsonWriter;
46
import org.distorted.objectlib.main.InitData;
47
import org.distorted.objectlib.shape.ShapeHexahedron;
48 43
import org.distorted.objectlib.main.TwistyObject;
49
import org.distorted.objectlib.objects.TwistyBandagedCuboid;
44

  
50 45
import org.json.JSONException;
51 46

  
52 47
///////////////////////////////////////////////////////////////////////////////////////////////////
......
64 59
   private final DistortedScreen mScreen;
65 60
   private final Static3D mScale;
66 61
   private final Static4D mQuatT, mQuatA;
67
   private final int[] mObjSize;
62
   private final BandagedObject mObject;
68 63

  
69
   private BandagedCubit[] mCubits;
70 64
   private boolean mInitialPhase;
71 65
   private long mStartTime;
72 66
   private float mQuatX, mQuatY, mQuatZ, mQuatW;
73
   private int mX, mY, mZ, mNumCubits;
74 67
   private boolean mResetQuats, mSetQuatT, mResettingObject, mConnectingCubits, mCreatingCubits, mRescaling;
75 68
   private int mIndex1, mIndex2;
76 69
   private int mSaveIcon;
......
100 93

  
101 94
     mObjectScreenRatio= INIT_RATIO;
102 95
     mSaveIcon = -1;
103
     mObjSize  = new int[3];
104 96

  
105 97
     mScreen = new DistortedScreen();
106 98
     mScreen.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
107 99
     mScale = new Static3D(1,1,1);
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 int computeNumCubits(int x, int y, int z)
133
     {
134
     return ( x<=1 || y<=1 || z<=1 ) ? x*y*z : x*y*z-(x-2)*(y-2)*(z-2);
135
     }
136

  
137
///////////////////////////////////////////////////////////////////////////////////////////////////
138

  
139
   private void createCubits()
140
     {
141
     mCubits = new BandagedCubit[mNumCubits];
142
     int c=0;
143

  
144
     float begX = 0.5f*(1-mX);
145
     float begY = 0.5f*(1-mY);
146
     float begZ = 0.5f*(1-mZ);
147

  
148
     for(int x=0; x<mX; x++)
149
       for(int y=0; y<mY; y++)
150
          for(int z=0; z<mZ; z++)
151
            if( x==0 || x==mX-1 || y==0 || y==mY-1 || z==0 || z==mZ-1 )
152
              {
153
              float[] pos = new float[] { begX+x,begY+y,begZ+z };
154
              mCubits[c] = new BandagedCubit(pos,mX,mY,mZ,mQuatT,mQuatA,mScale,false);
155
              c++;
156
              }
157

  
158
     mView.setCubits(mCubits,mX,mY,mZ);
159
     }
160

  
161
///////////////////////////////////////////////////////////////////////////////////////////////////
162

  
163
   private void resetObject()
164
     {
165
     mView.resetCubits();
166

  
167
     for(int c=0; c<mNumCubits; c++)
168
       {
169
       if( !mCubits[c].isAttached() )
170
         {
171
         mCubits[c].attach();
172
         mScreen.attach(mCubits[c].getNode());
173
         }
174
       if( mCubits[c].getPosition().length>3 )
175
         {
176
         mCubits[c].reset(mScaleValue);
177
         }
178
       mCubits[c].setUnmarked();
179
       }
100
     mObject = new BandagedObject(mScreen);
180 101
     }
181 102

  
182 103
///////////////////////////////////////////////////////////////////////////////////////////////////
......
236 157
     if( mConnectingCubits )
237 158
       {
238 159
       mConnectingCubits = false;
239
       tryConnectingCubits(mIndex1,mIndex2);
160
       mObject.tryConnectingCubits(mIndex1,mIndex2,mScaleValue);
240 161
       }
241 162

  
242 163
     if( mCreatingCubits )
243 164
       {
244 165
       mCreatingCubits = false;
245

  
246 166
       rescaleObject();
247 167

  
248 168
       if( mCubitsCreated )
249 169
         {
250
         createCubits();
251

  
170
         mObject.createCubits(mQuatT,mQuatA,mScale);
171
         float[] dist = mObject.getDist3D();
172
         BandagedCreatorTouchControl control = mView.getTouchControl();
173
         control.setDist3D(dist);
252 174
         mScreen.detachAll();
253 175
         mView.resetCubits();
254

  
255
         for(int i=0; i<mNumCubits; i++)
256
           {
257
           mCubits[i].scaleMove(mScaleValue);
258
           DistortedNode node = mCubits[i].getNode();
259
           mScreen.attach(node);
260
           }
176
         mObject.attachCubits(mScaleValue);
261 177
         }
262 178
       }
263 179

  
......
265 181
       {
266 182
       mRescaling = false;
267 183
       rescaleObject();
268
       for(int i=0; i<mNumCubits; i++) mCubits[i].scaleMove(mScaleValue);
184
       mObject.scaleCubits(mScaleValue);
269 185
       BandagedCreatorTouchControl control = mView.getTouchControl();
270 186
       control.setObjectRatio(mObjectScreenRatio);
271 187
       }
......
281 197
        mWidth = width;
282 198
        mHeight= height;
283 199
        rescaleObject();
284

  
285 200
        mScreen.detachAll();
286 201
        int touched = mView.getTouched();
287

  
288
        for(int i=0; i<mNumCubits; i++)
289
          if( mCubits[i].isAttached() )
290
            {
291
            mCubits[i].scaleMove(mScaleValue);
292
            if( touched==i ) mCubits[i].setMarked();
293
            else             mCubits[i].setUnmarked();
294
            DistortedNode node = mCubits[i].getNode();
295
            mScreen.attach(node);
296
            }
297

  
202
        mObject.attachAndMarkCubits(mScaleValue,touched);
298 203
        mView.setScreenSize(width,height);
299 204
        mScreen.resize(width,height);
300 205
        }
......
306 211
   public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
307 212
      {
308 213
      DistortedLibrary.setMax(EffectType.VERTEX,0);
309
      MeshBase.setMaxEffComponents(120);
310

  
214
      MeshBase.setMaxEffComponents(120); // what?
311 215
      FragmentEffectBrightness.enable();
312

  
313 216
      DistortedLibrary.onSurfaceCreated(this,1);
314 217
      DistortedLibrary.setCull(true);
315

  
316
      if( mCubits==null )
317
        {
318
        createCubits();
319
        }
320
      else
321
        {
322
        for(int i=0; i<mNumCubits; i++) mCubits[i].recreateBitmap();
323
        }
324

  
218
      mObject.recreateCubits(mQuatT,mQuatA,mScale);
325 219
      mCubitsCreated = true;
326 220
      mWidth = 0;
327 221
      mHeight= 0;
......
343 237
     mConnectingCubits = true;
344 238
     }
345 239

  
346
///////////////////////////////////////////////////////////////////////////////////////////////////
347

  
348
   private void tryConnectingCubits(int index1, int index2)
349
     {
350
     if( index1!=index2 )
351
       {
352
       float[] pos1 = mCubits[index1].getPosition();
353
       float[] pos2 = mCubits[index2].getPosition();
354

  
355
       if( isAdjacent(pos1,pos2) )
356
         {
357
         mCubits[index2].join(pos1,mScaleValue);
358
         mCubits[index1].detach();
359
         mScreen.detach(mCubits[index1].getNode());
360
         }
361
       }
362
     }
363

  
364 240
///////////////////////////////////////////////////////////////////////////////////////////////////
365 241

  
366 242
   public Static4D getQuatAccu()
......
400 276

  
401 277
   public void saveObject()
402 278
     {
403
     int numAttached=0;
404

  
405
     for(int i=0; i<mNumCubits; i++)
406
       if( mCubits[i].isAttached() ) numAttached++;
407

  
408
     float[][] pos = new float[numAttached][];
409
     int attached=0;
410

  
411
     for(int i=0; i<mNumCubits; i++)
412
       if( mCubits[i].isAttached() )
413
         {
414
         pos[attached++] = mCubits[i].getPosition();
415
         }
416

  
417
     InitData data = new InitData(mObjSize,pos);
418
     TwistyObject obj = new TwistyBandagedCuboid( TwistyObject.MESH_NICE, TwistyObject.MODE_NORM,
419
                                                  new Static4D(0,0,0,1), new Static3D(0,0,0), 1.0f, data, null );
279
     TwistyObject obj = mObject.createObject(TwistyObject.MODE_NORM, 1.0f );
420 280
     String name = obj.getShortName();
421 281
     BandagedCreatorActivity act = (BandagedCreatorActivity) mView.getContext();
422 282

  
423 283
     if( act.objectDoesntExist(name) && createObjectJson(obj,act) )
424 284
       {
425
       setupIconCreation(act,data);
285
       setupIconCreation(act);
426 286
       act.addObject(obj.getShortName());
427 287
       }
428 288
     }
......
485 345

  
486 346
///////////////////////////////////////////////////////////////////////////////////////////////////
487 347

  
488
   private int computeProjectionAngle()
489
     {
490
     float quot1 = mObjSize[2]/ (float)mObjSize[0];
491
     float quot2 = mObjSize[2]/ (float)mObjSize[1];
492
     float quot3 = mObjSize[0]/ (float)mObjSize[2];
493
     float quot4 = mObjSize[0]/ (float)mObjSize[1];
494

  
495
     float quot5 = Math.max(quot1,quot2);
496
     float quot6 = Math.max(quot3,quot4);
497
     float quot7 = Math.max(quot5,quot6);
498

  
499
          if( quot7<=1.0f ) return 120;
500
     else if( quot7<=1.5f ) return 90;
501
     else if( quot7<=2.0f ) return 60;
502
     else                   return 30;
503
     }
504

  
505
///////////////////////////////////////////////////////////////////////////////////////////////////
506

  
507
   private void setupIconCreation(Activity act, InitData data)
348
   private void setupIconCreation(Activity act)
508 349
     {
509 350
     final float R=1.0f;
510 351
     final int FBO_WIDTH  = (int)(R*720);
511 352
     final int FBO_HEIGHT = (int)(R*1280);
512 353
     final float OBJECT_SIZE = R*0.35f;
513 354

  
514
     TwistyObject obj = new TwistyBandagedCuboid( TwistyObject.MESH_NICE, TwistyObject.MODE_ICON,
515
                                                  ShapeHexahedron.DEFAULT_ROT, new Static3D(0,0,0), OBJECT_SIZE, data, null );
516

  
355
     TwistyObject obj = mObject.createObject(TwistyObject.MODE_ICON, OBJECT_SIZE );
517 356
     DistortedEffects effects = obj.getObjectEffects();
518 357
     DistortedNode node = obj.getNode();
519 358

  
......
523 362
       mFramebuffer.glClearColor(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS, 1.0f);
524 363
       }
525 364

  
526
     mFramebuffer.setProjection( computeProjectionAngle() ,0.1f);
365
     mFramebuffer.setProjection( mObject.computeProjectionAngle() ,0.1f);
527 366
     mFramebuffer.detachAll();
528 367
     mFramebuffer.attach(node);
529 368

  
......
590 429

  
591 430
   private void rescaleObject()
592 431
     {
593
     final int size = mX>mY ? Math.max(mX, mZ) : Math.max(mY, mZ);
432
     float size = mObject.getSize();
594 433
     final float Q = mObjectScreenRatio/size;
595 434
     mScaleValue = mWidth<mHeight ? Q*mWidth : Q*mHeight;
596 435
     mScale.set( mScaleValue,mScaleValue,mScaleValue );
......
600 439

  
601 440
   public void changeObject(int x, int y, int z)
602 441
     {
603
     if( mX!=x || mY!=y || mZ!=z )
604
       {
605
       mX = x;
606
       mY = y;
607
       mZ = z;
608

  
609
       mObjSize[0] = mX;
610
       mObjSize[1] = mY;
611
       mObjSize[2] = mZ;
612

  
613
       mNumCubits = computeNumCubits(mX,mY,mZ);
614

  
615
       mCreatingCubits = true;
616
       }
442
     if( mObject.tryChangeObject(x,y,z) ) mCreatingCubits = true;
617 443
     }
618 444

  
619 445
///////////////////////////////////////////////////////////////////////////////////////////////////
......
644 470
     if( mInitialPhase && quotient>0.5f )
645 471
       {
646 472
       mInitialPhase=false;
647
       resetObject();
473
       mView.resetCubits();
474
       mObject.resetObject(mScaleValue);
648 475
       }
649 476

  
650 477
     double angle = 2*Math.PI*quotient*quotient*(3-2*quotient);
......
661 488

  
662 489
  public void touchCubit(int index)
663 490
    {
664
    if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setMarked();
491
    mObject.touchCubit(index);
665 492
    }
666 493

  
667 494
///////////////////////////////////////////////////////////////////////////////////////////////////
668 495

  
669 496
  public void untouchCubit(int index)
670 497
    {
671
    if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setUnmarked();
498
    mObject.untouchCubit(index);
499
    }
500

  
501
///////////////////////////////////////////////////////////////////////////////////////////////////
502

  
503
  public BandagedCreatorTouchControl createTouchControl()
504
    {
505
    return new BandagedCreatorTouchControl( getObjectRatio() , mScreen.getFOV(), mObject );
672 506
    }
673 507

  
674 508
///////////////////////////////////////////////////////////////////////////////////////////////////
src/main/java/org/distorted/bandaged/BandagedCreatorScreen.java
12 12
import java.lang.ref.WeakReference;
13 13
import java.util.ArrayList;
14 14

  
15
import android.annotation.SuppressLint;
15 16
import android.app.Activity;
16 17
import android.content.SharedPreferences;
17 18
import android.graphics.Bitmap;
......
124 125
    return ret;
125 126
    }
126 127

  
127

  
128 128
///////////////////////////////////////////////////////////////////////////////////////////////////
129 129

  
130 130
  private void changeObject()
......
319 319

  
320 320
///////////////////////////////////////////////////////////////////////////////////////////////////
321 321

  
322
    @SuppressLint("SuspiciousIndentation")
322 323
    @Override
323 324
    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id)
324 325
      {
src/main/java/org/distorted/bandaged/BandagedCreatorTouchControl.java
12 12
import org.distorted.library.helpers.QuatHelper;
13 13
import org.distorted.library.type.Static3D;
14 14
import org.distorted.library.type.Static4D;
15
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
16 15

  
17 16
///////////////////////////////////////////////////////////////////////////////////////////////////
18 17

  
19 18
public class BandagedCreatorTouchControl
20 19
{
21
  private static final float DIST2D = 0.5f;
22

  
20
  private final BandagedObject mObject;
23 21
  private final Static4D CAMERA_POINT;
24
  private final float[] mPoint, mCamera, mTouch, mPos;
22
  private final float[] mPoint, mCamera, mTouch;
25 23
  private final float[] mPoint2D;
26 24
  private float mObjectRatio;
27 25
  private final Static3D[] mFaceAxis;
28
  private final float[] mDist3D;
29 26

  
30
  private BandagedCubit[] mCubits;
31
  private int mNumCubits;
27
  private float[] mDist3D;
32 28
  private int mLastTouchedFace;
33
  private float mX, mY, mZ, mMax;
34

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

  
37
  private boolean isInsideFace(int face, float[] p)
38
    {
39
    return ( p[0]<=DIST2D && p[0]>=-DIST2D && p[1]<=DIST2D && p[1]>=-DIST2D );
40
    }
41 29

  
42 30
///////////////////////////////////////////////////////////////////////////////////////////////////
43 31
// Convert the 3D point3D into a 2D point on the same face surface, but in a different
......
118 106
      }
119 107
    }
120 108

  
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

  
123
  private void stretchPoint(int face, float[] output)
124
    {
125
    switch(face/2)
126
      {
127
      case 0: output[0] *= (mMax/mZ); output[1] *= (mMax/mY); break;
128
      case 1: output[0] *= (mMax/mX); output[1] *= (mMax/mZ); break;
129
      case 2: output[0] *= (mMax/mX); output[1] *= (mMax/mY); break;
130
      }
131
    }
132

  
133 109
///////////////////////////////////////////////////////////////////////////////////////////////////
134 110

  
135 111
  private boolean faceIsVisible(int face)
......
162 138
        float az = mFaceAxis[mLastTouchedFace].get2();
163 139

  
164 140
        convertTo2Dcoords(mTouch, ax,ay,az, mPoint2D);
165
        stretchPoint(mLastTouchedFace,mPoint2D);
166
        if( isInsideFace(mLastTouchedFace,mPoint2D) ) return true;
141
        mObject.stretchPoint(mLastTouchedFace,mPoint2D);
142
        if( mObject.isInsideFace(mLastTouchedFace,mPoint2D) ) return true;
167 143
        }
168 144
      }
169 145

  
170 146
    return false;
171 147
    }
172 148

  
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

  
175
  private void computePosition(int face, float pointX, float pointY)
176
    {
177
    switch(face)
178
      {
179
      case 0: mPos[0] = (mX-1)/2;
180
              mPos[1] = (int)(+mY*pointY+mY/2)-(mY-1)/2;
181
              mPos[2] = (int)(-mZ*pointX-mZ/2)+(mZ-1)/2;
182
              break;
183
      case 1: mPos[0] =-(mX-1)/2;
184
              mPos[1] = (int)(+mY*pointY+mY/2)-(mY-1)/2;
185
              mPos[2] = (int)(+mZ*pointX+mZ/2)-(mZ-1)/2;
186
              break;
187
      case 2: mPos[0] = (int)(+mX*pointX+mX/2)-(mX-1)/2;
188
              mPos[1] = (mY-1)/2;
189
              mPos[2] = (int)(-mZ*pointY-mZ/2)+(mZ-1)/2;
190
              break;
191
      case 3: mPos[0] = (int)(+mX*pointX+mX/2)-(mX-1)/2;
192
              mPos[1] =-(mY-1)/2;
193
              mPos[2] = (int)(+mZ*pointY+mZ/2)-(mZ-1)/2;
194
              break;
195
      case 4: mPos[0] = (int)(+mX*pointX+mX/2)-(mX-1)/2;
196
              mPos[1] = (int)(+mY*pointY+mY/2)-(mY-1)/2;
197
              mPos[2] = (mZ-1)/2;
198
              break;
199
      case 5: mPos[0] = (int)(-mX*pointX-mX/2)+(mX-1)/2;
200
              mPos[1] = (int)(+mY*pointY+mY/2)-(mY-1)/2;
201
              mPos[2] =-(mZ-1)/2;
202
              break;
203
      }
204
    }
205

  
206
///////////////////////////////////////////////////////////////////////////////////////////////////
207

  
208
  private int whichCubitTouched(int face, float pointX, float pointY)
209
    {
210
    computePosition(face,pointX,pointY);
211

  
212
    for(int c=0; c<mNumCubits; c++)
213
      if( mCubits[c].isAttached() )
214
        {
215
        float[] pos = mCubits[c].getPosition();
216
        int len = pos.length/3;
217

  
218
        for(int p=0; p<len; p++)
219
          if( pos[3*p]==mPos[0] && pos[3*p+1]==mPos[1] && pos[3*p+2]==mPos[2] ) return c;
220
        }
221

  
222
    android.util.Log.e("D", "whichCubitTouched: IMPOSSIBLE!!");
223
    return -1;
224
    }
225

  
226 149
///////////////////////////////////////////////////////////////////////////////////////////////////
227 150
// PUBLIC API
228 151
///////////////////////////////////////////////////////////////////////////////////////////////////
229 152

  
230
  public BandagedCreatorTouchControl(float ratio, float fov)
153
  public BandagedCreatorTouchControl(float ratio, float fov, BandagedObject object)
231 154
    {
155
    mObject = object;
232 156
    mPoint = new float[3];
233 157
    mCamera= new float[3];
234 158
    mTouch = new float[3];
235
    mPos   = new float[3];
236 159
    mPoint2D = new float[2];
237 160
    mDist3D  = new float[6];
238
    mFaceAxis = TouchControlHexahedron.FACE_AXIS;
161
    mFaceAxis = mObject.getFaceAxis();
239 162
    mObjectRatio = ratio;
240 163

  
241 164
    double halfFOV = fov * (Math.PI/360);
......
247 170

  
248 171
///////////////////////////////////////////////////////////////////////////////////////////////////
249 172

  
250
  public void setCubits(BandagedCubit[] cubits, int x, int y, int z)
173
  public void setDist3D(float[] dist3d)
251 174
    {
252
    mCubits = cubits;
253
    mNumCubits = cubits.length;
254

  
255
    mX = x;
256
    mY = y;
257
    mZ = z;
258
    mMax = mX>mY ? Math.max(mX,mZ) : Math.max(mY,mZ);
259

  
260
    mDist3D[0] = mDist3D[1] = 0.5f*(mX/mMax);
261
    mDist3D[2] = mDist3D[3] = 0.5f*(mY/mMax);
262
    mDist3D[4] = mDist3D[5] = 0.5f*(mZ/mMax);
175
    mDist3D = dist3d;
263 176
    }
264 177

  
265 178
///////////////////////////////////////////////////////////////////////////////////////////////////
......
282 195

  
283 196
    if( !touched ) return -1;
284 197

  
285
    return whichCubitTouched(mLastTouchedFace,mPoint2D[0],mPoint2D[1]);
198
    return mObject.whichCubitTouched(mLastTouchedFace,mPoint2D[0],mPoint2D[1]);
286 199
    }
287 200
}
288 201

  
src/main/java/org/distorted/bandaged/BandagedCreatorView.java
9 9

  
10 10
package org.distorted.bandaged;
11 11

  
12
import android.annotation.SuppressLint;
12 13
import android.app.ActivityManager;
13 14
import android.content.Context;
14 15
import android.content.pm.ConfigurationInfo;
......
19 20

  
20 21
import com.google.firebase.crashlytics.FirebaseCrashlytics;
21 22

  
22
import org.distorted.library.main.DistortedScreen;
23

  
24 23
///////////////////////////////////////////////////////////////////////////////////////////////////
25 24

  
26 25
public class BandagedCreatorView extends GLSurfaceView
......
53 52
        {
54 53
        BandagedCreatorActivity act = (BandagedCreatorActivity)context;
55 54
        mRenderer = new BandagedCreatorRenderer(this);
56
        DistortedScreen screen = mRenderer.getScreen();
57
        mTouchControl = new BandagedCreatorTouchControl( mRenderer.getObjectRatio() , screen.getFOV() );
55
        mTouchControl = mRenderer.createTouchControl();
58 56

  
59 57
        final ActivityManager activityManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
60 58

  
......
105 103
      return mRenderer;
106 104
      }
107 105

  
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

  
110
    public void setCubits(BandagedCubit[] cubits, int x, int y, int z)
111
      {
112
      mTouchControl.setCubits(cubits,x,y,z);
113
      }
114

  
115 106
///////////////////////////////////////////////////////////////////////////////////////////////////
116 107

  
117 108
    public void resetCubits()
......
321 312

  
322 313
///////////////////////////////////////////////////////////////////////////////////////////////////
323 314

  
315
    @SuppressLint("ClickableViewAccessibility")
324 316
    @Override
325 317
    public boolean onTouchEvent(MotionEvent event)
326 318
      {
src/main/java/org/distorted/bandaged/BandagedCreatorWorkerThread.java
89 89
          }
90 90

  
91 91
        try  { mThis.wait(); }
92
        catch(InterruptedException ex) { }
92
        catch(InterruptedException ignored) { }
93 93
        }
94 94
      }
95 95
    }
......
313 313
      if(bos!=null)
314 314
        {
315 315
        try { bos.close(); }
316
        catch(IOException io) {}
316
        catch(IOException ignored) {}
317 317
        }
318 318
      }
319 319

  
src/main/java/org/distorted/bandaged/BandagedObject.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2023 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Magic Cube.                                                              //
5
//                                                                                               //
6
// Magic Cube is proprietary software licensed under an EULA which you should have received      //
7
// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
8
///////////////////////////////////////////////////////////////////////////////////////////////////
9

  
10
package org.distorted.bandaged;
11

  
12
import org.distorted.library.main.DistortedNode;
13
import org.distorted.library.main.DistortedScreen;
14
import org.distorted.library.type.Static3D;
15
import org.distorted.library.type.Static4D;
16
import org.distorted.objectlib.main.InitData;
17
import org.distorted.objectlib.main.TwistyObject;
18
import org.distorted.objectlib.objects.TwistyBandagedCuboid;
19
import org.distorted.objectlib.shape.ShapeHexahedron;
20
import org.distorted.objectlib.touchcontrol.TouchControlHexahedron;
21

  
22
///////////////////////////////////////////////////////////////////////////////////////////////////
23

  
24
public class BandagedObject
25
{
26
    private static final float DIST2D = 0.5f;
27

  
28
    private final DistortedScreen mScreen;
29
    private final float[] mPos;
30

  
31
    private BandagedCubit[] mCubits;
32
    private int mX, mY, mZ;
33
    private int mNumCubits;
34

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

  
37
   BandagedObject(DistortedScreen screen)
38
     {
39
     mScreen = screen;
40
     mPos = new float[3];
41
     }
42

  
43
///////////////////////////////////////////////////////////////////////////////////////////////////
44

  
45
   void resetObject(float scale)
46
     {
47
     for(int c=0; c<mNumCubits; c++)
48
       {
49
       if( !mCubits[c].isAttached() )
50
         {
51
         mCubits[c].attach();
52
         mScreen.attach(mCubits[c].getNode());
53
         }
54
       if( mCubits[c].getPosition().length>3 )
55
         {
56
         mCubits[c].reset(scale);
57
         }
58
       mCubits[c].setUnmarked();
59
       }
60
     }
61

  
62
///////////////////////////////////////////////////////////////////////////////////////////////////
63

  
64
   private boolean isAdjacent(float[] pos1, float[] pos2)
65
     {
66
     int len1 = pos1.length/3;
67
     int len2 = pos2.length/3;
68

  
69
     for(int i=0; i<len1; i++)
70
       for(int j=0; j<len2; j++)
71
         {
72
         float d0 = pos1[3*i  ] - pos2[3*j  ];
73
         float d1 = pos1[3*i+1] - pos2[3*j+1];
74
         float d2 = pos1[3*i+2] - pos2[3*j+2];
75

  
76
         if( d0*d0 + d1*d1 + d2*d2 == 1 ) return true;
77
         }
78

  
79
     return false;
80
     }
81

  
82
///////////////////////////////////////////////////////////////////////////////////////////////////
83

  
84
   private int computeNumCubits(int x, int y, int z)
85
     {
86
     return ( x<=1 || y<=1 || z<=1 ) ? x*y*z : x*y*z-(x-2)*(y-2)*(z-2);
87
     }
88

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

  
91
   float getSize()
92
     {
93
     return mX>mY ? Math.max(mX, mZ) : Math.max(mY, mZ);
94
     }
95

  
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97

  
98
   float[][] getCubitPositions()
99
     {
100
     int numAttached = 0;
101

  
102
     for(int i=0; i<mNumCubits; i++)
103
       if( mCubits[i].isAttached() ) numAttached++;
104

  
105
     float[][] pos = new float[numAttached][];
106
     int attached=0;
107

  
108
     for(int i=0; i<mNumCubits; i++)
109
       if( mCubits[i].isAttached() )
110
         {
111
         pos[attached++] = mCubits[i].getPosition();
112
         }
113

  
114
     return pos;
115
     }
116

  
117
///////////////////////////////////////////////////////////////////////////////////////////////////
118

  
119
   TwistyObject createObject(int mode, float size)
120
     {
121
     float[][] pos = getCubitPositions();
122
     InitData data = new InitData( new int[] {mX,mY,mZ},pos);
123
     return new TwistyBandagedCuboid( TwistyObject.MESH_NICE, mode, ShapeHexahedron.DEFAULT_ROT, new Static3D(0,0,0), size, data, null );
124
     }
125

  
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

  
128
   void tryConnectingCubits(int index1, int index2, float scale)
129
     {
130
     if( index1!=index2 )
131
       {
132
       float[] pos1 = mCubits[index1].getPosition();
133
       float[] pos2 = mCubits[index2].getPosition();
134

  
135
       if( isAdjacent(pos1,pos2) )
136
         {
137
         mCubits[index2].join(pos1,scale);
138
         mCubits[index1].detach();
139
         mScreen.detach(mCubits[index1].getNode());
140
         }
141
       }
142
     }
143

  
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

  
146
   void attachCubits(float scale)
147
     {
148
     for(int i=0; i<mNumCubits; i++)
149
       {
150
       mCubits[i].scaleMove(scale);
151
       DistortedNode node = mCubits[i].getNode();
152
       mScreen.attach(node);
153
       }
154
     }
155

  
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

  
158
   void attachAndMarkCubits(float scale, int touched)
159
     {
160
     for(int i=0; i<mNumCubits; i++)
161
       {
162
       if( mCubits[i].isAttached() )
163
         {
164
         mCubits[i].scaleMove(scale);
165
         if( touched==i ) mCubits[i].setMarked();
166
         else             mCubits[i].setUnmarked();
167
         DistortedNode node = mCubits[i].getNode();
168
         mScreen.attach(node);
169
         }
170
       }
171
     }
172

  
173
///////////////////////////////////////////////////////////////////////////////////////////////////
174

  
175
   boolean tryChangeObject(int x, int y, int z)
176
     {
177
     if( mX!=x || mY!=y || mZ!=z )
178
       {
179
       mX = x;
180
       mY = y;
181
       mZ = z;
182
       mNumCubits = computeNumCubits(mX,mY,mZ);
183
       return true;
184
       }
185

  
186
     return false;
187
     }
188

  
189
///////////////////////////////////////////////////////////////////////////////////////////////////
190

  
191
   int computeProjectionAngle()
192
     {
193
     float quot1 = mZ/ (float)mX;
194
     float quot2 = mZ/ (float)mY;
195
     float quot3 = mX/ (float)mZ;
196
     float quot4 = mX/ (float)mY;
197

  
198
     float quot5 = Math.max(quot1,quot2);
199
     float quot6 = Math.max(quot3,quot4);
200
     float quot7 = Math.max(quot5,quot6);
201

  
202
          if( quot7<=1.0f ) return 120;
203
     else if( quot7<=1.5f ) return 90;
204
     else if( quot7<=2.0f ) return 60;
205
     else                   return 30;
206
     }
207

  
208
///////////////////////////////////////////////////////////////////////////////////////////////////
209

  
210
   void scaleCubits(float scale)
211
     {
212
     for(int i=0; i<mNumCubits; i++) mCubits[i].scaleMove(scale);
213
     }
214

  
215
///////////////////////////////////////////////////////////////////////////////////////////////////
216

  
217
   void recreateCubits(Static4D quatT, Static4D quatA, Static3D scale)
218
     {
219
     if( mCubits==null )
220
        {
221
        createCubits(quatT,quatA,scale);
222
        }
223
      else
224
        {
225
        for(int i=0; i<mNumCubits; i++) mCubits[i].recreateBitmap();
226
        }
227
     }
228

  
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

  
231
   float[] getDist3D()
232
     {
233
     float max = getSize();
234

  
235
     float x = 0.5f*(mX/max);
236
     float y = 0.5f*(mY/max);
237
     float z = 0.5f*(mZ/max);
238

  
239
     return new float[] {x,x,y,y,z,z};
240
     }
241

  
242
///////////////////////////////////////////////////////////////////////////////////////////////////
243

  
244
   void createCubits(Static4D quatT, Static4D quatA, Static3D scale)
245
     {
246
     mCubits = new BandagedCubit[mNumCubits];
247
     int c=0;
248

  
249
     float begX = 0.5f*(1-mX);
250
     float begY = 0.5f*(1-mY);
251
     float begZ = 0.5f*(1-mZ);
252

  
253
     for(int x=0; x<mX; x++)
254
       for(int y=0; y<mY; y++)
255
          for(int z=0; z<mZ; z++)
256
            if( x==0 || x==mX-1 || y==0 || y==mY-1 || z==0 || z==mZ-1 )
257
              {
258
              float[] pos = new float[] { begX+x,begY+y,begZ+z };
259
              mCubits[c] = new BandagedCubit(pos,mX,mY,mZ,quatT,quatA,scale,false);
260
              c++;
261
              }
262
    }
263

  
264
///////////////////////////////////////////////////////////////////////////////////////////////////
265

  
266
  Static3D[] getFaceAxis()
267
    {
268
    return TouchControlHexahedron.FACE_AXIS;
269
    }
270

  
271
///////////////////////////////////////////////////////////////////////////////////////////////////
272

  
273
  void touchCubit(int index)
274
    {
275
    if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setMarked();
276
    }
277

  
278
///////////////////////////////////////////////////////////////////////////////////////////////////
279

  
280
  void untouchCubit(int index)
281
    {
282
    if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setUnmarked();
283
    }
284

  
285
///////////////////////////////////////////////////////////////////////////////////////////////////
286

  
287
  void stretchPoint(int face, float[] output)
288
    {
289
    float max = getSize();
290

  
291
    switch(face/2)
292
      {
293
      case 0: output[0] *= (max/mZ); output[1] *= (max/mY); break;
294
      case 1: output[0] *= (max/mX); output[1] *= (max/mZ); break;
295
      case 2: output[0] *= (max/mX); output[1] *= (max/mY); break;
296
      }
297
    }
298

  
299
///////////////////////////////////////////////////////////////////////////////////////////////////
300

  
301
  int whichCubitTouched(int face, float pointX, float pointY)
302
    {
303
    switch(face)
304
      {
305
      case 0: mPos[0] = (mX-1)/2.0f;
306
              mPos[1] = (int)( mY*pointY+mY/2.0f)-(mY-1)/2.0f;
307
              mPos[2] = (int)(-mZ*pointX-mZ/2.0f)+(mZ-1)/2.0f;
308
              break;
309
      case 1: mPos[0] =-(mX-1)/2.0f;
310
              mPos[1] = (int)( mY*pointY+mY/2.0f)-(mY-1)/2.0f;
311
              mPos[2] = (int)( mZ*pointX+mZ/2.0f)-(mZ-1)/2.0f;
312
              break;
313
      case 2: mPos[0] = (int)( mX*pointX+mX/2.0f)-(mX-1)/2.0f;
314
              mPos[1] = (mY-1)/2.0f;
315
              mPos[2] = (int)(-mZ*pointY-mZ/2.0f)+(mZ-1)/2.0f;
316
              break;
317
      case 3: mPos[0] = (int)( mX*pointX+mX/2.0f)-(mX-1)/2.0f;
318
              mPos[1] =-(mY-1)/2.0f;
319
              mPos[2] = (int)( mZ*pointY+mZ/2.0f)-(mZ-1)/2.0f;
320
              break;
321
      case 4: mPos[0] = (int)( mX*pointX+mX/2.0f)-(mX-1)/2.0f;
322
              mPos[1] = (int)( mY*pointY+mY/2.0f)-(mY-1)/2.0f;
323
              mPos[2] = (mZ-1)/2.0f;
324
              break;
325
      case 5: mPos[0] = (int)(-mX*pointX-mX/2.0f)+(mX-1)/2.0f;
326
              mPos[1] = (int)( mY*pointY+mY/2.0f)-(mY-1)/2.0f;
327
              mPos[2] =-(mZ-1)/2.0f;
328
              break;
329
      }
330

  
331
    for(int c=0; c<mNumCubits; c++)
332
      if( mCubits[c].isAttached() )
333
        {
334
        float[] pos = mCubits[c].getPosition();
335
        int len = pos.length/3;
336

  
337
        for(int p=0; p<len; p++)
338
          if( pos[3*p]==mPos[0] && pos[3*p+1]==mPos[1] && pos[3*p+2]==mPos[2] ) return c;
339
        }
340

  
341
    android.util.Log.e("D", "whichCubitTouched: IMPOSSIBLE!!");
342
    return -1;
343
    }
344

  
345
///////////////////////////////////////////////////////////////////////////////////////////////////
346

  
347
  boolean isInsideFace(int face, float[] p)
348
    {
349
    return ( p[0]<=DIST2D && p[0]>=-DIST2D && p[1]<=DIST2D && p[1]>=-DIST2D );
350
    }
351
}

Also available in: Unified diff