Project

General

Profile

« Previous | Next » 

Revision e514732c

Added by Leszek Koltunski over 1 year ago

move the non-UI bandaged stuff to its own package in the object library.

View differences:

src/main/java/org/distorted/bandaged/BandagedCreatorRenderer.java
39 39
import org.distorted.library.type.Static1D;
40 40
import org.distorted.library.type.Static3D;
41 41
import org.distorted.library.type.Static4D;
42
import org.distorted.objectlib.bandaged.BandagedObject;
43
import org.distorted.objectlib.bandaged.BandagedObjectCuboid;
42 44
import org.distorted.objectlib.json.JsonWriter;
43 45
import org.distorted.objectlib.main.TwistyObject;
44 46

  
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.bandaged.BandagedObject;
15 16

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

  
src/main/java/org/distorted/bandaged/BandagedCubit.java
1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2022 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 android.graphics.Bitmap;
13
import android.graphics.Canvas;
14
import android.graphics.Paint;
15

  
16
import org.distorted.library.effect.EffectType;
17
import org.distorted.library.effect.FragmentEffectBrightness;
18
import org.distorted.library.effect.MatrixEffectMove;
19
import org.distorted.library.effect.MatrixEffectQuaternion;
20
import org.distorted.library.effect.MatrixEffectScale;
21
import org.distorted.library.main.DistortedEffects;
22
import org.distorted.library.main.DistortedNode;
23
import org.distorted.library.main.DistortedTexture;
24
import org.distorted.library.helpers.QuatHelper;
25
import org.distorted.library.mesh.MeshBase;
26
import org.distorted.library.type.Static1D;
27
import org.distorted.library.type.Static3D;
28
import org.distorted.library.type.Static4D;
29
import org.distorted.objectlib.helpers.FactoryCubit;
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

  
33
public class BandagedCubit
34
{
35
    private static final Static3D CENTER = new Static3D(0,0,0);
36
    private static final float[] mTmp = new float[4];
37
    private static final Static1D mAlpha = new Static1D(2.0f);
38
    private static Bitmap mBitmap;
39
    private static Static4D[] mTextureMaps;
40

  
41
    private final BandagedObject mObject;
42
    private final DistortedNode mNode;
43
    private final DistortedEffects mEffects;
44
    private final DistortedTexture mTexture;
45
    private final Static3D mMove;
46
    private final int mVariant;
47
    private final boolean mRoundCorners;
48

  
49
    private float mUnscaledX, mUnscaledY, mUnscaledZ;
50
    private float[] mPosition;
51
    private boolean mIsAttached;
52
    private long mMarkedEffectID;
53

  
54
///////////////////////////////////////////////////////////////////////////////////////////////////
55

  
56
    private static void createBitmap(int[] colors)
57
      {
58
      final int NUM = colors.length;
59
      final int SIZE= 32;
60

  
61
      mTextureMaps = new Static4D[NUM];
62

  
63
      Paint paint = new Paint();
64
      paint.setStyle(Paint.Style.FILL);
65
      mBitmap = Bitmap.createBitmap( NUM*SIZE, SIZE, Bitmap.Config.ARGB_4444);
66
      Canvas canvas = new Canvas(mBitmap);
67

  
68
      for(int color=0; color<NUM; color++)
69
        {
70
        paint.setColor(colors[color]);
71
        canvas.drawRect(color*SIZE, 0, (color+1)*SIZE, SIZE, paint);
72
        mTextureMaps[color] = new Static4D( ((float)color)/NUM, 0.0f, 1.0f/NUM, 1.0f );
73
        }
74
      }
75

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

  
78
    private void resetTextureMaps(MeshBase mesh)
79
      {
80
      FactoryCubit fact = FactoryCubit.getInstance();
81
      int numComponents = mesh.getNumTexComponents();
82
      Static4D[] maps = new Static4D[numComponents];
83

  
84
      for(int i=0; i<numComponents; i++)
85
        {
86
        Static4D q = fact.getQuaternion(i);
87
        QuatHelper.rotateVectorByQuat(mTmp,0,0,1,0,q);
88
        int index = mObject.computeMapsIndex(mTmp);
89
        maps[i] = mTextureMaps[index];
90
        }
91

  
92
      mesh.setTextureMap(maps,0);
93
      }
94

  
95
///////////////////////////////////////////////////////////////////////////////////////////////////
96

  
97
    private void computeMove(float[] position)
98
      {
99
      int numCenters = position.length/3;
100
      mUnscaledX=0.0f;
101
      mUnscaledY=0.0f;
102
      mUnscaledZ=0.0f;
103

  
104
      for(int center=0; center<numCenters; center++)
105
        {
106
        mUnscaledX += position[3*center  ];
107
        mUnscaledY += position[3*center+1];
108
        mUnscaledZ += position[3*center+2];
109
        }
110

  
111
      mUnscaledX /= numCenters;
112
      mUnscaledY /= numCenters;
113
      mUnscaledZ /= numCenters;
114
      }
115

  
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117
// PUBLIC API
118
///////////////////////////////////////////////////////////////////////////////////////////////////
119

  
120
    public BandagedCubit(BandagedObject object, float[] position, int variant, Static4D quat1,
121
                         Static4D quat2, Static3D scale, boolean roundCorners)
122
      {
123
      mObject = object;
124
      mRoundCorners = roundCorners;
125
      mPosition = position;
126
      mIsAttached = true;
127
      mMarkedEffectID = -1;
128
      mVariant = variant;
129

  
130
      computeMove(mPosition);
131
      mMove = new Static3D(0,0,0);
132

  
133
      MeshBase mesh = mObject.createMesh(mPosition,mRoundCorners);
134

  
135
      mTexture = new DistortedTexture();
136
      if( mBitmap==null ) createBitmap(mObject.getColors());
137
      mTexture.setTextureAlreadyInverted(mBitmap);
138

  
139
      resetTextureMaps(mesh);
140

  
141
      MatrixEffectScale scaleEffect = new MatrixEffectScale(scale);
142
      MatrixEffectQuaternion quat1Effect = new MatrixEffectQuaternion(quat1, CENTER);
143
      MatrixEffectQuaternion quat2Effect = new MatrixEffectQuaternion(quat2, CENTER);
144
      MatrixEffectMove moveEffect = new MatrixEffectMove(mMove);
145

  
146
      mEffects = new DistortedEffects();
147
      mEffects.apply(scaleEffect);
148
      mEffects.apply(moveEffect);
149
      mEffects.apply(quat2Effect);
150
      mEffects.apply(quat1Effect);
151

  
152
      mNode = new DistortedNode(mTexture,mEffects,mesh);
153
      }
154

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

  
157
    public void join(float[] position, float scale)
158
      {
159
      int len1 = mPosition.length;
160
      int len2 = position.length;
161
      float[] tmpPosition = new float[len1+len2];
162
      System.arraycopy(mPosition, 0, tmpPosition,    0, len1);
163
      System.arraycopy(position , 0, tmpPosition, len1, len2);
164
      mPosition = tmpPosition;
165

  
166
      computeMove(mPosition);
167
      MeshBase mesh = mObject.createMesh(mPosition,mRoundCorners);
168
      resetTextureMaps(mesh);
169
      mNode.setMesh(mesh);
170
      mMove.set( scale*mUnscaledX, scale*mUnscaledY, scale*mUnscaledZ);
171
      }
172

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

  
175
    public void reset(float scale)
176
      {
177
      float x = mPosition[0];
178
      float y = mPosition[1];
179
      float z = mPosition[2];
180

  
181
      mPosition = new float[3];
182
      mPosition[0] = x;
183
      mPosition[1] = y;
184
      mPosition[2] = z;
185

  
186
      computeMove(mPosition);
187
      MeshBase mesh = mObject.createMesh(mPosition,mRoundCorners);
188
      resetTextureMaps(mesh);
189
      mNode.setMesh(mesh);
190
      mMove.set( scale*mUnscaledX, scale*mUnscaledY, scale*mUnscaledZ);
191
      }
192

  
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194

  
195
    public void recreateBitmap()
196
      {
197
      if( mBitmap==null ) createBitmap(mObject.getColors());
198
      mTexture.setTextureAlreadyInverted(mBitmap);
199
      }
200

  
201
///////////////////////////////////////////////////////////////////////////////////////////////////
202

  
203
    public void scaleMove(float scale)
204
      {
205
      mMove.set( scale*mUnscaledX, scale*mUnscaledY, scale*mUnscaledZ);
206
      }
207

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

  
210
    public void setMarked()
211
      {
212
      if( mMarkedEffectID<0 )
213
        {
214
        FragmentEffectBrightness effect = new FragmentEffectBrightness(mAlpha);
215
        mMarkedEffectID = effect.getID();
216
        mEffects.apply(effect);
217
        }
218
      }
219

  
220
///////////////////////////////////////////////////////////////////////////////////////////////////
221

  
222
    public void setUnmarked()
223
      {
224
      mEffects.abortByType(EffectType.FRAGMENT);
225
      mMarkedEffectID = -1;
226
      }
227

  
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229

  
230
    public void detach()
231
      {
232
      mIsAttached = false;
233
      }
234

  
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

  
237
    public void attach()
238
      {
239
      mIsAttached = true;
240
      }
241

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

  
244
    public boolean isAttached()
245
      {
246
      return mIsAttached;
247
      }
248

  
249
///////////////////////////////////////////////////////////////////////////////////////////////////
250

  
251
    public float[] getPosition()
252
      {
253
      return mPosition;
254
      }
255

  
256
///////////////////////////////////////////////////////////////////////////////////////////////////
257

  
258
    public DistortedNode getNode()
259
      {
260
      return mNode;
261
      }
262
}
263

  
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.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)
36
     {
37
     mScreen = screen;
38
     mSize = new int[3];
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[1].get2() };
44
     }
