Project

General

Profile

Download (9.67 KB) Statistics
| Branch: | Revision:

distorted-objectlib / src / main / java / org / distorted / objectlib / bandaged / BandagedObject.java @ d2e06841

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.objectlib.bandaged;
11

    
12
import org.distorted.library.main.DistortedNode;
13
import org.distorted.library.main.DistortedScreen;
14
import org.distorted.library.mesh.MeshBase;
15
import org.distorted.library.type.Static3D;
16
import org.distorted.library.type.Static4D;
17
import org.distorted.objectlib.main.TwistyObject;
18

    
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

    
21
public abstract class BandagedObject
22
{
23
    private final DistortedScreen mScreen;
24
    private final float[][] mFaceAxis;
25
    private BandagedCubit[] mCubits;
26
    private final float[][] mRotAxis;
27

    
28
    float[][] mCuts;
29
    final int[] mSize;
30
    final float mDist2D;
31

    
32
    int mMax;
33
    int mNumCubits;
34

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

    
37
   BandagedObject(DistortedScreen screen)
38
     {
39
     mScreen = screen;
40
     mRotAxis = getRotAxis();
41
     mSize = new int[mRotAxis.length];
42
     mDist2D = getDist2D();
43
     Static3D[] axis = getFaceAxis();
44
     int numAxis = axis.length;
45
     mFaceAxis = new float[numAxis][];
46
     for(int i=0; i<numAxis; i++) mFaceAxis[i] = new float[] { axis[i].get0(), axis[i].get1(), axis[i].get2() };
47
     }
48

    
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50

    
51
   abstract float[][] getRotAxis();
52
   abstract float getDist2D();
53
   abstract int[] getColors();
54
   abstract float[][][] getPositions();
55
   abstract boolean isAdjacent(float dx, float dy, float dz);
56
   abstract MeshBase createMesh(float[] pos, boolean round);
57

    
58
   public abstract TwistyObject createObject(int mode, float scale );
59
   public abstract float[] getDist3D();
60
   public abstract int computeProjectionAngle();
61
   public abstract boolean tryChangeObject(int x, int y, int z);
62
   public abstract boolean isInsideFace(int face, float[] p);
63
   public abstract Static3D[] getFaceAxis();
64
   public abstract float getScreenRatio();
65

    
66
///////////////////////////////////////////////////////////////////////////////////////////////////
67

    
68
  private float getRotRow(int ax, float d)
69
    {
70
    float[] cuts = mCuts[ax];
71
    int numCuts = cuts.length;
72
    for(int c=0; c<numCuts; c++) if( d<=cuts[c] ) return c;
73
    return numCuts;
74
    }
75

    
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77

    
78
  float[][] getRotRows(float[] pos)
79
    {
80
    int num = pos.length/3;
81
    int numAx = mRotAxis.length;
82
    float[][] ret = new float[num][numAx];
83

    
84
    for(int p=0; p<num; p++)
85
      for(int a=0; a<numAx; a++)
86
        {
87
        float[] ax = mRotAxis[a];
88
        float x = pos[3*p];
89
        float y = pos[3*p+1];
90
        float z = pos[3*p+2];
91
        float d = ax[0]*x + ax[1]*y + ax[2]*z;
92
        ret[p][a] = getRotRow(a,d);
93
        }
94

    
95
    return ret;
96
    }
97

    
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99

    
100
   public void createCubits(Static4D quatT, Static4D quatA, Static3D scale)
101
     {
102
     mCubits = new BandagedCubit[mNumCubits];
103
     float[][][] pos = getPositions();
104
     int c=0;
105

    
106
     for(float[][] po : pos)
107
        for(float[] p : po)
108
          mCubits[c++] = new BandagedCubit(this, p, quatT, quatA, scale, false);
109
     }
110

    
111
///////////////////////////////////////////////////////////////////////////////////////////////////
112

    
113
   int computeMapsIndex(float[] faceAx)
114
      {
115
      int min=-1, numAxis = mFaceAxis.length;
116
      float error = Float.MAX_VALUE;
117
      float x = faceAx[0];
118
      float y = faceAx[1];
119
      float z = faceAx[2];
120

    
121
      for(int i=0; i<numAxis; i++)
122
        {
123
        float[] ax = mFaceAxis[i];
124
        float dx = x-ax[0];
125
        float dy = y-ax[1];
126
        float dz = z-ax[2];
127

    
128
        float diff = dx*dx + dy*dy + dz*dz;
129

    
130
        if( error>diff )
131
          {
132
          error = diff;
133
          min = i;
134
          }
135
        }
136

    
137
      return min;
138
      }
139

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

    
142
   public void resetObject(float scale)
143
     {
144
     for(int c=0; c<mNumCubits; c++)
145
       {
146
       if( !mCubits[c].isAttached() )
147
         {
148
         mCubits[c].attach();
149
         mScreen.attach(mCubits[c].getNode());
150
         }
151
       if( mCubits[c].getPosition().length>3 )
152
         {
153
         mCubits[c].reset(scale);
154
         }
155
       mCubits[c].setUnmarked();
156
       }
157
     }
158

    
159
///////////////////////////////////////////////////////////////////////////////////////////////////
160

    
161
   public float getMaxSize()
162
     {
163
     return mMax;
164
     }
165

    
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167

    
168
   float[][] getCubitPositions()
169
     {
170
     int numAttached = 0;
171

    
172
     for(int i=0; i<mNumCubits; i++)
173
       if( mCubits[i].isAttached() ) numAttached++;
174

    
175
     float[][] pos = new float[numAttached][];
176
     int attached=0;
177

    
178
     for(int i=0; i<mNumCubits; i++)
179
       if( mCubits[i].isAttached() )
180
         {
181
         pos[attached++] = mCubits[i].getPosition();
182
         }
183

    
184
     return pos;
185
     }
186

    
187
///////////////////////////////////////////////////////////////////////////////////////////////////
188

    
189
   public void tryConnectingCubits(int index1, int index2, float scale)
190
     {
191
     if( index1!=index2 )
192
       {
193
       float[] pos1 = mCubits[index1].getPosition();
194
       float[] pos2 = mCubits[index2].getPosition();
195

    
196
       if( isAdjacent(pos1,pos2) )
197
         {
198
         mCubits[index2].join(pos1,scale);
199
         mCubits[index1].detach();
200
         mScreen.detach(mCubits[index1].getNode());
201
         }
202
       }
203
     }
204

    
205
///////////////////////////////////////////////////////////////////////////////////////////////////
206

    
207
   public void attachCubits(float scale)
208
     {
209
     for(int i=0; i<mNumCubits; i++)
210
       {
211
       mCubits[i].scaleMove(scale);
212
       DistortedNode node = mCubits[i].getNode();
213
       mScreen.attach(node);
214
       }
215
     }
216

    
217
///////////////////////////////////////////////////////////////////////////////////////////////////
218

    
219
   public void attachAndMarkCubits(float scale, int touched)
220
     {
221
     for(int i=0; i<mNumCubits; i++)
222
       {
223
       if( mCubits[i].isAttached() )
224
         {
225
         mCubits[i].scaleMove(scale);
226
         if( touched==i ) mCubits[i].setMarked();
227
         else             mCubits[i].setUnmarked();
228
         DistortedNode node = mCubits[i].getNode();
229
         mScreen.attach(node);
230
         }
231
       }
232
     }
233

    
234
///////////////////////////////////////////////////////////////////////////////////////////////////
235

    
236
   public void scaleCubits(float scale)
237
     {
238
     for(int i=0; i<mNumCubits; i++) mCubits[i].scaleMove(scale);
239
     }
240

    
241
///////////////////////////////////////////////////////////////////////////////////////////////////
242

    
243
   public void recreateCubits(Static4D quatT, Static4D quatA, Static3D scale)
244
     {
245
     if( mCubits==null )
246
        {
247
        createCubits(quatT,quatA,scale);
248
        }
249
      else
250
        {
251
        for(int i=0; i<mNumCubits; i++) mCubits[i].recreateBitmap();
252
        }
253
     }
254

    
255
///////////////////////////////////////////////////////////////////////////////////////////////////
256

    
257
  public void touchCubit(int index)
258
    {
259
    if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setMarked();
260
    }
261

    
262
///////////////////////////////////////////////////////////////////////////////////////////////////
263

    
264
  public void untouchCubit(int index)
265
    {
266
    if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setUnmarked();
267
    }
268

    
269
///////////////////////////////////////////////////////////////////////////////////////////////////
270

    
271
  public int whichCubitTouched(float[] point3D)
272
    {
273
    float x = point3D[0]*mMax;
274
    float y = point3D[1]*mMax;
275
    float z = point3D[2]*mMax;
276

    
277
    int numAxis = mRotAxis.length;
278
    float[] rotRow = new float[numAxis];
279

    
280
    for(int a=0; a<numAxis; a++)
281
      {
282
      float[] ax = mRotAxis[a];
283
      float d = ax[0]*x + ax[1]*y + ax[2]*z;
284
      rotRow[a] = getRotRow(a,d);
285
      }
286

    
287
    int diff = Integer.MAX_VALUE;
288
    int currBest = -1;
289

    
290
    for(int c=0; c<mNumCubits; c++)
291
      if( mCubits[c].isAttached() )
292
        {
293
        float[][] cubitRotRow = mCubits[c].getRotRow();
294

    
295
        for(float[] row : cubitRotRow)
296
          {
297
          int currDiff = 0;
298

    
299
          for(int a=0; a<numAxis; a++)
300
            {
301
            float d = rotRow[a]-row[a];
302
            currDiff += d*d;
303
            }
304

    
305
          if( currDiff<diff )
306
            {
307
            diff = currDiff;
308
            currBest = c;
309
            }
310
          }
311
        }
312

    
313
    return currBest;
314
    }
315

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

    
318
  boolean isAdjacent(float[] pos1, float[] pos2)
319
     {
320
     int len1 = pos1.length/3;
321
     int len2 = pos2.length/3;
322

    
323
     for(int i=0; i<len1; i++)
324
       for(int j=0; j<len2; j++)
325
         {
326
         float dx = pos1[3*i  ] - pos2[3*j  ];
327
         float dy = pos1[3*i+1] - pos2[3*j+1];
328
         float dz = pos1[3*i+2] - pos2[3*j+2];
329

    
330
         if( isAdjacent(dx,dy,dz) ) return true;
331
         }
332

    
333
     return false;
334
     }
335
}
(3-3/11)