Project

General

Profile

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

distorted-objectlib / src / main / java / org / distorted / objectlib / json / JsonReader.java @ 40e77224

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 40e77224 Leszek Koltunski
  private int[][] mVariantFaceColor, mVariantFaceIsOuter, mCubitFaceColor;
71 82eb152a Leszek Koltunski
  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 40e77224 Leszek Koltunski
    mNumCubitVariants     = object.length();
214
    mVariantFaceColor     = new int[mNumCubitVariants][];
215
    mVariantFaceIsOuter   = new int[mNumCubitVariants][];
216
    mShapes               = new ObjectShape[mNumCubitVariants];
217
    mFaceShapes           = new ObjectFaceShape[mNumCubitVariants];
218 57ef6378 Leszek Koltunski
    float[][][] verts     = new float[mNumCubitVariants][][];
219
    float[][][] bands     = new float[mNumCubitVariants][][];
220
    float[][][] corners   = new float[mNumCubitVariants][][];
221
    float[][][] centers   = new float[mNumCubitVariants][][];
222
    float[][] convexity   = new float[mNumCubitVariants][];
223 82eb152a Leszek Koltunski
    int[][] cornerIndices = new int[mNumCubitVariants][];
224
    int[][] centerIndices = new int[mNumCubitVariants][];
225 57ef6378 Leszek Koltunski
    int[][] bandIndices   = new int[mNumCubitVariants][];
226 82eb152a Leszek Koltunski
    int[][][] vertIndices = new int[mNumCubitVariants][][];
227
228 d66e98d7 Leszek Koltunski
    mNumCubitFaces = -1;
229
230 82eb152a Leszek Koltunski
    for(int i=0; i<mNumCubitVariants; i++)
