More Rendering fixes

This commit is contained in:
Sebastian Hartte
2020-06-08 18:35:27 +02:00
parent 679ea1c332
commit b2afa0398c
44 changed files with 427 additions and 276 deletions
@@ -69,9 +69,6 @@ import appeng.util.SettingsFrom;
public abstract class AEBaseTileBlock<T extends AEBaseTile> extends AEBaseBlock
{
public static final ModelProperty<Direction> FORWARD = new ModelProperty<>();
public static final ModelProperty<Direction> UP = new ModelProperty<>();
@Nonnull
private Class<T> tileEntityClass;
@Nonnull
@@ -23,7 +23,6 @@ import appeng.container.ContainerOpener;
import appeng.container.implementations.ContainerCraftingCPU;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.state.BooleanProperty;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.state.StateContainer;
@@ -48,6 +47,7 @@ public abstract class AbstractCraftingUnitBlock<T extends TileCraftingTile> exte
{
super( props );
this.type = type;
this.setDefaultState(getDefaultState().with(FORMED, false).with(POWERED, false));
}
@Override
@@ -45,6 +45,7 @@ public class BlockMolecularAssembler extends AEBaseTileBlock<TileMolecularAssemb
public BlockMolecularAssembler(Block.Properties props)
{
super( props );
setDefaultState(getDefaultState().with(POWERED, false));
}
@Override
@@ -53,19 +54,10 @@ public class BlockMolecularAssembler extends AEBaseTileBlock<TileMolecularAssemb
builder.add(POWERED);
}
// FIXME: This apparently was used to update block states purely client-side... this wont work anymore :|
// FIXME @Override
// FIXME public BlockState getActualState( BlockState state, IBlockReader worldIn, BlockPos pos )
// FIXME {
// FIXME boolean powered = false;
// FIXME TileMolecularAssembler te = this.getTileEntity( worldIn, pos );
// FIXME if( te != null )
// FIXME {
// FIXME powered = te.isPowered();
// FIXME }
// FIXME
// FIXME return super.getActualState( state, worldIn, pos ).with( POWERED, powered );
// FIXME }
@Override
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, TileMolecularAssembler te) {
return currentState.with(POWERED, te.isPowered());
}
@Override
public ActionResultType onBlockActivated(BlockState state, World w, BlockPos pos, PlayerEntity p, Hand hand, BlockRayTraceResult hit) {
@@ -31,6 +31,5 @@ public class DriveRendering extends BlockRenderingCustomizer
public void customize( IBlockRendering rendering, IItemRendering itemRendering )
{
rendering.renderType(RenderType.getCutout());
// FIXME rendering.builtInModel( "models/block/builtin/drive", new DriveModel() );
}
}
@@ -26,6 +26,8 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
@@ -41,15 +43,6 @@ public class TesrRenderHelper
private static final IWideReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
/**
* Move the current coordinate system to the center of the given block face, assuming that the origin is currently
* at the center of a block.
*/
public static void moveToFace( MatrixStack mStack, Direction face )
{
mStack.translate( face.getXOffset() * 0.50, face.getYOffset() * 0.50, face.getZOffset() * 0.50 );
}
/**
* Rotate the current coordinate system so it is on the face of the given block side. This can be used to render on
* the given face as if it was
@@ -60,34 +53,28 @@ public class TesrRenderHelper
switch( face )
{
case UP:
mStack.scale( 1.0f, -1.0f, 1.0f );
mStack.rotate( Vector3f.XP.rotationDegrees( 90.0F ) );
mStack.rotate( Vector3f.ZP.rotationDegrees( spin * 90.0F ) );
break;
case DOWN:
mStack.scale( 1.0f, -1.0f, 1.0f );
mStack.rotate( Vector3f.XP.rotationDegrees( -90.0F ) );
mStack.rotate( Vector3f.ZP.rotationDegrees( spin * -90.0F ) );
break;
case EAST:
mStack.scale( -1.0f, -1.0f, -1.0f );
mStack.rotate( Vector3f.YP.rotationDegrees( -90.0F ) );
break;
case WEST:
mStack.scale( -1.0f, -1.0f, -1.0f );
mStack.rotate( Vector3f.YP.rotationDegrees( 90.0F ) );
break;
case WEST:
mStack.rotate( Vector3f.YP.rotationDegrees( -90.0F ) );
break;
case NORTH:
mStack.scale( -1.0f, -1.0f, -1.0f );
mStack.rotate( Vector3f.YP.rotationDegrees( 180.0F ) );
break;
case SOUTH:
mStack.scale( -1.0f, -1.0f, -1.0f );
mStack.rotate( Vector3f.YP.rotationDegrees( 180.0F ) );
break;
default:
@@ -99,36 +86,38 @@ public class TesrRenderHelper
/**
* Render an item in 2D.
*/
public static void renderItem2d(MatrixStack matrixStack, IRenderTypeBuffer buffers, ItemStack itemStack, float scale)
public static void renderItem2d(MatrixStack matrixStack, IRenderTypeBuffer buffers, ItemStack itemStack, float scale, int combinedLightIn, int combinedOverlayIn)
{
if( !itemStack.isEmpty() )
{
// FIXME RenderSystem.glMultiTexCoord2f( GL13.GL_TEXTURE22, 240.f, 240.0f );
// FIXME RenderSystem.pushMatrix();
// FIXME // The Z-scaling by 0.0001 causes the model to be visually "flattened"
// FIXME // This cannot replace a proper projection, but it's cheap and gives the desired
// FIXME // effect at least from head-on
// FIXME RenderSystem.scaled( scale / 32.0f, scale / 32.0f, 0.0001f );
// FIXME // Position the item icon at the top middle of the panel
// FIXME RenderSystem.translated( -8, -11, 0 );
// FIXME ItemRenderer renderItem = Minecraft.getInstance().getItemRenderer();
// FIXME renderItem.renderItemAndEffectIntoGUI( itemStack, 0, 0 );
// FIXME RenderSystem.popMatrix();
matrixStack.push();
// Push it out of the block face a bit to avoid z-fighting
matrixStack.translate(0, 0, 0.01f);
// The Z-scaling by 0.0002 causes the model to be visually "flattened"
// This cannot replace a proper projection, but it's cheap and gives the desired
// effect at least from head-on
matrixStack.scale( scale, scale, 0.0002f );
Minecraft.getInstance().getItemRenderer().renderItem(itemStack, ItemCameraTransforms.TransformType.GUI, combinedLightIn, OverlayTexture.NO_OVERLAY, matrixStack, buffers);
matrixStack.pop();
}
}
/**
* Render an item in 2D and the given text below it.
*
* @param matrixStack
* @param matrixStack
* @param buffers
* @param spacing Specifies how far apart the item and the item stack amount are rendered.
* @param combinedLightIn
* @param combinedOverlayIn
*/
public static void renderItem2dWithAmount(MatrixStack matrixStack, IRenderTypeBuffer buffers, IAEItemStack itemStack, float itemScale, float spacing)
public static void renderItem2dWithAmount(MatrixStack matrixStack, IRenderTypeBuffer buffers, IAEItemStack itemStack, float itemScale, float spacing, int combinedLightIn, int combinedOverlayIn)
{
final ItemStack renderStack = itemStack.asItemStackRepresentation();
TesrRenderHelper.renderItem2d( matrixStack, buffers, renderStack, itemScale );
TesrRenderHelper.renderItem2d( matrixStack, buffers, renderStack, itemScale, combinedLightIn, combinedOverlayIn );
final long stackSize = itemStack.getStackSize();
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm( stackSize );
@@ -136,10 +125,14 @@ public class TesrRenderHelper
// Render the item count
final FontRenderer fr = Minecraft.getInstance().fontRenderer;
final int width = fr.getStringWidth( renderedStackSize );
matrixStack.translate( 0.0f, spacing, 0 );
matrixStack.scale( 1.0f / 62.0f, 1.0f / 62.0f, 1.0f / 62.0f );
matrixStack.push();
matrixStack.translate( 0.0f, spacing, 0.02f );
matrixStack.scale( 1.0f / 62.0f, - 1.0f / 62.0f, 1.0f / 62.0f );
matrixStack.scale(0.5f, 0.5f, 0);
matrixStack.translate( -0.5f * width, 0.0f, 0.5f );
fr.drawString( renderedStackSize, 0, 0, 0 );
fr.renderString(renderedStackSize, 0, 0, -1, false, matrixStack.getLast().getMatrix(), buffers, false, 0, 15728880);
matrixStack.pop();
}
}
@@ -20,6 +20,7 @@ package appeng.client.render.crafting;
import appeng.client.render.cablebus.CubeBuilder;
import appeng.tile.crafting.CraftingCubeModelData;
import appeng.tile.crafting.TileCraftingTile;
import appeng.util.Platform;
import net.minecraft.block.BlockState;
@@ -249,13 +250,11 @@ abstract class CraftingCubeBakedModel implements IDynamicBakedModel
// If none is present, just assume there are no adjacent crafting cube blocks
private static EnumSet<Direction> getConnections( IModelData modelData )
{
CraftingCubeState cubeState = modelData.getData( TileCraftingTile.STATE );
if( cubeState == null )
{
return EnumSet.noneOf( Direction.class );
if (!(modelData instanceof CraftingCubeModelData)) {
return EnumSet.noneOf(Direction.class);
}
return cubeState.getConnections();
return ((CraftingCubeModelData) modelData).getConnections();
}
protected abstract void addInnerCube(Direction facing, BlockState state, IModelData modelData, CubeBuilder builder, float x1, float y1, float z1, float x2, float y2, float z2);
@@ -19,13 +19,10 @@
package appeng.client.render.crafting;
import appeng.block.crafting.AbstractCraftingUnitBlock;
import appeng.bootstrap.BlockRenderingCustomizer;
import appeng.bootstrap.IBlockRendering;
import appeng.bootstrap.IItemRendering;
import appeng.core.AppEng;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@@ -35,62 +32,12 @@ import net.minecraftforge.api.distmarker.OnlyIn;
*/
public class CraftingCubeRendering extends BlockRenderingCustomizer
{
private final String registryName;
private final AbstractCraftingUnitBlock.CraftingUnitType type;
public CraftingCubeRendering( String registryName, AbstractCraftingUnitBlock.CraftingUnitType type )
{
this.registryName = registryName;
this.type = type;
}
@Override
@OnlyIn( Dist.CLIENT )
public void customize( IBlockRendering rendering, IItemRendering itemRendering )
{
if (type != AbstractCraftingUnitBlock.CraftingUnitType.MONITOR) {
rendering.renderType(RenderType.getCutout());
}
ResourceLocation baseName = new ResourceLocation( AppEng.MOD_ID, this.registryName );
rendering.renderType(RenderType.getCutout());
// Disable auto-rotation
if( this.type != AbstractCraftingUnitBlock.CraftingUnitType.MONITOR )
{
rendering.modelCustomizer( ( loc, model ) -> model );
}
// FIXME // This is the standard blockstate model
// FIXME ModelResourceLocation defaultModel = new ModelResourceLocation( baseName, "normal" );
// FIXME
// FIXME // This is the built-in model
// FIXME String builtInName = "models/block/crafting/" + this.registryName + "/builtin";
// FIXME ModelResourceLocation builtInModelName = new ModelResourceLocation( new ResourceLocation( AppEng.MOD_ID, builtInName ), "normal" );
// FIXME
// FIXME rendering.builtInModel( builtInName, new CraftingCubeModel( this.type ) );
// FIXME
// FIXME rendering.stateMapper( block -> this.mapState( block, defaultModel, builtInModelName ) );
rendering.modelCustomizer( ( loc, model ) -> model );
}
// FIXME private Map<BlockState, ModelResourceLocation> mapState( Block block, ModelResourceLocation defaultModel, ModelResourceLocation formedModel )
// FIXME {
// FIXME Map<BlockState, ModelResourceLocation> result = new HashMap<>();
// FIXME for( BlockState state : block.getBlockState().getValidStates() )
// FIXME {
// FIXME if( state.get( AbstractCraftingUnitBlock.FORMED ) )
// FIXME {
// FIXME // Always use the builtin model if the multiblock is formed
// FIXME result.put( state, formedModel );
// FIXME }
// FIXME else
// FIXME {
// FIXME // Use the default model
// FIXME result.put( state, defaultModel );
// FIXME }
// FIXME }
// FIXME return result;
// FIXME }
}
@@ -1,45 +0,0 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 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, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 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 Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.client.render.crafting;
import java.util.EnumSet;
import net.minecraft.util.Direction;
/**
* Transports the rendering state for a block of a crafting cube.
*/
public final class CraftingCubeState
{
// Contains information on which sides of the block are connected to other parts of a formed crafting cube
private final EnumSet<Direction> connections;
public CraftingCubeState( EnumSet<Direction> connections )
{
this.connections = connections;
}
public EnumSet<Direction> getConnections()
{
return this.connections;
}
}
@@ -19,17 +19,23 @@
package appeng.client.render.crafting;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.core.Api;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.registry.Registry;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.render.TesrRenderHelper;
import appeng.tile.crafting.TileCraftingMonitorTile;
import net.minecraftforge.registries.ForgeRegistries;
/**
@@ -49,14 +55,15 @@ public class CraftingMonitorTESR extends TileEntityRenderer<TileCraftingMonitorT
Direction facing = te.getForward();
IAEItemStack jobProgress = te.getJobProgress();
if( jobProgress != null )
{
matrixStack.push();
matrixStack.translate(0.5, 0.5, 0.5);
matrixStack.translate(0.5, 0.5, 0.5); // Move to the center of the block
TesrRenderHelper.moveToFace( matrixStack, facing );
TesrRenderHelper.rotateToFace( matrixStack, facing, (byte) 0 );
TesrRenderHelper.renderItem2dWithAmount(matrixStack, buffers, jobProgress, 0.7f, 0.1f );
matrixStack.translate(0, 0.08, 0.5);
TesrRenderHelper.renderItem2dWithAmount(matrixStack, buffers, jobProgress, 0.3f, -0.18f, 15728880, combinedOverlay);
matrixStack.pop();
}
@@ -22,7 +22,8 @@ package appeng.client.render.crafting;
import appeng.api.util.AEColor;
import appeng.block.crafting.BlockCraftingMonitor;
import appeng.client.render.cablebus.CubeBuilder;
import appeng.tile.crafting.TileCraftingMonitorTile;
import appeng.client.render.model.AEModelData;
import appeng.tile.crafting.CraftingMonitorModelData;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.Direction;
@@ -36,7 +37,7 @@ import net.minecraftforge.client.model.data.IModelData;
* color. The textures
* are full-bright if the cube is powered.
*/
class MonitorBakedModel extends CraftingCubeBakedModel
public class MonitorBakedModel extends CraftingCubeBakedModel
{
private final TextureAtlasSprite chassisTexture;
@@ -96,21 +97,16 @@ class MonitorBakedModel extends CraftingCubeBakedModel
}
private static AEColor getColor(IModelData modelData) {
AEColor color = modelData.getData(TileCraftingMonitorTile.COLOR);
if (color != null) {
return color;
if (modelData instanceof CraftingMonitorModelData) {
return ((CraftingMonitorModelData) modelData).getColor();
}
return AEColor.TRANSPARENT;
}
private static Direction getForward(IModelData modelData) {
Direction forward = modelData.getData(BlockCraftingMonitor.FORWARD);
if (forward != null) {
return forward;
if (modelData instanceof AEModelData) {
return ((AEModelData) modelData).getForward();
}
return Direction.NORTH;
}
}
@@ -0,0 +1,67 @@
package appeng.client.render.model;
import com.google.common.base.Preconditions;
import net.minecraft.util.Direction;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelProperty;
import javax.annotation.Nullable;
import java.util.Objects;
/**
* This implementation of IModelData allows us to know precisely which data is part of the
* model data. This is relevant for {@link AutoRotatingBakedModel} and {@link AutoRotatingCacheKey}.
*/
public class AEModelData implements IModelData {
private final Direction up;
private final Direction forward;
public AEModelData(Direction up, Direction forward) {
this.up = Preconditions.checkNotNull(up);
this.forward = Preconditions.checkNotNull(forward);
}
public Direction getUp() {
return up;
}
public Direction getForward() {
return forward;
}
public boolean isCacheable() {
return true;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AEModelData that = (AEModelData) o;
return up == that.up &&
forward == that.forward;
}
@Override
public int hashCode() {
return Objects.hash(up, forward);
}
@Override
public boolean hasProperty(ModelProperty<?> prop) {
return false;
}
@Nullable
@Override
public <T> T getData(ModelProperty<T> prop) {
throw new IllegalStateException();
}
@Nullable
@Override
public <T> T setData(ModelProperty<T> prop, T data) {
throw new IllegalStateException();
}
}
@@ -19,7 +19,6 @@
package appeng.client.render.model;
import appeng.block.AEBaseTileBlock;
import appeng.client.render.FacingToRotation;
import com.google.common.base.Objects;
import com.google.common.cache.CacheBuilder;
@@ -36,7 +35,9 @@ 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.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.ILightReader;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
@@ -63,17 +64,17 @@ public class AutoRotatingBakedModel implements IBakedModel
this.quadCache = CacheBuilder.newBuilder().maximumSize( 252 ).build( new CacheLoader<AutoRotatingCacheKey, List<BakedQuad>>()
{
@Override
public List<BakedQuad> load( AutoRotatingCacheKey key ) throws Exception
public List<BakedQuad> load( AutoRotatingCacheKey key )
{
return AutoRotatingBakedModel.this.getRotatedModel( key.getBlockState(), key.getSide(), key.getForward(), key.getUp() );
return AutoRotatingBakedModel.this.getRotatedModel( key.getBlockState(), key.getSide(), new Random(0), key.getModelData() );
}
} );
}
private List<BakedQuad> getRotatedModel( BlockState state, Direction side, Direction forward, Direction up )
private List<BakedQuad> getRotatedModel(BlockState state, Direction side, Random rand, AEModelData modelData)
{
FacingToRotation f2r = FacingToRotation.get( forward, up );
List<BakedQuad> original = AutoRotatingBakedModel.this.parent.getQuads( state, f2r.resultingRotate( side ), new Random(0) );
FacingToRotation f2r = FacingToRotation.get( modelData.getForward(), modelData.getUp() );
List<BakedQuad> original = AutoRotatingBakedModel.this.parent.getQuads( state, f2r.resultingRotate( side ), rand, modelData );
List<BakedQuad> rotated = new ArrayList<>( original.size() );
for( BakedQuad quad : original )
{
@@ -155,21 +156,23 @@ public class AutoRotatingBakedModel implements IBakedModel
@Override
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData) {
Direction forward = extraData.getData(AEBaseTileBlock.FORWARD);
Direction up = extraData.getData(AEBaseTileBlock.UP);
if( forward == null || up == null )
{
if (!(extraData instanceof AEModelData)) {
return this.parent.getQuads( state, side, rand, extraData );
}
// The model has other properties than just forward/up, so it would cause our cache to inadvertendly also cache
// these
// additional states, possibly leading to huge issues if the other extended state properties do not implement
// equals/hashCode correctly
// FIXME: IModelData does not expose a way for us to check if it only has the two properties and no other
return this.getRotatedModel( state, side, forward, up );
AEModelData aeModelData = (AEModelData) extraData;
if (aeModelData.isCacheable()) {
return quadCache.getUnchecked(new AutoRotatingCacheKey(state, aeModelData, side));
} else {
return this.getRotatedModel(state, side, rand, aeModelData);
}
}
@Nonnull
@Override
public IModelData getModelData(@Nonnull ILightReader world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull IModelData tileData) {
return this.parent.getModelData(world, pos, state, tileData);
}
public static class VertexRotator extends QuadGatheringTransformer
@@ -29,15 +29,13 @@ import net.minecraft.util.Direction;
final class AutoRotatingCacheKey
{
private final BlockState blockState;
private final Direction forward;
private final Direction up;
private final AEModelData modelData;
private final Direction side;
AutoRotatingCacheKey( BlockState blockState, Direction forward, Direction up, Direction side )
AutoRotatingCacheKey( BlockState blockState, AEModelData modelData, Direction side )
{
this.blockState = blockState;
this.forward = forward;
this.up = up;
this.modelData = modelData;
this.side = side;
}
@@ -46,14 +44,8 @@ final class AutoRotatingCacheKey
return this.blockState;
}
public Direction getForward()
{
return this.forward;
}
public Direction getUp()
{
return this.up;
public AEModelData getModelData() {
return modelData;
}
public Direction getSide()
@@ -74,15 +66,14 @@ final class AutoRotatingCacheKey
}
AutoRotatingCacheKey cacheKey = (AutoRotatingCacheKey) o;
return this.blockState.equals( cacheKey.blockState ) && this.forward == cacheKey.forward && this.up == cacheKey.up && this.side == cacheKey.side;
return this.blockState.equals( cacheKey.blockState ) && this.modelData.equals(cacheKey.modelData) && this.side == cacheKey.side;
}
@Override
public int hashCode()
{
int result = this.blockState.hashCode();
result = 31 * result + this.forward.hashCode();
result = 31 * result + this.up.hashCode();
result = 31 * result + this.modelData.hashCode();
result = 31 * result + ( this.side != null ? this.side.hashCode() : 0 );
return result;
}
@@ -57,7 +57,12 @@ public class DriveBakedModel extends DelegateBakedModel
List<BakedQuad> result = new ArrayList<>(this.bakedBase.getQuads(state, side, rand, extraData));
DriveSlotsState slotsState = extraData.getData( TileDrive.SLOTS_STATE );
if (!(extraData instanceof DriveModelData)) {
return result;
}
DriveModelData driveModelData = (DriveModelData) extraData;
DriveSlotsState slotsState = driveModelData.getSlotsState();
if( side == null && slotsState != null )
{
@@ -20,7 +20,9 @@ package appeng.client.render.model;
import appeng.block.storage.DriveSlotState;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.renderer.model.*;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@@ -43,6 +45,11 @@ public class DriveModel implements IModelGeometry<DriveModel>
DriveSlotState.TYPES_FULL, new ResourceLocation( "appliedenergistics2:block/drive_cell_types_full" ),
DriveSlotState.FULL, new ResourceLocation( "appliedenergistics2:block/drive_cell_full" ) );
public static final Set<ResourceLocation> DEPENDENCIES = ImmutableSet.<ResourceLocation>builder()
.addAll(MODELS_CELLS.values())
.add(MODEL_BASE)
.build();
@Override
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation) {
EnumMap<DriveSlotState, IBakedModel> cellModels = new EnumMap<>( DriveSlotState.class );
@@ -0,0 +1,44 @@
package appeng.client.render.model;
import appeng.block.storage.DriveSlotsState;
import com.google.common.base.Preconditions;
import net.minecraft.util.Direction;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelProperty;
import javax.annotation.Nullable;
import java.util.Objects;
public class DriveModelData extends AEModelData {
private final DriveSlotsState slotsState;
public DriveModelData(Direction up, Direction forward, DriveSlotsState slotsState) {
super(up, forward);
this.slotsState = slotsState;
}
@Override
public boolean isCacheable() {
return false; // Too many combinations
}
public DriveSlotsState getSlotsState() {
return slotsState;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
DriveModelData that = (DriveModelData) o;
return slotsState.equals(that.slotsState);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), slotsState);
}
}
+3 -3
View File
@@ -73,6 +73,7 @@ import appeng.client.gui.implementations.GuiWireless;
import appeng.client.gui.implementations.GuiWirelessTerm;
import appeng.client.render.effects.*;
import appeng.client.render.model.BiometricCardModel;
import appeng.client.render.model.DriveModel;
import appeng.client.render.model.MemoryCardModel;
import appeng.client.render.model.SkyCompassModel;
import appeng.client.render.tesr.SkyChestTESR;
@@ -274,11 +275,10 @@ final class Registration
*/
@OnlyIn(Dist.CLIENT)
private void registerSpecialModels() {
for (ResourceLocation dependency : SkyCompassModel.DEPENDENCIES) {
ModelLoader.addSpecialModel(dependency);
}
SkyCompassModel.DEPENDENCIES.forEach(ModelLoader::addSpecialModel);
ModelLoader.addSpecialModel(BiometricCardModel.MODEL_BASE);
ModelLoader.addSpecialModel(MemoryCardModel.MODEL_BASE);
DriveModel.DEPENDENCIES.forEach(ModelLoader::addSpecialModel);
}
public void registerBlocks( RegistryEvent.Register<Block> event )
@@ -43,6 +43,9 @@ import appeng.bootstrap.components.IEntityRegistrationComponent;
import appeng.bootstrap.components.IInitComponent;
import appeng.bootstrap.definitions.TileEntityDefinition;
import appeng.client.render.crafting.CraftingCubeRendering;
import appeng.client.render.crafting.CraftingMonitorTESR;
import appeng.client.render.crafting.MonitorBakedModel;
import appeng.client.render.model.AutoRotatingBakedModel;
import appeng.client.render.spatial.SpatialPylonRendering;
import appeng.client.render.tesr.CrankTESR;
import appeng.client.render.tesr.SkyChestTESR;
@@ -427,11 +430,11 @@ public final class ApiBlocks implements IBlocks
FeatureFactory crafting = registry.features( AEFeature.CRAFTING_CPU );
Block.Properties craftingBlockProps = Block.Properties.create(Material.IRON);
this.craftingUnit = crafting.block( "crafting_unit", () -> new CraftingUnitBlock( craftingBlockProps, CraftingUnitType.UNIT ) )
.rendering( new CraftingCubeRendering( "crafting_unit", CraftingUnitType.UNIT ) )
.rendering( new CraftingCubeRendering() )
.tileEntity( craftingUnit )
.build();
this.craftingAccelerator = crafting.block( "crafting_accelerator", () -> new CraftingUnitBlock( craftingBlockProps, CraftingUnitType.ACCELERATOR ) )
.rendering( new CraftingCubeRendering( "crafting_accelerator", CraftingUnitType.ACCELERATOR ) )
.rendering( new CraftingCubeRendering() )
.tileEntity( craftingUnit )
.build();
@@ -440,22 +443,22 @@ public final class ApiBlocks implements IBlocks
this.craftingStorage1k = crafting.block( "crafting_storage_1k", () -> new BlockCraftingStorage( craftingBlockProps, CraftingUnitType.STORAGE_1K ) )
.item( ItemCraftingStorage::new )
.tileEntity(craftingStorage)
.rendering( new CraftingCubeRendering( "crafting_storage_1k", CraftingUnitType.STORAGE_1K ) )
.rendering( new CraftingCubeRendering() )
.build();
this.craftingStorage4k = crafting.block( "crafting_storage_4k", () -> new BlockCraftingStorage( craftingBlockProps, CraftingUnitType.STORAGE_4K ) )
.item( ItemCraftingStorage::new )
.tileEntity(craftingStorage)
.rendering( new CraftingCubeRendering( "crafting_storage_4k", CraftingUnitType.STORAGE_4K ) )
.rendering( new CraftingCubeRendering() )
.build();
this.craftingStorage16k = crafting.block( "crafting_storage_16k", () -> new BlockCraftingStorage( craftingBlockProps, CraftingUnitType.STORAGE_16K ) )
.item( ItemCraftingStorage::new )
.tileEntity(craftingStorage)
.rendering( new CraftingCubeRendering( "crafting_storage_16k", CraftingUnitType.STORAGE_16K ) )
.rendering( new CraftingCubeRendering() )
.build();
this.craftingStorage64k = crafting.block( "crafting_storage_64k", () -> new BlockCraftingStorage( craftingBlockProps, CraftingUnitType.STORAGE_64K ) )
.item( ItemCraftingStorage::new )
.tileEntity(craftingStorage)
.rendering( new CraftingCubeRendering( "crafting_storage_64k", CraftingUnitType.STORAGE_64K ) )
.rendering( new CraftingCubeRendering() )
.build();
this.craftingMonitor = crafting.block( "crafting_monitor", () -> new BlockCraftingMonitor(craftingBlockProps) )
.tileEntity( registry.tileEntity("crafting_monitor", TileCraftingMonitorTile.class, TileCraftingMonitorTile::new)
@@ -463,11 +466,24 @@ public final class ApiBlocks implements IBlocks
@OnlyIn(Dist.CLIENT)
@Override
public void customize(TileEntityRendering<TileCraftingMonitorTile> rendering) {
// FIXME rendering.tileEntityRenderer(CraftingMonitorTESR::new);
rendering.tileEntityRenderer(CraftingMonitorTESR::new);
}
})
.build() )
.rendering( new CraftingCubeRendering( "crafting_monitor", CraftingUnitType.MONITOR ) )
.rendering(new BlockRenderingCustomizer() {
@Override
@OnlyIn(Dist.CLIENT)
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
rendering.renderType(RenderType.getCutout());
rendering.modelCustomizer((path, model) -> {
// The formed model handles rotations itself, the unformed one does not
if (model instanceof MonitorBakedModel) {
return model;
}
return new AutoRotatingBakedModel(model);
});
}
})
.build();
this.molecularAssembler = registry.block( "molecular_assembler", () -> new BlockMolecularAssembler(Block.Properties.create(Material.IRON).notSolid()) )
@@ -268,13 +268,12 @@ public abstract class AbstractPartMonitor extends AbstractPartDisplay implements
}
matrixStack.push();
matrixStack.translate( 0.5, 0.5, 0.5 );
matrixStack.translate( 0.5, 0.5, 0.5 ); // Move into the center of the block
Direction facing = this.getSide().getFacing();
TesrRenderHelper.moveToFace( matrixStack, facing );
TesrRenderHelper.rotateToFace( matrixStack, facing, this.getSpin() );
TesrRenderHelper.renderItem2dWithAmount(matrixStack, buffers, ais, 0.8f, 0.17f );
TesrRenderHelper.renderItem2dWithAmount(matrixStack, buffers, ais, 0.8f, 0.17f, combinedLightIn, combinedOverlayIn );
matrixStack.pop();
+2 -4
View File
@@ -25,6 +25,7 @@ import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.api.util.IOrientable;
import appeng.block.AEBaseTileBlock;
import appeng.client.render.model.AEModelData;
import appeng.core.AELog;
import appeng.core.features.IStackSrc;
import appeng.helpers.ICustomNameObject;
@@ -521,10 +522,7 @@ public class AEBaseTile extends TileEntity implements IOrientable, ICommonTile,
@Nonnull
@Override
public IModelData getModelData() {
return new ModelDataMap.Builder()
.withInitial(AEBaseTileBlock.UP, up)
.withInitial(AEBaseTileBlock.FORWARD, forward)
.build();
return new AEModelData(up, forward);
}
}
@@ -0,0 +1,43 @@
package appeng.tile.crafting;
import appeng.client.render.model.AEModelData;
import com.google.common.base.Preconditions;
import net.minecraft.util.Direction;
import java.util.EnumSet;
import java.util.Objects;
public class CraftingCubeModelData extends AEModelData {
// Contains information on which sides of the block are connected to other parts of a formed crafting cube
private final EnumSet<Direction> connections;
public CraftingCubeModelData(Direction up, Direction forward, EnumSet<Direction> connections) {
super(up, forward);
this.connections = Preconditions.checkNotNull(connections);
}
@Override
public boolean isCacheable() {
return false; // Too many variants
}
public EnumSet<Direction> getConnections() {
return connections;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
CraftingCubeModelData that = (CraftingCubeModelData) o;
return connections.equals(that.connections);
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), connections);
}
}
@@ -0,0 +1,37 @@
package appeng.tile.crafting;
import appeng.api.util.AEColor;
import com.google.common.base.Preconditions;
import net.minecraft.util.Direction;
import java.util.EnumSet;
import java.util.Objects;
public class CraftingMonitorModelData extends CraftingCubeModelData {
private final AEColor color;
public CraftingMonitorModelData(Direction up, Direction forward, EnumSet<Direction> connections, AEColor color) {
super(up, forward, connections);
this.color = Preconditions.checkNotNull(color);
}
public AEColor getColor() {
return color;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
CraftingMonitorModelData that = (CraftingMonitorModelData) o;
return color == that.color;
}
@Override
public int hashCode() {
return Objects.hash(super.hashCode(), color);
}
}
@@ -22,7 +22,6 @@ package appeng.tile.crafting;
import java.io.IOException;
import java.util.Optional;
import appeng.block.AEBaseTileBlock;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
@@ -38,8 +37,6 @@ import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.AEColor;
import appeng.util.item.AEItemStack;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelProperty;
import javax.annotation.Nonnull;
@@ -47,8 +44,6 @@ import javax.annotation.Nonnull;
public class TileCraftingMonitorTile extends TileCraftingTile implements IColorableTile
{
public static final ModelProperty<AEColor> COLOR = new ModelProperty<>();
@OnlyIn( Dist.CLIENT )
private Integer dspList;
@@ -204,11 +199,7 @@ public class TileCraftingMonitorTile extends TileCraftingTile implements IColora
@Nonnull
@Override
public IModelData getModelData() {
return new ModelDataMap.Builder()
.withInitial(AEBaseTileBlock.FORWARD, getForward())
.withInitial(AEBaseTileBlock.UP, getUp())
.withInitial(COLOR, getColor())
.build();
return new CraftingMonitorModelData(getUp(), getForward(), getConnections(), getColor());
}
}
@@ -25,7 +25,6 @@ import java.util.Iterator;
import java.util.LinkedList;
import java.util.Optional;
import appeng.client.render.crafting.CraftingCubeState;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
@@ -61,7 +60,7 @@ import net.minecraft.world.IBlockReader;
import net.minecraftforge.client.model.data.EmptyModelData;
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.util.Constants;
import javax.annotation.Nonnull;
@@ -69,8 +68,6 @@ import javax.annotation.Nonnull;
public class TileCraftingTile extends AENetworkTile implements IAEMultiBlock, IPowerChannelState
{
public static final ModelProperty<CraftingCubeState> STATE = new ModelProperty<>();
private final CraftingCPUCalculator calc = new CraftingCPUCalculator( this );
private CompoundNBT previousState = null;
private boolean isCoreBlock = false;
@@ -183,7 +180,7 @@ public class TileCraftingTile extends AENetworkTile implements IAEMultiBlock, IP
{
// Not using flag 2 here (only send to clients, prevent block update) will cause infinite loops
// In case there is an inconsistency in the crafting clusters.
this.world.setBlockState( this.pos, newState, 2 );
this.world.setBlockState( this.pos, newState, Constants.BlockFlags.BLOCK_UPDATE);
}
}
@@ -394,12 +391,15 @@ public class TileCraftingTile extends AENetworkTile implements IAEMultiBlock, IP
this.previousState = previousState;
}
// FIXME: REMOVE AND MOVE TO IDynamicBakedModel!
@Nonnull
@Override
public IModelData getModelData() {
return new CraftingCubeModelData(getUp(), getForward(), getConnections());
}
protected EnumSet<Direction> getConnections() {
if (world == null) {
return EmptyModelData.INSTANCE;
return EnumSet.noneOf(Direction.class);
}
EnumSet<Direction> connections = EnumSet.noneOf( Direction.class );
@@ -412,9 +412,7 @@ public class TileCraftingTile extends AENetworkTile implements IAEMultiBlock, IP
}
}
return new ModelDataMap.Builder()
.withInitial(STATE, new CraftingCubeState( connections ))
.build();
return connections;
}
private boolean isConnected( IBlockReader world, BlockPos pos, Direction side )
@@ -423,4 +421,14 @@ public class TileCraftingTile extends AENetworkTile implements IAEMultiBlock, IP
return world.getBlockState( adjacentPos ).getBlock() instanceof AbstractCraftingUnitBlock;
}
/**
* When the block state changes (i.e. becoming formed or unformed), we need to update the
* model data since it contains connections to neighboring tiles.
*/
@Override
public void updateContainingBlockInfo() {
super.updateContainingBlockInfo();
requestModelDataUpdate();
}
}
@@ -29,6 +29,7 @@ import java.util.Map;
import appeng.block.AEBaseTileBlock;
import appeng.block.storage.DriveSlotsState;
import appeng.client.render.model.DriveModelData;
import appeng.container.implementations.ContainerDrive;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.item.ItemStack;
@@ -76,8 +77,6 @@ import javax.annotation.Nonnull;
public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPriorityHost
{
public static final ModelProperty<DriveSlotsState> SLOTS_STATE = new ModelProperty<>();
private static final int BIT_POWER_MASK = 0x80000000;
private static final int BIT_BLINK_MASK = 0x24924924;
private static final int BIT_STATE_MASK = 0xDB6DB6DB;
@@ -419,13 +418,7 @@ public class TileDrive extends AENetworkInvTile implements IChestOrDrive, IPrior
@Nonnull
@Override
public IModelData getModelData() {
return new ModelDataMap.Builder()
.withInitial(AEBaseTileBlock.UP, getUp())
.withInitial(AEBaseTileBlock.FORWARD, getForward())
.withInitial(SLOTS_STATE, DriveSlotsState.fromChestOrDrive( this ))
.build();
return new DriveModelData(getUp(), getForward(), DriveSlotsState.fromChestOrDrive( this ));
}
@Override
@@ -1,7 +1,10 @@
{
"variants": {
"": {
"formed=false": {
"model": "appliedenergistics2:block/crafting/accelerator"
},
"formed=true": {
"model": "appliedenergistics2:block/crafting/accelerator_formed"
}
}
}
@@ -1,7 +1,10 @@
{
"variants": {
"": {
"formed=false": {
"model": "appliedenergistics2:block/crafting/monitor"
},
"formed=true": {
"model": "appliedenergistics2:block/crafting/monitor_formed"
}
}
}
@@ -1,7 +1,10 @@
{
"variants": {
"": {
"formed=false": {
"model": "appliedenergistics2:block/crafting/storage_16k"
},
"formed=true": {
"model": "appliedenergistics2:block/crafting/storage_16k_formed"
}
}
}
@@ -1,7 +1,10 @@
{
"variants": {
"": {
"formed=false": {
"model": "appliedenergistics2:block/crafting/storage_1k"
},
"formed=true": {
"model": "appliedenergistics2:block/crafting/storage_1k_formed"
}
}
}
@@ -1,7 +1,10 @@
{
"variants": {
"": {
"formed=false": {
"model": "appliedenergistics2:block/crafting/storage_4k"
},
"formed=true": {
"model": "appliedenergistics2:block/crafting/storage_4k_formed"
}
}
}
@@ -1,7 +1,10 @@
{
"variants": {
"": {
"formed=false": {
"model": "appliedenergistics2:block/crafting/storage_64k"
},
"formed=true": {
"model": "appliedenergistics2:block/crafting/storage_64k_formed"
}
}
}
@@ -1,7 +1,10 @@
{
"variants": {
"": {
"formed=false": {
"model": "appliedenergistics2:block/crafting/unit"
},
"formed=true": {
"model": "appliedenergistics2:block/crafting/unit_formed"
}
}
}
@@ -1,7 +1,7 @@
{
"variants": {
"": {
"model": "appliedenergistics2:block/builtin/drive"
"model": "appliedenergistics2:block/drive"
}
}
}
@@ -1,15 +1,17 @@
{
"forge_marker": 1,
"defaults": {
"model": "appliedenergistics2:block/molecular_assembler"
},
"variants": {
"powered": {
"false": {
"multipart": [
{
"apply": {
"model":"appliedenergistics2:block/molecular_assembler"
}
},
{
"when": {
"powered": "true"
},
"true": {
"submodel": "appliedenergistics2:molecular_assembler_lights"
"apply": {
"model":"appliedenergistics2:block/molecular_assembler_lights"
}
}
}
}
]
}
@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "appliedenergistics2:block/spatial_pylon"
}
}
}
@@ -0,0 +1,4 @@
{
"loader": "appliedenergistics2:crafting_cube",
"type": "accelerator"
}
@@ -0,0 +1,4 @@
{
"loader": "appliedenergistics2:crafting_cube",
"type": "monitor"
}
@@ -0,0 +1,4 @@
{
"loader": "appliedenergistics2:crafting_cube",
"type": "storage_16k"
}
@@ -0,0 +1,4 @@
{
"loader": "appliedenergistics2:crafting_cube",
"type": "storage_1k"
}
@@ -0,0 +1,4 @@
{
"loader": "appliedenergistics2:crafting_cube",
"type": "storage_4k"
}
@@ -0,0 +1,4 @@
{
"loader": "appliedenergistics2:crafting_cube",
"type": "storage_64k"
}
@@ -0,0 +1,4 @@
{
"loader": "appliedenergistics2:crafting_cube",
"type": "unit"
}
@@ -0,0 +1,3 @@
{
"loader": "appliedenergistics2:drive"
}
@@ -0,0 +1,3 @@
{
"loader": "appliedenergistics2:spatial_pylon"
}