Search in sources :

Example 1 with ModelElementRotation

use of com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelElement.ModelElementRotation in project InteractiveChat-DiscordSRV-Addon by LOOHP.

the class ModelManager method loadDirectory.

@Override
protected void loadDirectory(String namespace, ResourcePackFile root) {
    if (!root.exists() || !root.isDirectory()) {
        throw new IllegalArgumentException(root.getAbsolutePath() + " is not a directory.");
    }
    JSONParser parser = new JSONParser();
    Map<String, BlockModel> models = new HashMap<>();
    Collection<ResourcePackFile> files = root.listFilesRecursively(new String[] { "json" });
    for (ResourcePackFile file : files) {
        try {
            String key = namespace + ":" + file.getRelativePathFrom(root);
            key = key.substring(0, key.lastIndexOf("."));
            InputStreamReader reader = new InputStreamReader(new BOMInputStream(file.getInputStream()), StandardCharsets.UTF_8);
            JSONObject rootJson = (JSONObject) parser.parse(reader);
            reader.close();
            String parent = (String) rootJson.getOrDefault("parent", null);
            boolean ambientocclusion = (boolean) rootJson.getOrDefault("ambientocclusion", true);
            ModelGUILight guiLight = rootJson.containsKey("gui_light") ? ModelGUILight.fromKey((String) rootJson.get("gui_light")) : null;
            Map<ModelDisplayPosition, ModelDisplay> display = new EnumMap<>(ModelDisplayPosition.class);
            JSONObject displayJson = (JSONObject) rootJson.get("display");
            if (displayJson != null) {
                for (Object obj : displayJson.keySet()) {
                    String displayKey = obj.toString();
                    JSONArray rotationArray = (JSONArray) ((JSONObject) displayJson.get(displayKey)).get("rotation");
                    JSONArray translationArray = (JSONArray) ((JSONObject) displayJson.get(displayKey)).get("translation");
                    JSONArray scaleArray = (JSONArray) ((JSONObject) displayJson.get(displayKey)).get("scale");
                    Coordinates3D rotation;
                    if (rotationArray == null) {
                        rotation = new Coordinates3D(0, 0, 0);
                    } else {
                        rotation = new Coordinates3D(((Number) rotationArray.get(0)).doubleValue(), ((Number) rotationArray.get(1)).doubleValue(), ((Number) rotationArray.get(2)).doubleValue());
                    }
                    Coordinates3D translation;
                    if (translationArray == null) {
                        translation = new Coordinates3D(0, 0, 0);
                    } else {
                        translation = new Coordinates3D(((Number) translationArray.get(0)).doubleValue(), ((Number) translationArray.get(1)).doubleValue(), ((Number) translationArray.get(2)).doubleValue());
                    }
                    Coordinates3D scale;
                    if (scaleArray == null) {
                        scale = new Coordinates3D(1, 1, 1);
                    } else {
                        scale = new Coordinates3D(((Number) scaleArray.get(0)).doubleValue(), ((Number) scaleArray.get(1)).doubleValue(), ((Number) scaleArray.get(2)).doubleValue());
                    }
                    ModelDisplayPosition displayPos = ModelDisplayPosition.fromKey(displayKey);
                    display.put(displayPos, new ModelDisplay(displayPos, rotation, translation, scale));
                }
            }
            Map<String, String> texture = new HashMap<>();
            JSONObject textureJson = (JSONObject) rootJson.get("textures");
            if (textureJson != null) {
                for (Object obj : textureJson.keySet()) {
                    String textureKey = obj.toString();
                    texture.put(textureKey, textureJson.get(textureKey).toString());
                }
            }
            List<ModelElement> elements = new ArrayList<>();
            JSONArray elementsArray = (JSONArray) rootJson.get("elements");
            if (elementsArray != null) {
                for (Object obj : elementsArray) {
                    JSONObject elementJson = (JSONObject) obj;
                    JSONArray fromArray = (JSONArray) elementJson.get("from");
                    JSONArray toArray = (JSONArray) elementJson.get("to");
                    Coordinates3D from = new Coordinates3D(((Number) fromArray.get(0)).doubleValue(), ((Number) fromArray.get(1)).doubleValue(), ((Number) fromArray.get(2)).doubleValue());
                    Coordinates3D to = new Coordinates3D(((Number) toArray.get(0)).doubleValue(), ((Number) toArray.get(1)).doubleValue(), ((Number) toArray.get(2)).doubleValue());
                    ModelElementRotation rotation;
                    JSONObject rotationJson = (JSONObject) elementJson.get("rotation");
                    if (rotationJson == null) {
                        rotation = null;
                    } else {
                        Coordinates3D origin;
                        JSONArray originArray = (JSONArray) rotationJson.get("origin");
                        if (originArray == null) {
                            origin = new Coordinates3D(0, 0, 0);
                        } else {
                            origin = new Coordinates3D(((Number) originArray.get(0)).doubleValue(), ((Number) originArray.get(1)).doubleValue(), ((Number) originArray.get(2)).doubleValue());
                        }
                        ModelAxis axis = ModelAxis.valueOf(rotationJson.get("axis").toString().toUpperCase());
                        double angle = ((Number) rotationJson.get("angle")).doubleValue();
                        boolean rescale = (boolean) rotationJson.getOrDefault("rescale", false);
                        rotation = new ModelElementRotation(origin, axis, angle, rescale);
                    }
                    boolean shade = (boolean) elementJson.getOrDefault("shade", true);
                    Map<ModelFaceSide, ModelFace> face = new EnumMap<>(ModelFaceSide.class);
                    JSONObject facesJson = (JSONObject) elementJson.get("faces");
                    if (facesJson != null) {
                        for (Object obj1 : facesJson.keySet()) {
                            String faceKey = obj1.toString();
                            ModelFaceSide side = ModelFaceSide.fromKey(faceKey);
                            JSONObject faceJson = (JSONObject) facesJson.get(faceKey);
                            TextureUV uv;
                            JSONArray uvArray = (JSONArray) faceJson.get("uv");
                            if (uvArray == null) {
                                uv = null;
                            } else {
                                uv = new TextureUV(((Number) uvArray.get(0)).doubleValue(), ((Number) uvArray.get(1)).doubleValue(), ((Number) uvArray.get(2)).doubleValue(), ((Number) uvArray.get(3)).doubleValue());
                            }
                            String faceTexture = (String) faceJson.get("texture");
                            Object cullfaceObj = faceJson.get("cullface");
                            ModelFaceSide cullface = null;
                            if (cullfaceObj != null && cullfaceObj instanceof String) {
                                cullface = ModelFaceSide.fromKey((String) cullfaceObj);
                            }
                            if (cullface == null) {
                                cullface = side;
                            }
                            int faceRotation = ((Number) faceJson.getOrDefault("rotation", 0)).intValue();
                            int faceTintindex = ((Number) faceJson.getOrDefault("tintindex", -1)).intValue();
                            face.put(side, new ModelFace(side, uv, faceTexture, cullface, faceRotation, faceTintindex));
                        }
                    }
                    elements.add(new ModelElement(from, to, rotation, shade, face));
                }
            }
            List<ModelOverride> overrides = new ArrayList<>();
            JSONArray overridesArray = (JSONArray) rootJson.get("overrides");
            if (overridesArray != null) {
                for (Object obj : overridesArray) {
                    JSONObject overrideJson = (JSONObject) obj;
                    JSONObject predicateJson = (JSONObject) overrideJson.get("predicate");
                    Map<ModelOverrideType, Float> predicates = new EnumMap<>(ModelOverrideType.class);
                    for (Object obj1 : predicateJson.keySet()) {
                        String predicateTypeKey = obj1.toString();
                        ModelOverrideType type = ModelOverrideType.fromKey(predicateTypeKey);
                        Object value = predicateJson.get(predicateTypeKey);
                        predicates.put(type, ((Number) value).floatValue());
                    }
                    String model = (String) overrideJson.get("model");
                    overrides.add(new ModelOverride(predicates, model));
                }
            }
            Collections.reverse(overrides);
            models.put(key, new BlockModel(this, parent, ambientocclusion, guiLight, display, texture, elements, overrides));
        } catch (Exception e) {
            new ResourceLoadingException("Unable to load block model " + file.getAbsolutePath(), e).printStackTrace();
        }
    }
    this.models.putAll(models);
}
Also used : ModelDisplayPosition(com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelDisplay.ModelDisplayPosition) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BOMInputStream(com.loohp.interactivechat.libs.org.apache.commons.io.input.BOMInputStream) ResourceLoadingException(com.loohp.interactivechatdiscordsrvaddon.resources.ResourceLoadingException) ModelOverrideType(com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelOverride.ModelOverrideType) EnumMap(java.util.EnumMap) InputStreamReader(java.io.InputStreamReader) JSONArray(com.loohp.interactivechat.libs.org.json.simple.JSONArray) ModelFaceSide(com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelFace.ModelFaceSide) ResourceLoadingException(com.loohp.interactivechatdiscordsrvaddon.resources.ResourceLoadingException) ModelElementRotation(com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelElement.ModelElementRotation) JSONObject(com.loohp.interactivechat.libs.org.json.simple.JSONObject) JSONParser(com.loohp.interactivechat.libs.org.json.simple.parser.JSONParser) ResourcePackFile(com.loohp.interactivechatdiscordsrvaddon.resources.ResourcePackFile) JSONObject(com.loohp.interactivechat.libs.org.json.simple.JSONObject)

