Skip to content

Instantly share code, notes, and snippets.

@derkalaender
Last active December 31, 2019 17:37
Show Gist options
  • Save derkalaender/8edf5a1448e50b24bd800e51094485da to your computer and use it in GitHub Desktop.
Save derkalaender/8edf5a1448e50b24bd800e51094485da to your computer and use it in GitHub Desktop.
Simple to use builder for making Minecraft/Forge VoxelShapes
private val INSIDE_SHAPE: VoxelShape by lazy {
voxelShape { cube(2 by 2 by 2, 14 by 14 by 14) }
}
private val OUTSIDE_SHAPE: VoxelShape by lazy {
voxelShape {
shape { fullCube }
-voxelShape {
cube(2 by 2 by 0, 14 by 14 by 16)
+voxelShape { cube(2 by 0 by 2, 14 by 16 by 14) }
+voxelShape { cube(0 by 2 by 2, 16 by 14 by 14) }
}
}
}
private val COMBINED_SHAPE: VoxelShape by lazy {
INSIDE_SHAPE.add(OUTSIDE_SHAPE)
}
package de.derkalaender.frame.util
import net.minecraft.block.Block
import net.minecraft.util.math.shapes.IBooleanFunction
import net.minecraft.util.math.shapes.VoxelShape
import net.minecraft.util.math.shapes.VoxelShapes
fun VoxelShape.add(other: VoxelShape, vararg more: VoxelShape): VoxelShape = VoxelShapes.or(this, other, *more)
fun VoxelShape.subtract(other: VoxelShape): VoxelShape = VoxelShapes.combineAndSimplify(this, other, IBooleanFunction.ONLY_FIRST)
@DslMarker
annotation class VoxelShapeDsl
@VoxelShapeDsl
class VoxelShapeBuilder {
val fullCube: VoxelShape = VoxelShapes.fullCube()
val empty: VoxelShape = VoxelShapes.empty()
private var voxelShape: VoxelShape = empty
fun cube(builder: CubeBuilder.() -> Unit) {
voxelShape = CubeBuilder().apply(builder).build().asVoxelShape()
}
fun cube(position: Triple<Double, Double, Double>, size: Triple<Double, Double, Double>) {
cube {
position { position }
size { size }
}
}
fun shape(shape: () -> VoxelShape) {
voxelShape = shape()
}
operator fun VoxelShape.unaryPlus() {
voxelShape.add(this)
}
operator fun VoxelShape.unaryMinus() {
voxelShape.subtract(this)
}
fun build() = voxelShape
infix fun Number.by(o: Number) = Pair(this.toDouble(), o.toDouble())
infix fun Pair<Double, Double>.by(o: Number) = Triple(this.first, this.second, o.toDouble())
}
class Cube(
val position: Triple<Double, Double, Double>,
val size: Triple<Double, Double, Double>
) {
fun asVoxelShape(): VoxelShape = Block.makeCuboidShape(
position.first, position.second, position.third,
size.first, size.second, size.third
)
}
@VoxelShapeDsl
class CubeBuilder {
private var position = Triple(0.0, 0.0, 0.0)
private var size = Triple(0.0, 0.0, 0.0)
fun position(position: () -> Triple<Double, Double, Double>) {
this.position = position()
}
fun size(size: () -> Triple<Double, Double, Double>) {
this.size = size()
}
fun build() = Cube(position, size)
}
fun voxelShape(builder: VoxelShapeBuilder.() -> Unit) = VoxelShapeBuilder().apply(builder).build()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment