Merge branch 'mc1.15/dev' of https://github.com/Creators-of-Create/Create into mc1.15/dev

This commit is contained in:
simibubi 2021-03-15 23:20:26 +01:00
commit e38d85a633
36 changed files with 492 additions and 139 deletions

View file

@ -77,6 +77,7 @@ import com.simibubi.create.content.contraptions.relays.belt.BeltRenderer;
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.content.contraptions.relays.elementary.SimpleKineticTileEntity;
import com.simibubi.create.content.contraptions.relays.encased.*;
import com.simibubi.create.content.contraptions.relays.gauge.GaugeInstance;
import com.simibubi.create.content.contraptions.relays.gauge.GaugeRenderer;
import com.simibubi.create.content.contraptions.relays.gauge.SpeedGaugeTileEntity;
import com.simibubi.create.content.contraptions.relays.gauge.StressGaugeTileEntity;
@ -260,7 +261,7 @@ public class AllTileEntities {
public static final TileEntityEntry<FluidValveTileEntity> FLUID_VALVE = Create.registrate()
.tileEntity("fluid_valve", FluidValveTileEntity::new)
.instance(() -> ShaftInstance::new)
.instance(() -> FluidValveInstance::new)
.validBlocks(AllBlocks.FLUID_VALVE)
.renderer(() -> FluidValveRenderer::new)
.register();
@ -515,14 +516,14 @@ public class AllTileEntities {
public static final TileEntityEntry<SpeedGaugeTileEntity> SPEEDOMETER = Create.registrate()
.tileEntity("speedometer", SpeedGaugeTileEntity::new)
.instance(() -> ShaftInstance::new)
.instance(() -> GaugeInstance.Speed::new)
.validBlocks(AllBlocks.SPEEDOMETER)
.renderer(() -> GaugeRenderer::speed)
.register();
public static final TileEntityEntry<StressGaugeTileEntity> STRESSOMETER = Create.registrate()
.tileEntity("stressometer", StressGaugeTileEntity::new)
.instance(() -> ShaftInstance::new)
.instance(() -> GaugeInstance.Stress::new)
.validBlocks(AllBlocks.STRESSOMETER)
.renderer(() -> GaugeRenderer::stress)
.register();

View file

@ -4,12 +4,13 @@ import java.nio.ByteBuffer;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.impl.IFlatLight;
import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos;
public class KineticData<D extends KineticData<D>> extends InstanceData {
public class KineticData<D extends KineticData<D>> extends InstanceData implements IFlatLight<D> {
private float x;
private float y;
private float z;
@ -65,11 +66,13 @@ public class KineticData<D extends KineticData<D>> extends InstanceData {
return (D) this;
}
@Override
public D setBlockLight(int blockLight) {
this.blockLight = (byte) ((blockLight & 0xF) << 4);
return (D) this;
}
@Override
public D setSkyLight(int skyLight) {
this.skyLight = (byte) ((skyLight & 0xF) << 4);
return (D) this;

View file

@ -36,12 +36,6 @@ public abstract class KineticTileInstance<T extends KineticTileEntity> extends T
return key;
}
protected final void relight(InstanceKey<? extends KineticData<?>> key) {
key.getInstance()
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos))
.setSkyLight(world.getLightLevel(LightType.SKY, pos));
}
protected float getRotationOffset(final Direction.Axis axis) {
float offset = CogWheelBlock.isLargeCog(lastState) ? 11.25f : 0;
double d = (((axis == Direction.Axis.X) ? 0 : pos.getX()) + ((axis == Direction.Axis.Y) ? 0 : pos.getY())

View file

@ -4,14 +4,10 @@ import static com.simibubi.create.content.contraptions.base.KineticTileEntityRen
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class SingleRotatingInstance extends KineticTileInstance<KineticTileEntity> {
@ -35,7 +31,7 @@ public class SingleRotatingInstance extends KineticTileInstance<KineticTileEntit
@Override
public void updateLight() {
relight(rotatingModelKey);
relight(pos, rotatingModelKey.getInstance());
}
@Override

View file

@ -82,19 +82,10 @@ public class FanInstance extends KineticTileInstance<EncasedFanTileEntity> {
final Direction direction = lastState.get(FACING);
BlockPos behind = pos.offset(direction.getOpposite());
putLight(shaft, behind);
relight(behind, shaft.getInstance());
BlockPos inFront = pos.offset(direction);
putLight(fan, inFront);
}
private void putLight(InstanceKey<RotatingData> key, BlockPos pos) {
int blockLight = world.getLightLevel(LightType.BLOCK, pos);
int skyLight = world.getLightLevel(LightType.SKY, pos);
key.getInstance()
.setBlockLight(blockLight)
.setSkyLight(skyLight);
relight(inFront, fan.getInstance());
}
@Override

View file

@ -150,20 +150,10 @@ public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> im
@Override
public void updateLight() {
int block = world.getLightLevel(LightType.BLOCK, pos);
int sky = world.getLightLevel(LightType.SKY, pos);
shaft.getInstance().setBlockLight(block).setSkyLight(sky);
wheel.getInstance().setBlockLight(block).setSkyLight(sky);
relight(pos, shaft.getInstance(), wheel.getInstance());
if (connection != null) {
BlockPos pos = this.pos.offset(connection);
int connectionBlock = world.getLightLevel(LightType.BLOCK, pos);
int connectionSky = world.getLightLevel(LightType.SKY, pos);
connectors.stream()
.map(InstanceKey::getInstance)
.forEach(data -> data.setBlockLight(connectionBlock).setSkyLight(connectionSky));
relight(this.pos.offset(connection), connectors.stream().map(InstanceKey::getInstance));
}
}

View file

@ -66,9 +66,6 @@ public class EngineInstance extends TileEntityInstance<EngineTileEntity> {
@Override
public void updateLight() {
int block = world.getLightLevel(LightType.BLOCK, pos);
int sky = world.getLightLevel(LightType.SKY, pos);
frame.getInstance().setBlockLight(block).setSkyLight(sky);
relight(pos, frame.getInstance());
}
}

View file

@ -92,14 +92,9 @@ public class MixerInstance extends ShaftlessCogInstance implements ITickableInst
public void updateLight() {
super.updateLight();
BlockPos down = pos.down();
mixerHead.getInstance()
.setBlockLight(world.getLightLevel(LightType.BLOCK, down))
.setSkyLight(world.getLightLevel(LightType.SKY, down));
relight(pos.down(), mixerHead.getInstance());
mixerPole.getInstance()
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos))
.setSkyLight(world.getLightLevel(LightType.SKY, pos));
relight(pos, mixerPole.getInstance());
}
@Override

View file

@ -67,9 +67,7 @@ public class PressInstance extends ShaftInstance implements ITickableInstance {
public void updateLight() {
super.updateLight();
pressHead.getInstance()
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos))
.setSkyLight(world.getLightLevel(LightType.SKY, pos));
relight(pos, pressHead.getInstance());
}
@Override

View file

@ -63,9 +63,7 @@ public class StickerInstance extends TileEntityInstance<StickerTileEntity> imple
@Override
public void updateLight() {
head.getInstance()
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos))
.setSkyLight(world.getLightLevel(LightType.SKY, pos));
relight(pos, head.getInstance());
}
@Override

