Rendering/Model Fixes
This commit is contained in:
@@ -23,6 +23,7 @@ import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Quaternion;
|
||||
|
||||
@@ -18,15 +18,11 @@
|
||||
|
||||
package appeng.client.render.effects;
|
||||
|
||||
import net.minecraft.client.particle.*;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.client.particle.IAnimatedSprite;
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
import net.minecraft.client.particle.IParticleRenderType;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.SpriteTexturedParticle;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import appeng.block.storage.DriveSlotsState;
|
||||
import net.fabricmc.fabric.api.renderer.v1.Renderer;
|
||||
import net.fabricmc.fabric.api.renderer.v1.RendererAccess;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ModelHelper;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.api.rendering.data.v1.RenderAttachedBlockView;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class DriveBakedModel extends ForwardingBakedModel implements FabricBakedModel {
|
||||
private final Map<Item, BakedModel> cellModels;
|
||||
private final Map<Item, Mesh> bakedCells;
|
||||
private final BakedModel defaultCellModel;
|
||||
private final Mesh defaultCell;
|
||||
|
||||
private final RenderContext.QuadTransform[] slotTransforms;
|
||||
|
||||
public DriveBakedModel(BakedModel bakedBase, Map<Item, BakedModel> cellModels, BakedModel defaultCell) {
|
||||
this.wrapped = bakedBase;
|
||||
this.defaultCellModel = defaultCell;
|
||||
this.defaultCell = convertCellModel(defaultCell);
|
||||
this.slotTransforms = buildSlotTransforms();
|
||||
this.bakedCells = convertCellModels(cellModels);
|
||||
this.cellModels = cellModels;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the origin of a drive slot for positioning a cell model into it.
|
||||
*/
|
||||
public static void getSlotOrigin(int row, int col, Vector3f translation) {
|
||||
// Position this drive model copy at the correct slot. The transform is based on
|
||||
// the cell-model being in slot 0,0,0 while the upper left slot's origin is at
|
||||
// 9,13,1
|
||||
float xOffset = (9 - col * 8) / 16.0f;
|
||||
float yOffset = (13 - row * 3) / 16.0f;
|
||||
float zOffset = 1 / 16.0f;
|
||||
translation.set(xOffset, yOffset, zOffset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
|
||||
super.emitBlockQuads(blockView, state, pos, randomSupplier, context);
|
||||
|
||||
// Add cell models on top of the base model, if possible
|
||||
DriveSlotsState slotsState = getDriveSlotsState(blockView, pos);
|
||||
if (slotsState != null) {
|
||||
for (int row = 0; row < 5; row++) {
|
||||
for (int col = 0; col < 2; col++) {
|
||||
int slot = getSlotIndex(row, col);
|
||||
|
||||
// Add the cell chassis
|
||||
Item cell = slotsState.getCell(slot);
|
||||
BakedModel cellChassisModel = getCellChassisModel(cell);
|
||||
|
||||
context.pushTransform(slotTransforms[slot]);
|
||||
context.fallbackConsumer().accept(cellChassisModel);
|
||||
context.meshConsumer().accept(getCellChassisMesh(cell));
|
||||
context.popTransform();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static DriveSlotsState getDriveSlotsState(BlockRenderView blockView, BlockPos pos) {
|
||||
if (!(blockView instanceof RenderAttachedBlockView)) {
|
||||
return null;
|
||||
}
|
||||
Object attachedData = ((RenderAttachedBlockView) blockView).getBlockEntityRenderAttachment(pos);
|
||||
if (!(attachedData instanceof DriveModelData)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ((DriveModelData) attachedData).getSlotsState();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAmbientOcclusion() {
|
||||
// We have faces inside the chassis that are facing east, but should not receive
|
||||
// ambient occlusion from the east-side, but sadly this cannot be fine-tuned on
|
||||
// a face-by-face basis.
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determine which drive chassis to show based on the used cell
|
||||
public Mesh getCellChassisMesh(Item cell) {
|
||||
if (cell == null) {
|
||||
return bakedCells.get(Items.AIR);
|
||||
}
|
||||
final Mesh model = bakedCells.get(cell);
|
||||
|
||||
return model != null ? model : defaultCell;
|
||||
}
|
||||
|
||||
public BakedModel getCellChassisModel(Item cell) {
|
||||
if (cell == null) {
|
||||
return cellModels.get(Items.AIR);
|
||||
}
|
||||
final BakedModel model = cellModels.get(cell);
|
||||
|
||||
return model != null ? model : defaultCellModel;
|
||||
}
|
||||
|
||||
private RenderContext.QuadTransform[] buildSlotTransforms() {
|
||||
RenderContext.QuadTransform[] result = new RenderContext.QuadTransform[5 * 2];
|
||||
|
||||
for (int row = 0; row < 5; row++) {
|
||||
for (int col = 0; col < 2; col++) {
|
||||
|
||||
Vector3f translation = new Vector3f();
|
||||
getSlotOrigin(row, col, translation);
|
||||
|
||||
result[getSlotIndex(row, col)] = new QuadTranslator(translation.getX(), translation.getY(), translation.getZ());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int getSlotIndex(int row, int col) {
|
||||
return row * 2 + col;
|
||||
}
|
||||
|
||||
private static class QuadTranslator implements RenderContext.QuadTransform {
|
||||
private final float x;
|
||||
private final float y;
|
||||
private final float z;
|
||||
|
||||
public QuadTranslator(float x, float y, float z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transform(MutableQuadView quad) {
|
||||
Vector3f target = new Vector3f();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
quad.copyPos(i, target);
|
||||
target.add(x, y, z);
|
||||
quad.pos(i, target);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<Item, Mesh> convertCellModels(Map<Item, BakedModel> cellModels) {
|
||||
Map<Item, Mesh> result = new IdentityHashMap<>();
|
||||
|
||||
for (Map.Entry<Item, BakedModel> entry : cellModels.entrySet()) {
|
||||
result.put(entry.getKey(), convertCellModel(entry.getValue()));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Mesh convertCellModel(BakedModel bakedModel) {
|
||||
Renderer renderer = RendererAccess.INSTANCE.getRenderer();
|
||||
Random random = new Random();
|
||||
MeshBuilder meshBuilder = renderer.meshBuilder();
|
||||
QuadEmitter emitter = meshBuilder.getEmitter();
|
||||
emitter.material(renderer.materialFinder().disableDiffuse(0, false).disableAo(0, true).find());
|
||||
|
||||
for (int i = 0; i <= ModelHelper.NULL_FACE_ID; i++) {
|
||||
Direction face = ModelHelper.faceFromIndex(i);
|
||||
List<BakedQuad> quads = bakedModel.getQuads(null, face, random);
|
||||
for (BakedQuad quad : quads) {
|
||||
emitter.fromVanilla(quad.getVertexData(), 0, false);
|
||||
emitter.cullFace(face);
|
||||
emitter.nominalFace(face);
|
||||
emitter.emit();
|
||||
}
|
||||
}
|
||||
return meshBuilder.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import appeng.api.client.ICellModelRegistry;
|
||||
import appeng.client.render.BasicUnbakedModel;
|
||||
import appeng.core.Api;
|
||||
import appeng.core.api.client.ApiCellModelRegistry;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.ModelBakeSettings;
|
||||
import net.minecraft.client.render.model.ModelLoader;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.util.SpriteIdentifier;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class DriveModel implements BasicUnbakedModel {
|
||||
|
||||
private static final Identifier MODEL_BASE = new Identifier(
|
||||
"appliedenergistics2:block/drive/drive_base");
|
||||
private static final Identifier MODEL_CELL_EMPTY = new Identifier(
|
||||
"appliedenergistics2:block/drive/drive_cell_empty");
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public BakedModel bake(ModelLoader loader, Function<SpriteIdentifier, Sprite> textureGetter, ModelBakeSettings rotationContainer, Identifier modelId) {
|
||||
final ICellModelRegistry cellRegistry = Api.instance().client().cells();
|
||||
final Map<Item, BakedModel> cellModels = new IdentityHashMap<>();
|
||||
|
||||
// Load the base model and the model for each cell model.
|
||||
for (Entry<Item, Identifier> entry : cellRegistry.models().entrySet()) {
|
||||
BakedModel cellModel = loader.bake(entry.getValue(), rotationContainer);
|
||||
cellModels.put(entry.getKey(), cellModel);
|
||||
}
|
||||
|
||||
final BakedModel baseModel = loader.bake(MODEL_BASE, rotationContainer);
|
||||
final BakedModel defaultCell = loader.bake(cellRegistry.getDefaultModel(), rotationContainer);
|
||||
cellModels.put(Items.AIR, loader.bake(MODEL_CELL_EMPTY, rotationContainer));
|
||||
|
||||
return new DriveBakedModel(baseModel, cellModels, defaultCell);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Identifier> getModelDependencies() {
|
||||
ICellModelRegistry cells = Api.instance().client().cells();
|
||||
return ImmutableSet.<Identifier>builder()
|
||||
.add(cells.getDefaultModel())
|
||||
.addAll(ApiCellModelRegistry.getModels())
|
||||
.addAll(cells.models().values())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,15 +2,13 @@ package appeng.client.render.tesr;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.Vector3f;
|
||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
|
||||
|
||||
import appeng.api.implementations.tiles.IChestOrDrive;
|
||||
import appeng.block.storage.DriveSlotState;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexFormats;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
|
||||
/**
|
||||
* Utility class to render LEDs for storage cells from a Tile Entity Renderer.
|
||||
@@ -53,11 +51,11 @@ class CellLedRenderer {
|
||||
// Bottom Face
|
||||
R, B, FR, L, B, FR, L, B, BA, R, B, BA, };
|
||||
|
||||
public static final RenderType RENDER_LAYER = RenderType.makeType("ae_drive_leds",
|
||||
DefaultVertexFormats.POSITION_COLOR, 7, 32565, false, true, RenderType.State.getBuilder().build(false));
|
||||
public static final RenderLayer RENDER_LAYER = RenderLayer.of("ae_drive_leds",
|
||||
VertexFormats.POSITION_COLOR, 7, 32565, false, true, RenderLayer.MultiPhaseParameters.builder().build(false));
|
||||
|
||||
public static void renderLed(IChestOrDrive drive, int slot, IVertexBuilder buffer, MatrixStack ms,
|
||||
float partialTicks) {
|
||||
public static void renderLed(IChestOrDrive drive, int slot, VertexConsumer buffer, MatrixStack ms,
|
||||
float partialTicks) {
|
||||
|
||||
Vector3f color = getColorForSlot(drive, slot, partialTicks);
|
||||
if (color == null) {
|
||||
@@ -68,8 +66,8 @@ class CellLedRenderer {
|
||||
float x = LED_QUADS[i];
|
||||
float y = LED_QUADS[i + 1];
|
||||
float z = LED_QUADS[i + 2];
|
||||
buffer.pos(ms.getLast().getMatrix(), x, y, z).color(color.getX(), color.getY(), color.getZ(), 1.f)
|
||||
.endVertex();
|
||||
buffer.vertex(ms.peek().getModel(), x, y, z).color(color.getX(), color.getY(), color.getZ(), 1.f)
|
||||
.next();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,56 +25,57 @@ import java.util.Random;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
|
||||
import appeng.client.render.BakedModelUnwrapper;
|
||||
import appeng.client.render.model.AutoRotatingBakedModel;
|
||||
import appeng.client.render.model.DriveBakedModel;
|
||||
import appeng.tile.storage.ChestBlockEntity;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockModelRenderer;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.ModelManager;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
|
||||
import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.block.BlockModelRenderer;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.BakedModelManager;
|
||||
import net.minecraft.client.render.model.BakedQuad;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
|
||||
import appeng.api.client.ICellModelRegistry;
|
||||
import appeng.block.storage.DriveSlotsState;
|
||||
import appeng.client.render.DelegateBakedModel;
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import appeng.core.Api;
|
||||
import appeng.tile.storage.ChestTileEntity;
|
||||
|
||||
/**
|
||||
* The tile entity renderer for ME chests takes care of rendering the right
|
||||
* model for the inserted cell, as well as the LED.
|
||||
*/
|
||||
public class ChestTileEntityRenderer extends TileEntityRenderer<ChestTileEntity> {
|
||||
public class ChestTileEntityRenderer extends BlockEntityRenderer<ChestBlockEntity> {
|
||||
|
||||
private final ICellModelRegistry cellModelRegistry = Api.instance().client().cells();
|
||||
|
||||
private final ModelManager modelManager;
|
||||
private final BakedModelManager modelManager;
|
||||
|
||||
private final BlockModelRenderer blockRenderer;
|
||||
|
||||
public ChestTileEntityRenderer(TileEntityRendererDispatcher rendererDispatcherIn) {
|
||||
super(rendererDispatcherIn);
|
||||
Minecraft client = Minecraft.getInstance();
|
||||
modelManager = client.getModelManager();
|
||||
blockRenderer = client.getBlockRendererDispatcher().getBlockModelRenderer();
|
||||
public ChestTileEntityRenderer(BlockEntityRenderDispatcher renderDispatcher) {
|
||||
super(renderDispatcher);
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
modelManager = client.getBakedModelManager();
|
||||
blockRenderer = client.getBlockRenderManager().getModelRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(ChestTileEntity chest, float partialTicks, MatrixStack matrices, IRenderTypeBuffer buffers,
|
||||
int combinedLight, int combinedOverlay) {
|
||||
public void render(ChestBlockEntity chest, float partialTicks, MatrixStack matrices, VertexConsumerProvider buffers,
|
||||
int combinedLight, int combinedOverlay) {
|
||||
|
||||
World world = chest.getWorld();
|
||||
if (world == null) {
|
||||
@@ -88,12 +89,12 @@ public class ChestTileEntityRenderer extends TileEntityRenderer<ChestTileEntity>
|
||||
return; // No cell inserted into chest
|
||||
}
|
||||
|
||||
ResourceLocation cellModelLocation = cellModelRegistry.model(cellItem);
|
||||
if (cellModelLocation == null) {
|
||||
cellModelLocation = cellModelRegistry.getDefaultModel();
|
||||
// Try to get the right cell chassis model from the drive model since it already loads them all
|
||||
DriveBakedModel driveModel = getDriveModel();
|
||||
if (driveModel == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
IBakedModel model = modelManager.getModel(cellModelLocation);
|
||||
BakedModel cellModel = driveModel.getCellChassisModel(cellItem);
|
||||
|
||||
matrices.push();
|
||||
matrices.translate(0.5, 0.5, 0.5);
|
||||
@@ -106,45 +107,49 @@ public class ChestTileEntityRenderer extends TileEntityRenderer<ChestTileEntity>
|
||||
matrices.translate(5 / 16.0, 4 / 16.0, 0);
|
||||
|
||||
// Render the cell model as-if it was a block model
|
||||
IVertexBuilder buffer = buffers.getBuffer(RenderType.getCutout());
|
||||
VertexConsumer buffer = buffers.getBuffer(RenderLayer.getCutout());
|
||||
// We "fake" the position here to make it use the light-value in front of the
|
||||
// drive
|
||||
FaceRotatingModel rotatedModel = new FaceRotatingModel(model, rotation);
|
||||
blockRenderer.renderModel(world, rotatedModel, chest.getBlockState(), chest.getPos(), matrices, buffer, false,
|
||||
new Random(), 0L, combinedOverlay, EmptyModelData.INSTANCE);
|
||||
BakedModel rotatedModel = new FaceRotatingModel(cellModel, rotation);
|
||||
blockRenderer.render(world, rotatedModel, chest.getCachedState(), chest.getPos(), matrices, buffer, false,
|
||||
new Random(), 0L, combinedOverlay);
|
||||
|
||||
IVertexBuilder ledBuffer = buffers.getBuffer(CellLedRenderer.RENDER_LAYER);
|
||||
VertexConsumer ledBuffer = buffers.getBuffer(CellLedRenderer.RENDER_LAYER);
|
||||
CellLedRenderer.renderLed(chest, 0, ledBuffer, matrices, partialTicks);
|
||||
|
||||
matrices.pop();
|
||||
}
|
||||
|
||||
private DriveBakedModel getDriveModel() {
|
||||
BakedModel driveModel = modelManager.getBlockModels().getModel(Api.instance().definitions().blocks().drive().block().getDefaultState());
|
||||
return BakedModelUnwrapper.unwrap(driveModel, DriveBakedModel.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The actual vertex data will be transformed using the matrix stack, but the
|
||||
* faces will not be correctly rotated so the incorrect lighting data would be
|
||||
* used to apply diffuse lighting and the lightmap texture.
|
||||
*/
|
||||
private static class FaceRotatingModel extends DelegateBakedModel {
|
||||
private static class FaceRotatingModel extends ForwardingBakedModel {
|
||||
private final FacingToRotation r;
|
||||
|
||||
protected FaceRotatingModel(IBakedModel base, FacingToRotation r) {
|
||||
super(base);
|
||||
protected FaceRotatingModel(BakedModel base, FacingToRotation r) {
|
||||
this.wrapped = base;
|
||||
this.r = r;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
|
||||
@Nonnull IModelData extraData) {
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand) {
|
||||
if (side != null) {
|
||||
side = r.rotate(side); // This fixes the incorrect lightmap position
|
||||
side = r.resultingRotate(side); // This fixes the incorrect lightmap position
|
||||
}
|
||||
List<BakedQuad> quads = new ArrayList<>(super.getQuads(state, side, rand, extraData));
|
||||
List<BakedQuad> quads = new ArrayList<>(super.getQuads(state, side, rand));
|
||||
|
||||
for (int i = 0; i < quads.size(); i++) {
|
||||
BakedQuad quad = quads.get(i);
|
||||
quads.set(i, new BakedQuad(quad.getVertexData(), quad.getTintIndex(), r.rotate(quad.getFace()),
|
||||
quad.func_187508_a(), quad.shouldApplyDiffuseLighting()));
|
||||
quads.set(i, new BakedQuad(quad.getVertexData(), quad.getColorIndex(), r.rotate(quad.getFace()),
|
||||
/* FIXME FABRIC: sprite is protected but unused?? */ null, quad.hasShade()));
|
||||
}
|
||||
|
||||
return quads;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package appeng.client.render.tesr;
|
||||
|
||||
import net.minecraft.client.render.RenderLayer;
|
||||
import appeng.client.render.model.DriveBakedModel;
|
||||
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;
|
||||
@@ -13,7 +12,6 @@ import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import appeng.client.render.model.DriveBakedModel;
|
||||
import appeng.tile.storage.DriveBlockEntity;
|
||||
|
||||
/**
|
||||
@@ -22,8 +20,8 @@ import appeng.tile.storage.DriveBlockEntity;
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class DriveLedTileEntityRenderer extends BlockEntityRenderer<DriveBlockEntity> {
|
||||
|
||||
public DriveLedTileEntityRenderer(BlockEntityRendererDispatcher rendererDispatcher) {
|
||||
super(rendererDispatcher);
|
||||
public DriveLedTileEntityRenderer(BlockEntityRenderDispatcher renderDispatcher) {
|
||||
super(renderDispatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user