45

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

  
48
   abstract float getDist2D();
49
   abstract float[] getDist3D();
50
   abstract int[] getColors();
51
   abstract Static3D[] getFaceAxis();
52
   abstract float[][][] getPositions();
53
   abstract boolean isAdjacent(float dx, float dy, float dz);
54
   abstract int computeProjectionAngle();
55
   abstract boolean tryChangeObject(int x, int y, int z);
56
   abstract boolean isInsideFace(int face, float[] p);
57
   abstract TwistyObject createObject(int mode, float scale );
58
   abstract MeshBase createMesh(float[] pos, boolean round);
59

  
60
///////////////////////////////////////////////////////////////////////////////////////////////////
61

  
62
   void createCubits(Static4D quatT, Static4D quatA, Static3D scale)
63
     {
64
     mCubits = new BandagedCubit[mNumCubits];
65
     float[][][] pos = getPositions();
66
     int c=0,numVariants = pos.length;
67

  
68
     for(int v=0; v<numVariants; v++)
69
       {
70
       int numCubits = pos[v].length;
71

  
72
       for(int vi=0; vi<numCubits; vi++)
73
         mCubits[c++] = new BandagedCubit(this,pos[v][vi],v,quatT,quatA,scale,false);
74
       }
75
     }
76

  
77
///////////////////////////////////////////////////////////////////////////////////////////////////
78

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

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

  
94
        float diff = dx*dx + dy*dy + dz*dz;
