Search in sources :

Example 1 with Model

use of com.loohp.blockmodelrenderer.render.Model 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)

Example 2 with Model

use of com.loohp.blockmodelrenderer.render.Model in project InteractiveChat-DiscordSRV-Addon by LOOHP.

the class ModelRenderer method generateItemRenderModel.

private Model generateItemRenderModel(double width, double height, double depth, BufferedImage image) {
    int w = image.getWidth();
    int h = image.getHeight();
    double intervalX = (1.0 / (double) w) * width;
    double intervalY = (1.0 / (double) h) * height;
    double z = depth / 2 - 0.5;
    List<Hexahedron> hexahedrons = new ArrayList<>();
    int[] colors = image.getRGB(0, 0, w, h, null, 0, w);
    hexahedrons.add(Hexahedron.fromCorners(new Point3D(0, 0, z), new Point3D(width, height, z + 1), false, new BufferedImage[] { null, null, ImageUtils.copyImage(image), null, ImageUtils.copyImage(image), null }));
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            int color = colors[y * w + x];
            if (ColorUtils.getAlpha(color) > 0) {
                BufferedImage pixel = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
                pixel.setRGB(0, 0, color);
                BufferedImage[] imageArray = new BufferedImage[6];
                // u
                imageArray[0] = ColorUtils.getAlpha(ImageUtils.getRGB(colors, x, y + 1, w, h)) <= 0 ? ImageUtils.copyImage(pixel) : null;
                // d
                imageArray[1] = ColorUtils.getAlpha(ImageUtils.getRGB(colors, x, y - 1, w, h)) <= 0 ? ImageUtils.copyImage(pixel) : null;
                // n
                imageArray[2] = null;
                // e
                imageArray[3] = ColorUtils.getAlpha(ImageUtils.getRGB(colors, x + 1, y, w, h)) <= 0 ? ImageUtils.copyImage(pixel) : null;
                // s
                imageArray[4] = null;
                // w
                imageArray[5] = ColorUtils.getAlpha(ImageUtils.getRGB(colors, x - 1, y, w, h)) <= 0 ? ImageUtils.copyImage(pixel) : null;
                if (!CustomArrayUtils.allNull(imageArray)) {
                    double scaledX = (double) x * intervalX;
                    double scaledY = height - (double) y * intervalY;
                    hexahedrons.add(Hexahedron.fromCorners(new Point3D(scaledX, scaledY, z), new Point3D(scaledX + intervalX, scaledY - intervalY, z + 1), false, imageArray));
                }
            }
        }
    }
    return new Model(hexahedrons);
}
Also used : Point3D(com.loohp.blockmodelrenderer.render.Point3D) Hexahedron(com.loohp.blockmodelrenderer.render.Hexahedron) ArrayList(java.util.ArrayList) Model(com.loohp.blockmodelrenderer.render.Model) BlockModel(com.loohp.interactivechatdiscordsrvaddon.resources.models.BlockModel) BufferedImage(java.awt.image.BufferedImage)

Example 3 with Model

use of com.loohp.blockmodelrenderer.render.Model in project InteractiveChat-DiscordSRV-Addon by LOOHP.

the class ModelRenderer method renderPlayer.