231
      {
232
      JSONObject jsonShape = object.getJSONObject(i);
233
234
      ////// vertices /////////////////////////////////////////////////
235
      JSONArray jsonVertices= jsonShape.getJSONArray("vertices");
236
      int numVertices = jsonVertices.length();
237 57ef6378 Leszek Koltunski
      verts[i] = new float[numVertices][3];
238 82eb152a Leszek Koltunski
      cornerIndices[i] = new int[numVertices];
239
      centerIndices[i] = new int[numVertices];
240
241
      for(int j=0; j<numVertices; j++)
242
        {
243
        JSONObject vert = jsonVertices.getJSONObject(j);
244 57ef6378 Leszek Koltunski
        verts[i][j][0] = (float)vert.getDouble("x");
245
        verts[i][j][1] = (float)vert.getDouble("y");
246
        verts[i][j][2] = (float)vert.getDouble("z");
247 82eb152a Leszek Koltunski
        cornerIndices[i][j] = vert.getInt("cornerIndex");
248
        centerIndices[i][j] = vert.getInt("centerIndex");
249
        }
250
251
      ////// faces ////////////////////////////////////////////////////
252
      JSONArray jsonFaces= jsonShape.getJSONArray("faces");
253
      int numFaces = jsonFaces.length();
254 40e77224 Leszek Koltunski
      mVariantFaceColor[i]   = new int[numFaces];
255
      mVariantFaceIsOuter[i] = new int[numFaces];
256 82eb152a Leszek Koltunski
      bandIndices[i] = new int[numFaces];
257
      vertIndices[i] = new int[numFaces][];
258
259 d66e98d7 Leszek Koltunski
      if( mNumCubitFaces<numFaces ) mNumCubitFaces=numFaces;
260
261 82eb152a Leszek Koltunski
      for(int j=0; j<numFaces; j++)
262
        {
263
        JSONObject jsonFace = jsonFaces.getJSONObject(j);
264 40e77224 Leszek Koltunski
        mVariantFaceColor[i][j]   = jsonFace.getInt("sticker");
265
        mVariantFaceIsOuter[i][j] = jsonFace.optInt("isOuter",0);
266 82eb152a Leszek Koltunski
        bandIndices[i][j] = jsonFace.getInt("bandIndex");
267
        JSONArray vertices = jsonFace.getJSONArray("vertexIndices");
268
        int numV = vertices.length();
269
        vertIndices[i][j] = new int[numV];
270
        for(int k=0; k<numV; k++) vertIndices[i][j][k] = vertices.getInt(k);
271
        }
272
273
      ////// bands ////////////////////////////////////////////////////
274
      JSONArray jsonBands= jsonShape.getJSONArray("bands");
275
      int numBands = jsonBands.length();
276
      bands[i] = new float[numBands][7];
277
278
      for(int j=0; j<numBands; j++)
279
        {
280
        JSONObject jsonBand = jsonBands.getJSONObject(j);
281
282
        bands[i][j][0] = (float)jsonBand.getDouble("height");
283
        bands[i][j][1] = (float)jsonBand.getDouble("angle");
284
        bands[i][j][2] = (float)jsonBand.getDouble("distanceToCenter");
285
        bands[i][j][3] = (float)jsonBand.getDouble("distanceToFlat");
286
        bands[i][j][4] = (float)jsonBand.getDouble("numOfBands");
287
        bands[i][j][5] = (float)jsonBand.getDouble("extraI");
288
        bands[i][j][6] = (float)jsonBand.getDouble("extraJ");
289
        }
290
291
      ////// cornerPush ///////////////////////////////////////////////
292 9e8eb9e4 Leszek Koltunski
      JSONArray jsonCornerPush= jsonShape.optJSONArray("cornerPush");
293 82eb152a Leszek Koltunski
294 9e8eb9e4 Leszek Koltunski
      if( jsonCornerPush!=null )
295 82eb152a Leszek Koltunski
        {
296 9e8eb9e4 Leszek Koltunski
        int numCornerP = jsonCornerPush.length();
297
        corners[i] = new float[numCornerP][2];
298
299
        for(int j=0; j<numCornerP; j++)
300
          {
301
          JSONObject jsonC = jsonCornerPush.getJSONObject(j);
302
          corners[i][j][0] = (float)jsonC.getDouble("strength");
303
          corners[i][j][1] = (float)jsonC.getDouble("radius");
304
          }
305 82eb152a Leszek Koltunski
        }
306
307
      ////// centerPush ///////////////////////////////////////////////
308 9e8eb9e4 Leszek Koltunski
      JSONArray jsonCenterPush= jsonShape.optJSONArray("centerPush");
309 82eb152a Leszek Koltunski
310 9e8eb9e4 Leszek Koltunski
      if( jsonCenterPush!=null )
311 82eb152a Leszek Koltunski
        {
312 9e8eb9e4 Leszek Koltunski
        int numCenterP = jsonCenterPush.length();
313
        centers[i] = new float[numCenterP][3];
314
315
        for(int j=0; j<numCenterP; j++)
316
          {
317
          JSONObject jsonC = jsonCenterPush.getJSONObject(j);
318
          centers[i][j][0] = (float)jsonC.getDouble("x");
319
          centers[i][j][1] = (float)jsonC.getDouble("y");
320
          centers[i][j][2] = (float)jsonC.getDouble("z");
321
          }
322 82eb152a Leszek Koltunski
        }
323
324
      ////// convexity ///////////////////////////////////////////////
325 9e8eb9e4 Leszek Koltunski
      JSONObject jsonConvexity = jsonShape.optJSONObject("convexity");
326
327
      if( jsonConvexity!=null )
328 82eb152a Leszek Koltunski
        {
329
        convexity[i] = new float[3];
330
        convexity[i][0] = (float)jsonConvexity.getDouble("x");
331
        convexity[i][1] = (float)jsonConvexity.getDouble("y");
332
        convexity[i][2] = (float)jsonConvexity.getDouble("z");
333
        }
334
      }
335
336
    for(int i=0; i<mNumCubitVariants; i++)
337
      {
338 59a971c1 Leszek Koltunski
      mShapes[i] = new ObjectShape(verts[i],vertIndices[i]);
339 3ee1d662 Leszek Koltunski
      mFaceShapes[i] = new ObjectFaceShape(bands[i],bandIndices[i],corners[i],cornerIndices[i],centers[i],centerIndices[i],convexity[i] );
340 82eb152a Leszek Koltunski
      }
341
    }
342
343
///////////////////////////////////////////////////////////////////////////////////////////////////
344
345
  private void parseStickers(JSONArray object) throws JSONException
346
    {
347
    mNumStickerTypes = object.length();
348
    mObjectSticker = new ObjectSticker[mNumStickerTypes];
349
350
    for(int i=0; i<mNumStickerTypes; i++)
351
      {
352
      JSONObject sticker = object.getJSONObject(i);
353
      float stroke = (float)sticker.getDouble("stroke");
354
      JSONArray vertices = sticker.getJSONArray("vertices");
355
      int numVertices = vertices.length();
356
357
      float[] coords     = new float[2*numVertices];
358
      float[] curvatures = new float[numVertices];
359
      float[] radii      = new float[numVertices];
360
361
      for(int j=0; j<numVertices; j++)
362
        {
363
        JSONObject vertex = vertices.getJSONObject(j);
364
365
        coords[2*j  ] = (float)vertex.getDouble("x");
366
        coords[2*j+1] = (float)vertex.getDouble("y");
367
        curvatures[j] = (float)vertex.getDouble("angle");
368
        radii[j]      = (float)vertex.getDouble("radius");
369
        }
370
371
      mObjectSticker[i] = new ObjectSticker(coords,curvatures,radii,stroke);
372
      }
373
    }