View file

@ -81,9 +81,7 @@ public class GantryCarriageInstance extends ShaftInstance implements ITickableIn
@Override
public void updateLight() {
gantryCogs.getInstance()
.setBlockLight(world.getLightLevel(LightType.BLOCK, pos))
.setSkyLight(world.getLightLevel(LightType.SKY, pos));
relight(pos, gantryCogs.getInstance());
}
@Override

View file

@ -25,6 +25,8 @@ import net.minecraft.world.TickPriority;
import net.minecraft.world.World;
import net.minecraft.world.server.ServerWorld;
import javax.annotation.Nonnull;
public class FluidValveBlock extends DirectionalAxisKineticBlock implements IAxisPipe {
public static final BooleanProperty ENABLED = BooleanProperty.create("enabled");
@ -60,9 +62,10 @@ public class FluidValveBlock extends DirectionalAxisKineticBlock implements IAxi
return AllTileEntities.FLUID_VALVE.create();
}
@Nonnull
public static Axis getPipeAxis(BlockState state) {
if (!(state.getBlock() instanceof FluidValveBlock))
return null;
throw new IllegalStateException("Provided BlockState is for a different block.");
Direction facing = state.get(FACING);
boolean alongFirst = !state.get(AXIS_ALONG_FIRST_COORDINATE);
for (Axis axis : Iterate.axes) {
@ -74,7 +77,7 @@ public class FluidValveBlock extends DirectionalAxisKineticBlock implements IAxi
}
return axis;
}
return null;
throw new IllegalStateException("Impossible axis.");
}
@Override

