Project

General

Profile

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

magiccube / src / main / java / org / distorted / bandaged / BandagedCubit.java @ f3b3c087

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.FactoryBandagedCubit;
30
import org.distorted.objectlib.helpers.FactoryCubit;
31

    
32
import static org.distorted.objectlib.main.TwistyObject.COLOR_BLUE;
33
import static org.distorted.objectlib.main.TwistyObject.COLOR_GREEN;
34
import static org.distorted.objectlib.main.TwistyObject.COLOR_ORANGE;
35
import static org.distorted.objectlib.main.TwistyObject.COLOR_RED;
36
import static org.distorted.objectlib.main.TwistyObject.COLOR_WHITE;
37
import static org.distorted.objectlib.main.TwistyObject.COLOR_YELLOW;
38

    
39
///////////////////////////////////////////////////////////////////////////////////////////////////
40

    
41
public class BandagedCubit
42
{
43
    private static final Static3D CENTER = new Static3D(0,0,0);
44
    private static final float[] mTmp = new float[4];
45
    private static final Static1D mAlpha = new Static1D(2.0f);
46
    private static Bitmap mBitmap;
47
    private static Static4D[] mTextureMaps;
48

    
49
    private final DistortedNode mNode;
50
    private final DistortedEffects mEffects;
51
    private final DistortedTexture mTexture;
52
    private final Static3D mMove;
53
    private final boolean mRoundCorners;
54
    private final int mX, mY, mZ;
55

    
56
    private float mUnscaledX, mUnscaledY, mUnscaledZ;
57
    private float[] mPosition;
58
    private boolean mIsAttached;
59
    private long mMarkedEffectID;
60

    
61
///////////////////////////////////////////////////////////////////////////////////////////////////
62

    
63
    private static void createBitmap()
64
      {
65
      final int[] FACE_COLORS = new int[]
66
         {
67
           COLOR_YELLOW, COLOR_WHITE,
68
           COLOR_BLUE  , COLOR_GREEN,
69
           COLOR_RED   , COLOR_ORANGE
70
         };
71
      final int NUM = FACE_COLORS.length;
72
      final int SIZE= 32;
73

    
74
      mTextureMaps = new Static4D[NUM];
75

    
76
      Paint paint = new Paint();
77
      paint.setStyle(Paint.Style.FILL);
78
      mBitmap = Bitmap.createBitmap( NUM*SIZE, SIZE, Bitmap.Config.ARGB_4444);
79
      Canvas canvas = new Canvas(mBitmap);
80

    
81
      for(int color=0; color<NUM; color++)
82
        {
83
        paint.setColor(FACE_COLORS[color]);
84
        canvas.drawRect(color*SIZE, 0, (color+1)*SIZE, SIZE, paint);
85
        mTextureMaps[color] = new Static4D( ((float)color)/NUM, 0.0f, 1.0f/NUM, 1.0f );
86
        }
87
      }
88

    
89
///////////////////////////////////////////////////////////////////////////////////////////////////
90
// (x,y,z) ==
91
//
92
// ( 1,0,0) --> 0
93
// (-1,0,0) --> 1
94
// (0, 1,0) --> 2
95
// (0,-1,0) --> 3
96
// (0,0, 1) --> 4
97
// (0,0,-1) --> 5
98

    
99
    private int computeMapsIndex(float x, float y, float z)
100
      {
101
      int ix = x>0 ? (int)(x+0.5f) : (int)(x-0.5f);
102
      int iy = y>0 ? (int)(y+0.5f) : (int)(y-0.5f);
103
      int iz = z>0 ? (int)(z+0.5f) : (int)(z-0.5f);
104

    
105
      if( ix== 1 ) return 0;
106
      if( ix==-1 ) return 1;
107
      if( iy== 1 ) return 2;
108
      if( iy==-1 ) return 3;
109
      if( iz== 1 ) return 4;
110
      if( iz==-1 ) return 5;
111

    
112
      return 0;
113
      }
114

    
115
///////////////////////////////////////////////////////////////////////////////////////////////////
116

    
117
    private void resetTextureMaps(MeshBase mesh)
118
      {
119
      FactoryCubit fact = FactoryCubit.getInstance();
120
      int numComponents = mesh.getNumTexComponents();
121
      Static4D[] maps = new Static4D[numComponents];
122

    
123
      for(int i=0; i<numComponents; i++)
124
        {
125
        Static4D q = fact.getQuaternion(i);
126
        QuatHelper.rotateVectorByQuat(mTmp,0,0,1,0,q);
127
        int index = computeMapsIndex(mTmp[0], mTmp[1], mTmp[2]);
128
        maps[i] = mTextureMaps[index];
129
        }
130

    
131
      mesh.setTextureMap(maps,0);
132
      }
133

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

    
136
    private void computeMove(float[] position)
137
      {
138
      int numCenters = position.length/3;
139
      mUnscaledX=0.0f;
140
      mUnscaledY=0.0f;
141
      mUnscaledZ=0.0f;
142

    
143
      for(int center=0; center<numCenters; center++)
144
        {
145
        mUnscaledX += position[3*center  ];
146
        mUnscaledY += position[3*center+1];
147
        mUnscaledZ += position[3*center+2];
148
        }
149

    
150
      mUnscaledX /= numCenters;
151
      mUnscaledY /= numCenters;
152
      mUnscaledZ /= numCenters;
153
      }
154

    
155
///////////////////////////////////////////////////////////////////////////////////////////////////
156
// PUBLIC API
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
    public BandagedCubit(float[] position, int x, int y, int z, Static4D quat1,
160
                         Static4D quat2, Static3D scale, boolean roundCorners)
161
      {
162
      mX = x;
163
      mY = y;
164
      mZ = z;
165
      mRoundCorners = roundCorners;
166
      mPosition = position;
167
      mIsAttached = true;
168
      mMarkedEffectID = -1;
169

    
170
      computeMove(mPosition);
171
      mMove = new Static3D(0,0,0);
172

    
173
      FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
174
      MeshBase mesh = factory.createMesh(mPosition,mX,mY,mZ,false,mRoundCorners);
175

    
176
      mTexture = new DistortedTexture();
177
      if( mBitmap==null ) createBitmap();
178
      mTexture.setTextureAlreadyInverted(mBitmap);
179

    
180
      resetTextureMaps(mesh);
181

    
182
      MatrixEffectScale scaleEffect = new MatrixEffectScale(scale);
183
      MatrixEffectQuaternion quat1Effect = new MatrixEffectQuaternion(quat1, CENTER);
184
      MatrixEffectQuaternion quat2Effect = new MatrixEffectQuaternion(quat2, CENTER);
185
      MatrixEffectMove moveEffect = new MatrixEffectMove(mMove);
186

    
187
      mEffects = new DistortedEffects();
188
      mEffects.apply(scaleEffect);
189
      mEffects.apply(moveEffect);
190
      mEffects.apply(quat2Effect);
191
      mEffects.apply(quat1Effect);
192

    
193
      mNode = new DistortedNode(mTexture,mEffects,mesh);
194
      }
195

    
196
///////////////////////////////////////////////////////////////////////////////////////////////////
197

    
198
    public void join(float[] position, float scale)
199
      {
200
      int len1 = mPosition.length;
201
      int len2 = position.length;
202

    
203
      float[] tmpPosition = new float[len1+len2];
204

    
205
      System.arraycopy(mPosition, 0, tmpPosition,    0, len1);
206
      System.arraycopy(position , 0, tmpPosition, len1, len2);
207

    
208
      computeMove(tmpPosition);
209
      mPosition = tmpPosition;
210

    
211
      FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
212
      MeshBase mesh = factory.createMesh(mPosition,mX,mY,mZ,false,mRoundCorners);
213
      resetTextureMaps(mesh);
214
      mNode.setMesh(mesh);
215
      mMove.set( scale*mUnscaledX, scale*mUnscaledY, scale*mUnscaledZ);
216
      }
217

    
218
///////////////////////////////////////////////////////////////////////////////////////////////////
219

    
220
    public void reset(float scale)
221
      {
222
      float x = mPosition[0];
223
      float y = mPosition[1];
224
      float z = mPosition[2];
225

    
226
      mPosition = new float[3];
227
      mPosition[0] = x;
228
      mPosition[1] = y;
229
      mPosition[2] = z;
230

    
231
      computeMove(mPosition);
232

    
233
      FactoryBandagedCubit factory = FactoryBandagedCubit.getInstance();
234
      MeshBase mesh = factory.createMesh(mPosition,mX,mY,mZ,false,mRoundCorners);
235
      resetTextureMaps(mesh);
236
      mNode.setMesh(mesh);
237
      mMove.set( scale*mUnscaledX, scale*mUnscaledY, scale*mUnscaledZ);
238
      }
239

    
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241

    
242
    public void recreateBitmap()
243
      {
244
      if( mBitmap==null ) createBitmap();
245
      mTexture.setTextureAlreadyInverted(mBitmap);
246
      }
247

    
248
///////////////////////////////////////////////////////////////////////////////////////////////////
249

    
250
    public void scaleMove(float scale)
251
      {
252
      mMove.set( scale*mUnscaledX, scale*mUnscaledY, scale*mUnscaledZ);
253
      }
254

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

    
257
    public void setMarked()
258
      {
259
      if( mMarkedEffectID<0 )
260
        {
261
        FragmentEffectBrightness effect = new FragmentEffectBrightness(mAlpha);
262
        mMarkedEffectID = effect.getID();
263
        mEffects.apply(effect);
264
        }
265
      }
266

    
267
///////////////////////////////////////////////////////////////////////////////////////////////////
268

    
269
    public void setUnmarked()
270
      {
271
      mEffects.abortByType(EffectType.FRAGMENT);
272
      mMarkedEffectID = -1;
273
      }
274

    
275
///////////////////////////////////////////////////////////////////////////////////////////////////
276

    
277
    public void detach()
278
      {
279
      mIsAttached = false;
280
      }
281

    
282
///////////////////////////////////////////////////////////////////////////////////////////////////
283

    
284
    public void attach()
285
      {
286
      mIsAttached = true;
287
      }
288

    
289
///////////////////////////////////////////////////////////////////////////////////////////////////
290

    
291
    public boolean isAttached()
292
      {
293
      return mIsAttached;
294
      }
295

    
296
///////////////////////////////////////////////////////////////////////////////////////////////////
297

    
298
    public float[] getPosition()
299
      {
300
      return mPosition;
301
      }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

    
305
    public DistortedNode getNode()
306
      {
307
      return mNode;
308
      }
309
}
310

    
(8-8/13)