Restore SBB contraption rendering

This commit is contained in:
PepperCode1 2024-05-16 21:18:58 -07:00
parent 7d265eb2c1
commit 79e1c8c950
46 changed files with 493 additions and 764 deletions

View file

@ -1,8 +1,8 @@
package com.simibubi.create; package com.simibubi.create;
import com.simibubi.create.content.contraptions.glue.SuperGlueSelectionHandler; import com.simibubi.create.content.contraptions.glue.SuperGlueSelectionHandler;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher; import com.simibubi.create.content.contraptions.render.ContraptionRenderInfo;
import com.simibubi.create.content.contraptions.render.SBBContraptionManager; import com.simibubi.create.content.contraptions.render.ContraptionRenderInfoManager;
import com.simibubi.create.content.decoration.encasing.CasingConnectivity; import com.simibubi.create.content.decoration.encasing.CasingConnectivity;
import com.simibubi.create.content.equipment.bell.SoulPulseEffectHandler; import com.simibubi.create.content.equipment.bell.SoulPulseEffectHandler;
import com.simibubi.create.content.equipment.potatoCannon.PotatoCannonRenderHandler; import com.simibubi.create.content.equipment.potatoCannon.PotatoCannonRenderHandler;
@ -80,7 +80,7 @@ public class CreateClient {
BUFFER_CACHE.registerCompartment(CachedBufferer.DIRECTIONAL_PARTIAL); BUFFER_CACHE.registerCompartment(CachedBufferer.DIRECTIONAL_PARTIAL);
BUFFER_CACHE.registerCompartment(KineticBlockEntityRenderer.KINETIC_BLOCK); BUFFER_CACHE.registerCompartment(KineticBlockEntityRenderer.KINETIC_BLOCK);
BUFFER_CACHE.registerCompartment(WaterWheelRenderer.WATER_WHEEL); BUFFER_CACHE.registerCompartment(WaterWheelRenderer.WATER_WHEEL);
BUFFER_CACHE.registerCompartment(SBBContraptionManager.CONTRAPTION, 20); BUFFER_CACHE.registerCompartment(ContraptionRenderInfo.CONTRAPTION, 20);
BUFFER_CACHE.registerCompartment(WorldSectionElement.DOC_WORLD_SECTION, 20); BUFFER_CACHE.registerCompartment(WorldSectionElement.DOC_WORLD_SECTION, 20);
AllPartialModels.init(); AllPartialModels.init();
@ -95,7 +95,7 @@ public class CreateClient {
BUFFER_CACHE.invalidate(); BUFFER_CACHE.invalidate();
SCHEMATIC_HANDLER.updateRenderers(); SCHEMATIC_HANDLER.updateRenderers();
ContraptionRenderDispatcher.reset(); ContraptionRenderInfoManager.resetAll();
} }
public static void checkGraphicsFanciness() { public static void checkGraphicsFanciness() {

View file

@ -28,7 +28,7 @@ import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.elevator.ElevatorContraption; import com.simibubi.create.content.contraptions.elevator.ElevatorContraption;
import com.simibubi.create.content.contraptions.glue.SuperGlueEntity; import com.simibubi.create.content.contraptions.glue.SuperGlueEntity;
import com.simibubi.create.content.contraptions.mounted.MountedContraption; import com.simibubi.create.content.contraptions.mounted.MountedContraption;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher; import com.simibubi.create.content.contraptions.render.ContraptionRenderInfo;
import com.simibubi.create.content.contraptions.sync.ContraptionSeatMappingPacket; import com.simibubi.create.content.contraptions.sync.ContraptionSeatMappingPacket;
import com.simibubi.create.content.decoration.slidingDoor.SlidingDoorBlock; import com.simibubi.create.content.decoration.slidingDoor.SlidingDoorBlock;
import com.simibubi.create.content.trains.entity.CarriageContraption; import com.simibubi.create.content.trains.entity.CarriageContraption;
@ -379,7 +379,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
if (!contraption.deferInvalidate) if (!contraption.deferInvalidate)
return; return;
contraption.deferInvalidate = false; contraption.deferInvalidate = false;
ContraptionRenderDispatcher.invalidate(contraption); ContraptionRenderInfo.invalidate(contraption);
}); });
if (!(level() instanceof ServerLevelAccessor sl)) if (!(level() instanceof ServerLevelAccessor sl))

View file

@ -158,8 +158,7 @@ public abstract class Contraption {
// Client // Client
public Map<BlockPos, ModelData> modelData; public Map<BlockPos, ModelData> modelData;
public Map<BlockPos, BlockEntity> presentBlockEntities; public Map<BlockPos, BlockEntity> presentBlockEntities;
public List<BlockEntity> maybeInstancedBlockEntities; public List<BlockEntity> renderedBlockEntities;
public List<BlockEntity> specialRenderedBlockEntities;
protected ContraptionWorld world; protected ContraptionWorld world;
public boolean deferInvalidate; public boolean deferInvalidate;
@ -176,8 +175,7 @@ public abstract class Contraption {
glueToRemove = new HashSet<>(); glueToRemove = new HashSet<>();
initialPassengers = new HashMap<>(); initialPassengers = new HashMap<>();
presentBlockEntities = new HashMap<>(); presentBlockEntities = new HashMap<>();
maybeInstancedBlockEntities = new ArrayList<>(); renderedBlockEntities = new ArrayList<>();
specialRenderedBlockEntities = new ArrayList<>();
pendingSubContraptions = new ArrayList<>(); pendingSubContraptions = new ArrayList<>();
stabilizedSubContraptions = new HashMap<>(); stabilizedSubContraptions = new HashMap<>();
simplifiedEntityColliders = Optional.empty(); simplifiedEntityColliders = Optional.empty();
@ -688,7 +686,7 @@ public abstract class Contraption {
public void readNBT(Level world, CompoundTag nbt, boolean spawnData) { public void readNBT(Level world, CompoundTag nbt, boolean spawnData) {
blocks.clear(); blocks.clear();
presentBlockEntities.clear(); presentBlockEntities.clear();
specialRenderedBlockEntities.clear(); renderedBlockEntities.clear();
Tag blocks = nbt.get("Blocks"); Tag blocks = nbt.get("Blocks");
// used to differentiate between the 'old' and the paletted serialization // used to differentiate between the 'old' and the paletted serialization
@ -893,20 +891,17 @@ public abstract class Contraption {
if (be == null) if (be == null)
return; return;
be.setLevel(world); be.setLevel(world);
modelData.put(info.pos(), be.getModelData());
if (be instanceof KineticBlockEntity kbe) if (be instanceof KineticBlockEntity kbe)
kbe.setSpeed(0); kbe.setSpeed(0);
be.getBlockState(); be.getBlockState();
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(info.state());
if (movementBehaviour == null || !movementBehaviour.hasSpecialInstancedRendering())
maybeInstancedBlockEntities.add(be);
if (movementBehaviour != null && !movementBehaviour.renderAsNormalBlockEntity())
return;
presentBlockEntities.put(info.pos(), be); presentBlockEntities.put(info.pos(), be);
specialRenderedBlockEntities.add(be); modelData.put(info.pos(), be.getModelData());
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(info.state());
if (movementBehaviour == null || !movementBehaviour.disableBlockEntityRendering()) {
renderedBlockEntities.add(be);
}
}); });
} }
@ -1376,8 +1371,8 @@ public abstract class Contraption {
}, blocks.keySet()); }, blocks.keySet());
} }
public Collection<BlockEntity> getSpecialRenderedBEs() { public Collection<BlockEntity> getRenderedBEs() {
return specialRenderedBlockEntities; return renderedBlockEntities;
} }
public boolean isHiddenInPortal(BlockPos localPos) { public boolean isHiddenInPortal(BlockPos localPos) {

View file

@ -11,32 +11,31 @@ import com.jozufozu.flywheel.lib.instance.AbstractInstance;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
public class ActorInstance extends AbstractInstance { public class ActorInstance extends AbstractInstance {
public float x; public float x;
public float y; public float y;
public float z; public float z;
public byte blockLight; public byte blockLight;
public byte skyLight; public byte skyLight;
public float rotationOffset; public float rotationOffset;
public byte rotationAxisX; public byte rotationAxisX;
public byte rotationAxisY; public byte rotationAxisY;
public byte rotationAxisZ; public byte rotationAxisZ;
public Quaternionf rotation = new Quaternionf(); public Quaternionf rotation = new Quaternionf();
public byte rotationCenterX = 64; public byte rotationCenterX = 64;
public byte rotationCenterY = 64; public byte rotationCenterY = 64;
public byte rotationCenterZ = 64; public byte rotationCenterZ = 64;
public float speed; public float speed;
public ActorInstance(InstanceType<?> type, InstanceHandle handle) { public ActorInstance(InstanceType<?> type, InstanceHandle handle) {
super(type, handle); super(type, handle);
} }
public ActorInstance setPosition(BlockPos pos) { public ActorInstance setPosition(BlockPos pos) {
this.x = pos.getX(); this.x = pos.getX();
this.y = pos.getY(); this.y = pos.getY();
this.z = pos.getZ(); this.z = pos.getZ();
return this; return this;
} }
public ActorInstance setBlockLight(int blockLight) { public ActorInstance setBlockLight(int blockLight) {
this.blockLight = (byte) blockLight; this.blockLight = (byte) blockLight;
@ -48,39 +47,39 @@ public class ActorInstance extends AbstractInstance {
return this; return this;
} }
public ActorInstance setRotationOffset(float rotationOffset) { public ActorInstance setRotationOffset(float rotationOffset) {
this.rotationOffset = rotationOffset; this.rotationOffset = rotationOffset;
return this; return this;
} }
public ActorInstance setSpeed(float speed) { public ActorInstance setSpeed(float speed) {
this.speed = speed; this.speed = speed;
return this; return this;
} }
public ActorInstance setRotationAxis(Vector3f axis) { public ActorInstance setRotationAxis(Vector3f axis) {
setRotationAxis(axis.x(), axis.y(), axis.z()); setRotationAxis(axis.x(), axis.y(), axis.z());
return this; return this;
} }
public ActorInstance setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) { public ActorInstance setRotationAxis(float rotationAxisX, float rotationAxisY, float rotationAxisZ) {
this.rotationAxisX = (byte) (rotationAxisX * 127); this.rotationAxisX = (byte) (rotationAxisX * 127);
this.rotationAxisY = (byte) (rotationAxisY * 127); this.rotationAxisY = (byte) (rotationAxisY * 127);
this.rotationAxisZ = (byte) (rotationAxisZ * 127); this.rotationAxisZ = (byte) (rotationAxisZ * 127);
return this; return this;
} }
public ActorInstance setRotationCenter(Vector3f axis) { public ActorInstance setRotationCenter(Vector3f axis) {
setRotationCenter(axis.x(), axis.y(), axis.z()); setRotationCenter(axis.x(), axis.y(), axis.z());
return this; return this;
} }
public ActorInstance setRotationCenter(float rotationCenterX, float rotationCenterY, float rotationCenterZ) { public ActorInstance setRotationCenter(float rotationCenterX, float rotationCenterY, float rotationCenterZ) {
this.rotationCenterX = (byte) (rotationCenterX * 127); this.rotationCenterX = (byte) (rotationCenterX * 127);
this.rotationCenterY = (byte) (rotationCenterY * 127); this.rotationCenterY = (byte) (rotationCenterY * 127);
this.rotationCenterZ = (byte) (rotationCenterZ * 127); this.rotationCenterZ = (byte) (rotationCenterZ * 127);
return this; return this;
} }
public ActorInstance setLocalRotation(Quaternionfc q) { public ActorInstance setLocalRotation(Quaternionfc q) {
this.rotation.set(q); this.rotation.set(q);

View file

@ -138,11 +138,6 @@ public class ContraptionControlsMovement implements MovementBehaviour {
.string(); .string();
} }
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void renderInContraption(MovementContext ctx, VirtualRenderWorld renderWorld, ContraptionMatrices matrices, public void renderInContraption(MovementContext ctx, VirtualRenderWorld renderWorld, ContraptionMatrices matrices,

View file

@ -5,11 +5,11 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableBoolean;
import com.jozufozu.flywheel.api.visualization.VisualizationContext; import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour; import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorVisual; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
@ -45,25 +45,6 @@ public class HarvesterMovementBehaviour implements MovementBehaviour {
.getOpposite()); .getOpposite());
} }
@Override
public boolean hasSpecialInstancedRendering() {
return true;
}
@Nullable
@Override
public ActorVisual createInstance(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) {
return new HarvesterActorVisual(visualizationContext, simulationWorld, movementContext);
}
@Override
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffers) {
if (!ContraptionRenderDispatcher.canInstance())
HarvesterRenderer.renderInContraption(context, renderWorld, matrices, buffers);
}
@Override @Override
public Vec3 getActiveAreaOffset(MovementContext context) { public Vec3 getActiveAreaOffset(MovementContext context) {
return Vec3.atLowerCornerOf(context.state.getValue(HarvesterBlock.FACING) return Vec3.atLowerCornerOf(context.state.getValue(HarvesterBlock.FACING)
@ -218,4 +199,23 @@ public class HarvesterMovementBehaviour implements MovementBehaviour {
.createLegacyBlock(); .createLegacyBlock();
} }
@Override
public boolean disableBlockEntityRendering() {
return true;
}
@Override
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffers) {
if (!VisualizationManager.supportsVisualization(context.world))
HarvesterRenderer.renderInContraption(context, renderWorld, matrices, buffers);
}
@Nullable
@Override
public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) {
return new HarvesterActorVisual(visualizationContext, simulationWorld, movementContext);
}
} }

View file

@ -6,7 +6,6 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer; import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
@ -15,6 +14,7 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld; import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -54,7 +54,7 @@ public class HarvesterRenderer extends SafeBlockEntityRenderer<HarvesterBlockEnt
transform(context.world, facing, superBuffer, speed, PIVOT); transform(context.world, facing, superBuffer, speed, PIVOT);
superBuffer superBuffer
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .light(matrices.getWorld(), LevelRenderer.getLightColor(renderWorld, context.localPos))
.renderInto(matrices.getViewProjection(), buffers.getBuffer(RenderType.cutoutMipped())); .renderInto(matrices.getViewProjection(), buffers.getBuffer(RenderType.cutoutMipped()));
} }