374
375
///////////////////////////////////////////////////////////////////////////////////////////////////
376
377
  private void parseMesh(JSONObject object) throws JSONException
378
    {
379
    JSONArray cubits   = object.getJSONArray("cubits");
380
    parseCubits(cubits);
381
    JSONArray shapes   = object.getJSONArray("shapes");
382
    parseShapes(shapes);
383
    JSONArray stickers = object.getJSONArray("stickers");
384
    parseStickers(stickers);
385
    }
386
387
///////////////////////////////////////////////////////////////////////////////////////////////////
388
389 beee90ab Leszek Koltunski
  private void parseAxis1(JSONArray object) throws JSONException
390 82eb152a Leszek Koltunski
    {
391
    int numAxis = object.length();
392
393 beee90ab Leszek Koltunski
    mBasicAngle     = new int[numAxis][];
394 82eb152a Leszek Koltunski
    mAxis           = new Static3D[numAxis];
395
    mCuts           = new float[numAxis][];
396
    mLayerRotatable = new boolean[numAxis][];
397
    mNumLayers      = new int[numAxis];
398
399
    for(int i=0; i<numAxis; i++)
400
      {
401
      JSONObject jsonAx = object.getJSONObject(i);
402
403 beee90ab Leszek Koltunski
      float x = (float)jsonAx.getDouble("x");
404
      float y = (float)jsonAx.getDouble("y");
405
      float z = (float)jsonAx.getDouble("z");
406
407
      mAxis[i] = new Static3D(x,y,z);
408
409
      JSONArray jsonCuts = jsonAx.getJSONArray("cuts");
410
      int numCuts = jsonCuts.length();
411
      mCuts[i] = new float[numCuts];
412
      for(int j=0; j<numCuts; j++) mCuts[i][j] = (float)jsonCuts.getDouble(j);
413
414
      JSONArray jsonRota = jsonAx.getJSONArray("rotatable");
415
      int numRota = jsonRota.length();
416
      mLayerRotatable[i] = new boolean[numRota];
417
      for(int j=0; j<numRota; j++) mLayerRotatable[i][j] = jsonRota.getBoolean(j);
418
419
      mBasicAngle[i] = new int[numRota];
420
      int basicAngle = jsonAx.getInt("basicAngle");
421
      for(int j=0; j<numRota; j++) mBasicAngle[i][j] = basicAngle;
422
423
      mNumLayers[i] = numRota;
424
      }
425
    }
426
427
///////////////////////////////////////////////////////////////////////////////////////////////////
428
429 7aae846c Leszek Koltunski
  private void parseAxis2or3or4(JSONArray object) throws JSONException
430 beee90ab Leszek Koltunski
    {
431
    int numAxis = object.length();
432
433
    mBasicAngle     = new int[numAxis][];
434
    mAxis           = new Static3D[numAxis];
435
    mCuts           = new float[numAxis][];
436
    mLayerRotatable = new boolean[numAxis][];
437
    mNumLayers      = new int[numAxis];
438
439
    for(int i=0; i<numAxis; i++)
440
      {
441
      JSONObject jsonAx = object.getJSONObject(i);
442 82eb152a Leszek Koltunski
443
      float x = (float)jsonAx.getDouble("x");
444
      float y = (float)jsonAx.getDouble("y");
445
      float z = (float)jsonAx.getDouble("z");
446
447
      mAxis[i] = new Static3D(x,y,z);
448
449 beee90ab Leszek Koltunski
      JSONArray jsonAngles = jsonAx.getJSONArray("basicAngles");
450
      int numAngles = jsonAngles.length();
451
      mBasicAngle[i] = new int[numAngles];
452
      for(int j=0; j<numAngles; j++) mBasicAngle[i][j] = jsonAngles.getInt(j);
453
454 82eb152a Leszek Koltunski
      JSONArray jsonCuts = jsonAx.getJSONArray("cuts");
455
      int numCuts = jsonCuts.length();
456
      mCuts[i] = new float[numCuts];
457
      for(int j=0; j<numCuts; j++) mCuts[i][j] = (float)jsonCuts.getDouble(j);
458
459
      JSONArray jsonRota = jsonAx.getJSONArray("rotatable");
460
      int numRota = jsonRota.length();
461
      mLayerRotatable[i] = new boolean[numRota];
462
      for(int j=0; j<numRota; j++) mLayerRotatable[i][j] = jsonRota.getBoolean(j);
463
464
      mNumLayers[i] = numRota;
465
      }
466
    }
