Project

General

Profile

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

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

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

    
27
    final int[] mSize;
28
    final float mDist2D;
29

    
30
    int mMax;
31
    int mNumCubits;
32

    
33
///////////////////////////////////////////////////////////////////////////////////////////////////
34

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

    
46
///////////////////////////////////////////////////////////////////////////////////////////////////
47

    
48
   abstract float getDist2D();
49
   abstract int[] getColors();
50
   abstract float[][][] getPositions();
51
   abstract boolean isAdjacent(float dx, float dy, float dz);
52
   abstract MeshBase createMesh(float[] pos, boolean round);
53

    
54
   public abstract TwistyObject createObject(int mode, float scale );
55
   public abstract float[] getDist3D();
56
   public abstract int computeProjectionAngle();
57
   public abstract boolean tryChangeObject(int x, int y, int z);
58
   public abstract boolean isInsideFace(int face, float[] p);
59
   public abstract Static3D[] getFaceAxis();
60
   public abstract float getScreenRatio();
61

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

    
64
   public void createCubits(Static4D quatT, Static4D quatA, Static3D scale)
65
     {
66
     mCubits = new BandagedCubit[mNumCubits];
67
     float[][][] pos = getPositions();
68
     int c=0;
69

    
70
     for(float[][] po : pos)
71
        for(float[] p : po)
72
           mCubits[c++]=new BandagedCubit(this, p, quatT, quatA, scale, false);
73
     }
74

    
75
///////////////////////////////////////////////////////////////////////////////////////////////////
76

    
77
   int computeMapsIndex(float[] faceAx)
78
      {
79
      int min=-1, numAxis = mFaceAxis.length;
80
      float error = Float.MAX_VALUE;
81
      float x = faceAx[0];
82
      float y = faceAx[1];
83
      float z = faceAx[2];
84

    
85
      for(int i=0; i<numAxis; i++)
86
        {
87
        float[] ax = mFaceAxis[i];
88
        float dx = x-ax[0];
89
        float dy = y-ax[1];
90
        float dz = z-ax[2];
91

    
92
        float diff = dx*dx + dy*dy + dz*dz;
93

    
94
        if( error>diff )
95
          {
96
          error = diff;
97
          min = i;
98
          }
99
        }
100

    
101
      return min;
102
      }
103

    
104
///////////////////////////////////////////////////////////////////////////////////////////////////
105

    
106
   public void resetObject(float scale)
107
     {
108
     for(int c=0; c<mNumCubits; c++)
109
       {
110
       if( !mCubits[c].isAttached() )
111
         {
112
         mCubits[c].attach();
113
         mScreen.attach(mCubits[c].getNode());
114
         }
115
       if( mCubits[c].getPosition().length>3 )
116
         {
117
         mCubits[c].reset(scale);
118
         }
119
       mCubits[c].setUnmarked();
120
       }
121
     }
122

    
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124

    
125
   public float getMaxSize()
126
     {
127
     return mMax;
128
     }
129

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

    
132
   float[][] getCubitPositions()
133
     {
134
     int numAttached = 0;
135

    
136
     for(int i=0; i<mNumCubits; i++)
137
       if( mCubits[i].isAttached() ) numAttached++;
138

    
139
     float[][] pos = new float[numAttached][];
140
     int attached=0;
141

    
142
     for(int i=0; i<mNumCubits; i++)
143
       if( mCubits[i].isAttached() )
144
         {
145
         pos[attached++] = mCubits[i].getPosition();
146
         }
147

    
148
     return pos;
149
     }
150

    
151
///////////////////////////////////////////////////////////////////////////////////////////////////
152

    
153
   public void tryConnectingCubits(int index1, int index2, float scale)
154
     {
155
     if( index1!=index2 )
156
       {
157
       float[] pos1 = mCubits[index1].getPosition();
158
       float[] pos2 = mCubits[index2].getPosition();
159

    
160
       if( isAdjacent(pos1,pos2) )
161
         {
162
         mCubits[index2].join(pos1,scale);
163
         mCubits[index1].detach();
164
         mScreen.detach(mCubits[index1].getNode());
165
         }
166
       }
167
     }