View file

@ -5,11 +5,11 @@ import java.util.Optional;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.visualization.VisualizationContext; import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour; import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorVisual; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.trains.entity.CarriageContraption; import com.simibubi.create.content.trains.entity.CarriageContraption;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.animation.LerpedFloat; import com.simibubi.create.foundation.utility.animation.LerpedFloat;
@ -40,13 +40,13 @@ public class PortableStorageInterfaceMovement implements MovementBehaviour {
} }
@Override @Override
public boolean hasSpecialInstancedRendering() { public boolean disableBlockEntityRendering() {
return true; return true;
} }
@Nullable @Nullable
@Override @Override
public ActorVisual createInstance(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld, public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) { MovementContext movementContext) {
return new PSIActorVisual(visualizationContext, simulationWorld, movementContext); return new PSIActorVisual(visualizationContext, simulationWorld, movementContext);
} }
@ -55,7 +55,7 @@ public class PortableStorageInterfaceMovement implements MovementBehaviour {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffer) { ContraptionMatrices matrices, MultiBufferSource buffer) {
if (!ContraptionRenderDispatcher.canInstance()) if (!VisualizationManager.supportsVisualization(context.world))
PortableStorageInterfaceRenderer.renderInContraption(context, renderWorld, matrices, buffer); PortableStorageInterfaceRenderer.renderInContraption(context, renderWorld, matrices, buffer);
} }

View file

@ -10,7 +10,6 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer; import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
@ -19,6 +18,7 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.animation.LerpedFloat; import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld; import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -56,7 +56,7 @@ public class PortableStorageInterfaceRenderer extends SafeBlockEntityRenderer<Po
boolean lit = animation.settled(); boolean lit = animation.settled();
render(blockState, lit, progress, matrices.getModel(), render(blockState, lit, progress, matrices.getModel(),
sbb -> sbb sbb -> sbb
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .light(matrices.getWorld(), LevelRenderer.getLightColor(renderWorld, context.localPos))
.renderInto(matrices.getViewProjection(), vb)); .renderInto(matrices.getViewProjection(), vb));
} }

View file

@ -10,13 +10,13 @@ import java.util.function.BiConsumer;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.jozufozu.flywheel.api.visualization.VisualizationContext; import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.actors.roller.RollerBlockEntity.RollingMode; import com.simibubi.create.content.contraptions.actors.roller.RollerBlockEntity.RollingMode;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.pulley.PulleyContraption; import com.simibubi.create.content.contraptions.pulley.PulleyContraption;
import com.simibubi.create.content.contraptions.render.ActorVisual; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour; import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour;
import com.simibubi.create.content.logistics.filter.FilterItemStack; import com.simibubi.create.content.logistics.filter.FilterItemStack;
import com.simibubi.create.content.trains.bogey.StandardBogeyBlock; import com.simibubi.create.content.trains.bogey.StandardBogeyBlock;
@ -70,13 +70,13 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
} }
@Override @Override
public boolean hasSpecialInstancedRendering() { public boolean disableBlockEntityRendering() {
return true; return true;
} }
@Nullable @Nullable
@Override @Override
public ActorVisual createInstance(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld, public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) { MovementContext movementContext) {
return new RollerActorVisual(visualizationContext, simulationWorld, movementContext); return new RollerActorVisual(visualizationContext, simulationWorld, movementContext);
} }
@ -84,7 +84,7 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
@Override @Override
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffers) { ContraptionMatrices matrices, MultiBufferSource buffers) {
if (!ContraptionRenderDispatcher.canInstance()) if (!VisualizationManager.supportsVisualization(context.world))
RollerRenderer.renderInContraption(context, renderWorld, matrices, buffers); RollerRenderer.renderInContraption(context, renderWorld, matrices, buffers);
} }

View file

@ -7,7 +7,6 @@ import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.actors.harvester.HarvesterRenderer; import com.simibubi.create.content.contraptions.actors.harvester.HarvesterRenderer;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.blockEntity.renderer.SmartBlockEntityRenderer; import com.simibubi.create.foundation.blockEntity.renderer.SmartBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
@ -15,6 +14,7 @@ import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld; import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context;
@ -73,7 +73,7 @@ public class RollerRenderer extends SmartBlockEntityRenderer<RollerBlockEntity>
PoseStack viewProjection = matrices.getViewProjection(); PoseStack viewProjection = matrices.getViewProjection();
viewProjection.pushPose(); viewProjection.pushPose();
viewProjection.translate(0, -.25, 0); viewProjection.translate(0, -.25, 0);
int contraptionWorldLight = ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld); int contraptionWorldLight = LevelRenderer.getLightColor(renderWorld, context.localPos);
superBuffer.translate(0, -.5, .5) superBuffer.translate(0, -.5, .5)
.rotateYDegrees(90) .rotateYDegrees(90)
.light(matrices.getWorld(), contraptionWorldLight) .light(matrices.getWorld(), contraptionWorldLight)

