mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-02-13 08:14: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;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.PonyRenderManager;
|
||||
import com.minelittlepony.client.render.IPonyRender;
|
||||
import com.minelittlepony.client.transform.PonyTransformation;
|
||||
|
@ -11,8 +10,6 @@ import com.minelittlepony.pony.meta.Race;
|
|||
import com.minelittlepony.pony.meta.Size;
|
||||
import net.minecraft.block.Material;
|
||||
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.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
@ -20,31 +17,17 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.item.ArmorItem;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.resource.Resource;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Box;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
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
|
||||
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 IPonyData metadata;
|
||||
|
||||
|
@ -56,19 +39,7 @@ public class Pony implements IPony {
|
|||
}
|
||||
|
||||
Pony(Identifier resource) {
|
||||
texture = 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);
|
||||
}
|
||||
this(resource, PonyData.parse(resource));
|
||||
}
|
||||
|
||||
@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
|
||||
public boolean isPerformingRainboom(LivingEntity entity) {
|
||||
Vec3d motion = entity.getVelocity();
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
package com.minelittlepony.client.pony;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
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.gson.annotations.Expose;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.util.render.NativeUtil;
|
||||
import com.minelittlepony.pony.IPonyData;
|
||||
import com.minelittlepony.pony.meta.Gender;
|
||||
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.IInterpolator;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.concurrent.Immutable;
|
||||
|
||||
/**
|
||||
|
@ -25,7 +33,33 @@ import javax.annotation.concurrent.Immutable;
|
|||
@Immutable
|
||||
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
|
||||
private final Race race;
|
||||
|
@ -100,6 +134,11 @@ public class PonyData implements IPonyData {
|
|||
return wearables[wearable.ordinal()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public IInterpolator getInterpolator(UUID interpolatorId) {
|
||||
return BasicEasingInterpolator.getInstance(interpolatorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(this)
|
||||
|
@ -111,16 +150,4 @@ public class PonyData implements IPonyData {
|
|||
.add("glowColor", "#" + Integer.toHexString(glowColor))
|
||||
.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