467
468
///////////////////////////////////////////////////////////////////////////////////////////////////
469
470
  private void parseQuats(JSONArray object) throws JSONException
471
    {
472
    int numQuats = object.length();
473
    mQuats = new Static4D[numQuats];
474
475
    for(int i=0; i<numQuats; i++)
476
      {
477
      JSONObject jsonQuat = object.getJSONObject(i);
478
479
      float x = (float)jsonQuat.getDouble("x");
480
      float y = (float)jsonQuat.getDouble("y");
481
      float z = (float)jsonQuat.getDouble("z");
482
      float w = (float)jsonQuat.getDouble("w");
483
484
      mQuats[i] = new Static4D(x,y,z,w);
485
      }
486
    }
487
488
///////////////////////////////////////////////////////////////////////////////////////////////////
489
490
  private void parseScrambling(JSONObject object) throws JSONException
491
    {
492
    mScrambleType = object.getInt("scrambleType");
493
494
    if( mScrambleType==0 )
495
      {
496
      JSONArray jsonStates = object.getJSONArray("scrambleStates");
497
      int numStates = jsonStates.length();
498
      mStates = new ScrambleState[numStates];
499
500
      for(int i=0; i<numStates; i++)
501
        {
502
        JSONArray jsonState = jsonStates.getJSONArray(i);
503
        int numAxis = jsonState.length();
504
        int[][] scramblingData = new int[numAxis][];
505
506
        for(int j=0; j<numAxis; j++)
507
          {
508
          JSONArray jsonData = jsonState.getJSONArray(j);
509
          int numData = jsonData.length();
510
          scramblingData[j] = new int[numData];
511
          for(int k=0; k<numData; k++) scramblingData[j][k] = jsonData.getInt(k);
512
          }
513
514
        mStates[i] = new ScrambleState(scramblingData);
515
        }
516
      }
517
    }
518
519
///////////////////////////////////////////////////////////////////////////////////////////////////
520
521
  private void parseTouchcontrol(JSONObject object) throws JSONException
522
    {
523
    mMovementType = object.getInt("movementType");
524
    mMovementSplit= object.getInt("movementSplit");
525
526 82904e62 Leszek Koltunski
    try
527 82eb152a Leszek Koltunski
      {
528 82904e62 Leszek Koltunski
      JSONArray jsonEnabled = object.getJSONArray("enabledAxis");
529
      int numFace = jsonEnabled.length();
530 82eb152a Leszek Koltunski
531 82904e62 Leszek Koltunski
      mEnabled = new int[numFace][][];
532
533
      for(int i=0; i<numFace; i++)
534 82eb152a Leszek Koltunski
        {
535 82904e62 Leszek Koltunski
        JSONArray jsonSection = jsonEnabled.getJSONArray(i);
536
        int numSection = jsonSection.length();
537
        mEnabled[i] = new int[numSection][];
538
539
        for(int j=0; j<numSection; j++)
540
          {
541
          JSONArray jsonAx = jsonSection.getJSONArray(j);
542
          int numAxis = jsonAx.length();
543
          mEnabled[i][j] = new int[numAxis];
544
          for(int k=0; k<numAxis; k++) mEnabled[i][j][k] = jsonAx.getInt(k);
545
          }
546 82eb152a Leszek Koltunski
        }
547
      }
548 82904e62 Leszek Koltunski
    catch( JSONException ex )
549
      {
550
      // ignore, the object does not have to have 'enabledAxis' defined at all.
551
      }
552 82eb152a Leszek Koltunski
553
    try
554
      {
555
      JSONArray jsonDist = object.getJSONArray("dist3D");
556 a72cd106 Leszek Koltunski
      int num = jsonDist.length();
557
      mDist3D = new float[num];
558
      for(int j=0; j<num; j++) mDist3D[j] = (float)jsonDist.getDouble(j);
559 82eb152a Leszek Koltunski
      }
560
    catch( JSONException ex )
561
      {
562 a72cd106 Leszek Koltunski
      // ignore, the object does not have a 'dist3D' which is possible.
563 82eb152a Leszek Koltunski
      }
564
    }
565
566
///////////////////////////////////////////////////////////////////////////////////////////////////
567
568
  private void parseColors(JSONArray object) throws JSONException
