Ported Outline utility to 1.15

- Outliner can now be used in 1.15
- Ported Chassis range display to use new Outlines
This commit is contained in:
simibubi 2020-05-15 17:13:38 +02:00
parent afd6ec17e0
commit 071482bb26
16 changed files with 525 additions and 370 deletions

View file

@ -1,5 +1,7 @@
package com.simibubi.create; package com.simibubi.create;
import static com.simibubi.create.foundation.utility.data.BlockStateGen.oxidizedBlockstate;
import static com.simibubi.create.foundation.utility.data.ModelGen.oxidizedItemModel;
import static com.simibubi.create.modules.Sections.SCHEMATICS; import static com.simibubi.create.modules.Sections.SCHEMATICS;
import com.simibubi.create.foundation.registrate.CreateRegistrate; import com.simibubi.create.foundation.registrate.CreateRegistrate;
@ -21,8 +23,6 @@ import com.tterrag.registrate.builders.ItemBuilder;
import com.tterrag.registrate.util.DataIngredient; import com.tterrag.registrate.util.DataIngredient;
import com.tterrag.registrate.util.entry.BlockEntry; import com.tterrag.registrate.util.entry.BlockEntry;
import com.tterrag.registrate.util.nullness.NonNullFunction; import com.tterrag.registrate.util.nullness.NonNullFunction;
import com.tterrag.registrate.util.nullness.NonNullSupplier;
import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
@ -33,9 +33,7 @@ import net.minecraft.tags.BlockTags;
import net.minecraft.tags.ItemTags; import net.minecraft.tags.ItemTags;
import net.minecraft.tags.Tag; import net.minecraft.tags.Tag;
import net.minecraft.tags.TagCollection; import net.minecraft.tags.TagCollection;
import net.minecraft.util.IItemProvider;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.generators.ConfiguredModel;
import net.minecraftforge.common.ToolType; import net.minecraftforge.common.ToolType;
public class AllBlocksNew { public class AllBlocksNew {
@ -124,9 +122,12 @@ public class AllBlocksNew {
.build() .build()
.register(); .register();
static { REGISTRATE.startSection(Sections.MATERIALS); } static {
REGISTRATE.startSection(Sections.MATERIALS);
}
public static final BlockEntry<OxidizingBlock> COPPER_ORE = REGISTRATE.block("copper_ore", p -> new OxidizingBlock(p, 1)) public static final BlockEntry<OxidizingBlock> COPPER_ORE =
REGISTRATE.block("copper_ore", p -> new OxidizingBlock(p, 1))
.initialProperties(() -> Blocks.IRON_ORE) .initialProperties(() -> Blocks.IRON_ORE)
.transform(oxidizedBlockstate()) .transform(oxidizedBlockstate())
.transform(tagBlockAndItem("ores/copper")) .transform(tagBlockAndItem("ores/copper"))
@ -135,12 +136,14 @@ public class AllBlocksNew {
public static final BlockEntry<Block> ZINC_ORE = REGISTRATE.block("zinc_ore", Block::new) public static final BlockEntry<Block> ZINC_ORE = REGISTRATE.block("zinc_ore", Block::new)
.initialProperties(() -> Blocks.GOLD_BLOCK) .initialProperties(() -> Blocks.GOLD_BLOCK)
.properties(p -> p.harvestLevel(2).harvestTool(ToolType.PICKAXE)) .properties(p -> p.harvestLevel(2)
.harvestTool(ToolType.PICKAXE))
.transform(tagBlockAndItem("ores/zinc")) .transform(tagBlockAndItem("ores/zinc"))
.build() .build()
.register(); .register();
public static final BlockEntry<OxidizingBlock> COPPER_BLOCK = REGISTRATE.block("copper_block", p -> new OxidizingBlock(p, 1 / 32f)) public static final BlockEntry<OxidizingBlock> COPPER_BLOCK =
REGISTRATE.block("copper_block", p -> new OxidizingBlock(p, 1 / 32f))
.initialProperties(() -> Blocks.IRON_BLOCK) .initialProperties(() -> Blocks.IRON_BLOCK)
.transform(tagBlockAndItem("storage_blocks/copper")) .transform(tagBlockAndItem("storage_blocks/copper"))
.transform(oxidizedItemModel()) .transform(oxidizedItemModel())
@ -148,9 +151,11 @@ public class AllBlocksNew {
.transform(oxidizedBlockstate()) .transform(oxidizedBlockstate())
.register(); .register();
public static final BlockEntry<OxidizingBlock> COPPER_SHINGLES = REGISTRATE.block("copper_shingles", p -> new OxidizingBlock(p, 1 / 32f)) public static final BlockEntry<OxidizingBlock> COPPER_SHINGLES =
REGISTRATE.block("copper_shingles", p -> new OxidizingBlock(p, 1 / 32f))
.initialProperties(() -> Blocks.IRON_BLOCK) .initialProperties(() -> Blocks.IRON_BLOCK)
.item().transform(oxidizedItemModel()) .item()
.transform(oxidizedItemModel())
.recipe((ctx, prov) -> prov.square(DataIngredient.tag(forgeItemTag("plates/copper")), ctx, true)) .recipe((ctx, prov) -> prov.square(DataIngredient.tag(forgeItemTag("plates/copper")), ctx, true))
.transform(oxidizedBlockstate()) .transform(oxidizedBlockstate())
.register(); .register();
@ -169,25 +174,10 @@ public class AllBlocksNew {
.recipe((ctx, prov) -> prov.square(DataIngredient.tag(forgeItemTag("ingots/brass")), ctx, false)) .recipe((ctx, prov) -> prov.square(DataIngredient.tag(forgeItemTag("ingots/brass")), ctx, false))
.register(); .register();
private static String getOxidizedModel(String name, int level) { // Utility
return "block/oxidized/" + name + "_" + level;
}
private static <P> NonNullUnaryOperator<BlockBuilder<OxidizingBlock, P>> oxidizedBlockstate() { private static <T extends Block, P> NonNullFunction<BlockBuilder<T, P>, ItemBuilder<BlockItem, BlockBuilder<T, P>>> tagBlockAndItem(
return b -> b.blockstate((ctx, prov) -> prov.getVariantBuilder(ctx.getEntry()) String tagName) {
.forAllStates(state -> {
String name = getOxidizedModel(ctx.getName(), state.get(OxidizingBlock.OXIDIZATION));
return ConfiguredModel.builder()
.modelFile(prov.models().cubeAll(name, prov.modLoc(name)))
.build();
}));
}
private static <P> NonNullFunction<ItemBuilder<BlockItem, P>, P> oxidizedItemModel() {
return b -> b.model((ctx, prov) -> prov.withExistingParent(ctx.getName(), prov.modLoc(getOxidizedModel(ctx.getName(), 0)))).build();
}
private static <T extends Block, P> NonNullFunction<BlockBuilder<T, P>, ItemBuilder<BlockItem, BlockBuilder<T, P>>> tagBlockAndItem(String tagName) {
return b -> b.tag(forgeBlockTag(tagName)) return b -> b.tag(forgeBlockTag(tagName))
.item() .item()
.tag(forgeItemTag(tagName)); .tag(forgeItemTag(tagName));

View file

@ -26,4 +26,8 @@ public enum AllSpecialTextures {
Minecraft.getInstance().getTextureManager().bindTexture(location); Minecraft.getInstance().getTextureManager().bindTexture(location);
} }
public ResourceLocation getLocation() {
return location;
}
} }

View file

@ -12,7 +12,6 @@ import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.modules.contraptions.KineticDebugger; import com.simibubi.create.modules.contraptions.KineticDebugger;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.contraptions.ChassisRangeDisplay;
import com.simibubi.create.modules.contraptions.components.turntable.TurntableHandler; import com.simibubi.create.modules.contraptions.components.turntable.TurntableHandler;
import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorHandler; import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorHandler;
import com.simibubi.create.modules.curiosities.zapper.terrainzapper.TerrainZapperRenderHandler; import com.simibubi.create.modules.curiosities.zapper.terrainzapper.TerrainZapperRenderHandler;
@ -78,10 +77,13 @@ public class ClientEvents {
ms.push(); ms.push();
ms.translate(-view.getX(), -view.getY(), -view.getZ()); ms.translate(-view.getX(), -view.getY(), -view.getZ());
IRenderTypeBuffer.Impl buffer = Minecraft.getInstance().getBufferBuilders().getEntityVertexConsumers(); IRenderTypeBuffer.Impl buffer = Minecraft.getInstance()
.getBufferBuilders()
.getEntityVertexConsumers();
CreateClient.schematicHandler.render(ms, buffer, 0xF000F0, OverlayTexture.DEFAULT_UV); CreateClient.schematicHandler.render(ms, buffer, 0xF000F0, OverlayTexture.DEFAULT_UV);
CreateClient.outliner.renderOutlines(ms, buffer);
KineticDebugger.renderSourceOutline(ms, buffer); KineticDebugger.renderSourceOutline(ms, buffer);
ChassisRangeDisplay.renderOutlines(event.getPartialTicks(), ms, buffer);
TerrainZapperRenderHandler.render(ms, buffer); TerrainZapperRenderHandler.render(ms, buffer);
ms.pop(); ms.pop();
@ -94,8 +96,9 @@ public class ClientEvents {
if (event.getType() != ElementType.HOTBAR) if (event.getType() != ElementType.HOTBAR)
return; return;
onRenderHotbar(new MatrixStack(), Minecraft.getInstance().getBufferBuilders().getEntityVertexConsumers(), onRenderHotbar(new MatrixStack(), Minecraft.getInstance()
0xF000F0, OverlayTexture.DEFAULT_UV); .getBufferBuilders()
.getEntityVertexConsumers(), 0xF000F0, OverlayTexture.DEFAULT_UV);
} }
public static void onRenderHotbar(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { public static void onRenderHotbar(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
@ -121,8 +124,7 @@ public class ClientEvents {
double delta = event.getScrollDelta(); double delta = event.getScrollDelta();
boolean cancelled = CreateClient.schematicHandler.mouseScrolled(delta) boolean cancelled = CreateClient.schematicHandler.mouseScrolled(delta)
|| CreateClient.schematicAndQuillHandler.mouseScrolled(delta) || CreateClient.schematicAndQuillHandler.mouseScrolled(delta) || FilteringHandler.onScroll(delta)
|| FilteringHandler.onScroll(delta)
|| ScrollValueHandler.onScroll(delta); || ScrollValueHandler.onScroll(delta);
event.setCanceled(cancelled); event.setCanceled(cancelled);
} }
@ -147,7 +149,8 @@ public class ClientEvents {
return; return;
ItemStack stack = event.getItemStack(); ItemStack stack = event.getItemStack();
String translationKey = stack.getItem().getTranslationKey(stack); String translationKey = stack.getItem()
.getTranslationKey(stack);
if (!translationKey.startsWith(itemPrefix) && !translationKey.startsWith(blockPrefix)) if (!translationKey.startsWith(itemPrefix) && !translationKey.startsWith(blockPrefix))
return; return;
@ -155,7 +158,8 @@ public class ClientEvents {
List<ITextComponent> itemTooltip = event.getToolTip(); List<ITextComponent> itemTooltip = event.getToolTip();
List<ITextComponent> toolTip = new ArrayList<>(); List<ITextComponent> toolTip = new ArrayList<>();
toolTip.add(itemTooltip.remove(0)); toolTip.add(itemTooltip.remove(0));
TooltipHelper.getTooltip(stack).addInformation(toolTip); TooltipHelper.getTooltip(stack)
.addInformation(toolTip);
itemTooltip.addAll(0, toolTip); itemTooltip.addAll(0, toolTip);
} }

View file

@ -9,6 +9,7 @@ import com.simibubi.create.foundation.block.render.CustomBlockModels;
import com.simibubi.create.foundation.block.render.SpriteShifter; import com.simibubi.create.foundation.block.render.SpriteShifter;
import com.simibubi.create.foundation.item.IHaveCustomItemModel; import com.simibubi.create.foundation.item.IHaveCustomItemModel;
import com.simibubi.create.foundation.utility.SuperByteBufferCache; import com.simibubi.create.foundation.utility.SuperByteBufferCache;
import com.simibubi.create.foundation.utility.outliner.Outliner;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.components.contraptions.ChassisRangeDisplay; import com.simibubi.create.modules.contraptions.components.contraptions.ChassisRangeDisplay;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionRenderer; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionRenderer;
@ -41,6 +42,7 @@ public class CreateClient {
public static SchematicHandler schematicHandler; public static SchematicHandler schematicHandler;
public static SchematicAndQuillHandler schematicAndQuillHandler; public static SchematicAndQuillHandler schematicAndQuillHandler;
public static SuperByteBufferCache bufferCache; public static SuperByteBufferCache bufferCache;
public static Outliner outliner;
private static CustomBlockModels customBlockModels; private static CustomBlockModels customBlockModels;
public static void addListeners(IEventBus modEventBus) { public static void addListeners(IEventBus modEventBus) {
@ -57,6 +59,7 @@ public class CreateClient {
schematicSender = new ClientSchematicLoader(); schematicSender = new ClientSchematicLoader();
schematicHandler = new SchematicHandler(); schematicHandler = new SchematicHandler();
schematicAndQuillHandler = new SchematicAndQuillHandler(); schematicAndQuillHandler = new SchematicAndQuillHandler();
outliner = new Outliner();
bufferCache = new SuperByteBufferCache(); bufferCache = new SuperByteBufferCache();
bufferCache.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE); bufferCache.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE);
@ -79,6 +82,7 @@ public class CreateClient {
schematicSender.tick(); schematicSender.tick();
schematicAndQuillHandler.tick(); schematicAndQuillHandler.tick();
schematicHandler.tick(); schematicHandler.tick();
outliner.tickOutlines();
ChassisRangeDisplay.clientTick(); ChassisRangeDisplay.clientTick();
} }

View file

@ -3,10 +3,13 @@ package com.simibubi.create.foundation.utility.data;
import java.util.function.Function; import java.util.function.Function;
import com.simibubi.create.foundation.world.OxidizingBlock;
import com.simibubi.create.modules.palettes.PavedBlock; import com.simibubi.create.modules.palettes.PavedBlock;
import com.tterrag.registrate.builders.BlockBuilder;
import com.tterrag.registrate.providers.DataGenContext; import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider; import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
import com.tterrag.registrate.util.nullness.NonNullBiConsumer; import com.tterrag.registrate.util.nullness.NonNullBiConsumer;
import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -56,4 +59,14 @@ public class BlockStateGen {
.build()); .build());
} }
public static <P> NonNullUnaryOperator<BlockBuilder<OxidizingBlock, P>> oxidizedBlockstate() {
return b -> b.blockstate((ctx, prov) -> prov.getVariantBuilder(ctx.getEntry())
.forAllStates(state -> {
String name = ModelGen.getOxidizedModel(ctx.getName(), state.get(OxidizingBlock.OXIDIZATION));
return ConfiguredModel.builder()
.modelFile(prov.models().cubeAll(name, prov.modLoc(name)))
.build();
}));
}
} }

View file

@ -1,9 +1,12 @@
package com.simibubi.create.foundation.utility.data; package com.simibubi.create.foundation.utility.data;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.tterrag.registrate.builders.ItemBuilder;
import com.tterrag.registrate.providers.DataGenContext; import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.util.nullness.NonNullFunction;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.generators.BlockStateProvider; import net.minecraftforge.client.model.generators.BlockStateProvider;
import net.minecraftforge.client.model.generators.ModelFile; import net.minecraftforge.client.model.generators.ModelFile;
@ -26,4 +29,12 @@ public class ModelGen {
.texture("overlay", overlay); .texture("overlay", overlay);
} }
public static <P> NonNullFunction<ItemBuilder<BlockItem, P>, P> oxidizedItemModel() {
return b -> b.model((ctx, prov) -> prov.withExistingParent(ctx.getName(), prov.modLoc(ModelGen.getOxidizedModel(ctx.getName(), 0)))).build();
}
public static String getOxidizedModel(String name, int level) {
return "block/oxidized/" + name + "_" + level;
}
} }

