Ported in-world interfaces

- Outlines now support shading/normals
- Refactored Value boxes to use the outliner system
- Ported scrolloption, filter and frequency slot rendering
This commit is contained in:
simibubi 2020-05-16 17:51:29 +02:00
parent 170f154b74
commit fb72a686e7
28 changed files with 491 additions and 398 deletions

View file

@ -10,6 +10,7 @@ public enum AllSpecialTextures {
BLANK("blank.png"),
CHECKERED("checkerboard.png"),
THIN_CHECKERED("thin_checkerboard.png"),
HIGHLIGHT_CHECKERED("highlighted_checkerboard.png"),
SELECTION("selection.png"),

View file

@ -5,6 +5,9 @@ import java.util.List;
import java.util.Map;
import java.util.function.Function;
import com.simibubi.create.foundation.behaviour.filtering.FilteringRenderer;
import com.simibubi.create.foundation.behaviour.linked.LinkRenderer;
import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueRenderer;
import com.simibubi.create.foundation.block.render.CustomBlockModels;
import com.simibubi.create.foundation.block.render.SpriteShifter;
import com.simibubi.create.foundation.item.IHaveCustomItemModel;
@ -82,8 +85,11 @@ public class CreateClient {
schematicSender.tick();
schematicAndQuillHandler.tick();
schematicHandler.tick();
FilteringRenderer.tick();
LinkRenderer.tick();
ScrollValueRenderer.tick();
ChassisRangeDisplay.tick();
outliner.tickOutlines();
ChassisRangeDisplay.clientTick();
}
@OnlyIn(Dist.CLIENT)

View file

@ -1,9 +1,17 @@
package com.simibubi.create;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.matrix.MatrixStack.Entry;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@ -149,6 +157,7 @@ public enum ScreenResources {
;
public static final int FONT_COLOR = 0x575F7A;
public static final ResourceLocation ICON_ATLAS = Create.asResource("textures/gui/icons.png");
public final ResourceLocation location;
public int width, height;
@ -172,7 +181,9 @@ public enum ScreenResources {
@OnlyIn(Dist.CLIENT)
public void bind() {
Minecraft.getInstance().getTextureManager().bindTexture(location);
Minecraft.getInstance()
.getTextureManager()
.bindTexture(location);
}
@OnlyIn(Dist.CLIENT)
@ -187,4 +198,39 @@ public enum ScreenResources {
}, x, y);
}
@OnlyIn(Dist.CLIENT)
public void draw(MatrixStack ms, IRenderTypeBuffer buffer, int color) {
IVertexBuilder builder = buffer.getBuffer(RenderType.getTextSeeThrough(this.location));
float sheetSize = 256;
int i = 15 << 20 | 15 << 4;
int j = i >> 16 & '\uffff';
int k = i & '\uffff';
Entry peek = ms.peek();
Vec3d rgb = ColorHelper.getRGB(color);
Vec3d vec4 = new Vec3d(1, 1, 0);
Vec3d vec3 = new Vec3d(0, 1, 0);
Vec3d vec2 = new Vec3d(0, 0, 0);
Vec3d vec1 = new Vec3d(1, 0, 0);
float u1 = (startX + width) / sheetSize;
float u2 = startX / sheetSize;
float v1 = startY / sheetSize;
float v2 = (startY + height) / sheetSize;
vertex(peek, builder, j, k, rgb, vec1, u1, v1);
vertex(peek, builder, j, k, rgb, vec2, u2, v1);
vertex(peek, builder, j, k, rgb, vec3, u2, v2);
vertex(peek, builder, j, k, rgb, vec4, u1, v2);
}
@OnlyIn(Dist.CLIENT)
private void vertex(Entry peek, IVertexBuilder builder, int j, int k, Vec3d rgb, Vec3d vec, float u, float v) {
builder.vertex(peek.getModel(), (float) vec.x, (float) vec.y, (float) vec.z)
.color((float) rgb.x, (float) rgb.y, (float) rgb.z, 1)
.texture(u, v)
.light(j, k)
.endVertex();
}
}

View file