569
    {
570 253e440f Leszek Koltunski
    mNumFaceColors = object.length()-1;
571
572 82eb152a Leszek Koltunski
    mColor = new int[mNumFaceColors];
573
    for(int i=0; i<mNumFaceColors; i++) mColor[i] = object.getInt(i);
574 253e440f Leszek Koltunski
575
    mInternalColor = object.getInt(mNumFaceColors);
576 82eb152a Leszek Koltunski
    }
577
578 3c48fab9 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
579
580
  private void parseSolved(JSONObject solved) throws JSONException
581
    {
582
    mSolvedFuncIndex = solved.getInt("functionIndex");
583
584
    try
585
      {
586
      JSONArray groupArray= solved.getJSONArray("groups");
587
      int numGroups = groupArray.length();
588
      mSolvedQuats  = new int[numGroups][];
589
590
      for(int i=0; i<numGroups; i++)
591
        {
592
        JSONArray groupElements = groupArray.getJSONArray(i);
593
        int groupSize = groupElements.length();
594
        mSolvedQuats[i] = new int[groupSize];
595
        for(int j=0; j<groupSize; j++) mSolvedQuats[i][j] = groupElements.getInt(j);
596
        }
597
      }
598
    catch( JSONException ex )
599
      {
600
      // ignore, the object does not have to have an array of solved groups.
601
      }
602
    }
603
604 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
605
606
  private void parseVersion1(JSONObject object) throws JSONException
607
    {
608
    JSONObject metadata    = object.getJSONObject("metadata");
609 1d581993 Leszek Koltunski
    parseMetadata1(metadata);
610 82eb152a Leszek Koltunski
    JSONObject mesh        = object.getJSONObject("mesh");
611
    parseMesh(mesh);
612
    JSONArray axis         = object.getJSONArray("axis");
613 beee90ab Leszek Koltunski
    parseAxis1(axis);
614
    JSONArray quats        = object.getJSONArray("quats");
615
    parseQuats(quats);
616
    JSONObject scrambling  = object.getJSONObject("scrambling");
617
    parseScrambling(scrambling);
618
    JSONObject touchcontrol= object.getJSONObject("touchcontrol");
619
    parseTouchcontrol(touchcontrol);
620
    JSONArray colors       = object.getJSONArray("colors");
621
    parseColors(colors);
622
    JSONObject solved      = object.getJSONObject("solved");
623
    parseSolved(solved);
624
    }
625
626
///////////////////////////////////////////////////////////////////////////////////////////////////
627
628 7aae846c Leszek Koltunski
  private void parseVersion2or3or4(JSONObject object) throws JSONException
629 beee90ab Leszek Koltunski
    {
630
    JSONObject metadata    = object.getJSONObject("metadata");
631 7aae846c Leszek Koltunski
    parseMetadata2or3or4(metadata);
632 beee90ab Leszek Koltunski
    JSONObject mesh        = object.getJSONObject("mesh");
633
    parseMesh(mesh);
634
    JSONArray axis         = object.getJSONArray("axis");
635 7aae846c Leszek Koltunski
    parseAxis2or3or4(axis);
636 82eb152a Leszek Koltunski
    JSONArray quats        = object.getJSONArray("quats");
637
    parseQuats(quats);
638
    JSONObject scrambling  = object.getJSONObject("scrambling");
639
    parseScrambling(scrambling);
640
    JSONObject touchcontrol= object.getJSONObject("touchcontrol");
641
    parseTouchcontrol(touchcontrol);
642
    JSONArray colors       = object.getJSONArray("colors");
643
    parseColors(colors);
644 3c48fab9 Leszek Koltunski
    JSONObject solved      = object.getJSONObject("solved");
645
    parseSolved(solved);
646 82eb152a Leszek Koltunski
    }
647
648 052e0362 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
649
650
  private void parseVersion1Tutorial(JSONObject object) throws JSONException
651
    {
652
    mTutorialObject = object.getString("object");
653
    JSONArray tuts= object.getJSONArray("tutorials");
654
655
    int len = tuts.length();
656
    mTutorials = new String[len][4];
657
658
    for(int i=0; i<len; i++)
659
      {
660
      JSONObject tut = tuts.getJSONObject(i);
661
      mTutorials[i][0] = tut.getString("language");
662
      mTutorials[i][1] = tut.getString("link");
663
      mTutorials[i][2] = tut.getString("title");
664
      mTutorials[i][3] = tut.getString("author");
665
      }
666
    }
667
668 b39f8e39 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
669
670 1d581993 Leszek Koltunski
  private void parseVersion1Metadata(JSONObject object) throws JSONException
671
    {
672
    JSONObject metadata = object.getJSONObject("metadata");
673
    parseMetadata1(metadata);
674
    }
