Optimisation is a game where you write more code in order to do less. In Al Jazari 2 doing less means drawing less blocks. Contiguous blocks of the same type are already automatically collapsed into single larger ones with the Octree – but if we can figure out which blocks are completely surrounded by other blocks, we can save more time by not building or drawing them either.
Here is a large sphere – clipped by the world volume, showing a slice through the internal block structure:
The next version has all internal blocks removed, in this case shaving 10% off the total primitives built and drawn:
The gaps in the sphere from the clipping allow us to look inside at how the octree has optimised the structure. The gain is higher in a more normal Minecraft set up with a reasonably flat floor covering a large amount of blocks. Here is the code involved, built on top of a functional library I’m building up on to manipulate this kind of data. It maps over each Octree leaf checking all the blocks it touches on each of its six sides, taking into account that the size of the leaf block may be bigger than one.
(define (octree-check-edge f o pos size) (define (do-x x y) (cond ((eq? x -1) #f) ((octree-leaf-empty? (octree-ref o (vadd pos (f x y)))) #t) (else (do-x (- x 1) y)))) (define (do-y y) (cond ((eq? y -1) #f) ((do-x size y) #t) (else (do-y (- y 1))))) (do-y size)) (define (octree-is-visible? o pos size) (or (octree-check-edge (lambda (x y) (vector size x y)) o pos size) (octree-check-edge (lambda (x y) (vector -1 x y)) o pos size) (octree-check-edge (lambda (x y) (vector x size y)) o pos size) (octree-check-edge (lambda (x y) (vector x -1 y)) o pos size) (octree-check-edge (lambda (x y) (vector x y size)) o pos size) (octree-check-edge (lambda (x y) (vector x y -1)) o pos size))) (define (octree-calc-viz o) (octree-map (lambda (v pos size depth) (octree-leaf (octree-is-visible? o pos size) (octree-leaf-value v))) o))