Add new system for model data, replacing extended states (#5564)
This commit is contained in:
parent
a7204b5cd3
commit
9209c3cbfe
29 changed files with 718 additions and 572 deletions
|
@ -1,15 +1,86 @@
|
|||
--- a/net/minecraft/client/renderer/BlockModelRenderer.java
|
||||
+++ b/net/minecraft/client/renderer/BlockModelRenderer.java
|
||||
@@ -45,7 +45,7 @@
|
||||
@@ -44,11 +44,17 @@
|
||||
this.field_187499_a = p_i46575_1_;
|
||||
}
|
||||
|
||||
+ @Deprecated
|
||||
public boolean func_199324_a(IWorldReader p_199324_1_, IBakedModel p_199324_2_, IBlockState p_199324_3_, BlockPos p_199324_4_, BufferBuilder p_199324_5_, boolean p_199324_6_, Random p_199324_7_, long p_199324_8_) {
|
||||
- boolean flag = Minecraft.func_71379_u() && p_199324_3_.func_185906_d() == 0 && p_199324_2_.func_177555_b();
|
||||
+ boolean flag = Minecraft.func_71379_u() && p_199324_3_.getLightValue(p_199324_1_, p_199324_4_) == 0 && p_199324_2_.isAmbientOcclusion(p_199324_3_);
|
||||
+ return renderModel(p_199324_1_, p_199324_2_, p_199324_3_, p_199324_4_, p_199324_5_, p_199324_6_, p_199324_7_, p_199324_8_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ }
|
||||
|
||||
+ public boolean renderModel(IWorldReader p_199324_1_, IBakedModel p_199324_2_, IBlockState p_199324_3_, BlockPos p_199324_4_, BufferBuilder p_199324_5_, boolean p_199324_6_, Random p_199324_7_, long p_199324_8_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
+ boolean flag = Minecraft.func_71379_u() && p_199324_3_.getLightValue(p_199324_1_, p_199324_4_) == 0 && p_199324_2_.isAmbientOcclusion(p_199324_3_);
|
||||
+ modelData = p_199324_2_.getModelData(p_199324_1_, p_199324_4_, p_199324_3_, modelData);
|
||||
+
|
||||
try {
|
||||
return flag ? this.func_199326_b(p_199324_1_, p_199324_2_, p_199324_3_, p_199324_4_, p_199324_5_, p_199324_6_, p_199324_7_, p_199324_8_) : this.func_199325_c(p_199324_1_, p_199324_2_, p_199324_3_, p_199324_4_, p_199324_5_, p_199324_6_, p_199324_7_, p_199324_8_);
|
||||
@@ -120,6 +120,13 @@
|
||||
- return flag ? this.func_199326_b(p_199324_1_, p_199324_2_, p_199324_3_, p_199324_4_, p_199324_5_, p_199324_6_, p_199324_7_, p_199324_8_) : this.func_199325_c(p_199324_1_, p_199324_2_, p_199324_3_, p_199324_4_, p_199324_5_, p_199324_6_, p_199324_7_, p_199324_8_);
|
||||
+ return flag ? this.renderModelSmooth(p_199324_1_, p_199324_2_, p_199324_3_, p_199324_4_, p_199324_5_, p_199324_6_, p_199324_7_, p_199324_8_, modelData) : this.renderModelFlat(p_199324_1_, p_199324_2_, p_199324_3_, p_199324_4_, p_199324_5_, p_199324_6_, p_199324_7_, p_199324_8_, modelData);
|
||||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.func_85055_a(throwable, "Tesselating block model");
|
||||
CrashReportCategory crashreportcategory = crashreport.func_85058_a("Block model being tesselated");
|
||||
@@ -58,7 +64,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ @Deprecated
|
||||
public boolean func_199326_b(IWorldReader p_199326_1_, IBakedModel p_199326_2_, IBlockState p_199326_3_, BlockPos p_199326_4_, BufferBuilder p_199326_5_, boolean p_199326_6_, Random p_199326_7_, long p_199326_8_) {
|
||||
+ return renderModelSmooth(p_199326_1_, p_199326_2_, p_199326_3_, p_199326_4_, p_199326_5_, p_199326_6_, p_199326_7_, p_199326_8_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ }
|
||||
+
|
||||
+ public boolean renderModelSmooth(IWorldReader p_199326_1_, IBakedModel p_199326_2_, IBlockState p_199326_3_, BlockPos p_199326_4_, BufferBuilder p_199326_5_, boolean p_199326_6_, Random p_199326_7_, long p_199326_8_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
boolean flag = false;
|
||||
float[] afloat = new float[EnumFacing.values().length * 2];
|
||||
BitSet bitset = new BitSet(3);
|
||||
@@ -66,7 +77,7 @@
|
||||
|
||||
for(EnumFacing enumfacing : EnumFacing.values()) {
|
||||
p_199326_7_.setSeed(p_199326_8_);
|
||||
- List<BakedQuad> list = p_199326_2_.func_200117_a(p_199326_3_, enumfacing, p_199326_7_);
|
||||
+ List<BakedQuad> list = p_199326_2_.getQuads(p_199326_3_, enumfacing, p_199326_7_, modelData);
|
||||
if (!list.isEmpty() && (!p_199326_6_ || Block.func_176225_a(p_199326_3_, p_199326_1_, p_199326_4_, enumfacing))) {
|
||||
this.func_187492_a(p_199326_1_, p_199326_3_, p_199326_4_, p_199326_5_, list, afloat, bitset, blockmodelrenderer$ambientocclusionface);
|
||||
flag = true;
|
||||
@@ -74,7 +85,7 @@
|
||||
}
|
||||
|
||||
p_199326_7_.setSeed(p_199326_8_);
|
||||
- List<BakedQuad> list1 = p_199326_2_.func_200117_a(p_199326_3_, (EnumFacing)null, p_199326_7_);
|
||||
+ List<BakedQuad> list1 = p_199326_2_.getQuads(p_199326_3_, (EnumFacing)null, p_199326_7_, modelData);
|
||||
if (!list1.isEmpty()) {
|
||||
this.func_187492_a(p_199326_1_, p_199326_3_, p_199326_4_, p_199326_5_, list1, afloat, bitset, blockmodelrenderer$ambientocclusionface);
|
||||
flag = true;
|
||||
@@ -83,13 +94,18 @@
|
||||
return flag;
|
||||
}
|
||||
|
||||
+ @Deprecated
|
||||
public boolean func_199325_c(IWorldReader p_199325_1_, IBakedModel p_199325_2_, IBlockState p_199325_3_, BlockPos p_199325_4_, BufferBuilder p_199325_5_, boolean p_199325_6_, Random p_199325_7_, long p_199325_8_) {
|
||||
+ return renderModelFlat(p_199325_1_, p_199325_2_, p_199325_3_, p_199325_4_, p_199325_5_, p_199325_6_, p_199325_7_, p_199325_8_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ }
|
||||
+
|
||||
+ public boolean renderModelFlat(IWorldReader p_199325_1_, IBakedModel p_199325_2_, IBlockState p_199325_3_, BlockPos p_199325_4_, BufferBuilder p_199325_5_, boolean p_199325_6_, Random p_199325_7_, long p_199325_8_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
boolean flag = false;
|
||||
BitSet bitset = new BitSet(3);
|
||||
|
||||
for(EnumFacing enumfacing : EnumFacing.values()) {
|
||||
p_199325_7_.setSeed(p_199325_8_);
|
||||
- List<BakedQuad> list = p_199325_2_.func_200117_a(p_199325_3_, enumfacing, p_199325_7_);
|
||||
+ List<BakedQuad> list = p_199325_2_.getQuads(p_199325_3_, enumfacing, p_199325_7_, modelData);
|
||||
if (!list.isEmpty() && (!p_199325_6_ || Block.func_176225_a(p_199325_3_, p_199325_1_, p_199325_4_, enumfacing))) {
|
||||
int i = p_199325_3_.func_185889_a(p_199325_1_, p_199325_4_.func_177972_a(enumfacing));
|
||||
this.func_187496_a(p_199325_1_, p_199325_3_, p_199325_4_, i, false, p_199325_5_, list, bitset);
|
||||
@@ -98,7 +114,7 @@
|
||||
}
|
||||
|
||||
p_199325_7_.setSeed(p_199325_8_);
|
||||
- List<BakedQuad> list1 = p_199325_2_.func_200117_a(p_199325_3_, (EnumFacing)null, p_199325_7_);
|
||||
+ List<BakedQuad> list1 = p_199325_2_.getQuads(p_199325_3_, (EnumFacing)null, p_199325_7_, modelData);
|
||||
if (!list1.isEmpty()) {
|
||||
this.func_187496_a(p_199325_1_, p_199325_3_, p_199325_4_, -1, true, p_199325_5_, list1, bitset);
|
||||
flag = true;
|
||||
@@ -120,6 +136,13 @@
|
||||
p_187492_8_.func_187491_a(p_187492_1_, p_187492_2_, p_187492_3_, bakedquad.func_178210_d(), p_187492_6_, p_187492_7_);
|
||||
p_187492_4_.func_178981_a(bakedquad.func_178209_a());
|
||||
p_187492_4_.func_178962_a(p_187492_8_.field_178207_c[0], p_187492_8_.field_178207_c[1], p_187492_8_.field_178207_c[2], p_187492_8_.field_178207_c[3]);
|
||||
|
@ -23,7 +94,7 @@
|
|||
if (bakedquad.func_178212_b()) {
|
||||
int k = this.field_187499_a.func_186724_a(p_187492_2_, p_187492_1_, p_187492_3_, bakedquad.func_178211_c());
|
||||
float f = (float)(k >> 16 & 255) / 255.0F;
|
||||
@@ -229,10 +236,22 @@
|
||||
@@ -229,10 +252,22 @@
|
||||
float f = (float)(k >> 16 & 255) / 255.0F;
|
||||
float f1 = (float)(k >> 8 & 255) / 255.0F;
|
||||
float f2 = (float)(k & 255) / 255.0F;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
this.field_175025_e = new BlockFluidRenderer();
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
@@ -40,12 +40,17 @@
|
||||
if (p_175020_1_.func_185901_i() == EnumBlockRenderType.MODEL) {
|
||||
IBakedModel ibakedmodel = this.field_175028_a.func_178125_b(p_175020_1_);
|
||||
long i = p_175020_1_.func_209533_a(p_175020_2_);
|
||||
|
@ -18,16 +18,26 @@
|
|||
this.field_175027_c.func_199324_a(p_175020_4_, ibakedmodel1, p_175020_1_, p_175020_2_, Tessellator.func_178181_a().func_178180_c(), true, this.field_195476_e, i);
|
||||
}
|
||||
}
|
||||
@@ -53,6 +53,8 @@
|
||||
|
||||
+ @Deprecated
|
||||
public boolean func_195475_a(IBlockState p_195475_1_, BlockPos p_195475_2_, IWorldReader p_195475_3_, BufferBuilder p_195475_4_, Random p_195475_5_) {
|
||||
+ return renderBlock(p_195475_1_, p_195475_2_, p_195475_3_, p_195475_4_, p_195475_5_, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ }
|
||||
+
|
||||
+ public boolean renderBlock(IBlockState p_195475_1_, BlockPos p_195475_2_, IWorldReader p_195475_3_, BufferBuilder p_195475_4_, Random p_195475_5_, net.minecraftforge.client.model.data.IModelData modelData) {
|
||||
try {
|
||||
EnumBlockRenderType enumblockrendertype = p_195475_1_.func_185901_i();
|
||||
if (enumblockrendertype == EnumBlockRenderType.INVISIBLE) {
|
||||
@@ -53,7 +58,7 @@
|
||||
} else {
|
||||
switch(enumblockrendertype) {
|
||||
case MODEL:
|
||||
+ IBakedModel model = this.func_184389_a(p_195475_1_);
|
||||
+ p_195475_1_ = p_195475_1_.func_177230_c().getExtendedState(p_195475_1_, p_195475_3_, p_195475_2_);
|
||||
return this.field_175027_c.func_199324_a(p_195475_3_, this.func_184389_a(p_195475_1_), p_195475_1_, p_195475_2_, p_195475_4_, true, p_195475_5_, p_195475_1_.func_209533_a(p_195475_2_));
|
||||
- return this.field_175027_c.func_199324_a(p_195475_3_, this.func_184389_a(p_195475_1_), p_195475_1_, p_195475_2_, p_195475_4_, true, p_195475_5_, p_195475_1_.func_209533_a(p_195475_2_));
|
||||
+ return this.field_175027_c.renderModel(p_195475_3_, this.func_184389_a(p_195475_1_), p_195475_1_, p_195475_2_, p_195475_4_, true, p_195475_5_, p_195475_1_.func_209533_a(p_195475_2_), modelData);
|
||||
case ENTITYBLOCK_ANIMATED:
|
||||
return false;
|
||||
@@ -105,4 +107,9 @@
|
||||
default:
|
||||
@@ -105,4 +110,9 @@
|
||||
public void func_195410_a(IResourceManager p_195410_1_) {
|
||||
this.field_175025_e.func_178268_a();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
--- a/net/minecraft/client/renderer/chunk/ChunkRenderTask.java
|
||||
+++ b/net/minecraft/client/renderer/chunk/ChunkRenderTask.java
|
||||
@@ -19,11 +19,14 @@
|
||||
private CompiledChunk field_178547_f;
|
||||
private ChunkRenderTask.Status field_178548_g = ChunkRenderTask.Status.PENDING;
|
||||
private boolean field_178554_h;
|
||||
+ private java.util.Map<net.minecraft.util.math.BlockPos, net.minecraftforge.client.model.data.IModelData> modelData;
|
||||
|
||||
public ChunkRenderTask(RenderChunk p_i46560_1_, ChunkRenderTask.Type p_i46560_2_, double p_i46560_3_) {
|
||||
this.field_178553_a = p_i46560_1_;
|
||||
this.field_178549_d = p_i46560_2_;
|
||||
this.field_188229_e = p_i46560_3_;
|
||||
+
|
||||
+ modelData = net.minecraftforge.client.model.ModelDataManager.getModelData(net.minecraft.client.Minecraft.func_71410_x().field_71441_e, new net.minecraft.util.math.ChunkPos(p_i46560_1_.func_178568_j()));
|
||||
}
|
||||
|
||||
public ChunkRenderTask.Status func_178546_a() {
|
||||
@@ -128,4 +131,8 @@
|
||||
REBUILD_CHUNK,
|
||||
RESORT_TRANSPARENCY;
|
||||
}
|
||||
+
|
||||
+ public net.minecraftforge.client.model.data.IModelData getModelData(net.minecraft.util.math.BlockPos pos) {
|
||||
+ return modelData.getOrDefault(pos, net.minecraftforge.client.model.data.EmptyModelData.INSTANCE);
|
||||
+ }
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
VisGraph lvt_11_1_ = new VisGraph();
|
||||
HashSet lvt_12_1_ = Sets.newHashSet();
|
||||
if (lvt_10_1_ != null) {
|
||||
@@ -142,22 +143,23 @@
|
||||
@@ -142,22 +143,24 @@
|
||||
lvt_11_1_.func_178606_a(blockpos$mutableblockpos);
|
||||
}
|
||||
|
||||
|
@ -41,13 +41,14 @@
|
|||
IFluidState ifluidstate = lvt_10_1_.func_204610_c(blockpos$mutableblockpos);
|
||||
- if (!ifluidstate.func_206888_e()) {
|
||||
- BlockRenderLayer blockrenderlayer1 = ifluidstate.func_180664_k();
|
||||
+ net.minecraftforge.client.model.data.IModelData modelData = p_178581_4_.getModelData(blockpos$mutableblockpos);
|
||||
+ for(BlockRenderLayer blockrenderlayer1 : BlockRenderLayer.values()) {
|
||||
+ net.minecraftforge.client.ForgeHooksClient.setRenderLayer(blockrenderlayer1);
|
||||
+ if (!ifluidstate.func_206888_e() && ifluidstate.canRenderInLayer(blockrenderlayer1)) {
|
||||
int j = blockrenderlayer1.ordinal();
|
||||
BufferBuilder bufferbuilder = p_178581_4_.func_178545_d().func_179039_a(j);
|
||||
if (!compiledchunk.func_178492_d(blockrenderlayer1)) {
|
||||
@@ -168,17 +170,18 @@
|
||||
@@ -168,17 +171,18 @@
|
||||
aboolean[j] |= blockrendererdispatcher.func_205318_a(blockpos$mutableblockpos, lvt_10_1_, bufferbuilder, ifluidstate);
|
||||
}
|
||||
|
||||
|
@ -64,7 +65,8 @@
|
|||
this.func_178573_a(bufferbuilder1, blockpos);
|
||||
}
|
||||
|
||||
aboolean[k] |= blockrendererdispatcher.func_195475_a(iblockstate, blockpos$mutableblockpos, lvt_10_1_, bufferbuilder1, random);
|
||||
- aboolean[k] |= blockrendererdispatcher.func_195475_a(iblockstate, blockpos$mutableblockpos, lvt_10_1_, bufferbuilder1, random);
|
||||
+ aboolean[k] |= blockrendererdispatcher.renderBlock(iblockstate, blockpos$mutableblockpos, lvt_10_1_, bufferbuilder1, random, modelData);
|
||||
}
|
||||
+ }
|
||||
+ net.minecraftforge.client.ForgeHooksClient.setRenderLayer(null);
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
--- a/net/minecraft/client/renderer/model/IBakedModel.java
|
||||
+++ b/net/minecraft/client/renderer/model/IBakedModel.java
|
||||
@@ -10,7 +10,7 @@
|
||||
@@ -10,7 +10,9 @@
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
-public interface IBakedModel {
|
||||
+public interface IBakedModel extends net.minecraftforge.client.extensions.IForgeBakedModel {
|
||||
+
|
||||
+ @Deprecated
|
||||
List<BakedQuad> func_200117_a(@Nullable IBlockState p_200117_1_, @Nullable EnumFacing p_200117_2_, Random p_200117_3_);
|
||||
|
||||
boolean func_177555_b();
|
||||
@@ -21,7 +21,8 @@
|
||||
@@ -21,7 +23,8 @@
|
||||
|
||||
TextureAtlasSprite func_177554_e();
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
--- a/net/minecraft/world/chunk/ChunkSection.java
|
||||
+++ b/net/minecraft/world/chunk/ChunkSection.java
|
||||
@@ -35,6 +35,8 @@
|
||||
}
|
||||
|
||||
public void func_177484_a(int p_177484_1_, int p_177484_2_, int p_177484_3_, IBlockState p_177484_4_) {
|
||||
+ if (p_177484_4_ instanceof net.minecraftforge.common.property.IExtendedBlockState)
|
||||
+ p_177484_4_ = ((net.minecraftforge.common.property.IExtendedBlockState)p_177484_4_).getClean();
|
||||
IBlockState iblockstate = this.func_177485_a(p_177484_1_, p_177484_2_, p_177484_3_);
|
||||
IFluidState ifluidstate = this.func_206914_b(p_177484_1_, p_177484_2_, p_177484_3_);
|
||||
IFluidState ifluidstate1 = p_177484_4_.func_204520_s();
|
|
@ -20,14 +20,28 @@
|
|||
package net.minecraftforge.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.BitSet;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.chunk.RenderChunkCache;
|
||||
import net.minecraft.client.renderer.texture.NativeImage;
|
||||
|
@ -36,13 +50,10 @@ import net.minecraft.resources.IResourceManager;
|
|||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
|
||||
public class MinecraftForgeClient
|
||||
{
|
||||
|
|
|
@ -19,9 +19,20 @@
|
|||
|
||||
package net.minecraftforge.client.extensions;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.ItemCameraTransforms;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
|
||||
public interface IForgeBakedModel
|
||||
{
|
||||
|
@ -30,6 +41,12 @@ public interface IForgeBakedModel
|
|||
return (IBakedModel) this;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
default List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, @Nonnull Random rand, @Nonnull IModelData extraData)
|
||||
{
|
||||
return getBakedModel().getQuads(state, side, rand);
|
||||
}
|
||||
|
||||
default boolean isAmbientOcclusion(IBlockState state) { return getBakedModel().isAmbientOcclusion(); }
|
||||
|
||||
/*
|
||||
|
@ -40,4 +57,9 @@ public interface IForgeBakedModel
|
|||
{
|
||||
return net.minecraftforge.client.ForgeHooksClient.handlePerspective(getBakedModel(), cameraTransformType);
|
||||
}
|
||||
|
||||
default @Nonnull IModelData getModelData(@Nonnull IWorldReader world, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nonnull IModelData tileData)
|
||||
{
|
||||
return tileData;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
package net.minecraftforge.client.model;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
|
||||
public class ModelDataManager
|
||||
{
|
||||
private static WeakReference<World> currentWorld = new WeakReference<>(null);
|
||||
|
||||
private static final Map<ChunkPos, Set<BlockPos>> needModelDataRefresh = new HashMap<>();
|
||||
|
||||
private static final LoadingCache<ChunkPos, Map<BlockPos, IModelData>> modelDataCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(1000)
|
||||
.concurrencyLevel(5)
|
||||
.expireAfterAccess(30, TimeUnit.SECONDS)
|
||||
.build(new CacheLoader<ChunkPos, Map<BlockPos, IModelData>>(){
|
||||
|
||||
@Override
|
||||
public Map<BlockPos, IModelData> load(@Nonnull ChunkPos key)
|
||||
{
|
||||
return new ConcurrentHashMap<>();
|
||||
}
|
||||
});
|
||||
|
||||
private static void cleanCaches(World world)
|
||||
{
|
||||
if (world != currentWorld.get())
|
||||
{
|
||||
currentWorld = new WeakReference<>(world);
|
||||
needModelDataRefresh.clear();
|
||||
modelDataCache.invalidateAll();
|
||||
}
|
||||
}
|
||||
|
||||
public static void requestModelDataRefresh(TileEntity te)
|
||||
{
|
||||
World world = te.getWorld();
|
||||
Preconditions.checkNotNull(world, "Tile entity world must not be null");
|
||||
Preconditions.checkArgument(world == Minecraft.getInstance().world, "Cannot request a model data refresh for a world other than the current client world");
|
||||
synchronized (needModelDataRefresh)
|
||||
{
|
||||
cleanCaches(world);
|
||||
needModelDataRefresh.computeIfAbsent(new ChunkPos(te.getPos()), $ -> Collections.synchronizedSet(new HashSet<>()))
|
||||
.add(te.getPos());
|
||||
}
|
||||
}
|
||||
|
||||
private static void refreshModelData(World world, ChunkPos chunk)
|
||||
{
|
||||
Set<BlockPos> needUpdate;
|
||||
synchronized (needModelDataRefresh)
|
||||
{
|
||||
cleanCaches(world);
|
||||
needUpdate = needModelDataRefresh.remove(chunk);
|
||||
}
|
||||
if (needUpdate != null)
|
||||
{
|
||||
Map<BlockPos, IModelData> data = modelDataCache.getUnchecked(chunk);
|
||||
for (BlockPos pos : needUpdate)
|
||||
{
|
||||
TileEntity toUpdate = world.getTileEntity(pos);
|
||||
if (toUpdate != null)
|
||||
{
|
||||
data.put(pos, toUpdate.getModelData());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static @Nullable IModelData getModelData(World world, BlockPos pos)
|
||||
{
|
||||
return getModelData(world, new ChunkPos(pos)).get(pos);
|
||||
}
|
||||
|
||||
public static Map<BlockPos, IModelData> getModelData(World world, ChunkPos pos)
|
||||
{
|
||||
refreshModelData(world, pos);
|
||||
return modelDataCache.getUnchecked(pos);
|
||||
}
|
||||
}
|
|
@ -43,13 +43,13 @@ import net.minecraft.resources.IResourceManager;
|
|||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
|
||||
import net.minecraftforge.client.model.pipeline.TRSRTransformer;
|
||||
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
||||
import net.minecraftforge.versions.forge.ForgeVersion;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
@ -103,7 +103,7 @@ public final class ModelFluid implements IUnbakedModel
|
|||
bakedTextureGetter.apply(fluid.getFlowing()),
|
||||
Optional.ofNullable(fluid.getOverlay()).map(bakedTextureGetter),
|
||||
fluid.isLighterThanAir(),
|
||||
Optional.empty()
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ public final class ModelFluid implements IUnbakedModel
|
|||
}
|
||||
});
|
||||
|
||||
public CachingBakedFluid(Optional<TRSRTransformation> transformation, ImmutableMap<TransformType, TRSRTransformation> transforms, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, Optional<TextureAtlasSprite> overlay, boolean gas, Optional<IExtendedBlockState> stateOption)
|
||||
public CachingBakedFluid(Optional<TRSRTransformation> transformation, ImmutableMap<TransformType, TRSRTransformation> transforms, VertexFormat format, int color, TextureAtlasSprite still, TextureAtlasSprite flowing, Optional<TextureAtlasSprite> overlay, boolean gas, Optional<IModelData> stateOption)
|
||||
{
|
||||
super(transformation, transforms, format, color, still, flowing, overlay, gas, stateOption.isPresent(), getCorners(stateOption), getFlow(stateOption), getOverlay(stateOption));
|
||||
}
|
||||
|
@ -171,12 +171,12 @@ public final class ModelFluid implements IUnbakedModel
|
|||
* while also providing good use of the available value range.
|
||||
* (For fluids with default quanta, this evenly divides the per-block intervals of 1/9 by 96)
|
||||
*/
|
||||
private static int[] getCorners(Optional<IExtendedBlockState> stateOption)
|
||||
private static int[] getCorners(Optional<IModelData> stateOption)
|
||||
{
|
||||
int[] cornerRound = {0, 0, 0, 0};
|
||||
if (stateOption.isPresent())
|
||||
{
|
||||
IExtendedBlockState state = stateOption.get();
|
||||
IModelData state = stateOption.get();
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Float level = null; // TODO fluids state.getValue(BlockFluidBase.LEVEL_CORNERS[i]);
|
||||
|
@ -193,7 +193,7 @@ public final class ModelFluid implements IUnbakedModel
|
|||
* The value is currently stored as the angle rounded to the nearest degree.
|
||||
* A value of -1000 is used to signify no flow.
|
||||
*/
|
||||
private static int getFlow(Optional<IExtendedBlockState> stateOption)
|
||||
private static int getFlow(Optional<IModelData> stateOption)
|
||||
{
|
||||
Float flow = -1000f;
|
||||
if (stateOption.isPresent())
|
||||
|
@ -213,12 +213,12 @@ public final class ModelFluid implements IUnbakedModel
|
|||
* instead of the normal "flowing" texture (if applicable for that fluid).
|
||||
* The sides are stored here by their regular horizontal index.
|
||||
*/
|
||||
private static boolean[] getOverlay(Optional<IExtendedBlockState> stateOption)
|
||||
private static boolean[] getOverlay(Optional<IModelData> stateOption)
|
||||
{
|
||||
boolean[] overlaySides = new boolean[4];
|
||||
if (stateOption.isPresent())
|
||||
{
|
||||
IExtendedBlockState state = stateOption.get();
|
||||
IModelData state = stateOption.get();
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Boolean overlay = null; // TODO fluids state.getValue(BlockFluidBase.SIDE_OVERLAYS[i]);
|
||||
|
@ -229,11 +229,11 @@ public final class ModelFluid implements IUnbakedModel
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, Random rand)
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, Random rand, IModelData modelData)
|
||||
{
|
||||
if (side != null && state instanceof IExtendedBlockState)
|
||||
if (side != null)
|
||||
{
|
||||
Optional<IExtendedBlockState> exState = Optional.of((IExtendedBlockState)state);
|
||||
Optional<IModelData> exState = Optional.of(modelData);
|
||||
|
||||
int[] cornerRound = getCorners(exState);
|
||||
int flowRound = getFlow(exState);
|
||||
|
|
|
@ -77,12 +77,12 @@ import net.minecraft.util.ResourceLocation;
|
|||
import net.minecraft.util.registry.IRegistry;
|
||||
import net.minecraftforge.client.model.animation.AnimationItemOverrideList;
|
||||
import net.minecraftforge.client.model.animation.ModelBlockAnimation;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.common.ForgeMod;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
import net.minecraftforge.common.model.Models;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
import net.minecraftforge.common.model.animation.IClip;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.Properties;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fml.client.ClientModLoader;
|
||||
|
@ -510,20 +510,12 @@ public final class ModelLoader extends ModelBakery
|
|||
private final ItemOverrideList overrides = new AnimationItemOverrideList(VanillaModelWrapper.this, modelState, format, bakedTextureGetter, super.getOverrides());
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, Random rand)
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, Random rand, IModelData modelData)
|
||||
{
|
||||
if(state instanceof IExtendedBlockState)
|
||||
IModelState newState = modelData.getData(Properties.AnimationProperty);
|
||||
if(newState != null)
|
||||
{
|
||||
IExtendedBlockState exState = (IExtendedBlockState)state;
|
||||
if(exState.getUnlistedNames().contains(Properties.AnimationProperty))
|
||||
{
|
||||
IModelState newState = exState.getValue(Properties.AnimationProperty);
|
||||
IExtendedBlockState newExState = (IExtendedBlockState) exState.withProperty(Properties.AnimationProperty, null);
|
||||
if(newState != null)
|
||||
{
|
||||
return VanillaModelWrapper.this.bake(modelGetter, bakedTextureGetter, new ModelStateComposition(modelState, newState), uvlock, format).getQuads(newExState, side, rand);
|
||||
}
|
||||
}
|
||||
return VanillaModelWrapper.this.bake(modelGetter, bakedTextureGetter, new ModelStateComposition(modelState, newState), uvlock, format).getQuads(state, side, rand, modelData);
|
||||
}
|
||||
return super.getQuads(state, side, rand);
|
||||
}
|
||||
|
|
|
@ -19,26 +19,26 @@
|
|||
|
||||
package net.minecraftforge.client.model.animation;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
import net.minecraft.client.renderer.BufferBuilder;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraftforge.client.MinecraftForgeClient;
|
||||
import net.minecraftforge.client.model.ModelDataManager;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.common.animation.Event;
|
||||
import net.minecraftforge.common.animation.IEventHandler;
|
||||
import net.minecraftforge.common.model.animation.CapabilityAnimation;
|
||||
import net.minecraftforge.common.model.animation.IAnimationStateMachine;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.Properties;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* Generic {@link TileGameRenderer} that works with the Forge model system and animations.
|
||||
*/
|
||||
|
@ -58,30 +58,23 @@ public class TileEntityRendererAnimation<T extends TileEntity> extends TileEntit
|
|||
BlockPos pos = te.getPos();
|
||||
IWorldReader world = MinecraftForgeClient.getRegionRenderCache(te.getWorld(), pos);
|
||||
IBlockState state = world.getBlockState(pos);
|
||||
if(state.getBlock().getStateContainer().getProperties().contains(Properties.StaticProperty))
|
||||
IBakedModel model = blockRenderer.getBlockModelShapes().getModel(state);
|
||||
IModelData data = model.getModelData(world, pos, state, ModelDataManager.getModelData(te.getWorld(), pos));
|
||||
if (data.hasProperty(Properties.AnimationProperty))
|
||||
{
|
||||
state = state.with(Properties.StaticProperty, false);
|
||||
}
|
||||
if(state instanceof IExtendedBlockState)
|
||||
{
|
||||
IExtendedBlockState exState = (IExtendedBlockState)state;
|
||||
if(exState.getUnlistedNames().contains(Properties.AnimationProperty))
|
||||
{
|
||||
float time = Animation.getWorldTime(getWorld(), partialTick);
|
||||
cap
|
||||
.map(asm -> asm.apply(time))
|
||||
.ifPresent(pair -> {
|
||||
handleEvents(te, time, pair.getRight());
|
||||
float time = Animation.getWorldTime(getWorld(), partialTick);
|
||||
cap
|
||||
.map(asm -> asm.apply(time))
|
||||
.ifPresent(pair -> {
|
||||
handleEvents(te, time, pair.getRight());
|
||||
|
||||
// TODO: caching?
|
||||
IBakedModel model = blockRenderer.getBlockModelShapes().getModel(exState.getClean());
|
||||
IExtendedBlockState animState = (IExtendedBlockState) exState.withProperty(Properties.AnimationProperty, pair.getLeft());
|
||||
// TODO: caching?
|
||||
data.setData(Properties.AnimationProperty, pair.getLeft());
|
||||
|
||||
renderer.setTranslation(x - pos.getX(), y - pos.getY(), z - pos.getZ());
|
||||
renderer.setTranslation(x - pos.getX(), y - pos.getY(), z - pos.getZ());
|
||||
|
||||
blockRenderer.getBlockModelRenderer().renderModel(world, model, animState, pos, renderer, false, new Random(), 42);
|
||||
});
|
||||
}
|
||||
blockRenderer.getBlockModelRenderer().renderModel(world, model, state, pos, renderer, false, new Random(), 42, data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -27,13 +27,33 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Vector3f;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.commons.lang3.tuple.Triple;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Collections2;
|
||||
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;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
|
@ -59,6 +79,8 @@ import net.minecraftforge.client.model.b3d.B3DModel.Mesh;
|
|||
import net.minecraftforge.client.model.b3d.B3DModel.Node;
|
||||
import net.minecraftforge.client.model.b3d.B3DModel.Texture;
|
||||
import net.minecraftforge.client.model.b3d.B3DModel.Vertex;
|
||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
||||
import net.minecraftforge.common.model.IModelPart;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
|
@ -66,30 +88,8 @@ import net.minecraftforge.common.model.Models;
|
|||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
import net.minecraftforge.common.model.animation.IClip;
|
||||
import net.minecraftforge.common.model.animation.IJoint;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.Properties;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.apache.commons.lang3.tuple.Triple;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.function.Function;
|
||||
import com.google.common.base.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Collections2;
|
||||
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;
|
||||
|
||||
/*
|
||||
* Loader for Blitz3D models.
|
||||
* To enable for your mod call instance.addDomain(modId).
|
||||
|
@ -599,7 +599,7 @@ public enum B3DLoader implements ICustomModelLoader
|
|||
}
|
||||
}
|
||||
|
||||
private static final class BakedWrapper implements IBakedModel
|
||||
private static final class BakedWrapper implements IDynamicBakedModel
|
||||
{
|
||||
private final Node<?> node;
|
||||
private final IModelState state;
|
||||
|
@ -647,34 +647,27 @@ public enum B3DLoader implements ICustomModelLoader
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, Random rand)
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, Random rand, IModelData data)
|
||||
{
|
||||
if(side != null) return ImmutableList.of();
|
||||
IModelState modelState = this.state;
|
||||
if(state instanceof IExtendedBlockState)
|
||||
IModelState newState = data.getData(Properties.AnimationProperty);
|
||||
if(newState != null)
|
||||
{
|
||||
IExtendedBlockState exState = (IExtendedBlockState)state;
|
||||
if(exState.getUnlistedNames().contains(Properties.AnimationProperty))
|
||||
// FIXME: should animation state handle the parent state, or should it remain here?
|
||||
IModelState parent = this.state;
|
||||
if(parent instanceof B3DState)
|
||||
{
|
||||
// FIXME: should animation state handle the parent state, or should it remain here?
|
||||
IModelState parent = this.state;
|
||||
if(parent instanceof B3DState)
|
||||
{
|
||||
B3DState ps = (B3DState)parent;
|
||||
parent = ps.getParent();
|
||||
}
|
||||
IModelState newState = exState.getValue(Properties.AnimationProperty);
|
||||
if(newState != null)
|
||||
{
|
||||
if (parent == null)
|
||||
{
|
||||
modelState = newState;
|
||||
}
|
||||
else
|
||||
{
|
||||
modelState = new ModelStateComposition(parent, newState);
|
||||
}
|
||||
}
|
||||
B3DState ps = (B3DState)parent;
|
||||
parent = ps.getParent();
|
||||
}
|
||||
if (parent == null)
|
||||
{
|
||||
modelState = newState;
|
||||
}
|
||||
else
|
||||
{
|
||||
modelState = new ModelStateComposition(parent, newState);
|
||||
}
|
||||
}
|
||||
if(quads == null)
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
package net.minecraftforge.client.model.data;
|
||||
|
||||
public enum EmptyModelData implements IModelData
|
||||
{
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public boolean hasProperty(ModelProperty<?> prop) { return false; }
|
||||
|
||||
@Override
|
||||
public <T> T getData(ModelProperty<T> prop) { return null; }
|
||||
|
||||
@Override
|
||||
public <T> T setData(ModelProperty<T> prop, T data) { return null; }
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package net.minecraftforge.client.model.data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
|
||||
/**
|
||||
* Convenience interface with default implementation of {@link IBakedModel#getQuads(net.minecraft.block.state.IBlockState, net.minecraft.util.EnumFacing, java.util.Random)}.
|
||||
*/
|
||||
public interface IDynamicBakedModel extends IBakedModel
|
||||
{
|
||||
@Override
|
||||
default @Nonnull List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, @Nonnull Random rand)
|
||||
{
|
||||
return getQuads(state, side, rand, EmptyModelData.INSTANCE);
|
||||
}
|
||||
|
||||
// Force this to be overriden otherwise this introduces a default cycle between the two overloads.
|
||||
@Override
|
||||
@Nonnull
|
||||
List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, @Nonnull Random rand, @Nonnull IModelData extraData);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package net.minecraftforge.client.model.data;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public interface IModelData
|
||||
{
|
||||
/**
|
||||
* Check if this data has a property, even if the value is {@code null}. Can be
|
||||
* used by code that intends to fill in data for a render pipeline, such as the
|
||||
* forge animation system.
|
||||
* <p>
|
||||
* IMPORTANT: {@link #getData(ModelProperty)} <em>can</em> return {@code null}
|
||||
* even if this method returns {@code true}.
|
||||
*
|
||||
* @param prop The property to check for inclusion in this model data
|
||||
* @return {@code true} if this data has the given property, even if no value is present
|
||||
*/
|
||||
boolean hasProperty(ModelProperty<?> prop);
|
||||
|
||||
@Nullable
|
||||
<T> T getData(ModelProperty<T> prop);
|
||||
|
||||
@Nullable
|
||||
<T> T setData(ModelProperty<T> prop, T data);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package net.minecraftforge.client.model.data;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
public class ModelDataMap implements IModelData
|
||||
{
|
||||
private final Map<ModelProperty<?>, Object> backingMap;
|
||||
|
||||
private ModelDataMap(Map<ModelProperty<?>, Object> map)
|
||||
{
|
||||
this.backingMap = new IdentityHashMap<>(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasProperty(ModelProperty<?> prop)
|
||||
{
|
||||
return backingMap.containsKey(prop);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getData(ModelProperty<T> prop)
|
||||
{
|
||||
return (T) backingMap.get(prop);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T setData(ModelProperty<T> prop, T data)
|
||||
{
|
||||
Preconditions.checkArgument(prop.test(data), "Value is invalid for this property");
|
||||
return (T) backingMap.put(prop, data);
|
||||
}
|
||||
|
||||
public static class Builder
|
||||
{
|
||||
private final Map<ModelProperty<?>, Object> defaults = new IdentityHashMap<>();
|
||||
|
||||
public Builder withProperty(ModelProperty<?> prop)
|
||||
{
|
||||
return withInitial(prop, null);
|
||||
}
|
||||
|
||||
public <T> Builder withInitial(ModelProperty<T> prop, T data)
|
||||
{
|
||||
this.defaults.put(prop, data);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ModelDataMap build()
|
||||
{
|
||||
return new ModelDataMap(defaults);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package net.minecraftforge.client.model.data;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
|
||||
public class ModelProperty<T> implements Predicate<T> {
|
||||
|
||||
private final Predicate<T> pred;
|
||||
|
||||
public ModelProperty() {
|
||||
this(Predicates.alwaysTrue());
|
||||
}
|
||||
|
||||
public ModelProperty(Predicate<T> pred) {
|
||||
this.pred = pred;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(T t) {
|
||||
return pred.test(t);
|
||||
}
|
||||
}
|
|
@ -54,13 +54,13 @@ import net.minecraft.resources.IResourceManager;
|
|||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.*;
|
||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
||||
import net.minecraftforge.common.model.IModelPart;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
import net.minecraftforge.common.model.Models;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IUnlistedProperty;
|
||||
import net.minecraftforge.common.property.Properties;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
@ -1255,36 +1255,7 @@ public class OBJModel implements IUnbakedModel
|
|||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum OBJProperty implements IUnlistedProperty<OBJState>
|
||||
{
|
||||
INSTANCE;
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "OBJProperty";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(OBJState value)
|
||||
{
|
||||
return value instanceof OBJState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<OBJState> getType()
|
||||
{
|
||||
return OBJState.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valueToString(OBJState value)
|
||||
{
|
||||
return value.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public class OBJBakedModel implements IBakedModel
|
||||
public class OBJBakedModel implements IDynamicBakedModel
|
||||
{
|
||||
private final OBJModel model;
|
||||
private IModelState state;
|
||||
|
@ -1308,26 +1279,18 @@ public class OBJModel implements IUnbakedModel
|
|||
|
||||
// FIXME: merge with getQuads
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(IBlockState blockState, EnumFacing side, Random rand)
|
||||
public List<BakedQuad> getQuads(IBlockState blockState, EnumFacing side, Random rand, IModelData modelData)
|
||||
{
|
||||
if (side != null) return ImmutableList.of();
|
||||
if (quads == null)
|
||||
{
|
||||
quads = buildQuads(this.state);
|
||||
}
|
||||
if (blockState instanceof IExtendedBlockState)
|
||||
IModelState newState = modelData.getData(Properties.AnimationProperty);
|
||||
if (newState != null)
|
||||
{
|
||||
IExtendedBlockState exState = (IExtendedBlockState) blockState;
|
||||
if (exState.getUnlistedNames().contains(Properties.AnimationProperty))
|
||||
{
|
||||
|
||||
IModelState newState = exState.getValue(Properties.AnimationProperty);
|
||||
if (newState != null)
|
||||
{
|
||||
newState = new ModelStateComposition(this.state, newState);
|
||||
return buildQuads(newState);
|
||||
}
|
||||
}
|
||||
newState = new ModelStateComposition(this.state, newState);
|
||||
return buildQuads(newState);
|
||||
}
|
||||
return quads;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
package net.minecraftforge.common.extensions;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.init.Blocks;
|
||||
|
@ -29,6 +31,9 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.client.model.ModelDataManager;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
|
||||
|
||||
public interface IForgeTileEntity extends ICapabilitySerializable<NBTTagCompound>
|
||||
|
@ -86,7 +91,10 @@ public interface IForgeTileEntity extends ICapabilitySerializable<NBTTagCompound
|
|||
* Called when this is first added to the world (by {@link World#addTileEntity(TileEntity)}).
|
||||
* Override instead of adding {@code if (firstTick)} stuff in update.
|
||||
*/
|
||||
default void onLoad(){}
|
||||
default void onLoad()
|
||||
{
|
||||
requestModelDataUpdate();
|
||||
}
|
||||
|
||||
default boolean shouldRenderInPass(int pass)
|
||||
{
|
||||
|
@ -168,4 +176,19 @@ public interface IForgeTileEntity extends ICapabilitySerializable<NBTTagCompound
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
default void requestModelDataUpdate()
|
||||
{
|
||||
TileEntity te = getTileEntity();
|
||||
World world = te.getWorld();
|
||||
if (world != null && world.isRemote)
|
||||
{
|
||||
ModelDataManager.requestModelDataRefresh(te);
|
||||
}
|
||||
}
|
||||
|
||||
default @Nonnull IModelData getModelData()
|
||||
{
|
||||
return EmptyModelData.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,178 +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.common.property;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableTable;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.state.BlockState;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.state.AbstractStateHolder;
|
||||
import net.minecraft.state.IProperty;
|
||||
import net.minecraft.state.IStateHolder;
|
||||
import net.minecraft.state.StateContainer;
|
||||
// TODO Extended states gotta go, I doubt this works at all
|
||||
public class ExtendedStateContainer<O, S extends IExtendedState<S>> extends StateContainer<O, S>
|
||||
{
|
||||
private final ImmutableSet<IUnlistedProperty<?>> unlistedProperties;
|
||||
|
||||
public <A extends AbstractStateHolder<O, S>> ExtendedStateContainer(O blockIn, StateContainer.IFactory<O, S, A> stateFactory, net.minecraft.state.IProperty<?>[] properties, IUnlistedProperty<?>[] unlistedProperties)
|
||||
{
|
||||
super(blockIn, getProxyFactory(unlistedProperties, stateFactory), buildListedMap(properties));// TODO Unlisted properties?, buildUnlistedMap(unlistedProperties));
|
||||
ImmutableSet.Builder<IUnlistedProperty<?>> builder = ImmutableSet.builder();
|
||||
for(IUnlistedProperty<?> property : unlistedProperties)
|
||||
{
|
||||
builder.add(property);
|
||||
}
|
||||
this.unlistedProperties = builder.build();
|
||||
}
|
||||
|
||||
private static <O, S extends IExtendedState<S>, A extends AbstractStateHolder<O, S>>
|
||||
StateContainer.IFactory<O, S, AbstractStateHolder<O,S>> getProxyFactory(IUnlistedProperty<?>[] unlistedProperties, StateContainer.IFactory<O, S, A> proxy)
|
||||
{
|
||||
return (o, props) -> {
|
||||
if (unlistedProperties == null || unlistedProperties.length == 0) return proxy.create(o, props);
|
||||
return new ExtendedStateHolder<O, S>(o, props, buildUnlistedMap(unlistedProperties), null);
|
||||
};
|
||||
}
|
||||
|
||||
public Collection<IUnlistedProperty<?>> getUnlistedProperties()
|
||||
{
|
||||
return unlistedProperties;
|
||||
}
|
||||
|
||||
private static Map<String, IProperty<?>> buildListedMap(IProperty<?>[] properties)
|
||||
{
|
||||
return Arrays.stream(properties).collect(Collectors.toMap(IProperty::getName, Function.identity()));
|
||||
}
|
||||
|
||||
private static ImmutableMap<IUnlistedProperty<?>, Optional<?>> buildUnlistedMap(IUnlistedProperty<?>[] unlistedProperties)
|
||||
{
|
||||
ImmutableMap.Builder<IUnlistedProperty<?>, Optional<?>> builder = ImmutableMap.builder();
|
||||
for(IUnlistedProperty<?> p : unlistedProperties)
|
||||
{
|
||||
builder.put(p, Optional.empty());
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
protected static class ExtendedStateHolder<O, S extends IExtendedState<S>> extends AbstractStateHolder<O, S> implements IExtendedState<S>
|
||||
{
|
||||
private final ImmutableMap<IUnlistedProperty<?>, Optional<?>> unlistedProperties;
|
||||
private S cleanState;
|
||||
|
||||
protected ExtendedStateHolder(O block, ImmutableMap<IProperty<?>, Comparable<?>> properties, ImmutableMap<IUnlistedProperty<?>, Optional<?>> unlistedProperties, S clean)
|
||||
{
|
||||
super(block, properties);
|
||||
this.unlistedProperties = unlistedProperties;
|
||||
this.cleanState = clean == null ? (S) this : clean;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public <T extends Comparable<T>, V extends T> S with(@Nonnull IProperty<T> property, @Nonnull V value)
|
||||
{
|
||||
S clean = super.with(property, value);
|
||||
if (clean == this.cleanState) {
|
||||
return (S) this;
|
||||
}
|
||||
|
||||
if (this == this.cleanState)
|
||||
{ // no dynamic properties present, looking up in the normal table
|
||||
return clean;
|
||||
}
|
||||
|
||||
return (S) new ExtendedStateHolder(object, ((IStateHolder)clean).getValues(), unlistedProperties, this.cleanState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> S withProperty(IUnlistedProperty<V> property, @Nullable V value)
|
||||
{
|
||||
Optional<?> oldValue = unlistedProperties.get(property);
|
||||
if (oldValue == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Cannot set unlisted property " + property + " as it does not exist in " + this);
|
||||
}
|
||||
if (Objects.equals(oldValue.orElse(null), value))
|
||||
{
|
||||
return (S) this;
|
||||
}
|
||||
if (!property.isValid(value))
|
||||
{
|
||||
throw new IllegalArgumentException("Cannot set unlisted property " + property + " to " + value + " on object " + object + ", it is not an allowed value");
|
||||
}
|
||||
boolean clean = true;
|
||||
ImmutableMap.Builder<IUnlistedProperty<?>, Optional<?>> builder = ImmutableMap.builder();
|
||||
for (Map.Entry<IUnlistedProperty<?>, Optional<?>> entry : unlistedProperties.entrySet())
|
||||
{
|
||||
IUnlistedProperty<?> key = entry.getKey();
|
||||
Optional<?> newValue = key.equals(property) ? Optional.ofNullable(value) : entry.getValue();
|
||||
if (newValue.isPresent()) clean = false;
|
||||
builder.put(key, newValue);
|
||||
}
|
||||
if (clean)
|
||||
{ // no dynamic properties, lookup normal state
|
||||
return (S) cleanState;
|
||||
}
|
||||
return (S) new ExtendedStateHolder(object, getValues(), builder.build(), this.cleanState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<IUnlistedProperty<?>> getUnlistedNames()
|
||||
{
|
||||
return unlistedProperties.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <V> V getValue(IUnlistedProperty<V> property)
|
||||
{
|
||||
Optional<?> value = unlistedProperties.get(property);
|
||||
if (value == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Cannot get unlisted property " + property + " as it does not exist in " + this);
|
||||
}
|
||||
return property.getType().cast(value.orElse(null));
|
||||
}
|
||||
|
||||
public ImmutableMap<IUnlistedProperty<?>, Optional<?>> getUnlistedProperties()
|
||||
{
|
||||
return unlistedProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public S getClean()
|
||||
{
|
||||
return cleanState;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,27 +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.common.property;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
|
||||
public interface IExtendedBlockState extends IExtendedState<IBlockState>, IBlockState
|
||||
{
|
||||
|
||||
}
|
|
@ -1,41 +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.common.property;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.state.IStateHolder;
|
||||
|
||||
import java.util.Optional;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
public interface IExtendedState<C> extends IStateHolder<C>
|
||||
{
|
||||
Collection<IUnlistedProperty<?>> getUnlistedNames();
|
||||
|
||||
<V>V getValue(IUnlistedProperty<V> property);
|
||||
|
||||
<V>C withProperty(IUnlistedProperty<V> property, V value);
|
||||
|
||||
ImmutableMap<IUnlistedProperty<?>, Optional<?>> getUnlistedProperties();
|
||||
|
||||
C getClean();
|
||||
}
|
|
@ -1,31 +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.common.property;
|
||||
|
||||
public interface IUnlistedProperty<V>
|
||||
{
|
||||
String getName();
|
||||
|
||||
boolean isValid(V value);
|
||||
|
||||
Class<V> getType();
|
||||
|
||||
String valueToString(V value);
|
||||
}
|
|
@ -20,7 +20,7 @@
|
|||
package net.minecraftforge.common.property;
|
||||
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.IProperty;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
|
||||
public class Properties
|
||||
|
@ -33,54 +33,5 @@ public class Properties
|
|||
/**
|
||||
* Property holding the IModelState used for animating the model in the TESR.
|
||||
*/
|
||||
public static final IUnlistedProperty<IModelState> AnimationProperty = new IUnlistedProperty<IModelState>()
|
||||
{
|
||||
@Override
|
||||
public String getName() { return "forge_animation"; }
|
||||
@Override
|
||||
public boolean isValid(IModelState state) { return true; }
|
||||
@Override
|
||||
public Class<IModelState> getType() { return IModelState.class; }
|
||||
@Override
|
||||
public String valueToString(IModelState state) { return state.toString(); }
|
||||
};
|
||||
|
||||
public static <V extends Comparable<V>> IUnlistedProperty<V> toUnlisted(IProperty<V> property)
|
||||
{
|
||||
return new PropertyAdapter<V>(property);
|
||||
}
|
||||
|
||||
public static class PropertyAdapter<V extends Comparable<V>> implements IUnlistedProperty<V>
|
||||
{
|
||||
private final IProperty<V> parent;
|
||||
|
||||
public PropertyAdapter(IProperty<V> parent)
|
||||
{
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return parent.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(V value)
|
||||
{
|
||||
return parent.getAllowedValues().contains(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<V> getType()
|
||||
{
|
||||
return parent.getValueClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valueToString(V value)
|
||||
{
|
||||
return parent.getName(value);
|
||||
}
|
||||
}
|
||||
public static final ModelProperty<IModelState> AnimationProperty = new ModelProperty<IModelState>();
|
||||
}
|
||||
|
|
|
@ -1,70 +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.common.property;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Range;
|
||||
|
||||
public class PropertyFloat implements IUnlistedProperty<Float>
|
||||
{
|
||||
private final String name;
|
||||
private final Predicate<Float> validator;
|
||||
|
||||
public PropertyFloat(String name)
|
||||
{
|
||||
this(name, Predicates.alwaysTrue());
|
||||
}
|
||||
|
||||
public PropertyFloat(String name, float min, float max)
|
||||
{
|
||||
this(name, Range.closed(min, max));
|
||||
}
|
||||
|
||||
public PropertyFloat(String name, Predicate<Float> validator)
|
||||
{
|
||||
this.name = name;
|
||||
this.validator = validator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(Float value)
|
||||
{
|
||||
return validator.apply(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Float> getType()
|
||||
{
|
||||
return Float.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valueToString(Float value)
|
||||
{
|
||||
return value.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"variants": {
|
||||
"": { "model": "forge:modeltest" }
|
||||
}
|
||||
}
|
|
@ -4,6 +4,11 @@ net/minecraft/block/BlockRailPowered.<init>(Lnet/minecraft/block/Block$Propertie
|
|||
net/minecraft/block/BlockRedstoneWire.canConnectTo(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/world/IBlockReader;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/EnumFacing;)Z=|p_176343_0_,world,pos,p_176343_1_
|
||||
|
||||
net/minecraft/client/multiplayer/WorldClient.removeEntity(Lnet/minecraft/entity/Entity;Z)V=|p_72900_1_,keepData
|
||||
|
||||
net/minecraft/client/renderer/BlockRendererDispatcher.renderBlock(Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/world/IWorldReader;Lnet/minecraft/client/renderer/BufferBuilder;Ljava/util/Random;Lnet/minecraftforge/client/model/data/IModelData;)Z=|p_195475_1_,p_195475_2_,p_195475_3_,p_195475_4_,p_195475_5_,modelData
|
||||
net/minecraft/client/renderer/BlockModelRenderer.renderModel(Lnet/minecraft/world/IWorldReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/renderer/BufferBuilder;ZLjava/util/Random;JLnet/minecraftforge/client/model/data/IModelData;)Z=|p_199324_1_,p_199324_2_,p_199324_3_,p_199324_4_,p_199324_5_,p_199324_6_,p_199324_7_,p_199324_8_,modelData
|
||||
net/minecraft/client/renderer/BlockModelRenderer.renderModelSmooth(Lnet/minecraft/world/IWorldReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/renderer/BufferBuilder;ZLjava/util/Random;JLnet/minecraftforge/client/model/data/IModelData;)Z=|p_199326_1_,p_199326_2_,p_199326_3_,p_199326_4_,p_199326_5_,p_199326_6_,p_199326_7_,p_199326_8_,modelData
|
||||
net/minecraft/client/renderer/BlockModelRenderer.renderModelFlat(Lnet/minecraft/world/IWorldReader;Lnet/minecraft/client/renderer/model/IBakedModel;Lnet/minecraft/block/state/IBlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/renderer/BufferBuilder;ZLjava/util/Random;JLnet/minecraftforge/client/model/data/IModelData;)Z=|p_199325_1_,p_199325_2_,p_199325_3_,p_199325_4_,p_199325_5_,p_199325_6_,p_199325_7_,p_199325_8_,modelData
|
||||
net/minecraft/client/renderer/model/BakedQuad.<init>([IILnet/minecraft/util/EnumFacing;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;ZLnet/minecraft/client/renderer/vertex/VertexFormat;)V=|p_i46574_1_,p_i46574_2_,p_i46574_3_,p_i46574_4_,applyDiffuseLighting,format
|
||||
net/minecraft/client/renderer/model/FaceBakery.makeBakedQuad(Lnet/minecraft/client/renderer/Vector3f;Lnet/minecraft/client/renderer/Vector3f;Lnet/minecraft/client/renderer/model/BlockPartFace;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;Lnet/minecraft/util/EnumFacing;Lnet/minecraftforge/common/model/ITransformation;Lnet/minecraft/client/renderer/model/BlockPartRotation;ZZ)Lnet/minecraft/client/renderer/model/BakedQuad;=|p_199332_1_,p_199332_2_,p_199332_3_,p_199332_4_,p_199332_5_,p_199332_6_,p_199332_7_,p_199332_8_,p_199332_9_
|
||||
net/minecraft/client/renderer/model/FaceBakery.makeQuadVertexData(Lnet/minecraft/client/renderer/model/BlockFaceUV;Lnet/minecraft/client/renderer/texture/TextureAtlasSprite;Lnet/minecraft/util/EnumFacing;[FLnet/minecraftforge/common/model/ITransformation;Lnet/minecraft/client/renderer/model/BlockPartRotation;Z)[I=|p_188012_1_,p_188012_2_,p_188012_3_,p_188012_4_,p_188012_5_,p_188012_6_,p_188012_7_
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* 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.debug.client.model;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockContainer;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.model.ModelResourceLocation;
|
||||
import net.minecraft.client.renderer.texture.MissingTextureSprite;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.EnumBlockRenderType;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.ITickable;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraftforge.client.event.ModelBakeEvent;
|
||||
import net.minecraftforge.client.model.ModelDataManager;
|
||||
import net.minecraftforge.client.model.data.IDynamicBakedModel;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
|
||||
@Mod(ModelDataTest.MODID)
|
||||
public class ModelDataTest
|
||||
{
|
||||
public static final String MODID = "forgedebugmodeldata";
|
||||
public static final String VERSION = "1.0";
|
||||
|
||||
private static final ModelProperty<Boolean> MAGIC_PROP = new ModelProperty<Boolean>();
|
||||
|
||||
public ModelDataTest()
|
||||
{
|
||||
final IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
modEventBus.addGenericListener(Block.class, this::registerBlocks);
|
||||
modEventBus.addGenericListener(TileEntityType.class, this::registerTileEntities);
|
||||
MinecraftForge.EVENT_BUS.addListener(this::modelBake);
|
||||
}
|
||||
|
||||
public void modelBake(ModelBakeEvent event)
|
||||
{
|
||||
final IBakedModel stone = event.getModelRegistry().get(new ModelResourceLocation("minecraft:stone"));
|
||||
final IBakedModel dirt = event.getModelRegistry().get(new ModelResourceLocation("minecraft:dirt"));
|
||||
final IBakedModel old = event.getModelRegistry().get(new ModelResourceLocation("forge:modeltest"));
|
||||
event.getModelRegistry().put(new ModelResourceLocation("forge:modeltest"), new IDynamicBakedModel()
|
||||
{
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, Random rand, IModelData modelData)
|
||||
{
|
||||
return modelData.getData(MAGIC_PROP) ? stone.getQuads(state, side, rand, modelData) : dirt.getQuads(state, side, rand, modelData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture()
|
||||
{
|
||||
return MissingTextureSprite.getSprite();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public IModelData getModelData(@Nonnull IWorldReader world, @Nonnull BlockPos pos, @Nonnull IBlockState state, @Nonnull IModelData tileData)
|
||||
{
|
||||
if (world.getBlockState(pos.down()).getBlock() == Blocks.AIR)
|
||||
{
|
||||
tileData.setData(MAGIC_PROP, !tileData.getData(MAGIC_PROP));
|
||||
}
|
||||
return tileData;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final TileEntityType<Tile> TILE_TYPE = TileEntityType.Builder.create(Tile::new).build(null);
|
||||
|
||||
private static class Tile extends TileEntity implements ITickable
|
||||
{
|
||||
|
||||
public Tile()
|
||||
{
|
||||
super(TILE_TYPE);
|
||||
}
|
||||
|
||||
private int counter;
|
||||
|
||||
@Override
|
||||
public void tick()
|
||||
{
|
||||
if (world.isRemote && counter++ == 100)
|
||||
{
|
||||
ModelDataManager.requestModelDataRefresh(this);
|
||||
world.markBlockRangeForRenderUpdate(getPos(), getPos());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModelData getModelData()
|
||||
{
|
||||
return new ModelDataMap.Builder().withInitial(MAGIC_PROP, counter < 100).build();
|
||||
}
|
||||
}
|
||||
|
||||
public void registerBlocks(RegistryEvent.Register<Block> event)
|
||||
{
|
||||
event.getRegistry().register(new BlockContainer(Block.Properties.create(Material.ROCK))
|
||||
{
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public TileEntity createNewTileEntity(IBlockReader worldIn)
|
||||
{
|
||||
return new Tile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EnumBlockRenderType getRenderType(IBlockState state)
|
||||
{
|
||||
return EnumBlockRenderType.MODEL;
|
||||
}
|
||||
}.setRegistryName("forge:modeltest"));
|
||||
}
|
||||
|
||||
public void registerTileEntities(RegistryEvent.Register<TileEntityType<?>> event)
|
||||
{
|
||||
event.getRegistry().register(TILE_TYPE.setRegistryName("forge:modeltest"));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue