Project

General

Profile

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

magiccube / src / main / java / org / distorted / bandaged / BandagedObject.java @ f404152d

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
}
(9-9/14)