Example 2 with ModelElementRotation

use of com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelElement.ModelElementRotation in project InteractiveChat-DiscordSRV-Addon by LOOHP.

the class ModelRenderer method generateStandardRenderModel.

@SuppressWarnings("SuspiciousNameCombination")
private Model generateStandardRenderModel(BlockModel blockModel, ResourceManager manager, Map<String, TextureResource> providedTextures, TintIndexData tintIndexData, boolean enchanted, boolean skin) {
    Map<String, BufferedImage> cachedResize = new ConcurrentHashMap<>();
    List<ModelElement> elements = new ArrayList<>(blockModel.getElements());
    List<Hexahedron> hexahedrons = new ArrayList<>(elements.size());
    Queue<Future<Hexahedron>> tasks = new ConcurrentLinkedQueue<>();
    Iterator<ModelElement> itr = elements.iterator();
    while (itr.hasNext()) {
        ModelElement element = itr.next();
        tasks.add(modelResolvingService.submit(() -> {
            ModelElementRotation rotation = element.getRotation();
            boolean ignoreZFight = false;
            if (rotation != null) {
                ignoreZFight = rotation.isRescale();
            }
            Hexahedron hexahedron = Hexahedron.fromCorners(new Point3D(element.getFrom().getX(), element.getFrom().getY(), element.getFrom().getZ()), new Point3D(element.getTo().getX(), element.getTo().getY(), element.getTo().getZ()), ignoreZFight, new BufferedImage[6]);
            BufferedImage[] images = new BufferedImage[6];
            BufferedImage[] overlayImages = new BufferedImage[6];
            int i = 0;
            for (ModelFaceSide side : ModelFaceSide.values()) {
                ModelFace faceData = element.getFace(side);
                if (faceData == null) {
                    images[i] = null;
                } else {
                    TextureUV uv = faceData.getUV();
                    TextureResource resource = providedTextures.get(faceData.getTexture());
                    if (resource == null) {
                        resource = manager.getTextureManager().getTexture(faceData.getTexture(), false);
                    }
                    if (resource == null || !resource.isTexture()) {
                        images[i] = null;
                    } else if (uv != null && (uv.getXDiff() == 0 || uv.getYDiff() == 0)) {
                        images[i] = null;
                    } else {
                        BufferedImage cached = cachedResize.get(faceData.getTexture());
                        if (cached == null) {
                            cached = resource.getTexture();
                            if (resource.hasTextureMeta()) {
                                TextureMeta meta = resource.getTextureMeta();
                                if (meta.hasProperties()) {
                                    TextureProperties properties = meta.getProperties();
                                    if (properties.isBlur()) {
                                        cached = ImageUtils.applyGaussianBlur(cached);
                                    }
                                }
                                if (meta.hasAnimation()) {
                                    TextureAnimation animation = meta.getAnimation();
                                    if (animation.hasWidth() && animation.hasHeight()) {
                                        cached = ImageUtils.copyAndGetSubImage(cached, 0, 0, animation.getWidth(), animation.getHeight());
                                    } else {
                                        cached = ImageUtils.copyAndGetSubImage(cached, 0, 0, cached.getWidth(), cached.getWidth());
                                    }
                                }
                            }
                            if (cached.getWidth() > cached.getHeight()) {
                                cached = ImageUtils.resizeImageFillWidth(cached, skin ? SKIN_RESOLUTION : TEXTURE_RESOLUTION);
                            } else {
                                cached = ImageUtils.resizeImageFillHeight(cached, skin ? SKIN_RESOLUTION : TEXTURE_RESOLUTION);
                            }
                            cachedResize.put(faceData.getTexture(), cached);
                        }
                        images[i] = ImageUtils.copyImage(cached);
                        if (uv == null) {
                            Point3D[] points;
                            switch(side) {
                                case DOWN:
                                    points = hexahedron.getDownFace().getPoints();
                                    break;
                                case EAST:
                                    points = hexahedron.getEastFace().getPoints();
                                    break;
                                case NORTH:
                                    points = hexahedron.getNorthFace().getPoints();
                                    break;
                                case SOUTH:
                                    points = hexahedron.getSouthFace().getPoints();
                                    break;
                                case UP:
                                    points = hexahedron.getUpFace().getPoints();
                                    break;
                                case WEST:
                                default:
                                    points = hexahedron.getWestFace().getPoints();
                                    break;
                            }
                            double x1;
                            double y1;
                            double x2;
                            double y2;
                            if (points[0].x == points[2].x) {
                                x1 = points[0].y;
                                y1 = points[0].z;
                                x2 = points[2].y;
                                y2 = points[2].z;
                            } else if (points[0].y == points[2].y) {
                                x1 = points[0].z;
                                y1 = points[0].x;
                                x2 = points[2].z;
                                y2 = points[2].x;
                            } else {
                                x1 = points[0].y;
                                y1 = points[0].x;
                                x2 = points[2].y;
                                y2 = points[2].x;
                            }
                            uv = new TextureUV(Math.min(x1, x2), Math.min(y1, y2), Math.max(x1, x2), Math.max(y1, y2));
                        }
                        uv = uv.getScaled(1, (double) images[i].getHeight() / (double) images[i].getWidth());
                        uv = uv.getScaled((double) images[i].getWidth() / 16.0);
                        int x1 = (int) Math.ceil(uv.getX1());
                        int y1 = (int) Math.ceil(uv.getY1());
                        int dX = Math.abs((int) Math.floor(uv.getX2()) - x1);
                        int dY = Math.abs((int) Math.floor(uv.getY2()) - y1);
                        if (uv.isVerticallyFlipped()) {
                            images[i] = ImageUtils.flipVertically(images[i]);
                            y1 = images[i].getHeight() - y1;
                        }
                        if (uv.isHorizontallyFlipped()) {
                            images[i] = ImageUtils.flipHorizontal(images[i]);
                            x1 = images[i].getWidth() - x1;
                        }
                        images[i] = ImageUtils.copyAndGetSubImage(images[i], x1, y1, Math.max(1, dX), Math.max(1, dY));
                        int rotationAngle = faceData.getRotation();
                        if (rotationAngle % 360 != 0) {
                            images[i] = ImageUtils.rotateImageByDegrees(images[i], rotationAngle);
                        }
                        images[i] = tintIndexData.applyTint(images[i], faceData.getTintindex());
                        if (enchanted) {
                            overlayImages[i] = rawEnchantmentGlintProvider.apply(images[i]);
                        }
                    }
                }
                i++;
            }
            hexahedron.setImage(images);
            hexahedron.setOverlay(overlayImages);
            hexahedron.setOverlayAdditionFactor(OVERLAY_ADDITION_FACTORS);
            if (rotation != null) {
                hexahedron.translate(-rotation.getOrigin().getX(), -rotation.getOrigin().getY(), -rotation.getOrigin().getZ());
                switch(rotation.getAxis()) {
                    case X:
                        hexahedron.rotate(rotation.getAngle(), 0, 0, false);
                        break;
                    case Y:
                        hexahedron.rotate(0, rotation.getAngle(), 0, false);
                        break;
                    case Z:
                    default:
                        hexahedron.rotate(0, 0, rotation.getAngle(), false);
                        break;
                }
                hexahedron.translate(rotation.getOrigin().getX(), rotation.getOrigin().getY(), rotation.getOrigin().getZ());
            }
            return hexahedron;
        }));
        itr.remove();
    }
    while (!tasks.isEmpty() || !elements.isEmpty()) {
        Future<Hexahedron> task = tasks.poll();
        if (task == null) {
            try {
                TimeUnit.MILLISECONDS.sleep(1);
            } catch (InterruptedException e) {
            }
        } else {
            try {
                hexahedrons.add(task.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
    }
    return new Model(hexahedrons);
}
Also used : TextureResource(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureResource) ArrayList(java.util.ArrayList) BufferedImage(java.awt.image.BufferedImage) ModelElement(com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelElement) TextureUV(com.loohp.interactivechatdiscordsrvaddon.resources.models.TextureUV) ModelFace(com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelFace) Hexahedron(com.loohp.blockmodelrenderer.render.Hexahedron) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ExecutionException(java.util.concurrent.ExecutionException) TextureAnimation(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureAnimation) ModelFaceSide(com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelFace.ModelFaceSide) ModelElementRotation(com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelElement.ModelElementRotation) TextureProperties(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureProperties) Point3D(com.loohp.blockmodelrenderer.render.Point3D) TextureMeta(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureMeta) Model(com.loohp.blockmodelrenderer.render.Model) BlockModel(com.loohp.interactivechatdiscordsrvaddon.resources.models.BlockModel) Future(java.util.concurrent.Future) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue)

Aggregations

ModelElementRotation (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelElement.ModelElementRotation)2 ModelFaceSide (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelFace.ModelFaceSide)2 ArrayList (java.util.ArrayList)2 Hexahedron (com.loohp.blockmodelrenderer.render.Hexahedron)1 Model (com.loohp.blockmodelrenderer.render.Model)1 Point3D (com.loohp.blockmodelrenderer.render.Point3D)1 BOMInputStream (com.loohp.interactivechat.libs.org.apache.commons.io.input.BOMInputStream)1 JSONArray (com.loohp.interactivechat.libs.org.json.simple.JSONArray)1 JSONObject (com.loohp.interactivechat.libs.org.json.simple.JSONObject)1 JSONParser (com.loohp.interactivechat.libs.org.json.simple.parser.JSONParser)1 ResourceLoadingException (com.loohp.interactivechatdiscordsrvaddon.resources.ResourceLoadingException)1 ResourcePackFile (com.loohp.interactivechatdiscordsrvaddon.resources.ResourcePackFile)1 BlockModel (com.loohp.interactivechatdiscordsrvaddon.resources.models.BlockModel)1 ModelDisplayPosition (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelDisplay.ModelDisplayPosition)1 ModelElement (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelElement)1 ModelFace (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelFace)1 ModelOverrideType (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelOverride.ModelOverrideType)1 TextureUV (com.loohp.interactivechatdiscordsrvaddon.resources.models.TextureUV)1 TextureAnimation (com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureAnimation)1 TextureMeta (com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureMeta)1