675
676
///////////////////////////////////////////////////////////////////////////////////////////////////
677
678 7aae846c Leszek Koltunski
  private void parseVersion2or3or4Metadata(JSONObject object) throws JSONException
679 b39f8e39 Leszek Koltunski
    {
680
    JSONObject metadata = object.getJSONObject("metadata");
681 7aae846c Leszek Koltunski
    parseMetadata2or3or4(metadata);
682 b39f8e39 Leszek Koltunski
    }
683
684 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
685
686
  public void parseJsonFile(InputStream jsonStream)
687
    {
688
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
689
690
    try
691
      {
692
      StringBuilder contents = new StringBuilder();
693
      String tmp;
694
      while( (tmp = br.readLine()) != null) contents.append(tmp);
695
      br.close();
696
      jsonStream.close();
697
698
      JSONObject object = new JSONObject(contents.toString());
699
      int major = object.getInt("major");
700
701 e7d3259a Leszek Koltunski
      if( major==1 )
702
        {
703
        parseVersion1(object);
704
        }
705 7aae846c Leszek Koltunski
      else if( major==2 || major==3 || major==4 )
706 e7d3259a Leszek Koltunski
        {
707 7aae846c Leszek Koltunski
        parseVersion2or3or4(object);
708 e7d3259a Leszek Koltunski
        }
709 82eb152a Leszek Koltunski
      else
710
        {
711
        android.util.Log.e("readJsonFile", "Unknown version "+major);
712
        }
713
      }
714
    catch(IOException e)
715
      {
716
      android.util.Log.e("readJsonFile", "Error reading JSON file: "+e.toString());
717
      }
718
    catch( JSONException e )
719
      {
720
      android.util.Log.e("parseJsonFile", "Error parsing JSON file: "+e.toString());
721
      }
722
    }
723
724 b39f8e39 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
725
726
  public void parseJsonFileMetadata(InputStream jsonStream)
727
    {
728
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
729
730
    try
731
      {
732
      StringBuilder contents = new StringBuilder();
733
      String tmp;
734
      while( (tmp = br.readLine()) != null) contents.append(tmp);
735
      br.close();
736
      jsonStream.close();
737
738
      JSONObject object = new JSONObject(contents.toString());
739
      int major = object.getInt("major");
740
741 1d581993 Leszek Koltunski
      if( major==1 )
742
        {
743
        parseVersion1Metadata(object);
744
        }
745 7aae846c Leszek Koltunski
      else if( major==2 || major==3 || major==4 )
746 b39f8e39 Leszek Koltunski
        {
747 7aae846c Leszek Koltunski
        parseVersion2or3or4Metadata(object);
748 b39f8e39 Leszek Koltunski
        }
749
      else
750
        {
751
        android.util.Log.e("readJsonFileQuick", "Unknown version "+major);
752
        }
753
      }
754
    catch(IOException e)
755
      {
756
      android.util.Log.e("readJsonFileQuick", "Error reading JSON file: "+e.toString());
757
      }
758
    catch( JSONException e )
759
      {
760
      android.util.Log.e("parseJsonFileQuick", "Error parsing JSON file: "+e.toString());
761
      }
762
    }
763
764 bf52deb2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
765
766 ef021035 Leszek Koltunski
  public int readNumScrambles(Context context, String fileName)
767 bf52deb2 Leszek Koltunski
    {
768
    File file = new File(context.getFilesDir(), fileName);
769
    InputStream stream;
770
771
    try
772
      {
773
      stream = new FileInputStream(file);
774 ef021035 Leszek Koltunski
      BufferedReader br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
775
776
      StringBuilder contents = new StringBuilder();
777
      String tmp;
778
      while( (tmp = br.readLine()) != null) contents.append(tmp);
779
      br.close();
780
      stream.close();
781
782
      JSONObject object = new JSONObject(contents.toString());
783 7aae846c Leszek Koltunski
      JSONObject metadata = object.getJSONObject("metadata");
784
      return metadata.getInt("scrambles");
785 bf52deb2 Leszek Koltunski
      }
786
    catch(FileNotFoundException ex)
787
      {
788 ef021035 Leszek Koltunski
      android.util.Log.e("readNumScrambles", "file "+fileName+" not found: "+ex.getMessage());
789 bf52deb2 Leszek Koltunski
      }
790 ef021035 Leszek Koltunski
    catch(IOException e)
791
      {
792
      android.util.Log.e("readNumScrambles", "Error reading JSON file: "+e.toString());
793
      }
794
    catch( JSONException e )
795
      {
796
      android.util.Log.e("readNumScrambles", "Error parsing JSON file: "+e.toString());
797
      }
798
799
    return 0;
800 bf52deb2 Leszek Koltunski
    }