View file

@ -0,0 +1,91 @@
package com.simibubi.create.content.contraptions.fluids.pipes;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.ITickableInstance;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.block.BlockState;
import net.minecraft.util.Direction;
import net.minecraft.util.math.MathHelper;
public class FluidValveInstance extends ShaftInstance implements ITickableInstance {
protected InstanceKey<ModelData> pointer;
protected double xRot;
protected double yRot;
protected int pointerRotationOffset;
public FluidValveInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
super(dispatcher, tile);
}
@Override
protected void init() {
super.init();
Direction facing = lastState.get(FluidValveBlock.FACING);
yRot = AngleHelper.horizontalAngle(facing);
xRot = facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90;
Direction.Axis pipeAxis = FluidValveBlock.getPipeAxis(lastState);
Direction.Axis shaftAxis = KineticTileEntityRenderer.getRotationAxisOf(tile);
pointerRotationOffset = 0;
if (pipeAxis.isHorizontal() && shaftAxis == Direction.Axis.Z || pipeAxis.isVertical())
pointerRotationOffset = 90;
pointer = modelManager.basicMaterial().getModel(AllBlockPartials.FLUID_VALVE_POINTER, lastState).createInstance();
updateLight();
transformPointer((FluidValveTileEntity) tile);
}
@Override
public void tick() {
FluidValveTileEntity valve = (FluidValveTileEntity) tile;
if (valve.pointer.settled()) return;
transformPointer(valve);
}
private void transformPointer(FluidValveTileEntity valve) {
float pointerRotation = MathHelper.lerp(valve.pointer.getValue(AnimationTickHolder.getPartialTicks()), 0, -90);
MatrixStack ms = new MatrixStack();
MatrixStacker.of(ms)
.translate(getFloatingPos())
.centre()
.rotateY(yRot)
.rotateX(xRot)
.rotateY(pointerRotationOffset + pointerRotation)
.unCentre();
pointer.getInstance().setTransform(ms);
}
@Override
public void updateLight() {
super.updateLight();
relight(pos, pointer.getInstance());
}
@Override
public void remove() {
super.remove();
pointer.delete();
}
}

View file