View file

@ -1,13 +1,16 @@
package com.simibubi.create.foundation.utility.outliner; package com.simibubi.create.foundation.utility.outliner;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder; import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
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.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -24,10 +27,10 @@ public class AABBOutline extends Outline {
} }
@Override @Override
public void render(BufferBuilder buffer) { public void render(MatrixStack ms, IRenderTypeBuffer buffer) {
Vec3d color = ColorHelper.getRGB(0xFFFFFF); Vec3d color = ColorHelper.getRGB(0xFFFFFF);
float alpha = 1f; float alpha = 1f;
renderBB(bb, buffer, color, alpha, !disableCull); renderBB(ms, buffer, bb, color, alpha, !disableCull);
} }
public void setTextures(AllSpecialTextures faceTexture, AllSpecialTextures highlightTexture) { public void setTextures(AllSpecialTextures faceTexture, AllSpecialTextures highlightTexture) {
@ -39,8 +42,10 @@ public class AABBOutline extends Outline {
this.highlightedFace = face; this.highlightedFace = face;
} }
public void renderBB(AxisAlignedBB bb, IVertexBuilder builder, Vec3d color, float alpha, boolean doCulling) { public void renderBB(MatrixStack ms, IRenderTypeBuffer buffer, AxisAlignedBB bb, Vec3d color, float alpha,
Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); boolean doCulling) {
Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo()
.getProjectedView();
boolean inside = bb.contains(projectedView); boolean inside = bb.contains(projectedView);
bb = bb.grow(inside ? -1 / 128d : 1 / 128d); bb = bb.grow(inside ? -1 / 128d : 1 / 128d);
@ -53,50 +58,54 @@ public class AABBOutline extends Outline {
Vec3d xYZ = new Vec3d(bb.minX, bb.maxY, bb.maxZ); Vec3d xYZ = new Vec3d(bb.minX, bb.maxY, bb.maxZ);
Vec3d XYZ = new Vec3d(bb.maxX, bb.maxY, bb.maxZ); Vec3d XYZ = new Vec3d(bb.maxX, bb.maxY, bb.maxZ);
renderFace(Direction.NORTH, xYz, XYz, Xyz, xyz, builder);
renderFace(Direction.SOUTH, XYZ, xYZ, xyZ, XyZ, builder);
renderFace(Direction.EAST, XYz, XYZ, XyZ, Xyz, builder);
renderFace(Direction.WEST, xYZ, xYz, xyz, xyZ, builder);
renderFace(Direction.UP, xYZ, XYZ, XYz, xYz, builder);
renderFace(Direction.DOWN, xyz, Xyz, XyZ, xyZ, builder);
Vec3d start = xyz; Vec3d start = xyz;
AllSpecialTextures.BLANK.bind(); renderAACuboidLine(ms, buffer, start, Xyz);
renderAACuboidLine(start, Xyz, color, alpha, builder); renderAACuboidLine(ms, buffer, start, xYz);
renderAACuboidLine(start, xYz, color, alpha, builder); renderAACuboidLine(ms, buffer, start, xyZ);
renderAACuboidLine(start, xyZ, color, alpha, builder);
start = XyZ; start = XyZ;
renderAACuboidLine(start, xyZ, color, alpha, builder); renderAACuboidLine(ms, buffer, start, xyZ);
renderAACuboidLine(start, XYZ, color, alpha, builder); renderAACuboidLine(ms, buffer, start, XYZ);
renderAACuboidLine(start, Xyz, color, alpha, builder); renderAACuboidLine(ms, buffer, start, Xyz);
start = XYz; start = XYz;
renderAACuboidLine(start, xYz, color, alpha, builder); renderAACuboidLine(ms, buffer, start, xYz);
renderAACuboidLine(start, Xyz, color, alpha, builder); renderAACuboidLine(ms, buffer, start, Xyz);
renderAACuboidLine(start, XYZ, color, alpha, builder); renderAACuboidLine(ms, buffer, start, XYZ);
start = xYZ; start = xYZ;
renderAACuboidLine(start, XYZ, color, alpha, builder); renderAACuboidLine(ms, buffer, start, XYZ);
renderAACuboidLine(start, xyZ, color, alpha, builder); renderAACuboidLine(ms, buffer, start, xyZ);
renderAACuboidLine(start, xYz, color, alpha, builder); renderAACuboidLine(ms, buffer, start, xYz);
renderFace(ms, buffer, Direction.NORTH, xYz, XYz, Xyz, xyz, inside);
renderFace(ms, buffer, Direction.SOUTH, XYZ, xYZ, xyZ, XyZ, inside);
renderFace(ms, buffer, Direction.EAST, XYz, XYZ, XyZ, Xyz, inside);
renderFace(ms, buffer, Direction.WEST, xYZ, xYz, xyz, xyZ, inside);
renderFace(ms, buffer, Direction.UP, xYZ, XYZ, XYz, xYz, inside);
renderFace(ms, buffer, Direction.DOWN, xyz, Xyz, XyZ, xyZ, inside);
} }
protected void renderFace(Direction direction, Vec3d p1, Vec3d p2, Vec3d p3, Vec3d p4, IVertexBuilder builder) { protected void renderFace(MatrixStack ms, IRenderTypeBuffer buffer, Direction direction, Vec3d p1, Vec3d p2,
Vec3d p3, Vec3d p4, boolean noCull) {
ResourceLocation faceTexture = this.faceTexture.getLocation();
if (direction == highlightedFace && highlightedTexture != null) if (direction == highlightedFace && highlightedTexture != null)
highlightedTexture.bind(); faceTexture = highlightedTexture.getLocation();
else if (faceTexture != null) else if (faceTexture == null)
faceTexture.bind();
else
return; return;
RenderType translucentType =
noCull ? RenderType.getEntityTranslucent(faceTexture) : RenderType.getEntityTranslucentCull(faceTexture);
IVertexBuilder builder = buffer.getBuffer(translucentType);
Axis axis = direction.getAxis();
Vec3d uDiff = p2.subtract(p1); Vec3d uDiff = p2.subtract(p1);
Vec3d vDiff = p4.subtract(p1); Vec3d vDiff = p4.subtract(p1);
Axis axis = direction.getAxis();
float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x); float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x);
float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y); float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y);
putQuadUV(p1, p2, p3, p4, 0, 0, maxU, maxV, new Vec3d(1, 1, 1), 1, builder); putQuadUV(ms, builder, p1, p2, p3, p4, 0, 0, maxU, maxV);
} }
} }