801
802 052e0362 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
803
804
  public void parseJsonTutorial(InputStream jsonStream)
805
    {
806
    BufferedReader br = new BufferedReader(new InputStreamReader(jsonStream, StandardCharsets.UTF_8));
807
808
    try
809
      {
810
      StringBuilder contents = new StringBuilder();
811
      String tmp;
812
      while( (tmp = br.readLine()) != null) contents.append(tmp);
813
      br.close();
814
      jsonStream.close();
815
816
      JSONObject object = new JSONObject(contents.toString());
817
      int major = object.getInt("major");
818
819
      if( major==1 )
820
        {
821
        parseVersion1Tutorial(object);
822
        }
823
      else
824
        {
825
        android.util.Log.e("readJsonFile", "Unknown tutorial version "+major);
826
        }
827
      }
828
    catch(IOException e)
829
      {
830
      android.util.Log.e("readJsonFile", "Error reading JSON file: "+e.toString());
831
      }
832
    catch( JSONException e )
833
      {
834
      android.util.Log.e("parseJsonFile", "Error parsing JSON file: "+e.toString());
835
      }
836
    }
837
838 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
839
840
  public ScrambleState[] getScrambleStates()
841
    {
842
    return mStates;
843
    }
844
845
///////////////////////////////////////////////////////////////////////////////////////////////////
846
847 19595510 Leszek Koltunski
  public int[][] getSolvedQuats()
848 82eb152a Leszek Koltunski
    {
849 19595510 Leszek Koltunski
    return mSolvedQuats;
850 82eb152a Leszek Koltunski
    }
851
852
///////////////////////////////////////////////////////////////////////////////////////////////////
853
854
  public Static4D[] getQuats()
855
    {
856
    return mQuats;
857
    }
858
859
///////////////////////////////////////////////////////////////////////////////////////////////////
860
861
  public int getSolvedFunctionIndex()
862
    {
863
    return mSolvedFuncIndex;
864
    }
865
866
///////////////////////////////////////////////////////////////////////////////////////////////////
867
868
  public int getNumStickerTypes()
869
    {
870
    return mNumStickerTypes;
871
    }
872
873
///////////////////////////////////////////////////////////////////////////////////////////////////
874
875
  public float[][] getCuts()
876
    {
877
    return mCuts;
878
    }
879
880
///////////////////////////////////////////////////////////////////////////////////////////////////
881
882
  public boolean[][] getLayerRotatable()
883
    {
884
    return mLayerRotatable;
885
    }
886
887
///////////////////////////////////////////////////////////////////////////////////////////////////
888
889
  public int getMovementType()
890
    {
891
    return mMovementType;
892
    }
893
894
///////////////////////////////////////////////////////////////////////////////////////////////////
895
896
  public int getMovementSplit()
897
    {
898
    return mMovementSplit;
899
    }
900
901
///////////////////////////////////////////////////////////////////////////////////////////////////
902
903
  public int[][][] getEnabled()
904
    {
905
    return mEnabled;
906
    }
907
908
///////////////////////////////////////////////////////////////////////////////////////////////////
909
910
  public float[] getDist3D()
911
    {
912
    return mDist3D;
913
    }
914
915 d66e98d7 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
916
917
  public int getNumCubitFaces()
918
    {
919
    return mNumCubitFaces;
920
    }
921
922 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
923
924
  public float[][] getCubitPositions()
925
    {
926
    return mPositions;
927
    }
928
929
///////////////////////////////////////////////////////////////////////////////////////////////////
930
931
  public ObjectShape getObjectShape(int variant)
932
    {
933
    return mShapes[variant];
934
    }
935
936 3ee1d662 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
937
938
  public ObjectFaceShape getObjectFaceShape(int variant)
939
    {
940
    return mFaceShapes[variant];
941
    }
942
943 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
944
945 d0e6cf7f Leszek Koltunski
  public Static4D getCubitQuats(int cubit)
946 82eb152a Leszek Koltunski
    {
947
    return mCubitQuats[cubit];
948
    }
949
950
///////////////////////////////////////////////////////////////////////////////////////////////////
951
952
  public int getNumCubitVariants()
953
    {
954
    return mNumCubitVariants;
955
    }
956
957
///////////////////////////////////////////////////////////////////////////////////////////////////
958
959
  public int getCubitVariant(int cubit)
960
    {
961
    return mCubitVariant[cubit];
962
    }
963
964
///////////////////////////////////////////////////////////////////////////////////////////////////
965
966
  public int getVariantFaceColor(int variant, int face)
967
    {
968
    int[] colors = mVariantFaceColor[variant];
969
    return colors.length>face ? colors[face] : -1;
970
    }
