Newer
Older
EPQ-3D-renderer / src / main / java / uk / org / floop / epq3d / JsonReader.java
package uk.org.floop.epq3d;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import java.awt.*;
import java.io.FileReader;
import java.io.IOException;
import java.util.Objects;

// Program for print data in JSON format.
public class JsonReader {
    JSONObject fileCollections;
    JSONObject fileTextures;

    Texture[] textures;
    ObjectCollection mainCollection;
    public JsonReader() {
        JSONParser parser = new JSONParser();
        Object obj;
        try {
             obj = parser.parse(new FileReader("jsonCollections.json"));
        } catch (IOException | ParseException e) {
            throw new RuntimeException(e);
        }
        fileCollections = (JSONObject)obj;
        try {
            obj = parser.parse(new FileReader("jsonTextures.json"));
        } catch (IOException | ParseException e) {
            throw new RuntimeException(e);
        }
        fileTextures = (JSONObject)obj;
    }
    public void getObjects(){
        textures = getTextures((JSONArray) fileTextures.get("textures"));
        mainCollection = separateCollection((JSONObject) ((JSONArray) fileCollections.get("collections")).get(0), textures);
        fileCollections.get("collection");
    }
    private ObjectCollection separateCollection(JSONObject json, Texture[] textures){
        ObjectCollection result = new ObjectCollection();

        // first, get the sub collections of the object and separate them recursively.
        JSONArray subCollections = (JSONArray) json.get("subCollections");
        if(subCollections != null) for (Object collection: subCollections) {
            result.addCollection(separateCollection((JSONObject) collection, textures));
        }
        // next, get the name of the collection
        result.name = json.get("name").toString();

        // next, get the objects contained in this collection
        JSONArray objects3d = (JSONArray) json.get("objects");
        if(objects3d != null) for(Object objectJson: objects3d){
            JSONObject object = (JSONObject)objectJson;
            JSONArray pointsJson = (JSONArray) object.get("points");
            // pack points
            PointComp[] points = new PointComp[pointsJson.size()];
            for (int i = 0; i < pointsJson.size(); i+=1){
                JSONArray jsonPoint = (JSONArray) pointsJson.get(i);
                points[i] = new PointComp(
                        (double) jsonPoint.get(0),
                        (double) jsonPoint.get(1),
                        (double) jsonPoint.get(2)
                );

            }
            // make faceList, UV list and texture lists
            // (the indices should match up, if they don't something went wrong)
            JSONArray faceListJson = (JSONArray) object.get("faceList");
            JSONArray uvPointsListJson = (JSONArray) object.get("uvPointsList");
            JSONArray texturesNamesJson = (JSONArray) object.get("textureList");

            int[][] faceList = new int[faceListJson.size()][];
            double[][][] uvPointsList = new double[faceListJson.size()][][];
            Texture[] texturesList = new Texture[faceListJson.size()];
            int uvIndex = 0;
            for (int i = 0; i < faceListJson.size(); i+=1) {
                JSONArray jsonFace = (JSONArray) faceListJson.get(i);
                String jsonTextureName = (String) texturesNamesJson.get(i);

                faceList[i] = new int[jsonFace.size()];
                uvPointsList[i] = new double[jsonFace.size()][];
                // probably inefficient linear search but idc because this code only runs once
                for (Texture texture : textures) {
                    if (Objects.equals(texture.name, jsonTextureName)) {
                        texturesList[i] = texture;
                        break;
                    }
                }
                for (int j = 0; j < jsonFace.size(); j += 1){
                    faceList[i][j] = (int)(long)jsonFace.get(j);
                    if(!texturesList[i].isSolid()){
                        uvPointsList[i][j] = new double[2];
                        uvPointsList[i][j][0] = (double)((JSONArray)uvPointsListJson.get(uvIndex)).get(0);
                        uvPointsList[i][j][1] = (double)((JSONArray)uvPointsListJson.get(uvIndex)).get(1);
                    }
                    uvIndex += 1;
                }

            }
            result.addObject(new Object3d(points, faceList, uvPointsList, false, texturesList, true));
        }
        return result;
    }
    public Texture[] getTextures(JSONArray textures){
        Texture[] result = new Texture[textures.size()];
        for(int i = 0; i < textures.size(); i += 1){
            JSONObject JsonTexture = (JSONObject) textures.get(i);
            if(Objects.equals(JsonTexture.get("type"), "solid")){
                result[i] = new Texture(JsonTexture.get("name").toString(), Color.decode('#' + (String) JsonTexture.get("color")));
            } else if(Objects.equals(JsonTexture.get("type"), "image")){
                result[i] = new Texture(JsonTexture.get("name").toString(), Color.decode('#' + (String) JsonTexture.get("color")), (String) JsonTexture.get("imgPath"));
            } else if(Objects.equals(JsonTexture.get("type"), "camera")){
                result[i] = new Texture(JsonTexture.get("name").toString());
            }
        }
        return result;
    }
}