Search in sources :

Example 1 with BlockModel

use of com.loohp.interactivechatdiscordsrvaddon.resources.models.BlockModel 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 BlockModel

use of com.loohp.interactivechatdiscordsrvaddon.resources.models.BlockModel 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)

Example 3 with BlockModel

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

the class ModelRenderer method render.

public RenderResult render(int width, int height, int internalWidth, int internalHeight, ResourceManager manager, boolean post1_8, String modelKey, ModelDisplayPosition displayPosition, Map<ModelOverrideType, Float> predicate, Map<String, TextureResource> providedTextures, TintIndexData tintIndexData, boolean enchanted, boolean usePlayerModelPosition) {
    String cacheKey = cacheKey(width, height, manager.getUuid(), modelKey, displayPosition, predicate, cacheKeyProvidedTextures(providedTextures), enchanted);
    Cache<?> cachedRender = Cache.getCache(cacheKey);
    if (cachedRender != null) {
        RenderResult cachedResult = (RenderResult) cachedRender.getObject();
        if (cachedResult.isSuccessful()) {
            return cachedResult;
        }
    }
    String rejectedReason = null;
    BlockModel blockModel = manager.getModelManager().resolveBlockModel(modelKey, post1_8, predicate);
    if (blockModel == null) {
        return new RenderResult(MODEL_NOT_FOUND, null);
    }
    BufferedImage image = new BufferedImage(internalWidth, internalHeight, BufferedImage.TYPE_INT_ARGB);
    if (blockModel.getRawParent() == null || !blockModel.getRawParent().contains("/")) {
        renderBlockModel(generateStandardRenderModel(blockModel, manager, providedTextures, tintIndexData, enchanted, false), image, blockModel.getDisplay(displayPosition), blockModel.getGUILight(), usePlayerModelPosition);
    } else if (blockModel.getRawParent().equals(ModelManager.ITEM_BASE)) {
        Graphics2D g = image.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
        for (int i = 0; blockModel.getTextures().containsKey(ModelManager.ITEM_BASE_LAYER + i); i++) {
            String resourceLocation = blockModel.getTextures().get(ModelManager.ITEM_BASE_LAYER + i);
            if (!resourceLocation.contains(":")) {
                resourceLocation = ResourceRegistry.DEFAULT_NAMESPACE + ":" + resourceLocation;
            }
            TextureResource resource = providedTextures.get(resourceLocation);
            if (resource == null) {
                resource = manager.getTextureManager().getTexture(resourceLocation);
            }
            BufferedImage texture = resource.getTexture();
            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 (enchanted) {
            image = enchantmentGlintProvider.apply(image);
        }
    } else {
        rejectedReason = blockModel.getRawParent();
    }
    RenderResult result;
    if (rejectedReason == null) {
        result = new RenderResult(ImageUtils.resizeImageQuality(image, width, height), blockModel);
    } else {
        result = new RenderResult(rejectedReason == null ? "null" : rejectedReason, blockModel);
    }
    Cache.putCache(cacheKey, result, cacheTimeoutSupplier.getAsLong());
    return result;
}
Also used : TextureResource(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureResource) TextureProperties(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureProperties) TextureMeta(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureMeta) TextureAnimation(com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureAnimation) BlockModel(com.loohp.interactivechatdiscordsrvaddon.resources.models.BlockModel) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D)

Aggregations

BlockModel (com.loohp.interactivechatdiscordsrvaddon.resources.models.BlockModel)3 TextureAnimation (com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureAnimation)3 TextureMeta (com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureMeta)3 TextureProperties (com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureProperties)3 TextureResource (com.loohp.interactivechatdiscordsrvaddon.resources.textures.TextureResource)3 BufferedImage (java.awt.image.BufferedImage)3 Model (com.loohp.blockmodelrenderer.render.Model)2 Graphics2D (java.awt.Graphics2D)2 Hexahedron (com.loohp.blockmodelrenderer.render.Hexahedron)1 Point3D (com.loohp.blockmodelrenderer.render.Point3D)1 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 ArrayList (java.util.ArrayList)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)1