mirror of
https://github.com/GTNewHorizons/Chisel.git
synced 2026-11-11 15:57:31 +00:00
review fixes
This commit is contained in:
1 parent
c1e8606629
commit
6eed99f030
10 files changed
+183
-37
No files matched your search
@@ -31,6 +31,7 @@ import team.chisel.ctmlib.ISubmapManager;
|
||||
import team.chisel.ctmlib.RenderBlocksCTM;
|
||||
import team.chisel.ctmlib.RenderBlocksColumn;
|
||||
import team.chisel.ctmlib.TextureSubmap;
|
||||
import team.chisel.ctmlib.TextureSubmapCTM;
|
||||
|
||||
/**
|
||||
* Handles all default {@link ISubmapManager} behavior
|
||||
@@ -197,8 +198,8 @@ public enum TextureType {
|
||||
IIcon baseIcon = register.registerIcon(modName + ":" + texturePath);
|
||||
return Triple.of(
|
||||
baseIcon,
|
||||
new TextureSubmap(register.registerIcon(modName + ":" + texturePath + "-ctm"), 4, 4),
|
||||
new TextureSubmap(baseIcon, 2, 2)
|
||||
new TextureSubmapCTM(register.registerIcon(modName + ":" + texturePath + "-ctm"), 4),
|
||||
new TextureSubmapCTM(baseIcon, 2)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ import team.chisel.ctmlib.TextureSubmapResource;
|
||||
/**
|
||||
* Provides generated resources for independently stitched CTM submap sprites.
|
||||
* <p>
|
||||
* For example, a request for chisel:textures/blocks/__chisel_submap/4x4/2_1/foo.png is resolved from
|
||||
* chisel:textures/blocks/foo.png and cropped to the requested cell. This lets Minecraft and other mods treat each
|
||||
* For example, a request for chisel:textures/blocks/__chisel_submap/2x2/1_0/foo.png is resolved from
|
||||
* chisel:textures/blocks/foo.png and cropped to its top-right tile. This lets Minecraft and other mods treat each
|
||||
* submap sprite like an ordinary texture resource.
|
||||
*/
|
||||
@Mixin(FallbackResourceManager.class)
|
||||
@@ -54,6 +54,7 @@ public abstract class MixinFallbackResourceManager {
|
||||
List<IResource> resources = new ArrayList<>(sources.size());
|
||||
|
||||
for (IResource source : sources) {
|
||||
// Different resource packs may provide different images for the same location, so we can't cache them
|
||||
resources.add(new TextureSubmapResource(source, submap, false));
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
import team.chisel.ctmlib.Drawing;
|
||||
import team.chisel.ctmlib.RenderBlocksCTM;
|
||||
import team.chisel.ctmlib.TextureSubmap;
|
||||
import team.chisel.ctmlib.TextureSubmapCTM;
|
||||
import team.chisel.init.ChiselBlocks;
|
||||
|
||||
public class SubmapManagerAntiblock extends SubmapManagerBase {
|
||||
@@ -93,8 +94,8 @@ public class SubmapManagerAntiblock extends SubmapManagerBase {
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerIcons(String modName, Block block, IIconRegister register) {
|
||||
submap = new TextureSubmap(register.registerIcon(modName + ":antiblock/" + color + "-antiBlock-ctm"), 4, 4);
|
||||
submapSmall = new TextureSubmap(register.registerIcon(modName + ":antiblock/" + color + "-antiBlock"), 2, 2);
|
||||
submap = new TextureSubmapCTM(register.registerIcon(modName + ":antiblock/" + color + "-antiBlock-ctm"), 4);
|
||||
submapSmall = new TextureSubmapCTM(register.registerIcon(modName + ":antiblock/" + color + "-antiBlock"), 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,6 +11,7 @@ import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import team.chisel.ctmlib.RenderBlocksCTM;
|
||||
import team.chisel.ctmlib.TextureSubmap;
|
||||
import team.chisel.ctmlib.TextureSubmapCTM;
|
||||
|
||||
public class SubmapManagerCarpetFloor extends SubmapManagerBase {
|
||||
|
||||
@@ -39,8 +40,8 @@ public class SubmapManagerCarpetFloor extends SubmapManagerBase {
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerIcons(String modName, Block block, IIconRegister register) {
|
||||
String path = modName + ":carpet/" + color;
|
||||
submap = new TextureSubmap(register.registerIcon(path + "-ctm"), 4, 4);
|
||||
submapSmall = new TextureSubmap(register.registerIcon(path), 2, 2);
|
||||
submap = new TextureSubmapCTM(register.registerIcon(path + "-ctm"), 4);
|
||||
submapSmall = new TextureSubmapCTM(register.registerIcon(path), 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,6 +13,7 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
import team.chisel.ctmlib.ISubmapManager;
|
||||
import team.chisel.ctmlib.RenderBlocksCTM;
|
||||
import team.chisel.ctmlib.TextureSubmap;
|
||||
import team.chisel.ctmlib.TextureSubmapCTM;
|
||||
|
||||
public class SubmapManagerSlab implements ISubmapManager {
|
||||
|
||||
@@ -42,8 +43,8 @@ public class SubmapManagerSlab implements ISubmapManager {
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerIcons(String modName, Block block, IIconRegister register) {
|
||||
String path = modName + ":" + texture;
|
||||
submap = new TextureSubmap(register.registerIcon(path + "-ctm"), 4, 4);
|
||||
submapSmall = new TextureSubmap(register.registerIcon(path), 2, 2);
|
||||
submap = new TextureSubmapCTM(register.registerIcon(path + "-ctm"), 4);
|
||||
submapSmall = new TextureSubmapCTM(register.registerIcon(path), 2);
|
||||
sideTexture = register.registerIcon(path + "-side");
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import team.chisel.ctmlib.RenderBlocksCTM;
|
||||
import team.chisel.ctmlib.TextureSubmap;
|
||||
import team.chisel.ctmlib.TextureSubmapCTM;
|
||||
|
||||
public class SubmapManagerSpecialMaterial extends SubmapManagerBase {
|
||||
|
||||
@@ -71,8 +72,8 @@ public class SubmapManagerSpecialMaterial extends SubmapManagerBase {
|
||||
public void registerIcons(String modName, Block block, IIconRegister register) {
|
||||
String materialName = materialType.name()
|
||||
.toLowerCase();
|
||||
submap = new TextureSubmap(register.registerIcon(modName + ":" + materialName + "/" + color + "-ctm"), 4, 4);
|
||||
submapSmall = new TextureSubmap(register.registerIcon(modName + ":" + materialName + "/" + color), 2, 2);
|
||||
submap = new TextureSubmapCTM(register.registerIcon(modName + ":" + materialName + "/" + color + "-ctm"), 4);
|
||||
submapSmall = new TextureSubmapCTM(register.registerIcon(modName + ":" + materialName + "/" + color), 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -48,8 +48,8 @@ public class SubmapManagerCTM implements ISubmapManager {
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void registerIcons(String modName, Block block, IIconRegister register) {
|
||||
submap = new TextureSubmap(register.registerIcon(modName + ":" + textureName + "-ctm"), 4, 4);
|
||||
submapSmall = new TextureSubmap(register.registerIcon(modName + ":" + textureName), 2, 2);
|
||||
submap = new TextureSubmapCTM(register.registerIcon(modName + ":" + textureName + "-ctm"), 4);
|
||||
submapSmall = new TextureSubmapCTM(register.registerIcon(modName + ":" + textureName), 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,7 +16,7 @@ import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import lombok.experimental.Delegate;
|
||||
|
||||
/**
|
||||
* Splits a texture sheet into independently stitched sub-icons used for CTM and other texture manipulation.
|
||||
* Represents a grid of individually accessible texture regions.
|
||||
*/
|
||||
public class TextureSubmap implements IIcon, ISubmap {
|
||||
|
||||
@@ -29,17 +29,11 @@ public class TextureSubmap implements IIcon, ISubmap {
|
||||
protected final IIcon[][] icons;
|
||||
|
||||
/**
|
||||
* Construct a new square submap.
|
||||
*
|
||||
* @param baseIcon The IIcon to submap.
|
||||
* @param width The width of the map, in icons.
|
||||
* @param height The height of the map, in icons. Must equal {@code width}.
|
||||
* @param height The height of the map, in icons.
|
||||
*/
|
||||
public TextureSubmap(IIcon baseIcon, int width, int height) {
|
||||
if (width != height) {
|
||||
throw new IllegalArgumentException("TextureSubmap must be square: " + width + "x" + height);
|
||||
}
|
||||
|
||||
this.baseIcon = baseIcon;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
@@ -47,9 +41,6 @@ public class TextureSubmap implements IIcon, ISubmap {
|
||||
submaps.add(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* The large "base" icon used for the submap.
|
||||
*/
|
||||
public IIcon getBaseIcon() {
|
||||
return baseIcon;
|
||||
}
|
||||
@@ -114,20 +105,138 @@ public class TextureSubmap implements IIcon, ISubmap {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the real sprites backing this submap.
|
||||
*/
|
||||
public void registerSubIcons(TextureMap textureMap) {
|
||||
registerSpriteGrid(textureMap, width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits the texture into a grid of atlas sprites and assigns sub-icons to them.
|
||||
* <p>
|
||||
* The number of sub-icons is determined by the submap's width and height,
|
||||
* while spriteColumns and spriteRows determine how many separate atlas sprites
|
||||
* are used. Each sprite can contain one or more sub-icons.
|
||||
* <p>
|
||||
* For example, a 4x4 submap backed by a 2x2 sprite grid uses four atlas sprites,
|
||||
* each containing a 2x2 group of sub-icons.
|
||||
*/
|
||||
protected final void registerSpriteGrid(TextureMap textureMap, int spriteColumns, int spriteRows) {
|
||||
if (baseIcon == null || width <= 0 || height <= 0) {
|
||||
return;
|
||||
}
|
||||
if (spriteColumns <= 0 || spriteRows <= 0 || width % spriteColumns != 0 || height % spriteRows != 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Logical submap " + width
|
||||
+ "x"
|
||||
+ height
|
||||
+ " cannot be backed by sprite grid "
|
||||
+ spriteColumns
|
||||
+ "x"
|
||||
+ spriteRows);
|
||||
}
|
||||
|
||||
ResourceLocation sourceLocation = new ResourceLocation(baseIcon.getIconName());
|
||||
IIcon[][] sprites = new IIcon[spriteColumns][spriteRows];
|
||||
|
||||
for (int spriteX = 0; spriteX < spriteColumns; spriteX++) {
|
||||
for (int spriteY = 0; spriteY < spriteRows; spriteY++) {
|
||||
sprites[spriteX][spriteY] = getBackingSprite(
|
||||
textureMap,
|
||||
sourceLocation,
|
||||
spriteColumns,
|
||||
spriteRows,
|
||||
spriteX,
|
||||
spriteY);
|
||||
}
|
||||
}
|
||||
|
||||
int cellsPerSpriteX = width / spriteColumns;
|
||||
int cellsPerSpriteY = height / spriteRows;
|
||||
boolean wholeSprite = cellsPerSpriteX == 1 && cellsPerSpriteY == 1;
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
String name = TextureSubmapResource.getSubIconName(sourceLocation, width, height, x, y);
|
||||
icons[x][y] = textureMap.registerIcon(name);
|
||||
IIcon sprite = sprites[x / cellsPerSpriteX][y / cellsPerSpriteY];
|
||||
icons[x][y] = wholeSprite ? sprite
|
||||
: new TextureRegion(
|
||||
sprite,
|
||||
cellsPerSpriteX,
|
||||
cellsPerSpriteY,
|
||||
x % cellsPerSpriteX,
|
||||
y % cellsPerSpriteY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IIcon getBackingSprite(TextureMap textureMap, ResourceLocation sourceLocation, int columns, int rows, int x,
|
||||
int y) {
|
||||
|
||||
if (columns == 1 && rows == 1) {
|
||||
return baseIcon;
|
||||
}
|
||||
|
||||
String name = TextureSubmapResource.getSubIconName(sourceLocation, columns, rows, x, y);
|
||||
return textureMap.registerIcon(name);
|
||||
}
|
||||
|
||||
private static final class TextureRegion implements IIcon {
|
||||
|
||||
private final IIcon parent;
|
||||
private final int columns;
|
||||
private final int rows;
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
private TextureRegion(IIcon parent, int columns, int rows, int x, int y) {
|
||||
this.parent = parent;
|
||||
this.columns = columns;
|
||||
this.rows = rows;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMinU() {
|
||||
return getInterpolatedU(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMaxU() {
|
||||
return getInterpolatedU(16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getInterpolatedU(double u) {
|
||||
return parent.getInterpolatedU((16.0 * x + u) / columns);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMinV() {
|
||||
return getInterpolatedV(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getMaxV() {
|
||||
return getInterpolatedV(16);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getInterpolatedV(double v) {
|
||||
return parent.getInterpolatedV((16.0 * y + v) / rows);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIconName() {
|
||||
return parent.getIconName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return parent.getIconWidth() / columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return parent.getIconHeight() / rows;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package team.chisel.ctmlib;
|
||||
|
||||
import net.minecraft.client.renderer.texture.TextureMap;
|
||||
import net.minecraft.util.IIcon;
|
||||
|
||||
/**
|
||||
* A CTM submap that keeps each tile in one atlas sprite while exposing its four quadrants as sub-icons.
|
||||
*/
|
||||
public final class TextureSubmapCTM extends TextureSubmap {
|
||||
|
||||
/**
|
||||
* @param baseIcon The registered texture sheet.
|
||||
* @param size The number of logical quadrants per axis: 4 for the CTM sheet, 2 for the normal texture.
|
||||
*/
|
||||
public TextureSubmapCTM(IIcon baseIcon, int size) {
|
||||
super(baseIcon, size, size);
|
||||
|
||||
if (size <= 0 || (size & 1) != 0) {
|
||||
throw new IllegalArgumentException("CTM submap size must be a positive even number: " + size);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSubIcons(TextureMap textureMap) {
|
||||
registerSpriteGrid(textureMap, getWidth() / 2, getHeight() / 2);
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,9 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.imageio.IIOImage;
|
||||
@@ -35,7 +35,7 @@ public final class TextureSubmapResource implements IResource {
|
||||
private record SubmapCacheKey(ResourceLocation source, int columns, int rows) {}
|
||||
|
||||
@Nullable
|
||||
private static HashMap<SubmapCacheKey, byte[][]> imageCache;
|
||||
private static volatile ConcurrentHashMap<SubmapCacheKey, byte[][]> imageCache;
|
||||
|
||||
private static final String PREFIX = "__chisel_submap/";
|
||||
|
||||
@@ -103,7 +103,7 @@ public final class TextureSubmapResource implements IResource {
|
||||
}
|
||||
|
||||
public static void beginTextureStitch() {
|
||||
imageCache = new HashMap<>();
|
||||
imageCache = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
public static void endTextureStitch() {
|
||||
@@ -124,15 +124,19 @@ public final class TextureSubmapResource implements IResource {
|
||||
}
|
||||
|
||||
private byte[] getCachedImageData(IResource resource, SubmapLocation submap) throws IOException {
|
||||
if (!cacheable || imageCache == null) {
|
||||
ConcurrentHashMap<SubmapCacheKey, byte[][]> cache = imageCache;
|
||||
if (!cacheable || cache == null) {
|
||||
return generateCell(resource, submap);
|
||||
}
|
||||
|
||||
SubmapCacheKey key = new SubmapCacheKey(submap.source(), submap.columns(), submap.rows());
|
||||
byte[][] cells = imageCache.get(key);
|
||||
byte[][] cells = cache.get(key);
|
||||
if (cells == null) {
|
||||
cells = generateSubmap(resource, submap);
|
||||
imageCache.put(key, cells);
|
||||
byte[][] existing = cache.putIfAbsent(key, cells);
|
||||
if (existing != null) {
|
||||
cells = existing;
|
||||
}
|
||||
}
|
||||
|
||||
return cells[submap.cellX() * submap.rows() + submap.cellY()];
|
||||
@@ -176,7 +180,7 @@ public final class TextureSubmapResource implements IResource {
|
||||
|
||||
ImageWriteParam param = writer.getDefaultWriteParam();
|
||||
if (param.canWriteCompressed()) {
|
||||
// disable compression so we don't spend time on compressing and decompressing to just get the image bytes
|
||||
// Disable compression to avoid wasting time compressing images that will immediately be decoded again
|
||||
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||
param.setCompressionQuality(1.0f);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user