<div>Dear list.</div><div><br></div><div>The code below is my latest study in non-euclidean architecture. Here I'm building a tower with a roof. The walls of the tower rise up perpendicular to the surface it's on. This isn't at all unusual, of course. You'll say that the walls of your own house do the same. However, were your house build on a sphere that would mean that the floor of your attic would have a larger surface than the floor on ground level. Good thing we don't actually live on a sphere in reality; it would get very confusing very quickly. </div>
<div><br></div><div>The main trick here is that when we have a spot on a sphere we can move straight "up" by simply multiplying the location vector of that spot. That does mean we need to build from a perspective (the centre of the world) that's quite far away from the model, hence the jumping up and down states and doing some operations based on matrices instead of from the state and regular transforms. By getting the location from a matrix I get rid of the rotation element of the local state.</div>
<div><br></div><div>Enjoy (zoom out for a bit as the camera starts out at the origin which is inside of the sphere)</div><div><br></div><div>Yours,</div><div>Kas.</div><div><br></div><div><br></div><div>(clear-colour (vector 0 0 1))</div>
<div>(clear)</div><div><br></div><div>(define diam 10)</div><div><br></div><div>(with-state</div><div>    (colour (vector 0 1 0))</div><div>    (scale diam)</div><div>    (build-sphere 20 20))</div><div><br></div><div>(define (loc-from-mat m)</div>
<div>    (vector</div><div>        (vector-ref m 12)</div><div>        (vector-ref m 13)</div><div>        (vector-ref m 14)))</div><div><br></div><div>(define (above spot height)</div><div>    (let ((loc (loc-from-mat spot)))</div>
<div>        (vadd loc (vmul (vnormalise loc) height))))</div><div><br></div><div>(define (build-block  x y z)</div><div>    (with-state</div><div>        (let ((origin (get-transform)))</div><div>            (let((ground_corners (list </div>
<div>                    (mmul origin (mtranslate (vector (/ x -2) (/ y -2) 0 )))</div><div>                    (mmul origin (mtranslate (vector (/ x  2) (/ y -2) 0 )))</div><div>                    (mmul origin (mtranslate (vector (/ x  2) (/ y  2) 0 )))</div>
<div>                    (mmul origin (mtranslate (vector (/ x -2) (/ y  2) 0 ))))))</div><div>                (identity)</div><div>                (with-primitive (build-polygons 16 'quad-list)</div><div>                    (for ((x (in-range 0 4)))</div>
<div>                        (pdata-set! "p" (* x 4)        (loc-from-mat (list-ref ground_corners x)))</div><div>                        (pdata-set! "p" ( + (* x 4) 1) (loc-from-mat (list-ref ground_corners (modulo (+ x 1) 4))))</div>
<div>                        (pdata-set! "p" ( + (* x 4) 3) (above (list-ref ground_corners x) z))</div><div>                        (pdata-set! "p" ( + (* x 4) 2) (above (list-ref ground_corners (modulo (+ x 1) 4))z)))</div>
<div>                        (recalc-normals 0.5))))))</div><div><br></div><div>(define (build-roof-duo x y z build-height roof-col)</div><div>    (with-state</div><div>        (let ((origin (get-transform)))</div><div>            (let((ground_corners (list </div>
<div>                    (mmul origin (mtranslate (vector (/ x -2) (/ y -2) 0 )))</div><div>                    (mmul origin (mtranslate (vector (/ x  2) (/ y -2) 0 )))</div><div>                    (mmul origin (mtranslate (vector (/ x  2) (/ y  2) 0 )))</div>
<div>                    (mmul origin (mtranslate (vector (/ x -2) (/ y  2) 0 )))</div><div><br></div><div>                    (mmul origin (mtranslate (vector 0        (/ y -2) 0 )))</div><div>                    (mmul origin (mtranslate (vector 0        (/ y  2) 0 ))))))</div>
<div>            (identity)</div><div>        (with-primitive (build-polygons 8 'quad-list)</div><div>            (pdata-set! "p" 0 (above (list-ref ground_corners 0) build-height))</div><div>            (pdata-set! "p" 1 (above (list-ref ground_corners 4) (+ build-height z)))</div>
<div>            (pdata-set! "p" 2 (above (list-ref ground_corners 5) (+ build-height z)))</div><div>            (pdata-set! "p" 3 (above (list-ref ground_corners 3) build-height))</div><div>            </div>
<div>            (pdata-set! "p" 4 (above (list-ref ground_corners 4) (+ build-height z)))</div><div>            (pdata-set! "p" 5 (above (list-ref ground_corners 1) build-height ))</div><div>            (pdata-set! "p" 6 (above (list-ref ground_corners 2) build-height ))</div>
<div>            (pdata-set! "p" 7 (above (list-ref ground_corners 5) (+ build-height z)))</div><div>            </div><div>            (colour roof-col)</div><div>            (recalc-normals .5)</div><div>            )</div>
<div>        </div><div>        (with-primitive (build-polygons 6 'triangle-list)</div><div>            (pdata-set! "p" 0 (above (list-ref ground_corners 0) build-height))</div><div>            (pdata-set! "p" 1 (above (list-ref ground_corners 1) build-height))</div>
<div>            (pdata-set! "p" 2 (above (list-ref ground_corners 4) (+ build-height z)))</div><div>            (pdata-set! "p" 3 (above (list-ref ground_corners 2) build-height))</div><div>            (pdata-set! "p" 4 (above (list-ref ground_corners 3) build-height))</div>
<div>            (pdata-set! "p" 5 (above (list-ref ground_corners 5) (+ build-height z)))            </div><div>            (recalc-normals .5)</div><div>            )))))</div><div><br></div><div>(rotate (vector 45 45 0))</div>
<div>(translate (vector 0 0 (- diam .1)))</div><div>(build-block  1 1 3)</div><div><br></div><div>(build-roof-duo 1 1 .5 3 (vector 1 0 0))</div>