95

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

  
103
      return min;
104
      }
105

  
106
///////////////////////////////////////////////////////////////////////////////////////////////////
107

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

  
125
///////////////////////////////////////////////////////////////////////////////////////////////////
126

  
127
   float getMaxSize()
128
     {
129
     return mMax;
130
     }
131

  
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133

  
134
   float[][] getCubitPositions()
135
     {
136
     int numAttached = 0;
137

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

  
141
     float[][] pos = new float[numAttached][];
142
     int attached=0;
143

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

  
150
     return pos;
151
     }
152

  
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

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

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

  
171
///////////////////////////////////////////////////////////////////////////////////////////////////
172

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

  
183
///////////////////////////////////////////////////////////////////////////////////////////////////
184

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

  
200
///////////////////////////////////////////////////////////////////////////////////////////////////
201

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

  
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208

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

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

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

  
228
///////////////////////////////////////////////////////////////////////////////////////////////////
229

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

  
235
///////////////////////////////////////////////////////////////////////////////////////////////////
236

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

  
243
    int minIndex = -1;
244
    float minDist = Float.MAX_VALUE;
245

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

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

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

  
267
    return minIndex;
268
    }
269

  
270
///////////////////////////////////////////////////////////////////////////////////////////////////
271

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

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

  
284
         if( isAdjacent(dx,dy,dz) ) return true;
