mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-15 09:23:40 +01:00
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:
parent
afd6ec17e0
commit
071482bb26
16 changed files with 525 additions and 370 deletions
|
@ -1,5 +1,7 @@
|
|||
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 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.entry.BlockEntry;
|
||||
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.Blocks;
|
||||
|
@ -33,15 +33,13 @@ import net.minecraft.tags.BlockTags;
|
|||
import net.minecraft.tags.ItemTags;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.tags.TagCollection;
|
||||
import net.minecraft.util.IItemProvider;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.generators.ConfiguredModel;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
|
||||
public class AllBlocksNew {
|
||||
|
||||
private static final CreateRegistrate REGISTRATE = Create.registrate()
|
||||
.itemGroup(() -> Create.baseCreativeTab);
|
||||
.itemGroup(() -> Create.baseCreativeTab);
|
||||
|
||||
static {
|
||||
REGISTRATE.startSection(SCHEMATICS);
|
||||
|
@ -123,76 +121,68 @@ public class AllBlocksNew {
|
|||
.model(AssetLookup::customItemModel)
|
||||
.build()
|
||||
.register();
|
||||
|
||||
static { REGISTRATE.startSection(Sections.MATERIALS); }
|
||||
|
||||
public static final BlockEntry<OxidizingBlock> COPPER_ORE = REGISTRATE.block("copper_ore", p -> new OxidizingBlock(p, 1))
|
||||
.initialProperties(() -> Blocks.IRON_ORE)
|
||||
.transform(oxidizedBlockstate())
|
||||
.transform(tagBlockAndItem("ores/copper"))
|
||||
|
||||
static {
|
||||
REGISTRATE.startSection(Sections.MATERIALS);
|
||||
}
|
||||
|
||||
public static final BlockEntry<OxidizingBlock> COPPER_ORE =
|
||||
REGISTRATE.block("copper_ore", p -> new OxidizingBlock(p, 1))
|
||||
.initialProperties(() -> Blocks.IRON_ORE)
|
||||
.transform(oxidizedBlockstate())
|
||||
.transform(tagBlockAndItem("ores/copper"))
|
||||
.transform(oxidizedItemModel())
|
||||
.register();
|
||||
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<Block> ZINC_ORE = REGISTRATE.block("zinc_ore", Block::new)
|
||||
.initialProperties(() -> Blocks.GOLD_BLOCK)
|
||||
.properties(p -> p.harvestLevel(2).harvestTool(ToolType.PICKAXE))
|
||||
.properties(p -> p.harvestLevel(2)
|
||||
.harvestTool(ToolType.PICKAXE))
|
||||
.transform(tagBlockAndItem("ores/zinc"))
|
||||
.build()
|
||||
.build()
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<OxidizingBlock> COPPER_BLOCK = REGISTRATE.block("copper_block", p -> new OxidizingBlock(p, 1 / 32f))
|
||||
.initialProperties(() -> Blocks.IRON_BLOCK)
|
||||
.transform(tagBlockAndItem("storage_blocks/copper"))
|
||||
|
||||
public static final BlockEntry<OxidizingBlock> COPPER_BLOCK =
|
||||
REGISTRATE.block("copper_block", p -> new OxidizingBlock(p, 1 / 32f))
|
||||
.initialProperties(() -> Blocks.IRON_BLOCK)
|
||||
.transform(tagBlockAndItem("storage_blocks/copper"))
|
||||
.transform(oxidizedItemModel())
|
||||
.recipe((ctx, prov) -> prov.square(DataIngredient.tag(forgeItemTag("ingots/copper")), ctx, false))
|
||||
.transform(oxidizedBlockstate())
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<OxidizingBlock> COPPER_SHINGLES = REGISTRATE.block("copper_shingles", p -> new OxidizingBlock(p, 1 / 32f))
|
||||
.initialProperties(() -> Blocks.IRON_BLOCK)
|
||||
.item().transform(oxidizedItemModel())
|
||||
.recipe((ctx, prov) -> prov.square(DataIngredient.tag(forgeItemTag("plates/copper")), ctx, true))
|
||||
.transform(oxidizedBlockstate())
|
||||
.register();
|
||||
|
||||
.recipe((ctx, prov) -> prov.square(DataIngredient.tag(forgeItemTag("ingots/copper")), ctx, false))
|
||||
.transform(oxidizedBlockstate())
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<OxidizingBlock> COPPER_SHINGLES =
|
||||
REGISTRATE.block("copper_shingles", p -> new OxidizingBlock(p, 1 / 32f))
|
||||
.initialProperties(() -> Blocks.IRON_BLOCK)
|
||||
.item()
|
||||
.transform(oxidizedItemModel())
|
||||
.recipe((ctx, prov) -> prov.square(DataIngredient.tag(forgeItemTag("plates/copper")), ctx, true))
|
||||
.transform(oxidizedBlockstate())
|
||||
.register();
|
||||
|
||||
public static final BlockEntry<Block> ZINC_BLOCK = REGISTRATE.block("zinc_block", Block::new)
|
||||
.initialProperties(() -> Blocks.IRON_BLOCK)
|
||||
.transform(tagBlockAndItem("storage_blocks/zinc"))
|
||||
.build()
|
||||
.build()
|
||||
.recipe((ctx, prov) -> prov.square(DataIngredient.tag(forgeItemTag("ingots/zinc")), ctx, false))
|
||||
.register();
|
||||
|
||||
|
||||
public static final BlockEntry<Block> BRASS_BLOCK = REGISTRATE.block("brass_block", Block::new)
|
||||
.initialProperties(() -> Blocks.IRON_BLOCK)
|
||||
.transform(tagBlockAndItem("storage_blocks/brass"))
|
||||
.build()
|
||||
.build()
|
||||
.recipe((ctx, prov) -> prov.square(DataIngredient.tag(forgeItemTag("ingots/brass")), ctx, false))
|
||||
.register();
|
||||
|
||||
// Utility
|
||||
|
||||
private static String getOxidizedModel(String name, int level) {
|
||||
return "block/oxidized/" + name + "_" + level;
|
||||
}
|
||||
|
||||
private static <P> NonNullUnaryOperator<BlockBuilder<OxidizingBlock, P>> oxidizedBlockstate() {
|
||||
return b -> b.blockstate((ctx, prov) -> prov.getVariantBuilder(ctx.getEntry())
|
||||
.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))
|
||||
.item()
|
||||
.tag(forgeItemTag(tagName));
|
||||
}
|
||||
|
||||
private static <T extends Block, P> NonNullFunction<BlockBuilder<T, P>, ItemBuilder<BlockItem, BlockBuilder<T, P>>> tagBlockAndItem(String tagName) {
|
||||
return b -> b.tag(forgeBlockTag(tagName))
|
||||
.item()
|
||||
.tag(forgeItemTag(tagName));
|
||||
}
|
||||
|
||||
private static Tag<Block> forgeBlockTag(String name) {
|
||||
return forgeTag(BlockTags.getCollection(), name);
|
||||
}
|
||||
|
@ -200,15 +190,15 @@ public class AllBlocksNew {
|
|||
private static Tag<Item> forgeItemTag(String name) {
|
||||
return forgeTag(ItemTags.getCollection(), name);
|
||||
}
|
||||
|
||||
|
||||
private static <T> Tag<T> forgeTag(TagCollection<T> collection, String name) {
|
||||
return tag(collection, "forge", name);
|
||||
}
|
||||
|
||||
|
||||
private static <T> Tag<T> tag(TagCollection<T> collection, String domain, String name) {
|
||||
return collection.getOrCreate(new ResourceLocation(domain, name));
|
||||
}
|
||||
|
||||
|
||||
public static void register() {}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,5 +25,9 @@ public enum AllSpecialTextures {
|
|||
public void bind() {
|
||||
Minecraft.getInstance().getTextureManager().bindTexture(location);
|
||||
}
|
||||
|
||||
public ResourceLocation getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
}
|
|
@ -12,7 +12,6 @@ import com.simibubi.create.foundation.item.TooltipHelper;
|
|||
import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||
import com.simibubi.create.modules.contraptions.KineticDebugger;
|
||||
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.relays.belt.item.BeltConnectorHandler;
|
||||
import com.simibubi.create.modules.curiosities.zapper.terrainzapper.TerrainZapperRenderHandler;
|
||||
|
@ -74,18 +73,21 @@ public class ClientEvents {
|
|||
MatrixStack ms = event.getMatrixStack();
|
||||
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
||||
Vec3d view = info.getProjectedView();
|
||||
|
||||
|
||||
ms.push();
|
||||
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.outliner.renderOutlines(ms, buffer);
|
||||
KineticDebugger.renderSourceOutline(ms, buffer);
|
||||
ChassisRangeDisplay.renderOutlines(event.getPartialTicks(), ms, buffer);
|
||||
TerrainZapperRenderHandler.render(ms, buffer);
|
||||
|
||||
|
||||
ms.pop();
|
||||
|
||||
|
||||
buffer.draw();
|
||||
}
|
||||
|
||||
|
@ -94,8 +96,9 @@ public class ClientEvents {
|
|||
if (event.getType() != ElementType.HOTBAR)
|
||||
return;
|
||||
|
||||
onRenderHotbar(new MatrixStack(), Minecraft.getInstance().getBufferBuilders().getEntityVertexConsumers(),
|
||||
0xF000F0, OverlayTexture.DEFAULT_UV);
|
||||
onRenderHotbar(new MatrixStack(), Minecraft.getInstance()
|
||||
.getBufferBuilders()
|
||||
.getEntityVertexConsumers(), 0xF000F0, OverlayTexture.DEFAULT_UV);
|
||||
}
|
||||
|
||||
public static void onRenderHotbar(MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) {
|
||||
|
@ -121,9 +124,8 @@ public class ClientEvents {
|
|||
double delta = event.getScrollDelta();
|
||||
|
||||
boolean cancelled = CreateClient.schematicHandler.mouseScrolled(delta)
|
||||
|| CreateClient.schematicAndQuillHandler.mouseScrolled(delta)
|
||||
|| FilteringHandler.onScroll(delta)
|
||||
|| ScrollValueHandler.onScroll(delta);
|
||||
|| CreateClient.schematicAndQuillHandler.mouseScrolled(delta) || FilteringHandler.onScroll(delta)
|
||||
|| ScrollValueHandler.onScroll(delta);
|
||||
event.setCanceled(cancelled);
|
||||
}
|
||||
|
||||
|
@ -147,7 +149,8 @@ public class ClientEvents {
|
|||
return;
|
||||
|
||||
ItemStack stack = event.getItemStack();
|
||||
String translationKey = stack.getItem().getTranslationKey(stack);
|
||||
String translationKey = stack.getItem()
|
||||
.getTranslationKey(stack);
|
||||
if (!translationKey.startsWith(itemPrefix) && !translationKey.startsWith(blockPrefix))
|
||||
return;
|
||||
|
||||
|
@ -155,7 +158,8 @@ public class ClientEvents {
|
|||
List<ITextComponent> itemTooltip = event.getToolTip();
|
||||
List<ITextComponent> toolTip = new ArrayList<>();
|
||||
toolTip.add(itemTooltip.remove(0));
|
||||
TooltipHelper.getTooltip(stack).addInformation(toolTip);
|
||||
TooltipHelper.getTooltip(stack)
|
||||
.addInformation(toolTip);
|
||||
itemTooltip.addAll(0, toolTip);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.item.IHaveCustomItemModel;
|
||||
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.components.contraptions.ChassisRangeDisplay;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionRenderer;
|
||||
|
@ -41,6 +42,7 @@ public class CreateClient {
|
|||
public static SchematicHandler schematicHandler;
|
||||
public static SchematicAndQuillHandler schematicAndQuillHandler;
|
||||
public static SuperByteBufferCache bufferCache;
|
||||
public static Outliner outliner;
|
||||
private static CustomBlockModels customBlockModels;
|
||||
|
||||
public static void addListeners(IEventBus modEventBus) {
|
||||
|
@ -57,6 +59,7 @@ public class CreateClient {
|
|||
schematicSender = new ClientSchematicLoader();
|
||||
schematicHandler = new SchematicHandler();
|
||||
schematicAndQuillHandler = new SchematicAndQuillHandler();
|
||||
outliner = new Outliner();
|
||||
|
||||
bufferCache = new SuperByteBufferCache();
|
||||
bufferCache.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE);
|
||||
|
@ -74,11 +77,12 @@ public class CreateClient {
|
|||
if (resourceManager instanceof IReloadableResourceManager)
|
||||
((IReloadableResourceManager) resourceManager).addReloadListener(new ResourceReloadHandler());
|
||||
}
|
||||
|
||||
|
||||
public static void gameTick() {
|
||||
schematicSender.tick();
|
||||
schematicAndQuillHandler.tick();
|
||||
schematicHandler.tick();
|
||||
outliner.tickOutlines();
|
||||
ChassisRangeDisplay.clientTick();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,10 +3,13 @@ package com.simibubi.create.foundation.utility.data;
|
|||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.simibubi.create.foundation.world.OxidizingBlock;
|
||||
import com.simibubi.create.modules.palettes.PavedBlock;
|
||||
import com.tterrag.registrate.builders.BlockBuilder;
|
||||
import com.tterrag.registrate.providers.DataGenContext;
|
||||
import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
|
||||
import com.tterrag.registrate.util.nullness.NonNullBiConsumer;
|
||||
import com.tterrag.registrate.util.nullness.NonNullUnaryOperator;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -56,4 +59,14 @@ public class BlockStateGen {
|
|||
.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();
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package com.simibubi.create.foundation.utility.data;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.tterrag.registrate.builders.ItemBuilder;
|
||||
import com.tterrag.registrate.providers.DataGenContext;
|
||||
import com.tterrag.registrate.util.nullness.NonNullFunction;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.generators.BlockStateProvider;
|
||||
import net.minecraftforge.client.model.generators.ModelFile;
|
||||
|
@ -26,4 +29,12 @@ public class ModelGen {
|
|||
.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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
package com.simibubi.create.foundation.utility.outliner;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
import com.simibubi.create.AllSpecialTextures;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
|
||||
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.Axis;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
|
@ -24,10 +27,10 @@ public class AABBOutline extends Outline {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void render(BufferBuilder buffer) {
|
||||
public void render(MatrixStack ms, IRenderTypeBuffer buffer) {
|
||||
Vec3d color = ColorHelper.getRGB(0xFFFFFF);
|
||||
float alpha = 1f;
|
||||
renderBB(bb, buffer, color, alpha, !disableCull);
|
||||
renderBB(ms, buffer, bb, color, alpha, !disableCull);
|
||||
}
|
||||
|
||||
public void setTextures(AllSpecialTextures faceTexture, AllSpecialTextures highlightTexture) {
|
||||
|
@ -39,8 +42,10 @@ public class AABBOutline extends Outline {
|
|||
this.highlightedFace = face;
|
||||
}
|
||||
|
||||
public void renderBB(AxisAlignedBB bb, IVertexBuilder builder, Vec3d color, float alpha, boolean doCulling) {
|
||||
Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView();
|
||||
public void renderBB(MatrixStack ms, IRenderTypeBuffer buffer, AxisAlignedBB bb, Vec3d color, float alpha,
|
||||
boolean doCulling) {
|
||||
Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo()
|
||||
.getProjectedView();
|
||||
boolean inside = bb.contains(projectedView);
|
||||
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.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;
|
||||
AllSpecialTextures.BLANK.bind();
|
||||
renderAACuboidLine(start, Xyz, color, alpha, builder);
|
||||
renderAACuboidLine(start, xYz, color, alpha, builder);
|
||||
renderAACuboidLine(start, xyZ, color, alpha, builder);
|
||||
renderAACuboidLine(ms, buffer, start, Xyz);
|
||||
renderAACuboidLine(ms, buffer, start, xYz);
|
||||
renderAACuboidLine(ms, buffer, start, xyZ);
|
||||
|
||||
start = XyZ;
|
||||
renderAACuboidLine(start, xyZ, color, alpha, builder);
|
||||
renderAACuboidLine(start, XYZ, color, alpha, builder);
|
||||
renderAACuboidLine(start, Xyz, color, alpha, builder);
|
||||
renderAACuboidLine(ms, buffer, start, xyZ);
|
||||
renderAACuboidLine(ms, buffer, start, XYZ);
|
||||
renderAACuboidLine(ms, buffer, start, Xyz);
|
||||
|
||||
start = XYz;
|
||||
renderAACuboidLine(start, xYz, color, alpha, builder);
|
||||
renderAACuboidLine(start, Xyz, color, alpha, builder);
|
||||
renderAACuboidLine(start, XYZ, color, alpha, builder);
|
||||
renderAACuboidLine(ms, buffer, start, xYz);
|
||||
renderAACuboidLine(ms, buffer, start, Xyz);
|
||||
renderAACuboidLine(ms, buffer, start, XYZ);
|
||||
|
||||
start = xYZ;
|
||||
renderAACuboidLine(start, XYZ, color, alpha, builder);
|
||||
renderAACuboidLine(start, xyZ, color, alpha, builder);
|
||||
renderAACuboidLine(start, xYz, color, alpha, builder);
|
||||
renderAACuboidLine(ms, buffer, start, XYZ);
|
||||
renderAACuboidLine(ms, buffer, start, xyZ);
|
||||
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)
|
||||
highlightedTexture.bind();
|
||||
else if (faceTexture != null)
|
||||
faceTexture.bind();
|
||||
else
|
||||
faceTexture = highlightedTexture.getLocation();
|
||||
else if (faceTexture == null)
|
||||
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 vDiff = p4.subtract(p1);
|
||||
Axis axis = direction.getAxis();
|
||||
float maxU = (float) Math.abs(axis == Axis.X ? uDiff.z : uDiff.x);
|
||||
float maxV = (float) Math.abs(axis == Axis.Y ? vDiff.z : vDiff.y);
|
||||
putQuadUV(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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,12 +3,16 @@ package com.simibubi.create.foundation.utility.outliner;
|
|||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
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.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.Axis;
|
||||
import net.minecraft.util.Direction.AxisDirection;
|
||||
|
@ -18,41 +22,59 @@ import net.minecraft.util.math.Vec3d;
|
|||
public class BlockClusterOutline extends Outline {
|
||||
|
||||
private Cluster cluster;
|
||||
private float alpha;
|
||||
|
||||
public BlockClusterOutline(Iterable<BlockPos> selection) {
|
||||
cluster = new Cluster();
|
||||
selection.forEach(cluster::include);
|
||||
alpha = .5f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(BufferBuilder buffer) {
|
||||
Vec3d color = ColorHelper.getRGB(0xDDDDDD);
|
||||
AllSpecialTextures.SELECTION.bind();
|
||||
|
||||
public void render(MatrixStack ms, IRenderTypeBuffer buffer) {
|
||||
for (MergeEntry edge : cluster.visibleEdges) {
|
||||
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()) {
|
||||
AxisDirection axisDirection = cluster.visibleFaces.get(face);
|
||||
Direction direction = Direction.getFacingFromAxis(axisDirection, face.axis);
|
||||
BlockPos pos = face.pos;
|
||||
if (axisDirection == AxisDirection.POSITIVE)
|
||||
pos = pos.offset(direction.getOpposite());
|
||||
renderFace(pos, direction, color, alpha * .25f, 1 / 64d, buffer);
|
||||
renderBlockFace(ms, buffer, pos, direction);
|
||||
}
|
||||
|
||||
AllSpecialTextures.BLANK.bind();
|
||||
|
||||
for (MergeEntry edge : cluster.visibleEdges) {
|
||||
lineWidth = 1 / 16f * alpha;
|
||||
Vec3d start = new Vec3d(edge.pos);
|
||||
Direction direction = Direction.getFacingFromAxis(AxisDirection.POSITIVE, edge.axis);
|
||||
renderAACuboidLine(start, new Vec3d(edge.pos.offset(direction)), color, 1, buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setAlpha(float alpha) {
|
||||
this.alpha = alpha;
|
||||
protected void renderBlockFace(MatrixStack ms, IRenderTypeBuffer buffer, BlockPos pos, Direction face) {
|
||||
Optional<AllSpecialTextures> faceTexture = params.faceTexture;
|
||||
if (!faceTexture.isPresent())
|
||||
return;
|
||||
|
||||
RenderType translucentType = RenderType.getEntityTranslucent(faceTexture.get()
|
||||
.getLocation());
|
||||
IVertexBuilder builder = buffer.getBuffer(translucentType);
|
||||
|
||||
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 + 1 / 64d);
|
||||
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 {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package com.simibubi.create.foundation.utility.outliner;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
|
||||
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.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
@ -23,24 +24,25 @@ public class ChasingAABBOutline extends AABBOutline {
|
|||
targetBB = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
prevBB = bb;
|
||||
bb = interpolateBBs(bb, targetBB, .5f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(BufferBuilder buffer) {
|
||||
public void render(MatrixStack ms, IRenderTypeBuffer buffer) {
|
||||
Vec3d color = ColorHelper.getRGB(0xFFFFFF);
|
||||
float alpha = 1f;
|
||||
renderBB(interpolateBBs(prevBB, bb, Minecraft.getInstance().getRenderPartialTicks()), buffer, color, alpha,
|
||||
true);
|
||||
renderBB(ms, buffer, interpolateBBs(prevBB, bb, Minecraft.getInstance()
|
||||
.getRenderPartialTicks()), color, alpha, true);
|
||||
}
|
||||
|
||||
private static AxisAlignedBB interpolateBBs(AxisAlignedBB current, AxisAlignedBB target, float pt) {
|
||||
return new AxisAlignedBB(MathHelper.lerp(pt, current.minX, target.minX),
|
||||
MathHelper.lerp(pt, current.minY, target.minY), MathHelper.lerp(pt, current.minZ, target.minZ),
|
||||
MathHelper.lerp(pt, current.maxX, target.maxX), MathHelper.lerp(pt, current.maxY, target.maxY),
|
||||
MathHelper.lerp(pt, current.maxZ, target.maxZ));
|
||||
MathHelper.lerp(pt, current.minY, target.minY), MathHelper.lerp(pt, current.minZ, target.minZ),
|
||||
MathHelper.lerp(pt, current.maxX, target.maxX), MathHelper.lerp(pt, current.maxY, target.maxY),
|
||||
MathHelper.lerp(pt, current.maxZ, target.maxZ));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,21 +1,34 @@
|
|||
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.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.client.renderer.texture.OverlayTexture;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public abstract class Outline {
|
||||
|
||||
protected float lineWidth = 1 / 32f;
|
||||
protected OutlineParams params;
|
||||
|
||||
public Outline() {
|
||||
params = new OutlineParams();
|
||||
}
|
||||
|
||||
public abstract void render(BufferBuilder buffer);
|
||||
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);
|
||||
if (diff.x + diff.y + diff.z < 0) {
|
||||
Vec3d temp = start;
|
||||
|
@ -24,13 +37,17 @@ public abstract class Outline {
|
|||
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);
|
||||
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);
|
||||
end = end.add(extension);
|
||||
plane = plane.scale(lineWidth / 2);
|
||||
|
||||
Vec3d a1 = plane.add(start);
|
||||
Vec3d b1 = plane.add(end);
|
||||
plane = VecHelper.rotate(plane, -90, axis);
|
||||
|
@ -43,55 +60,92 @@ public abstract class Outline {
|
|||
Vec3d a4 = plane.add(start);
|
||||
Vec3d b4 = plane.add(end);
|
||||
|
||||
putQuad(b4, b3, b2, b1, rgb, alpha, builder);
|
||||
putQuad(a1, a2, a3, a4, rgb, alpha, builder);
|
||||
|
||||
putQuad(a1, b1, b2, a2, rgb, alpha, builder);
|
||||
putQuad(a2, b2, b3, a3, rgb, alpha, builder);
|
||||
putQuad(a3, b3, b4, a4, rgb, alpha, builder);
|
||||
putQuad(a4, b4, b1, a1, rgb, alpha, builder);
|
||||
putQuad(ms, builder, b4, b3, b2, b1);
|
||||
putQuad(ms, builder, a1, a2, a3, a4);
|
||||
putQuad(ms, builder, a1, b1, b2, a2);
|
||||
putQuad(ms, builder, a2, b2, b3, a3);
|
||||
putQuad(ms, builder, a3, b3, b4, a4);
|
||||
putQuad(ms, builder, a4, b4, b1, a1);
|
||||
}
|
||||
|
||||
protected void renderFace(BlockPos pos, Direction face, Vec3d rgb, float alpha, double scaleOffset,
|
||||
IVertexBuilder builder) {
|
||||
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(MatrixStack ms, IVertexBuilder builder, Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4) {
|
||||
putQuadUV(ms, builder, v1, v2, v3, v4, 0, 0, 1, 1);
|
||||
}
|
||||
|
||||
public void putQuad(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, Vec3d rgb, float alpha, IVertexBuilder builder) {
|
||||
putQuadUV(v1, v2, v3, v4, 0, 0, 1, 1, rgb, alpha, builder);
|
||||
public void putQuadUV(MatrixStack ms, IVertexBuilder builder, Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, float minU,
|
||||
float minV, float maxU, float maxV) {
|
||||
putVertex(ms, builder, v1, minU, minV);
|
||||
putVertex(ms, builder, v2, maxU, minV);
|
||||
putVertex(ms, builder, v3, maxU, maxV);
|
||||
putVertex(ms, builder, v4, minU, maxV);
|
||||
}
|
||||
|
||||
public void putQuadUV(Vec3d v1, Vec3d v2, Vec3d v3, Vec3d v4, float minU, float minV, float maxU, float maxV,
|
||||
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) {
|
||||
protected void putVertex(MatrixStack ms, IVertexBuilder builder, Vec3d pos, float u, float v) {
|
||||
int i = 15 << 20 | 15 << 4;
|
||||
int j = i >> 16 & '\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)
|
||||
.light(j, k).endVertex();
|
||||
Entry peek = ms.peek();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -9,19 +9,14 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
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.AllKeys;
|
||||
import com.simibubi.create.foundation.utility.outliner.BlockClusterOutline;
|
||||
import com.simibubi.create.foundation.utility.outliner.Outline;
|
||||
import com.simibubi.create.foundation.utility.outliner.OutlineParticle;
|
||||
import com.simibubi.create.AllSpecialTextures;
|
||||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.foundation.utility.outliner.Outliner.ExpireType;
|
||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -35,16 +30,20 @@ public class ChassisRangeDisplay {
|
|||
private static GroupEntry lastHoveredGroup = null;
|
||||
|
||||
private static class Entry {
|
||||
BlockClusterOutline outline;
|
||||
OutlineParticle<Outline> particle;
|
||||
ChassisTileEntity te;
|
||||
int timer;
|
||||
|
||||
public Entry(ChassisTileEntity te) {
|
||||
this.te = te;
|
||||
outline = new BlockClusterOutline(createSelection(te));
|
||||
particle = OutlineParticle.create(outline);
|
||||
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) {
|
||||
|
@ -66,6 +65,11 @@ public class ChassisRangeDisplay {
|
|||
super(te);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getOutlineKey() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<BlockPos> createSelection(ChassisTileEntity chassis) {
|
||||
Set<BlockPos> list = new HashSet<>();
|
||||
|
@ -87,22 +91,23 @@ public class ChassisRangeDisplay {
|
|||
World world = Minecraft.getInstance().world;
|
||||
boolean hasWrench = AllItems.WRENCH.typeOf(player.getHeldItemMainhand());
|
||||
|
||||
for (Iterator<BlockPos> iterator = entries.keySet().iterator(); iterator.hasNext();) {
|
||||
Entry entry = entries.get(iterator.next());
|
||||
if (tickEntry(entry, hasWrench)) {
|
||||
entry.particle.remove();
|
||||
for (Iterator<BlockPos> iterator = entries.keySet()
|
||||
.iterator(); iterator.hasNext();) {
|
||||
BlockPos pos = iterator.next();
|
||||
Entry entry = entries.get(pos);
|
||||
if (tickEntry(entry, hasWrench))
|
||||
iterator.remove();
|
||||
}
|
||||
CreateClient.outliner.keepCluster(entry.getOutlineKey());
|
||||
}
|
||||
|
||||
for (Iterator<GroupEntry> iterator = groupEntries.iterator(); iterator.hasNext();) {
|
||||
GroupEntry group = iterator.next();
|
||||
if (tickEntry(group, hasWrench)) {
|
||||
iterator.remove();
|
||||
group.particle.remove();
|
||||
if (group == lastHoveredGroup)
|
||||
lastHoveredGroup = null;
|
||||
}
|
||||
CreateClient.outliner.keepCluster(group.getOutlineKey());
|
||||
}
|
||||
|
||||
if (!hasWrench)
|
||||
|
@ -125,11 +130,8 @@ public class ChassisRangeDisplay {
|
|||
if (ctrl) {
|
||||
GroupEntry existingGroupForPos = getExistingGroupForPos(pos);
|
||||
if (existingGroupForPos != null) {
|
||||
for (ChassisTileEntity included : existingGroupForPos.includedTEs) {
|
||||
Entry removed = entries.remove(included.getPos());
|
||||
if (removed != null)
|
||||
removed.particle.remove();
|
||||
}
|
||||
for (ChassisTileEntity included : existingGroupForPos.includedTEs)
|
||||
entries.remove(included.getPos());
|
||||
existingGroupForPos.timer = DISPLAY_TIME;
|
||||
return;
|
||||
}
|
||||
|
@ -138,28 +140,18 @@ public class ChassisRangeDisplay {
|
|||
if (!entries.containsKey(pos) || ctrl)
|
||||
display(chassisTileEntity);
|
||||
else {
|
||||
deselect();
|
||||
if (!ctrl)
|
||||
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) {
|
||||
ChassisTileEntity chassisTileEntity = entry.te;
|
||||
World teWorld = chassisTileEntity.getWorld();
|
||||
World world = Minecraft.getInstance().world;
|
||||
|
||||
if (chassisTileEntity.isRemoved() || teWorld == null || teWorld != world
|
||||
|| !world.isBlockPresent(chassisTileEntity.getPos())) {
|
||||
|| !world.isBlockPresent(chassisTileEntity.getPos())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -175,63 +167,31 @@ public class ChassisRangeDisplay {
|
|||
}
|
||||
|
||||
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) {
|
||||
// TODO 1.15 buffered render
|
||||
if (entries.isEmpty() && groupEntries.isEmpty()) {
|
||||
// Display a group and kill any selections of its contained chassis blocks
|
||||
if (AllKeys.ctrlDown()) {
|
||||
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;
|
||||
}
|
||||
RenderSystem.lineWidth(2);
|
||||
//TessellatorHelper.prepareForDrawing();
|
||||
RenderSystem.disableTexture();
|
||||
RenderSystem.enableAlphaTest();
|
||||
|
||||
for (Entry entry : entries.values())
|
||||
renderPositions(entry, partialTicks);
|
||||
for (Entry groupEntry : groupEntries)
|
||||
renderPositions(groupEntry, partialTicks);
|
||||
// Display an individual chassis and kill any group selections that contained it
|
||||
BlockPos pos = chassis.getPos();
|
||||
GroupEntry entry = getExistingGroupForPos(pos);
|
||||
if (entry != null)
|
||||
CreateClient.outliner.remove(entry.getOutlineKey());
|
||||
|
||||
RenderSystem.enableTexture();
|
||||
RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
//TessellatorHelper.cleanUpAfterDrawing();
|
||||
RenderSystem.lineWidth(1);
|
||||
}
|
||||
groupEntries.clear();
|
||||
entries.clear();
|
||||
entries.put(pos, new Entry(chassis));
|
||||
|
||||
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) {
|
||||
|
|
|
@ -10,16 +10,11 @@ import org.apache.commons.io.IOUtils;
|
|||
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllKeys;
|
||||
import com.simibubi.create.AllSpecialTextures;
|
||||
import com.simibubi.create.foundation.gui.ScreenOpener;
|
||||
import com.simibubi.create.foundation.gui.TextInputPromptScreen;
|
||||
import com.simibubi.create.foundation.utility.FilesHelper;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
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.client.Minecraft;
|
||||
|
@ -49,7 +44,7 @@ public class SchematicAndQuillHandler {
|
|||
private Direction selectedFace;
|
||||
private int range = 10;
|
||||
|
||||
private OutlineParticle<ChasingAABBOutline> particle;
|
||||
// private OutlineParticle<ChasingAABBOutline> particle;
|
||||
|
||||
public boolean mouseScrolled(double delta) {
|
||||
if (!isActive())
|
||||
|
@ -129,10 +124,10 @@ public class SchematicAndQuillHandler {
|
|||
|
||||
public void tick() {
|
||||
if (!isActive()) {
|
||||
if (particle != null) {
|
||||
particle.setExpired();
|
||||
particle = null;
|
||||
}
|
||||
// if (particle != null) {
|
||||
// particle.setExpired();
|
||||
// particle = null;
|
||||
// }
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -157,49 +152,49 @@ public class SchematicAndQuillHandler {
|
|||
setCursor(null);
|
||||
}
|
||||
|
||||
if (particle == null)
|
||||
return;
|
||||
// if (particle == null)
|
||||
// return;
|
||||
//
|
||||
// ChasingAABBOutline outline = particle.getOutline();
|
||||
// if (particle.isAlive())
|
||||
// outline.tick();
|
||||
|
||||
ChasingAABBOutline outline = particle.getOutline();
|
||||
if (particle.isAlive())
|
||||
outline.tick();
|
||||
|
||||
if (secondPos == null) {
|
||||
selectedFace = null;
|
||||
outline.highlightFace(null);
|
||||
return;
|
||||
}
|
||||
|
||||
AxisAlignedBB bb = new AxisAlignedBB(firstPos, secondPos).expand(1, 1, 1).grow(.45f);
|
||||
Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView();
|
||||
boolean inside = bb.contains(projectedView);
|
||||
|
||||
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);
|
||||
// if (secondPos == null) {
|
||||
// selectedFace = null;
|
||||
// outline.highlightFace(null);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// AxisAlignedBB bb = new AxisAlignedBB(firstPos, secondPos).expand(1, 1, 1).grow(.45f);
|
||||
// Vec3d projectedView = Minecraft.getInstance().gameRenderer.getActiveRenderInfo().getProjectedView();
|
||||
// boolean inside = bb.contains(projectedView);
|
||||
//
|
||||
// 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) {
|
||||
selectedPos = pos;
|
||||
AxisAlignedBB bb = getCurrentSelectionBox();
|
||||
|
||||
if (particle != null && !particle.isAlive())
|
||||
particle = null;
|
||||
if (bb == null) {
|
||||
if (particle != null)
|
||||
particle.setExpired();
|
||||
return;
|
||||
}
|
||||
|
||||
if (particle == null) {
|
||||
ChasingAABBOutline outline = new ChasingAABBOutline(bb);
|
||||
outline.setTextures(AllSpecialTextures.CHECKERED, AllSpecialTextures.HIGHLIGHT_CHECKERED);
|
||||
particle = OutlineParticle.create(outline);
|
||||
}
|
||||
|
||||
ChasingAABBOutline outline = particle.getOutline();
|
||||
outline.target(bb);
|
||||
// if (particle != null && !particle.isAlive())
|
||||
// particle = null;
|
||||
// if (bb == null) {
|
||||
// if (particle != null)
|
||||
// particle.setExpired();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (particle == null) {
|
||||
// ChasingAABBOutline outline = new ChasingAABBOutline(bb);
|
||||
// outline.setTextures(AllSpecialTextures.CHECKERED, AllSpecialTextures.HIGHLIGHT_CHECKERED);
|
||||
// particle = OutlineParticle.create(outline);
|
||||
// }
|
||||
//
|
||||
// ChasingAABBOutline outline = particle.getOutline();
|
||||
// outline.target(bb);
|
||||
}
|
||||
|
||||
private AxisAlignedBB getCurrentSelectionBox() {
|
||||
|
|
|
@ -65,9 +65,9 @@ public class DeployTool extends PlacementToolBase {
|
|||
RenderSystem.translated(-rotationOffset.x, 0, -rotationOffset.z);
|
||||
RenderSystem.translated(-xOrigin, 0, -zOrigin);
|
||||
|
||||
schematicHandler.getOutline().setTextures(AllSpecialTextures.CHECKERED, null);
|
||||
schematicHandler.getOutline().render(Tessellator.getInstance().getBuffer());
|
||||
schematicHandler.getOutline().setTextures(null, null);
|
||||
// schematicHandler.getOutline().setTextures(AllSpecialTextures.CHECKERED, null);
|
||||
// schematicHandler.getOutline().render(Tessellator.getInstance().getBuffer());TODO
|
||||
// schematicHandler.getOutline().setTextures(null, null);
|
||||
RenderSystem.popMatrix();
|
||||
}
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ public abstract class SchematicToolBase implements ISchematicTool {
|
|||
RenderHelper.disableStandardItemLighting();
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.enableBlend();
|
||||
outline.render(Tessellator.getInstance().getBuffer());
|
||||
// outline.render(Tessellator.getInstance().getBuffer());TODO
|
||||
RenderSystem.popMatrix();
|
||||
outline.setTextures(null, null);
|
||||
|
||||
|
|
Loading…
Reference in a new issue