View file

@ -5,13 +5,13 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld; import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -32,7 +32,7 @@ public class ControlsRenderer {
.center() .center()
.rotateYDegrees(hAngle) .rotateYDegrees(hAngle)
.uncenter() .uncenter()
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .light(matrices.getWorld(), LevelRenderer.getLightColor(renderWorld, context.localPos))
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.cutoutMipped())); .renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.cutoutMipped()));
double yOffset = Mth.lerp(equipAnimation * equipAnimation, -0.15f, 0.05f); double yOffset = Mth.lerp(equipAnimation * equipAnimation, -0.15f, 0.05f);
@ -52,7 +52,7 @@ public class ControlsRenderer {
.translate(0, -2 / 16f, -3 / 16f) .translate(0, -2 / 16f, -3 / 16f)
.translate(first ? 0 : 6 / 16f, 0, 0); .translate(first ? 0 : 6 / 16f, 0, 0);
lever.transform(ms) lever.transform(ms)
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .light(matrices.getWorld(), LevelRenderer.getLightColor(renderWorld, context.localPos))
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid())); .renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid()));
ms.popPose(); ms.popPose();
} }

View file

@ -5,6 +5,7 @@ import javax.annotation.Nullable;
import org.joml.Quaternionf; import org.joml.Quaternionf;
import com.jozufozu.flywheel.api.visualization.VisualizationContext; import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.jozufozu.flywheel.lib.model.baked.PartialModel; import com.jozufozu.flywheel.lib.model.baked.PartialModel;
import com.mojang.math.Axis; import com.mojang.math.Axis;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
@ -15,12 +16,12 @@ import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorVisual; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld; import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
@ -36,11 +37,16 @@ public class StabilizedBearingMovementBehaviour implements MovementBehaviour {
return null; return null;
} }
@Override
public boolean disableBlockEntityRendering() {
return true;
}
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffer) { ContraptionMatrices matrices, MultiBufferSource buffer) {
if (ContraptionRenderDispatcher.canInstance()) if (!VisualizationManager.supportsVisualization(context.world))
return; return;
Direction facing = context.state.getValue(BlockStateProperties.FACING); Direction facing = context.state.getValue(BlockStateProperties.FACING);
@ -67,18 +73,13 @@ public class StabilizedBearingMovementBehaviour implements MovementBehaviour {
// render // render
superBuffer superBuffer
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .light(matrices.getWorld(), LevelRenderer.getLightColor(renderWorld, context.localPos))
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid())); .renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid()));
} }
@Override
public boolean hasSpecialInstancedRendering() {
return true;
}
@Nullable @Nullable
@Override @Override
public ActorVisual createInstance(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld, public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) { MovementContext movementContext) {
return new StabilizedBearingVisual(visualizationContext, simulationWorld, movementContext); return new StabilizedBearingVisual(visualizationContext, simulationWorld, movementContext);
} }

View file