971
972 7aae846c Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
973
974
  public int[] getCubitTypes()
975
    {
976
    return mCubitType;
977
    }
978
979
///////////////////////////////////////////////////////////////////////////////////////////////////
980
981
  public float[][] getCubitOffsets()
982
    {
983
    return mCubitRowOffset;
984
    }
985
986 40e77224 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
987
988
  public int[][] getVariantFaceIsOuter()
989
    {
990
    return mVariantFaceIsOuter;
991
    }
992
993 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
994
995 ed0988c0 Leszek Koltunski
  public int getCubitFaceFace(int cubit, int face)
996 82eb152a Leszek Koltunski
    {
997
    return mCubitFaceColor[cubit][face];
998
    }
999
1000 e1a86bf2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1001
1002
  public int getNumScrambles()
1003
    {
1004
    return mNumScrambles;
1005
    }
1006
1007 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1008
1009
  public ObjectSticker retSticker(int sticker)
1010
    {
1011
    return mObjectSticker[sticker];
1012
    }
1013
1014
///////////////////////////////////////////////////////////////////////////////////////////////////
1015
1016
  public Static3D[] getRotationAxis()
1017
    {
1018
    return mAxis;
1019
    }
1020
1021
///////////////////////////////////////////////////////////////////////////////////////////////////
1022
1023 beee90ab Leszek Koltunski
  public int[][] getBasicAngle()
1024 82eb152a Leszek Koltunski
    {
1025
    return mBasicAngle;
1026
    }
1027
1028
///////////////////////////////////////////////////////////////////////////////////////////////////
1029
1030 1d581993 Leszek Koltunski
  public ObjectSignature getSignature()
1031 82eb152a Leszek Koltunski
    {
1032 5f54927b Leszek Koltunski
    return mSignature;
1033 82eb152a Leszek Koltunski
    }
1034
1035
///////////////////////////////////////////////////////////////////////////////////////////////////
1036
1037
  public String getObjectName()
1038
    {
1039
    return mLongName;
1040
    }
1041
1042 e1a86bf2 Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1043
1044
  public String getShortName()
1045
    {
1046
    return mShortName;
1047
    }
1048
1049 82eb152a Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1050
1051
  public String getInventor()
1052
    {
1053
    return mInventor;
1054
    }
1055
1056
///////////////////////////////////////////////////////////////////////////////////////////////////
1057
1058
  public int getYearOfInvention()
1059
    {
1060
    return mYearOfInvention;
1061
    }
1062
1063
///////////////////////////////////////////////////////////////////////////////////////////////////
1064
1065
  public int getComplexity()
1066
    {
1067
    return mComplexity;
1068
    }
1069
1070
///////////////////////////////////////////////////////////////////////////////////////////////////
1071
1072
  public int getNumFaces()
1073
    {
1074
    return mNumFaces;
1075
    }
1076
1077
///////////////////////////////////////////////////////////////////////////////////////////////////
1078
1079
  public int getNumFaceColors()
1080
    {
1081
    return mNumFaceColors;
1082
    }
1083
1084
///////////////////////////////////////////////////////////////////////////////////////////////////
1085
1086
  public int[] getNumLayers()
1087
    {
1088
    return mNumLayers;
1089
    }
1090
1091
///////////////////////////////////////////////////////////////////////////////////////////////////
1092
1093
  public float getSize()
1094
    {
1095
    return mSize;
1096
    }
1097
1098
///////////////////////////////////////////////////////////////////////////////////////////////////
1099
1100
  public int getScrambleType()
1101
    {
1102
    return mScrambleType;
1103
    }
1104
1105
///////////////////////////////////////////////////////////////////////////////////////////////////
1106
1107
  public int getColor(int face)
1108
    {
1109
    return mColor[face];
1110
    }
1111 0f72365b Leszek Koltunski
1112 253e440f Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1113
1114
  public int getInternalColor()
1115
    {
1116
    return mInternalColor;
1117
    }
1118
1119 0f72365b Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
1120
1121
  public boolean shouldResetTextureMaps()
1122
    {
1123
    return mResetMaps;
1124
    }
1125 052e0362 Leszek Koltunski
1126
///////////////////////////////////////////////////////////////////////////////////////////////////
1127
1128
  public String getTutorialObject()
1129
    {
1130
    return mTutorialObject;
1131
    }
1132
1133
///////////////////////////////////////////////////////////////////////////////////////////////////
1134
1135
  public String[][] getTutorials()
1136
    {
1137
    return mTutorials;
1138
    }
1139
1140 82eb152a Leszek Koltunski
}