From 4c68489c76fb1eabb70e51be25c7559ce1dbaaf8 Mon Sep 17 00:00:00 2001 From: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Date: Thu, 21 Nov 2024 18:02:37 +0100 Subject: [PATCH 1/9] added one directional graph connections --- .../config/features/dev/GraphConfig.java | 7 +- .../skyhanni/test/graph/GraphEditor.kt | 147 +++++++++++++++--- .../at/hannibal2/skyhanni/utils/LorenzVec.kt | 8 + .../hannibal2/skyhanni/utils/RenderUtils.kt | 80 +++++++++- 4 files changed, 216 insertions(+), 26 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/dev/GraphConfig.java b/src/main/java/at/hannibal2/skyhanni/config/features/dev/GraphConfig.java index dda1ddb1e50c..e8ba698e5c01 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/dev/GraphConfig.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/dev/GraphConfig.java @@ -24,7 +24,7 @@ public class GraphConfig { @Expose @ConfigOption(name = "Toggle Ghost Position", desc = "Creates or removes the Ghost Position. This helps editing nodes tht are in the air.") - @ConfigEditorKeybind(defaultKey = Keyboard.KEY_F) + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) public int toggleGhostPosition = Keyboard.KEY_NONE; @Expose @@ -97,6 +97,11 @@ public class GraphConfig { @ConfigEditorKeybind(defaultKey = Keyboard.KEY_NONE) public int dissolveKey = Keyboard.KEY_NONE; + @Expose + @ConfigOption(name = "Edge Cycle", desc = "Cycles the direction of the edge.") + @ConfigEditorKeybind(defaultKey = Keyboard.KEY_H) + public int edgeCycle = Keyboard.KEY_H; + @Expose @ConfigLink(owner = GraphConfig.class, field = "enabled") public Position infoDisplay = new Position(20, 20); diff --git a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt index 6a187e9012d4..927919917e63 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt @@ -28,6 +28,7 @@ import at.hannibal2.skyhanni.utils.OSUtils import at.hannibal2.skyhanni.utils.RaycastUtils import at.hannibal2.skyhanni.utils.RenderUtils.draw3DLineNea import at.hannibal2.skyhanni.utils.RenderUtils.drawDynamicText +import at.hannibal2.skyhanni.utils.RenderUtils.drawPyramid import at.hannibal2.skyhanni.utils.RenderUtils.drawWaypointFilled import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings import kotlinx.coroutines.runBlocking @@ -36,6 +37,7 @@ import net.minecraftforge.fml.common.eventhandler.EventPriority import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable import java.awt.Color +import kotlin.math.min @SkyHanniModule object GraphEditor { @@ -140,7 +142,10 @@ object GraphEditor { if (activeNode != null) { add("§eText: §6${KeyboardManager.getKeyName(config.textKey)}") if (dissolvePossible) add("§eDissolve: §6${KeyboardManager.getKeyName(config.dissolveKey)}") - if (selectedEdge != null) add("§eSplit: §6${KeyboardManager.getKeyName(config.splitKey)}") + if (selectedEdge != null) { + add("§eSplit: §6${KeyboardManager.getKeyName(config.splitKey)}") + add("§eCycle Direction: §6${KeyboardManager.getKeyName(config.edgeCycle)}") + } } } @@ -231,17 +236,45 @@ object GraphEditor { private fun LorenzRenderWorldEvent.drawEdge(edge: GraphingEdge) { if (edge.node1.position.distanceToPlayer() > config.maxNodeDistance) return + val color = when { + selectedEdge == edge -> edgeSelectedColor + edge in highlightedEdges -> edgeDijkstraColor + else -> edgeColor + } + this.draw3DLineNea( edge.node1.position.add(0.5, 0.5, 0.5), edge.node2.position.add(0.5, 0.5, 0.5), - when { - selectedEdge == edge -> edgeSelectedColor - edge in highlightedEdges -> edgeDijkstraColor - else -> edgeColor - }, + color, 7, !seeThroughBlocks, ) + if (edge.direction != EdgeDirection.BOTH) { + val lineVec = edge.node2.position - edge.node1.position + val center = edge.node1.position + lineVec / 2.0 + val quad1 = edge.node1.position + lineVec / 4.0 + val quad2 = edge.node1.position + lineVec * (3.0 / 4.0) + + val pyramidSize = lineVec.normalize() + .times(min(lineVec.length() / 10.0, 1.0)) * (if (edge.direction == EdgeDirection.ONE_TO_TWO) 1.0 else -1.0) + + val lineOffsetVec = LorenzVec(0.5, 0.5, 0.5) + + fun pyramidDraw( + pos: LorenzVec, + ) { + this.drawPyramid( + pos + lineOffsetVec + pyramidSize, + pos + lineOffsetVec, + pos.crossProduct(lineVec).normalize().times(pyramidSize.length() / 2.5) + pos + lineOffsetVec, + color, + ) + } + + pyramidDraw(center) + pyramidDraw(quad1) + pyramidDraw(quad2) + } } private fun GraphingNode.getNodeColor() = when (this) { @@ -262,7 +295,7 @@ object GraphEditor { private fun chatAtDisable() = ChatUtils.clickableChat( "Graph Editor is now inactive. §lClick to activate.", - GraphEditor::commandIn + GraphEditor::commandIn, ) private fun input() { @@ -398,16 +431,22 @@ object GraphEditor { inTutorialMode = !inTutorialMode ChatUtils.chat("Tutorial mode is now ${if (inTutorialMode) "active" else "inactive"}.") } - if (selectedEdge != null && config.splitKey.isKeyClicked()) { - val edge = selectedEdge ?: return - feedBackInTutorial("Split Edge into a Node and two edges.") - val middle = edge.node1.position.middle(edge.node2.position).roundLocationToBlock() - val node = GraphingNode(id++, middle) - nodes.add(node) - edges.remove(edge) - addEdge(node, edge.node1) - addEdge(node, edge.node2) - activeNode = node + val selectedEdge = selectedEdge + if (selectedEdge != null) { + if (config.splitKey.isKeyClicked()) { + feedBackInTutorial("Split Edge into a Node and two edges.") + val middle = selectedEdge.node1.position.middle(selectedEdge.node2.position).roundLocationToBlock() + val node = GraphingNode(id++, middle) + nodes.add(node) + edges.remove(selectedEdge) + addEdge(node, selectedEdge.node1) + addEdge(node, selectedEdge.node2) + activeNode = node + } + if (config.edgeCycle.isKeyClicked()) { + selectedEdge.cycleDirection(activeNode) + feedBackInTutorial("Cycled Direction to: ${selectedEdge.cycleText(activeNode)}") + } } if (dissolvePossible && config.dissolveKey.isKeyClicked()) { feedBackInTutorial("Dissolved the node, now it is gone.") @@ -538,11 +577,11 @@ object GraphEditor { node.name, node.tags.map { it.internalName - } + }, ) } val neighbours = GraphEditor.nodes.map { node -> - edges.filter { it.isInEdge(node) }.map { edge -> + edges.filter { it.isInEdge(node) && it.isValidDirectionFrom(node) }.map { edge -> val otherNode = if (node == edge.node1) edge.node2 else edge.node1 @@ -572,8 +611,16 @@ object GraphEditor { graph.map { node -> // TODO: Fix this to not use bang bangs @Suppress("MapGetWithNotNullAssertionOperator") - node.neighbours.map { GraphingEdge(translation[node]!!, translation[it.key]!!) } - }.flatten().distinct(), + node.neighbours.map { GraphingEdge(translation[node]!!, translation[it.key]!!, EdgeDirection.ONE_TO_TWO) } + }.flatten().groupingBy { it.hashCode() }.fold( + { key, element -> element }, + { key, accumulator, element -> + if ((element.node1 == accumulator.node1 && accumulator.direction != element.direction) || (element.node1 == accumulator.node2 && accumulator.direction == element.direction)) { + accumulator.direction = EdgeDirection.BOTH + } + accumulator + }, + ).values, ) id = nodes.lastOrNull()?.id?.plus(1) ?: 0 checkDissolve() @@ -598,11 +645,17 @@ object GraphEditor { val path = GraphUtils.findShortestPathAsGraph(current, goal) + if (path.isEmpty()) { + ChatUtils.chat("No Path found") + } + val inGraph = path.map { nodes[it.id] } highlightedNodes.addAll(inGraph) - val edge = edges.filter { highlightedNodes.contains(it.node1) && highlightedNodes.contains(it.node2) } - highlightedEdges.addAll(edge) + highlightedEdges.addAll( + highlightedNodes.zipWithNext { a, b -> edges.firstOrNull { it.isValidConnectionFromTo(a, b) } } + .filterNotNull(), + ) } private fun clear() { @@ -651,7 +704,7 @@ class GraphingNode( } } -private class GraphingEdge(val node1: GraphingNode, val node2: GraphingNode) { +private class GraphingEdge(val node1: GraphingNode, val node2: GraphingNode, var direction: EdgeDirection = EdgeDirection.BOTH) { fun isInEdge(node: GraphingNode?) = node1 == node || node2 == node @@ -678,4 +731,50 @@ private class GraphingEdge(val node1: GraphingNode, val node2: GraphingNode) { } return result } + + fun cycleDirection(standpoint: GraphingNode?) { + direction = if (standpoint != node2) { + when (direction) { + EdgeDirection.BOTH -> EdgeDirection.ONE_TO_TWO + EdgeDirection.ONE_TO_TWO -> EdgeDirection.TOW_TO_ONE + EdgeDirection.TOW_TO_ONE -> EdgeDirection.BOTH + } + } else { + when (direction) { + EdgeDirection.BOTH -> EdgeDirection.TOW_TO_ONE + EdgeDirection.TOW_TO_ONE -> EdgeDirection.ONE_TO_TWO + EdgeDirection.ONE_TO_TWO -> EdgeDirection.BOTH + } + } + } + + fun cycleText(standpoint: GraphingNode?) = when (direction) { + EdgeDirection.BOTH -> "Bidirectional" + EdgeDirection.ONE_TO_TWO -> if (standpoint != node1) { + "AwayFromYou" + } else { + "ToYou" + } + + EdgeDirection.TOW_TO_ONE -> if (standpoint != node1) { + "ToYou" + } else { + "AwayFromYou" + } + } + + fun isValidDirectionFrom(standpoint: GraphingNode?) = when (direction) { + EdgeDirection.BOTH -> true + EdgeDirection.ONE_TO_TWO -> standpoint == node1 + EdgeDirection.TOW_TO_ONE -> standpoint == node2 + } + + fun isValidConnectionFromTo(a: GraphingNode, b: GraphingNode): Boolean = + ((this.node1 == a && this.node2 == b) || (this.node1 == b && this.node2 == a)) && isValidDirectionFrom(a) +} + +private enum class EdgeDirection { + BOTH, + ONE_TO_TWO, + TOW_TO_ONE, } diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt index 1604b1362889..6e52fa8ae64f 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt @@ -83,6 +83,14 @@ data class LorenzVec( fun angleInDeg(other: LorenzVec) = Math.toDegrees(angleInRad(other)) + fun crossProduct(other: LorenzVec): LorenzVec = LorenzVec( + this.y * other.z - this.z * other.y, + this.z * other.x - this.x * other.z, + this.x * other.y - this.y * other.x, + ) + + fun scaledTo(other: LorenzVec) = this.normalize().times(other.length()) + fun normalize() = length().let { LorenzVec(x / it, y / it, z / it) } fun inverse() = LorenzVec(1.0 / x, 1.0 / y, 1.0 / z) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index 1f13c86f5b65..f64321dce2fc 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -4,6 +4,7 @@ import at.hannibal2.skyhanni.config.core.config.Position import at.hannibal2.skyhanni.data.GuiEditManager import at.hannibal2.skyhanni.data.GuiEditManager.getAbsX import at.hannibal2.skyhanni.data.GuiEditManager.getAbsY +import at.hannibal2.skyhanni.data.GuiEditManager.getDummySize import at.hannibal2.skyhanni.data.model.Graph import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.events.GuiRenderItemEvent @@ -19,11 +20,12 @@ import at.hannibal2.skyhanni.utils.ColorUtils.getFirstColorCode import at.hannibal2.skyhanni.utils.LorenzColor.Companion.toLorenzColor import at.hannibal2.skyhanni.utils.LorenzUtils.getCorners import at.hannibal2.skyhanni.utils.compat.EnchantmentsCompat -import at.hannibal2.skyhanni.utils.compat.GuiScreenUtils import at.hannibal2.skyhanni.utils.renderables.Renderable import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXAligned import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderYAligned import at.hannibal2.skyhanni.utils.shader.ShaderManager +import io.github.moulberry.notenoughupdates.util.Utils.getMouseX +import io.github.moulberry.notenoughupdates.util.Utils.getMouseY import io.github.notenoughupdates.moulconfig.internal.TextRenderUtils import net.minecraft.client.Minecraft import net.minecraft.client.gui.FontRenderer @@ -767,6 +769,82 @@ object RenderUtils { drawCylinderInWorld(color, location.x, location.y, location.z, radius, height, partialTicks) } + fun LorenzRenderWorldEvent.drawPyramid( + topPoint: LorenzVec, + baseCenterPoint: LorenzVec, + baseEdgePoint: LorenzVec, + color: Color, + depth: Boolean = true, + ) { + GlStateManager.enableBlend() + GlStateManager.disableLighting() + GlStateManager.tryBlendFuncSeparate(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0) + GlStateManager.disableTexture2D() + GlStateManager.disableCull() + GlStateManager.enableAlpha() + if (!depth) { + GL11.glDisable(GL11.GL_DEPTH_TEST) + GlStateManager.depthMask(false) + } + GlStateManager.pushMatrix() + + color.bindColor() + + val tessellator = Tessellator.getInstance() + val worldRenderer = tessellator.worldRenderer + worldRenderer.begin(GL11.GL_TRIANGLE_FAN, DefaultVertexFormats.POSITION) + val inverseView = getViewerPos(partialTicks) + RenderUtils.translate(inverseView.negated()) + + worldRenderer.pos(topPoint).endVertex() + + val corner1 = baseEdgePoint + + val cornerCenterVec = baseEdgePoint - baseCenterPoint + + val corner3 = baseCenterPoint - cornerCenterVec + + val baseTopVecNormalized = (topPoint - baseCenterPoint).normalize() + + val corner2 = baseTopVecNormalized.crossProduct(cornerCenterVec) + baseCenterPoint + val corner4 = cornerCenterVec.crossProduct(baseTopVecNormalized) + baseCenterPoint + + worldRenderer.pos(corner1).endVertex() + worldRenderer.pos(corner2).endVertex() + + worldRenderer.pos(corner2).endVertex() + worldRenderer.pos(corner3).endVertex() + + worldRenderer.pos(corner3).endVertex() + worldRenderer.pos(corner4).endVertex() + + worldRenderer.pos(corner4).endVertex() + worldRenderer.pos(corner1).endVertex() + + tessellator.draw() + + worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION) + + worldRenderer.pos(corner1).endVertex() + worldRenderer.pos(corner4).endVertex() + worldRenderer.pos(corner3).endVertex() + worldRenderer.pos(corner2).endVertex() + + + tessellator.draw() + + + GlStateManager.popMatrix() + GlStateManager.enableTexture2D() + GlStateManager.enableCull() + GlStateManager.disableBlend() + GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f) + if (!depth) { + GL11.glEnable(GL11.GL_DEPTH_TEST) + GlStateManager.depthMask(true) + } + } + // Todo: Gauge whether or not partialTicks is actually necessary, or if it can be removed @Suppress("UnusedParameter") fun drawCylinderInWorld( From 5ea3a85b7fbd03fba7c70960b654e2dbd985d919 Mon Sep 17 00:00:00 2001 From: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Date: Thu, 21 Nov 2024 18:08:21 +0100 Subject: [PATCH 2/9] fixed wrong imports --- src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt index f64321dce2fc..a6f92fb10932 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/RenderUtils.kt @@ -4,7 +4,6 @@ import at.hannibal2.skyhanni.config.core.config.Position import at.hannibal2.skyhanni.data.GuiEditManager import at.hannibal2.skyhanni.data.GuiEditManager.getAbsX import at.hannibal2.skyhanni.data.GuiEditManager.getAbsY -import at.hannibal2.skyhanni.data.GuiEditManager.getDummySize import at.hannibal2.skyhanni.data.model.Graph import at.hannibal2.skyhanni.events.GuiContainerEvent import at.hannibal2.skyhanni.events.GuiRenderItemEvent @@ -20,12 +19,11 @@ import at.hannibal2.skyhanni.utils.ColorUtils.getFirstColorCode import at.hannibal2.skyhanni.utils.LorenzColor.Companion.toLorenzColor import at.hannibal2.skyhanni.utils.LorenzUtils.getCorners import at.hannibal2.skyhanni.utils.compat.EnchantmentsCompat +import at.hannibal2.skyhanni.utils.compat.GuiScreenUtils import at.hannibal2.skyhanni.utils.renderables.Renderable import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXAligned import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderYAligned import at.hannibal2.skyhanni.utils.shader.ShaderManager -import io.github.moulberry.notenoughupdates.util.Utils.getMouseX -import io.github.moulberry.notenoughupdates.util.Utils.getMouseY import io.github.notenoughupdates.moulconfig.internal.TextRenderUtils import net.minecraft.client.Minecraft import net.minecraft.client.gui.FontRenderer @@ -1815,7 +1813,6 @@ object RenderUtils { GlStateManager.enableDepth() } - /** * Method to draw a rounded textured rect. * From 8bf772c7f4c58f5a19d53146fab248c1e858f7ba Mon Sep 17 00:00:00 2001 From: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Date: Thu, 21 Nov 2024 18:16:56 +0100 Subject: [PATCH 3/9] detekt --- .../java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt index 927919917e63..54de3b66ffc9 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt @@ -615,7 +615,10 @@ object GraphEditor { }.flatten().groupingBy { it.hashCode() }.fold( { key, element -> element }, { key, accumulator, element -> - if ((element.node1 == accumulator.node1 && accumulator.direction != element.direction) || (element.node1 == accumulator.node2 && accumulator.direction == element.direction)) { + if ( + (element.node1 == accumulator.node1 && accumulator.direction != element.direction) || + (element.node1 == accumulator.node2 && accumulator.direction == element.direction) + ) { accumulator.direction = EdgeDirection.BOTH } accumulator From 6706b8dd466f82d15c6e1d5643fd07f46c46e8db Mon Sep 17 00:00:00 2001 From: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Date: Sat, 23 Nov 2024 02:14:12 +0100 Subject: [PATCH 4/9] fix import issue --- .../skyhanni/test/graph/GraphEditor.kt | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt index 54de3b66ffc9..99e879c3ba8d 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt @@ -607,24 +607,26 @@ object GraphEditor { }, ) val translation = graph.mapIndexed { index, node -> node to nodes[index] }.toMap() - edges.addAll( - graph.map { node -> - // TODO: Fix this to not use bang bangs - @Suppress("MapGetWithNotNullAssertionOperator") - node.neighbours.map { GraphingEdge(translation[node]!!, translation[it.key]!!, EdgeDirection.ONE_TO_TWO) } - }.flatten().groupingBy { it.hashCode() }.fold( - { key, element -> element }, - { key, accumulator, element -> - if ( - (element.node1 == accumulator.node1 && accumulator.direction != element.direction) || - (element.node1 == accumulator.node2 && accumulator.direction == element.direction) - ) { - accumulator.direction = EdgeDirection.BOTH - } - accumulator - }, - ).values, + + val neighbors = graph.map { node -> + // TODO: Fix this to not use bang bangs + @Suppress("MapGetWithNotNullAssertionOperator") + node.neighbours.map { GraphingEdge(translation[node]!!, translation[it.key]!!, EdgeDirection.ONE_TO_TWO) } + }.flatten() + + val reduced = neighbors.groupingBy { it }.reduce( + { _, accumulator, element -> + if ( + (element.node1 == accumulator.node1 && accumulator.direction != element.direction) || + (element.node1 == accumulator.node2 && accumulator.direction == element.direction) + ) { + accumulator.direction = EdgeDirection.BOTH + } + accumulator + }, ) + + edges.addAll(reduced.values) id = nodes.lastOrNull()?.id?.plus(1) ?: 0 checkDissolve() selectedEdge = findEdgeBetweenActiveAndClosest() @@ -671,14 +673,16 @@ object GraphEditor { ghostPosition = null } - private fun prune() { // TODO fix - val hasNeighbours = nodes.associateWith { false }.toMutableMap() - edges.forEach { - hasNeighbours[it.node1] = true - hasNeighbours[it.node2] = true + private fun prune() {} // TODO fix + /* + val hasNeighbours = nodes.associateWith { false }.toMutableMap() + edges.forEach { + hasNeighbours[it.node1] = true + hasNeighbours[it.node2] = true + } + nodes.removeIf { hasNeighbours[it] == false } } - nodes.removeIf { hasNeighbours[it] == false } - } + */ fun LorenzVec.distanceSqToPlayer(): Double = ghostPosition?.let { distanceSq(it) } ?: distanceSq(playerLocation()) } From da08251ece06261597fbcbec394a17f60e536a94 Mon Sep 17 00:00:00 2001 From: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Date: Sat, 23 Nov 2024 02:25:13 +0100 Subject: [PATCH 5/9] prune no more --- .../at/hannibal2/skyhanni/test/graph/GraphEditor.kt | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt index 99e879c3ba8d..66fe1aeaf629 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt @@ -566,9 +566,7 @@ object GraphEditor { edges.add(edge) } else false - /** Has a side effect on the graphing graph, since it runs [prune] on the graphing graph*/ private fun compileGraph(): Graph { - prune() val indexedTable = nodes.mapIndexed { index, node -> node.id to index }.toMap() val nodes = nodes.mapIndexed { index, node -> GraphNode( @@ -673,17 +671,6 @@ object GraphEditor { ghostPosition = null } - private fun prune() {} // TODO fix - /* - val hasNeighbours = nodes.associateWith { false }.toMutableMap() - edges.forEach { - hasNeighbours[it.node1] = true - hasNeighbours[it.node2] = true - } - nodes.removeIf { hasNeighbours[it] == false } - } - */ - fun LorenzVec.distanceSqToPlayer(): Double = ghostPosition?.let { distanceSq(it) } ?: distanceSq(playerLocation()) } From c9f4962c50a6c0a0ad4d7398907a707db2f72650 Mon Sep 17 00:00:00 2001 From: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Date: Sun, 1 Dec 2024 17:43:19 +0100 Subject: [PATCH 6/9] added split key support --- .../skyhanni/test/graph/GraphEditor.kt | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt index 66fe1aeaf629..85c8256e6525 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt @@ -439,8 +439,8 @@ object GraphEditor { val node = GraphingNode(id++, middle) nodes.add(node) edges.remove(selectedEdge) - addEdge(node, selectedEdge.node1) - addEdge(node, selectedEdge.node2) + addEdge(selectedEdge.node1, node, selectedEdge.direction) + addEdge(node, selectedEdge.node2, selectedEdge.direction) activeNode = node } if (config.edgeCycle.isKeyClicked()) { @@ -557,14 +557,15 @@ object GraphEditor { ).let { e -> edges.indexOfFirst { it == e }.takeIf { it != -1 } } else null - private fun addEdge(node1: GraphingNode?, node2: GraphingNode?) = if (node1 != null && node2 != null && node1 != node2) { - val edge = GraphingEdge(node1, node2) - if (edge.isInEdge(activeNode)) { - checkDissolve() - selectedEdge = findEdgeBetweenActiveAndClosest() - } - edges.add(edge) - } else false + private fun addEdge(node1: GraphingNode?, node2: GraphingNode?, direction: EdgeDirection = EdgeDirection.BOTH) = + if (node1 != null && node2 != null && node1 != node2) { + val edge = GraphingEdge(node1, node2, direction) + if (edge.isInEdge(activeNode)) { + checkDissolve() + selectedEdge = findEdgeBetweenActiveAndClosest() + } + edges.add(edge) + } else false private fun compileGraph(): Graph { val indexedTable = nodes.mapIndexed { index, node -> node.id to index }.toMap() From 473bdaeb4489d7b151497a4ec8a1619be0433ed5 Mon Sep 17 00:00:00 2001 From: hannibal2 <24389977+hannibal00212@users.noreply.github.com> Date: Sun, 1 Dec 2024 18:09:03 +0100 Subject: [PATCH 7/9] code cleanup --- .../skyhanni/test/graph/GraphEditor.kt | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt index 85c8256e6525..257f3fa5fa30 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt @@ -250,17 +250,22 @@ object GraphEditor { !seeThroughBlocks, ) if (edge.direction != EdgeDirection.BOTH) { - val lineVec = edge.node2.position - edge.node1.position - val center = edge.node1.position + lineVec / 2.0 - val quad1 = edge.node1.position + lineVec / 4.0 - val quad2 = edge.node1.position + lineVec * (3.0 / 4.0) + drawDirection(edge, color) + } + } - val pyramidSize = lineVec.normalize() - .times(min(lineVec.length() / 10.0, 1.0)) * (if (edge.direction == EdgeDirection.ONE_TO_TWO) 1.0 else -1.0) + private fun LorenzRenderWorldEvent.drawDirection(edge: GraphingEdge, color: Color) { + val lineVec = edge.node2.position - edge.node1.position + val center = edge.node1.position + lineVec / 2.0 + val quad1 = edge.node1.position + lineVec / 4.0 + val quad2 = edge.node1.position + lineVec * (3.0 / 4.0) - val lineOffsetVec = LorenzVec(0.5, 0.5, 0.5) + val pyramidSize = lineVec.normalize() + .times(min(lineVec.length() / 10.0, 1.0)) * (if (edge.direction == EdgeDirection.ONE_TO_TWO) 1.0 else -1.0) - fun pyramidDraw( + val lineOffsetVec = LorenzVec(0.5, 0.5, 0.5) + + fun pyramidDraw( pos: LorenzVec, ) { this.drawPyramid( @@ -271,10 +276,9 @@ object GraphEditor { ) } - pyramidDraw(center) - pyramidDraw(quad1) - pyramidDraw(quad2) - } + pyramidDraw(center) + pyramidDraw(quad1) + pyramidDraw(quad2) } private fun GraphingNode.getNodeColor() = when (this) { From f606b2cc0ea2f6d3b757ca8d1ad7fa2c6eec302a Mon Sep 17 00:00:00 2001 From: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Date: Sun, 1 Dec 2024 18:09:43 +0100 Subject: [PATCH 8/9] added dissolve support --- .../at/hannibal2/skyhanni/test/graph/GraphEditor.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt index 85c8256e6525..65bcd2cc9c32 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt @@ -458,7 +458,16 @@ object GraphEditor { edges.removeAll(edgePair) nodes.remove(activeNode) activeNode = null - addEdge(neighbors1, neighbors2) + val direction = if (edge1.direction == EdgeDirection.BOTH || edge2.direction == EdgeDirection.BOTH) EdgeDirection.BOTH else { + val a = edge1.node1 == edge2.node1 + val b = edge1.direction == edge2.direction + if ((a && b) || (!a && !b)) { + if (edge1.isValidDirectionFrom(neighbors1)) EdgeDirection.ONE_TO_TWO else EdgeDirection.TOW_TO_ONE + } else { + EdgeDirection.BOTH + } + } + addEdge(neighbors1, neighbors2, direction) } } From c572ce55ee4ef31597a6af545275976204af82f9 Mon Sep 17 00:00:00 2001 From: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com> Date: Sun, 1 Dec 2024 18:41:40 +0100 Subject: [PATCH 9/9] fixed dissolve support --- .../skyhanni/test/graph/GraphEditor.kt | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt index e76e3f11a199..d9da76825420 100644 --- a/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt +++ b/src/main/java/at/hannibal2/skyhanni/test/graph/GraphEditor.kt @@ -266,15 +266,15 @@ object GraphEditor { val lineOffsetVec = LorenzVec(0.5, 0.5, 0.5) fun pyramidDraw( - pos: LorenzVec, - ) { - this.drawPyramid( - pos + lineOffsetVec + pyramidSize, - pos + lineOffsetVec, - pos.crossProduct(lineVec).normalize().times(pyramidSize.length() / 2.5) + pos + lineOffsetVec, - color, - ) - } + pos: LorenzVec, + ) { + this.drawPyramid( + pos + lineOffsetVec + pyramidSize, + pos + lineOffsetVec, + pos.crossProduct(lineVec).normalize().times(pyramidSize.length() / 2.5) + pos + lineOffsetVec, + color, + ) + } pyramidDraw(center) pyramidDraw(quad1) @@ -459,18 +459,23 @@ object GraphEditor { val edge2 = edgePair[1] val neighbors1 = if (edge1.node1 == activeNode) edge1.node2 else edge1.node1 val neighbors2 = if (edge2.node1 == activeNode) edge2.node2 else edge2.node1 + val direction = + if (edge1.direction == EdgeDirection.BOTH || edge2.direction == EdgeDirection.BOTH) EdgeDirection.BOTH else when { + edge1.isValidConnectionFromTo(neighbors1, activeNode) && edge2.isValidConnectionFromTo( + activeNode, + neighbors2, + ) -> EdgeDirection.ONE_TO_TWO + + edge1.isValidConnectionFromTo(activeNode, neighbors1) && edge2.isValidConnectionFromTo( + neighbors2, + activeNode, + ) -> EdgeDirection.TOW_TO_ONE + + else -> EdgeDirection.BOTH + } edges.removeAll(edgePair) nodes.remove(activeNode) activeNode = null - val direction = if (edge1.direction == EdgeDirection.BOTH || edge2.direction == EdgeDirection.BOTH) EdgeDirection.BOTH else { - val a = edge1.node1 == edge2.node1 - val b = edge1.direction == edge2.direction - if ((a && b) || (!a && !b)) { - if (edge1.isValidDirectionFrom(neighbors1)) EdgeDirection.ONE_TO_TWO else EdgeDirection.TOW_TO_ONE - } else { - EdgeDirection.BOTH - } - } addEdge(neighbors1, neighbors2, direction) } } @@ -777,7 +782,7 @@ private class GraphingEdge(val node1: GraphingNode, val node2: GraphingNode, var EdgeDirection.TOW_TO_ONE -> standpoint == node2 } - fun isValidConnectionFromTo(a: GraphingNode, b: GraphingNode): Boolean = + fun isValidConnectionFromTo(a: GraphingNode?, b: GraphingNode?): Boolean = ((this.node1 == a && this.node2 == b) || (this.node1 == b && this.node2 == a)) && isValidDirectionFrom(a) }