View file

@ -3,12 +3,16 @@ package com.simibubi.create.foundation.utility.outliner;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
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.Direction.AxisDirection; import net.minecraft.util.Direction.AxisDirection;
@ -18,18 +22,19 @@ import net.minecraft.util.math.Vec3d;
public class BlockClusterOutline extends Outline { public class BlockClusterOutline extends Outline {
private Cluster cluster; private Cluster cluster;
private float alpha;
public BlockClusterOutline(Iterable<BlockPos> selection) { public BlockClusterOutline(Iterable<BlockPos> selection) {
cluster = new Cluster(); cluster = new Cluster();
selection.forEach(cluster::include); selection.forEach(cluster::include);
alpha = .5f;
} }
@Override @Override
public void render(BufferBuilder buffer) { public void render(MatrixStack ms, IRenderTypeBuffer buffer) {
Vec3d color = ColorHelper.getRGB(0xDDDDDD); for (MergeEntry edge : cluster.visibleEdges) {
AllSpecialTextures.SELECTION.bind(); Vec3d start = new Vec3d(edge.pos);
Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, edge.axis);
renderAACuboidLine(ms, buffer, start, new Vec3d(edge.pos.offset(direction)));
}
for (MergeEntry face : cluster.visibleFaces.keySet()) { for (MergeEntry face : cluster.visibleFaces.keySet()) {
AxisDirection axisDirection = cluster.visibleFaces.get(face); AxisDirection axisDirection = cluster.visibleFaces.get(face);
@ -37,22 +42,39 @@ public class BlockClusterOutline extends Outline {
BlockPos pos = face.pos; BlockPos pos = face.pos;
if (axisDirection == AxisDirection.POSITIVE) if (axisDirection == AxisDirection.POSITIVE)
pos = pos.offset(direction.getOpposite()); pos = pos.offset(direction.getOpposite());
renderFace(pos, direction, color, alpha * .25f, 1 / 64d, buffer); renderBlockFace(ms, buffer, pos, direction);
}
} }
AllSpecialTextures.BLANK.bind(); protected void renderBlockFace(MatrixStack ms, IRenderTypeBuffer buffer, BlockPos pos, Direction face) {
Optional<AllSpecialTextures> faceTexture = params.faceTexture;
if (!faceTexture.isPresent())
return;
for (MergeEntry edge : cluster.visibleEdges) { RenderType translucentType = RenderType.getEntityTranslucent(faceTexture.get()
lineWidth = 1 / 16f * alpha; .getLocation());
Vec3d start = new Vec3d(edge.pos); IVertexBuilder builder = buffer.getBuffer(translucentType);
Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, edge.axis);
renderAACuboidLine(start, new Vec3d(edge.pos.offset(direction)), color, 1, buffer);
}
} Vec3d center = VecHelper.getCenterOf(pos);
Vec3d offset = new Vec3d(face.getDirectionVec());
Vec3d plane = VecHelper.planeByNormal(offset);
Axis axis = face.getAxis();
public void setAlpha(float alpha) { offset = offset.scale(1 / 2f + 1 / 64d);
this.alpha = alpha; plane = plane.scale(1 / 2f)
.add(offset);
int deg = face.getAxisDirection()
.getOffset() * 90;
Vec3d a1 = plane.add(center);
plane = VecHelper.rotate(plane, deg, axis);
Vec3d a2 = plane.add(center);
plane = VecHelper.rotate(plane, deg, axis);
Vec3d a3 = plane.add(center);
plane = VecHelper.rotate(plane, deg, axis);
Vec3d a4 = plane.add(center);
putQuad(ms, builder, a1, a2, a3, a4);
} }
private static class Cluster { private static class Cluster {

View file

@ -1,9 +1,10 @@
package com.simibubi.create.foundation.utility.outliner; package com.simibubi.create.foundation.utility.outliner;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
@ -23,17 +24,18 @@ public class ChasingAABBOutline extends AABBOutline {
targetBB = target; targetBB = target;
} }
@Override
public void tick() { public void tick() {
prevBB = bb; prevBB = bb;
bb = interpolateBBs(bb, targetBB, .5f); bb = interpolateBBs(bb, targetBB, .5f);
} }
@Override @Override
public void render(BufferBuilder buffer) { public void render(MatrixStack ms, IRenderTypeBuffer buffer) {
Vec3d color = ColorHelper.getRGB(0xFFFFFF); Vec3d color = ColorHelper.getRGB(0xFFFFFF);
float alpha = 1f; float alpha = 1f;
renderBB(interpolateBBs(prevBB, bb, Minecraft.getInstance().getRenderPartialTicks()), buffer, color, alpha, renderBB(ms, buffer, interpolateBBs(prevBB, bb, Minecraft.getInstance()
true); .getRenderPartialTicks()), color, alpha, true);
} }
private static AxisAlignedBB interpolateBBs(AxisAlignedBB current, AxisAlignedBB target, float pt) { private static AxisAlignedBB interpolateBBs(AxisAlignedBB current, AxisAlignedBB target, float pt) {

View file

@ -1,21 +1,34 @@
package com.simibubi.create.foundation.utility.outliner; package com.simibubi.create.foundation.utility.outliner;
import java.util.Optional;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.matrix.MatrixStack.Entry;
import com.mojang.blaze3d.vertex.IVertexBuilder; import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
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.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public abstract class Outline { public abstract class Outline {
protected float lineWidth = 1 / 32f; protected OutlineParams params;
public abstract void render(BufferBuilder buffer); public Outline() {
params = new OutlineParams();
}
public abstract void render(MatrixStack ms, IRenderTypeBuffer buffer);
public void renderAACuboidLine(MatrixStack ms, IRenderTypeBuffer buffer, Vec3d start, Vec3d end) {
IVertexBuilder builder = buffer.getBuffer(RenderType.getEntitySolid(AllSpecialTextures.BLANK.getLocation()));
public void renderAACuboidLine(Vec3d start, Vec3d end, Vec3d rgb, float alpha, IVertexBuilder builder) {
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) {
Vec3d temp = start; Vec3d temp = start;
@ -24,13 +37,17 @@ public abstract class Outline {
diff = diff.scale(-1); diff = diff.scale(-1);
} }
Vec3d extension = diff.normalize().scale(lineWidth / 2); float lineWidth = params.getLineWidth();
Vec3d extension = diff.normalize()
.scale(lineWidth / 2);
Vec3d plane = VecHelper.planeByNormal(diff); Vec3d plane = VecHelper.planeByNormal(diff);
Axis axis = Direction.getFacingFromVector(diff.x, diff.y, diff.z).getAxis(); Direction face = Direction.getFacingFromVector(diff.x, diff.y, diff.z);
Axis axis = face.getAxis();
start = start.subtract(extension); start = start.subtract(extension);
end = end.add(extension); end = end.add(extension);
plane = plane.scale(lineWidth / 2); plane = plane.scale(lineWidth / 2);
Vec3d a1 = plane.add(start); Vec3d a1 = plane.add(start);
Vec3d b1 = plane.add(end); Vec3d b1 = plane.add(end);
plane = VecHelper.rotate(plane, -90, axis); plane = VecHelper.rotate(plane, -90, axis);
@ -43,55 +60,92 @@ public abstract class Outline {
Vec3d a4 = plane.add(start); Vec3d a4 = plane.add(start);
Vec3d b4 = plane.add(end); Vec3d b4 = plane.add(end);
putQuad(b4, b3, b2, b1, rgb, alpha, builder); putQuad(ms, builder, b4, b3, b2, b1);
putQuad(a1, a2, a3, a4, rgb, alpha, builder); putQuad(ms, builder, a1, a2, a3, a4);
putQuad(ms, builder, a1, b1, b2, a2);
putQuad(a1, b1, b2, a2, rgb, alpha, builder); putQuad(ms, builder, a2, b2, b3, a3);
putQuad(a2, b2, b3, a3, rgb, alpha, builder); putQuad(ms, builder, a3, b3, b4, a4);
putQuad(a3, b3, b4, a4, rgb, alpha, builder); putQuad(ms, builder, a4, b4, b1, a1);
putQuad(a4, b4, b1, a1, rgb, alpha, builder);
} }
protected void renderFace(BlockPos pos, Direction face, Vec3d rgb, float alpha, double scaleOffset, public void putQuad(MatrixStack ms, IVertexBuilder builder, Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4) {
IVertexBuilder builder) { putQuadUV(ms, builder, v1, v2, v3, v4, 0, 0, 1, 1);
Vec3d center = VecHelper.getCenterOf(pos);
Vec3d offset = new Vec3d(face.getDirectionVec());
Vec3d plane = VecHelper.planeByNormal(offset);
Axis axis = face.getAxis();
offset = offset.scale(1 / 2f + scaleOffset);
plane = plane.scale(1 / 2f).add(offset);
int deg = face.getAxisDirection().getOffset() * 90;
Vec3d a1 = plane.add(center);
plane = VecHelper.rotate(plane, deg, axis);
Vec3d a2 = plane.add(center);
plane = VecHelper.rotate(plane, deg, axis);
Vec3d a3 = plane.add(center);
plane = VecHelper.rotate(plane, deg, axis);
Vec3d a4 = plane.add(center);
putQuad(a1, a2, a3, a4, rgb, alpha, builder);
} }
public void putQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, Vec3d rgb, float alpha, IVertexBuilder builder) { public void putQuadUV(MatrixStack ms, IVertexBuilder builder, Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, float minU,
putQuadUV(v1, v2, v3, v4, 0, 0, 1, 1, rgb, alpha, builder); 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);
} }
public void putQuadUV(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, float minU, float minV, float maxU, float maxV, protected void putVertex(MatrixStack ms, IVertexBuilder builder, Vec3d pos, float u, float v) {
Vec3d rgb, float alpha, IVertexBuilder builder) {
putVertex(v1, rgb, minU, minV, alpha, builder);
putVertex(v2, rgb, maxU, minV, alpha, builder);
putVertex(v3, rgb, maxU, maxV, alpha, builder);
putVertex(v4, rgb, minU, maxV, alpha, builder);
}
protected void putVertex(Vec3d pos, Vec3d rgb, float u, float v, float alpha, IVertexBuilder builder) {
int i = 15 << 20 | 15 << 4; int i = 15 << 20 | 15 << 4;
int j = i >> 16 & '\uffff'; int j = i >> 16 & '\uffff';
int k = i & '\uffff'; int k = i & '\uffff';
builder.vertex(pos.x, pos.y, pos.z).texture(u, v).color((float) rgb.x, (float) rgb.y, (float) rgb.z, alpha) Entry peek = ms.peek();
.light(j, k).endVertex(); Vec3d rgb = params.rgb;
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)
.endVertex();
}
public void tick() {}
public OutlineParams getParams() {
return params;
}
public static class OutlineParams {
Optional<AllSpecialTextures> faceTexture;
Optional<AllSpecialTextures> hightlightedFaceTexture;
boolean fadeLineWidth;
float alpha;
private float lineWidth;
int lightMapU, lightMapV;
Vec3d rgb;
public OutlineParams() {
faceTexture = hightlightedFaceTexture = Optional.empty();
alpha = 1;
lineWidth = 1 / 32f;
fadeLineWidth = true;
rgb = ColorHelper.getRGB(0xFFFFFF);
int i = 15 << 20 | 15 << 4;
lightMapU = i >> 16 & '\uffff';
lightMapV = i & '\uffff';
}
// builder
public OutlineParams colored(int color) {
rgb = ColorHelper.getRGB(color);
return this;
}
public OutlineParams lineWidth(float width) {
this.lineWidth = width;
return this;
}
public OutlineParams withFaceTexture(AllSpecialTextures texture) {
this.faceTexture = Optional.of(texture);
return this;
}
// util
float getLineWidth() {
return fadeLineWidth ? alpha * lineWidth : lineWidth;
}
} }
} }

View file

@ -1,55 +0,0 @@
package com.simibubi.create.foundation.utility.outliner;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
import net.minecraft.client.particle.IParticleRenderType;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
public class OutlineParticle<O extends Outline> extends Particle {
protected O outline;
protected OutlineParticle(O outline, World worldIn, double xCoordIn, double yCoordIn, double zCoordIn) {
super(worldIn, xCoordIn, yCoordIn, zCoordIn);
this.outline = outline;
this.maxAge = 1024;
}
public static <O extends Outline> OutlineParticle<O> create(O outline) {
Minecraft mc = Minecraft.getInstance();
ClientPlayerEntity player = mc.player;
OutlineParticle<O> effect =
new OutlineParticle<>(outline, mc.world, player.getX(), player.getY(), player.getZ());
mc.particles.addEffect(effect);
return effect;
}
public void remove() {
isExpired = true;
}
@Override
public void buildGeometry(IVertexBuilder builder, ActiveRenderInfo renderInfo, float p_225606_3_) {
Vec3d view = renderInfo.getProjectedView();
// GlStateManager.translated(-view.x, -view.y, -view.z);
// TODO
// GlStateManager.enableBlend();
// getOutline().render(buffer);
// GlStateManager.disableBlend();
}
@Override
public IParticleRenderType getRenderType() {
return IParticleRenderType.CUSTOM;
}
public O getOutline() {
return outline;
}
}

View file

@ -0,0 +1,142 @@
package com.simibubi.create.foundation.utility.outliner;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.utility.outliner.Outline.OutlineParams;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
public class Outliner {
Map<Object, OutlineEntry> outlines;
// Facade
public OutlineParams showAABB(Object slot, AxisAlignedBB bb, ExpireType type) {
createAABBOutlineIfMissing(slot, bb, type);
ChasingAABBOutline outline = getAndRefreshAABB(slot);
outline.prevBB = outline.targetBB = bb;
return outline.getParams();
}
public OutlineParams chaseAABB(Object slot, AxisAlignedBB bb, ExpireType type) {
createAABBOutlineIfMissing(slot, bb, type);
ChasingAABBOutline outline = getAndRefreshAABB(slot);
outline.targetBB = bb;
return outline.getParams();
}
public OutlineParams showCluster(Object slot, Iterable<BlockPos> selection, ExpireType type) {
BlockClusterOutline outline = new BlockClusterOutline(selection);
OutlineEntry entry = new OutlineEntry(outline, type);
outlines.put(slot, entry);
return entry.getOutline()
.getParams();
}
public void keepCluster(Object slot) {
if (outlines.containsKey(slot))
outlines.get(slot).ticksTillRemoval = 1;
}
public void remove(Object slot) {
outlines.remove(slot);
}
// Utility
private void createAABBOutlineIfMissing(Object slot, AxisAlignedBB bb, ExpireType type) {
if (!outlines.containsKey(slot)) {
ChasingAABBOutline outline = new ChasingAABBOutline(bb);
outlines.put(slot, new OutlineEntry(outline, type));
}
}
private ChasingAABBOutline getAndRefreshAABB(Object slot) {
OutlineEntry entry = outlines.get(slot);
entry.ticksTillRemoval = 1;
return (ChasingAABBOutline) entry.getOutline();
}
// Maintenance
public Outliner() {
outlines = new HashMap<>();
}
public void tickOutlines() {
Set<Object> toClear = new HashSet<>();
outlines.forEach((key, entry) -> {
entry.ticksTillRemoval--;
entry.getOutline()
.tick();
if (entry.isAlive())
return;
toClear.add(key);
});
toClear.forEach(outlines::remove);
}
public void renderOutlines(MatrixStack ms, IRenderTypeBuffer buffer) {
outlines.forEach((key, entry) -> {
Outline outline = entry.getOutline();
outline.params.alpha = 1;
if (entry.type != ExpireType.IMMEDIATE && entry.ticksTillRemoval < 0) {
int prevTicks = entry.ticksTillRemoval + 1;
float lastAlpha = prevTicks >= 0 ? 1 : 1 + (prevTicks / (float) entry.type.fadeTicks);
float currentAlpha = 1 + (entry.ticksTillRemoval / (float) entry.type.fadeTicks);
float alpha = MathHelper.lerp(Minecraft.getInstance()
.getRenderPartialTicks(), lastAlpha, currentAlpha);
outline.params.alpha = alpha * alpha * alpha;
if (outline.params.alpha < 1 / 8f)
return;
}
outline.render(ms, buffer);
});
}
public enum ExpireType {
IMMEDIATE(0), FADE(8), FADE_EXPAND(10);
private int fadeTicks;
private ExpireType(int fadeTicks) {
this.fadeTicks = fadeTicks;
}
}
private class OutlineEntry {
private Outline outline;
private int ticksTillRemoval;
private ExpireType type;
public OutlineEntry(Outline outline, ExpireType type) {
this.outline = outline;
this.type = type;
ticksTillRemoval = 1;
}
public boolean isAlive() {
return ticksTillRemoval >= -type.fadeTicks;
}
public Outline getOutline() {
return outline;
}
}
}

View file

@ -9,19 +9,14 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
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.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.AllKeys; import com.simibubi.create.AllKeys;
import com.simibubi.create.foundation.utility.outliner.BlockClusterOutline; import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.foundation.utility.outliner.Outline; import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.utility.outliner.OutlineParticle; import com.simibubi.create.foundation.utility.outliner.Outliner.ExpireType;
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity; import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -35,16 +30,20 @@ public class ChassisRangeDisplay {
private static GroupEntry lastHoveredGroup = null; private static GroupEntry lastHoveredGroup = null;
private static class Entry { private static class Entry {
BlockClusterOutline outline;
OutlineParticle<Outline> particle;
ChassisTileEntity te; ChassisTileEntity te;
int timer; int timer;
public Entry(ChassisTileEntity te) { public Entry(ChassisTileEntity te) {
this.te = te; this.te = te;
outline = new BlockClusterOutline(createSelection(te));
particle = OutlineParticle.create(outline);
timer = DISPLAY_TIME; timer = DISPLAY_TIME;
CreateClient.outliner.showCluster(getOutlineKey(), createSelection(te), ExpireType.FADE)
.colored(0xFFFFBB)
.lineWidth(1 / 16f)
.withFaceTexture(AllSpecialTextures.CHECKERED);
}
protected Object getOutlineKey() {
return te.getPos();
} }
protected Set<BlockPos> createSelection(ChassisTileEntity chassis) { protected Set<BlockPos> createSelection(ChassisTileEntity chassis) {
@ -66,6 +65,11 @@ public class ChassisRangeDisplay {
super(te); super(te);
} }
@Override
protected Object getOutlineKey() {
return this;
}
@Override @Override
protected Set<BlockPos> createSelection(ChassisTileEntity chassis) { protected Set<BlockPos> createSelection(ChassisTileEntity chassis) {
Set<BlockPos> list = new HashSet<>(); Set<BlockPos> list = new HashSet<>();
@ -87,22 +91,23 @@ public class ChassisRangeDisplay {
World world = Minecraft.getInstance().world; World world = Minecraft.getInstance().world;
boolean hasWrench = AllItems.WRENCH.typeOf(player.getHeldItemMainhand()); boolean hasWrench = AllItems.WRENCH.typeOf(player.getHeldItemMainhand());
for (Iterator<BlockPos> iterator = entries.keySet().iterator(); iterator.hasNext();) { for (Iterator<BlockPos> iterator = entries.keySet()
Entry entry = entries.get(iterator.next()); .iterator(); iterator.hasNext();) {
if (tickEntry(entry, hasWrench)) { BlockPos pos = iterator.next();
entry.particle.remove(); Entry entry = entries.get(pos);
if (tickEntry(entry, hasWrench))
iterator.remove(); iterator.remove();
} CreateClient.outliner.keepCluster(entry.getOutlineKey());
} }
for (Iterator<GroupEntry> iterator = groupEntries.iterator(); iterator.hasNext();) { for (Iterator<GroupEntry> iterator = groupEntries.iterator(); iterator.hasNext();) {
GroupEntry group = iterator.next(); GroupEntry group = iterator.next();
if (tickEntry(group, hasWrench)) { if (tickEntry(group, hasWrench)) {
iterator.remove(); iterator.remove();
group.particle.remove();
if (group == lastHoveredGroup) if (group == lastHoveredGroup)
lastHoveredGroup = null; lastHoveredGroup = null;
} }
CreateClient.outliner.keepCluster(group.getOutlineKey());
} }
if (!hasWrench) if (!hasWrench)
@ -125,11 +130,8 @@ public class ChassisRangeDisplay {
if (ctrl) { if (ctrl) {
GroupEntry existingGroupForPos = getExistingGroupForPos(pos); GroupEntry existingGroupForPos = getExistingGroupForPos(pos);
if (existingGroupForPos != null) { if (existingGroupForPos != null) {
for (ChassisTileEntity included : existingGroupForPos.includedTEs) { for (ChassisTileEntity included : existingGroupForPos.includedTEs)
Entry removed = entries.remove(included.getPos()); entries.remove(included.getPos());
if (removed != null)
removed.particle.remove();
}
existingGroupForPos.timer = DISPLAY_TIME; existingGroupForPos.timer = DISPLAY_TIME;
return; return;
} }
@ -138,21 +140,11 @@ public class ChassisRangeDisplay {
if (!entries.containsKey(pos) || ctrl) if (!entries.containsKey(pos) || ctrl)
display(chassisTileEntity); display(chassisTileEntity);
else { else {
deselect();
if (!ctrl) if (!ctrl)
entries.get(pos).timer = DISPLAY_TIME; entries.get(pos).timer = DISPLAY_TIME;
} }
} }
private static void deselect() {
for (Entry entry : entries.values())
if (entry.timer > 10)
entry.timer = 10;
for (Entry entry : groupEntries)
if (entry.timer > 10)
entry.timer = 10;
}
private static boolean tickEntry(Entry entry, boolean hasWrench) { private static boolean tickEntry(Entry entry, boolean hasWrench) {
ChassisTileEntity chassisTileEntity = entry.te; ChassisTileEntity chassisTileEntity = entry.te;
World teWorld = chassisTileEntity.getWorld(); World teWorld = chassisTileEntity.getWorld();
@ -175,63 +167,31 @@ public class ChassisRangeDisplay {
} }
public static void display(ChassisTileEntity chassis) { public static void display(ChassisTileEntity chassis) {
deselect();
if (AllKeys.ctrlDown()) {
groupEntries.forEach(e -> e.particle.remove());
groupEntries.clear();
GroupEntry hoveredGroup = new GroupEntry(chassis);
for (ChassisTileEntity included : hoveredGroup.includedTEs) {
Entry remove = entries.remove(included.getPos());
if (remove != null)
remove.particle.remove();
}
groupEntries.add(hoveredGroup);
} else {
Entry old = entries.put(chassis.getPos(), new Entry(chassis));
if (old != null)
old.particle.remove();
}
}
public static void renderOutlines(float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer) { // Display a group and kill any selections of its contained chassis blocks
// TODO 1.15 buffered render if (AllKeys.ctrlDown()) {
if (entries.isEmpty() && groupEntries.isEmpty()) { GroupEntry hoveredGroup = new GroupEntry(chassis);
for (ChassisTileEntity included : hoveredGroup.includedTEs)
CreateClient.outliner.remove(included.getPos());
groupEntries.forEach(entry -> CreateClient.outliner.remove(entry.getOutlineKey()));
groupEntries.clear();
entries.clear();
groupEntries.add(hoveredGroup);
return; return;
} }
RenderSystem.lineWidth(2);
//TessellatorHelper.prepareForDrawing();
RenderSystem.disableTexture();
RenderSystem.enableAlphaTest();
for (Entry entry : entries.values()) // Display an individual chassis and kill any group selections that contained it
renderPositions(entry, partialTicks); BlockPos pos = chassis.getPos();
for (Entry groupEntry : groupEntries) GroupEntry entry = getExistingGroupForPos(pos);
renderPositions(groupEntry, partialTicks); if (entry != null)
CreateClient.outliner.remove(entry.getOutlineKey());
RenderSystem.enableTexture(); groupEntries.clear();
RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); entries.clear();
//TessellatorHelper.cleanUpAfterDrawing(); entries.put(pos, new Entry(chassis));
RenderSystem.lineWidth(1);
}
public static void renderPositions(Entry entry, float partialTicks) {
// GlStateManager.pushMatrix();
// RenderHelper.disableStandardItemLighting();
// GlStateManager.normal3f(0.0F, 1.0F, 0.0F);
// GlStateManager.color4f(1, 1, 1, 1);
// GlStateManager.enableTexture();
// GlStateManager.depthMask(false);
// GlStateManager.enableBlend();
// GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
//
float timer = entry.timer - partialTicks;
float alpha = timer > 20 ? 1 : timer / 20f;
entry.outline.setAlpha(alpha);
// entry.outline.render(Tessellator.getInstance().getBuffer());
//
// GlStateManager.disableBlend();
// GlStateManager.depthMask(true);
// GlStateManager.popMatrix();
} }
private static GroupEntry getExistingGroupForPos(BlockPos pos) { private static GroupEntry getExistingGroupForPos(BlockPos pos) {

View file

@ -10,16 +10,11 @@ import org.apache.commons.io.IOUtils;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.AllKeys; import com.simibubi.create.AllKeys;
import com.simibubi.create.AllSpecialTextures;
import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.gui.TextInputPromptScreen; import com.simibubi.create.foundation.gui.TextInputPromptScreen;
import com.simibubi.create.foundation.utility.FilesHelper; import com.simibubi.create.foundation.utility.FilesHelper;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
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.VecHelper;
import com.simibubi.create.foundation.utility.outliner.ChasingAABBOutline;
import com.simibubi.create.foundation.utility.outliner.OutlineParticle;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -49,7 +44,7 @@ public class SchematicAndQuillHandler {
private Direction selectedFace; private Direction selectedFace;
private int range = 10; private int range = 10;
private OutlineParticle<ChasingAABBOutline> particle; // private OutlineParticle<ChasingAABBOutline> particle;
public boolean mouseScrolled(double delta) { public boolean mouseScrolled(double delta) {
if (!isActive()) if (!isActive())
@ -129,10 +124,10 @@ public class SchematicAndQuillHandler {
public void tick() { public void tick() {
if (!isActive()) { if (!isActive()) {
if (particle != null) { // if (particle != null) {
particle.setExpired(); // particle.setExpired();
particle = null; // particle = null;
} // }
return; return;
} }
@ -157,49 +152,49 @@ public class SchematicAndQuillHandler {
setCursor(null); setCursor(null);
} }
if (particle == null) // if (particle == null)
return; // return;
//
// ChasingAABBOutline outline = particle.getOutline();
// if (particle.isAlive())
// outline.tick();
ChasingAABBOutline outline = particle.getOutline(); // if (secondPos == null) {
if (particle.isAlive()) // selectedFace = null;
outline.tick(); // outline.highlightFace(null);
// return;
if (secondPos == null) { // }
selectedFace = null; //
outline.highlightFace(null); // AxisAlignedBB bb = new AxisAlignedBB(firstPos, secondPos).expand(1, 1, 1).grow(.45f);
return; // Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView();
} // boolean inside = bb.contains(projectedView);
//
AxisAlignedBB bb = new AxisAlignedBB(firstPos, secondPos).expand(1, 1, 1).grow(.45f); // PredicateTraceResult result =
Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView(); // RaycastHelper.rayTraceUntil(player, 70, pos -> inside ^ bb.contains(VecHelper.getCenterOf(pos)));
boolean inside = bb.contains(projectedView); // selectedFace = result.missed() ? null : inside ? result.getFacing().getOpposite() : result.getFacing();
// outline.highlightFace(AllKeys.ACTIVATE_TOOL.isPressed() ? selectedFace : null);
PredicateTraceResult result =
RaycastHelper.rayTraceUntil(player, 70, pos -> inside ^ bb.contains(VecHelper.getCenterOf(pos)));
selectedFace = result.missed() ? null : inside ? result.getFacing().getOpposite() : result.getFacing();
outline.highlightFace(AllKeys.ACTIVATE_TOOL.isPressed() ? selectedFace : null);
} }
private void setCursor(BlockPos pos) { private void setCursor(BlockPos pos) {
selectedPos = pos; selectedPos = pos;
AxisAlignedBB bb = getCurrentSelectionBox(); AxisAlignedBB bb = getCurrentSelectionBox();
if (particle != null && !particle.isAlive()) // if (particle != null && !particle.isAlive())
particle = null; // particle = null;
if (bb == null) { // if (bb == null) {
if (particle != null) // if (particle != null)
particle.setExpired(); // particle.setExpired();
return; // return;
} // }
//
if (particle == null) { // if (particle == null) {
ChasingAABBOutline outline = new ChasingAABBOutline(bb); // ChasingAABBOutline outline = new ChasingAABBOutline(bb);
outline.setTextures(AllSpecialTextures.CHECKERED, AllSpecialTextures.HIGHLIGHT_CHECKERED); // outline.setTextures(AllSpecialTextures.CHECKERED, AllSpecialTextures.HIGHLIGHT_CHECKERED);
particle = OutlineParticle.create(outline); // particle = OutlineParticle.create(outline);
} // }
//
ChasingAABBOutline outline = particle.getOutline(); // ChasingAABBOutline outline = particle.getOutline();
outline.target(bb); // outline.target(bb);
} }
private AxisAlignedBB getCurrentSelectionBox() { private AxisAlignedBB getCurrentSelectionBox() {

View file

@ -65,9 +65,9 @@ public class DeployTool extends PlacementToolBase {
RenderSystem.translated(-rotationOffset.x, 0, -rotationOffset.z); RenderSystem.translated(-rotationOffset.x, 0, -rotationOffset.z);
RenderSystem.translated(-xOrigin, 0, -zOrigin); RenderSystem.translated(-xOrigin, 0, -zOrigin);
schematicHandler.getOutline().setTextures(AllSpecialTextures.CHECKERED, null); // schematicHandler.getOutline().setTextures(AllSpecialTextures.CHECKERED, null);
schematicHandler.getOutline().render(Tessellator.getInstance().getBuffer()); // schematicHandler.getOutline().render(Tessellator.getInstance().getBuffer());TODO
schematicHandler.getOutline().setTextures(null, null); // schematicHandler.getOutline().setTextures(null, null);
RenderSystem.popMatrix(); RenderSystem.popMatrix();
} }

View file

@ -129,7 +129,7 @@ public abstract class SchematicToolBase implements ISchematicTool {
RenderHelper.disableStandardItemLighting(); RenderHelper.disableStandardItemLighting();
RenderSystem.pushMatrix(); RenderSystem.pushMatrix();
RenderSystem.enableBlend(); RenderSystem.enableBlend();
outline.render(Tessellator.getInstance().getBuffer()); // outline.render(Tessellator.getInstance().getBuffer());TODO
RenderSystem.popMatrix(); RenderSystem.popMatrix();
outline.setTextures(null, null); outline.setTextures(null, null);