-
Notifications
You must be signed in to change notification settings - Fork 1
Rotating and Flipping Shapes
Directional blocks are the reason VoxLib exists in the first place. Build the shape once in one direction, then derive the other facings instead of maintaining four nearly identical copies.
VoxLib provides six transformations on VoxelShape. They return new shapes, cache repeated work, and never mutate the input.
| Function | Effect |
|---|---|
rotateLeft() |
90 degrees counterclockwise around the Y axis |
rotateRight() |
90 degrees clockwise around the Y axis |
flipHorizontal() |
180 degrees around the Y axis |
flipVertical() |
Mirrors Y coordinates, so top and bottom swap |
flipZ() |
Mirrors Z coordinates, so north and south swap |
rotate(transformation) |
Applies any VoxelShapeTransformation from the table above |
flip() exists as an alias for flipHorizontal(). It was the original name in 1.1.0 and remains available for compatibility. The general rotate extension is named rotateWithTransformation in Java.
import com.github.mystery2099.voxlib.rotation.VoxelRotation.rotateLeft
import com.github.mystery2099.voxlib.rotation.VoxelRotation.rotateRight
import com.github.mystery2099.voxlib.rotation.VoxelRotation.flipHorizontal
import com.github.mystery2099.voxlib.rotation.VoxelRotation.flipVertical
import com.github.mystery2099.voxlib.rotation.VoxelRotation.flipZ
import com.github.mystery2099.voxlib.rotation.VoxelShapeTransformation
val eastFacing = northFacing.rotateRight()
val southFacing = northFacing.flipHorizontal()
val westFacing = northFacing.rotateLeft()
val upsideDown = northFacing.flipVertical()
val mirrored = northFacing.flipZ()A common pattern is one master shape for a north-facing block, with all other facings derived from it. Using a shape whose "front" points north (negative Z):
| Target facing | Derivation |
|---|---|
NORTH |
original shape |
EAST |
rotateRight() |
SOUTH |
flipHorizontal() |
WEST |
rotateLeft() |
fun shapeForDirection(base: VoxelShape, facing: Direction): VoxelShape = when (facing) {
Direction.NORTH -> base
Direction.EAST -> base.rotateRight()
Direction.SOUTH -> base.flipHorizontal()
Direction.WEST -> base.rotateLeft()
else -> base
}The table assumes your original shape points north. rotateRight turns it clockwise when viewed from above, so its front ends up pointing east. If your original faces another axis, adjust the mapping to match. When a rotation looks backwards, the debug overlay is usually faster than trying to reason it out from coordinates.
flipVertical and flipZ are reflections, not rotations. They are useful for top/bottom and north/south variants, such as an upside-down slab or a shelf mounted on the opposite face.
- An empty shape stays empty.
-
Shapes.block()(the full cube) returns itself unchanged for every transformation.
Both checks skip the cache entirely.
Repeating the same transformation on the same shape instance is cheap after the first call. Rebuilding the source shape each time defeats that benefit because the cache keys use object identity. Caching and performance explains the exact behavior and limits.
Extension functions inside the Kotlin VoxelRotation object compile to instance methods with the receiver as the first parameter. Java accesses the singleton through INSTANCE:
import com.github.mystery2099.voxlib.rotation.VoxelRotation;
import com.github.mystery2099.voxlib.rotation.VoxelShapeTransformation;
VoxelRotation rotations = VoxelRotation.INSTANCE;
VoxelShape eastFacing = rotations.rotateRight(northFacing);
VoxelShape southFacing = rotations.flipHorizontal(northFacing);
VoxelShape transformed = rotations.rotateWithTransformation(
northFacing,
VoxelShapeTransformation.ROTATE_LEFT
);