func (p Pos) Neighbours(f func(neighbour Pos)) {
	if p.OutOfBounds() {
		return
	}
	p[0]++
	f(p)
	p[0] -= 2
	f(p)
	p[0]++
	p[1]++
	if p[1] <= MaxY {
		f(p)
	}
	p[1] -= 2
	if p[1] >= MinY {
		f(p)
	}
	p[1]++
	p[2]++
	f(p)
	p[2] -= 2
	f(p)
}
Neighbours calls the function passed for each of the block position's neighbours. If the Y value is out of
bounds, the function will not be called for that position.
package cube
import (
	"github.com/go-gl/mathgl/mgl64"
	"math"
)
const (
	MaxY = 255
	MinY = 0
)
type Pos [3]int
func (p Pos) X() int {
	return p[0]
}
func (p Pos) Y() int {
	return p[1]
}
func (p Pos) Z() int {
	return p[2]
}
func (p Pos) OutOfBounds() bool {
	y := p[1]
	return y > MaxY || y < MinY
}
func (p Pos) Add(pos Pos) Pos {
	return Pos{p[0] + pos[0], p[1] + pos[1], p[2] + pos[2]}
}
func (p Pos) Subtract(pos Pos) Pos {
	return Pos{p[0] - pos[0], p[1] - pos[1], p[2] - pos[2]}
}
func (p Pos) Vec3() mgl64.Vec3 {
	return mgl64.Vec3{float64(p[0]), float64(p[1]), float64(p[2])}
}
func (p Pos) Vec3Middle() mgl64.Vec3 {
	return mgl64.Vec3{float64(p[0]) + 0.5, float64(p[1]), float64(p[2]) + 0.5}
}
func (p Pos) Vec3Centre() mgl64.Vec3 {
	return mgl64.Vec3{float64(p[0]) + 0.5, float64(p[1]) + 0.5, float64(p[2]) + 0.5}
}
func (p Pos) Side(face Face) Pos {
	switch face {
	case FaceUp:
		p[1]++
	case FaceDown:
		p[1]--
	case FaceNorth:
		p[2]--
	case FaceSouth:
		p[2]++
	case FaceWest:
		p[0]--
	case FaceEast:
		p[0]++
	}
	return p
}
func (p Pos) Face(other Pos) Face {
	switch other {
	case p.Add(Pos{0, 1}):
		return FaceUp
	case p.Add(Pos{0, -1}):
		return FaceDown
	case p.Add(Pos{0, 0, -1}):
		return FaceNorth
	case p.Add(Pos{0, 0, 1}):
		return FaceSouth
	case p.Add(Pos{-1, 0, 0}):
		return FaceWest
	case p.Add(Pos{1, 0, 0}):
		return FaceEast
	}
	return FaceUp
}