mirror of
https://github.com/GeyserMC/Rainbow.git
synced 2025-12-19 14:59:16 +00:00
Only stitch/export first frame of animation
This commit is contained in:
@@ -2,31 +2,33 @@ package org.geysermc.rainbow.client;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.item.ClientItem;
|
||||
import net.minecraft.client.renderer.texture.SpriteContents;
|
||||
import net.minecraft.client.resources.model.AtlasManager;
|
||||
import net.minecraft.client.resources.model.EquipmentAssetManager;
|
||||
import net.minecraft.client.resources.model.EquipmentClientInfo;
|
||||
import net.minecraft.client.resources.model.ModelManager;
|
||||
import net.minecraft.client.resources.model.ResolvedModel;
|
||||
import net.minecraft.data.AtlasIds;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.world.item.equipment.EquipmentAsset;
|
||||
import org.geysermc.rainbow.client.accessor.ResolvedModelAccessor;
|
||||
import org.geysermc.rainbow.client.mixin.EntityRenderDispatcherAccessor;
|
||||
import org.geysermc.rainbow.mapping.AssetResolver;
|
||||
import org.geysermc.rainbow.mapping.texture.TextureResource;
|
||||
import org.geysermc.rainbow.mixin.SpriteContentsAccessor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Optional;
|
||||
|
||||
public class MinecraftAssetResolver implements AssetResolver {
|
||||
private final ModelManager modelManager;
|
||||
private final EquipmentAssetManager equipmentAssetManager;
|
||||
private final ResourceManager resourceManager;
|
||||
private final AtlasManager atlasManager;
|
||||
|
||||
public MinecraftAssetResolver(Minecraft minecraft) {
|
||||
modelManager = minecraft.getModelManager();
|
||||
equipmentAssetManager = ((EntityRenderDispatcherAccessor) minecraft.getEntityRenderDispatcher()).getEquipmentAssets();
|
||||
resourceManager = minecraft.getResourceManager();
|
||||
atlasManager = minecraft.getAtlasManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,7 +47,8 @@ public class MinecraftAssetResolver implements AssetResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openAsset(ResourceLocation location) throws IOException {
|
||||
return resourceManager.open(location);
|
||||
public Optional<TextureResource> getBlockTexture(ResourceLocation location) {
|
||||
SpriteContents contents = atlasManager.getAtlasOrThrow(AtlasIds.BLOCKS).getSprite(location).contents();
|
||||
return Optional.of(new TextureResource(((SpriteContentsAccessor) contents).getOriginalImage(), contents.width(), contents.height()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package org.geysermc.rainbow.datagen;
|
||||
|
||||
import com.google.common.hash.HashCode;
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.fabricmc.fabric.api.client.datagen.v1.provider.FabricModelProvider;
|
||||
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||
@@ -10,6 +10,7 @@ import net.minecraft.client.data.models.model.ModelInstance;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.renderer.block.model.ItemModelGenerator;
|
||||
import net.minecraft.client.renderer.item.ClientItem;
|
||||
import net.minecraft.client.resources.metadata.animation.AnimationMetadataSection;
|
||||
import net.minecraft.client.resources.model.EquipmentClientInfo;
|
||||
import net.minecraft.client.resources.model.ResolvedModel;
|
||||
import net.minecraft.client.resources.model.UnbakedModel;
|
||||
@@ -28,6 +29,7 @@ import org.geysermc.rainbow.Rainbow;
|
||||
import org.geysermc.rainbow.RainbowIO;
|
||||
import org.geysermc.rainbow.mapping.AssetResolver;
|
||||
import org.geysermc.rainbow.mapping.PackSerializer;
|
||||
import org.geysermc.rainbow.mapping.texture.TextureResource;
|
||||
import org.geysermc.rainbow.pack.BedrockPack;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -196,8 +198,15 @@ public abstract class RainbowModelProvider extends FabricModelProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream openAsset(ResourceLocation location) throws IOException {
|
||||
return resourceManager.open(location);
|
||||
public Optional<TextureResource> getBlockTexture(ResourceLocation location) {
|
||||
return resourceManager.getResource(Rainbow.decorateTextureLocation(location))
|
||||
.flatMap(resource -> RainbowIO.safeIO(() -> {
|
||||
Optional<AnimationMetadataSection> animationMetadata = resource.metadata().getSection(AnimationMetadataSection.TYPE);
|
||||
try (InputStream textureStream = resource.open()) {
|
||||
NativeImage texture = NativeImage.read(textureStream);
|
||||
return new TextureResource(texture, animationMetadata.map(animation -> animation.calculateFrameSize(texture.getWidth(), texture.getHeight())));
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,8 @@ import net.minecraft.client.resources.model.ResolvedModel;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.equipment.EquipmentAsset;
|
||||
import org.geysermc.rainbow.mapping.texture.TextureResource;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface AssetResolver {
|
||||
@@ -19,5 +18,5 @@ public interface AssetResolver {
|
||||
|
||||
Optional<EquipmentClientInfo> getEquipmentInfo(ResourceKey<EquipmentAsset> key);
|
||||
|
||||
InputStream openAsset(ResourceLocation location) throws IOException;
|
||||
Optional<TextureResource> getBlockTexture(ResourceLocation location);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package org.geysermc.rainbow.mapping.texture;
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.util.ProblemReporter;
|
||||
import org.geysermc.rainbow.Rainbow;
|
||||
import org.geysermc.rainbow.RainbowIO;
|
||||
import org.geysermc.rainbow.image.NativeImageUtil;
|
||||
import org.geysermc.rainbow.mapping.AssetResolver;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class BuiltInTextureHolder extends TextureHolder {
|
||||
@@ -21,9 +21,12 @@ public class BuiltInTextureHolder extends TextureHolder {
|
||||
@Override
|
||||
public Optional<byte[]> load(AssetResolver assetResolver, ProblemReporter reporter) {
|
||||
return RainbowIO.safeIO(() -> {
|
||||
try (InputStream texture = assetResolver.openAsset(Rainbow.decorateTextureLocation(source))) {
|
||||
return texture.readAllBytes();
|
||||
} catch (FileNotFoundException | NullPointerException exception) {
|
||||
try (TextureResource texture = assetResolver.getBlockTexture(source).orElse(null)) {
|
||||
Objects.requireNonNull(texture);
|
||||
try (NativeImage firstFrame = texture.getFirstFrame(false)) {
|
||||
return NativeImageUtil.writeToByteArray(firstFrame);
|
||||
}
|
||||
} catch (NullPointerException exception) {
|
||||
reportMissing(reporter);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import net.minecraft.client.renderer.block.model.TextureSlots;
|
||||
import net.minecraft.client.renderer.texture.SpriteContents;
|
||||
import net.minecraft.client.renderer.texture.SpriteLoader;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.metadata.animation.FrameSize;
|
||||
import net.minecraft.client.resources.model.Material;
|
||||
import net.minecraft.data.AtlasIds;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
@@ -17,7 +16,6 @@ import org.geysermc.rainbow.mixin.SpriteContentsAccessor;
|
||||
import org.geysermc.rainbow.mixin.SpriteLoaderAccessor;
|
||||
import org.geysermc.rainbow.mixin.TextureSlotsAccessor;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -58,10 +56,12 @@ public record StitchedTextures(Map<String, TextureAtlasSprite> sprites, Supplier
|
||||
|
||||
private static Optional<SpriteContents> readSpriteContents(ResourceLocation location, PackContext context) {
|
||||
return RainbowIO.safeIO(() -> {
|
||||
try (InputStream textureStream = context.assetResolver().openAsset(Rainbow.decorateTextureLocation(location))) {
|
||||
NativeImage texture = NativeImage.read(textureStream);
|
||||
return new SpriteContents(location, new FrameSize(texture.getWidth(), texture.getHeight()), texture);
|
||||
try (TextureResource texture = context.assetResolver().getBlockTexture(location).orElse(null)) {
|
||||
if (texture != null) {
|
||||
return new SpriteContents(location, texture.sizeOfFrame(), texture.getFirstFrame(true));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package org.geysermc.rainbow.mapping.texture;
|
||||
|
||||
import com.mojang.blaze3d.platform.NativeImage;
|
||||
import net.minecraft.client.resources.metadata.animation.FrameSize;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public record TextureResource(NativeImage texture, Optional<FrameSize> frameSize) implements AutoCloseable {
|
||||
|
||||
public TextureResource(NativeImage texture, int width, int height) {
|
||||
this(texture, texture.getWidth() != width || texture.getHeight() != height ? Optional.of(new FrameSize(width, height)) : Optional.empty());
|
||||
}
|
||||
|
||||
public NativeImage getFirstFrame(boolean copy) {
|
||||
if (frameSize.isEmpty() && !copy) {
|
||||
return texture;
|
||||
}
|
||||
FrameSize size = sizeOfFrame();
|
||||
NativeImage firstFrame = new NativeImage(size.width(), size.height(), false);
|
||||
texture.copyRect(firstFrame, 0, 0, 0, 0, size.width(), size.height(), false, false);
|
||||
return firstFrame;
|
||||
}
|
||||
|
||||
public FrameSize sizeOfFrame() {
|
||||
return frameSize.orElseGet(() -> new FrameSize(texture.getWidth(), texture.getHeight()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
texture.close();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user