(define (make-AABB bounding-box)
  (let
    ((l ((bounding-box 'get-lower-extent)))
     (u ((bounding-box 'get-upper-extent)))
     (o '()))
    (let
      ((lx ((l 'get-x)))
       (ly ((l 'get-y)))
       (lz ((l 'get-z)))
       (ux ((u 'get-x)))
       (uy ((u 'get-y)))
       (uz ((u 'get-z)))
       (ox 0.0)
       (oy 0.0)
       (oz 0.0)
       (xy 0.0)
       (yx 0.0)
       (zy 0.0)
       (yz 0.0)
       (xz 0.0)
       (zx 0.0)
       (jbyi 0.0)
       (ibyj 0.0)
       (jbyk 0.0)
       (kbyj 0.0)
       (kbyi 0.0)
       (ibyk 0.0))
      (let*
        (
        (mmm (lambda ()
          (or
            (< ox lx) (< oy ly) (< oz lz)
            (> (+ (- (* jbyi lx) uy) xy) 0.0)
            (> (+ (- (* ibyj ly) ux) yx) 0.0)
            (> (+ (- (* jbyk lz) uy) zy) 0.0)
            (> (+ (- (* kbyj ly) uz) yz) 0.0)
            (> (+ (- (* kbyi lx) uz) xz) 0.0)
            (> (+ (- (* ibyk lz) ux) zx) 0.0))))
        (mmp (lambda ()
          (or
            (< ox lx) (< oy ly) (> oz uz)
            (> (+ (- (* jbyi lx) uy) xy) 0.0)
            (> (+ (- (* ibyj ly) ux) yx) 0.0)
            (> (+ (- (* jbyk uz) uy) zy) 0.0)
            (< (+ (- (* kbyj ly) lz) yz) 0.0)
            (< (+ (- (* kbyi lx) lz) xz) 0.0)
            (> (+ (- (* ibyk uz) ux) zx) 0.0))))
        (mpm (lambda ()
          (or
            (< ox lx) (> oy uy) (< oz lz)
            (< (+ (- (* jbyi lx) ly) xy) 0.0)
            (> (+ (- (* ibyj uy) ux) yx) 0.0)
            (< (+ (- (* jbyk lz) ly) zy) 0.0)
            (> (+ (- (* kbyj uy) uz) yz) 0.0)
            (> (+ (- (* kbyi lx) uz) xz) 0.0)
            (> (+ (- (* ibyk lz) ux) zx) 0.0))))
        (mpp (lambda ()
          (or
            (< ox lx) (> oy uy) (> oz uz)
            (< (+ (- (* jbyi lx) ly) xy) 0.0)
            (> (+ (- (* ibyj uy) ux) yx) 0.0)
            (< (+ (- (* jbyk uz) ly) zy) 0.0)
            (< (+ (- (* kbyj uy) lz) yz) 0.0)
            (< (+ (- (* kbyi lx) lz) xz) 0.0)
            (> (+ (- (* ibyk uz) ux) zx) 0.0))))
        (pmm (lambda ()
          (or
            (> ox ux) (< oy ly) (< oz lz)
            (> (+ (- (* jbyi ux) uy) xy) 0.0)
            (< (+ (- (* ibyj ly) lx) yx) 0.0)
            (> (+ (- (* jbyk lz) uy) zy) 0.0)
            (> (+ (- (* kbyj ly) uz) yz) 0.0)
            (> (+ (- (* kbyi ux) uz) xz) 0.0)
            (< (+ (- (* ibyk lz) lx) zx) 0.0))))
        (pmp (lambda ()
          (or
            (> ox ux) (< oy ly) (> oz uz)
            (> (+ (- (* jbyi ux) uy) xy) 0.0)
            (< (+ (- (* ibyj ly) lx) yx) 0.0)
            (> (+ (- (* jbyk uz) uy) zy) 0.0)
            (< (+ (- (* kbyj ly) lz) yz) 0.0)
            (< (+ (- (* kbyi ux) lz) xz) 0.0)
            (< (+ (- (* ibyk uz) lx) zx) 0.0))))
        (ppm (lambda ()
          (or
            (> ox ux) (> oy uy) (< oz lz)
            (< (+ (- (* jbyi ux) ly) xy) 0.0)
            (< (+ (- (* ibyj uy) lx) yx) 0.0)
            (< (+ (- (* jbyk lz) ly) zy) 0.0)
            (> (+ (- (* kbyj uy) uz) yz) 0.0)
            (> (+ (- (* kbyi ux) uz) xz) 0.0)
            (< (+ (- (* ibyk lz) lx) zx) 0.0))))
        (ppp (lambda ()
          (or
            (> ox ux) (> oy uy) (> oz uz)
            (< (+ (- (* jbyi ux) ly) xy) 0.0)
            (< (+ (- (* ibyj uy) lx) yx) 0.0)
            (< (+ (- (* jbyk uz) ly) zy) 0.0)
            (< (+ (- (* kbyj uy) lz) yz) 0.0)
            (< (+ (- (* kbyi ux) lz) xz) 0.0)
            (< (+ (- (* ibyk uz) lx) zx) 0.0))))
        (omm (lambda ()
          (or
            (< ox lx) (> ox ux) (< oy ly) (< oz lz)
            (> (+ (- (* jbyk lz) uy) zy) 0.0)
            (> (+ (- (* kbyj ly) uz) yz) 0.0))))
        (omp (lambda ()
          (or
            (< ox lx) (> ox ux) (< oy ly) (> oz uz)
            (> (+ (- (* jbyk uz) uy) zy) 0.0)
            (< (+ (- (* kbyj ly) lz) yz) 0.0))))
        (opm (lambda ()
          (or
            (< ox lx) (> ox ux) (> oy uy) (< oz lz)
            (< (+ (- (* jbyk lz) ly) zy) 0.0)
            (> (+ (- (* kbyj uy) uz) yz) 0.0))))
        (opp (lambda ()
          (or
            (< ox lx) (> ox ux) (> oy uy) (> oz uz)
            (< (+ (- (* jbyk uz) ly) zy) 0.0)
            (< (+ (- (* kbyj uy) lz) yz) 0.0))))
        (mom (lambda ()
          (or
            (< oy ly) (> oy uy) (< ox lx) (< oz lz)
            (> (+ (- (* kbyi lx) uz) xz) 0.0)
            (> (+ (- (* ibyk lz) ux) zx) 0.0))))
        (mop (lambda ()
          (or
            (< oy ly) (> oy uy) (< ox lx) (> oz uz)
            (< (+ (- (* kbyi lx) lz) xz) 0.0)
            (> (+ (- (* ibyk uz) ux) zx) 0.0))))
        (pom (lambda ()
          (or
            (< oy ly) (> oy uy) (> ox ux) (< oz lz)
            (> (+ (- (* kbyi ux) uz) xz) 0.0)
            (< (+ (- (* ibyk lz) lx) zx) 0.0))))
        (pop (lambda ()
          (or
            (< oy ly) (> oy uy) (> ox ux) (> oz uz)
            (< (+ (- (* kbyi ux) lz) xz) 0.0)
            (< (+ (- (* ibyk uz) lx) zx) 0.0))))
        (mmo (lambda ()
          (or
            (< oz lz) (> oz uz) (< ox lx) (< oy ly)
            (> (+ (- (* jbyi lx) uy) xy) 0.0)
            (> (+ (- (* ibyj ly) ux) yx) 0.0))))
        (mpo (lambda ()
          (or
            (< oz lz) (> oz uz) (< ox lx) (> oy uy)
            (< (+ (- (* jbyi lx) ly) xy) 0.0)
            (> (+ (- (* ibyj uy) ux) yx) 0.0))))
        (pmo (lambda ()
          (or
            (< oz lz) (> oz uz) (> ox ux) (< oy ly)
            (> (+ (- (* jbyi ux) uy) xy) 0.0)
            (< (+ (- (* ibyj ly) lx) yx) 0.0))))
        (ppo (lambda ()
          (or
            (< oz lz) (> oz uz) (> ox ux) (> oy uy)
            (< (+ (- (* jbyi ux) ly) xy) 0.0)
            (< (+ (- (* ibyj uy) lx) yx) 0.0))))
        (moo (lambda ()
          (or (< ox lx) (< oy ly) (> oy uy) (< oz lz) (> oz uz))))
        (poo (lambda ()
          (or (> ox ux) (< oy ly) (> oy uy) (< oz lz) (> oz uz))))
        (oop (lambda ()
          (if (or (> oz uz) (< ox lx) (> ox ux) (< oy ly) (> oy uy))
            #f
            #t)))
        (oom (lambda ()
          (if (or (< oz lz) (< ox lx) (> ox ux) (< oy ly) (> oy uy))
            #f
            (oop))))
        (opo (lambda ()
          (if (or (> oy uy) (< ox lx) (> ox ux) (< oz lz) (> oz uz))
            #f
            (oom))))
        (omo (lambda ()
          (if (or (< oy ly) (< ox lx) (> ox ux) (< oz lz) (> oz uz))
            #f
            (opo))))

        (proc-vec
          (vector
            (lambda () (not (mmm))) ; mmm 0
            (lambda () (not (mmp))) ; mmp 1
            (lambda () (not (mmo))) ; mmo 2
            (lambda () (not (mpm))) ; mpm 3
            (lambda () (not (mpp))) ; mpp 4
            (lambda () (not (mpo))) ; mpo 5
            (lambda () (not (mom))) ; mom 6
            (lambda () (not (mop))) ; mop 7
            (lambda () (not (moo))) ; moo 8
            (lambda () (not (pmm))) ; pmm 9
            (lambda () (not (pmp))) ; pmp 10
            (lambda () (not (pmo))) ; pmo 11
            (lambda () (not (ppm))) ; ppm 12
            (lambda () (not (ppp))) ; ppp 13
            (lambda () (not (ppo))) ; ppo 14
            (lambda () (not (pom))) ; pom 15
            (lambda () (not (pop))) ; pop 16
            (lambda () (not (poo))) ; poo 17
            (lambda () (not (omm))) ; omm 18
            (lambda () (not (omp))) ; omp 19
            (lambda () (omo)) ; omo 20
            (lambda () (not (opm))) ; opm 21
            (lambda () (not (opp))) ; opp 22
            (lambda () (opo)) ; opo 23
            (lambda () (oom)) ; oom 24
            (lambda () (oop)))) ; oop 25

        )

        (lambda (selector)
          (case selector
            ((get-bounding-box)
             (lambda () bounding-box))
            ((inside?)
             (lambda (ray)
               (and
                 (>= ((((ray 'get-origin)) 'get-x))
                     ((((bounding-box 'get-lower-extent)) 'get-x)))
                 (<= ((((ray 'get-origin)) 'get-x))
                     ((((bounding-box 'get-upper-extent)) 'get-x)))
                 (>= ((((ray 'get-origin)) 'get-y))
                     ((((bounding-box 'get-lower-extent)) 'get-y)))
                 (<= ((((ray 'get-origin)) 'get-y))
                     ((((bounding-box 'get-upper-extent)) 'get-y)))
                 (>= ((((ray 'get-origin)) 'get-z))
                     ((((bounding-box 'get-lower-extent)) 'get-z)))
                 (<= ((((ray 'get-origin)) 'get-z))
                     ((((bounding-box 'get-upper-extent)) 'get-z))))))
            ((ray-intersects?)
             (lambda (ray)
               (set! o ((ray 'get-origin)))
               (set! ox ((o 'get-x)))
               (set! oy ((o 'get-y)))
               (set! oz ((o 'get-z)))
               (set! xy ((ray 'get-xy)))
               (set! yx ((ray 'get-yx)))
               (set! zy ((ray 'get-zy)))
               (set! yz ((ray 'get-yz)))
               (set! xz ((ray 'get-xz)))
               (set! zx ((ray 'get-zx)))
               (set! jbyi ((ray 'get-jbyi)))
               (set! ibyj ((ray 'get-ibyj)))
               (set! jbyk ((ray 'get-jbyk)))
               (set! kbyj ((ray 'get-kbyj)))
               (set! kbyi ((ray 'get-kbyi)))
               (set! ibyk ((ray 'get-ibyk)))
               (let
                 ((classification ((ray 'get-classification))))
                 (apply (vector-ref proc-vec classification) '())
)))))))))