@ -1,30 +1,48 @@
package com.simibubi.create.foundation.behaviour;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.ScreenResources;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform.Sided;
import com.simibubi.create.foundation.behaviour.scrollvalue.INamedIconOptions;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.outliner.ChasingAABBOutline;
import com.simibubi.create.modules.logistics.item.filter.FilterItem;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
public class ValueBox {
public class ValueBox extends ChasingAABBOutline {
String label = "Value Box";
String sublabel = "";
String scrollTooltip = "";
Vec3d labelOffset = Vec3d.ZERO;
int passiveColor;
int highlightColor;
AxisAlignedBB bb = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
protected String label = "Value Box";
protected String sublabel = "";
protected String scrollTooltip = "";
protected Vec3d labelOffset = Vec3d.ZERO;
public ValueBox(String label, AxisAlignedBB bb) {
protected int passiveColor;
protected int highlightColor;
protected boolean isPassive;
protected BlockPos pos;
protected ValueBoxTransform transform;
protected BlockState blockState;
public ValueBox(String label, AxisAlignedBB bb, BlockPos pos) {
super(bb);
this.label = label;
this.bb = bb;
this.pos = pos;
this.blockState = Minecraft.getInstance().world.getBlockState(pos);
}
public ValueBox transform(ValueBoxTransform transform) {
this.transform = transform;
return this;
}
public ValueBox offsetLabel(Vec3d offset) {
@ -48,39 +66,85 @@ public class ValueBox {
return this;
}
public void render(boolean highlighted) {
public ValueBox passive(boolean passive) {
this.isPassive = passive;
return this;
}
@Override
public void render(MatrixStack ms, IRenderTypeBuffer buffer) {
if (transform instanceof Sided && params.getHighlightedFace() != null)
((Sided) transform).fromSide(params.getHighlightedFace());
if (!transform.shouldRender(blockState))
return;
ms.push();
ms.translate(pos.getX(), pos.getY(), pos.getZ());
transform.transform(blockState, ms);
transformNormals = ms.peek()
.getNormal()
.copy();
params.colored(isPassive ? passiveColor : highlightColor);
super.render(ms, buffer);
float fontScale = -1 / 64f;
ms.scale(fontScale, fontScale, fontScale);
ms.push();
renderContents(ms, buffer);
ms.pop();
if (!isPassive) {
ms.push();
ms.translate(17.5, -.5, 7);
ms.translate(labelOffset.x, labelOffset.y, labelOffset.z);
renderHoveringText(ms, buffer, label);
if (!sublabel.isEmpty()) {
ms.translate(0, 10, 0);
renderHoveringText(ms, buffer, sublabel);
}
if (!scrollTooltip.isEmpty()) {
ms.translate(0, 10, 0);
renderHoveringText(ms, buffer, scrollTooltip, 0x998899, 0x111111);
}
ms.pop();
}
ms.pop();
}
public void renderContents(MatrixStack ms, IRenderTypeBuffer buffer) {}
public static class ItemValueBox extends ValueBox {
ItemStack stack;
int count;
public ItemValueBox(String label, AxisAlignedBB bb, ItemStack stack, int count) {
super(label, bb);
public ItemValueBox(String label, AxisAlignedBB bb, BlockPos pos, ItemStack stack, int count) {
super(label, bb, pos);
this.stack = stack;
this.count = count;
}
@Override
public void render(boolean highlighted) {
super.render(highlighted);
public void renderContents(MatrixStack ms, IRenderTypeBuffer buffer) {
super.renderContents(ms, buffer);
FontRenderer font = Minecraft.getInstance().fontRenderer;
String countString = count == 0 ? "*" : count + "";
RenderSystem.translated(17.5f, -5f, 7f);
ms.translate(17.5f, -5f, 7f);
boolean isFilter = stack.getItem() instanceof FilterItem;
if (isFilter)
RenderSystem.translated(3, 8, 7.25f);
ms.translate(3, 8, 7.25f);
else
RenderSystem.translated(-7 - font.getStringWidth(countString), 10, 10 + 1 / 4f);
ms.translate(-7 - font.getStringWidth(countString), 10, 10 + 1 / 4f);
double scale = 1.5;
RenderSystem.rotatef(0, 1, 0, 0);
RenderSystem.scaled(scale, scale, scale);
font.drawString(countString, 0, 0, isFilter ? 0xFFFFFF : 0xEDEDED);
RenderSystem.translated(0, 0, -1 / 16f);
font.drawString(countString, 1 - 1 / 8f, 1 - 1 / 8f, 0x4F4F4F);
float scale = 1.5f;
ms.scale(scale, scale, scale);
drawString(ms, buffer, countString, 0, 0, isFilter ? 0xFFFFFF : 0xEDEDED);
ms.translate(0, 0, -1 / 16f);
drawString(ms, buffer, countString, 1 - 1 / 8f, 1 - 1 / 8f, 0x4F4F4F);
}
}
@ -88,18 +152,18 @@ public class ValueBox {
public static class TextValueBox extends ValueBox {
String text;
public TextValueBox(String label, AxisAlignedBB bb, String text) {
super(label, bb);
public TextValueBox(String label, AxisAlignedBB bb, BlockPos pos, String text) {
super(label, bb, pos);
this.text = text;
}
@Override
public void render(boolean highlighted) {
super.render(highlighted);
public void renderContents(MatrixStack ms, IRenderTypeBuffer buffer) {
super.renderContents(ms, buffer);
FontRenderer font = Minecraft.getInstance().fontRenderer;
double scale = 4;
RenderSystem.scaled(scale, scale, 1);
RenderSystem.translated(-4, -4, 5);
float scale = 4;
ms.scale(scale, scale, 1);
ms.translate(-4, -4, 5);
int stringWidth = font.getStringWidth(text);
float numberScale = (float) font.FONT_HEIGHT / stringWidth;
@ -108,11 +172,10 @@ public class ValueBox {
numberScale = numberScale / 2;
float verticalMargin = (stringWidth - font.FONT_HEIGHT) / 2f;
RenderSystem.scaled(numberScale, numberScale, numberScale);
RenderSystem.translated(singleDigit ? stringWidth / 2 : 0, singleDigit ? -verticalMargin : verticalMargin,
0);
ms.scale(numberScale, numberScale, numberScale);
ms.translate(singleDigit ? stringWidth / 2 : 0, singleDigit ? -verticalMargin : verticalMargin, 0);
ValueBoxRenderer.renderText(font, text, 0xEDEDED, 0x4f4f4f);
renderHoveringText(ms, buffer, text, 0xEDEDED, 0x4f4f4f);
}
}
@ -120,25 +183,41 @@ public class ValueBox {
public static class IconValueBox extends ValueBox {
ScreenResources icon;
public IconValueBox(String label, INamedIconOptions iconValue, AxisAlignedBB bb) {
super(label, bb);
public IconValueBox(String label, INamedIconOptions iconValue, AxisAlignedBB bb, BlockPos pos) {
super(label, bb, pos);
subLabel(Lang.translate(iconValue.getTranslationKey()));
icon = iconValue.getIcon();
}
@Override
public void render(boolean highlighted) {
super.render(highlighted);
double scale = 4;
RenderSystem.scaled(scale, scale, 1);
RenderSystem.translated(-8, -8, 3/2f);
icon.draw(0, 0);
RenderSystem.color4f(.25f, .25f, .25f, 1);
RenderSystem.translated(.5f, .5f, -1);
icon.draw(0, 0);
RenderSystem.color4f(1, 1, 1, 1);
public void renderContents(MatrixStack ms, IRenderTypeBuffer buffer) {
super.renderContents(ms, buffer);
float scale = 4 * 16;
ms.scale(scale, scale, scale);
ms.translate(-.5f, -.5f, 1 / 32f);
icon.draw(ms, buffer, 0xFFFFFF);
}
}
// util
protected void renderHoveringText(MatrixStack ms, IRenderTypeBuffer buffer, String text) {
renderHoveringText(ms, buffer, text, highlightColor, ColorHelper.mixColors(passiveColor, 0, 0.75f));
}
protected void renderHoveringText(MatrixStack ms, IRenderTypeBuffer buffer, String text, int color,
int shadowColor) {
ms.push();
drawString(ms, buffer, text, 0, 0, color);
ms.translate(0, 0, -.25);
drawString(ms, buffer, text, 1, 1, shadowColor);
ms.pop();
}
private static void drawString(MatrixStack ms, IRenderTypeBuffer buffer, String text, float x, float y, int color) {
Minecraft.getInstance().fontRenderer.draw(text, x, y, color, false, ms.peek()
.getModel(), buffer, false, 0, 15728880);
}
}

View file

@ -1,11 +1,6 @@
package com.simibubi.create.foundation.behaviour;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.TessellatorHelper;
import com.simibubi.create.modules.contraptions.relays.elementary.ShaftBlock;
import com.simibubi.create.modules.logistics.item.filter.FilterItem;
@ -13,91 +8,26 @@ import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.FenceBlock;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.WorldRenderer;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
@SuppressWarnings("deprecation")
public class ValueBoxRenderer {
@Deprecated // TODO 1.15 buffered render
public static void renderBox(ValueBox box, boolean highlighted) {
RenderSystem.enableBlend();
RenderSystem.blendFuncSeparate(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA, SourceFactor.ONE,
DestFactor.ZERO);
RenderSystem.disableTexture();
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuffer();
bufferbuilder.begin(3, DefaultVertexFormats.POSITION_COLOR);
RenderSystem.lineWidth(highlighted ? 3 : 2);
Vec3d color = highlighted ? ColorHelper.getRGB(box.highlightColor) : ColorHelper.getRGB(box.passiveColor);
AxisAlignedBB bb = box.bb;
WorldRenderer.drawBox(bufferbuilder, bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ,
(float) color.x, (float) color.y, (float) color.z, 1f);
RenderSystem.lineWidth(1);
TessellatorHelper.draw();
RenderSystem.enableTexture();
float fontScale = -1 / 64f;
Vec3d shift = box.labelOffset;
FontRenderer font = Minecraft.getInstance().fontRenderer;
RenderSystem.scaled(fontScale, fontScale, fontScale);
if (highlighted) {
RenderSystem.pushMatrix();
RenderSystem.translated(17.5f, -5f, 7f);
RenderSystem.translated(shift.x, shift.y, shift.z);
renderText(box, font, box.label);
if (!box.sublabel.isEmpty()) {
RenderSystem.translated(0, 10, 0);
renderText(box, font, box.sublabel);
}
if (!box.scrollTooltip.isEmpty()) {
RenderSystem.translated(0, 10, 0);
renderText(font, box.scrollTooltip, 0x998899, 0x111111);
}
RenderSystem.popMatrix();
}
box.render(highlighted);
RenderSystem.disableBlend();
RenderSystem.disableAlphaTest();
}
public static void renderText(ValueBox box, FontRenderer font, String text) {
renderText(font, text, box.highlightColor, ColorHelper.mixColors(box.passiveColor, 0, 0.75f));
}
public static void renderText(FontRenderer font, String text, int color, int shadowColor) {
font.drawString(text, 0, 0, color);
RenderSystem.translated(0, 0, -1 / 4f);
font.drawString(text, 1, 1, shadowColor);
RenderSystem.translated(0, 0, 1 / 4f);
}
public static void renderItemIntoValueBox(ItemStack filter, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer();
IBakedModel modelWithOverrides = itemRenderer.getItemModelWithOverrides(filter, Minecraft.getInstance().world, null);
boolean blockItem = modelWithOverrides.isGui3d();
float scale = (!blockItem ? .5f : 1f) - 1 / 64f;
float zOffset = (!blockItem ? -.225f : 0) + customZOffset(filter.getItem());
RenderSystem.scaled(scale, scale, scale);
RenderSystem.translated(0, 0, zOffset);
ms.scale(scale, scale, scale);
ms.translate(0, 0, zOffset);
itemRenderer.renderItem(filter, TransformType.FIXED, light, overlay, ms, buffer);
}

View file

@ -4,11 +4,12 @@ import java.util.function.Function;
import org.apache.commons.lang3.tuple.Pair;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.GlHelper;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;
import net.minecraft.block.material.Material;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
@ -20,7 +21,7 @@ public abstract class ValueBoxTransform {
protected abstract Vec3d getLocation(BlockState state);
protected abstract Vec3d getOrientation(BlockState state);
protected abstract void rotate(BlockState state, MatrixStack ms);
public boolean testHit(BlockState state, Vec3d localHit) {
Vec3d offset = getLocation(state);
@ -29,10 +30,17 @@ public abstract class ValueBoxTransform {
return localHit.distanceTo(offset) < scale / 2;
}
public void renderTransformed(BlockState state, Runnable render) {
public void transform(BlockState state, MatrixStack ms) {
Vec3d position = getLocation(state);
Vec3d rotation = getOrientation(state);
GlHelper.renderTransformed(position, rotation, scale, render);
if (position == null)
return;
ms.translate(position.x, position.y, position.z);
rotate(state, ms);
ms.scale(scale, scale, scale);
}
public boolean shouldRender(BlockState state) {
return state.getMaterial() != Material.AIR && getLocation(state) != null;
}
protected Vec3d rotateHorizontally(BlockState state, Vec3d vec) {
@ -63,7 +71,7 @@ public abstract class ValueBoxTransform {
public static Pair<ValueBoxTransform, ValueBoxTransform> makeSlots(Function<Boolean, ? extends Dual> factory) {
return Pair.of(factory.apply(true), factory.apply(false));
}
public boolean testHit(BlockState state, Vec3d localHit) {
Vec3d offset = getLocation(state);
if (offset == null)
@ -72,16 +80,16 @@ public abstract class ValueBoxTransform {
}
}
public static abstract class Sided extends ValueBoxTransform {
protected Direction direction = Direction.UP;
public Sided fromSide(Direction direction) {
this.direction = direction;
return this;
}
@Override
protected Vec3d getLocation(BlockState state) {
Vec3d location = getSouthLocation();
@ -89,33 +97,31 @@ public abstract class ValueBoxTransform {
location = VecHelper.rotateCentered(location, AngleHelper.verticalAngle(direction), Axis.Z);
return location;
}
protected abstract Vec3d getSouthLocation();
@Override
protected Vec3d getOrientation(BlockState state) {
protected void rotate(BlockState state, MatrixStack ms) {
float yRot = AngleHelper.horizontalAngle(direction) + 180;
float zRot = direction == Direction.UP ? 90 : direction == Direction.DOWN ? 270 : 0;
return new Vec3d(0, yRot, zRot);
float xRot = direction == Direction.UP ? 90 : direction == Direction.DOWN ? 270 : 0;
ms.multiply(VecHelper.rotateY(yRot));
ms.multiply(VecHelper.rotateX(xRot));
}
@Override
public void renderTransformed(BlockState state, Runnable render) {
if (!isSideActive(state, direction))
return;
super.renderTransformed(state, render);
public boolean shouldRender(BlockState state) {
return super.shouldRender(state) && isSideActive(state, direction);
}
@Override
public boolean testHit(BlockState state, Vec3d localHit) {
return isSideActive(state, direction) && super.testHit(state, localHit);
}
protected boolean isSideActive(BlockState state, Direction direction) {
return true;
}
}
}

View file

@ -1,14 +1,14 @@
package com.simibubi.create.foundation.behaviour.filtering;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.behaviour.ValueBox;
import com.simibubi.create.foundation.behaviour.ValueBox.ItemValueBox;
import com.simibubi.create.foundation.behaviour.ValueBoxRenderer;
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.TessellatorHelper;
import com.simibubi.create.modules.logistics.item.filter.FilterItem;
import net.minecraft.block.BlockState;
@ -21,22 +21,17 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.DrawHighlightEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(value = Dist.CLIENT)
public class FilteringRenderer {
@SubscribeEvent
public static void renderBlockHighlight(DrawHighlightEvent event) {
RayTraceResult target = event.getTarget();
public static void tick() {
Minecraft mc = Minecraft.getInstance();
RayTraceResult target = mc.objectMouseOver;
if (target == null || !(target instanceof BlockRayTraceResult))
return;
BlockRayTraceResult result = (BlockRayTraceResult) target;
ClientWorld world = Minecraft.getInstance().world;
ClientWorld world = mc.world;
BlockPos pos = result.getPos();
BlockState state = world.getBlockState(pos);
@ -45,34 +40,37 @@ public class FilteringRenderer {
return;
if (!behaviour.isActive())
return;
if (Minecraft.getInstance().player.isSneaking())
if (mc.player.isSneaking())
return;
if (!behaviour.slotPositioning.shouldRender(state))
return;
TessellatorHelper.prepareForDrawing();
RenderSystem.translated(pos.getX(), pos.getY(), pos.getZ());
ItemStack filter = behaviour.getFilter();
boolean isFilterSlotted = filter.getItem() instanceof FilterItem;
boolean showCount = behaviour.isCountVisible();
String label = isFilterSlotted ? "" : Lang.translate("logistics.filter");
boolean hit = behaviour.slotPositioning.testHit(state, target.getHitVec()
.subtract(new Vec3d(pos)));
behaviour.slotPositioning.renderTransformed(state, () -> {
AxisAlignedBB emptyBB = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO);
AxisAlignedBB bb = isFilterSlotted ? emptyBB.grow(.45f, .31f, .2f) : emptyBB.grow(.25f);
AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.25f);
String label = Lang.translate("logistics.filter");
ItemStack filter = behaviour.getFilter();
if (filter.getItem() instanceof FilterItem)
label = "";
boolean showCount = behaviour.isCountVisible();
ValueBox box =
showCount ? new ItemValueBox(label, bb, filter, behaviour.scrollableValue) : new ValueBox(label, bb);
if (showCount)
box.scrollTooltip("[" + Lang.translate("action.scroll") + "]");
box.offsetLabel(behaviour.textShift).withColors(0x7777BB, 0xCCBBFF);
ValueBoxRenderer.renderBox(box, behaviour.testHit(target.getHitVec()));
ValueBox box = showCount ? new ItemValueBox(label, bb, pos, filter, behaviour.scrollableValue)
: new ValueBox(label, bb, pos);
});
box.offsetLabel(behaviour.textShift)
.withColors(0x7A6A2C, 0xB79D64)
.scrollTooltip(showCount ? "[" + Lang.translate("action.scroll") + "]" : "")
.passive(!hit);
TessellatorHelper.cleanUpAfterDrawing();
CreateClient.outliner.showValueBox(pos, box.transform(behaviour.slotPositioning))
.lineWidth(1 / 64f)
.withFaceTexture(hit ? AllSpecialTextures.THIN_CHECKERED : null)
.highlightFace(result.getFace());
}
public static void renderOnTileEntity(SmartTileEntity tileEntityIn, float partialTicks, MatrixStack ms,
IRenderTypeBuffer buffer, int light, int overlay) {
IRenderTypeBuffer buffer, int light, int overlay) {
if (tileEntityIn == null || tileEntityIn.isRemoved())
return;
@ -81,19 +79,14 @@ public class FilteringRenderer {
return;
if (!behaviour.isActive())
return;
if (behaviour.getFilter().isEmpty())
if (behaviour.getFilter()
.isEmpty())
return;
BlockState state = tileEntityIn.getBlockState();
TessellatorHelper.prepareForDrawing();
BlockPos pos = tileEntityIn.getPos();
RenderSystem.translated(pos.getX(), pos.getY(), pos.getZ());
behaviour.slotPositioning.renderTransformed(state, () -> {
ValueBoxRenderer.renderItemIntoValueBox(behaviour.getFilter(), ms, buffer, light, overlay);
});
TessellatorHelper.cleanUpAfterDrawing();
ms.push();
behaviour.slotPositioning.transform(tileEntityIn.getBlockState(), ms);
ValueBoxRenderer.renderItemIntoValueBox(behaviour.getFilter(), ms, buffer, light, overlay);
ms.pop();
}
}

View file

@ -1,66 +1,64 @@
package com.simibubi.create.foundation.behaviour.linked;
import java.util.function.Consumer;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.datafixers.util.Pair;
import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.behaviour.ValueBox;
import com.simibubi.create.foundation.behaviour.ValueBoxRenderer;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.TessellatorHelper;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.DrawHighlightEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(value = Dist.CLIENT)
public class LinkRenderer {
@SubscribeEvent
public static void renderBlockHighlight(DrawHighlightEvent event) {
RayTraceResult target = event.getTarget();
public static void tick() {
Minecraft mc = Minecraft.getInstance();
RayTraceResult target = mc.objectMouseOver;
if (target == null || !(target instanceof BlockRayTraceResult))
return;
BlockRayTraceResult result = (BlockRayTraceResult) target;
ClientWorld world = Minecraft.getInstance().world;
ClientWorld world = mc.world;
BlockPos pos = result.getPos();
BlockState state = world.getBlockState(pos);
LinkBehaviour behaviour = TileEntityBehaviour.get(world, pos, LinkBehaviour.TYPE);
if (behaviour == null)
return;
TessellatorHelper.prepareForDrawing();
RenderSystem.translated(pos.getX(), pos.getY(), pos.getZ());
String freq1 = Lang.translate("logistics.firstFrequency");
String freq2 = Lang.translate("logistics.secondFrequency");
renderEachSlot(state, behaviour, first -> {
for (boolean first : Iterate.trueAndFalse) {
AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.25f);
String label = first ? freq2 : freq1;
ValueBox box = new ValueBox(label, bb).withColors(0x992266, 0xFF55AA).offsetLabel(behaviour.textShift);
ValueBoxRenderer.renderBox(box, behaviour.testHit(first, target.getHitVec()));
});
boolean hit = behaviour.testHit(first, target.getHitVec());
ValueBoxTransform transform = first ? behaviour.firstSlot : behaviour.secondSlot;
TessellatorHelper.cleanUpAfterDrawing();
ValueBox box = new ValueBox(label, bb, pos).withColors(0x601F18, 0xB73C2D)
.offsetLabel(behaviour.textShift)
.passive(!hit);
CreateClient.outliner.showValueBox(Pair.of(Boolean.valueOf(first), pos), box.transform(transform))
.lineWidth(1 / 64f)
.withFaceTexture(hit ? AllSpecialTextures.THIN_CHECKERED : null)
.highlightFace(result.getFace());
}
}
public static void renderOnTileEntity(SmartTileEntity tileEntityIn, float partialTicks, MatrixStack ms,
IRenderTypeBuffer buffer, int light, int overlay) {
IRenderTypeBuffer buffer, int light, int overlay) {
if (tileEntityIn == null || tileEntityIn.isRemoved())
return;
@ -68,23 +66,16 @@ public class LinkRenderer {
if (behaviour == null)
return;
BlockState state = tileEntityIn.getBlockState();
TessellatorHelper.prepareForDrawing();
BlockPos pos = tileEntityIn.getPos();
RenderSystem.translated(pos.getX(), pos.getY(), pos.getZ());
for (boolean first : Iterate.trueAndFalse) {
ValueBoxTransform transform = first ? behaviour.firstSlot : behaviour.secondSlot;
ItemStack stack = first ? behaviour.frequencyFirst.getStack() : behaviour.frequencyLast.getStack();
renderEachSlot(state, behaviour, first -> {
ValueBoxRenderer.renderItemIntoValueBox(
first ? behaviour.frequencyFirst.getStack() : behaviour.frequencyLast.getStack(),
ms, buffer, light, overlay);
});
ms.push();
transform.transform(tileEntityIn.getBlockState(), ms);
ValueBoxRenderer.renderItemIntoValueBox(stack, ms, buffer, light, overlay);
ms.pop();
}
TessellatorHelper.cleanUpAfterDrawing();
}
private static void renderEachSlot(BlockState state, LinkBehaviour behaviour, Consumer<Boolean> render) {
behaviour.firstSlot.renderTransformed(state, () -> render.accept(true));
behaviour.secondSlot.renderTransformed(state, () -> render.accept(false));
}
}

View file

@ -1,21 +1,15 @@
package com.simibubi.create.foundation.behaviour.scrollvalue;
import com.mojang.blaze3d.platform.GlStateManager.DestFactor;
import com.mojang.blaze3d.platform.GlStateManager.SourceFactor;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllKeys;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.behaviour.ValueBox;
import com.simibubi.create.foundation.behaviour.ValueBox.IconValueBox;
import com.simibubi.create.foundation.behaviour.ValueBox.TextValueBox;
import com.simibubi.create.foundation.behaviour.ValueBoxRenderer;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform.Sided;
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.TessellatorHelper;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.Direction;
@ -24,22 +18,17 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.DrawHighlightEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber(value = Dist.CLIENT)
public class ScrollValueRenderer {
@SubscribeEvent
public static void renderBlockHighlight(DrawHighlightEvent event) {
RayTraceResult target = event.getTarget();
public static void tick() {
Minecraft mc = Minecraft.getInstance();
RayTraceResult target = mc.objectMouseOver;
if (target == null || !(target instanceof BlockRayTraceResult))
return;
BlockRayTraceResult result = (BlockRayTraceResult) target;
ClientWorld world = Minecraft.getInstance().world;
ClientWorld world = mc.world;
BlockPos pos = result.getPos();
Direction face = result.getFace();
@ -50,48 +39,41 @@ public class ScrollValueRenderer {
return;
boolean highlight = behaviour.testHit(target.getHitVec());
TessellatorHelper.prepareForDrawing();
if (behaviour instanceof BulkScrollValueBehaviour && AllKeys.ctrlDown()) {
BulkScrollValueBehaviour bulkScrolling = (BulkScrollValueBehaviour) behaviour;
for (SmartTileEntity smartTileEntity : bulkScrolling.getBulk()) {
RenderSystem.pushMatrix();
ScrollValueBehaviour other = TileEntityBehaviour.get(smartTileEntity, ScrollValueBehaviour.TYPE);
if (other != null)
render(world, smartTileEntity.getPos(), face, other, highlight);
RenderSystem.popMatrix();
addBox(world, smartTileEntity.getPos(), face, other, highlight);
}
} else
render(world, pos, face, behaviour, highlight);
TessellatorHelper.cleanUpAfterDrawing();
RenderSystem.enableAlphaTest();
RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
addBox(world, pos, face, behaviour, highlight);
}
protected static void render(ClientWorld world, BlockPos pos, Direction face, ScrollValueBehaviour behaviour,
boolean highlight) {
RenderSystem.translated(pos.getX(), pos.getY(), pos.getZ());
BlockState state = world.getBlockState(pos);
if (behaviour.slotPositioning instanceof Sided)
((Sided) behaviour.slotPositioning).fromSide(face);
behaviour.slotPositioning.renderTransformed(state, () -> {
AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.5f).contract(0, 0, -.5f).offset(0, 0,
-.125f);
String label = behaviour.label;
ValueBox box;
protected static void addBox(ClientWorld world, BlockPos pos, Direction face, ScrollValueBehaviour behaviour,
boolean highlight) {
AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.5f)
.contract(0, 0, -.5f)
.offset(0, 0, -.125f);
String label = behaviour.label;
ValueBox box;
if (behaviour instanceof ScrollOptionBehaviour) {
box = new IconValueBox(label, ((ScrollOptionBehaviour<?>) behaviour).getIconForSelected(), bb);
} else {
box = new TextValueBox(label, bb, behaviour.formatValue());
if (behaviour.unit != null)
box.subLabel("(" + behaviour.unit.apply(behaviour.scrollableValue) + ")");
}
if (behaviour instanceof ScrollOptionBehaviour) {
box = new IconValueBox(label, ((ScrollOptionBehaviour<?>) behaviour).getIconForSelected(), bb, pos);
} else {
box = new TextValueBox(label, bb, pos, behaviour.formatValue());
if (behaviour.unit != null)
box.subLabel("(" + behaviour.unit.apply(behaviour.scrollableValue) + ")");
}
box.scrollTooltip("[" + Lang.translate("action.scroll") + "]");
box.offsetLabel(behaviour.textShift.add(20, -10, 0)).withColors(0xbe970b, 0xffe75e);
ValueBoxRenderer.renderBox(box, highlight);
});
box.scrollTooltip("[" + Lang.translate("action.scroll") + "]");
box.offsetLabel(behaviour.textShift.add(20, -10, 0))
.withColors(0x5A5D5A, 0xB5B7B6)
.passive(!highlight);
CreateClient.outliner.showValueBox(pos, box.transform(behaviour.slotPositioning))
.lineWidth(1 / 64f)
.highlightFace(face);
}
}

View file

@ -1,35 +0,0 @@
package com.simibubi.create.foundation.utility;
import org.lwjgl.opengl.GL11;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.util.math.Vec3d;
public class GlHelper {
public static void renderTransformed(Vec3d position, Vec3d rotation, float scale, Runnable render) {
if (position == null)
return;
RenderSystem.pushMatrix();
RenderSystem.translated(position.x, position.y, position.z);
RenderSystem.rotatef((float) rotation.y, 0, 1, 0);
RenderSystem.rotatef((float) rotation.z, 1, 0, 0);
RenderSystem.rotatef((float) rotation.x, 0, 0, 1);
RenderSystem.scaled(scale, scale, scale);
render.run();
RenderSystem.popMatrix();
}
public static void enableTextureRepeat() {
RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10242, GL11.GL_REPEAT);
RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10243, GL11.GL_REPEAT);
}
public static void disableTextureRepeat() {
RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10242, GL11.GL_CLAMP);
RenderSystem.texParameter(GL11.GL_TEXTURE_2D, 10243, GL11.GL_CLAMP);
}
}

View file

@ -2,6 +2,8 @@ package com.simibubi.create.foundation.utility;
import java.util.Random;
import net.minecraft.client.renderer.Quaternion;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.nbt.DoubleNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.util.Direction;
@ -10,6 +12,8 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class VecHelper {
@ -19,9 +23,10 @@ public class VecHelper {
public static Vec3d rotateCentered(Vec3d vec, double deg, Axis axis) {
Vec3d shift = getCenterOf(BlockPos.ZERO);
return VecHelper.rotate(vec.subtract(shift), deg, axis).add(shift);
return VecHelper.rotate(vec.subtract(shift), deg, axis)
.add(shift);
}
public static Vec3d rotate(Vec3d vec, double deg, Axis axis) {
if (deg == 0)
return vec;
@ -52,7 +57,7 @@ public class VecHelper {
public static Vec3d offsetRandomly(Vec3d vec, Random r, float radius) {
return new Vec3d(vec.x + (r.nextFloat() - .5f) * 2 * radius, vec.y + (r.nextFloat() - .5f) * 2 * radius,
vec.z + (r.nextFloat() - .5f) * 2 * radius);
vec.z + (r.nextFloat() - .5f) * 2 * radius);
}
public static Vec3d planeByNormal(Vec3d vec) {
@ -71,27 +76,42 @@ public class VecHelper {
public static Vec3d readNBT(ListNBT list) {
return new Vec3d(list.getDouble(0), list.getDouble(1), list.getDouble(2));
}
public static Vec3d voxelSpace(double x, double y, double z) {
return new Vec3d(x, y, z).scale(1 / 16f);
}
public static int getCoordinate(Vec3i pos, Axis axis) {
return axis.getCoordinate(pos.getX(), pos.getY(), pos.getZ());
}
public static float getCoordinate(Vec3d vec, Axis axis) {
return (float) axis.getCoordinate(vec.x, vec.y, vec.z);
}
public static boolean onSameAxis(BlockPos pos1, BlockPos pos2, Axis axis) {
if (pos1.equals(pos2))
return true;
for (Axis otherAxis : Axis.values())
for (Axis otherAxis : Axis.values())
if (axis != otherAxis)
if (getCoordinate(pos1, otherAxis) != getCoordinate(pos2, otherAxis))
return false;
return true;
}
@OnlyIn(Dist.CLIENT)
public static Quaternion rotateX(double angle) {
return Vector3f.POSITIVE_X.getDegreesQuaternion((float) angle);
}
@OnlyIn(Dist.CLIENT)
public static Quaternion rotateY(double angle) {
return Vector3f.POSITIVE_Y.getDegreesQuaternion((float) angle);
}
@OnlyIn(Dist.CLIENT)
public static Quaternion rotateZ(double angle) {
return Vector3f.POSITIVE_Z.getDegreesQuaternion((float) angle);
}
}

View file

@ -75,7 +75,7 @@ public class AABBOutline extends Outline {
return;
ResourceLocation faceTexture = params.faceTexture.get().getLocation();
if (direction == params.highlightedFace && params.hightlightedFaceTexture.isPresent())
if (direction == params.getHighlightedFace() && params.hightlightedFaceTexture.isPresent())
faceTexture = params.hightlightedFaceTexture.get().getLocation();
RenderType translucentType =
@ -87,7 +87,7 @@ public class AABBOutline extends Outline {
Vec3d vDiff = p4.subtract(p1);
float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x);
float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y);
putQuadUV(ms, builder, p1, p2, p3, p4, 0, 0, maxU, maxV);
putQuadUV(ms, builder, p1, p2, p3, p4, 0, 0, maxU, maxV, Direction.UP);
}
}

View file

@ -74,7 +74,7 @@ public class BlockClusterOutline extends Outline {
plane = VecHelper.rotate(plane, deg, axis);
Vec3d a4 = plane.add(center);
putQuad(ms, builder, a1, a2, a3, a4);
putQuad(ms, builder, a1, a2, a3, a4, face);
}
private static class Cluster {

View file

@ -12,6 +12,7 @@ import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.Matrix3f;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.util.Direction;
@ -21,6 +22,7 @@ import net.minecraft.util.math.Vec3d;
public abstract class Outline {
protected OutlineParams params;
protected Matrix3f transformNormals;
public Outline() {
params = new OutlineParams();
@ -62,40 +64,74 @@ public abstract class Outline {
Vec3d a4 = plane.add(start);
Vec3d b4 = plane.add(end);
putQuad(ms, builder, b4, b3, b2, b1);
putQuad(ms, builder, a1, a2, a3, a4);
putQuad(ms, builder, a1, b1, b2, a2);
putQuad(ms, builder, a2, b2, b3, a3);
putQuad(ms, builder, a3, b3, b4, a4);
putQuad(ms, builder, a4, b4, b1, a1);
if (params.disableNormals) {
face = Direction.UP;
putQuad(ms, builder, b4, b3, b2, b1, face);
putQuad(ms, builder, a1, a2, a3, a4, face);
putQuad(ms, builder, a1, b1, b2, a2, face);
putQuad(ms, builder, a2, b2, b3, a3, face);
putQuad(ms, builder, a3, b3, b4, a4, face);
putQuad(ms, builder, a4, b4, b1, a1, face);
return;
}
putQuad(ms, builder, b4, b3, b2, b1, face);
putQuad(ms, builder, a1, a2, a3, a4, face.getOpposite());
Vec3d vec = a1.subtract(a4);
face = Direction.getFacingFromVector(vec.x, vec.y, vec.z);
putQuad(ms, builder, a1, b1, b2, a2, face);
vec = VecHelper.rotate(vec, -90, axis);
face = Direction.getFacingFromVector(vec.x, vec.y, vec.z);
putQuad(ms, builder, a2, b2, b3, a3, face);
vec = VecHelper.rotate(vec, -90, axis);
face = Direction.getFacingFromVector(vec.x, vec.y, vec.z);
putQuad(ms, builder, a3, b3, b4, a4, face);
vec = VecHelper.rotate(vec, -90, axis);
face = Direction.getFacingFromVector(vec.x, vec.y, vec.z);
putQuad(ms, builder, a4, b4, b1, a1, face);
}
public void putQuad(MatrixStack ms, IVertexBuilder builder, Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4) {
putQuadUV(ms, builder, v1, v2, v3, v4, 0, 0, 1, 1);
public void putQuad(MatrixStack ms, IVertexBuilder builder, Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4,
Direction normal) {
putQuadUV(ms, builder, v1, v2, v3, v4, 0, 0, 1, 1, normal);
}
public void putQuadUV(MatrixStack ms, IVertexBuilder builder, Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, float minU,
float minV, float maxU, float maxV) {
putVertex(ms, builder, v1, minU, minV);
putVertex(ms, builder, v2, maxU, minV);
putVertex(ms, builder, v3, maxU, maxV);
putVertex(ms, builder, v4, minU, maxV);
float minV, float maxU, float maxV, Direction normal) {
putVertex(ms, builder, v1, minU, minV, normal);
putVertex(ms, builder, v2, maxU, minV, normal);
putVertex(ms, builder, v3, maxU, maxV, normal);
putVertex(ms, builder, v4, minU, maxV, normal);
}
protected void putVertex(MatrixStack ms, IVertexBuilder builder, Vec3d pos, float u, float v) {
protected void putVertex(MatrixStack ms, IVertexBuilder builder, Vec3d pos, float u, float v, Direction normal) {
int i = 15 << 20 | 15 << 4;
int j = i >> 16 & '\uffff';
int k = i & '\uffff';
Entry peek = ms.peek();
Vec3d rgb = params.rgb;
if (transformNormals == null)
transformNormals = peek.getNormal();
int xOffset = 0;
int yOffset = 0;
int zOffset = 0;
if (normal != null) {
xOffset = normal.getXOffset();
yOffset = normal.getYOffset();
zOffset = normal.getZOffset();
}
builder.vertex(peek.getModel(), (float) pos.x, (float) pos.y, (float) pos.z)
.color((float) rgb.x, (float) rgb.y, (float) rgb.z, params.alpha)
.texture(u, v)
.overlay(OverlayTexture.DEFAULT_UV)
.light(j, k)
.normal(peek.getNormal(), 0, 1, 0)
.normal(peek.getNormal(), xOffset, yOffset, zOffset)
.endVertex();
transformNormals = null;
}
public void tick() {}
@ -105,15 +141,16 @@ public abstract class Outline {
}
public static class OutlineParams {
Optional<AllSpecialTextures> faceTexture;
Optional<AllSpecialTextures> hightlightedFaceTexture;
Direction highlightedFace;
boolean fadeLineWidth;
boolean disableCull;
float alpha;
protected Optional<AllSpecialTextures> faceTexture;
protected Optional<AllSpecialTextures> hightlightedFaceTexture;
protected Direction highlightedFace;
protected boolean fadeLineWidth;
protected boolean disableCull;
protected boolean disableNormals;
protected float alpha;
protected int lightMapU, lightMapV;
protected Vec3d rgb;
private float lineWidth;
int lightMapU, lightMapV;
Vec3d rgb;
public OutlineParams() {
faceTexture = hightlightedFaceTexture = Optional.empty();
@ -140,13 +177,13 @@ public abstract class Outline {
}
public OutlineParams withFaceTexture(AllSpecialTextures texture) {
this.faceTexture = Optional.of(texture);
this.faceTexture = Optional.ofNullable(texture);
return this;
}
public OutlineParams withFaceTextures(AllSpecialTextures texture, AllSpecialTextures highlightTexture) {
this.faceTexture = Optional.of(texture);
this.hightlightedFaceTexture = Optional.of(highlightTexture);
this.faceTexture = Optional.ofNullable(texture);
this.hightlightedFaceTexture = Optional.ofNullable(highlightTexture);
return this;
}
@ -155,12 +192,26 @@ public abstract class Outline {
return this;
}
// util
public OutlineParams disableNormals() {
disableNormals = true;
return this;
}
float getLineWidth() {
public OutlineParams disableCull() {
disableCull = true;
return this;
}
// getter
public float getLineWidth() {
return fadeLineWidth ? alpha * lineWidth : lineWidth;
}
public Direction getHighlightedFace() {
return highlightedFace;
}
}
}

View file

@ -7,6 +7,7 @@ import java.util.Optional;
import java.util.Set;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.behaviour.ValueBox;
import com.simibubi.create.foundation.utility.outliner.Outline.OutlineParams;
import net.minecraft.client.Minecraft;
@ -21,6 +22,11 @@ public class Outliner {
// Facade
public OutlineParams showValueBox(Object slot, ValueBox box) {
outlines.put(slot, new OutlineEntry(box));
return box.getParams();
}
public OutlineParams showAABB(Object slot, AxisAlignedBB bb) {
createAABBOutlineIfMissing(slot, bb);
ChasingAABBOutline outline = getAndRefreshAABB(slot);

View file

@ -9,6 +9,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import com.mojang.datafixers.util.Pair;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllKeys;
import com.simibubi.create.AllSpecialTextures;
@ -36,13 +37,14 @@ public class ChassisRangeDisplay {
this.te = te;
timer = DISPLAY_TIME;
CreateClient.outliner.showCluster(getOutlineKey(), createSelection(te))
.colored(0xFFFFBB)
.colored(0xFFFFFF)
.disableNormals()
.lineWidth(1 / 16f)
.withFaceTexture(AllSpecialTextures.CHECKERED);
.withFaceTexture(AllSpecialTextures.HIGHLIGHT_CHECKERED);
}
protected Object getOutlineKey() {
return te.getPos();
return Pair.of(te.getPos(), new Integer(1));
}
protected Set<BlockPos> createSelection(ChassisTileEntity chassis) {
@ -85,7 +87,7 @@ public class ChassisRangeDisplay {
static Map<BlockPos, Entry> entries = new HashMap<>();
static List<GroupEntry> groupEntries = new ArrayList<>();
public static void clientTick() {
public static void tick() {
PlayerEntity player = Minecraft.getInstance().player;
World world = Minecraft.getInstance().world;
boolean hasWrench = AllItems.WRENCH.typeOf(player.getHeldItemMainhand());

View file

@ -2,8 +2,10 @@ package com.simibubi.create.modules.contraptions.components.contraptions;
import java.util.function.BiPredicate;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;
import net.minecraft.state.properties.BlockStateProperties;
@ -23,10 +25,9 @@ public class DirectionalExtenderScrollOptionSlot extends CenteredSideValueBoxTra
}
@Override
protected Vec3d getOrientation(BlockState state) {
Vec3d orientation = super.getOrientation(state);
if (direction.getAxis().isHorizontal())
return orientation;
return orientation.add(0, AngleHelper.horizontalAngle(state.get(BlockStateProperties.FACING)) - 90, 0);
protected void rotate(BlockState state, MatrixStack ms) {
if (!direction.getAxis().isHorizontal())
ms.multiply(VecHelper.rotateY(AngleHelper.horizontalAngle(state.get(BlockStateProperties.FACING)) - 90));
super.rotate(state, ms);
}
}

View file

@ -5,10 +5,7 @@ import org.apache.commons.lang3.tuple.Pair;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.behaviour.ValueBox;
import com.simibubi.create.foundation.behaviour.ValueBoxRenderer;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.GlHelper;
import com.simibubi.create.foundation.utility.TessellatorHelper;
import net.minecraft.block.BlockState;
@ -18,7 +15,6 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.Hand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.RayTraceResult;
@ -67,16 +63,16 @@ public class ConnectedInputRenderer {
int zRot = face == Direction.UP ? 90 : face == Direction.DOWN ? 270 : 0;
float yRot = AngleHelper.horizontalAngle(face.getOpposite());
Vec3d rotation = new Vec3d(0, yRot, zRot);
//
// GlHelper.renderTransformed(pair.getValue(), rotation, .5f, () -> {
//
// String label = "Connect / Disconnect";// Lang.translate("crafter.connect");
// AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(1/3f);
// ValueBox box = new ValueBox(label, bb, pos);
// box.withColors(0x018383, 0x42e6a4).offsetLabel(new Vec3d(10, 0, 0));
// ValueBoxRenderer.renderBox(box, activatedDirection == pair.getKey());
GlHelper.renderTransformed(pair.getValue(), rotation, .5f, () -> {
String label = "Connect / Disconnect";// Lang.translate("crafter.connect");
AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(1/3f);
ValueBox box = new ValueBox(label, bb);
box.withColors(0x018383, 0x42e6a4).offsetLabel(new Vec3d(10, 0, 0));
ValueBoxRenderer.renderBox(box, activatedDirection == pair.getKey());
});
// });
}
TessellatorHelper.cleanUpAfterDrawing();

View file

@ -1,5 +1,6 @@
package com.simibubi.create.modules.contraptions.components.deployer;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper;
@ -25,11 +26,12 @@ public class DeployerFilterSlot extends ValueBoxTransform {
}
@Override
protected Vec3d getOrientation(BlockState state) {
protected void rotate(BlockState state, MatrixStack ms) {
Direction facing = state.get(DeployerBlock.FACING);
float yRot = AngleHelper.horizontalAngle(facing) + 180;
float zRot = facing == Direction.UP ? 90 : facing == Direction.DOWN ? 270 : 0;
return new Vec3d(0, yRot, zRot);
ms.multiply(VecHelper.rotateY(yRot));
ms.multiply(VecHelper.rotateX(zRot));
}
}

View file

@ -1,5 +1,6 @@
package com.simibubi.create.modules.contraptions.components.saw;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.utility.VecHelper;
@ -19,8 +20,9 @@ public class SawFilterSlot extends ValueBoxTransform {
}
@Override
protected Vec3d getOrientation(BlockState state) {
return new Vec3d(0, state.get(SawBlock.AXIS_ALONG_FIRST_COORDINATE) ? 270 : 180, 90);
protected void rotate(BlockState state, MatrixStack ms) {
ms.multiply(VecHelper.rotateY(state.get(SawBlock.AXIS_ALONG_FIRST_COORDINATE) ? 270 : 180));
ms.multiply(VecHelper.rotateX(90));
}
}

View file

@ -1,5 +1,6 @@
package com.simibubi.create.modules.logistics.block;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper;
@ -37,11 +38,12 @@ public class RedstoneLinkFrequencySlot extends ValueBoxTransform.Dual {
}
@Override
protected Vec3d getOrientation(BlockState state) {
protected void rotate(BlockState state, MatrixStack ms) {
Direction facing = state.get(RedstoneLinkBlock.FACING);
float yRot = facing.getAxis().isVertical() ? 180 : AngleHelper.horizontalAngle(facing);
float yRot = facing.getAxis().isVertical() ? 0 : AngleHelper.horizontalAngle(facing) + 180;
float zRot = facing == Direction.UP ? 90 : facing == Direction.DOWN ? 270 : 0;
return new Vec3d(0, yRot + 180, zRot);
ms.multiply(VecHelper.rotateY(yRot));
ms.multiply(VecHelper.rotateX(zRot));
}
@Override

View file

@ -1,5 +1,6 @@
package com.simibubi.create.modules.logistics.block.belts.observer;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper;
@ -18,9 +19,9 @@ public class BeltObserverFilterSlot extends ValueBoxTransform {
}
@Override
protected Vec3d getOrientation(BlockState state) {
float yRot = AngleHelper.horizontalAngle(state.get(HorizontalBlock.HORIZONTAL_FACING));
return new Vec3d(0, 180 + yRot, 90);
protected void rotate(BlockState state, MatrixStack ms) {
ms.multiply(VecHelper.rotateY(AngleHelper.horizontalAngle(state.get(HorizontalBlock.HORIZONTAL_FACING)) + 180));
ms.multiply(VecHelper.rotateX(90));
}
}

View file

@ -1,5 +1,6 @@
package com.simibubi.create.modules.logistics.block.diodes;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper;
@ -16,8 +17,10 @@ public class FlexpeaterScrollSlot extends ValueBoxTransform {
}
@Override
protected Vec3d getOrientation(BlockState state) {
return new Vec3d(0, AngleHelper.horizontalAngle(state.get(BlockStateProperties.HORIZONTAL_FACING)) + 180, 90);
protected void rotate(BlockState state, MatrixStack ms) {
float y = AngleHelper.horizontalAngle(state.get(BlockStateProperties.HORIZONTAL_FACING)) + 180;
ms.multiply(VecHelper.rotateY(y));
ms.multiply(VecHelper.rotateX(90));
}
}

View file

@ -2,6 +2,7 @@ package com.simibubi.create.modules.logistics.block.extractor;
import static net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper;
@ -24,17 +25,18 @@ public class ExtractorSlots {
protected Vec3d getLocation(BlockState state) {
Vec3d location = offsetForHorizontal;
if (state.getBlock() instanceof TransposerBlock)
location = location.add(0, 2/16f, 0);
location = location.add(0, 2 / 16f, 0);
if (AttachedLogisticalBlock.isVertical(state))
location = state.get(AttachedLogisticalBlock.UPWARD) ? offsetForUpward : offsetForDownward;
return rotateHorizontally(state, location);
}
@Override
protected Vec3d getOrientation(BlockState state) {
protected void rotate(BlockState state, MatrixStack ms) {
float yRot = AngleHelper.horizontalAngle(state.get(HORIZONTAL_FACING));
float zRot = (AttachedLogisticalBlock.isVertical(state)) ? 0 : 90;
return new Vec3d(0, yRot, zRot);
float xRot = (AttachedLogisticalBlock.isVertical(state)) ? 0 : 90;
ms.multiply(VecHelper.rotateY(yRot));
ms.multiply(VecHelper.rotateX(xRot));
}
}
@ -53,14 +55,14 @@ public class ExtractorSlots {
protected Vec3d getLocation(BlockState state) {
Vec3d location = offsetForHorizontal;
if (state.getBlock() instanceof TransposerBlock)
location = location.add(0, 2/16f, 0);
location = location.add(0, 2 / 16f, 0);
if (!isFirst())
location = location.add(0, 4/16f, 0);
location = location.add(0, 4 / 16f, 0);
if (AttachedLogisticalBlock.isVertical(state)) {
location = state.get(AttachedLogisticalBlock.UPWARD) ? offsetForUpward : offsetForDownward;
if (!isFirst())
location = location.add(-4/16f, 0, 0);
location = location.add(-4 / 16f, 0, 0);
}
float yRot = AngleHelper.horizontalAngle(state.get(HORIZONTAL_FACING));
@ -69,12 +71,13 @@ public class ExtractorSlots {
}
@Override
protected Vec3d getOrientation(BlockState state) {
protected void rotate(BlockState state, MatrixStack ms) {
float horizontalAngle = AngleHelper.horizontalAngle(state.get(HORIZONTAL_FACING));
boolean vertical = AttachedLogisticalBlock.isVertical(state);
float xRot = vertical ? (state.get(AttachedLogisticalBlock.UPWARD) ? 90 : 270) : 0;
float yRot = vertical ? horizontalAngle + 180 : horizontalAngle + 270;
return new Vec3d(xRot, yRot, 0);
ms.multiply(VecHelper.rotateY(yRot));
ms.multiply(VecHelper.rotateZ(xRot));
}
}

View file

@ -1,5 +1,6 @@
package com.simibubi.create.modules.logistics.block.funnel;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper;
@ -31,18 +32,19 @@ public class FunnelFilterSlot extends ValueBoxTransform {
}
@Override
protected Vec3d getOrientation(BlockState state) {
protected void rotate(BlockState state, MatrixStack ms) {
Direction blockFacing = AttachedLogisticalBlock.getBlockFacing(state);
boolean vertical = AttachedLogisticalBlock.isVertical(state);
float horizontalAngle = AngleHelper.horizontalAngle(state.get(ExtractorBlock.HORIZONTAL_FACING));
float yRot = blockFacing == Direction.DOWN ? horizontalAngle + 180 : horizontalAngle;
float zRot = (vertical || state.get(FunnelBlock.BELT)) ? 90 : 0;
float xRot = (vertical || state.get(FunnelBlock.BELT)) ? 90 : 0;
if (blockFacing == Direction.UP)
zRot += 180;
return new Vec3d(0, yRot, zRot);
xRot += 180;
ms.multiply(VecHelper.rotateY(yRot));
ms.multiply(VecHelper.rotateX(xRot));
}
}

View file

@ -2,11 +2,13 @@ package com.simibubi.create.modules.logistics.block.inventories;
import java.util.List;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;
import net.minecraft.item.ItemStack;
@ -87,8 +89,8 @@ public class CreativeCrateTileEntity extends CrateTileEntity {
return new FilteringBehaviour(this, new ValueBoxTransform() {
@Override
protected Vec3d getOrientation(BlockState state) {
return new Vec3d(0, 0, 90);
protected void rotate(BlockState state, MatrixStack ms) {
ms.multiply(VecHelper.rotateX(90));
}
@Override

View file

@ -175,8 +175,9 @@ public class SchematicAndQuillHandler {
AxisAlignedBB currentSelectionBox = getCurrentSelectionBox();
if (currentSelectionBox != null)
outliner().chaseAABB(outlineSlot, currentSelectionBox)
.colored(0xDDDFFF)
.colored(0x6886c5)
.withFaceTextures(AllSpecialTextures.CHECKERED, AllSpecialTextures.HIGHLIGHT_CHECKERED)
.disableNormals()
.highlightFace(selectedFace);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 B