Lots more moved
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.AffineTransformation;
|
||||
import net.minecraft.client.render.Tessellator;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.util.ISlimReadableNumberConverter;
|
||||
import appeng.util.IWideReadableNumberConverter;
|
||||
import appeng.util.ReadableNumberConverter;
|
||||
|
||||
/**
|
||||
* @author AlgorithmX2
|
||||
* @author thatsIch
|
||||
* @version rv2
|
||||
* @since rv0
|
||||
*/
|
||||
public class StackSizeRenderer {
|
||||
private static final ISlimReadableNumberConverter SLIM_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
private static final IWideReadableNumberConverter WIDE_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
|
||||
public void renderStackSize(TextRenderer fontRenderer, IAEItemStack aeStack, int xPos, int yPos) {
|
||||
if (aeStack != null) {
|
||||
if (aeStack.getStackSize() == 0 && aeStack.isCraftable()) {
|
||||
final String craftLabelText = AEConfig.instance().isUseLargeFonts() ? GuiText.LargeFontCraft.getLocal()
|
||||
: GuiText.SmallFontCraft.getLocal();
|
||||
|
||||
renderSizeLabel(fontRenderer, xPos, yPos, craftLabelText);
|
||||
}
|
||||
|
||||
if (aeStack.getStackSize() > 0) {
|
||||
final String stackSize = this.getToBeRenderedStackSize(aeStack.getStackSize());
|
||||
|
||||
renderSizeLabel(fontRenderer, xPos, yPos, stackSize);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void renderSizeLabel(TextRenderer fontRenderer, float xPos, float yPos, String text) {
|
||||
|
||||
final float scaleFactor = AEConfig.instance().isUseLargeFonts() ? 0.85f : 0.5f;
|
||||
final float inverseScaleFactor = 1.0f / scaleFactor;
|
||||
final int offset = AEConfig.instance().isUseLargeFonts() ? 0 : -1;
|
||||
|
||||
AffineTransformation tm = new AffineTransformation(new Vector3f(0, 0, 300), // Taken from
|
||||
// ItemRenderer.renderItemOverlayIntoGUI
|
||||
null, new Vector3f(scaleFactor, scaleFactor, scaleFactor), null);
|
||||
|
||||
RenderSystem.disableBlend();
|
||||
final int X = (int) ((xPos + offset + 16.0f - fontRenderer.getWidth(text) * scaleFactor)
|
||||
* inverseScaleFactor);
|
||||
final int Y = (int) ((yPos + offset + 16.0f - 7.0f * scaleFactor) * inverseScaleFactor);
|
||||
VertexConsumerProvider.Immediate buffer = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
|
||||
fontRenderer.draw(text, X, Y, 16777215, true, tm.getMatrix(), buffer, false, 0, 15728880);
|
||||
buffer.draw();
|
||||
RenderSystem.enableBlend();
|
||||
}
|
||||
|
||||
private String getToBeRenderedStackSize(final long originalSize) {
|
||||
if (AEConfig.instance().isUseLargeFonts()) {
|
||||
return SLIM_CONVERTER.toSlimReadableForm(originalSize);
|
||||
} else {
|
||||
return WIDE_CONVERTER.toWideReadableForm(originalSize);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.color.block.BlockColorProvider;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
import appeng.api.util.AEColor;
|
||||
|
||||
/**
|
||||
* Returns the shades of a single AE color for tint indices 0, 1, and 2.
|
||||
*/
|
||||
public class StaticBlockColor implements BlockColorProvider {
|
||||
|
||||
private final AEColor color;
|
||||
|
||||
public StaticBlockColor(AEColor color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor(BlockState state, @Nullable BlockRenderView worldIn, @Nullable BlockPos pos, int tintIndex) {
|
||||
return this.color.getVariantByTintIndex(tintIndex);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
import appeng.util.IWideReadableNumberConverter;
|
||||
import appeng.util.ReadableNumberConverter;
|
||||
|
||||
/**
|
||||
* Helper methods for rendering TESRs.
|
||||
*/
|
||||
public class TesrRenderHelper {
|
||||
|
||||
private static final IWideReadableNumberConverter NUMBER_CONVERTER = ReadableNumberConverter.INSTANCE;
|
||||
|
||||
/**
|
||||
* 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 a 2D canvas.
|
||||
*/
|
||||
public static void rotateToFace(MatrixStack mStack, Direction face, byte spin) {
|
||||
switch (face) {
|
||||
case UP:
|
||||
mStack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(270));
|
||||
mStack.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(-spin * 90.0F));
|
||||
break;
|
||||
|
||||
case DOWN:
|
||||
mStack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(90.0F));
|
||||
mStack.multiply(Vector3f.POSITIVE_Z.getDegreesQuaternion(spin * -90.0F));
|
||||
break;
|
||||
|
||||
case EAST:
|
||||
mStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(90.0F));
|
||||
break;
|
||||
|
||||
case WEST:
|
||||
mStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(-90.0F));
|
||||
break;
|
||||
|
||||
case NORTH:
|
||||
mStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(180.0F));
|
||||
break;
|
||||
|
||||
case SOUTH:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO, A different approach will have to be used for this from TESRs, -covers,
|
||||
// i have ideas.
|
||||
/**
|
||||
* Render an item in 2D.
|
||||
*/
|
||||
public static void renderItem2d(MatrixStack matrixStack, VertexConsumerProvider buffers, ItemStack itemStack,
|
||||
float scale, int combinedLightIn, int combinedOverlayIn) {
|
||||
if (!itemStack.isEmpty()) {
|
||||
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);
|
||||
|
||||
MinecraftClient.getInstance().getItemRenderer().renderItem(itemStack, ModelTransformation.Mode.GUI,
|
||||
combinedLightIn, OverlayTexture.DEFAULT_UV, matrixStack, buffers);
|
||||
|
||||
matrixStack.pop();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render an item in 2D and the given text below it.
|
||||
*
|
||||
* @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, VertexConsumerProvider buffers,
|
||||
IAEItemStack itemStack, float itemScale, float spacing, int combinedLightIn, int combinedOverlayIn) {
|
||||
final ItemStack renderStack = itemStack.asItemStackRepresentation();
|
||||
|
||||
TesrRenderHelper.renderItem2d(matrixStack, buffers, renderStack, itemScale, combinedLightIn, combinedOverlayIn);
|
||||
|
||||
final long stackSize = itemStack.getStackSize();
|
||||
final String renderedStackSize = NUMBER_CONVERTER.toWideReadableForm(stackSize);
|
||||
|
||||
// Render the item count
|
||||
final TextRenderer fr = MinecraftClient.getInstance().textRenderer;
|
||||
final int width = fr.getWidth(renderedStackSize);
|
||||
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.draw(renderedStackSize, 0, 0, -1, false, matrixStack.peek().getModel(), buffers, false, 0,
|
||||
15728880);
|
||||
matrixStack.pop();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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 net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.fabricmc.api.EnvType;
|
||||
|
||||
import appeng.bootstrap.BlockRenderingCustomizer;
|
||||
import appeng.bootstrap.IBlockRendering;
|
||||
import appeng.bootstrap.IItemRendering;
|
||||
|
||||
/**
|
||||
* Rendering customization for the crafting cube.
|
||||
*/
|
||||
public class CraftingCubeRendering extends BlockRenderingCustomizer {
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
|
||||
rendering.renderType(RenderLayer.getCutout());
|
||||
// Disable auto-rotation
|
||||
rendering.modelCustomizer((loc, model) -> model);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
import appeng.block.storage.DriveSlotsState;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.renderable;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.render.model.json.Transformation;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ItemRenderable<T extends BlockEntity> implements Renderable<T> {
|
||||
|
||||
private final Function<T, Pair<ItemStack, Transformation>> f;
|
||||
|
||||
public ItemRenderable(Function<T, Pair<ItemStack, Transformation>> f) {
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTileEntityAt(T te, float partialTicks, net.minecraft.client.util.math.MatrixStack matrixStack,
|
||||
VertexConsumerProvider buffers, int combinedLight, int combinedOverlay) {
|
||||
Pair<ItemStack, Transformation> pair = this.f.apply(te);
|
||||
if (pair != null && pair.getLeft() != null) {
|
||||
matrixStack.push();
|
||||
if (pair.getRight() != null) {
|
||||
pair.getRight().apply(true, matrixStack); // FIXME: check left handed
|
||||
}
|
||||
MinecraftClient.getInstance().getItemRenderer().renderItem(pair.getLeft(),
|
||||
ModelTransformation.Mode.GROUND, combinedLight, combinedOverlay, matrixStack, buffers);
|
||||
matrixStack.pop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.renderable;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
|
||||
public interface Renderable<T extends BlockEntity> {
|
||||
|
||||
void renderTileEntityAt(T te, float partialTicks, MatrixStack matrixStack, VertexConsumerProvider buffers,
|
||||
int combinedLight, int combinedOverlay);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.spatial;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import appeng.bootstrap.BlockRenderingCustomizer;
|
||||
import appeng.bootstrap.IBlockRendering;
|
||||
import appeng.bootstrap.IItemRendering;
|
||||
|
||||
public class SpatialPylonRendering extends BlockRenderingCustomizer {
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
|
||||
rendering.renderType(RenderLayer.getCutout());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.tesr;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.TexturedRenderLayers;
|
||||
import net.minecraft.client.render.block.BlockRenderManager;
|
||||
import net.minecraft.util.math.Quaternion;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import appeng.tile.grindstone.CrankBlockEntity;
|
||||
|
||||
/**
|
||||
* This FastTESR only handles the animated model of the turning crank. When the
|
||||
* crank is at rest, it is rendered using a normal model.
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class CrankTESR extends BlockEntityRenderer<CrankBlockEntity> {
|
||||
|
||||
public CrankTESR(BlockEntityRenderDispatcher rendererDispatcherIn) {
|
||||
super(rendererDispatcherIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(CrankBlockEntity te, float partialTicks, MatrixStack ms, VertexConsumerProvider buffers,
|
||||
int combinedLightIn, int combinedOverlayIn) {
|
||||
|
||||
// Apply GL transformations relative to the center of the block: 1) TE rotation
|
||||
// and 2) crank rotation
|
||||
ms.push();
|
||||
ms.translate(0.5, 0.5, 0.5);
|
||||
FacingToRotation.get(te.getForward(), te.getUp()).push(ms);
|
||||
ms.multiply(new Quaternion(0, te.getVisibleRotation(), 0, true));
|
||||
ms.translate(-0.5, -0.5, -0.5);
|
||||
|
||||
BlockState blockState = te.getCachedState();
|
||||
BlockRenderManager dispatcher = MinecraftClient.getInstance().getBlockRenderManager();
|
||||
BakedModel model = dispatcher.getModel(blockState);
|
||||
VertexConsumer buffer = buffers.getBuffer(TexturedRenderLayers.getEntityTranslucentCull());
|
||||
dispatcher.getModelRenderer().render(ms.peek(), buffer, null, model, 1, 1, 1,
|
||||
combinedLightIn, combinedOverlayIn);
|
||||
ms.pop();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
package appeng.client.render.tesr;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import appeng.block.storage.DriveSlotState;
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import appeng.tile.storage.DriveBlockEntity;
|
||||
|
||||
/**
|
||||
* Renders the drive cell status indicators.
|
||||
*/
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class DriveLedTileEntityRenderer extends BlockEntityRenderer<DriveBlockEntity> {
|
||||
|
||||
private static final EnumMap<DriveSlotState, Vector3f> STATE_COLORS;
|
||||
|
||||
// Color used for the cell indicator for blinking during recent activity
|
||||
private static final Vector3f BLINK_COLOR = new Vector3f(1, 0.5f, 0.5f);
|
||||
|
||||
static {
|
||||
STATE_COLORS = new EnumMap<>(DriveSlotState.class);
|
||||
STATE_COLORS.put(DriveSlotState.OFFLINE, new Vector3f(0, 0, 0));
|
||||
STATE_COLORS.put(DriveSlotState.ONLINE, new Vector3f(0, 1, 0));
|
||||
STATE_COLORS.put(DriveSlotState.NOT_EMPTY, new Vector3f(0f, 0.667f, 1));
|
||||
STATE_COLORS.put(DriveSlotState.TYPES_FULL, new Vector3f(1, 0.667f, 0));
|
||||
STATE_COLORS.put(DriveSlotState.FULL, new Vector3f(1, 0, 0));
|
||||
}
|
||||
|
||||
private static final float L = 14 / 16.f; // left (x-axis)
|
||||
private static final float R = 13 / 16.f; // right (x-axis)
|
||||
private static final float T = 14 / 16.f; // top (x-axis)
|
||||
private static final float B = 12.999f / 16.f; // bottom (x-axis)
|
||||
private static final float FR = 0.999f / 16.f; // front (z-axis)
|
||||
private static final float BA = 1.499f / 16.f; // back (z-axis)
|
||||
|
||||
// Vertex data for the LED cuboid (has no back)
|
||||
// Directions are when looking from the front onto the LED
|
||||
private static final float[] LED_QUADS = {
|
||||
// Front Face
|
||||
R, T, FR, L, T, FR, L, B, FR, R, B, FR,
|
||||
// Left Face
|
||||
L, T, FR, L, T, BA, L, B, BA, L, B, FR,
|
||||
// Right Face
|
||||
R, T, BA, R, T, FR, R, B, FR, R, B, BA,
|
||||
// Top Face
|
||||
R, T, BA, L, T, BA, L, T, FR, R, T, FR,
|
||||
// Bottom Face
|
||||
R, B, FR, L, B, FR, L, B, BA, R, B, BA, };
|
||||
|
||||
private static final RenderLayer STATE = RenderLayer.of("ae_drive_leds", VertexFormats.POSITION_COLOR, 7,
|
||||
32565, false, true, RenderLayer.MultiPhaseParameters.builder().build(false));
|
||||
|
||||
public DriveLedTileEntityRenderer(BlockEntityRenderDispatcher rendererDispatcherIn) {
|
||||
super(rendererDispatcherIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(DriveBlockEntity drive, float partialTicks, MatrixStack ms, VertexConsumerProvider buffers,
|
||||
int combinedLightIn, int combinedOverlayIn) {
|
||||
|
||||
if (drive.getCellCount() != 10) {
|
||||
throw new IllegalStateException("Expected drive to have 10 slots");
|
||||
}
|
||||
|
||||
ms.push();
|
||||
ms.translate(0.5, 0.5, 0.5);
|
||||
FacingToRotation.get(drive.getForward(), drive.getUp()).push(ms);
|
||||
ms.translate(-0.5, -0.5, -0.5);
|
||||
|
||||
VertexConsumer buffer = buffers.getBuffer(STATE);
|
||||
|
||||
for (int row = 0; row < 5; row++) {
|
||||
for (int col = 0; col < 2; col++) {
|
||||
int slot = row * 2 + col;
|
||||
Vector3f color = getColorForSlot(drive, slot, partialTicks);
|
||||
if (color == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ms.push();
|
||||
|
||||
// Position this drive model copy at the correct slot. The transform is based on
|
||||
// the
|
||||
// cell-model being in slot 0,0 at the top left of the drive.
|
||||
float xOffset = -col * 8 / 16.0f;
|
||||
float yOffset = -row * 3 / 16.0f;
|
||||
ms.translate(xOffset, yOffset, 0);
|
||||
|
||||
for (int i = 0; i < LED_QUADS.length; i += 3) {
|
||||
float x = LED_QUADS[i];
|
||||
float y = LED_QUADS[i + 1];
|
||||
float z = LED_QUADS[i + 2];
|
||||
buffer.vertex(ms.peek().getModel(), x, y, z).color(color.getX(), color.getY(), color.getZ(), 1.f)
|
||||
.next();
|
||||
}
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
}
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
private Vector3f getColorForSlot(DriveBlockEntity drive, int slot, float partialTicks) {
|
||||
DriveSlotState state = DriveSlotState.fromCellStatus(drive.getCellStatus(slot));
|
||||
if (state == DriveSlotState.EMPTY) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!drive.isPowered()) {
|
||||
return STATE_COLORS.get(DriveSlotState.OFFLINE);
|
||||
}
|
||||
|
||||
Vector3f col = STATE_COLORS.get(state);
|
||||
if (drive.isCellBlinking(slot)) {
|
||||
// 200 ms interval (100ms to get to red, then 100ms back)
|
||||
long t = System.currentTimeMillis() % 200;
|
||||
float f = (t - 100) / 200.0f + 0.5f;
|
||||
f = easeInOutCubic(f);
|
||||
col = col.copy();
|
||||
col.lerp(BLINK_COLOR, f);
|
||||
}
|
||||
|
||||
return col;
|
||||
}
|
||||
|
||||
private static float easeInOutCubic(float x) {
|
||||
return x < 0.5f ? 4 * x * x * x : 1 - (float) Math.pow(-2 * x + 2, 3) / 2;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
|
||||
package appeng.client.render.tesr;
|
||||
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||
import net.minecraft.client.util.SpriteIdentifier;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.client.render.item.ItemRenderer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.tag.ItemTags;
|
||||
import net.minecraft.tag.Tag;
|
||||
import net.minecraft.util.math.Quaternion;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import appeng.api.features.InscriberProcessType;
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.recipes.handlers.InscriberRecipe;
|
||||
import appeng.tile.misc.InscriberBlockEntity;
|
||||
|
||||
/**
|
||||
* Renders the dynamic parts of an inscriber (the presses, the animation and the
|
||||
* item being smashed)
|
||||
*/
|
||||
public final class InscriberTESR extends BlockEntityRenderer<InscriberBlockEntity> {
|
||||
|
||||
private static final float ITEM_RENDER_SCALE = 1.0f / 1.2f;
|
||||
|
||||
private static final SpriteIdentifier TEXTURE_INSIDE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
new Identifier(AppEng.MOD_ID, "block/inscriber_inside"));
|
||||
|
||||
public static final ImmutableList<SpriteIdentifier> SPRITES = ImmutableList.of(
|
||||
TEXTURE_INSIDE
|
||||
);
|
||||
|
||||
public InscriberTESR(BlockEntityRenderDispatcher rendererDispatcherIn) {
|
||||
super(rendererDispatcherIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(InscriberBlockEntity tile, float partialTicks, MatrixStack ms, VertexConsumerProvider buffers,
|
||||
int combinedLight, int combinedOverlay) {
|
||||
|
||||
// render inscriber
|
||||
|
||||
ms.push();
|
||||
ms.translate(0.5F, 0.5F, 0.5F);
|
||||
FacingToRotation.get(tile.getForward(), tile.getUp()).push(ms);
|
||||
ms.translate(-0.5F, -0.5F, -0.5F);
|
||||
|
||||
// render sides of stamps
|
||||
|
||||
long absoluteProgress = 0;
|
||||
|
||||
if (tile.isSmash()) {
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
absoluteProgress = currentTime - tile.getClientStart();
|
||||
if (absoluteProgress > 800) {
|
||||
tile.setSmash(false);
|
||||
}
|
||||
}
|
||||
|
||||
final float relativeProgress = absoluteProgress % 800 / 400.0f;
|
||||
float progress = relativeProgress;
|
||||
|
||||
if (progress > 1.0f) {
|
||||
progress = 1.0f - (easeDecompressMotion(progress - 1.0f));
|
||||
} else {
|
||||
progress = easeCompressMotion(progress);
|
||||
}
|
||||
|
||||
float press = 0.2f;
|
||||
press -= progress / 5.0f;
|
||||
|
||||
float middle = 0.5f;
|
||||
middle += 0.02f;
|
||||
final float TwoPx = 2.0f / 16.0f;
|
||||
final float base = 0.4f;
|
||||
|
||||
final Sprite tas = TEXTURE_INSIDE.getSprite();
|
||||
|
||||
VertexConsumer buffer = buffers.getBuffer(RenderLayer.getSolid());
|
||||
|
||||
// Bottom of Top Stamp
|
||||
addVertex(buffer, ms, tas, TwoPx, middle + press, TwoPx, 2, 13, combinedOverlay, combinedLight, Direction.DOWN);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle + press, TwoPx, 14, 13, combinedOverlay, combinedLight,
|
||||
Direction.DOWN);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle + press, 1.0f - TwoPx, 14, 2, combinedOverlay, combinedLight,
|
||||
Direction.DOWN);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle + press, 1.0f - TwoPx, 2, 2, combinedOverlay, combinedLight,
|
||||
Direction.DOWN);
|
||||
|
||||
// Front of Top Stamp
|
||||
addVertex(buffer, ms, tas, TwoPx, middle + base, TwoPx, 2, 3 - 16 * (press - base), combinedOverlay,
|
||||
combinedLight, Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle + base, TwoPx, 14, 3 - 16 * (press - base), combinedOverlay,
|
||||
combinedLight, Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle + press, TwoPx, 14, 3, combinedOverlay, combinedLight,
|
||||
Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle + press, TwoPx, 2, 3, combinedOverlay, combinedLight, Direction.NORTH);
|
||||
|
||||
// Top of Bottom Stamp
|
||||
middle -= 2.0f * 0.02f;
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle - press, TwoPx, 2, 13, combinedOverlay, combinedLight,
|
||||
Direction.UP);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle - press, TwoPx, 14, 13, combinedOverlay, combinedLight, Direction.UP);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle - press, 1.0f - TwoPx, 14, 2, combinedOverlay, combinedLight,
|
||||
Direction.UP);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle - press, 1.0f - TwoPx, 2, 2, combinedOverlay, combinedLight,
|
||||
Direction.UP);
|
||||
|
||||
// Front of Bottom Stamp
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle + -base, TwoPx, 2, 3 - 16 * (press - base), combinedOverlay,
|
||||
combinedLight, Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle - base, TwoPx, 14, 3 - 16 * (press - base), combinedOverlay,
|
||||
combinedLight, Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, TwoPx, middle - press, TwoPx, 14, 3, combinedOverlay, combinedLight,
|
||||
Direction.NORTH);
|
||||
addVertex(buffer, ms, tas, 1.0f - TwoPx, middle - press, TwoPx, 2, 3, combinedOverlay, combinedLight,
|
||||
Direction.NORTH);
|
||||
|
||||
// render items.
|
||||
|
||||
FixedItemInv tileInv = tile.getInternalInventory();
|
||||
|
||||
int items = 0;
|
||||
if (!tileInv.getInvStack(0).isEmpty()) {
|
||||
items++;
|
||||
}
|
||||
if (!tileInv.getInvStack(1).isEmpty()) {
|
||||
items++;
|
||||
}
|
||||
if (!tileInv.getInvStack(2).isEmpty()) {
|
||||
items++;
|
||||
}
|
||||
|
||||
boolean renderPresses;
|
||||
if (relativeProgress > 1.0f || items == 0) {
|
||||
// When crafting completes, dont render the presses (they mave have been
|
||||
// consumed, see below)
|
||||
renderPresses = false;
|
||||
|
||||
ItemStack is = tileInv.getInvStack(3);
|
||||
|
||||
if (is.isEmpty()) {
|
||||
final InscriberRecipe ir = tile.getTask();
|
||||
if (ir != null) {
|
||||
// The "PRESS" type will consume the presses so they should not render after
|
||||
// completing
|
||||
// the press animation
|
||||
renderPresses = ir.getProcessType() == InscriberProcessType.INSCRIBE;
|
||||
is = ir.getOutput().copy();
|
||||
}
|
||||
}
|
||||
this.renderItem(ms, is, 0.0f, buffers, combinedLight, combinedOverlay);
|
||||
} else {
|
||||
renderPresses = true;
|
||||
this.renderItem(ms, tileInv.getInvStack(2), 0.0f, buffers, combinedLight, combinedOverlay);
|
||||
}
|
||||
|
||||
if (renderPresses) {
|
||||
this.renderItem(ms, tileInv.getInvStack(0), press, buffers, combinedLight, combinedOverlay);
|
||||
this.renderItem(ms, tileInv.getInvStack(1), -press, buffers, combinedLight, combinedOverlay);
|
||||
}
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
private static void addVertex(VertexConsumer vb, MatrixStack ms, Sprite sprite, float x, float y,
|
||||
float z, double texU, double texV, int overlayUV, int lightmapUV, Direction front) {
|
||||
vb.vertex(ms.peek().getModel(), x, y, z);
|
||||
vb.color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
vb.texture(sprite.getFrameU(texU), sprite.getFrameV(texV));
|
||||
vb.overlay(overlayUV);
|
||||
vb.light(lightmapUV);
|
||||
vb.normal(ms.peek().getNormal(), front.getOffsetX(), front.getOffsetY(), front.getOffsetZ());
|
||||
vb.next();
|
||||
}
|
||||
|
||||
private static final Identifier TAG_STORAGE_BLOCKS = new Identifier("forge:storage_blocks");
|
||||
|
||||
private void renderItem(MatrixStack ms, final ItemStack stack, final float o, VertexConsumerProvider buffers,
|
||||
int combinedLight, int combinedOverlay) {
|
||||
if (!stack.isEmpty()) {
|
||||
ms.push();
|
||||
// move to center
|
||||
ms.translate(0.5f, 0.5f + o, 0.5f);
|
||||
ms.multiply(new Quaternion(90, 0, 0, true));
|
||||
// set scale
|
||||
ms.scale(ITEM_RENDER_SCALE, ITEM_RENDER_SCALE, ITEM_RENDER_SCALE);
|
||||
|
||||
ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
|
||||
|
||||
// heuristic to scale items down much further than blocks
|
||||
Tag<Item> storageBlockTag = ItemTags.getContainer().get(TAG_STORAGE_BLOCKS);
|
||||
if (storageBlockTag == null || !stack.getItem().isIn(storageBlockTag)) {
|
||||
ms.scale(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
itemRenderer.renderItem(stack, ModelTransformation.Mode.FIXED, combinedLight, combinedOverlay, ms,
|
||||
buffers);
|
||||
ms.pop();
|
||||
}
|
||||
}
|
||||
|
||||
// See https://easings.net/#easeOutBack
|
||||
private static float easeCompressMotion(float x) {
|
||||
float c1 = 1.70158f;
|
||||
float c3 = c1 + 1;
|
||||
|
||||
return (float) (1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2));
|
||||
}
|
||||
|
||||
// See https://easings.net/#easeInQuint
|
||||
private static float easeDecompressMotion(float x) {
|
||||
return x * x * x * x * x;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.tesr;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import appeng.client.render.renderable.Renderable;
|
||||
import appeng.tile.AEBaseBlockEntity;
|
||||
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class ModularTESR<T extends AEBaseBlockEntity> extends BlockEntityRenderer<T> {
|
||||
|
||||
private final List<Renderable<? super T>> renderables;
|
||||
|
||||
@SafeVarargs
|
||||
public ModularTESR(BlockEntityRenderDispatcher rendererDispatcherIn, Renderable<? super T>... renderables) {
|
||||
super(rendererDispatcherIn);
|
||||
this.renderables = ImmutableList.copyOf(renderables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(T te, float partialTicks, MatrixStack ms, VertexConsumerProvider buffers, int combinedLight,
|
||||
int combinedOverlay) {
|
||||
ms.push();
|
||||
ms.translate(0.5, 0.5, 0.5);
|
||||
FacingToRotation.get(te.getForward(), te.getUp()).push(ms);
|
||||
ms.translate(-0.5, -0.5, -0.5);
|
||||
for (Renderable<? super T> renderable : this.renderables) {
|
||||
renderable.renderTileEntityAt(te, partialTicks, ms, buffers, combinedLight, combinedOverlay);
|
||||
}
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user