Schematics in 1.15

- Ported Schematic placement tools to a usable state (missing preview and noCull)
This commit is contained in:
simibubi 2020-05-26 14:40:15 +02:00
parent f9fc00855a
commit 57edbe0c38
14 changed files with 300 additions and 250 deletions

View File

@ -60,7 +60,6 @@ public class MechanicalCrafterRenderer extends SafeTileEntityRenderer<Mechanical
ms.pop(); ms.pop();
renderFast(te, partialTicks, ms, buffer, light); renderFast(te, partialTicks, ms, buffer, light);
// TessellatorHelper.draw();
} }
public void renderItems(MechanicalCrafterTileEntity te, float partialTicks, MatrixStack ms, public void renderItems(MechanicalCrafterTileEntity te, float partialTicks, MatrixStack ms,

View File

@ -4,7 +4,6 @@ import java.util.List;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.AllKeys; import com.simibubi.create.AllKeys;
import com.simibubi.create.content.schematics.SchematicWorld; import com.simibubi.create.content.schematics.SchematicWorld;
@ -14,7 +13,7 @@ import com.simibubi.create.content.schematics.packet.SchematicPlacePacket;
import com.simibubi.create.foundation.gui.ToolSelectionScreen; import com.simibubi.create.foundation.gui.ToolSelectionScreen;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.networking.NbtPacket; import com.simibubi.create.foundation.networking.NbtPacket;
import com.simibubi.create.foundation.utility.TessellatorHelper; import com.simibubi.create.foundation.utility.outliner.AABBOutline;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.entity.player.ClientPlayerEntity;
@ -33,7 +32,7 @@ public class SchematicHandler {
private String displayedSchematic; private String displayedSchematic;
private SchematicTransformation transformation; private SchematicTransformation transformation;
private AxisAlignedBB bounds; private AxisAlignedBB bounds;
private boolean deployed; private boolean deployed;
private boolean active; private boolean active;
private Tools currentTool; private Tools currentTool;
@ -42,6 +41,7 @@ public class SchematicHandler {
private int syncCooldown; private int syncCooldown;
private int activeHotbarSlot; private int activeHotbarSlot;
private ItemStack activeSchematicItem; private ItemStack activeSchematicItem;
private AABBOutline outline;
private SchematicRenderer renderer; private SchematicRenderer renderer;
private SchematicHotbarSlotOverlay overlay; private SchematicHotbarSlotOverlay overlay;
@ -73,7 +73,9 @@ public class SchematicHandler {
return; return;
} }
if (!active || !stack.getTag().getString("File").equals(displayedSchematic)) if (!active || !stack.getTag()
.getString("File")
.equals(displayedSchematic))
init(player, stack); init(player, stack);
if (!active) if (!active)
return; return;
@ -85,12 +87,14 @@ public class SchematicHandler {
sync(); sync();
selectionScreen.update(); selectionScreen.update();
currentTool.getTool().updateSelection(); currentTool.getTool()
.updateSelection();
} }
private void init(ClientPlayerEntity player, ItemStack stack) { private void init(ClientPlayerEntity player, ItemStack stack) {
loadSettings(stack); loadSettings(stack);
displayedSchematic = stack.getTag().getString("File"); displayedSchematic = stack.getTag()
.getString("File");
active = true; active = true;
if (deployed) { if (deployed) {
setupRenderer(); setupRenderer();
@ -106,7 +110,8 @@ public class SchematicHandler {
private void setupRenderer() { private void setupRenderer() {
Template schematic = SchematicItem.loadSchematic(activeSchematicItem); Template schematic = SchematicItem.loadSchematic(activeSchematicItem);
if (schematic.getSize().equals(BlockPos.ZERO)) if (schematic.getSize()
.equals(BlockPos.ZERO))
return; return;
SchematicWorld w = new SchematicWorld(BlockPos.ZERO, Minecraft.getInstance().world); SchematicWorld w = new SchematicWorld(BlockPos.ZERO, Minecraft.getInstance().world);
@ -118,25 +123,21 @@ public class SchematicHandler {
boolean present = activeSchematicItem != null; boolean present = activeSchematicItem != null;
if (!active && !present) if (!active && !present)
return; return;
if (active) {
TessellatorHelper.prepareForDrawing();
currentTool.getTool().renderTool(ms, buffer, light, overlay);
TessellatorHelper.cleanUpAfterDrawing();
}
GlStateManager.pushMatrix(); ms.push();
TessellatorHelper.prepareForDrawing(); transformation.applyGLTransformations(ms);
transformation.applyGLTransformations();
renderer.render(ms, buffer); renderer.render(ms, buffer);
GlStateManager.disableCull(); if (active)
currentTool.getTool()
.renderOnSchematic(ms, buffer, light, overlay);
ms.pop();
if (active) if (active) {
currentTool.getTool().renderToolLocal(ms, buffer, light, overlay); ms.push();
currentTool.getTool()
GlStateManager.enableCull(); .renderTool(ms, buffer, light, overlay);
GlStateManager.depthMask(true); ms.pop();
TessellatorHelper.cleanUpAfterDrawing(); }
GlStateManager.popMatrix();
} }
public void renderOverlay(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { public void renderOverlay(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
@ -145,8 +146,10 @@ public class SchematicHandler {
if (activeSchematicItem != null) if (activeSchematicItem != null)
this.overlay.renderOn(activeHotbarSlot); this.overlay.renderOn(activeHotbarSlot);
currentTool.getTool().renderOverlay(ms, buffer, light, overlay); currentTool.getTool()
selectionScreen.renderPassive(Minecraft.getInstance().getRenderPartialTicks()); .renderOverlay(ms, buffer, light, overlay);
selectionScreen.renderPassive(Minecraft.getInstance()
.getRenderPartialTicks());
} }
public void onMouseInput(int button, boolean pressed) { public void onMouseInput(int button, boolean pressed) {
@ -157,7 +160,8 @@ public class SchematicHandler {
if (Minecraft.getInstance().player.isSneaking()) if (Minecraft.getInstance().player.isSneaking())
return; return;
currentTool.getTool().handleRightClick(); currentTool.getTool()
.handleRightClick();
} }
public void onKeyInput(int key, boolean pressed) { public void onKeyInput(int key, boolean pressed) {
@ -183,7 +187,8 @@ public class SchematicHandler {
return true; return true;
} }
if (AllKeys.ACTIVATE_TOOL.isPressed()) if (AllKeys.ACTIVATE_TOOL.isPressed())
return currentTool.getTool().handleMouseWheel(delta); return currentTool.getTool()
.handleMouseWheel(delta);
return false; return false;
} }
@ -201,7 +206,8 @@ public class SchematicHandler {
private boolean itemLost(PlayerEntity player) { private boolean itemLost(PlayerEntity player) {
for (int i = 0; i < PlayerInventory.getHotbarSize(); i++) { for (int i = 0; i < PlayerInventory.getHotbarSize(); i++) {
if (!player.inventory.getStackInSlot(i).isItemEqual(activeSchematicItem)) if (!player.inventory.getStackInSlot(i)
.isItemEqual(activeSchematicItem))
continue; continue;
if (!ItemStack.areItemStackTagsEqual(player.inventory.getStackInSlot(i), activeSchematicItem)) if (!ItemStack.areItemStackTagsEqual(player.inventory.getStackInSlot(i), activeSchematicItem))
continue; continue;
@ -222,15 +228,18 @@ public class SchematicHandler {
CompoundNBT tag = activeSchematicItem.getTag(); CompoundNBT tag = activeSchematicItem.getTag();
tag.putBoolean("Deployed", deployed); tag.putBoolean("Deployed", deployed);
tag.put("Anchor", NBTUtil.writeBlockPos(transformation.getAnchor())); tag.put("Anchor", NBTUtil.writeBlockPos(transformation.getAnchor()));
tag.putString("Rotation", settings.getRotation().name()); tag.putString("Rotation", settings.getRotation()
tag.putString("Mirror", settings.getMirror().name()); .name());
tag.putString("Mirror", settings.getMirror()
.name());
AllPackets.channel.sendToServer(new NbtPacket(activeSchematicItem, activeHotbarSlot)); AllPackets.channel.sendToServer(new NbtPacket(activeSchematicItem, activeHotbarSlot));
} }
public void equip(Tools tool) { public void equip(Tools tool) {
this.currentTool = tool; this.currentTool = tool;
currentTool.getTool().init(); currentTool.getTool()
.init();
} }
public void loadSettings(ItemStack blueprint) { public void loadSettings(ItemStack blueprint) {
@ -245,8 +254,10 @@ public class SchematicHandler {
BlockPos size = NBTUtil.readBlockPos(tag.getCompound("Bounds")); BlockPos size = NBTUtil.readBlockPos(tag.getCompound("Bounds"));
bounds = new AxisAlignedBB(BlockPos.ZERO, size); bounds = new AxisAlignedBB(BlockPos.ZERO, size);
// outline = new AABBOutline(bounds); outline = new AABBOutline(bounds);
// outline.disableCull = true; outline.getParams()
.lineWidth(1 / 16f)
.disableNormals();
transformation.init(anchor, settings, bounds); transformation.init(anchor, settings, bounds);
} }
@ -293,4 +304,8 @@ public class SchematicHandler {
return activeSchematicItem; return activeSchematicItem;
} }
public AABBOutline getOutline() {
return outline;
}
} }

View File

@ -1,22 +1,17 @@
package com.simibubi.create.content.schematics.client; package com.simibubi.create.content.schematics.client;
import java.nio.ByteBuffer;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import org.lwjgl.system.MemoryUtil;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.datafixers.util.Pair;
import com.simibubi.create.content.schematics.SchematicWorld; import com.simibubi.create.content.schematics.SchematicWorld;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -24,10 +19,7 @@ import net.minecraft.client.renderer.RegionRenderCacheBuilder;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup; import net.minecraft.client.renderer.RenderTypeLookup;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.entity.Entity;
import net.minecraft.inventory.container.PlayerContainer;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.model.data.EmptyModelData; import net.minecraftforge.client.model.data.EmptyModelData;
@ -75,40 +67,40 @@ public class SchematicRenderer {
public void render(MatrixStack ms, IRenderTypeBuffer buffer) { public void render(MatrixStack ms, IRenderTypeBuffer buffer) {
// TODO 1.15 buffered render // TODO 1.15 buffered render
if (!active) // if (!active)
return; // return;
//
final Entity entity = Minecraft.getInstance() // final Entity entity = Minecraft.getInstance()
.getRenderViewEntity(); // .getRenderViewEntity();
//
if (entity == null) { // if (entity == null) {
return; // return;
} // }
//
ActiveRenderInfo renderInfo = Minecraft.getInstance().gameRenderer.getActiveRenderInfo(); // ActiveRenderInfo renderInfo = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
Vec3d view = renderInfo.getProjectedView(); // Vec3d view = renderInfo.getProjectedView();
double renderPosX = view.x; // double renderPosX = view.x;
double renderPosY = view.y; // double renderPosY = view.y;
double renderPosZ = view.z; // double renderPosZ = view.z;
//
RenderSystem.enableAlphaTest(); // RenderSystem.enableAlphaTest();
RenderSystem.enableBlend(); // RenderSystem.enableBlend();
Minecraft.getInstance() // Minecraft.getInstance()
.getTextureManager() // .getTextureManager()
.bindTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE); // .bindTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE);
//
for (RenderType layer : RenderType.getBlockLayers()) { // for (RenderType layer : RenderType.getBlockLayers()) {
if (!usedBlockRenderLayers.contains(layer)) { // if (!usedBlockRenderLayers.contains(layer)) {
continue; // continue;
} // }
final BufferBuilder bufferBuilder = bufferCache.get(layer); // final BufferBuilder bufferBuilder = bufferCache.get(layer);
RenderSystem.pushMatrix(); // RenderSystem.pushMatrix();
RenderSystem.translated(-renderPosX, -renderPosY, -renderPosZ); // RenderSystem.translated(-renderPosX, -renderPosY, -renderPosZ);
drawBuffer(bufferBuilder); // drawBuffer(bufferBuilder);
RenderSystem.popMatrix(); // RenderSystem.popMatrix();
} // }
RenderSystem.disableAlphaTest(); // RenderSystem.disableAlphaTest();
RenderSystem.disableBlend(); // RenderSystem.disableBlend();
} }
private void redraw(Minecraft minecraft) { private void redraw(Minecraft minecraft) {
@ -153,17 +145,17 @@ public class SchematicRenderer {
} }
} }
private static void drawBuffer(final BufferBuilder bufferBuilder) { // private static void drawBuffer(final BufferBuilder bufferBuilder) {
Pair<BufferBuilder.DrawState, ByteBuffer> pair = bufferBuilder.popData(); // Pair<BufferBuilder.DrawState, ByteBuffer> pair = bufferBuilder.popData();
BufferBuilder.DrawState state = pair.getFirst(); // BufferBuilder.DrawState state = pair.getFirst();
//
if (state.getCount() > 0) { // if (state.getCount() > 0) {
state.getVertexFormat() // state.getVertexFormat()
.startDrawing(MemoryUtil.memAddress(pair.getSecond())); // .startDrawing(MemoryUtil.memAddress(pair.getSecond()));
RenderSystem.drawArrays(state.getMode(), 0, state.getCount()); // RenderSystem.drawArrays(state.getMode(), 0, state.getCount());
state.getVertexFormat() // state.getVertexFormat()
.endDrawing(); // .endDrawing();
} // }
} // }
} }

View File

@ -1,8 +1,9 @@
package com.simibubi.create.content.schematics.client; package com.simibubi.create.content.schematics.client;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingAngle; import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingAngle;
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue; import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -38,7 +39,8 @@ public class SchematicTransformation {
xOrigin = bounds.getXSize() / 2f; xOrigin = bounds.getXSize() / 2f;
zOrigin = bounds.getZSize() / 2f; zOrigin = bounds.getZSize() / 2f;
int r = -(settings.getRotation().ordinal() * 90); int r = -(settings.getRotation()
.ordinal() * 90);
rotation.start(r); rotation.start(r);
Vec3d vec = fromAnchor(anchor); Vec3d vec = fromAnchor(anchor);
@ -47,21 +49,22 @@ public class SchematicTransformation {
z.start((float) vec.z); z.start((float) vec.z);
} }
public void applyGLTransformations() { public void applyGLTransformations(MatrixStack ms) {
float pt = Minecraft.getInstance().getRenderPartialTicks(); float pt = Minecraft.getInstance()
.getRenderPartialTicks();
// Translation // Translation
RenderSystem.translated(x.get(pt), y.get(pt), z.get(pt)); ms.translate(x.get(pt), y.get(pt), z.get(pt));
Vec3d rotationOffset = getRotationOffset(true); Vec3d rotationOffset = getRotationOffset(true);
// Rotation & Mirror // Rotation & Mirror
ms.translate(xOrigin, 0, zOrigin);
RenderSystem.translated(xOrigin + rotationOffset.x, 0, zOrigin + rotationOffset.z); MatrixStacker.of(ms)
RenderSystem.rotatef(rotation.get(pt), 0, 1, 0); .translate(rotationOffset)
RenderSystem.translated(-rotationOffset.x, 0, -rotationOffset.z); .rotateY(rotation.get(pt))
RenderSystem.scaled(scaleFrontBack.get(pt), 1, scaleLeftRight.get(pt)); .translateBack(rotationOffset);
RenderSystem.translated(-xOrigin, 0, -zOrigin); ms.scale(scaleFrontBack.get(pt), 1, scaleLeftRight.get(pt));
ms.translate(-xOrigin, 0, -zOrigin);
} }
@ -81,7 +84,8 @@ public class SchematicTransformation {
} }
public Vec3d toLocalSpace(Vec3d vec) { public Vec3d toLocalSpace(Vec3d vec) {
float pt = Minecraft.getInstance().getRenderPartialTicks(); float pt = Minecraft.getInstance()
.getRenderPartialTicks();
Vec3d rotationOffset = getRotationOffset(true); Vec3d rotationOffset = getRotationOffset(true);
vec = vec.subtract(x.get(pt), y.get(pt), z.get(pt)); vec = vec.subtract(x.get(pt), y.get(pt), z.get(pt));
@ -168,7 +172,8 @@ public class SchematicTransformation {
} }
public float getCurrentRotation() { public float getCurrentRotation() {
float pt = Minecraft.getInstance().getRenderPartialTicks(); float pt = Minecraft.getInstance()
.getRenderPartialTicks();
return rotation.get(pt); return rotation.get(pt);
} }

View File

@ -1,13 +1,14 @@
package com.simibubi.create.content.schematics.client.tools; package com.simibubi.create.content.schematics.client.tools;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllKeys; import com.simibubi.create.AllKeys;
import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.content.schematics.client.SchematicTransformation; import com.simibubi.create.content.schematics.client.SchematicTransformation;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.outliner.AABBOutline;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
@ -26,7 +27,9 @@ public class DeployTool extends PlacementToolBase {
@Override @Override
public void updateSelection() { public void updateSelection() {
if (schematicHandler.isActive() && selectionRange == -1) { if (schematicHandler.isActive() && selectionRange == -1) {
selectionRange = (int) (schematicHandler.getBounds().getCenter().length() / 2); selectionRange = (int) (schematicHandler.getBounds()
.getCenter()
.length() / 2);
selectionRange = MathHelper.clamp(selectionRange, 1, 100); selectionRange = MathHelper.clamp(selectionRange, 1, 100);
} }
selectIgnoreBlocks = AllKeys.ACTIVATE_TOOL.isPressed(); selectIgnoreBlocks = AllKeys.ACTIVATE_TOOL.isPressed();
@ -40,10 +43,9 @@ public class DeployTool extends PlacementToolBase {
if (selectedPos == null) if (selectedPos == null)
return; return;
RenderSystem.pushMatrix(); ms.push();
RenderHelper.disableStandardItemLighting(); float pt = Minecraft.getInstance()
RenderSystem.enableBlend(); .getRenderPartialTicks();
float pt = Minecraft.getInstance().getRenderPartialTicks();
double x = MathHelper.lerp(pt, lastChasingSelectedPos.x, chasingSelectedPos.x); double x = MathHelper.lerp(pt, lastChasingSelectedPos.x, chasingSelectedPos.x);
double y = MathHelper.lerp(pt, lastChasingSelectedPos.y, chasingSelectedPos.y); double y = MathHelper.lerp(pt, lastChasingSelectedPos.y, chasingSelectedPos.y);
double z = MathHelper.lerp(pt, lastChasingSelectedPos.z, chasingSelectedPos.z); double z = MathHelper.lerp(pt, lastChasingSelectedPos.z, chasingSelectedPos.z);
@ -56,17 +58,23 @@ public class DeployTool extends PlacementToolBase {
int centerZ = (int) center.z; int centerZ = (int) center.z;
double xOrigin = bounds.getXSize() / 2f; double xOrigin = bounds.getXSize() / 2f;
double zOrigin = bounds.getZSize() / 2f; double zOrigin = bounds.getZSize() / 2f;
Vec3d origin = new Vec3d(xOrigin, 0, zOrigin);
RenderSystem.translated(x - centerX, y, z - centerZ); ms.translate(x - centerX, y, z - centerZ);
RenderSystem.translated(xOrigin + rotationOffset.x, 0, zOrigin + rotationOffset.z); MatrixStacker.of(ms)
RenderSystem.rotatef(transformation.getCurrentRotation(), 0, 1, 0); .translate(origin)
RenderSystem.translated(-rotationOffset.x, 0, -rotationOffset.z); .translate(rotationOffset)
RenderSystem.translated(-xOrigin, 0, -zOrigin); .rotateY(transformation.getCurrentRotation())
.translateBack(rotationOffset)
.translateBack(origin);
// schematicHandler.getOutline().setTextures(AllSpecialTextures.CHECKERED, null); AABBOutline outline = schematicHandler.getOutline();
// schematicHandler.getOutline().render(Tessellator.getInstance().getBuffer());TODO outline.getParams()
// schematicHandler.getOutline().setTextures(null, null); .withFaceTexture(AllSpecialTextures.CHECKERED);
RenderSystem.popMatrix(); outline.render(ms, buffer);
outline.getParams()
.clearTextures();
ms.pop();
} }
@Override @Override
@ -82,16 +90,20 @@ public class DeployTool extends PlacementToolBase {
public boolean handleRightClick() { public boolean handleRightClick() {
if (selectedPos == null) if (selectedPos == null)
return super.handleRightClick(); return super.handleRightClick();
Vec3d center = schematicHandler.getBounds().getCenter(); Vec3d center = schematicHandler.getBounds()
.getCenter();
BlockPos target = selectedPos.add(-((int) center.x), 0, -((int) center.z)); BlockPos target = selectedPos.add(-((int) center.x), 0, -((int) center.z));
ItemStack item = schematicHandler.getActiveSchematicItem(); ItemStack item = schematicHandler.getActiveSchematicItem();
if (item != null) { if (item != null) {
item.getTag().putBoolean("Deployed", true); item.getTag()
item.getTag().put("Anchor", NBTUtil.writeBlockPos(target)); .putBoolean("Deployed", true);
item.getTag()
.put("Anchor", NBTUtil.writeBlockPos(target));
} }
schematicHandler.getTransformation().moveTo(target); schematicHandler.getTransformation()
.moveTo(target);
schematicHandler.markDirty(); schematicHandler.markDirty();
schematicHandler.deploy(); schematicHandler.deploy();
return true; return true;

View File

@ -1,19 +1,20 @@
package com.simibubi.create.content.schematics.client.tools; package com.simibubi.create.content.schematics.client.tools;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.outliner.AABBOutline;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.AxisDirection;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public class FlipTool extends PlacementToolBase { public class FlipTool extends PlacementToolBase {
private AABBOutline outline = new AABBOutline(new AxisAlignedBB(BlockPos.ZERO));
@Override @Override
public void init() { public void init() {
super.init(); super.init();
@ -38,67 +39,42 @@ public class FlipTool extends PlacementToolBase {
} }
private void mirror() { private void mirror() {
if (schematicSelected && selectedFace.getAxis().isHorizontal()) { if (schematicSelected && selectedFace.getAxis()
schematicHandler.getTransformation().flip(selectedFace.getAxis()); .isHorizontal()) {
schematicHandler.getTransformation()
.flip(selectedFace.getAxis());
schematicHandler.markDirty(); schematicHandler.markDirty();
} }
} }
@Override @Override
public void renderToolLocal(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { public void renderOnSchematic(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
super.renderToolLocal(ms, buffer, light, overlay); super.renderOnSchematic(ms, buffer, light, overlay);
if (!schematicSelected || !selectedFace.getAxis().isHorizontal()) if (!schematicSelected || !selectedFace.getAxis()
.isHorizontal())
return; return;
GlStateManager.pushMatrix();
RenderHelper.disableStandardItemLighting();
GlStateManager.enableBlend();
Direction facing = selectedFace.rotateY(); Direction facing = selectedFace.rotateY();
Axis axis = facing.getAxis();
Vec3d color = ColorHelper.getRGB(0x4d80e4);
AxisAlignedBB bounds = schematicHandler.getBounds(); AxisAlignedBB bounds = schematicHandler.getBounds();
Vec3d plane = VecHelper.planeByNormal(new Vec3d(facing.getDirectionVec())); Vec3d directionVec = new Vec3d(Direction.getFacingFromAxis(AxisDirection.POSITIVE, facing.getAxis())
plane = plane.mul(bounds.getXSize() / 2f + 1, bounds.getYSize() / 2f + 1, bounds.getZSize() / 2f + 1); .getDirectionVec());
Vec3d center = bounds.getCenter(); Vec3d boundsSize = new Vec3d(bounds.getXSize(), bounds.getYSize(), bounds.getZSize());
Vec3d vec = boundsSize.mul(directionVec);
bounds = bounds.contract(vec.x, vec.y, vec.z)
.grow(1 - directionVec.x, 1 - directionVec.y, 1 - directionVec.z);
bounds = bounds.offset(directionVec.scale(.5f)
.mul(boundsSize));
Vec3d v1 = plane.add(center); outline.setBounds(bounds);
plane = plane.mul(-1, 1, -1); AllSpecialTextures tex = AllSpecialTextures.HIGHLIGHT_CHECKERED;
Vec3d v2 = plane.add(center); outline.getParams()
plane = plane.mul(1, -1, 1); .lineWidth(1 / 16f)
Vec3d v3 = plane.add(center); .disableNormals()
plane = plane.mul(-1, 1, -1); .colored(0x4d80e4)
Vec3d v4 = plane.add(center); .withFaceTextures(tex, tex);
outline.render(ms, buffer);
// BufferBuilder buffer = Tessellator.getInstance().getBuffer();TODO 1.15
// buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP);
//
// AABBOutline outline = schematicHandler.getOutline();
// AllSpecialTextures.BLANK.bind();
// outline.renderAACuboidLine(v1, v2, color, 1, builder);
// outline.renderAACuboidLine(v2, v3, color, 1, builder);
// outline.renderAACuboidLine(v3, v4, color, 1, builder);
// outline.renderAACuboidLine(v4, v1, color, 1, builder);
//
// Tessellator.getInstance().draw();
// buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP);
//
// GlHelper.enableTextureRepeat();
// GlStateManager.depthMask(false);
// Vec3d uDiff = v2.subtract(v1);
// Vec3d vDiff = v4.subtract(v1);
// float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x);
// float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y);
//
// GlStateManager.enableCull();
// AllSpecialTextures.HIGHLIGHT_CHECKERED.bind();
// outline.putQuadUV(v1, v2, v3, v4, 0, 0, maxU, maxV, color, 1, builder);
// outline.putQuadUV(v2, v1, v4, v3, 0, 0, maxU, maxV, color, 1, builder);
// Tessellator.getInstance().draw();
// GlStateManager.popMatrix();
// GlHelper.disableTextureRepeat();
} }
} }

View File

@ -14,6 +14,6 @@ public interface ISchematicTool {
public void renderTool(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay); public void renderTool(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay);
public void renderOverlay(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay); public void renderOverlay(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay);
public void renderToolLocal(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay); public void renderOnSchematic(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay);
} }

View File

@ -1,39 +1,43 @@
package com.simibubi.create.content.schematics.client.tools; package com.simibubi.create.content.schematics.client.tools;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.utility.outliner.LineOutline;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
public class RotateTool extends PlacementToolBase { public class RotateTool extends PlacementToolBase {
private LineOutline line = new LineOutline();
@Override @Override
public boolean handleMouseWheel(double delta) { public boolean handleMouseWheel(double delta) {
schematicHandler.getTransformation().rotate90(delta > 0); schematicHandler.getTransformation()
.rotate90(delta > 0);
schematicHandler.markDirty(); schematicHandler.markDirty();
return true; return true;
} }
@Override @Override
public void renderToolLocal(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { public void renderOnSchematic(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
super.renderToolLocal(ms, buffer, light, overlay); super.renderOnSchematic(ms, buffer, light, overlay);
// GlStateManager.pushMatrix();TODO 1.15 AxisAlignedBB bounds = schematicHandler.getBounds();
// RenderHelper.disableStandardItemLighting(); double height = bounds.getYSize() + Math.max(20, bounds.getYSize());
// GlStateManager.enableBlend(); Vec3d center = bounds.getCenter()
// .add(schematicHandler.getTransformation()
// Vec3d color = ColorHelper.getRGB(0x4d80e4); .getRotationOffset(false));
// AxisAlignedBB bounds = schematicHandler.getBounds(); Vec3d start = center.subtract(0, height / 2, 0);
// double height = bounds.getYSize() + Math.max(20, bounds.getYSize()); Vec3d end = center.add(0, height / 2, 0);
//
// Vec3d center = bounds.getCenter().add(schematicHandler.getTransformation().getRotationOffset(false)); line.getParams()
// Vec3d start = center.subtract(0, height / 2, 0); .colored(0x4d80e4)
// Vec3d end = center.add(0, height / 2, 0); .disableCull()
// .disableNormals()
// BufferBuilder buffer = Tessellator.getInstance().getBuffer(); .lineWidth(1 / 16f);
// buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.PARTICLE_POSITION_TEX_COLOR_LMAP); line.set(start, end)
// schematicHandler.getOutline().renderAACuboidLine(start, end, color, 1, buffer); .render(ms, buffer);
// Tessellator.getInstance().draw();
// GlStateManager.popMatrix();
} }
} }

View File

@ -4,18 +4,19 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllKeys;
import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.content.schematics.client.SchematicHandler; import com.simibubi.create.content.schematics.client.SchematicHandler;
import com.simibubi.create.content.schematics.client.SchematicTransformation; import com.simibubi.create.content.schematics.client.SchematicTransformation;
import com.simibubi.create.foundation.utility.RaycastHelper; import com.simibubi.create.foundation.utility.RaycastHelper;
import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult; import com.simibubi.create.foundation.utility.RaycastHelper.PredicateTraceResult;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.outliner.AABBOutline;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -63,7 +64,8 @@ public abstract class SchematicToolBase implements ISchematicTool {
return; return;
} }
chasingSelectedPos = chasingSelectedPos.add(target.subtract(chasingSelectedPos).scale(1 / 2f)); chasingSelectedPos = chasingSelectedPos.add(target.subtract(chasingSelectedPos)
.scale(1 / 2f));
} }
public void updateTargetPos() { public void updateTargetPos() {
@ -88,8 +90,11 @@ public abstract class SchematicToolBase implements ISchematicTool {
// Select location at distance // Select location at distance
if (selectIgnoreBlocks) { if (selectIgnoreBlocks) {
float pt = Minecraft.getInstance().getRenderPartialTicks(); float pt = Minecraft.getInstance()
selectedPos = new BlockPos(player.getEyePosition(pt).add(player.getLookVec().scale(selectionRange))); .getRenderPartialTicks();
selectedPos = new BlockPos(player.getEyePosition(pt)
.add(player.getLookVec()
.scale(selectionRange)));
if (snap) if (snap)
lastChasingSelectedPos = chasingSelectedPos = new Vec3d(selectedPos); lastChasingSelectedPos = chasingSelectedPos = new Vec3d(selectedPos);
return; return;
@ -102,8 +107,12 @@ public abstract class SchematicToolBase implements ISchematicTool {
return; return;
BlockPos hit = new BlockPos(trace.getHitVec()); BlockPos hit = new BlockPos(trace.getHitVec());
boolean replaceable = player.world.getBlockState(hit).getMaterial().isReplaceable(); boolean replaceable = player.world.getBlockState(hit)
if (trace.getFace().getAxis().isVertical() && !replaceable) .getMaterial()
.isReplaceable();
if (trace.getFace()
.getAxis()
.isVertical() && !replaceable)
hit = hit.offset(trace.getFace()); hit = hit.offset(trace.getFace());
selectedPos = hit; selectedPos = hit;
if (snap) if (snap)
@ -111,30 +120,30 @@ public abstract class SchematicToolBase implements ISchematicTool {
} }
@Override @Override
public void renderTool(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { public void renderTool(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {}
if (!schematicHandler.isDeployed())
return;
// AABBOutline outline = schematicHandler.getOutline();
if (renderSelectedFace) {
// schematicHandler.getOutline().setTextures(null,
// AllKeys.ctrlDown() ? AllSpecialTextures.HIGHLIGHT_CHECKERED : AllSpecialTextures.CHECKERED);
// outline.highlightFace(selectedFace);
}
RenderHelper.disableStandardItemLighting();
RenderSystem.pushMatrix();
RenderSystem.enableBlend();
// outline.render(Tessellator.getInstance().getBuffer());TODO
RenderSystem.popMatrix();
// outline.setTextures(null, null);
}
@Override @Override
public void renderOverlay(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {} public void renderOverlay(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {}
@Override @Override
public void renderToolLocal(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {} public void renderOnSchematic(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
if (!schematicHandler.isDeployed())
return;
ms.push();
AABBOutline outline = schematicHandler.getOutline();
if (renderSelectedFace) {
outline.getParams()
.highlightFace(selectedFace)
.withFaceTextures(AllSpecialTextures.CHECKERED,
AllKeys.ctrlDown() ? AllSpecialTextures.HIGHLIGHT_CHECKERED : AllSpecialTextures.CHECKERED);
}
outline.getParams()
.disableCull();
outline.render(ms, buffer);
outline.getParams()
.withFaceTextures(null, null);
ms.pop();
}
} }

View File

@ -17,7 +17,7 @@ public class AABBOutline extends Outline {
protected AxisAlignedBB bb; protected AxisAlignedBB bb;
public AABBOutline(AxisAlignedBB bb) { public AABBOutline(AxisAlignedBB bb) {
this.bb = bb; this.setBounds(bb);
} }
@Override @Override
@ -28,8 +28,9 @@ public class AABBOutline extends Outline {
public void renderBB(MatrixStack ms, IRenderTypeBuffer buffer, AxisAlignedBB bb) { public void renderBB(MatrixStack ms, IRenderTypeBuffer buffer, AxisAlignedBB bb) {
Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo() Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo()
.getProjectedView(); .getProjectedView();
boolean inside = bb.contains(projectedView); boolean noCull = bb.contains(projectedView);
bb = bb.grow(inside ? -1 / 128d : 1 / 128d); bb = bb.grow(noCull ? -1 / 128d : 1 / 128d);
noCull |= params.disableCull;
Vec3d xyz = new Vec3d(bb.minX, bb.minY, bb.minZ); Vec3d xyz = new Vec3d(bb.minX, bb.minY, bb.minZ);
Vec3d Xyz = new Vec3d(bb.maxX, bb.minY, bb.minZ); Vec3d Xyz = new Vec3d(bb.maxX, bb.minY, bb.minZ);
@ -41,34 +42,35 @@ public class AABBOutline extends Outline {
Vec3d XYZ = new Vec3d(bb.maxX, bb.maxY, bb.maxZ); Vec3d XYZ = new Vec3d(bb.maxX, bb.maxY, bb.maxZ);
Vec3d start = xyz; Vec3d start = xyz;
renderAACuboidLine(ms, buffer, start, Xyz); renderAACuboidLine(ms, buffer, start, Xyz, noCull);
renderAACuboidLine(ms, buffer, start, xYz); renderAACuboidLine(ms, buffer, start, xYz, noCull);
renderAACuboidLine(ms, buffer, start, xyZ); renderAACuboidLine(ms, buffer, start, xyZ, noCull);
start = XyZ; start = XyZ;
renderAACuboidLine(ms, buffer, start, xyZ); renderAACuboidLine(ms, buffer, start, xyZ, noCull);
renderAACuboidLine(ms, buffer, start, XYZ); renderAACuboidLine(ms, buffer, start, XYZ, noCull);
renderAACuboidLine(ms, buffer, start, Xyz); renderAACuboidLine(ms, buffer, start, Xyz, noCull);
start = XYz; start = XYz;
renderAACuboidLine(ms, buffer, start, xYz); renderAACuboidLine(ms, buffer, start, xYz, noCull);
renderAACuboidLine(ms, buffer, start, Xyz); renderAACuboidLine(ms, buffer, start, Xyz, noCull);
renderAACuboidLine(ms, buffer, start, XYZ); renderAACuboidLine(ms, buffer, start, XYZ, noCull);
start = xYZ; start = xYZ;
renderAACuboidLine(ms, buffer, start, XYZ); renderAACuboidLine(ms, buffer, start, XYZ, noCull);
renderAACuboidLine(ms, buffer, start, xyZ); renderAACuboidLine(ms, buffer, start, xyZ, noCull);
renderAACuboidLine(ms, buffer, start, xYz); renderAACuboidLine(ms, buffer, start, xYz, noCull);
renderFace(ms, buffer, Direction.NORTH, xYz, XYz, Xyz, xyz, inside); renderFace(ms, buffer, Direction.NORTH, xYz, XYz, Xyz, xyz, noCull);
renderFace(ms, buffer, Direction.SOUTH, XYZ, xYZ, xyZ, XyZ, inside); renderFace(ms, buffer, Direction.SOUTH, XYZ, xYZ, xyZ, XyZ, noCull);
renderFace(ms, buffer, Direction.EAST, XYz, XYZ, XyZ, Xyz, inside); renderFace(ms, buffer, Direction.EAST, XYz, XYZ, XyZ, Xyz, noCull);
renderFace(ms, buffer, Direction.WEST, xYZ, xYz, xyz, xyZ, inside); renderFace(ms, buffer, Direction.WEST, xYZ, xYz, xyz, xyZ, noCull);
renderFace(ms, buffer, Direction.UP, xYZ, XYZ, XYz, xYz, inside); renderFace(ms, buffer, Direction.UP, xYZ, XYZ, XYz, xYz, noCull);
renderFace(ms, buffer, Direction.DOWN, xyz, Xyz, XyZ, xyZ, inside); renderFace(ms, buffer, Direction.DOWN, xyz, Xyz, XyZ, xyZ, noCull);
} }
//TODO noCull has no effect
protected void renderFace(MatrixStack ms, IRenderTypeBuffer buffer, Direction direction, Vec3d p1, Vec3d p2, protected void renderFace(MatrixStack ms, IRenderTypeBuffer buffer, Direction direction, Vec3d p1, Vec3d p2,
Vec3d p3, Vec3d p4, boolean noCull) { Vec3d p3, Vec3d p4, boolean noCull) {
if (!params.faceTexture.isPresent()) if (!params.faceTexture.isPresent())
@ -90,4 +92,8 @@ public class AABBOutline extends Outline {
putQuadUV(ms, builder, p1, p2, p3, p4, 0, 0, maxU, maxV, Direction.UP); putQuadUV(ms, builder, p1, p2, p3, p4, 0, 0, maxU, maxV, Direction.UP);
} }
public void setBounds(AxisAlignedBB bb) {
this.bb = bb;
}
} }

View File

@ -33,7 +33,7 @@ public class BlockClusterOutline extends Outline {
for (MergeEntry edge : cluster.visibleEdges) { for (MergeEntry edge : cluster.visibleEdges) {
Vec3d start = new Vec3d(edge.pos); Vec3d start = new Vec3d(edge.pos);
Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, edge.axis); Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, edge.axis);
renderAACuboidLine(ms, buffer, start, new Vec3d(edge.pos.offset(direction))); renderAACuboidLine(ms, buffer, start, new Vec3d(edge.pos.offset(direction)), false);
} }
for (MergeEntry face : cluster.visibleFaces.keySet()) { for (MergeEntry face : cluster.visibleFaces.keySet()) {

View File

@ -25,7 +25,7 @@ public class ChasingAABBOutline extends AABBOutline {
@Override @Override
public void tick() { public void tick() {
prevBB = bb; prevBB = bb;
bb = interpolateBBs(bb, targetBB, .5f); setBounds(interpolateBBs(bb, targetBB, .5f));
} }
@Override @Override

View File

@ -0,0 +1,24 @@
package com.simibubi.create.foundation.utility.outliner;
import com.mojang.blaze3d.matrix.MatrixStack;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.util.math.Vec3d;
public class LineOutline extends Outline {
private Vec3d start = Vec3d.ZERO;
private Vec3d end = Vec3d.ZERO;
public LineOutline set(Vec3d start, Vec3d end) {
this.start = start;
this.end = end;
return this;
}
@Override
public void render(MatrixStack ms, IRenderTypeBuffer buffer) {
renderAACuboidLine(ms, buffer, start, end, params.disableCull);
}
}

View File

@ -17,6 +17,7 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public abstract class Outline { public abstract class Outline {
@ -30,8 +31,11 @@ public abstract class Outline {
public abstract void render(MatrixStack ms, IRenderTypeBuffer buffer); public abstract void render(MatrixStack ms, IRenderTypeBuffer buffer);
public void renderAACuboidLine(MatrixStack ms, IRenderTypeBuffer buffer, Vec3d start, Vec3d end) { //TODO noCull has no effect
IVertexBuilder builder = buffer.getBuffer(RenderType.getEntitySolid(AllSpecialTextures.BLANK.getLocation())); public void renderAACuboidLine(MatrixStack ms, IRenderTypeBuffer buffer, Vec3d start, Vec3d end, boolean noCull) {
ResourceLocation tex = AllSpecialTextures.BLANK.getLocation();
IVertexBuilder builder =
buffer.getBuffer(noCull ? RenderType.getCutoutNoCull(tex, true) : RenderType.getEntitySolid(tex));
Vec3d diff = end.subtract(start); Vec3d diff = end.subtract(start);
if (diff.x + diff.y + diff.z < 0) { if (diff.x + diff.y + diff.z < 0) {
@ -181,6 +185,10 @@ public abstract class Outline {
return this; return this;
} }
public OutlineParams clearTextures() {
return this.withFaceTextures(null, null);
}
public OutlineParams withFaceTextures(AllSpecialTextures texture, AllSpecialTextures highlightTexture) { public OutlineParams withFaceTextures(AllSpecialTextures texture, AllSpecialTextures highlightTexture) {
this.faceTexture = Optional.ofNullable(texture); this.faceTexture = Optional.ofNullable(texture);
this.hightlightedFaceTexture = Optional.ofNullable(highlightTexture); this.hightlightedFaceTexture = Optional.ofNullable(highlightTexture);