@ -5,6 +5,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.MatrixStacker;
@ -25,6 +26,9 @@ public class FluidValveRenderer extends KineticTileEntityRenderer {
@Override
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
if (FastRenderDispatcher.available(te.getWorld())) return;
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
BlockState blockState = te.getBlockState();
SuperByteBuffer pointer = AllBlockPartials.FLUID_VALVE_POINTER.renderOn(blockState);

View file

@ -1,29 +1,24 @@
package com.simibubi.create.content.contraptions.relays.belt;
import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.function.Supplier;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.base.KineticData;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.item.DyeColor;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.LightType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class BeltInstance extends KineticTileInstance<BeltTileEntity> {
@ -103,9 +98,9 @@ public class BeltInstance extends KineticTileInstance<BeltTileEntity> {
@Override
public void updateLight() {
keys.forEach(this::relight);
relight(pos, keys.stream().map(InstanceKey::getInstance));
if (pulleyKey != null) relight(pulleyKey);
if (pulleyKey != null) relight(pos, pulleyKey.getInstance());
}
@Override

View file

@ -4,19 +4,16 @@ import java.util.ArrayList;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticData;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderRegistry;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.fml.DistExecutor;
public class SplitShaftInstance extends KineticTileInstance<SplitShaftTileEntity> {
@ -59,7 +56,7 @@ public class SplitShaftInstance extends KineticTileInstance<SplitShaftTileEntity
@Override
public void updateLight() {
keys.forEach(this::relight);
keys.forEach(key -> relight(pos, ((InstanceKey<? extends KineticData<?>>) key).getInstance()));
}
@Override

View file

@ -0,0 +1,173 @@
package com.simibubi.create.content.contraptions.relays.gauge;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.ITickableInstance;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.*;
import net.minecraft.util.Direction;
import net.minecraft.util.math.MathHelper;
import java.util.ArrayList;
public abstract class GaugeInstance extends ShaftInstance implements ITickableInstance {
protected ArrayList<DialFace> faces;
protected MatrixStack ms;
protected GaugeInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
super(dispatcher, tile);
}
@Override
protected void init() {
super.init();
faces = new ArrayList<>(2);
GaugeTileEntity gaugeTile = (GaugeTileEntity) tile;
GaugeBlock gaugeBlock = (GaugeBlock) lastState.getBlock();
InstancedModel<ModelData> dialModel = modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_DIAL, lastState);
InstancedModel<ModelData> headModel = getHeadModel();
ms = new MatrixStack();
MatrixStacker msr = MatrixStacker.of(ms);
msr.translate(getFloatingPos());
float progress = MathHelper.lerp(AnimationTickHolder.getPartialTicks(), gaugeTile.prevDialState, gaugeTile.dialState);
for (Direction facing : Iterate.directions) {
if (!gaugeBlock.shouldRenderHeadOnFace(world, pos, lastState, facing))
continue;
DialFace face = makeFace(facing, dialModel, headModel);
faces.add(face);
face.setupTransform(msr, progress);
}
updateLight();
}
private DialFace makeFace(Direction face, InstancedModel<ModelData> dialModel, InstancedModel<ModelData> headModel) {
return new DialFace(face, dialModel.createInstance(), headModel.createInstance());
}
@Override
public void tick() {
GaugeTileEntity gaugeTile = (GaugeTileEntity) tile;
if (MathHelper.epsilonEquals(gaugeTile.prevDialState, gaugeTile.dialState))
return;
float progress = MathHelper.lerp(AnimationTickHolder.getPartialTicks(), gaugeTile.prevDialState, gaugeTile.dialState);
MatrixStacker msr = MatrixStacker.of(ms);
for (DialFace faceEntry : faces) {
faceEntry.updateTransform(msr, progress);
}
}
@Override
public void updateLight() {
super.updateLight();
relight(pos, faces.stream()
.flatMap(Couple::stream)
.map(InstanceKey::getInstance));
}
@Override
public void remove() {
super.remove();
faces.forEach(DialFace::delete);
}
protected abstract InstancedModel<ModelData> getHeadModel();
private class DialFace extends Couple<InstanceKey<ModelData>> {
Direction face;
public DialFace(Direction face, InstanceKey<ModelData> first, InstanceKey<ModelData> second) {
super(first, second);
this.face = face;
}
private void setupTransform(MatrixStacker msr, float progress) {
float dialPivot = 5.75f / 16;
ms.push();
rotateToFace(msr);
getSecond().getInstance().setTransform(ms);
msr.translate(0, dialPivot, dialPivot)
.rotate(Direction.EAST, (float) (Math.PI / 2 * -progress))
.translate(0, -dialPivot, -dialPivot);
getFirst().getInstance().setTransform(ms);
ms.pop();
}
private void updateTransform(MatrixStacker msr, float progress) {
float dialPivot = 5.75f / 16;
ms.push();
rotateToFace(msr)
.translate(0, dialPivot, dialPivot)
.rotate(Direction.EAST, (float) (Math.PI / 2 * -progress))
.translate(0, -dialPivot, -dialPivot);
getFirst().getInstance().setTransform(ms);
ms.pop();
}
protected MatrixStacker rotateToFace(MatrixStacker msr) {
return msr.centre()
.rotate(Direction.UP, (float) ((-face.getHorizontalAngle() - 90) / 180 * Math.PI))
.unCentre();
}
private void delete() {
getFirst().delete();
getSecond().delete();
}
}
public static class Speed extends GaugeInstance {
public Speed(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
super(dispatcher, tile);
}
@Override
protected InstancedModel<ModelData> getHeadModel() {
return modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_HEAD_SPEED, lastState);
}
}
public static class Stress extends GaugeInstance {
public Stress(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
super(dispatcher, tile);
}
@Override
protected InstancedModel<ModelData> getHeadModel() {
return modelManager.getMaterial(RenderMaterials.MODELS).getModel(AllBlockPartials.GAUGE_HEAD_STRESS, lastState);
}
}
}

View file

@ -7,6 +7,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.relays.gauge.GaugeBlock.Type;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.block.BlockState;
@ -37,6 +38,8 @@ public class GaugeRenderer extends KineticTileEntityRenderer {
@Override
protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) {
if (FastRenderDispatcher.available(te.getWorld())) return;
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
BlockState gaugeState = te.getBlockState();
GaugeTileEntity gaugeTE = (GaugeTileEntity) te;
@ -47,14 +50,14 @@ public class GaugeRenderer extends KineticTileEntityRenderer {
.renderOn(gaugeState);
SuperByteBuffer dialBuffer = AllBlockPartials.GAUGE_DIAL.renderOn(gaugeState);
float dialPivot = 5.75f / 16;
float progress = MathHelper.lerp(partialTicks, gaugeTE.prevDialState, gaugeTE.dialState);
for (Direction facing : Iterate.directions) {
if (!((GaugeBlock) gaugeState.getBlock()).shouldRenderHeadOnFace(te.getWorld(), te.getPos(), gaugeState,
facing))
continue;
float dialPivot = 5.75f / 16;
float progress = MathHelper.lerp(partialTicks, gaugeTE.prevDialState, gaugeTE.dialState);
IVertexBuilder vb = buffer.getBuffer(RenderType.getSolid());
rotateBufferTowards(dialBuffer, facing).translate(0, dialPivot, dialPivot)
.rotate(Direction.EAST, (float) (Math.PI / 2 * -progress))

View file

@ -99,14 +99,7 @@ public class GearboxInstance extends KineticTileInstance<GearboxTileEntity> {
@Override
public void updateLight() {
int blockLight = tile.getWorld().getLightLevel(LightType.BLOCK, pos);
int skyLight = tile.getWorld().getLightLevel(LightType.SKY, pos);
for (InstanceKey<RotatingData> key : keys.values()) {
key.getInstance()
.setBlockLight(blockLight)
.setSkyLight(skyLight);
}
relight(pos, keys.values().stream().map(InstanceKey::getInstance));
}
@Override

View file

@ -73,7 +73,7 @@ public class ArmInstance extends SingleRotatingInstance implements ITickableInst
public void tick() {
ArmTileEntity arm = (ArmTileEntity) tile;
boolean settled = Stream.of(arm.baseAngle, arm.lowerArmAngle, arm.upperArmAngle, arm.headAngle).allMatch(InterpolatedValue::settled);
boolean settled = arm.baseAngle.settled() && arm.lowerArmAngle.settled() && arm.upperArmAngle.settled() && arm.headAngle.settled();
boolean rave = arm.phase == ArmTileEntity.Phase.DANCING;
if (!settled || rave || firstTick)
@ -154,13 +154,8 @@ public class ArmInstance extends SingleRotatingInstance implements ITickableInst
@Override
public void updateLight() {
super.updateLight();
int block = world.getLightLevel(LightType.BLOCK, pos);
int sky = world.getLightLevel(LightType.SKY, pos);
models.stream()
.map(InstanceKey::getInstance)
.forEach(data -> data.setSkyLight(sky).setBlockLight(block));
relight(pos, models.stream().map(InstanceKey::getInstance));
}
@Override

View file

@ -81,15 +81,6 @@ public class SchematicannonInstance extends TileEntityInstance<SchematicannonTil
@Override
public void updateLight() {
int block = world.getLightLevel(LightType.BLOCK, pos);
int sky = world.getLightLevel(LightType.SKY, pos);
connector.getInstance()
.setBlockLight(block)
.setSkyLight(sky);
pipe.getInstance()
.setBlockLight(block)
.setSkyLight(sky);
relight(pos, connector.getInstance(), pipe.getInstance());
}
}

View file

@ -21,6 +21,7 @@ import com.simibubi.create.content.contraptions.components.flywheel.engine.Engin
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
import com.simibubi.create.content.curiosities.tools.AllToolTiers;
import com.simibubi.create.foundation.item.ItemDescription.Palette;
import com.simibubi.create.foundation.utility.FontHelper;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.client.Minecraft;
@ -88,30 +89,8 @@ public class TooltipHelper {
words.add(word);
}
// Apply hard wrap
FontRenderer font = Minecraft.getInstance().fontRenderer;
List<String> lines = new LinkedList<>();
StringBuilder currentLine = new StringBuilder();
int width = 0;
for (String word : words) {
int newWidth = font.getStringWidth(word);
if (width + newWidth > maxWidthPerLine) {
if (width > 0) {
String line = currentLine.toString();
lines.add(line);
currentLine = new StringBuilder();
width = 0;
} else {
lines.add(word);
continue;
}
}
currentLine.append(word);
width += newWidth;
}
if (width > 0) {
lines.add(currentLine.toString());
}
List<String> lines = FontHelper.cutString(font, markedUp, maxWidthPerLine);
// Format
String lineStart = Strings.repeat(" ", indent);

View file

@ -25,6 +25,7 @@ import com.simibubi.create.foundation.ponder.content.PonderTagScreen;
import com.simibubi.create.foundation.ponder.ui.PonderButton;
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.FontHelper;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
@ -486,7 +487,7 @@ public class PonderUI extends AbstractSimiScreen {
RenderSystem.translated(x, y, 0);
RenderSystem.rotatef(indexDiff * -75, 1, 0, 0);
RenderSystem.translated(0, 0, 5);
font.drawSplitString(title, 0, 0, left.x - 51, ColorHelper.applyAlpha(textColor, 1 - indexDiff));
FontHelper.drawSplitString(font, title, 0, 0, left.x - 51, ColorHelper.applyAlpha(textColor, 1 - indexDiff));
RenderSystem.popMatrix();
if (chapter != null) {

View file

@ -286,4 +286,14 @@ public class PonderWorld extends SchematicWorld {
return state;
}
@Override
public boolean chunkExists(int x, int y) {
return true; // fix particle lighting
}
@Override
public boolean isBlockPresent(BlockPos pos) {
return true; // fix particle lighting
}
}

View file

@ -59,11 +59,11 @@ public class PonderWorldParticles {
}
}
public void renderParticles(MatrixStack ms, IRenderTypeBuffer buffer, ActiveRenderInfo p_228345_4_, float p_228345_5_) {
public void renderParticles(MatrixStack ms, IRenderTypeBuffer buffer, ActiveRenderInfo renderInfo, float pt) {
Minecraft mc = Minecraft.getInstance();
LightTexture p_228345_3_ = mc.gameRenderer.getLightmapTextureManager();
LightTexture lightTexture = mc.gameRenderer.getLightmapTextureManager();
p_228345_3_.enableLightmap();
lightTexture.enableLightmap();
Runnable enable = () -> {
RenderSystem.enableAlphaTest();
RenderSystem.defaultAlphaFunc();
@ -87,7 +87,7 @@ public class PonderWorldParticles {
iparticlerendertype.beginRender(bufferbuilder, mc.textureManager);
for (Particle particle : iterable)
particle.buildGeometry(bufferbuilder, p_228345_4_, p_228345_5_);
particle.buildGeometry(bufferbuilder, renderInfo, pt);
iparticlerendertype.finishRender(tessellator);
}
@ -97,7 +97,7 @@ public class PonderWorldParticles {
RenderSystem.depthMask(true);
RenderSystem.disableBlend();
RenderSystem.defaultAlphaFunc();
p_228345_3_.disableLightmap();
lightTexture.disableLightmap();
RenderSystem.disableFog();
}

View file

@ -16,6 +16,7 @@ import com.simibubi.create.foundation.ponder.PonderUI;
import com.simibubi.create.foundation.ponder.ui.ChapterLabel;
import com.simibubi.create.foundation.ponder.ui.LayoutHelper;
import com.simibubi.create.foundation.ponder.ui.PonderButton;
import com.simibubi.create.foundation.utility.FontHelper;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.block.Block;
@ -197,7 +198,7 @@ public class PonderTagScreen extends AbstractSimiScreen {
PonderUI.renderBox(x - 3, y - 3, w + 6, h + 6, false);
RenderSystem.translated(0, 0, 100);
font.drawSplitString(desc, x, y, w, 0xeeeeee);
FontHelper.drawSplitString(font, desc, x, y, w, 0xeeeeee);
RenderSystem.popMatrix();
}

View file

@ -10,6 +10,7 @@ import com.simibubi.create.foundation.ponder.PonderScene;
import com.simibubi.create.foundation.ponder.PonderUI;
import com.simibubi.create.foundation.ponder.content.PonderPalette;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.FontHelper;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec2f;
@ -120,8 +121,8 @@ public class TextWindowElement extends AnimatedOverlayElement {
RenderSystem.popMatrix();
}
screen.getFontRenderer()
.drawSplitString(bakedText, targetX - 10, 3, textWidth, ColorHelper.applyAlpha(brighterColor, fade));
FontHelper.drawSplitString(screen.getFontRenderer(), bakedText, targetX - 10, 3, textWidth,
ColorHelper.applyAlpha(brighterColor, fade));
RenderSystem.popMatrix();
}

View file

@ -34,6 +34,8 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
protected int minIndexChanged = -1;
protected int maxIndexChanged = -1;
protected boolean anyToRemove;
public InstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(buf);
this.renderer = renderer;
@ -73,6 +75,8 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
verifyKey(key);
key.invalidate();
anyToRemove = true;
}
public D getInstance(InstanceKey<D> key) {
@ -161,6 +165,8 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
// copied from ArrayList#removeIf
protected boolean doRemoval() {
if (!anyToRemove) return false;
// figure out which elements are to be removed
// any exception thrown from the filter predicate at this stage
// will leave the collection unmodified
@ -198,6 +204,8 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
maxIndexChanged = newSize - 1;
}
this.anyToRemove = false;
return anyToRemove;
}

View file

@ -6,8 +6,10 @@ import javax.annotation.Nullable;
import com.simibubi.create.foundation.ponder.PonderWorld;
import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.Minecraft;
@ -67,6 +69,10 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
return (RenderMaterial<P, M>) materials.get(materialType);
}
public RenderMaterial<P, InstancedModel<ModelData>> basicMaterial() {
return getMaterial(RenderMaterials.MODELS);
}
@Nullable
public <T extends TileEntity> TileEntityInstance<? super T> getInstance(T tile) {
return getInstance(tile, true);

View file

@ -1,5 +1,6 @@
package com.simibubi.create.foundation.render.backend.instancing;
import com.simibubi.create.foundation.render.backend.instancing.impl.IFlatLight;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity;
@ -7,6 +8,9 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.LightType;
import net.minecraft.world.World;
import java.util.Arrays;
import java.util.stream.Stream;
public abstract class TileEntityInstance<T extends TileEntity> {
protected final InstancedTileRenderer<?> modelManager;
@ -60,13 +64,19 @@ public abstract class TileEntityInstance<T extends TileEntity> {
return pos.subtract(modelManager.getOriginCoordinate());
}
protected void relight(BlockPos pos, ModelData... models) {
protected <L extends IFlatLight<?>> void relight(BlockPos pos, IFlatLight<?>... models) {
relight(world.getLightLevel(LightType.BLOCK, pos), world.getLightLevel(LightType.SKY, pos), models);
}
protected void relight(int block, int sky, ModelData... models) {
for (ModelData model : models) {
model.setBlockLight(block).setSkyLight(sky);
}
protected <L extends IFlatLight<?>> void relight(BlockPos pos, Stream<IFlatLight<?>> models) {
relight(world.getLightLevel(LightType.BLOCK, pos), world.getLightLevel(LightType.SKY, pos), models);
}
protected <L extends IFlatLight<?>> void relight(int block, int sky, IFlatLight<?>... models) {
relight(block, sky, Arrays.stream(models));
}
protected <L extends IFlatLight<?>> void relight(int block, int sky, Stream<IFlatLight<?>> models) {
models.forEach(model -> model.setBlockLight(block).setSkyLight(sky));
}
}

View file

@ -0,0 +1,26 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
/**
* An interface that implementors of {@link InstanceData} should also implement
* if they wish to make use of Flywheel's provided light update methods.
*
* This only covers flat lighting, smooth lighting is still TODO.
* @param <D> The name of the class that implements this interface.
*/
public interface IFlatLight<D extends InstanceData & IFlatLight<D>> {
/**
* @param blockLight An integer in the range [0, 15] representing the
* amount of block light this instance should receive.
* @return <code>this</code>
*/
D setBlockLight(int blockLight);
/**
* @param skyLight An integer in the range [0, 15] representing the
* amount of sky light this instance should receive.
* @return <code>this</code>
*/
D setSkyLight(int skyLight);
}

View file

@ -9,7 +9,7 @@ import net.minecraft.client.renderer.Matrix4f;
import java.nio.ByteBuffer;
public class ModelData extends InstanceData {
public class ModelData extends InstanceData implements IFlatLight<ModelData> {
private static final Matrix4f IDENT4 = new Matrix4f();
private static final Matrix3f IDENT3 = new Matrix3f();
static {
@ -54,11 +54,13 @@ public class ModelData extends InstanceData {
return this;
}
@Override
public ModelData setBlockLight(int blockLight) {
this.blockLight = (byte) (blockLight << 4);
return this;
}
@Override
public ModelData setSkyLight(int skyLight) {
this.skyLight = (byte) (skyLight << 4);
return this;

View file

@ -6,6 +6,7 @@ import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
@ -104,6 +105,10 @@ public class Couple<T> extends Pair<T, T> implements Iterable<T> {
return new Couplerator<>(this);
}
public Stream<T> stream() {
return Stream.of(first, second);
}
private static class Couplerator<T> implements Iterator<T> {
int state;

View file

@ -0,0 +1,85 @@
package com.simibubi.create.foundation.utility;
import java.text.BreakIterator;
import java.util.LinkedList;
import java.util.List;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.TransformationMatrix;
import net.minecraftforge.client.MinecraftForgeClient;
public final class FontHelper {
private FontHelper() {
}
public static List<String> cutString(FontRenderer font, String text, int maxWidthPerLine) {
// Split words
List<String> words = new LinkedList<>();
BreakIterator iterator = BreakIterator.getLineInstance(MinecraftForgeClient.getLocale());
iterator.setText(text);
int start = iterator.first();
for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) {
String word = text.substring(start, end);
words.add(word);
}
// Apply hard wrap
List<String> lines = new LinkedList<>();
StringBuilder currentLine = new StringBuilder();
int width = 0;
for (String word : words) {
int newWidth = font.getStringWidth(word);
if (width + newWidth > maxWidthPerLine) {
if (width > 0) {
String line = currentLine.toString();
lines.add(line);
currentLine = new StringBuilder();
width = 0;
} else {
lines.add(word);
continue;
}
}
currentLine.append(word);
width += newWidth;
}
if (width > 0) {
lines.add(currentLine.toString());
}
return lines;
}
public static void drawSplitString(FontRenderer font, String text, int x, int y, int width, int color) {
List<String> list = cutString(font, text, width);
Matrix4f matrix4f = TransformationMatrix.identity().getMatrix();
for (String s : list) {
float f = (float) x;
if (font.getBidiFlag()) {
int i = font.getStringWidth(font.bidiReorder(s));
f += (float) (width - i);
}
draw(font, s, f, (float) y, color, matrix4f, false);
y += 9;
}
}
private static int draw(FontRenderer font, String p_228078_1_, float p_228078_2_, float p_228078_3_,
int p_228078_4_, Matrix4f p_228078_5_, boolean p_228078_6_) {
if (p_228078_1_ == null) {
return 0;
} else {
IRenderTypeBuffer.Impl irendertypebuffer$impl = IRenderTypeBuffer
.immediate(Tessellator.getInstance().getBuffer());
int i = font.draw(p_228078_1_, p_228078_2_, p_228078_3_, p_228078_4_, p_228078_6_, p_228078_5_,
irendertypebuffer$impl, false, 0, 15728880);
irendertypebuffer$impl.draw();
return i;
}
}
}

View file

@ -24,6 +24,15 @@ public class MatrixStacker {
return instance;
}
public MatrixStacker restoreIdentity() {
MatrixStack.Entry entry = ms.peek();
entry.getModel().loadIdentity();
entry.getNormal().loadIdentity();
return this;
}
public MatrixStacker rotate(Direction axis, float radians) {
if (radians == 0)
return this;

View file

@ -81,6 +81,10 @@ public class LerpedFloat {
return MathHelper.lerp(partialTicks, previousValue, value);
}
public boolean settled() {
return MathHelper.epsilonEquals(previousValue, value);
}
public float getChaseTarget() {
return chaseTarget;
}