168

    
169
///////////////////////////////////////////////////////////////////////////////////////////////////
170

    
171
   public void attachCubits(float scale)
172
     {
173
     for(int i=0; i<mNumCubits; i++)
174
       {
175
       mCubits[i].scaleMove(scale);
176
       DistortedNode node = mCubits[i].getNode();
177
       mScreen.attach(node);
178
       }
179
     }
180

    
181
///////////////////////////////////////////////////////////////////////////////////////////////////
182

    
183
   public void attachAndMarkCubits(float scale, int touched)
184
     {
185
     for(int i=0; i<mNumCubits; i++)
186
       {
187
       if( mCubits[i].isAttached() )
188
         {
189
         mCubits[i].scaleMove(scale);
190
         if( touched==i ) mCubits[i].setMarked();
191
         else             mCubits[i].setUnmarked();
192
         DistortedNode node = mCubits[i].getNode();
193
         mScreen.attach(node);
194
         }
195
       }
196
     }
197

    
198
///////////////////////////////////////////////////////////////////////////////////////////////////
199

    
200
   public void scaleCubits(float scale)
201
     {
202
     for(int i=0; i<mNumCubits; i++) mCubits[i].scaleMove(scale);
203
     }
204

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

    
207
   public void recreateCubits(Static4D quatT, Static4D quatA, Static3D scale)
208
     {
209
     if( mCubits==null )
210
        {
211
        createCubits(quatT,quatA,scale);
212
        }
213
      else
214
        {
215
        for(int i=0; i<mNumCubits; i++) mCubits[i].recreateBitmap();
216
        }
217
     }
218

    
219
///////////////////////////////////////////////////////////////////////////////////////////////////
220

    
221
  public void touchCubit(int index)
222
    {
223
    if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setMarked();
224
    }
225

    
226
///////////////////////////////////////////////////////////////////////////////////////////////////
227

    
228
  public void untouchCubit(int index)
229
    {
230
    if( index>=0 && index<mNumCubits && mCubits[index]!=null ) mCubits[index].setUnmarked();
231
    }
232

    
233
///////////////////////////////////////////////////////////////////////////////////////////////////
234

    
235
  public int whichCubitTouched(float[] point3D)
236
    {
237
    float x = point3D[0]*mMax;
238
    float y = point3D[1]*mMax;
239
    float z = point3D[2]*mMax;
240

    
241
    int minIndex = -1;
242
    float minDist = Float.MAX_VALUE;
243

    
244
    for(int c=0; c<mNumCubits; c++)
245
      if( mCubits[c].isAttached() )
246
        {
247
        float[] pos = mCubits[c].getPosition();
248
        int len = pos.length/3;
249

    
250
        for(int p=0; p<len; p++)
251
          {
252
          float dx = pos[3*p  ]-x;
253
          float dy = pos[3*p+1]-y;
254
          float dz = pos[3*p+2]-z;
255
          float dist = dx*dx + dy*dy + dz*dz;
256

    
257
          if( dist<minDist )
258
            {
259
            minDist = dist;
260
            minIndex = c;
261
            }
262
          }
263
        }
264

    
265
    return minIndex;
266
    }
267

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

    
270
  boolean isAdjacent(float[] pos1, float[] pos2)
271
     {
272
     int len1 = pos1.length/3;
273
     int len2 = pos2.length/3;
274

    
275
     for(int i=0; i<len1; i++)
276
       for(int j=0; j<len2; j++)
277
         {
278
         float dx = pos1[3*i  ] - pos2[3*j  ];
279
         float dy = pos1[3*i+1] - pos2[3*j+1];
280
         float dz = pos1[3*i+2] - pos2[3*j+2];
281

    
282
         if( isAdjacent(dx,dy,dz) ) return true;
283
         }
284

    
285
     return false;
286
     }
287
}
(3-3/8)