mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-02-13 16:24:23 +01:00
Move everything related to PonyData parsing into the PonyData class
This commit is contained in:
parent
a7664bbe71
commit
0dab332a0e
3 changed files with 98 additions and 118 deletions
|
@ -1,7 +1,6 @@
|
||||||
package com.minelittlepony.client.pony;
|
package com.minelittlepony.client.pony;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.minelittlepony.client.MineLittlePony;
|
|
||||||
import com.minelittlepony.client.PonyRenderManager;
|
import com.minelittlepony.client.PonyRenderManager;
|
||||||
import com.minelittlepony.client.render.IPonyRender;
|
import com.minelittlepony.client.render.IPonyRender;
|
||||||
import com.minelittlepony.client.transform.PonyTransformation;
|
import com.minelittlepony.client.transform.PonyTransformation;
|
||||||
|
@ -11,8 +10,6 @@ import com.minelittlepony.pony.meta.Race;
|
||||||
import com.minelittlepony.pony.meta.Size;
|
import com.minelittlepony.pony.meta.Size;
|
||||||
import net.minecraft.block.Material;
|
import net.minecraft.block.Material;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.texture.NativeImage;
|
|
||||||
import net.minecraft.client.texture.TextureManager;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EquipmentSlot;
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
@ -20,31 +17,17 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||||
import net.minecraft.item.ArmorItem;
|
import net.minecraft.item.ArmorItem;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.resource.Resource;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.Box;
|
import net.minecraft.util.math.Box;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
import static com.mojang.blaze3d.platform.GlStateManager.getTexLevelParameter;
|
|
||||||
import static org.lwjgl.opengl.GL11.*;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
public class Pony implements IPony {
|
public class Pony implements IPony {
|
||||||
|
|
||||||
private static final AtomicInteger ponyCount = new AtomicInteger();
|
|
||||||
|
|
||||||
private static final NativeImage.Format[] formats = NativeImage.Format.values();
|
|
||||||
|
|
||||||
private final int ponyId = ponyCount.getAndIncrement();
|
|
||||||
|
|
||||||
private final Identifier texture;
|
private final Identifier texture;
|
||||||
private final IPonyData metadata;
|
private final IPonyData metadata;
|
||||||
|
|
||||||
|
@ -56,19 +39,7 @@ public class Pony implements IPony {
|
||||||
}
|
}
|
||||||
|
|
||||||
Pony(Identifier resource) {
|
Pony(Identifier resource) {
|
||||||
texture = resource;
|
this(resource, PonyData.parse(resource));
|
||||||
metadata = checkSkin(texture);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IPonyData checkSkin(Identifier resource) {
|
|
||||||
IPonyData data = checkPonyMeta(resource);
|
|
||||||
if (data != null) {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
try (NativeImage ponyTexture = getBufferedImage(resource)) {
|
|
||||||
return checkSkin(ponyTexture);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -79,81 +50,6 @@ public class Pony implements IPony {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private IPonyData checkPonyMeta(Identifier resource) {
|
|
||||||
try {
|
|
||||||
Resource res = MinecraftClient.getInstance().getResourceManager().getResource(resource);
|
|
||||||
|
|
||||||
PonyData data = res.getMetadata(PonyData.SERIALISER);
|
|
||||||
|
|
||||||
if (data != null) {
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
// Ignore uploaded texture
|
|
||||||
} catch (IOException e) {
|
|
||||||
MineLittlePony.logger.warn("Unable to read {} metadata", resource, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static NativeImage.Format getFormat(int glFormat) {
|
|
||||||
for (NativeImage.Format i : formats) {
|
|
||||||
if (i.getPixelDataFormat() == glFormat) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new RuntimeException("Unsupported image format");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static NativeImage getBufferedImage(@Nullable Identifier resource) {
|
|
||||||
if (resource == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
MinecraftClient mc = MinecraftClient.getInstance();
|
|
||||||
TextureManager textures = mc.getTextureManager();
|
|
||||||
|
|
||||||
if (!mc.isOnThread()) {
|
|
||||||
throw new RuntimeException("This can only be called from the main thread.");
|
|
||||||
}
|
|
||||||
// recreate NativeImage from the GL matrix
|
|
||||||
textures.bindTexture(resource);
|
|
||||||
|
|
||||||
int format = getTexLevelParameter(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT);
|
|
||||||
int width = getTexLevelParameter(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH);
|
|
||||||
int height = getTexLevelParameter(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT);
|
|
||||||
|
|
||||||
if (width * height == 0) {
|
|
||||||
throw new IllegalStateException("GL texture not uploaded yet");
|
|
||||||
}
|
|
||||||
|
|
||||||
NativeImage.Format channels = getFormat(format);
|
|
||||||
|
|
||||||
NativeImage image = new NativeImage(channels, width, height, false);
|
|
||||||
|
|
||||||
// This allocates a new array to store the image every time.
|
|
||||||
// Don't do this every time. Keep a cache and store it so we don't destroy memory.
|
|
||||||
try {
|
|
||||||
image.loadFromTextureImage(0, false);
|
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
image.close();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IPonyData checkSkin(@Nullable NativeImage bufferedimage) {
|
|
||||||
if (bufferedimage == null) {
|
|
||||||
return new PonyData();
|
|
||||||
}
|
|
||||||
MineLittlePony.logger.debug("\tStart skin check for pony #{} with image {}.", ponyId, bufferedimage);
|
|
||||||
return PonyData.parse(bufferedimage);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPerformingRainboom(LivingEntity entity) {
|
public boolean isPerformingRainboom(LivingEntity entity) {
|
||||||
Vec3d motion = entity.getVelocity();
|
Vec3d motion = entity.getVelocity();
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
package com.minelittlepony.client.pony;
|
package com.minelittlepony.client.pony;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.texture.NativeImage;
|
import net.minecraft.client.texture.NativeImage;
|
||||||
|
import net.minecraft.resource.Resource;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
import com.google.common.base.MoreObjects;
|
import com.google.common.base.MoreObjects;
|
||||||
import com.google.gson.annotations.Expose;
|
import com.google.gson.annotations.Expose;
|
||||||
|
import com.minelittlepony.client.MineLittlePony;
|
||||||
|
import com.minelittlepony.client.util.render.NativeUtil;
|
||||||
import com.minelittlepony.pony.IPonyData;
|
import com.minelittlepony.pony.IPonyData;
|
||||||
import com.minelittlepony.pony.meta.Gender;
|
import com.minelittlepony.pony.meta.Gender;
|
||||||
import com.minelittlepony.pony.meta.Race;
|
import com.minelittlepony.pony.meta.Race;
|
||||||
|
@ -14,8 +19,11 @@ import com.minelittlepony.pony.meta.Wearable;
|
||||||
import com.minelittlepony.util.animation.BasicEasingInterpolator;
|
import com.minelittlepony.util.animation.BasicEasingInterpolator;
|
||||||
import com.minelittlepony.util.animation.IInterpolator;
|
import com.minelittlepony.util.animation.IInterpolator;
|
||||||
|
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +33,33 @@ import javax.annotation.concurrent.Immutable;
|
||||||
@Immutable
|
@Immutable
|
||||||
public class PonyData implements IPonyData {
|
public class PonyData implements IPonyData {
|
||||||
|
|
||||||
public static final PonyDataSerialiser SERIALISER = new PonyDataSerialiser();
|
private static final PonyDataSerialiser SERIALISER = new PonyDataSerialiser();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given resource into a new IPonyData.
|
||||||
|
* This may either come from an attached json file or the image itself.
|
||||||
|
*/
|
||||||
|
public static IPonyData parse(@Nullable Identifier identifier) {
|
||||||
|
if (identifier == null) {
|
||||||
|
return new PonyData();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Resource res = MinecraftClient.getInstance().getResourceManager().getResource(identifier);
|
||||||
|
|
||||||
|
PonyData data = res.getMetadata(SERIALISER);
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
// Ignore uploaded texture
|
||||||
|
} catch (IOException e) {
|
||||||
|
MineLittlePony.logger.warn("Unable to read {} metadata", identifier, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NativeUtil.parseImage(identifier, PonyData::new);
|
||||||
|
}
|
||||||
|
|
||||||
@Expose
|
@Expose
|
||||||
private final Race race;
|
private final Race race;
|
||||||
|
@ -100,6 +134,11 @@ public class PonyData implements IPonyData {
|
||||||
return wearables[wearable.ordinal()];
|
return wearables[wearable.ordinal()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IInterpolator getInterpolator(UUID interpolatorId) {
|
||||||
|
return BasicEasingInterpolator.getInstance(interpolatorId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return MoreObjects.toStringHelper(this)
|
return MoreObjects.toStringHelper(this)
|
||||||
|
@ -111,16 +150,4 @@ public class PonyData implements IPonyData {
|
||||||
.add("glowColor", "#" + Integer.toHexString(glowColor))
|
.add("glowColor", "#" + Integer.toHexString(glowColor))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public IInterpolator getInterpolator(UUID interpolatorId) {
|
|
||||||
return BasicEasingInterpolator.getInstance(interpolatorId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses an image buffer into a new IPonyData representing the values stored in it's individual trigger pixels.
|
|
||||||
*/
|
|
||||||
public static IPonyData parse(NativeImage image) {
|
|
||||||
return new PonyData(image);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.minelittlepony.client.util.render;
|
||||||
|
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.texture.NativeImage;
|
||||||
|
import net.minecraft.client.texture.TextureManager;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static com.mojang.blaze3d.platform.GlStateManager.getTexLevelParameter;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_HEIGHT;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_INTERNAL_FORMAT;
|
||||||
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WIDTH;
|
||||||
|
|
||||||
|
public class NativeUtil {
|
||||||
|
private static final NativeImage.Format[] formats = NativeImage.Format.values();
|
||||||
|
|
||||||
|
public static NativeImage.Format getFormat(int glFormat) {
|
||||||
|
for (NativeImage.Format i : formats) {
|
||||||
|
if (i.getPixelDataFormat() == glFormat) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new RuntimeException("Unsupported image format");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T parseImage(Identifier resource, Function<NativeImage, T> consumer) {
|
||||||
|
MinecraftClient mc = MinecraftClient.getInstance();
|
||||||
|
TextureManager textures = mc.getTextureManager();
|
||||||
|
|
||||||
|
if (!mc.isOnThread()) {
|
||||||
|
throw new IllegalStateException("This can only be called from the main thread.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// recreate NativeImage from the GL matrix
|
||||||
|
textures.bindTexture(resource);
|
||||||
|
|
||||||
|
int format = getTexLevelParameter(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT);
|
||||||
|
int width = getTexLevelParameter(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH);
|
||||||
|
int height = getTexLevelParameter(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT);
|
||||||
|
|
||||||
|
if (width * height == 0) {
|
||||||
|
throw new IllegalStateException("GL texture not uploaded yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
try (NativeImage image = new NativeImage(getFormat(format), width, height, false)) {
|
||||||
|
// This allocates a new array to store the image every time.
|
||||||
|
// Don't do this every time. Keep a cache and store it so we don't destroy memory.
|
||||||
|
image.loadFromTextureImage(0, false);
|
||||||
|
|
||||||
|
return consumer.apply(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue