A few more binary-breaking changes, before it's too late:
- Move CompositeModel out of its package. - Move a few inner classes from the OBJ loader. - Rename the bucket model and fluid model classes to match the naming convention. - Remove BiomeEvent.* and WorldTypeEvent.InitBiomeGens as they are not currently implemented and they haven't been in the previous version either.
This commit is contained in:
parent
4b9920bcb3
commit
b6c12f5fff
12 changed files with 184 additions and 555 deletions
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.client.model.composite;
|
||||
package net.minecraftforge.client.model;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
|
@ -31,8 +31,8 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|||
import net.minecraft.resources.IResourceManager;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.*;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
import net.minecraftforge.client.model.geometry.IModelGeometryPart;
|
||||
|
@ -43,7 +43,7 @@ import javax.annotation.Nullable;
|
|||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class CompositeModel implements IBakedModel
|
||||
public class CompositeModel implements IDynamicBakedModel
|
||||
{
|
||||
public static final ModelProperty<SubmodelModelData> SUBMODEL_DATA = new ModelProperty<>();
|
||||
|
||||
|
@ -77,18 +77,6 @@ public class CompositeModel implements IBakedModel
|
|||
return quads;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand)
|
||||
{
|
||||
List<BakedQuad> quads = new ArrayList<>();
|
||||
for(IBakedModel part : bakedParts.values())
|
||||
{
|
||||
quads.addAll(part.getQuads(state, side, rand, EmptyModelData.INSTANCE));
|
||||
}
|
||||
return quads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
|
@ -26,21 +26,17 @@ import com.google.common.collect.Sets;
|
|||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.Quaternion;
|
||||
import net.minecraft.client.renderer.TransformationMatrix;
|
||||
import net.minecraft.client.renderer.model.*;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
|
||||
import net.minecraft.client.renderer.texture.MissingTextureSprite;
|
||||
import net.minecraft.client.renderer.texture.PngSizeInfo;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.fluid.Fluid;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.resources.IResource;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
@ -57,14 +53,13 @@ import org.apache.logging.log4j.Logger;
|
|||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public final class ModelDynBucket implements IModelGeometry<ModelDynBucket>
|
||||
public final class DynamicBucketModel implements IModelGeometry<DynamicBucketModel>
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final ModelResourceLocation LOCATION = new ModelResourceLocation(new ResourceLocation(ForgeVersion.MOD_ID, "dynbucket"), "inventory");
|
||||
|
@ -82,7 +77,7 @@ public final class ModelDynBucket implements IModelGeometry<ModelDynBucket>
|
|||
private final boolean tint;
|
||||
private final boolean coverIsMask;
|
||||
|
||||
public ModelDynBucket(Fluid fluid, boolean flipGas, boolean tint, boolean coverIsMask)
|
||||
public DynamicBucketModel(Fluid fluid, boolean flipGas, boolean tint, boolean coverIsMask)
|
||||
{
|
||||
this.fluid = fluid;
|
||||
this.flipGas = flipGas;
|
||||
|
@ -94,35 +89,9 @@ public final class ModelDynBucket implements IModelGeometry<ModelDynBucket>
|
|||
* Returns a new ModelDynBucket representing the given fluid, but with the same
|
||||
* other properties (flipGas, tint, coverIsMask).
|
||||
*/
|
||||
public ModelDynBucket withFluid(Fluid newFluid)
|
||||
public DynamicBucketModel withFluid(Fluid newFluid)
|
||||
{
|
||||
return new ModelDynBucket(newFluid, flipGas, tint, coverIsMask);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static IResource getResource(ResourceLocation resourceLocation)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Minecraft.getInstance().getResourceManager().getResource(resourceLocation);
|
||||
}
|
||||
catch (IOException ignored)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static PngSizeInfo getSizeInfo(IResource resource)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new PngSizeInfo(resource.toString(), resource.getInputStream());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new DynamicBucketModel(newFluid, flipGas, tint, coverIsMask);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -216,7 +185,7 @@ public final class ModelDynBucket implements IModelGeometry<ModelDynBucket>
|
|||
}
|
||||
}
|
||||
|
||||
return new BakedDynBucket(bakery, owner, this, builder.build(), particleSprite, DefaultVertexFormats.BLOCK, Maps.immutableEnumMap(transformMap), Maps.newHashMap(), transform.isIdentity(), modelTransform);
|
||||
return new BakedModel(bakery, owner, this, builder.build(), particleSprite, Maps.immutableEnumMap(transformMap), Maps.newHashMap(), transform.isIdentity(), modelTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -232,7 +201,7 @@ public final class ModelDynBucket implements IModelGeometry<ModelDynBucket>
|
|||
return texs;
|
||||
}
|
||||
|
||||
public enum LoaderDynBucket2 implements IModelLoader<ModelDynBucket>
|
||||
public enum Loader implements IModelLoader<DynamicBucketModel>
|
||||
{
|
||||
INSTANCE;
|
||||
|
||||
|
@ -255,7 +224,7 @@ public final class ModelDynBucket implements IModelGeometry<ModelDynBucket>
|
|||
}
|
||||
|
||||
@Override
|
||||
public ModelDynBucket read(JsonDeserializationContext deserializationContext, JsonObject modelContents)
|
||||
public DynamicBucketModel read(JsonDeserializationContext deserializationContext, JsonObject modelContents)
|
||||
{
|
||||
if (!modelContents.has("fluid"))
|
||||
throw new RuntimeException("Bucket model requires 'fluid' value.");
|
||||
|
@ -283,122 +252,15 @@ public final class ModelDynBucket implements IModelGeometry<ModelDynBucket>
|
|||
}
|
||||
|
||||
// create new model with correct liquid
|
||||
return new ModelDynBucket(fluid, flip, tint, coverIsMask);
|
||||
return new DynamicBucketModel(fluid, flip, tint, coverIsMask);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO Custom TAS
|
||||
private static final class BucketBaseSprite extends TextureAtlasSprite
|
||||
{
|
||||
private final ResourceLocation bucket = new ResourceLocation("item/bucket");
|
||||
private final ImmutableList<ResourceLocation> dependencies = ImmutableList.of(bucket);
|
||||
|
||||
private BucketBaseSprite(ResourceLocation res)
|
||||
{
|
||||
super(res, getSizeInfo(getResource(new ResourceLocation("textures/item/bucket.png"))), getResource(new ResourceLocation("textures/item/bucket.png")).getMetadata(AnimationMetadataSection.SERIALIZER));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomLoader(@Nonnull IResourceManager manager, @Nonnull ResourceLocation location)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies()
|
||||
{
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load(@Nonnull IResourceManager manager, @Nonnull ResourceLocation location, @Nonnull Function<ResourceLocation, TextureAtlasSprite> textureGetter)
|
||||
{
|
||||
final TextureAtlasSprite sprite = textureGetter.apply(bucket);
|
||||
// TODO custom sprites are gonna be a PITA, these are final
|
||||
width = sprite.getIconWidth();
|
||||
height = sprite.getIconHeight();
|
||||
// TODO No easy way to dump pixels of one sprite into another without n^2 for loop, investigate patch?
|
||||
final int[][] pixels = sprite.getFrameTextureData(0);
|
||||
this.clearFramesTextureData();
|
||||
this.framesTextureData.add(pixels);
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* Creates a bucket cover sprite from the vanilla resource.
|
||||
*/
|
||||
/* TODO Custom TAS
|
||||
private static final class BucketCoverSprite extends TextureAtlasSprite
|
||||
{
|
||||
private final ResourceLocation bucket = new ResourceLocation("item/bucket");
|
||||
private final ResourceLocation bucketCoverMask = new ResourceLocation(ForgeVersion.MOD_ID, "item/vanilla_bucket_cover_mask");
|
||||
private final ImmutableList<ResourceLocation> dependencies = ImmutableList.of(bucket, bucketCoverMask);
|
||||
|
||||
private BucketCoverSprite(ResourceLocation res)
|
||||
{
|
||||
super(res, getSizeInfo(getResource(new ResourceLocation("textures/item/bucket.png"))), getResource(new ResourceLocation("textures/item/bucket.png")).getMetadata(AnimationMetadataSection.SERIALIZER));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomLoader(@Nonnull IResourceManager manager, @Nonnull ResourceLocation location)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies()
|
||||
{
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean load(@Nonnull IResourceManager manager, @Nonnull ResourceLocation location, @Nonnull Function<ResourceLocation, TextureAtlasSprite> textureGetter)
|
||||
{
|
||||
final TextureAtlasSprite sprite = textureGetter.apply(bucket);
|
||||
final TextureAtlasSprite alphaMask = textureGetter.apply(bucketCoverMask);
|
||||
width = sprite.getIconWidth();
|
||||
height = sprite.getIconHeight();
|
||||
final int[][] pixels = new int[Minecraft.getMinecraft().gameSettings.mipmapLevels + 1][];
|
||||
pixels[0] = new int[width * height];
|
||||
|
||||
try (
|
||||
IResource empty = getResource(new ResourceLocation("textures/items/bucket_empty.png"));
|
||||
IResource mask = getResource(new ResourceLocation(ForgeVersion.MOD_ID, "textures/items/vanilla_bucket_cover_mask.png"))
|
||||
) {
|
||||
// use the alpha mask if it fits, otherwise leave the cover texture blank
|
||||
if (empty != null && mask != null && Objects.equals(empty.getPackName(), mask.getPackName()) &&
|
||||
alphaMask.getIconWidth() == width && alphaMask.getIconHeight() == height)
|
||||
{
|
||||
final int[][] oldPixels = sprite.getFrameTextureData(0);
|
||||
final int[][] alphaPixels = alphaMask.getFrameTextureData(0);
|
||||
|
||||
for (int p = 0; p < width * height; p++)
|
||||
{
|
||||
final int alphaMultiplier = alphaPixels[0][p] >>> 24;
|
||||
final int oldPixel = oldPixels[0][p];
|
||||
final int oldPixelAlpha = oldPixel >>> 24;
|
||||
final int newAlpha = oldPixelAlpha * alphaMultiplier / 0xFF;
|
||||
pixels[0][p] = (oldPixel & 0xFFFFFF) + (newAlpha << 24);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
LOGGER.error("Failed to close resource", e);
|
||||
}
|
||||
|
||||
this.clearFramesTextureData();
|
||||
this.framesTextureData.add(pixels);
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
private static final class BakedDynBucketOverrideHandler extends ItemOverrideList
|
||||
private static final class ContainedFluidOverrideHandler extends ItemOverrideList
|
||||
{
|
||||
private final ModelBakery bakery;
|
||||
|
||||
private BakedDynBucketOverrideHandler(ModelBakery bakery)
|
||||
private ContainedFluidOverrideHandler(ModelBakery bakery)
|
||||
{
|
||||
this.bakery = bakery;
|
||||
}
|
||||
|
@ -408,14 +270,14 @@ public final class ModelDynBucket implements IModelGeometry<ModelDynBucket>
|
|||
{
|
||||
return FluidUtil.getFluidContained(stack)
|
||||
.map(fluidStack -> {
|
||||
BakedDynBucket model = (BakedDynBucket)originalModel;
|
||||
BakedModel model = (BakedModel)originalModel;
|
||||
|
||||
Fluid fluid = fluidStack.getFluid();
|
||||
String name = fluid.getRegistryName().toString();
|
||||
|
||||
if (!model.cache.containsKey(name))
|
||||
{
|
||||
ModelDynBucket parent = model.parent.withFluid(fluid);
|
||||
DynamicBucketModel parent = model.parent.withFluid(fluid);
|
||||
IBakedModel bakedModel = parent.bake(model.owner, bakery, ModelLoader.defaultTextureGetter(), model.originalTransform, model.getOverrides(), new ResourceLocation("forge:bucket_override"));
|
||||
model.cache.put(name, bakedModel);
|
||||
return bakedModel;
|
||||
|
@ -429,27 +291,24 @@ public final class ModelDynBucket implements IModelGeometry<ModelDynBucket>
|
|||
}
|
||||
|
||||
// the dynamic bucket is based on the empty bucket
|
||||
private static final class BakedDynBucket extends BakedItemModel
|
||||
private static final class BakedModel extends BakedItemModel
|
||||
{
|
||||
private final IModelConfiguration owner;
|
||||
private final ModelDynBucket parent;
|
||||
private final DynamicBucketModel parent;
|
||||
private final Map<String, IBakedModel> cache; // contains all the baked models since they'll never change
|
||||
private final VertexFormat format;
|
||||
private final IModelTransform originalTransform;
|
||||
|
||||
BakedDynBucket(ModelBakery bakery,
|
||||
IModelConfiguration owner, ModelDynBucket parent,
|
||||
BakedModel(ModelBakery bakery,
|
||||
IModelConfiguration owner, DynamicBucketModel parent,
|
||||
ImmutableList<BakedQuad> quads,
|
||||
TextureAtlasSprite particle,
|
||||
VertexFormat format,
|
||||
ImmutableMap<TransformType, TransformationMatrix> transforms,
|
||||
Map<String, IBakedModel> cache,
|
||||
boolean untransformed,
|
||||
IModelTransform originalTransform)
|
||||
{
|
||||
super(quads, particle, transforms, new BakedDynBucketOverrideHandler(bakery), untransformed);
|
||||
super(quads, particle, transforms, new ContainedFluidOverrideHandler(bakery), untransformed);
|
||||
this.owner = owner;
|
||||
this.format = format;
|
||||
this.parent = parent;
|
||||
this.cache = cache;
|
||||
this.originalTransform = originalTransform;
|
|
@ -57,18 +57,17 @@ import com.google.common.cache.CacheLoader;
|
|||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
public final class ModelFluid implements IModelGeometry<ModelFluid>
|
||||
public final class FluidModel implements IModelGeometry<FluidModel>
|
||||
{
|
||||
public static final ModelFluid WATER = new ModelFluid(Fluids.WATER);
|
||||
public static final ModelFluid LAVA = new ModelFluid(Fluids.LAVA);
|
||||
public static final FluidModel WATER = new FluidModel(Fluids.WATER);
|
||||
public static final FluidModel LAVA = new FluidModel(Fluids.LAVA);
|
||||
|
||||
private final Fluid fluid;
|
||||
|
||||
public ModelFluid(Fluid fluid)
|
||||
public FluidModel(Fluid fluid)
|
||||
{
|
||||
this.fluid = fluid;
|
||||
}
|
||||
|
@ -477,20 +476,4 @@ public final class ModelFluid implements IModelGeometry<ModelFluid>
|
|||
return PerspectiveMapWrapper.handlePerspective(this, transforms, type, mat);
|
||||
}
|
||||
}
|
||||
|
||||
public ModelFluid process(ImmutableMap<String, String> customData)
|
||||
{
|
||||
if(!customData.containsKey("fluid")) return this;
|
||||
|
||||
String fluidStr = customData.get("fluid");
|
||||
JsonElement e = new JsonParser().parse(fluidStr);
|
||||
String fluid = e.getAsString();/* TODO fluids
|
||||
if(!FluidRegistry.isFluidRegistered(fluid))
|
||||
{
|
||||
LOGGER.fatal("fluid '{}' not found", fluid);
|
||||
return WATER;
|
||||
}
|
||||
return new ModelFluid(FluidRegistry.getFluid(fluid));*/
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -36,7 +36,6 @@ import net.minecraft.resources.IResourceManager;
|
|||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.JSONUtils;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.composite.CompositeModel;
|
||||
import net.minecraftforge.client.model.geometry.IModelGeometry;
|
||||
import net.minecraftforge.client.model.geometry.ISimpleModelGeometry;
|
||||
import net.minecraftforge.client.model.obj.OBJLoader;
|
||||
|
@ -60,7 +59,7 @@ public class ModelLoaderRegistry
|
|||
public static void init()
|
||||
{
|
||||
registerLoader(new ResourceLocation("forge:obj"), OBJLoader.INSTANCE);
|
||||
registerLoader(new ResourceLocation("forge:bucket"), ModelDynBucket.LoaderDynBucket2.INSTANCE);
|
||||
registerLoader(new ResourceLocation("forge:bucket"), DynamicBucketModel.Loader.INSTANCE);
|
||||
registerLoader(new ResourceLocation("forge:composite"), CompositeModel.Loader.INSTANCE);
|
||||
registerLoader(new ResourceLocation("minecraft:elements"), VanillaProxy.Loader.INSTANCE);
|
||||
registerLoader(new ResourceLocation("forge:multi-layer"), MultiLayerModel.Loader.INSTANCE);
|
||||
|
|
|
@ -33,13 +33,14 @@ import net.minecraft.entity.LivingEntity;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.common.model.TransformationHelper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class PerspectiveMapWrapper implements IBakedModel
|
||||
public class PerspectiveMapWrapper implements IDynamicBakedModel
|
||||
{
|
||||
private final IBakedModel parent;
|
||||
private final ImmutableMap<ItemCameraTransforms.TransformType, TransformationMatrix> transforms;
|
||||
|
@ -130,7 +131,6 @@ public class PerspectiveMapWrapper implements IBakedModel
|
|||
@Override public TextureAtlasSprite getParticleTexture() { return parent.getParticleTexture(); }
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override public ItemCameraTransforms getItemCameraTransforms() { return parent.getItemCameraTransforms(); }
|
||||
@Override public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand) { return parent.getQuads(state, side, rand); }
|
||||
@Override public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, Random rand, IModelData extraData)
|
||||
{
|
||||
return parent.getQuads(state, side, rand, extraData);
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
package net.minecraftforge.client.model.composite;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.client.model.obj;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import joptsimple.internal.Strings;
|
||||
import net.minecraft.resources.IResource;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class LineReader implements AutoCloseable
|
||||
{
|
||||
InputStreamReader lineStream;
|
||||
BufferedReader lineReader;
|
||||
|
||||
public LineReader(IResource resource)
|
||||
{
|
||||
this.lineStream = new InputStreamReader(resource.getInputStream(), Charsets.UTF_8);
|
||||
this.lineReader = new BufferedReader(lineStream);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String[] readAndSplitLine(boolean ignoreEmptyLines) throws IOException
|
||||
{
|
||||
//noinspection LoopConditionNotUpdatedInsideLoop
|
||||
do
|
||||
{
|
||||
String currentLine = lineReader.readLine();
|
||||
if (currentLine == null)
|
||||
return null;
|
||||
|
||||
List<String> lineParts = new ArrayList<>();
|
||||
|
||||
if (currentLine.startsWith("#"))
|
||||
currentLine = "";
|
||||
|
||||
if (currentLine.length() > 0)
|
||||
{
|
||||
|
||||
boolean hasContinuation;
|
||||
do
|
||||
{
|
||||
hasContinuation = currentLine.endsWith("\\");
|
||||
String tmp = hasContinuation ? currentLine.substring(0, currentLine.length() - 1) : currentLine;
|
||||
|
||||
Arrays.stream(tmp.split("[\t ]+")).filter(s -> !Strings.isNullOrEmpty(s)).forEach(lineParts::add);
|
||||
|
||||
if (hasContinuation)
|
||||
{
|
||||
currentLine = lineReader.readLine();
|
||||
if (currentLine == null)
|
||||
break;
|
||||
|
||||
if (currentLine.length() == 0 || currentLine.startsWith("#"))
|
||||
break;
|
||||
}
|
||||
} while (hasContinuation);
|
||||
}
|
||||
|
||||
if (lineParts.size() > 0)
|
||||
return lineParts.toArray(new String[0]);
|
||||
}
|
||||
while (ignoreEmptyLines);
|
||||
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception
|
||||
{
|
||||
lineReader.close();
|
||||
lineStream.close();
|
||||
}
|
||||
}
|
|
@ -37,7 +37,7 @@ public class MaterialLibrary
|
|||
{
|
||||
}
|
||||
|
||||
public MaterialLibrary(OBJLoader.LineReader reader) throws IOException
|
||||
public MaterialLibrary(LineReader reader) throws IOException
|
||||
{
|
||||
Material currentMaterial = null;
|
||||
|
||||
|
|
|
@ -19,11 +19,9 @@
|
|||
|
||||
package net.minecraftforge.client.model.obj;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import joptsimple.internal.Strings;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.resources.IResource;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
|
@ -31,18 +29,15 @@ import net.minecraft.util.JSONUtils;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.IModelLoader;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.*;
|
||||
|
||||
public class OBJLoader implements IModelLoader<OBJModel>
|
||||
{
|
||||
public static OBJLoader INSTANCE = new OBJLoader();
|
||||
|
||||
private final Map<ModelSettings, OBJModel> modelCache = Maps.newHashMap();
|
||||
private final Map<OBJModel.ModelSettings, OBJModel> modelCache = Maps.newHashMap();
|
||||
private final Map<ResourceLocation, MaterialLibrary> materialCache = Maps.newHashMap();
|
||||
|
||||
private IResourceManager manager = Minecraft.getInstance().getResourceManager();
|
||||
|
@ -70,10 +65,10 @@ public class OBJLoader implements IModelLoader<OBJModel>
|
|||
@Nullable
|
||||
String materialLibraryOverrideLocation = modelContents.has("materialLibraryOverride") ? JSONUtils.getString(modelContents, "materialLibraryOverride") : null;
|
||||
|
||||
return loadModel(new ModelSettings(new ResourceLocation(modelLocation), detectCullableFaces, diffuseLighting, flipV, ambientToFullbright, materialLibraryOverrideLocation));
|
||||
return loadModel(new OBJModel.ModelSettings(new ResourceLocation(modelLocation), detectCullableFaces, diffuseLighting, flipV, ambientToFullbright, materialLibraryOverrideLocation));
|
||||
}
|
||||
|
||||
public OBJModel loadModel(ModelSettings settings)
|
||||
public OBJModel loadModel(OBJModel.ModelSettings settings)
|
||||
{
|
||||
return modelCache.computeIfAbsent(settings, (data) -> {
|
||||
IResource resource;
|
||||
|
@ -120,117 +115,4 @@ public class OBJLoader implements IModelLoader<OBJModel>
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static class LineReader implements AutoCloseable
|
||||
{
|
||||
InputStreamReader lineStream;
|
||||
BufferedReader lineReader;
|
||||
|
||||
public LineReader(IResource resource)
|
||||
{
|
||||
this.lineStream = new InputStreamReader(resource.getInputStream(), Charsets.UTF_8);
|
||||
this.lineReader = new BufferedReader(lineStream);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String[] readAndSplitLine(boolean ignoreEmptyLines) throws IOException
|
||||
{
|
||||
//noinspection LoopConditionNotUpdatedInsideLoop
|
||||
do
|
||||
{
|
||||
String currentLine = lineReader.readLine();
|
||||
if (currentLine == null)
|
||||
return null;
|
||||
|
||||
List<String> lineParts = new ArrayList<>();
|
||||
|
||||
if (currentLine.startsWith("#"))
|
||||
currentLine = "";
|
||||
|
||||
if (currentLine.length() > 0)
|
||||
{
|
||||
|
||||
boolean hasContinuation;
|
||||
do
|
||||
{
|
||||
hasContinuation = currentLine.endsWith("\\");
|
||||
String tmp = hasContinuation ? currentLine.substring(0, currentLine.length() - 1) : currentLine;
|
||||
|
||||
Arrays.stream(tmp.split("[\t ]+")).filter(s -> !Strings.isNullOrEmpty(s)).forEach(lineParts::add);
|
||||
|
||||
if (hasContinuation)
|
||||
{
|
||||
currentLine = lineReader.readLine();
|
||||
if (currentLine == null)
|
||||
break;
|
||||
|
||||
if (currentLine.length() == 0 || currentLine.startsWith("#"))
|
||||
break;
|
||||
}
|
||||
} while (hasContinuation);
|
||||
}
|
||||
|
||||
if (lineParts.size() > 0)
|
||||
return lineParts.toArray(new String[0]);
|
||||
}
|
||||
while (ignoreEmptyLines);
|
||||
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws Exception
|
||||
{
|
||||
lineReader.close();
|
||||
lineStream.close();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ModelSettings
|
||||
{
|
||||
@Nonnull
|
||||
public final ResourceLocation modelLocation;
|
||||
public final boolean detectCullableFaces;
|
||||
public final boolean diffuseLighting;
|
||||
public final boolean flipV;
|
||||
public final boolean ambientToFullbright;
|
||||
@Nullable
|
||||
public final String materialLibraryOverrideLocation;
|
||||
|
||||
public ModelSettings(@Nonnull ResourceLocation modelLocation, boolean detectCullableFaces, boolean diffuseLighting, boolean flipV, boolean ambientToFullbright,
|
||||
@Nullable String materialLibraryOverrideLocation)
|
||||
{
|
||||
this.modelLocation = modelLocation;
|
||||
this.detectCullableFaces = detectCullableFaces;
|
||||
this.diffuseLighting = diffuseLighting;
|
||||
this.flipV = flipV;
|
||||
this.ambientToFullbright = ambientToFullbright;
|
||||
this.materialLibraryOverrideLocation = materialLibraryOverrideLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ModelSettings that = (ModelSettings) o;
|
||||
return equals(that);
|
||||
}
|
||||
|
||||
public boolean equals(@Nonnull ModelSettings that)
|
||||
{
|
||||
return detectCullableFaces == that.detectCullableFaces &&
|
||||
diffuseLighting == that.diffuseLighting &&
|
||||
flipV == that.flipV &&
|
||||
ambientToFullbright == that.ambientToFullbright &&
|
||||
modelLocation.equals(that.modelLocation) &&
|
||||
Objects.equals(materialLibraryOverrideLocation, that.materialLibraryOverrideLocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hash(modelLocation, detectCullableFaces, diffuseLighting, flipV, ambientToFullbright, materialLibraryOverrideLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
|||
import net.minecraftforge.common.model.TransformationHelper;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
@ -77,7 +78,7 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
|
|||
public final String materialLibraryOverrideLocation;
|
||||
|
||||
|
||||
OBJModel(OBJLoader.LineReader reader, OBJLoader.ModelSettings settings) throws IOException
|
||||
OBJModel(LineReader reader, ModelSettings settings) throws IOException
|
||||
{
|
||||
this.modelLocation = settings.modelLocation;
|
||||
this.detectCullableFaces = settings.detectCullableFaces;
|
||||
|
@ -611,4 +612,52 @@ public class OBJModel implements IMultipartModelGeometry<OBJModel>
|
|||
return mat != null && TransformationHelper.epsilonEquals(mat.ambientColor, new Vector4f(1,1,1,1), 1/256f);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ModelSettings
|
||||
{
|
||||
@Nonnull
|
||||
public final ResourceLocation modelLocation;
|
||||
public final boolean detectCullableFaces;
|
||||
public final boolean diffuseLighting;
|
||||
public final boolean flipV;
|
||||
public final boolean ambientToFullbright;
|
||||
@Nullable
|
||||
public final String materialLibraryOverrideLocation;
|
||||
|
||||
public ModelSettings(@Nonnull ResourceLocation modelLocation, boolean detectCullableFaces, boolean diffuseLighting, boolean flipV, boolean ambientToFullbright,
|
||||
@Nullable String materialLibraryOverrideLocation)
|
||||
{
|
||||
this.modelLocation = modelLocation;
|
||||
this.detectCullableFaces = detectCullableFaces;
|
||||
this.diffuseLighting = diffuseLighting;
|
||||
this.flipV = flipV;
|
||||
this.ambientToFullbright = ambientToFullbright;
|
||||
this.materialLibraryOverrideLocation = materialLibraryOverrideLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o)
|
||||
{
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
ModelSettings that = (ModelSettings) o;
|
||||
return equals(that);
|
||||
}
|
||||
|
||||
public boolean equals(@Nonnull ModelSettings that)
|
||||
{
|
||||
return detectCullableFaces == that.detectCullableFaces &&
|
||||
diffuseLighting == that.diffuseLighting &&
|
||||
flipV == that.flipV &&
|
||||
ambientToFullbright == that.ambientToFullbright &&
|
||||
modelLocation.equals(that.modelLocation) &&
|
||||
Objects.equals(materialLibraryOverrideLocation, that.materialLibraryOverrideLocation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hash(modelLocation, detectCullableFaces, diffuseLighting, flipV, ambientToFullbright, materialLibraryOverrideLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,152 +0,0 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.event.terraingen;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
|
||||
import net.minecraftforge.eventbus.api.Event.HasResult;
|
||||
|
||||
/**
|
||||
* BiomeEvent is fired whenever an event involving biomes occurs.<br>
|
||||
* If a method utilizes this {@link Event} as its parameter, the method will
|
||||
* receive every child event of this class.<br>
|
||||
* <br>
|
||||
* All children of this event are fired on the {@link MinecraftForge#TERRAIN_GEN_BUS}
|
||||
* unless stated otherwise in their Javadocs.
|
||||
**/
|
||||
public class BiomeEvent extends Event
|
||||
{
|
||||
private final Biome biome;
|
||||
|
||||
public BiomeEvent(Biome biome)
|
||||
{
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
public Biome getBiome()
|
||||
{
|
||||
return biome;
|
||||
}
|
||||
|
||||
/**
|
||||
* BiomeColor is fired whenever an event involving biome colors occurs. <br>
|
||||
* If a method utilizes this {@link Event} as its parameter, the method will
|
||||
* receive every child event of this class.<br>
|
||||
* <br>
|
||||
* All children of this event are fired on the {@link MinecraftForge#EVENT_BUS}.
|
||||
**/
|
||||
public static class BiomeColor extends BiomeEvent
|
||||
{
|
||||
private final int originalColor;
|
||||
private int newColor;
|
||||
|
||||
public BiomeColor(Biome biome, int original)
|
||||
{
|
||||
super(biome);
|
||||
originalColor = original;
|
||||
setNewColor(original);
|
||||
}
|
||||
|
||||
public int getOriginalColor()
|
||||
{
|
||||
return originalColor;
|
||||
}
|
||||
|
||||
public int getNewColor()
|
||||
{
|
||||
return newColor;
|
||||
}
|
||||
|
||||
public void setNewColor(int newColor)
|
||||
{
|
||||
this.newColor = newColor;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This event is fired when the village generator attempts to choose a block ID
|
||||
* based on the village's biome.
|
||||
*
|
||||
* You can cancel the event to override default values
|
||||
*/
|
||||
@HasResult
|
||||
public static class GetVillageBlockID extends BiomeEvent
|
||||
{
|
||||
private final BlockState original;
|
||||
private BlockState replacement;
|
||||
|
||||
public GetVillageBlockID(Biome biome, BlockState original)
|
||||
{
|
||||
super(biome);
|
||||
this.original = original;
|
||||
}
|
||||
|
||||
public BlockState getOriginal()
|
||||
{
|
||||
return original;
|
||||
}
|
||||
|
||||
public BlockState getReplacement()
|
||||
{
|
||||
return replacement;
|
||||
}
|
||||
|
||||
public void setReplacement(BlockState replacement)
|
||||
{
|
||||
this.replacement = replacement;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This event is fired when a biome is queried for its grass color.
|
||||
*/
|
||||
public static class GetGrassColor extends BiomeColor
|
||||
{
|
||||
public GetGrassColor(Biome biome, int original)
|
||||
{
|
||||
super(biome, original);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This event is fired when a biome is queried for its grass color.
|
||||
*/
|
||||
public static class GetFoliageColor extends BiomeColor
|
||||
{
|
||||
public GetFoliageColor(Biome biome, int original)
|
||||
{
|
||||
super(biome, original);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This event is fired when a biome is queried for its water color.
|
||||
*/
|
||||
public static class GetWaterColor extends BiomeColor
|
||||
{
|
||||
public GetWaterColor(Biome biome, int original)
|
||||
{
|
||||
super(biome, original);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -93,54 +93,4 @@ public class WorldTypeEvent extends Event
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* InitBiomeGens is fired when vanilla Minecraft attempts to initialize the biome providers.<br>
|
||||
* This event is fired just during biome provider initialization in
|
||||
* {@link BiomeProvider#BiomeProvider(long, WorldType, String)}. <br>
|
||||
* <br>
|
||||
* {@link #seed} the seed of the world. <br>
|
||||
* {@link #originalBiomeGens} the array of GenLayers original intended for this Biome generation. <br>
|
||||
* {@link #newBiomeGens} the array of GenLayers that will now be used for this Biome generation. <br>
|
||||
* If {@link #newBiomeGens} is set to a new value, that value will be used for the Biome generator. <br>
|
||||
* <br>
|
||||
* This event is not {@link Cancelable}.<br>
|
||||
* <br>
|
||||
* This event does not have a result. {@link HasResult} <br>
|
||||
* <br>
|
||||
* This event is fired on the {@link MinecraftForge#TERRAIN_GEN_BUS}.<br>
|
||||
**/
|
||||
public static class InitBiomeGens extends WorldTypeEvent
|
||||
{
|
||||
private final long seed;
|
||||
private final Layer[] originalBiomeGens;
|
||||
private Layer[] newBiomeGens;
|
||||
|
||||
public InitBiomeGens(WorldType worldType, long seed, Layer[] original)
|
||||
{
|
||||
super(worldType);
|
||||
this.seed = seed;
|
||||
originalBiomeGens = original;
|
||||
setNewBiomeGens(original.clone());
|
||||
}
|
||||
|
||||
public long getSeed()
|
||||
{
|
||||
return seed;
|
||||
}
|
||||
|
||||
public Layer[] getOriginalBiomeGens()
|
||||
{
|
||||
return originalBiomeGens;
|
||||
}
|
||||
|
||||
public Layer[] getNewBiomeGens()
|
||||
{
|
||||
return newBiomeGens;
|
||||
}
|
||||
|
||||
public void setNewBiomeGens(Layer[] newBiomeGens)
|
||||
{
|
||||
this.newBiomeGens = newBiomeGens;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue