Custom Model Loader
This commit is contained in:
@@ -86,6 +86,6 @@ public class FacadeBakedItemModel extends DelegateBakedModel
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return ItemOverrideList.NONE;
|
||||
return ItemOverrideList.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,6 +364,6 @@ public class CableBusBakedModel implements IBakedModel
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return ItemOverrideList.NONE;
|
||||
return ItemOverrideList.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public class FacadeBuilder
|
||||
{
|
||||
BakedPipeline pipeline = this.pipelines.get();
|
||||
Quad collectorQuad = this.collectors.get();
|
||||
boolean transparent = AEApi.instance().partHelper().getCableRenderMode().transparentFacades;
|
||||
boolean transparent = Api.INSTANCE.partHelper().getCableRenderMode().transparentFacades;
|
||||
Map<Direction, FacadeRenderState> facadeStates = renderState.getFacades();
|
||||
List<AxisAlignedBB> partBoxes = renderState.getBoundingBoxes();
|
||||
Set<Direction> sidesWithParts = renderState.getAttachments().keySet();
|
||||
|
||||
@@ -137,6 +137,6 @@ public class P2PTunnelFrequencyBakedModel implements IBakedModel, IPartBakedMode
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return ItemOverrideList.NONE;
|
||||
return ItemOverrideList.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -308,6 +308,6 @@ abstract class CraftingCubeBakedModel implements IBakedModel
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return ItemOverrideList.NONE;
|
||||
return ItemOverrideList.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,11 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
@@ -33,48 +31,63 @@ import com.google.common.base.Strings;
|
||||
import net.minecraft.block.BlockState;
|
||||
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.Material;
|
||||
import net.minecraft.client.renderer.texture.AtlasTexture;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import appeng.decorative.solid.BlockQuartzGlass;
|
||||
import appeng.decorative.solid.GlassState;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.ILightReader;
|
||||
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.client.model.pipeline.BakedQuadBuilder;
|
||||
|
||||
|
||||
class GlassBakedModel implements IBakedModel
|
||||
class GlassBakedModel implements IDynamicBakedModel
|
||||
{
|
||||
|
||||
// This unlisted property is used to determine the actual block that should be rendered
|
||||
public static final ModelProperty<GlassState> GLASS_STATE = new ModelProperty<>();
|
||||
|
||||
private static final byte[][][] OFFSETS = generateOffsets();
|
||||
|
||||
// Alternating textures based on position
|
||||
static final ResourceLocation TEXTURE_A = new ResourceLocation( "appliedenergistics2:blocks/glass/quartz_glass_a" );
|
||||
static final ResourceLocation TEXTURE_B = new ResourceLocation( "appliedenergistics2:blocks/glass/quartz_glass_b" );
|
||||
static final ResourceLocation TEXTURE_C = new ResourceLocation( "appliedenergistics2:blocks/glass/quartz_glass_c" );
|
||||
static final ResourceLocation TEXTURE_D = new ResourceLocation( "appliedenergistics2:blocks/glass/quartz_glass_d" );
|
||||
static final Material TEXTURE_A = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, new ResourceLocation( "appliedenergistics2:block/glass/quartz_glass_a" ));
|
||||
static final Material TEXTURE_B = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, new ResourceLocation( "appliedenergistics2:block/glass/quartz_glass_b" ));
|
||||
static final Material TEXTURE_C = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, new ResourceLocation( "appliedenergistics2:block/glass/quartz_glass_c" ));
|
||||
static final Material TEXTURE_D = new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, new ResourceLocation( "appliedenergistics2:block/glass/quartz_glass_d" ));
|
||||
|
||||
// Frame texture
|
||||
static final ResourceLocation[] TEXTURES_FRAME = generateTexturesFrame();
|
||||
static final Material[] TEXTURES_FRAME = generateTexturesFrame();
|
||||
|
||||
// Generates the required textures for the frame
|
||||
private static ResourceLocation[] generateTexturesFrame()
|
||||
private static Material[] generateTexturesFrame()
|
||||
{
|
||||
return IntStream.range( 1, 16 )
|
||||
.mapToObj( Integer::toBinaryString )
|
||||
.map( s -> Strings.padStart( s, 4, '0' ) )
|
||||
.map( s -> new ResourceLocation( "appliedenergistics2:blocks/glass/quartz_glass_frame" + s ) )
|
||||
.toArray( ResourceLocation[]::new );
|
||||
.map( s -> new ResourceLocation( "appliedenergistics2:block/glass/quartz_glass_frame" + s ) )
|
||||
.map( rl -> new Material(AtlasTexture.LOCATION_BLOCKS_TEXTURE, rl) )
|
||||
.toArray( Material[]::new );
|
||||
}
|
||||
|
||||
private final TextureAtlasSprite[] glassTextures;
|
||||
|
||||
private final TextureAtlasSprite[] frameTextures;
|
||||
|
||||
private final VertexFormat vertexFormat;
|
||||
|
||||
public GlassBakedModel( VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
||||
public GlassBakedModel( Function<Material, TextureAtlasSprite> bakedTextureGetter )
|
||||
{
|
||||
this.glassTextures = new TextureAtlasSprite[] {
|
||||
bakedTextureGetter.apply( TEXTURE_A ),
|
||||
@@ -83,8 +96,6 @@ class GlassBakedModel implements IBakedModel
|
||||
bakedTextureGetter.apply( TEXTURE_D )
|
||||
};
|
||||
|
||||
this.vertexFormat = format;
|
||||
|
||||
// The first frame texture would be empty, so we simply leave it set to null here
|
||||
this.frameTextures = new TextureAtlasSprite[16];
|
||||
for( int i = 0; i < TEXTURES_FRAME.length; i++ )
|
||||
@@ -94,15 +105,14 @@ class GlassBakedModel implements IBakedModel
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads( @Nullable BlockState state, @Nullable Direction side, long rand )
|
||||
public List<BakedQuad> getQuads( @Nullable BlockState state, @Nullable Direction side, Random rand, IModelData extraData )
|
||||
{
|
||||
if( !( state instanceof IExtendedBlockState ) || side == null )
|
||||
if( side == null )
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final IExtendedBlockState extState = (IExtendedBlockState) state;
|
||||
final GlassState glassState = extState.getValue( BlockQuartzGlass.GLASS_STATE );
|
||||
final GlassState glassState = extraData.getData( GLASS_STATE );
|
||||
|
||||
if( glassState == null )
|
||||
{
|
||||
@@ -153,6 +163,13 @@ class GlassBakedModel implements IBakedModel
|
||||
return quads;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_()
|
||||
{
|
||||
// TODO: Forge: Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the bitmask that indicates, in which directions (in terms of u,v space) a border should be drawn.
|
||||
*/
|
||||
@@ -217,8 +234,9 @@ class GlassBakedModel implements IBakedModel
|
||||
float v1 = MathHelper.clamp( 0 - vOffset, 0, 16 );
|
||||
float v2 = MathHelper.clamp( 16 - vOffset, 0, 16 );
|
||||
|
||||
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder( this.vertexFormat );
|
||||
builder.setTexture( sprite );
|
||||
|
||||
BakedQuadBuilder builder = new BakedQuadBuilder(sprite);
|
||||
builder.setQuadOrientation(side);
|
||||
this.putVertex( builder, normal, c1.x, c1.y, c1.z, sprite, u1, v1 );
|
||||
this.putVertex( builder, normal, c2.x, c2.y, c2.z, sprite, u1, v2 );
|
||||
this.putVertex( builder, normal, c3.x, c3.y, c3.z, sprite, u2, v2 );
|
||||
@@ -231,11 +249,13 @@ class GlassBakedModel implements IBakedModel
|
||||
* has to be precisely the order
|
||||
* in which the vertex elements had been declared in the vertex format.
|
||||
*/
|
||||
private void putVertex( UnpackedBakedQuad.Builder builder, Vec3d normal, double x, double y, double z, TextureAtlasSprite sprite, float u, float v )
|
||||
private void putVertex( BakedQuadBuilder builder, Vec3d normal, double x, double y, double z, TextureAtlasSprite sprite, float u, float v )
|
||||
{
|
||||
for( int e = 0; e < this.vertexFormat.getElementCount(); e++ )
|
||||
VertexFormat vertexFormat = builder.getVertexFormat();
|
||||
for( int e = 0; e < vertexFormat.getElements().size(); e++ )
|
||||
{
|
||||
switch( this.vertexFormat.getElement( e ).getUsage() )
|
||||
VertexFormatElement el = vertexFormat.getElements().get(e);
|
||||
switch( el.getUsage() )
|
||||
{
|
||||
case POSITION:
|
||||
builder.put( e, (float) x, (float) y, (float) z, 1.0f );
|
||||
@@ -244,7 +264,7 @@ class GlassBakedModel implements IBakedModel
|
||||
builder.put( e, 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
break;
|
||||
case UV:
|
||||
if( this.vertexFormat.getElement( e ).getIndex() == 0 )
|
||||
if( el.getIndex() == 0 )
|
||||
{
|
||||
u = sprite.getInterpolatedU( u );
|
||||
v = sprite.getInterpolatedV( v );
|
||||
@@ -264,7 +284,7 @@ class GlassBakedModel implements IBakedModel
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return ItemOverrideList.NONE;
|
||||
return ItemOverrideList.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -291,12 +311,6 @@ class GlassBakedModel implements IBakedModel
|
||||
return this.frameTextures[this.frameTextures.length - 1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms()
|
||||
{
|
||||
return ItemCameraTransforms.DEFAULT;
|
||||
}
|
||||
|
||||
private static byte[][][] generateOffsets()
|
||||
{
|
||||
final Random r = new Random( 924 );
|
||||
@@ -312,4 +326,31 @@ class GlassBakedModel implements IBakedModel
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IModelData getModelData(@Nonnull ILightReader world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull IModelData tileData) {
|
||||
|
||||
EnumSet<Direction> flushWith = EnumSet.noneOf( Direction.class );
|
||||
// Test every direction for another glass block
|
||||
for( Direction facing : Direction.values() )
|
||||
{
|
||||
if( isGlassBlock( world, pos, facing ) )
|
||||
{
|
||||
flushWith.add( facing );
|
||||
}
|
||||
}
|
||||
|
||||
GlassState glassState = new GlassState( pos.getX(), pos.getY(), pos.getZ(), flushWith );
|
||||
return new ModelDataMap.Builder()
|
||||
.withInitial(GLASS_STATE, glassState)
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
private static boolean isGlassBlock(IBlockReader world, BlockPos pos, Direction facing )
|
||||
{
|
||||
return world.getBlockState( pos.offset( facing ) ).getBlock() instanceof BlockQuartzGlass;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,52 +19,40 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.renderer.model.*;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
import net.minecraftforge.client.model.IModelConfiguration;
|
||||
import net.minecraftforge.client.model.geometry.IModelGeometry;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Model class for the connected texture glass model.
|
||||
*/
|
||||
public class GlassModel implements IModel
|
||||
public class GlassModel implements IModelGeometry<GlassModel>
|
||||
{
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies()
|
||||
{
|
||||
return Collections.emptySet();
|
||||
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation) {
|
||||
return new GlassBakedModel( spriteGetter );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getTextures()
|
||||
{
|
||||
return ImmutableSet.<ResourceLocation>builder()
|
||||
.add( GlassBakedModel.TEXTURE_A, GlassBakedModel.TEXTURE_B, GlassBakedModel.TEXTURE_C, GlassBakedModel.TEXTURE_D )
|
||||
.add( GlassBakedModel.TEXTURES_FRAME )
|
||||
public Collection<Material> getTextures(IModelConfiguration owner, Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors) {
|
||||
return ImmutableSet.<Material>builder()
|
||||
.add(GlassBakedModel.TEXTURE_A, GlassBakedModel.TEXTURE_B, GlassBakedModel.TEXTURE_C, GlassBakedModel.TEXTURE_D)
|
||||
.add(GlassBakedModel.TEXTURES_FRAME)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
||||
{
|
||||
return new GlassBakedModel( format, bakedTextureGetter );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModelState getDefaultState()
|
||||
{
|
||||
return TRSRTransformation.identity();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonObject;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
import net.minecraftforge.client.model.IModelLoader;
|
||||
|
||||
public class GlassModelLoader implements IModelLoader<GlassModel> {
|
||||
|
||||
public static final GlassModelLoader INSTANCE = new GlassModelLoader();
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(IResourceManager resourceManager) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlassModel read(JsonDeserializationContext deserializationContext, JsonObject modelContents) {
|
||||
return new GlassModel();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -255,6 +255,6 @@ class SpatialPylonBakedModel implements IBakedModel
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return ItemOverrideList.NONE;
|
||||
return ItemOverrideList.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user