@ -11,12 +11,6 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
public class BellMovementBehaviour implements MovementBehaviour { public class BellMovementBehaviour implements MovementBehaviour {
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override @Override
public boolean isActive(MovementContext context) { public boolean isActive(MovementContext context) {
return MovementBehaviour.super.isActive(context) && !(context.contraption instanceof CarriageContraption); return MovementBehaviour.super.isActive(context) && !(context.contraption instanceof CarriageContraption);

View file

@ -5,11 +5,6 @@ import net.minecraft.util.RandomSource;
import net.minecraft.world.level.block.CampfireBlock; import net.minecraft.world.level.block.CampfireBlock;
public class CampfireMovementBehaviour implements MovementBehaviour { public class CampfireMovementBehaviour implements MovementBehaviour {
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override @Override
public void tick(MovementContext context) { public void tick(MovementContext context) {
if (context.world == null || !context.world.isClientSide || context.position == null if (context.world == null || !context.world.isClientSide || context.position == null

View file

@ -80,11 +80,7 @@ public interface MovementBehaviour {
default void writeExtraData(MovementContext context) {} default void writeExtraData(MovementContext context) {}
default boolean renderAsNormalBlockEntity() { default boolean disableBlockEntityRendering() {
return false;
}
default boolean hasSpecialInstancedRendering() {
return false; return false;
} }
@ -94,7 +90,7 @@ public interface MovementBehaviour {
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@Nullable @Nullable
default ActorVisual createInstance(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld, default ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) { MovementContext movementContext) {
return null; return null;
} }

View file

@ -1,16 +1,30 @@
package com.simibubi.create.content.contraptions.render; package com.simibubi.create.content.contraptions.render;
import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.jozufozu.flywheel.lib.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.foundation.render.BlockEntityRenderHelper;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> extends EntityRenderer<C> { public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> extends EntityRenderer<C> {
public ContraptionEntityRenderer(EntityRendererProvider.Context context) { public ContraptionEntityRenderer(EntityRendererProvider.Context context) {
super(context); super(context);
} }
@ -21,7 +35,7 @@ public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> exte
} }
@Override @Override
public boolean shouldRender(C entity, Frustum clippingHelper, double cameraX, double cameraY, public boolean shouldRender(C entity, Frustum frustum, double cameraX, double cameraY,
double cameraZ) { double cameraZ) {
if (entity.getContraption() == null) if (entity.getContraption() == null)
return false; return false;
@ -30,18 +44,72 @@ public class ContraptionEntityRenderer<C extends AbstractContraptionEntity> exte
if (!entity.isReadyForRender()) if (!entity.isReadyForRender())
return false; return false;
return super.shouldRender(entity, clippingHelper, cameraX, cameraY, cameraZ); return super.shouldRender(entity, frustum, cameraX, cameraY, cameraZ);
} }
@Override @Override
public void render(C entity, float yaw, float partialTicks, PoseStack ms, MultiBufferSource buffers, public void render(C entity, float yaw, float partialTicks, PoseStack poseStack, MultiBufferSource buffers,
int overlay) { int overlay) {
super.render(entity, yaw, partialTicks, ms, buffers, overlay); super.render(entity, yaw, partialTicks, poseStack, buffers, overlay);
// Contraption contraption = entity.getContraption(); Contraption contraption = entity.getContraption();
// if (contraption != null) { if (contraption == null) {
// ContraptionRenderDispatcher.renderFromEntity(entity, contraption, buffers); return;
// } }
Level level = entity.level();
ContraptionRenderInfo renderInfo = ContraptionRenderInfo.get(contraption);
VirtualRenderWorld renderWorld = renderInfo.getRenderWorld();
ContraptionMatrices matrices = renderInfo.getMatrices();
matrices.setup(poseStack, entity);
if (!VisualizationManager.supportsVisualization(level)) {
for (RenderType renderType : RenderType.chunkBufferLayers()) {
SuperByteBuffer sbb = renderInfo.getBuffer(renderType);
if (!sbb.isEmpty()) {
VertexConsumer vc = buffers.getBuffer(renderType);
sbb.transform(matrices.getModel())
.light(matrices.getWorld())
.hybridLight()
.renderInto(poseStack, vc);
}
}
}
renderBlockEntities(level, renderWorld, contraption, matrices, buffers);
renderActors(level, renderWorld, contraption, matrices, buffers);
matrices.clear();
} }
private static void renderBlockEntities(Level level, VirtualRenderWorld renderWorld, Contraption c,
ContraptionMatrices matrices, MultiBufferSource buffer) {
BlockEntityRenderHelper.renderBlockEntities(level, renderWorld, c.getRenderedBEs(),
matrices.getModelViewProjection(), matrices.getLight(), buffer);
}
private static void renderActors(Level level, VirtualRenderWorld renderWorld, Contraption c,
ContraptionMatrices matrices, MultiBufferSource buffer) {
PoseStack m = matrices.getModel();
for (Pair<StructureTemplate.StructureBlockInfo, MovementContext> actor : c.getActors()) {
MovementContext context = actor.getRight();
if (context == null)
continue;
if (context.world == null)
context.world = level;
StructureTemplate.StructureBlockInfo blockInfo = actor.getLeft();
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
if (movementBehaviour != null) {
if (c.isHiddenInPortal(blockInfo.pos()))
continue;
m.pushPose();
TransformStack.of(m)
.translate(blockInfo.pos());
movementBehaviour.renderInContraption(context, renderWorld, matrices, buffer);
m.popPose();
}
}
}
} }

View file

@ -22,9 +22,7 @@ public class ContraptionMatrices {
private final Matrix4f world = new Matrix4f(); private final Matrix4f world = new Matrix4f();
private final Matrix4f light = new Matrix4f(); private final Matrix4f light = new Matrix4f();
private boolean ready; void setup(PoseStack viewProjection, AbstractContraptionEntity entity) {
public void setup(PoseStack viewProjection, AbstractContraptionEntity entity) {
float partialTicks = AnimationTickHolder.getPartialTicks(); float partialTicks = AnimationTickHolder.getPartialTicks();
this.viewProjection.pushPose(); this.viewProjection.pushPose();
@ -41,17 +39,14 @@ public class ContraptionMatrices {
light.set(world); light.set(world);
light.mul(model.last() light.mul(model.last()
.pose()); .pose());
ready = true;
} }
public void clear() { void clear() {
clearStack(modelViewProjection); clearStack(modelViewProjection);
clearStack(viewProjection); clearStack(viewProjection);
clearStack(model); clearStack(model);
world.identity(); world.identity();
light.identity(); light.identity();
ready = false;
} }
public PoseStack getModelViewProjection() { public PoseStack getModelViewProjection() {
@ -74,10 +69,6 @@ public class ContraptionMatrices {
return light; return light;
} }
public boolean isReady() {
return ready;
}
public static void transform(PoseStack ms, PoseStack transform) { public static void transform(PoseStack ms, PoseStack transform) {
ms.last() ms.last()
.pose() .pose()

View file

@ -1,31 +0,0 @@
package com.simibubi.create.content.contraptions.render;
public class ContraptionProgram {
// protected final int uLightBoxSize;
// protected final int uLightBoxMin;
// protected final int uModel;
//
// protected int uLightVolume;
//
// public ContraptionProgram(ResourceLocation name, int handle) {
// super(handle);
// uLightBoxSize = getUniformLocation("uLightBoxSize");
// uLightBoxMin = getUniformLocation("uLightBoxMin");
// uModel = getUniformLocation("uModel");
// }
//
// @Override
// protected void registerSamplers() {
// super.registerSamplers();
// uLightVolume = setSamplerBinding("uLightVolume", 4);
// }
//
// public void bind(Matrix4f model, AABB lightVolume) {
// double sizeX = lightVolume.maxX - lightVolume.minX;
// double sizeY = lightVolume.maxY - lightVolume.minY;
// double sizeZ = lightVolume.maxZ - lightVolume.minZ;
// GL20.glUniform3f(uLightBoxSize, (float) sizeX, (float) sizeY, (float) sizeZ);
// GL20.glUniform3f(uLightBoxMin, (float) lightVolume.minX, (float) lightVolume.minY, (float) lightVolume.minZ);
// // uploadMatrixUniform(uModel, model);
// }
}

View file

@ -1,182 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
import com.jozufozu.flywheel.api.event.RenderStageEvent;
import com.jozufozu.flywheel.backend.gl.error.GlError;
import com.jozufozu.flywheel.lib.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionWorld;
import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.foundation.render.BlockEntityRenderHelper;
import com.simibubi.create.foundation.utility.WorldAttached;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.common.Mod;
@OnlyIn(Dist.CLIENT)
@Mod.EventBusSubscriber(Dist.CLIENT)
public class ContraptionRenderDispatcher {
private static WorldAttached<ContraptionRenderingWorld<?>> WORLDS = new WorldAttached<>(SBBContraptionManager::new);
/**
* Reset a contraption's renderer.
*
* @param contraption The contraption to invalidate.
* @return true if there was a renderer associated with the given contraption.
*/
public static boolean invalidate(Contraption contraption) {
Level level = contraption.entity.level();
return WORLDS.get(level)
.invalidate(contraption);
}
public static void tick(Level world) {
if (Minecraft.getInstance()
.isPaused())
return;
WORLDS.get(world)
.tick();
}
public static void beginFrame(BeginFrameEvent event) {
WORLDS.get(event.getContext()
.level())
.beginFrame(event);
}
public static void renderLayer(RenderStageEvent event) {
WORLDS.get(event.getLevel())
.renderLayer(event);
GlError.pollAndThrow(() -> "contraption layer: " + event.getStage());
}
public static void onRendererReload(ReloadLevelRendererEvent event) {
reset();
}
public static void renderFromEntity(AbstractContraptionEntity entity, Contraption contraption,
MultiBufferSource buffers) {
Level world = entity.level();
ContraptionRenderInfo renderInfo = WORLDS.get(world)
.getRenderInfo(contraption);
ContraptionMatrices matrices = renderInfo.getMatrices();
// something went wrong with the other rendering
if (!matrices.isReady())
return;
VirtualRenderWorld renderWorld = renderInfo.renderWorld;
renderBlockEntities(world, renderWorld, contraption, matrices, buffers);
if (buffers instanceof MultiBufferSource.BufferSource)
((MultiBufferSource.BufferSource) buffers).endBatch();
renderActors(world, renderWorld, contraption, matrices, buffers);
}
public static VirtualRenderWorld setupRenderWorld(Level world, Contraption c) {
ContraptionWorld contraptionWorld = c.getContraptionWorld();
BlockPos origin = c.anchor;
int minBuildHeight = contraptionWorld.getMinBuildHeight();
int height = contraptionWorld.getHeight();
VirtualRenderWorld renderWorld = new VirtualRenderWorld(world, minBuildHeight, height, origin) {
@Override
public boolean supportsVisualization() {
return canInstance();
}
};
renderWorld.setBlockEntities(c.presentBlockEntities.values());
for (StructureTemplate.StructureBlockInfo info : c.getBlocks()
.values())
// Skip individual lighting updates to prevent lag with large contraptions
// FIXME 1.20 this '0' used to be Block.UPDATE_SUPPRESS_LIGHT, yet VirtualRenderWorld didn't actually parse the flags at all
renderWorld.setBlock(info.pos(), info.state(), 0);
renderWorld.runLightEngine();
return renderWorld;
}
public static void renderBlockEntities(Level world, VirtualRenderWorld renderWorld, Contraption c,
ContraptionMatrices matrices, MultiBufferSource buffer) {
BlockEntityRenderHelper.renderBlockEntities(world, renderWorld, c.getSpecialRenderedBEs(),
matrices.getModelViewProjection(), matrices.getLight(), buffer);
}
protected static void renderActors(Level world, VirtualRenderWorld renderWorld, Contraption c,
ContraptionMatrices matrices, MultiBufferSource buffer) {
PoseStack m = matrices.getModel();
for (Pair<StructureTemplate.StructureBlockInfo, MovementContext> actor : c.getActors()) {
MovementContext context = actor.getRight();
if (context == null)
continue;
if (context.world == null)
context.world = world;
StructureTemplate.StructureBlockInfo blockInfo = actor.getLeft();
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
if (movementBehaviour != null) {
if (c.isHiddenInPortal(blockInfo.pos()))
continue;
m.pushPose();
TransformStack.of(m)
.translate(blockInfo.pos());
movementBehaviour.renderInContraption(context, renderWorld, matrices, buffer);
m.popPose();
}
}
}
public static int getLight(Level world, float lx, float ly, float lz) {
BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos();
float block = 0, sky = 0;
float offset = 1 / 8f;
for (float zOffset = offset; zOffset >= -offset; zOffset -= 2 * offset)
for (float yOffset = offset; yOffset >= -offset; yOffset -= 2 * offset)
for (float xOffset = offset; xOffset >= -offset; xOffset -= 2 * offset) {
pos.set(lx + xOffset, ly + yOffset, lz + zOffset);
block += world.getBrightness(LightLayer.BLOCK, pos) / 8f;
sky += world.getBrightness(LightLayer.SKY, pos) / 8f;
}
return LightTexture.pack((int) block, (int) sky);
}
public static int getContraptionWorldLight(MovementContext context, VirtualRenderWorld renderWorld) {
return LevelRenderer.getLightColor(renderWorld, context.localPos);
}
public static void reset() {
}
public static boolean canInstance() {
return false;
}
}

View file

@ -1,78 +1,156 @@
package com.simibubi.create.content.contraptions.render; package com.simibubi.create.content.contraptions.render;
import com.jozufozu.flywheel.api.event.BeginFrameEvent; import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.jozufozu.flywheel.lib.model.ModelUtil;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity; import com.mojang.blaze3d.vertex.VertexFormat;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.Contraption; import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.content.contraptions.Contraption.RenderedBlocks;
import com.simibubi.create.content.contraptions.ContraptionWorld;
import com.simibubi.create.foundation.render.ShadeSeparatingVertexConsumer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.render.VirtualRenderHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld; import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.util.Mth; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
import net.minecraftforge.client.model.data.ModelData;
public class ContraptionRenderInfo { public class ContraptionRenderInfo {
public final Contraption contraption; public static final SuperByteBufferCache.Compartment<Pair<Contraption, RenderType>> CONTRAPTION = new SuperByteBufferCache.Compartment<>();
public final VirtualRenderWorld renderWorld; private static final ThreadLocal<ThreadLocalObjects> THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
private final Contraption contraption;
private final VirtualRenderWorld renderWorld;
private final ContraptionMatrices matrices = new ContraptionMatrices(); private final ContraptionMatrices matrices = new ContraptionMatrices();
private boolean visible;
public ContraptionRenderInfo(Contraption contraption, VirtualRenderWorld renderWorld) { ContraptionRenderInfo(Level level, Contraption contraption) {
this.contraption = contraption; this.contraption = contraption;
this.renderWorld = renderWorld; this.renderWorld = setupRenderWorld(level, contraption);
} }
public int getEntityId() { public static ContraptionRenderInfo get(Contraption contraption) {
return contraption.entity.getId(); return ContraptionRenderInfoManager.MANAGERS.get(contraption.entity.level()).getRenderInfo(contraption);
}
/**
* Reset a contraption's renderer.
*
* @param contraption The contraption to invalidate.
* @return true if there was a renderer associated with the given contraption.
*/
public static boolean invalidate(Contraption contraption) {
return ContraptionRenderInfoManager.MANAGERS.get(contraption.entity.level()).invalidate(contraption);
} }
public boolean isDead() { public boolean isDead() {
return !contraption.entity.isAliveOrStale(); return !contraption.entity.isAliveOrStale();
} }
public void beginFrame(BeginFrameEvent event) { public Contraption getContraption() {
matrices.clear(); return contraption;
AbstractContraptionEntity entity = contraption.entity;
visible = false;
// visible = event.getFrustum()
// .isVisible(entity.getBoundingBoxForCulling()
// .inflate(2));
} }
public boolean isVisible() { public VirtualRenderWorld getRenderWorld() {
return visible && contraption.entity.isAliveOrStale() && contraption.entity.isReadyForRender(); return renderWorld;
} }
/**
* Need to call this during RenderLayerEvent.
*/
public void setupMatrices(PoseStack viewProjection, double camX, double camY, double camZ) {
if (!matrices.isReady()) {
AbstractContraptionEntity entity = contraption.entity;
viewProjection.pushPose();
double x = Mth.lerp(AnimationTickHolder.getPartialTicks(), entity.xOld, entity.getX()) - camX;
double y = Mth.lerp(AnimationTickHolder.getPartialTicks(), entity.yOld, entity.getY()) - camY;
double z = Mth.lerp(AnimationTickHolder.getPartialTicks(), entity.zOld, entity.getZ()) - camZ;
viewProjection.translate(x, y, z);
matrices.setup(viewProjection, entity);
viewProjection.popPose();
}
}
/**
* If #setupMatrices is called correctly, the returned matrices will be ready
*/
public ContraptionMatrices getMatrices() { public ContraptionMatrices getMatrices() {
return matrices; return matrices;
} }
public void invalidate() { public SuperByteBuffer getBuffer(RenderType renderType) {
return CreateClient.BUFFER_CACHE.get(CONTRAPTION, Pair.of(contraption, renderType), () -> buildStructureBuffer(renderType));
}
public void invalidate() {
for (RenderType renderType : RenderType.chunkBufferLayers()) {
CreateClient.BUFFER_CACHE.invalidate(CONTRAPTION, Pair.of(contraption, renderType));
}
}
public static VirtualRenderWorld setupRenderWorld(Level level, Contraption c) {
ContraptionWorld contraptionWorld = c.getContraptionWorld();
BlockPos origin = c.anchor;
int minBuildHeight = contraptionWorld.getMinBuildHeight();
int height = contraptionWorld.getHeight();
VirtualRenderWorld renderWorld = new VirtualRenderWorld(level, minBuildHeight, height, origin) {
@Override
public boolean supportsVisualization() {
return VisualizationManager.supportsVisualization(level);
}
};
renderWorld.setBlockEntities(c.presentBlockEntities.values());
for (StructureTemplate.StructureBlockInfo info : c.getBlocks()
.values())
renderWorld.setBlock(info.pos(), info.state(), 0);
renderWorld.runLightEngine();
return renderWorld;
}
private SuperByteBuffer buildStructureBuffer(RenderType layer) {
BlockRenderDispatcher dispatcher = ModelUtil.VANILLA_RENDERER;
ModelBlockRenderer renderer = dispatcher.getModelRenderer();
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
PoseStack poseStack = objects.poseStack;
RandomSource random = objects.random;
RenderedBlocks blocks = contraption.getRenderedBlocks();
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
BufferBuilder shadedBuilder = objects.shadedBuilder;
BufferBuilder unshadedBuilder = objects.unshadedBuilder;
shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder);
ModelBlockRenderer.enableCaching();
for (BlockPos pos : blocks.positions()) {
BlockState state = blocks.lookup().apply(pos);
if (state.getRenderShape() == RenderShape.MODEL) {
BakedModel model = dispatcher.getBlockModel(state);
ModelData modelData = contraption.modelData.getOrDefault(pos, ModelData.EMPTY);
modelData = model.getModelData(renderWorld, pos, state, modelData);
long randomSeed = state.getSeed(pos);
random.setSeed(randomSeed);
if (model.getRenderTypes(state, random, modelData).contains(layer)) {
poseStack.pushPose();
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, shadeSeparatingWrapper, true, random, randomSeed, OverlayTexture.NO_OVERLAY, modelData, layer);
poseStack.popPose();
}
}
}
ModelBlockRenderer.clearCache();
shadeSeparatingWrapper.clear();
return VirtualRenderHelper.endAndCombine(shadedBuilder, unshadedBuilder);
}
private static class ThreadLocalObjects {
public final PoseStack poseStack = new PoseStack();
public final RandomSource random = RandomSource.createNewThreadLocalInstance();
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();
public final BufferBuilder shadedBuilder = new BufferBuilder(512);
public final BufferBuilder unshadedBuilder = new BufferBuilder(512);
} }
} }

View file

@ -0,0 +1,84 @@
package com.simibubi.create.content.contraptions.render;
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.foundation.utility.WorldAttached;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.client.Minecraft;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(Dist.CLIENT)
public class ContraptionRenderInfoManager {
static final WorldAttached<ContraptionRenderInfoManager> MANAGERS = new WorldAttached<>(ContraptionRenderInfoManager::new);
private final Level level;
private final Int2ObjectMap<ContraptionRenderInfo> renderInfos = new Int2ObjectOpenHashMap<>();
private int removalTimer;
private ContraptionRenderInfoManager(LevelAccessor level) {
this.level = (Level) level;
}
public static void tickFor(Level level) {
if (Minecraft.getInstance()
.isPaused())
return;
MANAGERS.get(level)
.tick();
}
public static void resetAll() {
MANAGERS.empty(ContraptionRenderInfoManager::delete);
}
@SubscribeEvent
public static void onReloadLevelRenderer(ReloadLevelRendererEvent event) {
resetAll();
}
ContraptionRenderInfo getRenderInfo(Contraption contraption) {
int entityId = contraption.entity.getId();
ContraptionRenderInfo renderInfo = renderInfos.get(entityId);
if (renderInfo == null) {
renderInfo = new ContraptionRenderInfo(level, contraption);
renderInfos.put(entityId, renderInfo);
}
return renderInfo;
}
boolean invalidate(Contraption contraption) {
int entityId = contraption.entity.getId();
ContraptionRenderInfo renderInfo = renderInfos.remove(entityId);
if (renderInfo != null) {
renderInfo.invalidate();
return true;
}
return false;
}
private void tick() {
if (removalTimer >= 20) {
renderInfos.values().removeIf(ContraptionRenderInfo::isDead);
removalTimer = 0;
}
removalTimer++;
}
private void delete() {
for (ContraptionRenderInfo renderer : renderInfos.values()) {
renderer.invalidate();
}
renderInfos.clear();
}
}

View file

@ -1,118 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import java.lang.ref.Reference;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
import com.jozufozu.flywheel.api.event.RenderStageEvent;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.ContraptionHandler;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
public abstract class ContraptionRenderingWorld<C extends ContraptionRenderInfo> {
protected final Level world;
private int removalTimer;
protected final Int2ObjectMap<C> renderInfos = new Int2ObjectOpenHashMap<>();
protected final List<C> visible = new ObjectArrayList<>();
public ContraptionRenderingWorld(LevelAccessor world) {
this.world = (Level) world;
}
public boolean invalidate(Contraption contraption) {
int entityId = contraption.entity.getId();
C removed = renderInfos.remove(entityId);
if (removed != null) {
removed.invalidate();
visible.remove(removed);
return true;
}
return false;
}
public void renderLayer(RenderStageEvent event) {
var position = event.getCamera()
.getPosition();
for (C c : visible) {
c.setupMatrices(event.getStack(), position.x, position.y, position.z);
}
}
protected abstract C create(Contraption c);
public void tick() {
removalTimer++;
if (removalTimer >= 20) {
removeDeadRenderers();
removalTimer = 0;
}
ContraptionHandler.loadedContraptions.get(world)
.values()
.stream()
.map(Reference::get)
.filter(Objects::nonNull)
.map(AbstractContraptionEntity::getContraption)
.filter(Objects::nonNull) // contraptions that are too large will not be synced, and un-synced contraptions will be null
.forEach(this::getRenderInfo);
}
public void beginFrame(BeginFrameEvent event) {
renderInfos.int2ObjectEntrySet()
.stream()
.map(Map.Entry::getValue)
.forEach(renderInfo -> renderInfo.beginFrame(event));
collectVisible();
}
protected void collectVisible() {
visible.clear();
renderInfos.int2ObjectEntrySet()
.stream()
.map(Map.Entry::getValue)
.filter(ContraptionRenderInfo::isVisible)
.forEach(visible::add);
}
public C getRenderInfo(Contraption c) {
int entityId = c.entity.getId();
C renderInfo = renderInfos.get(entityId);
if (renderInfo == null) {
renderInfo = create(c);
renderInfos.put(entityId, renderInfo);
}
return renderInfo;
}
public void delete() {
for (C renderer : renderInfos.values()) {
renderer.invalidate();
}
renderInfos.clear();
}
/**
* Remove all render infos associated with dead/removed contraptions.
*/
public void removeDeadRenderers() {
renderInfos.values().removeIf(ContraptionRenderInfo::isDead);
}
}

View file

@ -73,7 +73,7 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
setEmbeddingMatrices(partialTick); setEmbeddingMatrices(partialTick);
Contraption contraption = entity.getContraption(); Contraption contraption = entity.getContraption();
virtualRenderWorld = ContraptionRenderDispatcher.setupRenderWorld(level, contraption); virtualRenderWorld = ContraptionRenderInfo.setupRenderWorld(level, contraption);
RenderedBlocks blocks = contraption.getRenderedBlocks(); RenderedBlocks blocks = contraption.getRenderedBlocks();
BlockAndTintGetter modelWorld = new WrappedBlockAndTintGetter(virtualRenderWorld) { BlockAndTintGetter modelWorld = new WrappedBlockAndTintGetter(virtualRenderWorld) {
@ -91,7 +91,7 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
.instancer(InstanceTypes.TRANSFORMED, model) .instancer(InstanceTypes.TRANSFORMED, model)
.createInstance(); .createInstance();
for (BlockEntity be : contraption.maybeInstancedBlockEntities) { for (BlockEntity be : contraption.getRenderedBEs()) {
setupVisualizer(be, partialTick); setupVisualizer(be, partialTick);
} }
@ -102,32 +102,6 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
updateLight(); updateLight();
} }
private void setupActor(MutablePair<StructureTemplate.StructureBlockInfo, MovementContext> actor, float partialTick) {
MovementContext context = actor.getRight();
if (context == null) {
return;
}
if (context.world == null) {
context.world = level;
}
StructureTemplate.StructureBlockInfo blockInfo = actor.getLeft();
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
if (movementBehaviour == null) {
return;
}
var instance = movementBehaviour.createInstance(this.embedding, virtualRenderWorld, context);
if (instance == null) {
return;
}
instance.init(partialTick);
actors.add(instance);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
protected <T extends BlockEntity> void setupVisualizer(T be, float partialTicks) { protected <T extends BlockEntity> void setupVisualizer(T be, float partialTicks) {
BlockEntityVisualizer<? super T> visualizer = (BlockEntityVisualizer<? super T>) VisualizerRegistry.getVisualizer(be.getType()); BlockEntityVisualizer<? super T> visualizer = (BlockEntityVisualizer<? super T>) VisualizerRegistry.getVisualizer(be.getType());
@ -154,6 +128,32 @@ public class ContraptionVisual<E extends AbstractContraptionEntity> extends Abst
be.setLevel(world); be.setLevel(world);
} }
private void setupActor(MutablePair<StructureTemplate.StructureBlockInfo, MovementContext> actor, float partialTick) {
MovementContext context = actor.getRight();
if (context == null) {
return;
}
if (context.world == null) {
context.world = level;
}
StructureTemplate.StructureBlockInfo blockInfo = actor.getLeft();
MovementBehaviour movementBehaviour = AllMovementBehaviours.getBehaviour(blockInfo.state());
if (movementBehaviour == null) {
return;
}
var visual = movementBehaviour.createVisual(this.embedding, virtualRenderWorld, context);
if (visual == null) {
return;
}
visual.init(partialTick);
actors.add(visual);
}
@Override @Override
public Plan<VisualTickContext> planTick() { public Plan<VisualTickContext> planTick() {
return NestedPlan.of( return NestedPlan.of(

View file

@ -7,20 +7,18 @@ import net.minecraft.client.renderer.culling.Frustum;
import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.EntityRendererProvider;
public class OrientedContraptionEntityRenderer extends ContraptionEntityRenderer<OrientedContraptionEntity> { public class OrientedContraptionEntityRenderer extends ContraptionEntityRenderer<OrientedContraptionEntity> {
public OrientedContraptionEntityRenderer(EntityRendererProvider.Context context) { public OrientedContraptionEntityRenderer(EntityRendererProvider.Context context) {
super(context); super(context);
} }
@Override @Override
public boolean shouldRender(OrientedContraptionEntity entity, Frustum p_225626_2_, double p_225626_3_, public boolean shouldRender(OrientedContraptionEntity entity, Frustum frustum, double cameraX, double cameraY,
double p_225626_5_, double p_225626_7_) { double cameraZ) {
if (!super.shouldRender(entity, p_225626_2_, p_225626_3_, p_225626_5_, p_225626_7_)) if (!super.shouldRender(entity, frustum, cameraX, cameraY, cameraZ))
return false; return false;
if (entity.getContraption() if (entity.getContraption()
.getType() == ContraptionType.MOUNTED && entity.getVehicle() == null) .getType() == ContraptionType.MOUNTED && entity.getVehicle() == null)
return false; return false;
return true; return true;
} }
} }

View file

@ -1,127 +0,0 @@
package com.simibubi.create.content.contraptions.render;
import com.jozufozu.flywheel.api.event.RenderStageEvent;
import com.jozufozu.flywheel.lib.model.ModelUtil;
import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.Contraption;
import com.simibubi.create.content.contraptions.Contraption.RenderedBlocks;
import com.simibubi.create.foundation.render.ShadeSeparatingVertexConsumer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.render.VirtualRenderHelper;
import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.data.ModelData;
public class SBBContraptionManager extends ContraptionRenderingWorld<ContraptionRenderInfo> {
public static final SuperByteBufferCache.Compartment<Pair<Contraption, RenderType>> CONTRAPTION = new SuperByteBufferCache.Compartment<>();
private static final ThreadLocal<ThreadLocalObjects> THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
public SBBContraptionManager(LevelAccessor world) {
super(world);
}
@Override
public void renderLayer(RenderStageEvent event) {
super.renderLayer(event);
// RenderType type = event.getType();
// VertexConsumer consumer = event.buffers.bufferSource()
// .getBuffer(type);
// visible.forEach(info -> renderContraptionLayerSBB(info, type, consumer));
//
// event.buffers.bufferSource().endBatch(type);
}
@Override
public boolean invalidate(Contraption contraption) {
for (RenderType chunkBufferLayer : RenderType.chunkBufferLayers()) {
CreateClient.BUFFER_CACHE.invalidate(CONTRAPTION, Pair.of(contraption, chunkBufferLayer));
}
return super.invalidate(contraption);
}
@Override
protected ContraptionRenderInfo create(Contraption c) {
VirtualRenderWorld renderWorld = ContraptionRenderDispatcher.setupRenderWorld(world, c);
return new ContraptionRenderInfo(c, renderWorld);
}
private void renderContraptionLayerSBB(ContraptionRenderInfo renderInfo, RenderType layer, VertexConsumer consumer) {
if (!renderInfo.isVisible()) return;
SuperByteBuffer contraptionBuffer = CreateClient.BUFFER_CACHE.get(CONTRAPTION, Pair.of(renderInfo.contraption, layer), () -> buildStructureBuffer(renderInfo.renderWorld, renderInfo.contraption, layer));
if (!contraptionBuffer.isEmpty()) {
ContraptionMatrices matrices = renderInfo.getMatrices();
contraptionBuffer.transform(matrices.getModel())
.light(matrices.getWorld())
.hybridLight()
.renderInto(matrices.getViewProjection(), consumer);
}
}
private static SuperByteBuffer buildStructureBuffer(VirtualRenderWorld renderWorld, Contraption contraption, RenderType layer) {
BlockRenderDispatcher dispatcher = ModelUtil.VANILLA_RENDERER;
ModelBlockRenderer renderer = dispatcher.getModelRenderer();
ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
PoseStack poseStack = objects.poseStack;
RandomSource random = objects.random;
RenderedBlocks blocks = contraption.getRenderedBlocks();
ShadeSeparatingVertexConsumer shadeSeparatingWrapper = objects.shadeSeparatingWrapper;
BufferBuilder shadedBuilder = objects.shadedBuilder;
BufferBuilder unshadedBuilder = objects.unshadedBuilder;
shadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
unshadedBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
shadeSeparatingWrapper.prepare(shadedBuilder, unshadedBuilder);
ModelBlockRenderer.enableCaching();
for (BlockPos pos : blocks.positions()) {
BlockState state = blocks.lookup().apply(pos);
if (state.getRenderShape() == RenderShape.MODEL) {
BakedModel model = dispatcher.getBlockModel(state);
ModelData modelData = contraption.modelData.getOrDefault(pos, ModelData.EMPTY);
modelData = model.getModelData(renderWorld, pos, state, modelData);
long randomSeed = state.getSeed(pos);
random.setSeed(randomSeed);
if (model.getRenderTypes(state, random, modelData).contains(layer)) {
poseStack.pushPose();
poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
renderer.tesselateBlock(renderWorld, model, state, pos, poseStack, shadeSeparatingWrapper, true, random, randomSeed, OverlayTexture.NO_OVERLAY, modelData, layer);
poseStack.popPose();
}
}
}
ModelBlockRenderer.clearCache();
shadeSeparatingWrapper.clear();
return VirtualRenderHelper.endAndCombine(shadedBuilder, unshadedBuilder);
}
private static class ThreadLocalObjects {
public final PoseStack poseStack = new PoseStack();
public final RandomSource random = RandomSource.createNewThreadLocalInstance();
public final ShadeSeparatingVertexConsumer shadeSeparatingWrapper = new ShadeSeparatingVertexConsumer();
public final BufferBuilder shadedBuilder = new BufferBuilder(512);
public final BufferBuilder unshadedBuilder = new BufferBuilder(512);
}
}

View file

@ -32,12 +32,6 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
public class SlidingDoorMovementBehaviour implements MovementBehaviour { public class SlidingDoorMovementBehaviour implements MovementBehaviour {
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override @Override
public boolean mustTickWhileDisabled() { public boolean mustTickWhileDisabled() {
return true; return true;

View file

@ -64,7 +64,7 @@ public class BeltVisual extends KineticBlockEntityVisual<BeltBlockEntity> {
PartialModel beltPartial = BeltRenderer.getBeltPartial(diagonal, start, end, bottom); PartialModel beltPartial = BeltRenderer.getBeltPartial(diagonal, start, end, bottom);
SpriteShiftEntry spriteShift = BeltRenderer.getSpriteShiftEntry(color, diagonal, bottom); SpriteShiftEntry spriteShift = BeltRenderer.getSpriteShiftEntry(color, diagonal, bottom);
Instancer<BeltInstance> beltModel = instancerProvider.instancer(AllInstanceTypes.BELTS, Models.partial(beltPartial)); Instancer<BeltInstance> beltModel = instancerProvider.instancer(AllInstanceTypes.BELT, Models.partial(beltPartial));
keys.add(setup(beltModel.createInstance(), bottom, spriteShift)); keys.add(setup(beltModel.createInstance(), bottom, spriteShift));

View file

@ -9,6 +9,7 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import com.jozufozu.flywheel.api.visualization.VisualizationContext; import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.content.contraptions.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.AbstractContraptionEntity;
@ -18,7 +19,6 @@ import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.mounted.MountedContraption; import com.simibubi.create.content.contraptions.mounted.MountedContraption;
import com.simibubi.create.content.contraptions.render.ActorVisual; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.kinetics.deployer.DeployerBlockEntity.Mode; import com.simibubi.create.content.kinetics.deployer.DeployerBlockEntity.Mode;
import com.simibubi.create.content.logistics.filter.FilterItemStack; import com.simibubi.create.content.logistics.filter.FilterItemStack;
import com.simibubi.create.content.schematics.SchematicInstances; import com.simibubi.create.content.schematics.SchematicInstances;
@ -282,20 +282,20 @@ public class DeployerMovementBehaviour implements MovementBehaviour {
} }
@Override @Override
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, public boolean disableBlockEntityRendering() {
ContraptionMatrices matrices, MultiBufferSource buffers) { return true;
if (!ContraptionRenderDispatcher.canInstance())
DeployerRenderer.renderInContraption(context, renderWorld, matrices, buffers);
} }
@Override @Override
public boolean hasSpecialInstancedRendering() { public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
return true; ContraptionMatrices matrices, MultiBufferSource buffers) {
if (!VisualizationManager.supportsVisualization(context.world))
DeployerRenderer.renderInContraption(context, renderWorld, matrices, buffers);
} }
@Nullable @Nullable
@Override @Override
public ActorVisual createInstance(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld, public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld,
MovementContext movementContext) { MovementContext movementContext) {
return new DeployerActorVisual(visualizationContext, simulationWorld, movementContext); return new DeployerActorVisual(visualizationContext, simulationWorld, movementContext);
} }

View file

@ -13,7 +13,6 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.kinetics.base.IRotate; import com.simibubi.create.content.kinetics.base.IRotate;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer; import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
@ -29,6 +28,7 @@ import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld; import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -213,11 +213,11 @@ public class DeployerRenderer extends SafeBlockEntityRenderer<DeployerBlockEntit
transform(pole, blockState, true); transform(pole, blockState, true);
transform(hand, blockState, false); transform(hand, blockState, false);
shaft.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) shaft.light(matrices.getWorld(), LevelRenderer.getLightColor(renderWorld, context.localPos))
.renderInto(matrices.getViewProjection(), builder); .renderInto(matrices.getViewProjection(), builder);
pole.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) pole.light(matrices.getWorld(), LevelRenderer.getLightColor(renderWorld, context.localPos))
.renderInto(matrices.getViewProjection(), builder); .renderInto(matrices.getViewProjection(), builder);
hand.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) hand.light(matrices.getWorld(), LevelRenderer.getLightColor(renderWorld, context.localPos))
.renderInto(matrices.getViewProjection(), builder); .renderInto(matrices.getViewProjection(), builder);
m.popPose(); m.popPose();

View file

@ -38,7 +38,7 @@ public class DrillActorVisual extends ActorVisual {
else else
eulerY = facing.toYRot() + ((axis == Direction.Axis.X) ? 180 : 0); eulerY = facing.toYRot() + ((axis == Direction.Axis.X) ? 180 : 0);
drillHead = instancerProvider.instancer(AllInstanceTypes.ACTORS, Models.partial(AllPartialModels.DRILL_HEAD)) drillHead = instancerProvider.instancer(AllInstanceTypes.ACTOR, Models.partial(AllPartialModels.DRILL_HEAD))
.createInstance(); .createInstance();
drillHead.setPosition(context.localPos) drillHead.setPosition(context.localPos)
@ -46,12 +46,14 @@ public class DrillActorVisual extends ActorVisual {
.setRotationOffset(0) .setRotationOffset(0)
.setRotationAxis(0, 0, 1) .setRotationAxis(0, 0, 1)
.setLocalRotation(new Quaternionf().rotationXYZ(eulerX * Mth.DEG_TO_RAD, eulerY * Mth.DEG_TO_RAD, 0)) .setLocalRotation(new Quaternionf().rotationXYZ(eulerX * Mth.DEG_TO_RAD, eulerY * Mth.DEG_TO_RAD, 0))
.setSpeed(getSpeed(facing)); .setSpeed(getSpeed(facing))
.setChanged();
} }
@Override @Override
public void beginFrame() { public void beginFrame() {
drillHead.setSpeed(getSpeed(facing)); drillHead.setSpeed(getSpeed(facing))
.setChanged();
} }
protected float getSpeed(Direction facing) { protected float getSpeed(Direction facing) {

View file

@ -3,11 +3,11 @@ package com.simibubi.create.content.kinetics.drill;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.jozufozu.flywheel.api.visualization.VisualizationContext; import com.jozufozu.flywheel.api.visualization.VisualizationContext;
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.simibubi.create.AllTags; import com.simibubi.create.AllTags;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorVisual; import com.simibubi.create.content.contraptions.render.ActorVisual;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour; import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour;
import com.simibubi.create.foundation.damageTypes.CreateDamageSources; import com.simibubi.create.foundation.damageTypes.CreateDamageSources;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
@ -38,21 +38,21 @@ public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour {
} }
@Override @Override
@OnlyIn(value = Dist.CLIENT) public boolean disableBlockEntityRendering() {
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, return true;
ContraptionMatrices matrices, MultiBufferSource buffer) {
if (!ContraptionRenderDispatcher.canInstance())
DrillRenderer.renderInContraption(context, renderWorld, matrices, buffer);
} }
@Override @Override
public boolean hasSpecialInstancedRendering() { @OnlyIn(value = Dist.CLIENT)
return true; public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffer) {
if (!VisualizationManager.supportsVisualization(context.world))
DrillRenderer.renderInContraption(context, renderWorld, matrices, buffer);
} }
@Nullable @Nullable
@Override @Override
public ActorVisual createInstance(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld, MovementContext movementContext) { public ActorVisual createVisual(VisualizationContext visualizationContext, VirtualRenderWorld simulationWorld, MovementContext movementContext) {
return new DrillActorVisual(visualizationContext, simulationWorld, movementContext); return new DrillActorVisual(visualizationContext, simulationWorld, movementContext);
} }

View file

@ -3,7 +3,6 @@ package com.simibubi.create.content.kinetics.drill;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer; import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
@ -12,6 +11,7 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld; import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -49,7 +49,7 @@ public class DrillRenderer extends KineticBlockEntityRenderer<DrillBlockEntity>
.rotateZDegrees(angle) .rotateZDegrees(angle)
.uncenter() .uncenter()
.light(matrices.getWorld(), .light(matrices.getWorld(),
ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) LevelRenderer.getLightColor(renderWorld, context.localPos))
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid())); .renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.solid()));
} }

View file

@ -90,6 +90,11 @@ public class SawMovementBehaviour extends BlockBreakingMovementBehaviour {
world.addFreshEntity(entity); world.addFreshEntity(entity);
} }
@Override
public boolean disableBlockEntityRendering() {
return true;
}
@Override @Override
@OnlyIn(value = Dist.CLIENT) @OnlyIn(value = Dist.CLIENT)
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,

View file

@ -9,7 +9,6 @@ import com.mojang.math.Axis;
import com.simibubi.create.AllPartialModels; import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices; import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.contraptions.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer; import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringRenderer; import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringRenderer;
@ -21,6 +20,7 @@ import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld; import com.simibubi.create.foundation.virtualWorld.VirtualRenderWorld;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
@ -198,7 +198,7 @@ public class SawRenderer extends SafeBlockEntityRenderer<SawBlockEntity> {
} }
superBuffer.uncenter() superBuffer.uncenter()
.light(matrices.getWorld(), ContraptionRenderDispatcher.getContraptionWorldLight(context, renderWorld)) .light(matrices.getWorld(), LevelRenderer.getLightColor(renderWorld, context.localPos))
.renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.cutoutMipped())); .renderInto(matrices.getViewProjection(), buffer.getBuffer(RenderType.cutoutMipped()));
} }

View file

@ -119,9 +119,4 @@ public class FunnelMovementBehaviour implements MovementBehaviour {
} }
} }
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
} }

