Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / json / JsonReader.java @ 7aae846c

1 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2021 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// it under the terms of the GNU General Public License as published by                          //
8
// the Free Software Foundation, either version 2 of the License, or                             //
9
// (at your option) any later version.                                                           //
10
//                                                                                               //
11
// Distorted is distributed in the hope that it will be useful,                                  //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20
package org.distorted.objectlib.json;
21
22
import java.io.BufferedReader;
23 bf52deb2 Leszek Koltunski
import java.io.File;
24
import java.io.FileInputStream;
25
import java.io.FileNotFoundException;
26 82eb152a Leszek Koltunski
import java.io.IOException;
27
import java.io.InputStream;
28
import java.io.InputStreamReader;
29
import java.nio.charset.StandardCharsets;
30
31 bf52deb2 Leszek Koltunski
import android.content.Context;
32
33 3ee1d662 Leszek Koltunski
import org.distorted.objectlib.helpers.ObjectFaceShape;
34 1d581993 Leszek Koltunski
import org.distorted.objectlib.helpers.ObjectSignature;
35 7aae846c Leszek Koltunski
import org.distorted.objectlib.main.Cubit;
36 1f656ca7 Leszek Koltunski
import org.distorted.objectlib.objects.TwistyBandagedCuboid;
37 82eb152a Leszek Koltunski
import org.json.JSONArray;
38
import org.json.JSONException;
39
import org.json.JSONObject;
40
41
import org.distorted.library.type.Static3D;
42
import org.distorted.library.type.Static4D;
43
44
import org.distorted.objectlib.helpers.ObjectShape;
45
import org.distorted.objectlib.helpers.ObjectSticker;
46 10b7e306 Leszek Koltunski
import org.distorted.objectlib.scrambling.ScrambleState;
47 82eb152a Leszek Koltunski
import org.distorted.objectlib.main.ObjectType;
48
49
///////////////////////////////////////////////////////////////////////////////////////////////////
50
51
public class JsonReader
52
{
53
  private ScrambleState[] mStates;
54
  private int[][] mSolvedQuats;
55
  private Static4D[] mQuats;
56
  private int mSolvedFuncIndex;
57
  private int mNumStickerTypes;
58
  private float[][] mCuts;
59
  private boolean[][] mLayerRotatable;
60
  private int mMovementType, mMovementSplit;
61
  private int[][][] mEnabled;
62
  private float[] mDist3D;
63 d66e98d7 Leszek Koltunski
  private int mNumCubitFaces, mNumFaces, mNumFaceColors;
64 82eb152a Leszek Koltunski
  private float[][] mPositions;
65
  private ObjectShape[] mShapes;
66 3ee1d662 Leszek Koltunski
  private ObjectFaceShape[] mFaceShapes;
67 82eb152a Leszek Koltunski
  private Static4D[] mCubitQuats;
68
  private int mNumCubitVariants;
69
  private int[] mCubitVariant;
70
  private int[][] mVariantFaceColor, mCubitFaceColor;
71
  private ObjectSticker[] mObjectSticker;
72
  private Static3D[] mAxis;
73 beee90ab Leszek Koltunski
  private int[][] mBasicAngle;
74 e1a86bf2 Leszek Koltunski
  private String mLongName, mShortName, mInventor;
75 82eb152a Leszek Koltunski
  private int mYearOfInvention, mComplexity;
76
  private int[] mNumLayers;
77
  private float mSize;
78 e1a86bf2 Leszek Koltunski
  private int mScrambleType, mNumScrambles;
79 82eb152a Leszek Koltunski
  private int[] mColor;
80 253e440f Leszek Koltunski
  private int mInternalColor;
81 0f72365b Leszek Koltunski
  private boolean mResetMaps;
82 052e0362 Leszek Koltunski
  private String mTutorialObject;
83
  private String[][] mTutorials;
84 1d581993 Leszek Koltunski
  private ObjectSignature mSignature;
85 7aae846c Leszek Koltunski
  private int[] mCubitType;
86
  private float[][] mCubitRowOffset;
87 82eb152a Leszek Koltunski
88 a2d6c41a Leszek Koltunski
  private static JsonReader mThis;
89
90
///////////////////////////////////////////////////////////////////////////////////////////////////
91
92
  private JsonReader()
93
    {
94
    }
95
96
///////////////////////////////////////////////////////////////////////////////////////////////////
97
98
  public static JsonReader getInstance()
99
    {
100
    if( mThis==null ) mThis = new JsonReader();
101
    return mThis;
102
    }
103
104 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
105
106 1d581993 Leszek Koltunski
  private void parseMetadata1(JSONObject object) throws JSONException
107 82eb152a Leszek Koltunski
    {
108
    mLongName        = object.getString("longname");
109 e1a86bf2 Leszek Koltunski
    mShortName       = object.getString("shortname");
110 82eb152a Leszek Koltunski
    mInventor        = object.getString("inventor");
111
    mYearOfInvention = object.getInt("year");
112
    mComplexity      = object.getInt("complexity");
113
    mSize            = (float)object.getDouble("size");
114 e1a86bf2 Leszek Koltunski
    mNumScrambles    = object.getInt("scrambles");
115 0f72365b Leszek Koltunski
    mResetMaps       = object.getBoolean("resetmaps");
116 a72cd106 Leszek Koltunski
    mNumFaces        = object.getInt("num_faces");
117 e1a86bf2 Leszek Koltunski
118 5f54927b Leszek Koltunski
    try
119
      {
120 1d581993 Leszek Koltunski
      long signature = object.getLong("signature");
121
      mSignature = new ObjectSignature(signature);
122 5f54927b Leszek Koltunski
      }
123
    catch(JSONException ex)
124
      {
125
      // objects older than Feb 2022 do not have the 'signature' field. They all use the ObjectType.ordinal
126
      // as their signature.
127 1d581993 Leszek Koltunski
      long signature = ObjectType.getOrdinal(mShortName);
128
      mSignature = new ObjectSignature(signature);
129
      }
130
    }
131
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133
134 7aae846c Leszek Koltunski
  private void parseMetadata2or3or4(JSONObject object) throws JSONException
135 1d581993 Leszek Koltunski
    {
136
    mLongName        = object.getString("longname");
137
    mShortName       = object.getString("shortname");
138
    mInventor        = object.getString("inventor");
139
    mYearOfInvention = object.getInt("year");
140
    mComplexity      = object.getInt("complexity");
141
    mSize            = (float)object.getDouble("size");
142
    mNumScrambles    = object.getInt("scrambles");
143
    mResetMaps       = object.getBoolean("resetmaps");
144
    mNumFaces        = object.getInt("num_faces");
145
146
    try
147
      {
148
      long signature1 = object.getLong("signature1");
149
      long signature2 = object.getLong("signature2");
150
      long signature3 = object.getLong("signature3");
151 efeca8ef Leszek Koltunski
152 dc369304 Leszek Koltunski
      switch( TwistyBandagedCuboid.getType(mShortName,mLongName) )
153 efeca8ef Leszek Koltunski
        {
154 1f656ca7 Leszek Koltunski
        case 0: mSignature = new ObjectSignature(signature1,signature2,signature3); break;
155
        case 1: mSignature = new ObjectSignature(mShortName,signature1,signature2,signature3); break;
156
        case 2: mSignature = new ObjectSignature("333",signature1,signature2,signature3); break;
157 efeca8ef Leszek Koltunski
        }
158 1d581993 Leszek Koltunski
      }
159
    catch(JSONException ex)
160
      {
161
      long signature = object.getLong("signature");
162
      mSignature = new ObjectSignature(signature);
163 5f54927b Leszek Koltunski
      }
164 82eb152a Leszek Koltunski
    }
165
166
///////////////////////////////////////////////////////////////////////////////////////////////////
167
168
  private void parseCubits(JSONArray object) throws JSONException
169
    {
170
    int numCubits = object.length();
171
172
    mCubitQuats     = new Static4D[numCubits];
173
    mCubitVariant   = new int[numCubits];
174
    mPositions      = new float[numCubits][];
175
    mCubitFaceColor = new int[numCubits][];
176 7aae846c Leszek Koltunski
    mCubitType      = new int[numCubits];
177
    mCubitRowOffset = new float[numCubits][];
178 82eb152a Leszek Koltunski
179
    for(int i=0; i<numCubits; i++)
180
      {
181
      JSONObject jsonCubit = object.getJSONObject(i);
182
183
      float qx = (float)jsonCubit.getDouble("qx");
184
      float qy = (float)jsonCubit.getDouble("qy");
185
      float qz = (float)jsonCubit.getDouble("qz");
186
      float qw = (float)jsonCubit.getDouble("qw");
187
188
      mCubitQuats[i] = new Static4D(qx,qy,qz,qw);
189
      mCubitVariant[i] = jsonCubit.getInt("variant");
190
191
      JSONArray jsonCenter = jsonCubit.getJSONArray("centers");
192
      int numCenter = jsonCenter.length();
193
      mPositions[i] = new float[numCenter];
194
      for(int j=0; j<numCenter; j++) mPositions[i][j] = (float)jsonCenter.getDouble(j);
195
196
      JSONArray jsonColor  = jsonCubit.getJSONArray("colors");
197
      int numColor = jsonColor.length();
198
      mCubitFaceColor[i] = new int[numColor];
199
      for(int j=0; j<numColor; j++) mCubitFaceColor[i][j] = jsonColor.getInt(j);
200 7aae846c Leszek Koltunski
201
      mCubitType[i] = (int)jsonCubit.optInt("type", Cubit.TYPE_NORMAL);
202
      float xoff = (float)jsonCubit.optDouble("offsetX", 0 );
203
      float yoff = (float)jsonCubit.optDouble("offsetY", 0 );
204
      float zoff = (float)jsonCubit.optDouble("offsetZ", 0 );
205
      mCubitRowOffset[i] = new float[] {xoff,yoff,zoff};
206 82eb152a Leszek Koltunski
      }
207
    }
208
209
///////////////////////////////////////////////////////////////////////////////////////////////////
210
211
  private void parseShapes(JSONArray object) throws JSONException
212
    {
213
    mNumCubitVariants = object.length();
214
    mVariantFaceColor = new int[mNumCubitVariants][];
215 3ee1d662 Leszek Koltunski
    mShapes     = new ObjectShape[mNumCubitVariants];
216
    mFaceShapes = new ObjectFaceShape[mNumCubitVariants];
217 57ef6378 Leszek Koltunski
    float[][][] verts     = new float[mNumCubitVariants][][];
218
    float[][][] bands     = new float[mNumCubitVariants][][];
219
    float[][][] corners   = new float[mNumCubitVariants][][];
220
    float[][][] centers   = new float[mNumCubitVariants][][];
221
    float[][] convexity   = new float[mNumCubitVariants][];
222 82eb152a Leszek Koltunski
    int[][] cornerIndices = new int[mNumCubitVariants][];
223
    int[][] centerIndices = new int[mNumCubitVariants][];
224 57ef6378 Leszek Koltunski
    int[][] bandIndices   = new int[mNumCubitVariants][];
225 82eb152a Leszek Koltunski
    int[][][] vertIndices = new int[mNumCubitVariants][][];
226
227 d66e98d7 Leszek Koltunski
    mNumCubitFaces = -1;
228
229 82eb152a Leszek Koltunski
    for(int i=0; i<mNumCubitVariants; i++)
230
      {
231
      JSONObject jsonShape = object.getJSONObject(i);
232
233
      ////// vertices /////////////////////////////////////////////////
234
      JSONArray jsonVertices= jsonShape.getJSONArray("vertices");
235
      int numVertices = jsonVertices.length();
236 57ef6378 Leszek Koltunski
      verts[i] = new float[numVertices][3];
237 82eb152a Leszek Koltunski
      cornerIndices[i] = new int[numVertices];
238
      centerIndices[i] = new int[numVertices];
239
240
      for(int j=0; j<numVertices; j++)
241
        {
242
        JSONObject vert = jsonVertices.getJSONObject(j);
243 57ef6378 Leszek Koltunski
        verts[i][j][0] = (float)vert.getDouble("x");
244
        verts[i][j][1] = (float)vert.getDouble("y");
245
        verts[i][j][2] = (float)vert.getDouble("z");
246 82eb152a Leszek Koltunski
        cornerIndices[i][j] = vert.getInt("cornerIndex");
247
        centerIndices[i][j] = vert.getInt("centerIndex");
248
        }
249
250
      ////// faces ////////////////////////////////////////////////////
251
      JSONArray jsonFaces= jsonShape.getJSONArray("faces");
252
      int numFaces = jsonFaces.length();
253
      mVariantFaceColor[i] = new int[numFaces];
254
      bandIndices[i] = new int[numFaces];
255
      vertIndices[i] = new int[numFaces][];
256
257 d66e98d7 Leszek Koltunski
      if( mNumCubitFaces<numFaces ) mNumCubitFaces=numFaces;
258
259 82eb152a Leszek Koltunski
      for(int j=0; j<numFaces; j++)
260
        {
261
        JSONObject jsonFace = jsonFaces.getJSONObject(j);
262
        mVariantFaceColor[i][j] = jsonFace.getInt("sticker");
263
        bandIndices[i][j] = jsonFace.getInt("bandIndex");
264
        JSONArray vertices = jsonFace.getJSONArray("vertexIndices");
265
        int numV = vertices.length();
266
        vertIndices[i][j] = new int[numV];
267
        for(int k=0; k<numV; k++) vertIndices[i][j][k] = vertices.getInt(k);
268
        }
269
270
      ////// bands ////////////////////////////////////////////////////
271
      JSONArray jsonBands= jsonShape.getJSONArray("bands");
272
      int numBands = jsonBands.length();
273
      bands[i] = new float[numBands][7];
274
275
      for(int j=0; j<numBands; j++)
276
        {
277
        JSONObject jsonBand = jsonBands.getJSONObject(j);
278
279
        bands[i][j][0] = (float)jsonBand.getDouble("height");
280
        bands[i][j][1] = (float)jsonBand.getDouble("angle");
281
        bands[i][j][2] = (float)jsonBand.getDouble("distanceToCenter");
282
        bands[i][j][3] = (float)jsonBand.getDouble("distanceToFlat");
283
        bands[i][j][4] = (float)jsonBand.getDouble("numOfBands");
284
        bands[i][j][5] = (float)jsonBand.getDouble("extraI");
285
        bands[i][j][6] = (float)jsonBand.getDouble("extraJ");
286
        }
287
288
      ////// cornerPush ///////////////////////////////////////////////
289 9e8eb9e4 Leszek Koltunski
      JSONArray jsonCornerPush= jsonShape.optJSONArray("cornerPush");
290 82eb152a Leszek Koltunski
291 9e8eb9e4 Leszek Koltunski
      if( jsonCornerPush!=null )
292 82eb152a Leszek Koltunski
        {
293 9e8eb9e4 Leszek Koltunski
        int numCornerP = jsonCornerPush.length();
294
        corners[i] = new float[numCornerP][2];
295
296
        for(int j=0; j<numCornerP; j++)
297
          {
298
          JSONObject jsonC = jsonCornerPush.getJSONObject(j);
299
          corners[i][j][0] = (float)jsonC.getDouble("strength");
300
          corners[i][j][1] = (float)jsonC.getDouble("radius");
301
          }
302 82eb152a Leszek Koltunski
        }
303
304
      ////// centerPush ///////////////////////////////////////////////
305 9e8eb9e4 Leszek Koltunski
      JSONArray jsonCenterPush= jsonShape.optJSONArray("centerPush");
306 82eb152a Leszek Koltunski
307 9e8eb9e4 Leszek Koltunski
      if( jsonCenterPush!=null )
308 82eb152a Leszek Koltunski
        {
309 9e8eb9e4 Leszek Koltunski
        int numCenterP = jsonCenterPush.length();
310
        centers[i] = new float[numCenterP][3];
311
312
        for(int j=0; j<numCenterP; j++)
313
          {
314
          JSONObject jsonC = jsonCenterPush.getJSONObject(j);
315
          centers[i][j][0] = (float)jsonC.getDouble("x");
316
          centers[i][j][1] = (float)jsonC.getDouble("y");
317
          centers[i][j][2] = (float)jsonC.getDouble("z");
318
          }
319 82eb152a Leszek Koltunski
        }
320
321
      ////// convexity ///////////////////////////////////////////////
322 9e8eb9e4 Leszek Koltunski
      JSONObject jsonConvexity = jsonShape.optJSONObject("convexity");
323
324
      if( jsonConvexity!=null )
325 82eb152a Leszek Koltunski
        {
326
        convexity[i] = new float[3];
327
        convexity[i][0] = (float)jsonConvexity.getDouble("x");
328
        convexity[i][1] = (float)jsonConvexity.getDouble("y");
329
        convexity[i][2] = (float)jsonConvexity.getDouble("z");
330
        }
331
      }
332
333
    for(int i=0; i<mNumCubitVariants; i++)
334
      {
335 59a971c1 Leszek Koltunski
      mShapes[i] = new ObjectShape(verts[i],vertIndices[i]);
336 3ee1d662 Leszek Koltunski
      mFaceShapes[i] = new ObjectFaceShape(bands[i],bandIndices[i],corners[i],cornerIndices[i],centers[i],centerIndices[i],convexity[i] );
337 82eb152a Leszek Koltunski
      }
338
    }
339
340
///////////////////////////////////////////////////////////////////////////////////////////////////
341
342
  private void parseStickers(JSONArray object) throws JSONException
343
    {
344
    mNumStickerTypes = object.length();
345
    mObjectSticker = new ObjectSticker[mNumStickerTypes];
346
347
    for(int i=0; i<mNumStickerTypes; i++)
348
      {
349
      JSONObject sticker = object.getJSONObject(i);
350
      float stroke = (float)sticker.getDouble("stroke");
351
      JSONArray vertices = sticker.getJSONArray("vertices");
352
      int numVertices = vertices.length();
353
354
      float[] coords     = new float[2*numVertices];
355
      float[] curvatures = new float[numVertices];
356
      float[] radii      = new float[numVertices];
357
358
      for(int j=0; j<numVertices; j++)
359
        {
360
        JSONObject vertex = vertices.getJSONObject(j);
361
362
        coords[2*j  ] = (float)vertex.getDouble("x");
363
        coords[2*j+1] = (float)vertex.getDouble("y");
364
        curvatures[j] = (float)vertex.getDouble("angle");
365
        radii[j]      = (float)vertex.getDouble("radius");
366
        }
367
368
      mObjectSticker[i] = new ObjectSticker(coords,curvatures,radii,stroke);
369
      }
370
    }
371
372
///////////////////////////////////////////////////////////////////////////////////////////////////
373
374
  private void parseMesh(JSONObject object) throws JSONException
375
    {
376
    JSONArray cubits   = object.getJSONArray("cubits");
377
    parseCubits(cubits);
378
    JSONArray shapes   = object.getJSONArray("shapes");
379
    parseShapes(shapes);
380
    JSONArray stickers = object.getJSONArray("stickers");
381
    parseStickers(stickers);
382
    }
383
384
///////////////////////////////////////////////////////////////////////////////////////////////////
385
386 beee90ab Leszek Koltunski
  private void parseAxis1(JSONArray object) throws JSONException
387 82eb152a Leszek Koltunski
    {
388
    int numAxis = object.length();
389
390 beee90ab Leszek Koltunski
    mBasicAngle     = new int[numAxis][];
391 82eb152a Leszek Koltunski
    mAxis           = new Static3D[numAxis];
392
    mCuts           = new float[numAxis][];
393
    mLayerRotatable = new boolean[numAxis][];
394
    mNumLayers      = new int[numAxis];
395
396
    for(int i=0; i<numAxis; i++)
397
      {
398
      JSONObject jsonAx = object.getJSONObject(i);
399
400 beee90ab Leszek Koltunski
      float x = (float)jsonAx.getDouble("x");
401
      float y = (float)jsonAx.getDouble("y");
402
      float z = (float)jsonAx.getDouble("z");
403
404
      mAxis[i] = new Static3D(x,y,z);
405
406
      JSONArray jsonCuts = jsonAx.getJSONArray("cuts");
407
      int numCuts = jsonCuts.length();
408
      mCuts[i] = new float[numCuts];
409
      for(int j=0; j<numCuts; j++) mCuts[i][j] = (float)jsonCuts.getDouble(j);
410
411
      JSONArray jsonRota = jsonAx.getJSONArray("rotatable");
412
      int numRota = jsonRota.length();
413
      mLayerRotatable[i] = new boolean[numRota];
414
      for(int j=0; j<numRota; j++) mLayerRotatable[i][j] = jsonRota.getBoolean(j);
415
416
      mBasicAngle[i] = new int[numRota];
417
      int basicAngle = jsonAx.getInt("basicAngle");
418
      for(int j=0; j<numRota; j++) mBasicAngle[i][j] = basicAngle;
419
420
      mNumLayers[i] = numRota;
421
      }
422
    }
423
424
///////////////////////////////////////////////////////////////////////////////////////////////////
425
426 7aae846c Leszek Koltunski
  private void parseAxis2or3or4(JSONArray object) throws JSONException
427 beee90ab Leszek Koltunski
    {
428
    int numAxis = object.length();
429
430
    mBasicAngle     = new int[numAxis][];
431
    mAxis           = new Static3D[numAxis];
432
    mCuts           = new float[numAxis][];
433
    mLayerRotatable = new boolean[numAxis][];
434
    mNumLayers      = new int[numAxis];
435
436
    for(int i=0; i<numAxis; i++)
437
      {
438
      JSONObject jsonAx = object.getJSONObject(i);
439 82eb152a Leszek Koltunski
440
      float x = (float)jsonAx.getDouble("x");
441
      float y = (float)jsonAx.getDouble("y");
442
      float z = (float)jsonAx.getDouble("z");
443
444
      mAxis[i] = new Static3D(x,y,z);
445
446 beee90ab Leszek Koltunski
      JSONArray jsonAngles = jsonAx.getJSONArray("basicAngles");
447
      int numAngles = jsonAngles.length();
448
      mBasicAngle[i] = new int[numAngles];
449
      for(int j=0; j<numAngles; j++) mBasicAngle[i][j] = jsonAngles.getInt(j);
450
451 82eb152a Leszek Koltunski
      JSONArray jsonCuts = jsonAx.getJSONArray("cuts");
452
      int numCuts = jsonCuts.length();
453
      mCuts[i] = new float[numCuts];
454
      for(int j=0; j<numCuts; j++) mCuts[i][j] = (float)jsonCuts.getDouble(j);
455
456
      JSONArray jsonRota = jsonAx.getJSONArray("rotatable");
457
      int numRota = jsonRota.length();
458
      mLayerRotatable[i] = new boolean[numRota];
459
      for(int j=0; j<numRota; j++) mLayerRotatable[i][j] = jsonRota.getBoolean(j);
460
461
      mNumLayers[i] = numRota;
462
      }
463
    }
464
465
///////////////////////////////////////////////////////////////////////////////////////////////////
466
467
  private void parseQuats(JSONArray object) throws JSONException
468
    {
469
    int numQuats = object.length();
470
    mQuats = new Static4D[numQuats];
471
472
    for(int i=0; i<numQuats; i++)
473
      {
474
      JSONObject jsonQuat = object.getJSONObject(i);
475
476
      float x = (float)jsonQuat.getDouble("x");
477
      float y = (float)jsonQuat.getDouble("y");
478
      float z = (float)jsonQuat.getDouble("z");
479
      float w = (float)jsonQuat.getDouble("w");
480
481
      mQuats[i] = new Static4D(x,y,z,w);
482
      }
483
    }
484
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486
487
  private void parseScrambling(JSONObject object) throws JSONException
488
    {
489
    mScrambleType = object.getInt("scrambleType");
490
491
    if( mScrambleType==0 )
492
      {
493
      JSONArray jsonStates = object.getJSONArray("scrambleStates");
494
      int numStates = jsonStates.length();
495
      mStates = new ScrambleState[numStates];
496
497
      for(int i=0; i<numStates; i++)
498
        {
499
        JSONArray jsonState = jsonStates.getJSONArray(i);
500
        int numAxis = jsonState.length();
501
        int[][] scramblingData = new int[numAxis][];
502
503
        for(int j=0; j<numAxis; j++)
504
          {
505
          JSONArray jsonData = jsonState.getJSONArray(j);
506
          int numData = jsonData.length();
507
          scramblingData[j] = new int[numData];
508
          for(int k=0; k<numData; k++) scramblingData[j][k] = jsonData.getInt(k);
509
          }
510
511
        mStates[i] = new ScrambleState(scramblingData);
512
        }
513
      }
514
    }
515
516
///////////////////////////////////////////////////////////////////////////////////////////////////
517
518
  private void parseTouchcontrol(JSONObject object) throws JSONException
519
    {
520
    mMovementType = object.getInt("movementType");
521
    mMovementSplit= object.getInt("movementSplit");
522
523 82904e62 Leszek Koltunski
    try
524 82eb152a Leszek Koltunski
      {
525 82904e62 Leszek Koltunski
      JSONArray jsonEnabled = object.getJSONArray("enabledAxis");
526
      int numFace = jsonEnabled.length();
527 82eb152a Leszek Koltunski
528 82904e62 Leszek Koltunski
      mEnabled = new int[numFace][][];
529
530
      for(int i=0; i<numFace; i++)
531 82eb152a Leszek Koltunski
        {
532 82904e62 Leszek Koltunski
        JSONArray jsonSection = jsonEnabled.getJSONArray(i);
533
        int numSection = jsonSection.length();
534
        mEnabled[i] = new int[numSection][];
535
536
        for(int j=0; j<numSection; j++)
537
          {
538
          JSONArray jsonAx = jsonSection.getJSONArray(j);
539
          int numAxis = jsonAx.length();
540
          mEnabled[i][j] = new int[numAxis];
541
          for(int k=0; k<numAxis; k++) mEnabled[i][j][k] = jsonAx.getInt(k);
542
          }
543 82eb152a Leszek Koltunski
        }
544
      }
545 82904e62 Leszek Koltunski
    catch( JSONException ex )
546
      {
547
      // ignore, the object does not have to have 'enabledAxis' defined at all.
548
      }
549 82eb152a Leszek Koltunski
550
    try
551
      {
552
      JSONArray jsonDist = object.getJSONArray("dist3D");
553 a72cd106 Leszek Koltunski
      int num = jsonDist.length();
554
      mDist3D = new float[num];
555
      for(int j=0; j<num; j++) mDist3D[j] = (float)jsonDist.getDouble(j);
556 82eb152a Leszek Koltunski
      }
557
    catch( JSONException ex )
558
      {
559 a72cd106 Leszek Koltunski
      // ignore, the object does not have a 'dist3D' which is possible.
560 82eb152a Leszek Koltunski
      }
561
    }
562
563
///////////////////////////////////////////////////////////////////////////////////////////////////
564
565
  private void parseColors(JSONArray object) throws JSONException
566
    {
567 253e440f Leszek Koltunski
    mNumFaceColors = object.length()-1;
568
569 82eb152a Leszek Koltunski
    mColor = new int[mNumFaceColors];
570
    for(int i=0; i<mNumFaceColors; i++) mColor[i] = object.getInt(i);
571 253e440f Leszek Koltunski
572
    mInternalColor = object.getInt(mNumFaceColors);
573 82eb152a Leszek Koltunski
    }
574
575 3c48fab9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
576
577
  private void parseSolved(JSONObject solved) throws JSONException
578
    {
579
    mSolvedFuncIndex = solved.getInt("functionIndex");
580
581
    try
582
      {
583
      JSONArray groupArray= solved.getJSONArray("groups");
584
      int numGroups = groupArray.length();
585
      mSolvedQuats  = new int[numGroups][];
586
587
      for(int i=0; i<numGroups; i++)
588
        {
589
        JSONArray groupElements = groupArray.getJSONArray(i);
590
        int groupSize = groupElements.length();
591
        mSolvedQuats[i] = new int[groupSize];
592
        for(int j=0; j<groupSize; j++) mSolvedQuats[i][j] = groupElements.getInt(j);
593
        }
594
      }
595
    catch( JSONException ex )
596
      {
597
      // ignore, the object does not have to have an array of solved groups.
598
      }
599
    }
600
601 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
602
603
  private void parseVersion1(JSONObject object) throws JSONException
604
    {
605
    JSONObject metadata    = object.getJSONObject("metadata");
606 1d581993 Leszek Koltunski
    parseMetadata1(metadata);
607 82eb152a Leszek Koltunski
    JSONObject mesh        = object.getJSONObject("mesh");
608
    parseMesh(mesh);
609
    JSONArray axis         = object.getJSONArray("axis");
610 beee90ab Leszek Koltunski
    parseAxis1(axis);
611
    JSONArray quats        = object.getJSONArray("quats");
612
    parseQuats(quats);
613
    JSONObject scrambling  = object.getJSONObject("scrambling");
614
    parseScrambling(scrambling);
615
    JSONObject touchcontrol= object.getJSONObject("touchcontrol");
616
    parseTouchcontrol(touchcontrol);
617
    JSONArray colors       = object.getJSONArray("colors");
618
    parseColors(colors);
619
    JSONObject solved      = object.getJSONObject("solved");
620
    parseSolved(solved);
621
    }
622
623
///////////////////////////////////////////////////////////////////////////////////////////////////
624
625 7aae846c Leszek Koltunski
  private void parseVersion2or3or4(JSONObject object) throws JSONException
626 beee90ab Leszek Koltunski
    {
627
    JSONObject metadata    = object.getJSONObject("metadata");
628 7aae846c Leszek Koltunski
    parseMetadata2or3or4(metadata);
629 beee90ab Leszek Koltunski
    JSONObject mesh        = object.getJSONObject("mesh");
630
    parseMesh(mesh);
631
    JSONArray axis         = object.getJSONArray("axis");
632 7aae846c Leszek Koltunski
    parseAxis2or3or4(axis);
633 82eb152a Leszek Koltunski
    JSONArray quats        = object.getJSONArray("quats");
634
    parseQuats(quats);
635
    JSONObject scrambling  = object.getJSONObject("scrambling");
636
    parseScrambling(scrambling);
637
    JSONObject touchcontrol= object.getJSONObject("touchcontrol");
638
    parseTouchcontrol(touchcontrol);
639
    JSONArray colors       = object.getJSONArray("colors");
640
    parseColors(colors);
641 3c48fab9 Leszek Koltunski
    JSONObject solved      = object.getJSONObject("solved");
642
    parseSolved(solved);
643 82eb152a Leszek Koltunski
    }
644
645 052e0362 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
646
647
  private void parseVersion1Tutorial(JSONObject object) throws JSONException
648
    {
649
    mTutorialObject = object.getString("object");
650
    JSONArray tuts= object.getJSONArray("tutorials");
651
652
    int len = tuts.length();
653
    mTutorials = new String[len][4];
654
655
    for(int i=0; i<len; i++)
656
      {
657
      JSONObject tut = tuts.getJSONObject(i);
658
      mTutorials[i][0] = tut.getString("language");
659
      mTutorials[i][1] = tut.getString("link");
660
      mTutorials[i][2] = tut.getString("title");
661
      mTutorials[i][3] = tut.getString("author");
662
      }
663
    }
664
665 b39f8e39 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
666
667 1d581993 Leszek Koltunski
  private void parseVersion1Metadata(JSONObject object) throws JSONException
668
    {
669
    JSONObject metadata = object.getJSONObject("metadata");
670
    parseMetadata1(metadata);
671
    }
672
673
///////////////////////////////////////////////////////////////////////////////////////////////////
674
675 7aae846c Leszek Koltunski
  private void parseVersion2or3or4Metadata(JSONObject object) throws JSONException
676 b39f8e39 Leszek Koltunski
    {
677
    JSONObject metadata = object.getJSONObject("metadata");
678 7aae846c Leszek Koltunski
    parseMetadata2or3or4(metadata);
679 b39f8e39 Leszek Koltunski
    }
680
681 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
682
683
  public void parseJsonFile(InputStream jsonStream)
684
    {
685
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
686
687
    try
688
      {
689
      StringBuilder contents = new StringBuilder();
690
      String tmp;
691
      while( (tmp = br.readLine()) != null) contents.append(tmp);
692
      br.close();
693
      jsonStream.close();
694
695
      JSONObject object = new JSONObject(contents.toString());
696
      int major = object.getInt("major");
697
698 e7d3259a Leszek Koltunski
      if( major==1 )
699
        {
700
        parseVersion1(object);
701
        }
702 7aae846c Leszek Koltunski
      else if( major==2 || major==3 || major==4 )
703 e7d3259a Leszek Koltunski
        {
704 7aae846c Leszek Koltunski
        parseVersion2or3or4(object);
705 e7d3259a Leszek Koltunski
        }
706 82eb152a Leszek Koltunski
      else
707
        {
708
        android.util.Log.e("readJsonFile", "Unknown version "+major);
709
        }
710
      }
711
    catch(IOException e)
712
      {
713
      android.util.Log.e("readJsonFile", "Error reading JSON file: "+e.toString());
714
      }
715
    catch( JSONException e )
716
      {
717
      android.util.Log.e("parseJsonFile", "Error parsing JSON file: "+e.toString());
718
      }
719
    }
720
721 b39f8e39 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
722
723
  public void parseJsonFileMetadata(InputStream jsonStream)
724
    {
725
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
726
727
    try
728
      {
729
      StringBuilder contents = new StringBuilder();
730
      String tmp;
731
      while( (tmp = br.readLine()) != null) contents.append(tmp);
732
      br.close();
733
      jsonStream.close();
734
735
      JSONObject object = new JSONObject(contents.toString());
736
      int major = object.getInt("major");
737
738 1d581993 Leszek Koltunski
      if( major==1 )
739
        {
740
        parseVersion1Metadata(object);
741
        }
742 7aae846c Leszek Koltunski
      else if( major==2 || major==3 || major==4 )
743 b39f8e39 Leszek Koltunski
        {
744 7aae846c Leszek Koltunski
        parseVersion2or3or4Metadata(object);
745 b39f8e39 Leszek Koltunski
        }
746
      else
747
        {
748
        android.util.Log.e("readJsonFileQuick", "Unknown version "+major);
749
        }
750
      }
751
    catch(IOException e)
752
      {
753
      android.util.Log.e("readJsonFileQuick", "Error reading JSON file: "+e.toString());
754
      }
755
    catch( JSONException e )
756
      {
757
      android.util.Log.e("parseJsonFileQuick", "Error parsing JSON file: "+e.toString());
758
      }
759
    }
760
761 bf52deb2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
762
763 ef021035 Leszek Koltunski
  public int readNumScrambles(Context context, String fileName)
764 bf52deb2 Leszek Koltunski
    {
765
    File file = new File(context.getFilesDir(), fileName);
766
    InputStream stream;
767
768
    try
769
      {
770
      stream = new FileInputStream(file);
771 ef021035 Leszek Koltunski
      BufferedReader br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
772
773
      StringBuilder contents = new StringBuilder();
774
      String tmp;
775
      while( (tmp = br.readLine()) != null) contents.append(tmp);
776
      br.close();
777
      stream.close();
778
779
      JSONObject object = new JSONObject(contents.toString());
780 7aae846c Leszek Koltunski
      JSONObject metadata = object.getJSONObject("metadata");
781
      return metadata.getInt("scrambles");
782 bf52deb2 Leszek Koltunski
      }
783
    catch(FileNotFoundException ex)
784
      {
785 ef021035 Leszek Koltunski
      android.util.Log.e("readNumScrambles", "file "+fileName+" not found: "+ex.getMessage());
786 bf52deb2 Leszek Koltunski
      }
787 ef021035 Leszek Koltunski
    catch(IOException e)
788
      {
789
      android.util.Log.e("readNumScrambles", "Error reading JSON file: "+e.toString());
790
      }
791
    catch( JSONException e )
792
      {
793
      android.util.Log.e("readNumScrambles", "Error parsing JSON file: "+e.toString());
794
      }
795
796
    return 0;
797 bf52deb2 Leszek Koltunski
    }
798
799 052e0362 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
800
801
  public void parseJsonTutorial(InputStream jsonStream)
802
    {
803
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
804
805
    try
806
      {
807
      StringBuilder contents = new StringBuilder();
808
      String tmp;
809
      while( (tmp = br.readLine()) != null) contents.append(tmp);
810
      br.close();
811
      jsonStream.close();
812
813
      JSONObject object = new JSONObject(contents.toString());
814
      int major = object.getInt("major");
815
816
      if( major==1 )
817
        {
818
        parseVersion1Tutorial(object);
819
        }
820
      else
821
        {
822
        android.util.Log.e("readJsonFile", "Unknown tutorial version "+major);
823
        }
824
      }
825
    catch(IOException e)
826
      {
827
      android.util.Log.e("readJsonFile", "Error reading JSON file: "+e.toString());
828
      }
829
    catch( JSONException e )
830
      {
831
      android.util.Log.e("parseJsonFile", "Error parsing JSON file: "+e.toString());
832
      }
833
    }
834
835 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
836
837
  public ScrambleState[] getScrambleStates()
838
    {
839
    return mStates;
840
    }
841
842
///////////////////////////////////////////////////////////////////////////////////////////////////
843
844 19595510 Leszek Koltunski
  public int[][] getSolvedQuats()
845 82eb152a Leszek Koltunski
    {
846 19595510 Leszek Koltunski
    return mSolvedQuats;
847 82eb152a Leszek Koltunski
    }
848
849
///////////////////////////////////////////////////////////////////////////////////////////////////
850
851
  public Static4D[] getQuats()
852
    {
853
    return mQuats;
854
    }
855
856
///////////////////////////////////////////////////////////////////////////////////////////////////
857
858
  public int getSolvedFunctionIndex()
859
    {
860
    return mSolvedFuncIndex;
861
    }
862
863
///////////////////////////////////////////////////////////////////////////////////////////////////
864
865
  public int getNumStickerTypes()
866
    {
867
    return mNumStickerTypes;
868
    }
869
870
///////////////////////////////////////////////////////////////////////////////////////////////////
871
872
  public float[][] getCuts()
873
    {
874
    return mCuts;
875
    }
876
877
///////////////////////////////////////////////////////////////////////////////////////////////////
878
879
  public boolean[][] getLayerRotatable()
880
    {
881
    return mLayerRotatable;
882
    }
883
884
///////////////////////////////////////////////////////////////////////////////////////////////////
885
886
  public int getMovementType()
887
    {
888
    return mMovementType;
889
    }
890
891
///////////////////////////////////////////////////////////////////////////////////////////////////
892
893
  public int getMovementSplit()
894
    {
895
    return mMovementSplit;
896
    }
897
898
///////////////////////////////////////////////////////////////////////////////////////////////////
899
900
  public int[][][] getEnabled()
901
    {
902
    return mEnabled;
903
    }
904
905
///////////////////////////////////////////////////////////////////////////////////////////////////
906
907
  public float[] getDist3D()
908
    {
909
    return mDist3D;
910
    }
911
912 d66e98d7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
913
914
  public int getNumCubitFaces()
915
    {
916
    return mNumCubitFaces;
917
    }
918
919 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
920
921
  public float[][] getCubitPositions()
922
    {
923
    return mPositions;
924
    }
925
926
///////////////////////////////////////////////////////////////////////////////////////////////////
927
928
  public ObjectShape getObjectShape(int variant)
929
    {
930
    return mShapes[variant];
931
    }
932
933 3ee1d662 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
934
935
  public ObjectFaceShape getObjectFaceShape(int variant)
936
    {
937
    return mFaceShapes[variant];
938
    }
939
940 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
941
942 d0e6cf7f Leszek Koltunski
  public Static4D getCubitQuats(int cubit)
943 82eb152a Leszek Koltunski
    {
944
    return mCubitQuats[cubit];
945
    }
946
947
///////////////////////////////////////////////////////////////////////////////////////////////////
948
949
  public int getNumCubitVariants()
950
    {
951
    return mNumCubitVariants;
952
    }
953
954
///////////////////////////////////////////////////////////////////////////////////////////////////
955
956
  public int getCubitVariant(int cubit)
957
    {
958
    return mCubitVariant[cubit];
959
    }
960
961
///////////////////////////////////////////////////////////////////////////////////////////////////
962
963
  public int getVariantFaceColor(int variant, int face)
964
    {
965
    int[] colors = mVariantFaceColor[variant];
966
    return colors.length>face ? colors[face] : -1;
967
    }
968
969 7aae846c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
970
971
  public int[] getCubitTypes()
972
    {
973
    return mCubitType;
974
    }
975
976
///////////////////////////////////////////////////////////////////////////////////////////////////
977
978
  public float[][] getCubitOffsets()
979
    {
980
    return mCubitRowOffset;
981
    }
982
983 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
984
985 ed0988c0 Leszek Koltunski
  public int getCubitFaceFace(int cubit, int face)
986 82eb152a Leszek Koltunski
    {
987
    return mCubitFaceColor[cubit][face];
988
    }
989
990 e1a86bf2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
991
992
  public int getNumScrambles()
993
    {
994
    return mNumScrambles;
995
    }
996
997 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
998
999
  public ObjectSticker retSticker(int sticker)
1000
    {
1001
    return mObjectSticker[sticker];
1002
    }
1003
1004
///////////////////////////////////////////////////////////////////////////////////////////////////
1005
1006
  public Static3D[] getRotationAxis()
1007
    {
1008
    return mAxis;
1009
    }
1010
1011
///////////////////////////////////////////////////////////////////////////////////////////////////
1012
1013 beee90ab Leszek Koltunski
  public int[][] getBasicAngle()
1014 82eb152a Leszek Koltunski
    {
1015
    return mBasicAngle;
1016
    }
1017
1018
///////////////////////////////////////////////////////////////////////////////////////////////////
1019
1020 1d581993 Leszek Koltunski
  public ObjectSignature getSignature()
1021 82eb152a Leszek Koltunski
    {
1022 5f54927b Leszek Koltunski
    return mSignature;
1023 82eb152a Leszek Koltunski
    }
1024
1025
///////////////////////////////////////////////////////////////////////////////////////////////////
1026
1027
  public String getObjectName()
1028
    {
1029
    return mLongName;
1030
    }
1031
1032 e1a86bf2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1033
1034
  public String getShortName()
1035
    {
1036
    return mShortName;
1037
    }
1038
1039 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1040
1041
  public String getInventor()
1042
    {
1043
    return mInventor;
1044
    }
1045
1046
///////////////////////////////////////////////////////////////////////////////////////////////////
1047
1048
  public int getYearOfInvention()
1049
    {
1050
    return mYearOfInvention;
1051
    }
1052
1053
///////////////////////////////////////////////////////////////////////////////////////////////////
1054
1055
  public int getComplexity()
1056
    {
1057
    return mComplexity;
1058
    }
1059
1060
///////////////////////////////////////////////////////////////////////////////////////////////////
1061
1062
  public int getNumFaces()
1063
    {
1064
    return mNumFaces;
1065
    }
1066
1067
///////////////////////////////////////////////////////////////////////////////////////////////////
1068
1069
  public int getNumFaceColors()
1070
    {
1071
    return mNumFaceColors;
1072
    }
1073
1074
///////////////////////////////////////////////////////////////////////////////////////////////////
1075
1076
  public int[] getNumLayers()
1077
    {
1078
    return mNumLayers;
1079
    }
1080
1081
///////////////////////////////////////////////////////////////////////////////////////////////////
1082
1083
  public float getSize()
1084
    {
1085
    return mSize;
1086
    }
1087
1088
///////////////////////////////////////////////////////////////////////////////////////////////////
1089
1090
  public int getScrambleType()
1091
    {
1092
    return mScrambleType;
1093
    }
1094
1095
///////////////////////////////////////////////////////////////////////////////////////////////////
1096
1097
  public int getColor(int face)
1098
    {
1099
    return mColor[face];
1100
    }
1101 0f72365b Leszek Koltunski
1102 253e440f Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1103
1104
  public int getInternalColor()
1105
    {
1106
    return mInternalColor;
1107
    }
1108
1109 0f72365b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1110
1111
  public boolean shouldResetTextureMaps()
1112
    {
1113
    return mResetMaps;
1114
    }
1115 052e0362 Leszek Koltunski
1116
///////////////////////////////////////////////////////////////////////////////////////////////////
1117
1118
  public String getTutorialObject()
1119
    {
1120
    return mTutorialObject;
1121
    }
1122
1123
///////////////////////////////////////////////////////////////////////////////////////////////////
1124
1125
  public String[][] getTutorials()
1126
    {
1127
    return mTutorials;
1128
    }
1129
1130 82eb152a Leszek Koltunski
}