Project

General

Profile

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

magiccube / src / main / java / org / distorted / bandaged / BandagedCubit.java @ 306aa049

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.FragmentEffectBrightness;
17
import org.distorted.library.effect.MatrixEffectMove;
18
import org.distorted.library.effect.MatrixEffectQuaternion;
19
import org.distorted.library.effect.MatrixEffectScale;
20
import org.distorted.library.main.DistortedEffects;
21
import org.distorted.library.main.DistortedNode;
22
import org.distorted.library.main.DistortedTexture;
23
import org.distorted.library.main.QuatHelper;
24
import org.distorted.library.mesh.MeshBase;
25
import org.distorted.library.type.Static1D;
26
import org.distorted.library.type.Static3D;
27
import org.distorted.library.type.Static4D;
28
import org.distorted.objectlib.helpers.FactoryBandagedCubit;
29
import org.distorted.objectlib.helpers.FactoryCubit;
30

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

    
38
///////////////////////////////////////////////////////////////////////////////////////////////////
39

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

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

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

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

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

    
73
      mTextureMaps = new Static4D[NUM];
74

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

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

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

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

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

    
111
      return 0;
112
      }
113

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

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

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

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

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

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

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

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

    
154
///////////////////////////////////////////////////////////////////////////////////////////////////
155
// PUBLIC API
156
///////////////////////////////////////////////////////////////////////////////////////////////////
157

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

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

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

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

    
179
      resetTextureMaps(mesh);
180

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

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

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

    
195
///////////////////////////////////////////////////////////////////////////////////////////////////
196

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

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

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

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

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

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

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

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

    
230
      computeMove(mPosition);
231

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

    
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240

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

    
247
///////////////////////////////////////////////////////////////////////////////////////////////////
248

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

    
254
///////////////////////////////////////////////////////////////////////////////////////////////////
255

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

    
266
///////////////////////////////////////////////////////////////////////////////////////////////////
267

    
268
    public void setUnmarked()
269
      {
270
      if( mMarkedEffectID>=0 )
271
        {
272
        mEffects.abortById(mMarkedEffectID);
273
        mMarkedEffectID = -1;
274
        }
275
      }
276

    
277
///////////////////////////////////////////////////////////////////////////////////////////////////
278

    
279
    public void detach()
280
      {
281
      mIsAttached = false;
282
      }
283

    
284
///////////////////////////////////////////////////////////////////////////////////////////////////
285

    
286
    public void attach()
287
      {
288
      mIsAttached = true;
289
      }
290

    
291
///////////////////////////////////////////////////////////////////////////////////////////////////
292

    
293
    public boolean isAttached()
294
      {
295
      return mIsAttached;
296
      }
297

    
298
///////////////////////////////////////////////////////////////////////////////////////////////////
299

    
300
    public float[] getPosition()
301
      {
302
      return mPosition;
303
      }
304

    
305
///////////////////////////////////////////////////////////////////////////////////////////////////
306

    
307
    public DistortedNode getNode()
308
      {
309
      return mNode;
310
      }
311
}
312

    
(8-8/13)