public RenderResult renderPlayer(int width, int height, ResourceManager manager, boolean post1_8, boolean slim, Map<String, TextureResource> providedTextures, TintIndexData tintIndexData, Map<PlayerModelItemPosition, PlayerModelItem> modelItems) {
    String cacheKey = cacheKey(width, height, manager.getUuid(), slim, cacheKeyModelItems(modelItems), cacheKeyProvidedTextures(providedTextures));
    Cache<?> cachedRender = Cache.getCache(cacheKey);
    if (cachedRender != null) {
        RenderResult cachedResult = (RenderResult) cachedRender.getObject();
        if (cachedResult.isSuccessful()) {
            return cachedResult;
        }
    }
    BlockModel playerModel = manager.getModelManager().resolveBlockModel(slim ? PLAYER_MODEL_SLIM_RESOURCELOCATION : PLAYER_MODEL_RESOURCELOCATION, InteractiveChat.version.isOld(), Collections.emptyMap());
    if (playerModel == null) {
        return new RenderResult(MODEL_NOT_FOUND, null);
    }
    Model playerRenderModel = generateStandardRenderModel(playerModel, manager, providedTextures, tintIndexData, false, true);
    for (PlayerModelItem playerModelItem : modelItems.values()) {
        BlockModel itemBlockModel = playerModelItem.getModelKey() == null ? null : manager.getModelManager().resolveBlockModel(playerModelItem.getModelKey(), InteractiveChat.version.isOld(), playerModelItem.getPredicate());
        Model itemRenderModel = null;
        if (itemBlockModel != null) {
            if (itemBlockModel.getRawParent() == null || !itemBlockModel.getRawParent().contains("/")) {
                itemRenderModel = generateStandardRenderModel(itemBlockModel, manager, playerModelItem.getProvidedTextures(), playerModelItem.getTintIndexData(), playerModelItem.isEnchanted(), false);
            } else if (itemBlockModel.getRawParent().equals(ModelManager.ITEM_BASE)) {
                BufferedImage image = new BufferedImage(INTERNAL_W, INTERNAL_H, BufferedImage.TYPE_INT_ARGB);
                Graphics2D g = image.createGraphics();
                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
                for (int i = 0; itemBlockModel.getTextures().containsKey(ModelManager.ITEM_BASE_LAYER + i); i++) {
                    String resourceLocation = itemBlockModel.getTextures().get(ModelManager.ITEM_BASE_LAYER + i);
                    if (!resourceLocation.contains(":")) {
                        resourceLocation = ResourceRegistry.DEFAULT_NAMESPACE + ":" + resourceLocation;
                    }
                    TextureResource resource = playerModelItem.getProvidedTextures().get(resourceLocation);
                    if (resource == null) {
                        resource = manager.getTextureManager().getTexture(resourceLocation);
                    }
                    BufferedImage texture = resource.getTexture();
                    texture = tintIndexData.applyTint(texture, 1);
                    if (resource.hasTextureMeta()) {
                        TextureMeta meta = resource.getTextureMeta();
                        if (meta.hasProperties()) {
                            TextureProperties properties = meta.getProperties();
                            if (properties.isBlur()) {
                                texture = ImageUtils.applyGaussianBlur(texture);
                            }
                        }
                        if (meta.hasAnimation()) {
                            TextureAnimation animation = meta.getAnimation();
                            if (animation.hasWidth() && animation.hasHeight()) {
                                texture = ImageUtils.copyAndGetSubImage(texture, 0, 0, animation.getWidth(), animation.getHeight());
                            } else {
                                texture = ImageUtils.copyAndGetSubImage(texture, 0, 0, texture.getWidth(), texture.getWidth());
                            }
                        }
                    }
                    if (resourceLocation.equals(ResourceRegistry.MAP_MARKINGS_LOCATION)) {
                        ImageUtils.xor(image, ImageUtils.resizeImageAbs(texture, image.getWidth(), image.getHeight()), 200);
                    } else {
                        g.drawImage(texture, 0, 0, image.getWidth(), image.getHeight(), null);
                    }
                }
                g.dispose();
                image = tintIndexData.applyTint(image, 0);
                if (playerModelItem.isEnchanted()) {
                    image = enchantmentGlintProvider.apply(image);
                }
                itemRenderModel = generateItemRenderModel(16, 16, 16, image);
            }
        }
        if (itemRenderModel != null) {
            itemRenderModel.translate(-16 / 2.0, -16 / 2.0, -16 / 2.0);
            ModelDisplay displayData = itemBlockModel.getRawDisplay().get(playerModelItem.getPosition().getModelDisplayPosition());
            boolean flipX = playerModelItem.getPosition().isLiteralFlipped();
            boolean isMirror = false;
            if (displayData == null && playerModelItem.getPosition().getModelDisplayPosition().hasFallback()) {
                displayData = itemBlockModel.getRawDisplay().get(playerModelItem.getPosition().getModelDisplayPosition().getFallback());
                isMirror = true;
            }
            if (isMirror || !flipX) {
                if (displayData != null) {
                    Coordinates3D scale = displayData.getScale();
                    itemRenderModel.scale(scale.getX(), scale.getY(), scale.getZ());
                    Coordinates3D rotation = displayData.getRotation();
                    itemRenderModel.rotate(rotation.getX(), rotation.getY(), rotation.getZ() + (post1_8 ? 10 : 0), false);
                    Coordinates3D transform = displayData.getTranslation();
                    itemRenderModel.translate(transform.getX(), transform.getY() + (post1_8 ? -10 : 0), transform.getZ() + (post1_8 ? -2.75 : 0));
                }
                if (flipX) {
                    itemRenderModel.flipAboutPlane(false, true, true);
                }
            } else {
                if (displayData != null) {
                    Coordinates3D scale = displayData.getScale();
                    itemRenderModel.scale(scale.getX(), scale.getY(), scale.getZ());
                    Coordinates3D rotation = displayData.getRotation();
                    itemRenderModel.rotate(rotation.getX(), -rotation.getY(), -rotation.getZ(), false);
                    Coordinates3D transform = displayData.getTranslation();
                    itemRenderModel.translate(-transform.getX(), transform.getY(), transform.getZ());
                }
            }
            if (playerModelItem.getPosition().yIsZAxis()) {
                if (post1_8) {
                    itemRenderModel.rotate(180, 180, 0, false);
                } else {
                    itemRenderModel.rotate(90, 0, 0, true);
                }
            }
            double scale = playerModelItem.getPosition().getScale();
            itemRenderModel.scale(scale, scale, scale);
            itemRenderModel.translate((16 * scale) / 2, (16 * scale) / 2, (16 * scale) / 2);
            Coordinates3D defaultTranslation = playerModelItem.getPosition().getDefaultTranslate();
            itemRenderModel.translate(defaultTranslation.getX(), defaultTranslation.getY(), defaultTranslation.getZ());
            playerRenderModel.append(itemRenderModel);
        }
    }
    playerRenderModel.translate(-16 / 2.0, -16 / 2.0, -16 / 2.0);
    playerRenderModel.rotate(0, 180, 0, false);
    playerRenderModel.translate(16 / 2.0, 16 / 2.0, 16 / 2.0);
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    renderPlayerModel(playerRenderModel, image, playerModel.getGUILight());
    RenderResult result = new RenderResult(image, null);
    Cache.putCache(cacheKey, result, cacheTimeoutSupplier.getAsLong());
    return result;
}
Also used : TextureResource(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureResource) Coordinates3D(com.loohp.interactivechatdiscordsrvaddon.resources.models.Coordinates3D) TextureAnimation(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureAnimation) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D) TextureProperties(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureProperties) TextureMeta(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureMeta) Model(com.loohp.blockmodelrenderer.render.Model) BlockModel(com.loohp.interactivechatdiscordsrvaddon.resources.models.BlockModel) BlockModel(com.loohp.interactivechatdiscordsrvaddon.resources.models.BlockModel) ModelDisplay(com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelDisplay)

Aggregations

Model (com.loohp.blockmodelrenderer.render.Model)3 BlockModel (com.loohp.interactivechatdiscordsrvaddon.resources.models.BlockModel)3 BufferedImage (java.awt.image.BufferedImage)3 Hexahedron (com.loohp.blockmodelrenderer.render.Hexahedron)2 Point3D (com.loohp.blockmodelrenderer.render.Point3D)2 TextureAnimation (com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureAnimation)2 TextureMeta (com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureMeta)2 TextureProperties (com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureProperties)2 TextureResource (com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureResource)2 ArrayList (java.util.ArrayList)2 Coordinates3D (com.loohp.interactivechatdiscordsrvaddon.resources.models.Coordinates3D)1 ModelDisplay (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelDisplay)1 ModelElement (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelElement)1 ModelElementRotation (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelElement.ModelElementRotation)1 ModelFace (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelFace)1 ModelFaceSide (com.loohp.interactivechatdiscordsrvaddon.resources.models.ModelFace.ModelFaceSide)1 TextureUV (com.loohp.interactivechatdiscordsrvaddon.resources.models.TextureUV)1 Graphics2D (java.awt.Graphics2D)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)1