285
         }
286

  
287
     return false;
288
     }
289
}
src/main/java/org/distorted/bandaged/BandagedObjectCuboid.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.DistortedScreen;
13
import org.distorted.library.mesh.MeshBase;
14
import org.distorted.library.type.Static3D;
15
import org.distorted.objectlib.helpers.FactoryBandagedCuboid;
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 BandagedObjectCuboid extends BandagedObject
25
{
26
   BandagedObjectCuboid(DistortedScreen screen)
27
     {
28
     super(screen);
29
     }
30

  
31
///////////////////////////////////////////////////////////////////////////////////////////////////
32

  
33
   float[] getDist3D()
34
     {
35
     float max = mMax;
36

  
37
     float x = 0.5f*(mSize[0]/max);
38
     float y = 0.5f*(mSize[1]/max);
39
     float z = 0.5f*(mSize[2]/max);
40

  
41
     return new float[] {x,x,y,y,z,z};
42
     }
43

  
44
///////////////////////////////////////////////////////////////////////////////////////////////////
45

  
46
   float getDist2D()
47
     {
48
     return 0.5f;
49
     }
50

  
51
///////////////////////////////////////////////////////////////////////////////////////////////////
52

  
53
   int[] getColors()
54
     {
55
     return ShapeHexahedron.FACE_COLORS;
56
     }
57

  
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

  
60
  Static3D[] getFaceAxis()
61
    {
62
    return TouchControlHexahedron.FACE_AXIS;
63
    }
64

  
65
///////////////////////////////////////////////////////////////////////////////////////////////////
66

  
67
  boolean isAdjacent(float dx, float dy, float dz)
68
    {
69
    return dx*dx + dy*dy + dz*dz <= 1;
70
    }
71

  
72
///////////////////////////////////////////////////////////////////////////////////////////////////
73

  
74
  float[][][] getPositions()
75
    {
76
    float[][][] pos = new float[1][mNumCubits][];
77
    int c=0;
78
    int sx = mSize[0];
79
    int sy = mSize[1];
80
    int sz = mSize[2];
81

  
82
    float begX = 0.5f*(1-sx);
83
    float begY = 0.5f*(1-sy);
84
    float begZ = 0.5f*(1-sz);
85

  
86
    for(int x=0; x<sx; x++)
87
      for(int y=0; y<sy; y++)
88
         for(int z=0; z<sz; z++)
89
           if( x==0 || x==sx-1 || y==0 || y==sy-1 || z==0 || z==sz-1 )
90
              {
91
              pos[0][c++] = new float[] { begX+x,begY+y,begZ+z };
92
              }
93

  
94
    return pos;
95
    }
96

  
97
///////////////////////////////////////////////////////////////////////////////////////////////////
98

  
99
  boolean tryChangeObject(int x, int y, int z)
100
     {
101
     if( mSize[0]!=x || mSize[1]!=y || mSize[2]!=z )
102
       {
103
       mSize[0] = x;
104
       mSize[1] = y;
105
       mSize[2] = z;
106
       mMax = x>y ? Math.max(x,z) : Math.max(y,z);
107
       mNumCubits = ( x<=1 || y<=1 || z<=1 ) ? x*y*z : x*y*z-(x-2)*(y-2)*(z-2);
108
       return true;
109
       }
110

  
111
     return false;
112
     }
113

  
114
///////////////////////////////////////////////////////////////////////////////////////////////////
115

  
116
  int computeProjectionAngle()
117
     {
118
     float quot1 = mSize[2]/ (float)mSize[0];
119
     float quot2 = mSize[2]/ (float)mSize[1];
120
     float quot3 = mSize[0]/ (float)mSize[2];
121
     float quot4 = mSize[0]/ (float)mSize[1];
122

  
123
     float quot5 = Math.max(quot1,quot2);
124
     float quot6 = Math.max(quot3,quot4);
125
     float quot7 = Math.max(quot5,quot6);
126

  
127
          if( quot7<=1.0f ) return 120;
128
     else if( quot7<=1.5f ) return 90;
129
     else if( quot7<=2.0f ) return 60;
130
     else                   return 30;
131
     }
132

  
133
///////////////////////////////////////////////////////////////////////////////////////////////////
134

  
135
  boolean isInsideFace(int face, float[] p)
136
    {
137
    float max = mMax;
138

  
139
    switch(face/2)
140
      {
141
      case 0: p[0] *= (max/mSize[2]); p[1] *= (max/mSize[1]); break;
142
      case 1: p[0] *= (max/mSize[0]); p[1] *= (max/mSize[2]); break;
143
      case 2: p[0] *= (max/mSize[0]); p[1] *= (max/mSize[1]); break;
144
      }
145

  
146
    return ( p[0]<=mDist2D && p[0]>=-mDist2D && p[1]<=mDist2D && p[1]>=-mDist2D );
147
    }
148

  
149
///////////////////////////////////////////////////////////////////////////////////////////////////
150

  
151
  MeshBase createMesh(float[] pos, boolean round)
152
     {
153
     FactoryBandagedCuboid factory = FactoryBandagedCuboid.getInstance();
154
     return factory.createMesh(pos,mSize,false,round);
155
     }
156

  
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

  
159
  TwistyObject createObject(int mode, float size)
160
     {
161
     float[][] pos = getCubitPositions();
162
     InitData data = new InitData( mSize,pos);
163
     return new TwistyBandagedCuboid( TwistyObject.MESH_NICE, mode, ShapeHexahedron.DEFAULT_ROT, new Static3D(0,0,0), size, data, null );
164
     }
165
}
src/main/java/org/distorted/bandaged/BandagedObjectPyraminx.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 static org.distorted.objectlib.main.TwistyObject.SQ2;
13
import static org.distorted.objectlib.main.TwistyObject.SQ3;
14
import static org.distorted.objectlib.main.TwistyObject.SQ6;
15

  
16
import org.distorted.library.main.DistortedScreen;
17
import org.distorted.library.mesh.MeshBase;
18
import org.distorted.library.type.Static3D;
19
import org.distorted.objectlib.helpers.FactoryBandagedPyraminx;
20
import org.distorted.objectlib.main.InitData;
21
import org.distorted.objectlib.main.TwistyObject;
22
import org.distorted.objectlib.objects.TwistyBandagedPyraminx;
23
import org.distorted.objectlib.shape.ShapeTetrahedron;
24
import org.distorted.objectlib.touchcontrol.TouchControlTetrahedron;
25

  
26
///////////////////////////////////////////////////////////////////////////////////////////////////
27

  
28
public class BandagedObjectPyraminx extends BandagedObject
29
{
30
  BandagedObjectPyraminx(DistortedScreen screen)
31
    {
32
    super(screen);
33
    }
34

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

  
37
  private boolean isFaceInverted(int face)
38
    {
39
    return face>1;
40
    }
41

  
42
///////////////////////////////////////////////////////////////////////////////////////////////////
43

  
44
  private void addTetrahedralLattice(int size, float[][] pos)
45
    {
46
    final float DX = 1.0f;
47
    final float DY = SQ2/2;
48
    final float DZ = 1.0f;
49

  
50
    float startX = 0.0f;
51
    float startY =-DY*(size-1)/2;
52
    float startZ = DZ*(size-1)/2;
53

  
54
    int index = 0;
55

  
56
    for(int layer=0; layer<size; layer++)
57
      {
58
      float currX = startX;
59
      float currY = startY;
60

  
61
      for(int x=0; x<layer+1; x++)
62
        {
63
        float currZ = startZ;
64

  
65
        for(int z=0; z<size-layer; z++)
66
          {
67
          pos[index] = new float[] {currX,currY,currZ};
68
          index++;
69
          currZ -= DZ;
70
          }
71

  
72
        currX += DX;
73
        }
74

  
75
      startX-=DX/2;
76
      startY+=DY;
77
      startZ-=DZ/2;
78
      }
79
    }
80

  
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82

  
83
  float[] getDist3D()
84
    {
85
    float d = mSize[0]*SQ6/12;
86
    return new float[] {d,d,d,d};
87
    }
88

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

  
91
  float getDist2D()
92
    {
93
    return SQ3/6;
94
    }
95

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

  
98
  int[] getColors()
99
    {
100
    return ShapeTetrahedron.FACE_COLORS;
101
    }
102

  
103
///////////////////////////////////////////////////////////////////////////////////////////////////
104

  
105
  Static3D[] getFaceAxis()
106
    {
107
    return TouchControlTetrahedron.FACE_AXIS;
108
    }
109

  
110
///////////////////////////////////////////////////////////////////////////////////////////////////
111

  
112
  boolean tryChangeObject(int x, int y, int z)
113
    {
114
    if( mSize[0]!=x )
115
      {
116
      mSize[0] = x;
117
      mMax = mSize[0];
118
      int numOcta = (x-1)*x*(x+1)/6;
119
      int numTetra= x*(x+1)*(x+2)/6;
120
      mNumCubits = numOcta + numTetra;
121
      return true;
122
      }
123

  
124
    return false;
125
    }
126

  
127
///////////////////////////////////////////////////////////////////////////////////////////////////
128

  
129
  int computeProjectionAngle()
130
    {
131
    return 120;
132
    }
133

  
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135

  
136
  boolean isAdjacent(float dx, float dy, float dz)
137
    {
138
    return dx*dx + dy*dy + dz*dz < (SQ3/4)*1.01f;
139
    }
140

  
141
///////////////////////////////////////////////////////////////////////////////////////////////////
142

  
143
  float[][][] getPositions()
144
    {
145
    int num = mSize[0];
146
    int numO= (num-1)*num*(num+1)/6;
147
    int numT= (num+1)*num*(num+2)/6;
148

  
149
    float[][] retO = new float[numO][];
150
    float[][] retT = new float[numT][];
151

  
152
    addTetrahedralLattice(num-1,retO);
153
    addTetrahedralLattice(num  ,retT);
154

  
155
    return new float[][][] { retO,retT };
156
    }
157

  
158
///////////////////////////////////////////////////////////////////////////////////////////////////
159

  
160
  boolean isInsideFace(int face, float[] p)
161
    {
162
    float y = (isFaceInverted(face) ? p[1] : -p[1]);
163
    float x = p[0];
164
    return (y >= -mDist2D) && (y <= mDist2D*(2-6*x)) && (y <= mDist2D*(2+6*x));
165
    }
166

  
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168

  
169
  MeshBase createMesh(float[] pos, boolean round)
170
    {
171
    FactoryBandagedPyraminx factory = FactoryBandagedPyraminx.getInstance();
172
    return factory.createMesh(pos,mSize,false,round);
173
    }
174

  
175
///////////////////////////////////////////////////////////////////////////////////////////////////
176

  
177
  TwistyObject createObject(int mode, float size)
178
    {
179
    float[][] pos = getCubitPositions();
180
    InitData data = new InitData( mSize,pos);
181
    return new TwistyBandagedPyraminx( TwistyObject.MESH_NICE, mode, ShapeTetrahedron.DEFAULT_ROT, new Static3D(0,0,0), size, data, null );
182
    }
183
}

Also available in: Unified diff