|
|
@ -7,7 +7,7 @@ import me.eater.threedom.utils.joml.compareTo
|
|
|
|
import me.eater.threedom.utils.joml.getTranslation
|
|
|
|
import me.eater.threedom.utils.joml.getTranslation
|
|
|
|
import org.joml.Vector3dc
|
|
|
|
import org.joml.Vector3dc
|
|
|
|
|
|
|
|
|
|
|
|
class KDTree(private val document: IDocument, private val root: Node = Node(Vector3d(0, 0, 0))) {
|
|
|
|
class KDTree(private val document: IDocument, private var root: Node = Node(Vector3d(0, 0, 0))) {
|
|
|
|
private val nodeLocMap = mutableMapOf<Long, Vector3dc>()
|
|
|
|
private val nodeLocMap = mutableMapOf<Long, Vector3dc>()
|
|
|
|
|
|
|
|
|
|
|
|
data class Node(
|
|
|
|
data class Node(
|
|
|
@ -89,10 +89,10 @@ class KDTree(private val document: IDocument, private val root: Node = Node(Vect
|
|
|
|
val sorted = nodes.keys.sortedBy { it[axis] }
|
|
|
|
val sorted = nodes.keys.sortedBy { it[axis] }
|
|
|
|
val median = sorted.size / 2
|
|
|
|
val median = sorted.size / 2
|
|
|
|
val selected = sorted[median]
|
|
|
|
val selected = sorted[median]
|
|
|
|
val left = sorted.slice(0..median).toSet().takeIf { it.isNotEmpty() }?.let {
|
|
|
|
val left = sorted.slice(0 until median).toSet().takeIf { it.isNotEmpty() }?.let {
|
|
|
|
nodes.filterKeys(it::contains)
|
|
|
|
nodes.filterKeys(it::contains)
|
|
|
|
}?.let { create(it, depth + 1) }
|
|
|
|
}?.let { create(it, depth + 1) }
|
|
|
|
val right = sorted.slice(median + 1..sorted.size).toSet().takeIf { it.isNotEmpty() }?.let {
|
|
|
|
val right = sorted.slice(median + 1 until sorted.size).toSet().takeIf { it.isNotEmpty() }?.let {
|
|
|
|
nodes.filterKeys(it::contains)
|
|
|
|
nodes.filterKeys(it::contains)
|
|
|
|
}?.let { create(it, depth + 1) }
|
|
|
|
}?.let { create(it, depth + 1) }
|
|
|
|
return Node(selected, nodes[selected]?.toMutableSet() ?: mutableSetOf(), depth, left, right)
|
|
|
|
return Node(selected, nodes[selected]?.toMutableSet() ?: mutableSetOf(), depth, left, right)
|
|
|
@ -119,4 +119,8 @@ class KDTree(private val document: IDocument, private val root: Node = Node(Vect
|
|
|
|
nodeLocMap[node.nodeId]?.let { root.remove(it, node.nodeId) }
|
|
|
|
nodeLocMap[node.nodeId]?.let { root.remove(it, node.nodeId) }
|
|
|
|
add(node)
|
|
|
|
add(node)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fun rebalance() {
|
|
|
|
|
|
|
|
root = Node.create(nodeLocMap.entries.groupBy({ it.value }) { it.key })
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|