View file

@ -33,7 +33,7 @@ public class FunnelVisual extends AbstractBlockEntityVisual<FunnelBlockEntity> i
PartialModel flapPartial = (blockState.getBlock() instanceof FunnelBlock ? AllPartialModels.FUNNEL_FLAP PartialModel flapPartial = (blockState.getBlock() instanceof FunnelBlock ? AllPartialModels.FUNNEL_FLAP
: AllPartialModels.BELT_FUNNEL_FLAP); : AllPartialModels.BELT_FUNNEL_FLAP);
Instancer<FlapInstance> model = instancerProvider.instancer(AllInstanceTypes.FLAPS, Models.partial(flapPartial)); Instancer<FlapInstance> model = instancerProvider.instancer(AllInstanceTypes.FLAP, Models.partial(flapPartial));
int blockLight = level.getBrightness(LightLayer.BLOCK, pos); int blockLight = level.getBrightness(LightLayer.BLOCK, pos);
int skyLight = level.getBrightness(LightLayer.SKY, pos); int skyLight = level.getBrightness(LightLayer.SKY, pos);

View file

@ -31,7 +31,7 @@ public class BeltTunnelVisual extends AbstractBlockEntityVisual<BeltTunnelBlockE
} }
private void setupFlaps(float partialTick) { private void setupFlaps(float partialTick) {
Instancer<FlapInstance> model = instancerProvider.instancer(AllInstanceTypes.FLAPS, Models.partial(AllPartialModels.BELT_TUNNEL_FLAP)); Instancer<FlapInstance> model = instancerProvider.instancer(AllInstanceTypes.FLAP, Models.partial(AllPartialModels.BELT_TUNNEL_FLAP));
int blockLight = level.getBrightness(LightLayer.BLOCK, pos); int blockLight = level.getBrightness(LightLayer.BLOCK, pos);
int skyLight = level.getBrightness(LightLayer.SKY, pos); int skyLight = level.getBrightness(LightLayer.SKY, pos);

View file

@ -22,11 +22,6 @@ public class BasinMovementBehaviour implements MovementBehaviour {
return map; return map;
} }
@Override
public boolean renderAsNormalBlockEntity() {
return true;
}
@Override @Override
public void tick(MovementContext context) { public void tick(MovementContext context) {
MovementBehaviour.super.tick(context); MovementBehaviour.super.tick(context);

View file

@ -30,11 +30,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
public class BlazeBurnerMovementBehaviour implements MovementBehaviour { public class BlazeBurnerMovementBehaviour implements MovementBehaviour {
@Override
public boolean renderAsNormalBlockEntity() {
return false;
}
@Override @Override
public ItemStack canBeDisabledVia(MovementContext context) { public ItemStack canBeDisabledVia(MovementContext context) {
return null; return null;
@ -117,6 +112,11 @@ public class BlazeBurnerMovementBehaviour implements MovementBehaviour {
return false; return false;
} }
@Override
public boolean disableBlockEntityRendering() {
return true;
}
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld, public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,

View file

@ -254,17 +254,17 @@ public class CarriageContraption extends Contraption {
return secondBogeyPos; return secondBogeyPos;
} }
private Collection<BlockEntity> specialRenderedBEsOutsidePortal = new ArrayList<>(); private Collection<BlockEntity> renderedBEsOutsidePortal = new ArrayList<>();
@Override @Override
public RenderedBlocks getRenderedBlocks() { public RenderedBlocks getRenderedBlocks() {
if (notInPortal()) if (notInPortal())
return super.getRenderedBlocks(); return super.getRenderedBlocks();
specialRenderedBEsOutsidePortal = new ArrayList<>(); renderedBEsOutsidePortal = new ArrayList<>();
specialRenderedBlockEntities.stream() renderedBlockEntities.stream()
.filter(be -> !isHiddenInPortal(be.getBlockPos())) .filter(be -> !isHiddenInPortal(be.getBlockPos()))
.forEach(specialRenderedBEsOutsidePortal::add); .forEach(renderedBEsOutsidePortal::add);
Map<BlockPos, BlockState> values = new HashMap<>(); Map<BlockPos, BlockState> values = new HashMap<>();
blocks.forEach((pos, info) -> { blocks.forEach((pos, info) -> {
@ -278,10 +278,10 @@ public class CarriageContraption extends Contraption {
} }
@Override @Override
public Collection<BlockEntity> getSpecialRenderedBEs() { public Collection<BlockEntity> getRenderedBEs() {
if (notInPortal()) if (notInPortal())
return super.getSpecialRenderedBEs(); return super.getRenderedBEs();
return specialRenderedBEsOutsidePortal; return renderedBEsOutsidePortal;
} }
@Override @Override

View file

@ -12,6 +12,7 @@ import com.simibubi.create.content.contraptions.minecart.CouplingHandlerClient;
import com.simibubi.create.content.contraptions.minecart.CouplingPhysics; import com.simibubi.create.content.contraptions.minecart.CouplingPhysics;
import com.simibubi.create.content.contraptions.minecart.CouplingRenderer; import com.simibubi.create.content.contraptions.minecart.CouplingRenderer;
import com.simibubi.create.content.contraptions.minecart.capability.CapabilityMinecartController; import com.simibubi.create.content.contraptions.minecart.capability.CapabilityMinecartController;
import com.simibubi.create.content.contraptions.render.ContraptionRenderInfoManager;
import com.simibubi.create.content.decoration.girder.GirderWrenchBehavior; import com.simibubi.create.content.decoration.girder.GirderWrenchBehavior;
import com.simibubi.create.content.equipment.armor.BacktankArmorLayer; import com.simibubi.create.content.equipment.armor.BacktankArmorLayer;
import com.simibubi.create.content.equipment.armor.DivingHelmetItem; import com.simibubi.create.content.equipment.armor.DivingHelmetItem;
@ -155,6 +156,7 @@ public class ClientEvents {
PlacementHelpers.tick(); PlacementHelpers.tick();
CreateClient.OUTLINER.tickOutlines(); CreateClient.OUTLINER.tickOutlines();
CreateClient.GHOST_BLOCKS.tickGhosts(); CreateClient.GHOST_BLOCKS.tickGhosts();
ContraptionRenderInfoManager.tickFor(world);
BlueprintOverlayRenderer.tick(); BlueprintOverlayRenderer.tick();
ToolboxHandlerClient.clientTick(); ToolboxHandlerClient.clientTick();
TrackTargetingClient.clientTick(); TrackTargetingClient.clientTick();

View file

@ -19,8 +19,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public class AllInstanceTypes { public class AllInstanceTypes {
// FIXME: optimize layouts/pack fields together if possible
public static final InstanceType<RotatingInstance> ROTATING = SimpleInstanceType.builder(RotatingInstance::new) public static final InstanceType<RotatingInstance> ROTATING = SimpleInstanceType.builder(RotatingInstance::new)
.cullShader(asResource("instance/cull/rotating.glsl")) .cullShader(asResource("instance/cull/rotating.glsl"))
.vertexShader(asResource("instance/rotating.vert")) .vertexShader(asResource("instance/rotating.vert"))
@ -51,7 +49,8 @@ public class AllInstanceTypes {
MemoryUtil.memPutByte(ptr + 34, instance.rotationAxisZ); MemoryUtil.memPutByte(ptr + 34, instance.rotationAxisZ);
}) })
.register(); .register();
public static final InstanceType<BeltInstance> BELTS = SimpleInstanceType.builder(BeltInstance::new)
public static final InstanceType<BeltInstance> BELT = SimpleInstanceType.builder(BeltInstance::new)
.cullShader(asResource("instance/cull/belt.glsl")) .cullShader(asResource("instance/cull/belt.glsl"))
.vertexShader(asResource("instance/belt.vert")) .vertexShader(asResource("instance/belt.vert"))
.layout(LayoutBuilder.create() .layout(LayoutBuilder.create()
@ -92,9 +91,10 @@ public class AllInstanceTypes {
MemoryUtil.memPutFloat(ptr + 72, instance.scrollMult); MemoryUtil.memPutFloat(ptr + 72, instance.scrollMult);
}) })
.register(); .register();
public static final InstanceType<ActorInstance> ACTORS = SimpleInstanceType.builder(ActorInstance::new)
.cullShader(asResource("instance/cull/contraption_actor.glsl")) public static final InstanceType<ActorInstance> ACTOR = SimpleInstanceType.builder(ActorInstance::new)
.vertexShader(asResource("instance/contraption_actor.vert")) .cullShader(asResource("instance/cull/actor.glsl"))
.vertexShader(asResource("instance/actor.vert"))
.layout(LayoutBuilder.create() .layout(LayoutBuilder.create()
.vector("pos", FloatRepr.FLOAT, 3) .vector("pos", FloatRepr.FLOAT, 3)
.vector("light", IntegerRepr.SHORT, 2) .vector("light", IntegerRepr.SHORT, 2)
@ -126,7 +126,7 @@ public class AllInstanceTypes {
.register(); .register();
// TODO: remove // TODO: remove
public static final InstanceType<FlapInstance> FLAPS = SimpleInstanceType.builder(FlapInstance::new) public static final InstanceType<FlapInstance> FLAP = SimpleInstanceType.builder(FlapInstance::new)
.cullShader(asResource("instance/cull/flap.glsl")) .cullShader(asResource("instance/cull/flap.glsl"))
.vertexShader(asResource("instance/flap.vert")) .vertexShader(asResource("instance/flap.vert"))
.layout(LayoutBuilder.create() .layout(LayoutBuilder.create()

View file

@ -7,7 +7,7 @@ import javax.annotation.Nullable;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import org.joml.Vector4f; import org.joml.Vector4f;
import com.jozufozu.flywheel.api.backend.BackendManager; import com.jozufozu.flywheel.api.visualization.VisualizationManager;
import com.jozufozu.flywheel.impl.visualization.VisualizationHelper; import com.jozufozu.flywheel.impl.visualization.VisualizationHelper;
import com.jozufozu.flywheel.lib.transform.TransformStack; import com.jozufozu.flywheel.lib.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
@ -50,7 +50,7 @@ public class BlockEntityRenderHelper {
Iterator<BlockEntity> iterator = customRenderBEs.iterator(); Iterator<BlockEntity> iterator = customRenderBEs.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
BlockEntity blockEntity = iterator.next(); BlockEntity blockEntity = iterator.next();
if (BackendManager.isBackendOn() && VisualizationHelper.shouldSkipRender(blockEntity)) if (VisualizationManager.supportsVisualization(world) && VisualizationHelper.shouldSkipRender(blockEntity))
continue; continue;
BlockEntityRenderer<BlockEntity> renderer = Minecraft.getInstance().getBlockEntityRenderDispatcher().getRenderer(blockEntity); BlockEntityRenderer<BlockEntity> renderer = Minecraft.getInstance().getBlockEntityRenderDispatcher().getRenderer(blockEntity);