Skip to content

Commit

Permalink
reworked facade handeling
Browse files Browse the repository at this point in the history
- transparent rendering
- custom item model
- CTM and tint support
- Item models
  • Loading branch information
ferriarnus committed Dec 28, 2024
1 parent cb31ffd commit ea6cf4a
Show file tree
Hide file tree
Showing 24 changed files with 513 additions and 84 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"loader": "enderio:painted_block",
"reference": "minecraft:stone"
"loader": "enderio:facades_item",
"model": {
"parent": "enderio:block/conduit_facade"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"loader": "enderio:painted_block",
"reference": "minecraft:stone"
"loader": "enderio:facades_item",
"model": {
"parent": "enderio:block/hardened_conduit_facade"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"loader": "enderio:painted_block",
"reference": "minecraft:stone"
"loader": "enderio:facades_item",
"model": {
"parent": "enderio:block/transparent_conduit_facade"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"loader": "enderio:painted_block",
"reference": "minecraft:stone"
"loader": "enderio:facades_item",
"model": {
"parent": "enderio:block/transparent_hardened_conduit_facade"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,17 @@
import com.enderio.conduits.client.gui.conduit.ItemConduitScreenExtension;
import com.enderio.conduits.client.model.ConduitGeometry;
import com.enderio.conduits.client.model.ConduitItemModelLoader;
import com.enderio.conduits.client.model.FacadeItemGeometry;
import com.enderio.conduits.client.model.conduit.modifier.ConduitCoreModelModifiers;
import com.enderio.conduits.client.model.conduit.modifier.FluidConduitCoreModelModifier;
import com.enderio.conduits.common.init.ConduitBlocks;
import com.enderio.conduits.common.init.ConduitTypes;
import net.minecraft.client.Minecraft;
import net.minecraft.client.color.block.BlockColor;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.core.BlockPos;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.neoforge.client.event.ModelEvent;
import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -42,8 +33,7 @@ public class ConduitClientSetup {
private static final Map<ModelResourceLocation, BakedModel> MODELS = new HashMap<>();

public static final ModelResourceLocation CONDUIT_CONNECTOR = loc("block/conduit_connector");
public static final ModelResourceLocation CONDUIT_FACADE = loc("block/cube_all");
// public static final ModelResourceLocation CONDUIT_FACADE = loc("block/conduit_facade");
public static final ModelResourceLocation CONDUIT_FACADE_OVERLAY = loc("block/conduit_facade_overlay");
public static final ModelResourceLocation CONDUIT_CONNECTION = loc("block/conduit_connection");
public static final ModelResourceLocation CONDUIT_CORE = loc("block/conduit_core");
public static final ModelResourceLocation BOX = loc("block/box/1x1x1");
Expand All @@ -53,6 +43,12 @@ public class ConduitClientSetup {
public static final ModelResourceLocation CONDUIT_IO_OUT = loc("block/io/output");
public static final ModelResourceLocation CONDUIT_IO_REDSTONE = loc("block/io/redstone");

public static final ModelResourceLocation CONDUIT_FACADE = loc("block/conduit_facade");
public static final ModelResourceLocation CONDUIT_FACADE_HARDENED = loc("block/conduit_facade_hardened");
public static final ModelResourceLocation CONDUIT_FACADE_TRANSLUCENT = loc("block/conduit_facade_translucent");
public static final ModelResourceLocation CONDUIT_FACADE_TRANSLUCENT_HARDENED = loc("block/conduit_facade_translucent_hardened");


private ConduitClientSetup() {}

@SubscribeEvent
Expand All @@ -75,6 +71,7 @@ public static void registerConduitScreenExtensions(RegisterConduitScreenExtensio
public static void modelLoader(ModelEvent.RegisterGeometryLoaders event) {
event.register(EnderIOBase.loc("conduit"), new ConduitGeometry.Loader());
event.register(EnderIOBase.loc("conduit_item"), new ConduitItemModelLoader());
event.register(EnderIOBase.loc("facades_item"), new FacadeItemGeometry.Loader());
}

@SubscribeEvent
Expand All @@ -95,19 +92,6 @@ public static void bakingModelsFinished(ModelEvent.BakingCompleted event) {
}
}

@SubscribeEvent
public static void blockColors(RegisterColorHandlersEvent.Block block) {
block.register(new ConduitBlockColor(), ConduitBlocks.CONDUIT.get());
}

public static class ConduitBlockColor implements BlockColor {

@Override
public int getColor(BlockState state, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos, int tintIndex) {
return DyeColor.values()[tintIndex].getTextureDiffuseColor();
}
}

private static ModelResourceLocation loc(String modelName) {
ModelResourceLocation loc = ModelResourceLocation.standalone(EnderIOBase.loc(modelName));
MODEL_LOCATIONS.add(loc);
Expand All @@ -117,8 +101,4 @@ private static ModelResourceLocation loc(String modelName) {
public static BakedModel modelOf(ModelResourceLocation location) {
return MODELS.get(location);
}

public static Level getClientLevel() {
return Minecraft.getInstance().level;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.enderio.conduits.client;

import com.enderio.base.common.init.EIODataComponents;
import com.enderio.conduits.client.model.conduit.facades.FacadeHelper;
import com.enderio.conduits.common.conduit.block.ConduitBundleBlockEntity;
import net.minecraft.client.Minecraft;
import net.minecraft.client.color.block.BlockColor;
import net.minecraft.client.color.item.ItemColor;
import net.minecraft.core.BlockPos;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;

import java.util.Optional;

public class ConduitFacadeColor implements BlockColor, ItemColor {
@Override
public int getColor(BlockState state, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos, int tintIndex) {
if (tintIndex >= 0) {
return DyeColor.values()[tintIndex].getTextureDiffuseColor();
}
tintIndex = unmoveTintIndex(tintIndex);
if (level != null && pos != null) {
BlockEntity entity = level.getBlockEntity(pos);
if (entity instanceof ConduitBundleBlockEntity conduitBundleBlock) {

Optional<Block> facade = conduitBundleBlock.getBundle().facade();

if (facade.isPresent() && FacadeHelper.areFacadesVisible()) {
int color = Minecraft.getInstance().getBlockColors().getColor(facade.get().defaultBlockState(), level, pos, tintIndex);
if (color != -1) {
return color;
}
}
}
}

return 0xFFFFFF;
}

@Override
public int getColor(ItemStack stack, int tintIndex) {
var facadeData = stack.get(EIODataComponents.BLOCK_PAINT);
if (facadeData != null) {
var block = facadeData.paint();
return Minecraft.getInstance().getItemColors().getColor(block.asItem().getDefaultInstance(), tintIndex);
}

return 0;
}

public static int moveTintIndex(int original) {
return -original - 2;
}

public static int unmoveTintIndex(int original) {
if (original > 0) {
return original;
} else {
return -original - 2;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.enderio.conduits.client;

import com.enderio.conduits.client.model.conduit.facades.FacadeHelper;
import com.enderio.conduits.common.conduit.block.ConduitBundleBlock;
import com.enderio.conduits.common.conduit.block.ConduitBundleBlockEntity;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.BlockPos;
import net.minecraft.util.FastColor;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.block.state.BlockState;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.client.event.RenderLevelStageEvent;
import net.neoforged.neoforge.client.model.data.ModelData;
import net.neoforged.neoforge.client.model.pipeline.VertexConsumerWrapper;

import java.util.Map;

@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT)
public class ConduitFacadeRendering {

@SubscribeEvent
static void renderFacade(RenderLevelStageEvent event) {
if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_TRIPWIRE_BLOCKS || FacadeHelper.areFacadesVisible()) {
return;
}
for (Map.Entry<BlockPos, BlockState> entry : ConduitBundleBlockEntity.FACADES.entrySet()) {
ClientLevel level = Minecraft.getInstance().level;
if (!level.isLoaded(entry.getKey())) {
return;
}
if (level.getBlockState(entry.getKey()).getBlock() instanceof ConduitBundleBlock) {
if (entry.getValue() == null) {
continue;
}

var baseConsumer = Minecraft.getInstance().renderBuffers().bufferSource().getBuffer(Sheets.translucentCullBlockSheet());
var wrappedConsumer = new VertexConsumerWrapper(baseConsumer) {
@Override
public VertexConsumer setColor(int r, int g, int b, int a) {
super.setColor(r, g, b, 85);
return this;
}
};

var cameraPos = event.getCamera().getPosition();
event.getPoseStack().pushPose();
event.getPoseStack().translate(entry.getKey().getX()-cameraPos.x, entry.getKey().getY()-cameraPos.y, entry.getKey().getZ()-cameraPos.z);

var model = Minecraft.getInstance().getModelManager().getBlockModelShaper().getBlockModel(entry.getValue());
int color = Minecraft.getInstance().getBlockColors().getColor(entry.getValue(), level, entry.getKey());
for (var renderType : model.getRenderTypes(entry.getValue(), RandomSource.create(), ModelData.EMPTY)) {
Minecraft.getInstance().getBlockRenderer().getModelRenderer().renderModel(event.getPoseStack().last(), wrappedConsumer, entry.getValue(),
model, FastColor.ARGB32.red(color) / 255.0F, FastColor.ARGB32.green(color) / 255.0F, FastColor.ARGB32.blue(color) / 255.0F,
LightTexture.pack(level.getBrightness(LightLayer.BLOCK, entry.getKey()), level.getBrightness(LightLayer.SKY, entry.getKey())),
OverlayTexture.NO_OVERLAY, model.getModelData(level, entry.getKey(), entry.getValue(), ModelData.EMPTY), renderType
);
}
Minecraft.getInstance().renderBuffers().bufferSource().endBatch(Sheets.translucentCullBlockSheet());
event.getPoseStack().popPose();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.enderio.conduits.api.ConduitNode;
import com.enderio.conduits.api.model.ConduitCoreModelModifier;
import com.enderio.base.api.misc.RedstoneControl;
import com.enderio.base.client.paint.model.PaintingQuadTransformer;
import com.enderio.conduits.client.ConduitFacadeColor;
import com.enderio.conduits.client.model.conduit.facades.FacadeHelper;
import com.enderio.conduits.client.model.conduit.modifier.ConduitCoreModelModifiers;
import com.enderio.conduits.common.Area;
Expand All @@ -31,8 +31,10 @@
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.SingleThreadedRandomSource;
import net.neoforged.neoforge.client.ChunkRenderTypeSet;
import net.neoforged.neoforge.client.model.IDynamicBakedModel;
import net.neoforged.neoforge.client.model.IQuadTransformer;
Expand All @@ -56,7 +58,6 @@
import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_CONNECTION_BOX;
import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_CONNECTOR;
import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_CORE;
import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_FACADE;
import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_IO_IN;
import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_IO_IN_OUT;
import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_IO_OUT;
Expand All @@ -71,17 +72,20 @@ public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction

List<BakedQuad> quads = new ArrayList<>();
ConduitBundle conduitBundle = extraData.get(ConduitBundleBlockEntity.BUNDLE_MODEL_PROPERTY);
BlockPos pos = extraData.get(ConduitBundleBlockEntity.POS);
ModelData data = extraData.get(ConduitBundleBlockEntity.FACADE_MODEL_DATA);

if (conduitBundle != null && pos != null) {
if (conduitBundle != null) {
if (FacadeHelper.areFacadesVisible()) {
IQuadTransformer transformer = quad -> quad.tintIndex = ConduitFacadeColor.moveTintIndex(quad.getTintIndex());
Optional<Block> facadeOpt = conduitBundle.facade();
if (facadeOpt.isPresent()) {
BlockState facade = facadeOpt.get().defaultBlockState();
var model = Minecraft.getInstance().getBlockRenderer().getBlockModel(facade);
var facadeQuads = model.getQuads(facade, side, rand, data, renderType);

quads.addAll(/*new BlockColorQuadDataTransformer(pos, Minecraft.getInstance().level, facade)
.andThen(*/new PaintingQuadTransformer(facade, renderType)/*)*/
.process(modelOf(CONDUIT_FACADE).getQuads(state, side, rand, ModelData.EMPTY, renderType)));
if (renderType != null && model.getRenderTypes(facade, rand, data).contains(renderType)) {
quads.addAll(transformer.process(facadeQuads));
}
}

// If the facade should hide the conduits, escape early.
Expand Down Expand Up @@ -294,6 +298,9 @@ public TextureAtlasSprite getParticleIcon(ModelData data) {
if (conduitBundle == null || conduitBundle.getConduits().isEmpty()) {
return ModelHelper.getMissingTexture();
}
if (conduitBundle.hasFacade()) {
return Minecraft.getInstance().getBlockRenderer().getBlockModel(conduitBundle.facade().get().defaultBlockState()).getParticleIcon(data.get(ConduitBundleBlockEntity.FACADE_MODEL_DATA));
}
return sprite(conduitBundle, conduitBundle.getConduits().getFirst());
}

Expand All @@ -304,7 +311,27 @@ public ItemOverrides getOverrides() {

@Override
public ChunkRenderTypeSet getRenderTypes(@NotNull BlockState state, @NotNull RandomSource rand, @NotNull ModelData data) {
return ChunkRenderTypeSet.of(RenderType.cutout());
ChunkRenderTypeSet facadeRenderTypes = data.get(ConduitBundleBlockEntity.FACADE_RENDERTYPE);
ChunkRenderTypeSet renderTypes = ChunkRenderTypeSet.of(RenderType.cutout());
if (facadeRenderTypes != null) {
renderTypes = ChunkRenderTypeSet.union(renderTypes, facadeRenderTypes);
}
return renderTypes;
}

@Override
public ModelData getModelData(BlockAndTintGetter level, BlockPos pos, BlockState state, ModelData modelData) {
ModelData data = IDynamicBakedModel.super.getModelData(level, pos, state, modelData);
ModelData.Builder builder = data.derive();
ConduitBundle conduitBundle = data.get(ConduitBundleBlockEntity.BUNDLE_MODEL_PROPERTY);
if (conduitBundle != null && conduitBundle.hasFacade()) {
BlockState blockState = conduitBundle.facade().get().defaultBlockState();
BakedModel blockModel = Minecraft.getInstance().getBlockRenderer().getBlockModel(blockState);
ModelData facadeData = blockModel.getModelData(level, pos, blockState, ModelData.EMPTY);
builder.with(ConduitBundleBlockEntity.FACADE_MODEL_DATA, facadeData);
builder.with(ConduitBundleBlockEntity.FACADE_RENDERTYPE, blockModel.getRenderTypes(blockState, new SingleThreadedRandomSource(state.getSeed(pos)), facadeData));
}
return builder.build();
}

private static TextureAtlasSprite sprite(ConduitBundle conduitBundle, Holder<Conduit<?>> type) {
Expand Down
Loading

0 comments on commit ea6cf4a

Please sign in to comment.