;;-*-Lisp-*-
(in-package goal)

;; name: race-mesh.gc
;; name in dgo: race-mesh
;; dgos: WASLEAPR, DESRALLY, DESTRACK

;; DECOMP BEGINS

(deftype race-mesh-hash-search (structure)
  ((best-dist              float)
   (debug-cells-searched   int32)
   (debug-slices-searched  int32)
   (bounds                 bounding-box4w  :inline)
   (cell-quads             vector          2 :inline)
   (slice-quads            vector          4 :inline)
   (cell-bits              vector16ub      2 :inline :overlay-at cell-quads)
   (slice-bits             vector16ub      2 :inline :overlay-at slice-quads)
   )
  )


(deftype race-mesh-slice-query (structure)
  ((slice-id       int16)
   (lap-dist       float)
   (pt-on-slice    vector  :inline)
   (slice-corners  vector  4 :inline)
   (search-sphere  sphere  :inline)
   )
  )


(deftype race-path-edge-info (structure)
  ((sample-t  float)
   )
  )


(deftype race-path-sample (structure)
  ((bytes     uint8       32)
   (pos       vector      :inline :overlay-at (-> bytes 0))
   (quat      quaternion  :inline :overlay-at (-> bytes 16))
   (stick-x   int8                :overlay-at (-> bytes 12))
   (stick-y   int8                :overlay-at (-> bytes 13))
   (throttle  uint8               :overlay-at (-> bytes 14))
   (flags     uint8               :overlay-at (-> bytes 15))
   )
  )


(deftype race-path (structure)
  ((sample-count  uint16)
   (record-id     int8)
   (pad           uint8)
   (samples       (inline-array race-path-sample))
   (edge-infos    (inline-array race-path-edge-info))
   )
  (:methods
    (draw-path-debug (_type_ rgba rgba) none)
    (race-path-method-10 (_type_ vector float float) none)
    (race-path-method-11 (_type_ race-path-sample vector float) none)
    (race-path-method-12 (_type_ vector float float) float)
    )
  )


(deftype race-path-group (structure)
  ((name        string)
   (path-count  int8)
   (pad         uint8  3)
   (paths       (inline-array race-path))
   )
  )


(deftype race-mesh-edge (structure)
  ((left      vector  :inline)
   (right     vector  :inline)
   (lap-dist  float   :overlay-at (-> left data 3))
   )
  )


(deftype race-mesh-slice (structure)
  ((edge-index-array  uint16  2)
   (start-edge        int16   :overlay-at (-> edge-index-array 0))
   (end-edge          int16   :overlay-at (-> edge-index-array 1))
   )
  :pack-me
  )


(deftype race-mesh-hash-cell (structure)
  ((first-slice  int16)
   (slice-count  uint8)
   (pad          uint8)
   )
  )


(deftype race-mesh-hash (structure)
  ((cells-wide   int8)
   (cells-tall   int8)
   (cell-length  float)
   (cells        (inline-array race-mesh-hash-cell))
   (slice-table  (inline-array race-mesh-slice))
   (origin       vector  :inline)
   )
  )


(deftype race-mesh (basic)
  ((version           uint8)
   (path-group-count  uint8)
   (flags             race-mesh-flag)
   (pad               uint8  1)
   (slice-count       int16)
   (edge-count        int16)
   (slices            (inline-array race-mesh-slice))
   (edges             (inline-array race-mesh-edge))
   (hash              race-mesh-hash)
   (path-groups       (inline-array race-path-group))
   )
  (:methods
    (debug-draw-path (_type_ int int rgba rgba) none)
    (debug-draw-path-from-history (_type_ int int) symbol)
    (debug-draw-slice (_type_ int) none)
    (debug-draw-edges (_type_) none)
    (race-mesh-method-13 (_type_ race-mesh-slice-query) none)
    (race-mesh-method-14 (_type_ race-mesh-slice-query) none)
    (race-mesh-method-15 (_type_ int race-mesh-slice-query) none)
    (race-mesh-method-16 (_type_ race-mesh-slice-query) none)
    (race-mesh-method-17 (_type_ race-mesh-slice-query) symbol)
    (race-mesh-method-18 (_type_ race-mesh-hash-search int int race-mesh-slice-query) none)
    (race-mesh-method-19 (_type_ int race-mesh-slice-query) symbol)
    )
  )


(defmethod race-path-method-10 ((this race-path) (arg0 vector) (arg1 float) (arg2 float))
  (let ((v1-0 (new 'stack-no-clear 'inline-array 'vector 4))
        (a3-1 (the int arg1))
        )
    (vector-copy! (-> v1-0 0) (-> this samples a3-1 pos))
    (vector-copy! (-> v1-0 1) (-> this samples (+ a3-1 1) pos))
    (let ((f0-3 (- arg1 (the float a3-1))))
      (vector-lerp! arg0 (-> v1-0 0) (-> v1-0 1) f0-3)
      )
    )
  0
  (none)
  )

(defmethod race-path-method-11 ((this race-path) (arg0 race-path-sample) (arg1 vector) (arg2 float))
  (let ((gp-0 (new 'stack-no-clear 'inline-array 'race-path-sample 6)))
    (let ((f0-1 (the float (-> this sample-count))))
      (if (< f0-1 arg2)
          (set! arg2 (- arg2 f0-1))
          )
      (if (< arg2 0.0)
          (set! arg2 (+ arg2 f0-1))
          )
      )
    (let ((s1-0 (the int arg2)))
      (mem-copy! (the-as pointer (-> gp-0 0)) (the-as pointer (-> this samples s1-0)) 32)
      (mem-copy! (the-as pointer (-> gp-0 1)) (the-as pointer (-> this samples (+ s1-0 1))) 32)
      (let ((v1-7 (+ s1-0 2)))
        (if (< (the-as int (-> this sample-count)) v1-7)
            (set! v1-7 (- v1-7 (the-as int (-> this sample-count))))
            )
        (mem-copy! (the-as pointer (-> gp-0 2)) (the-as pointer (-> this samples v1-7)) 32)
        )
      (let ((f30-0 (- arg2 (the float s1-0))))
        (vector-lerp! (-> arg0 pos) (-> gp-0 0 pos) (-> gp-0 1 pos) f30-0)
        (quaternion-slerp! (-> arg0 quat) (-> gp-0 0 quat) (-> gp-0 1 quat) f30-0)
        (set! (-> arg0 stick-x)
              (the int (+ 0.5 (* (the float (-> gp-0 1 stick-x)) f30-0) (* (the float (-> gp-0 0 stick-x)) (- 1.0 f30-0))))
              )
        (set! (-> arg0 stick-y) (-> gp-0 0 stick-y))
        (set! (-> arg0 throttle)
              (the-as
                uint
                (the int
                     (+ 0.5 (* (the float (-> gp-0 1 throttle)) f30-0) (* (the float (-> gp-0 0 throttle)) (- 1.0 f30-0)))
                     )
                )
              )
        (set! (-> arg0 flags) (-> gp-0 0 flags))
        (vector-! (-> gp-0 4 pos) (-> gp-0 1 pos) (-> gp-0 0 pos))
        (vector-float*! (-> gp-0 3 pos) (-> gp-0 4 pos) 15.0)
        (vector-! (-> gp-0 4 pos) (-> gp-0 2 pos) (-> gp-0 1 pos))
        (vector-float*! (-> gp-0 3 quat vec) (-> gp-0 4 pos) 15.0)
        (vector-lerp! arg1 (-> gp-0 3 pos) (-> gp-0 3 quat vec) f30-0)
        )
      )
    )
  0
  0
  (none)
  )

(defmethod race-path-method-12 ((this race-path) (arg0 vector) (arg1 float) (arg2 float))
  (let ((gp-0 arg2)
        (s4-0 (new 'stack-no-clear 'matrix))
        (f30-0 (the float (-> this sample-count)))
        )
    (if (< f30-0 gp-0)
        (set! gp-0 (- gp-0 f30-0))
        )
    (if (< arg1 0.0)
        (set! arg1 (+ arg1 f30-0))
        )
    (race-path-method-10 this (-> s4-0 rvec) arg1 arg2)
    (race-path-method-10 this (-> s4-0 uvec) gp-0 arg2)
    (vector-! (-> s4-0 fvec) (-> s4-0 uvec) (-> s4-0 rvec))
    (vector-! (-> s4-0 trans) arg0 (-> s4-0 rvec))
    (let ((f0-8
            (fmax 0.0 (fmin 1.0 (/ (vector-dot (-> s4-0 fvec) (-> s4-0 trans)) (vector-length-squared (-> s4-0 fvec)))))
            )
          )
      (if (< gp-0 arg1)
          (set! gp-0 (+ gp-0 f30-0))
          )
      (let ((f0-10 (+ (* arg1 (- 1.0 f0-8)) (* gp-0 f0-8))))
        (if (< f30-0 f0-10)
            (set! f0-10 (- f0-10 f30-0))
            )
        (if (< f0-10 0.0)
            (+! f0-10 f30-0)
            )
        f0-10
        )
      )
    )
  )

(defmethod draw-path-debug ((this race-path) (arg0 rgba) (arg1 rgba))
  (local-vars (sv-32 vector) (sv-48 race-path-sample))
  (let ((s0-0 0)
        (s3-0 1)
        (s2-0 (+ (-> this sample-count) -1))
        (s1-0 (new 'stack-no-clear 'vector))
        )
    (set! sv-32 s1-0)
    (let ((v1-1 (-> (math-camera-pos) quad)))
      (set! (-> sv-32 quad) v1-1)
      )
    (while (< s0-0 (the-as int s2-0))
      (let ((s0-1 (-> this samples s0-0)))
        (set! sv-48 (-> this samples s3-0))
        (let ((f0-0 (vector-vector-distance-squared (-> s0-1 pos) s1-0))
              (f1-0 819200.0)
              )
          (if (< f0-0 (* f1-0 f1-0))
              (add-debug-line #t (bucket-id debug) (-> s0-1 pos) (-> sv-48 pos) arg0 #f arg1)
              )
          )
        )
      (set! s0-0 s3-0)
      (set! s3-0 (min (+ s3-0 1) (the-as int s2-0)))
      )
    )
  (format
    *stdcon*
    "path ~d time ~5,,3f~%"
    (-> this record-id)
    (* 0.06666667 (the float (-> this sample-count)))
    )
  0
  (none)
  )

(defmethod debug-draw-path ((this race-mesh) (arg0 int) (arg1 int) (arg2 rgba) (arg3 rgba))
  (when (< arg1 (the-as int (-> this path-group-count)))
    (let ((v1-2 (-> this path-groups arg1)))
      (if (< arg0 (-> v1-2 path-count))
          (draw-path-debug (-> v1-2 paths arg0) arg2 arg3)
          )
      )
    )
  (none)
  )

(defmethod debug-draw-path-from-history ((this race-mesh) (arg0 int) (arg1 int))
  (when (< arg1 (the-as int (-> this path-group-count)))
    (let ((v1-2 (-> this path-groups arg1)))
      (countdown (a2-1 (-> v1-2 path-count))
        (let ((a0-3 (-> v1-2 paths a2-1)))
          (when (= (-> a0-3 record-id) arg0)
            (let ((v1-3 (new 'static 'array rgba 16
                          (new 'static 'rgba :r #x40 :a #x80)
                          (new 'static 'rgba :r #xff :g #x30 :b #x30 :a #x80)
                          (new 'static 'rgba :g #xff :a #x80)
                          (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
                          (new 'static 'rgba :b #xff :a #x80)
                          (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
                          (new 'static 'rgba :r #x60 :g #x60 :b #x60 :a #x80)
                          (new 'static 'rgba :r #xff :g #xff :a #x80)
                          (new 'static 'rgba :g #xff :b #xff :a #x80)
                          (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
                          (new 'static 'rgba :r #xff :b #xff :a #x80)
                          (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
                          (new 'static 'rgba :r #xff :g #x80 :b #x40 :a #x80)
                          (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
                          (new 'static 'rgba :a #x80)
                          (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
                          )
                        )
                  (a2-2 (* arg0 2))
                  )
              (draw-path-debug a0-3 (-> v1-3 a2-2) (-> v1-3 (+ a2-2 1)))
              )
            (return #f)
            )
          )
        )
      )
    #f
    )
  )

;; WARN: Return type mismatch symbol vs none.
(defmethod debug-draw-slice ((this race-mesh) (arg0 int))
  (let* ((v1-1 (-> this slices arg0))
         (s3-0 (-> this edges (-> v1-1 start-edge)))
         (s4-0 (-> this edges (-> v1-1 end-edge)))
         )
    (add-debug-line
      #t
      (bucket-id debug-no-zbuf1)
      (-> s3-0 left)
      (-> s3-0 right)
      (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
      #f
      (the-as rgba -1)
      )
    (add-debug-line
      #t
      (bucket-id debug-no-zbuf1)
      (-> s3-0 right)
      (-> s4-0 right)
      (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
      #f
      (the-as rgba -1)
      )
    (add-debug-line
      #t
      (bucket-id debug-no-zbuf1)
      (-> s4-0 right)
      (-> s4-0 left)
      (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
      #f
      (the-as rgba -1)
      )
    (add-debug-line
      #t
      (bucket-id debug-no-zbuf1)
      (-> s4-0 left)
      (-> s3-0 left)
      (new 'static 'rgba :r #xff :g #xff :b #xff :a #x80)
      #f
      (the-as rgba -1)
      )
    (let ((s5-0 (new 'stack-no-clear 'vector)))
      (vector+! s5-0 (-> s3-0 left) (-> s3-0 right))
      (vector+! s5-0 s5-0 (-> s4-0 left))
      (vector+! s5-0 s5-0 (-> s4-0 right))
      (vector-float*! s5-0 s5-0 0.25)
      (let ((s4-1 add-debug-text-3d)
            (s3-1 #t)
            (s2-0 577)
            )
        (format (clear *temp-string*) "~D" arg0)
        (s4-1 s3-1 (the-as bucket-id s2-0) *temp-string* s5-0 (font-color white) (the-as vector2h #f))
        )
      )
    )
  (none)
  )

(defmethod debug-draw-edges ((this race-mesh))
  (let ((s5-0 0)
        (s4-0 (+ (-> this slice-count) -1))
        )
    (while (>= s4-0 s5-0)
      (let* ((v1-2 (-> this slices s5-0))
             (s3-0 (-> this edges (-> v1-2 start-edge)))
             (s2-0 (-> this edges (-> v1-2 end-edge)))
             )
        (add-debug-line #t (bucket-id debug-no-zbuf1) (-> s3-0 left) (-> s2-0 left) *color-white* #f (the-as rgba -1))
        (add-debug-line
          #t
          (bucket-id debug-no-zbuf1)
          (-> s3-0 right)
          (-> s2-0 right)
          *color-white*
          #f
          (the-as rgba -1)
          )
        (add-debug-line #t (bucket-id debug-no-zbuf1) (-> s2-0 left) (-> s2-0 right) *color-gray* #f (the-as rgba -1))
        )
      (+! s5-0 1)
      )
    )
  (let ((v1-8 (-> this edges 0)))
    (add-debug-line
      #t
      (bucket-id debug-no-zbuf1)
      (-> v1-8 left)
      (-> v1-8 right)
      *color-green*
      #f
      (the-as rgba -1)
      )
    )
  (let ((s5-1 (+ (-> this edge-count) -1)))
    (let ((v1-12 (-> this edges s5-1)))
      (add-debug-line
        #t
        (bucket-id debug-no-zbuf1)
        (-> v1-12 left)
        (-> v1-12 right)
        *color-red*
        #f
        (the-as rgba -1)
        )
      )
    (format *stdcon* "edge-count ~d last-edge ~d~%" (-> this edge-count) s5-1)
    )
  0
  (none)
  )

(defmethod race-mesh-method-19 ((this race-mesh) (arg0 int) (arg1 race-mesh-slice-query))
  (set! (-> arg1 slice-id) -1)
  (let* ((v1-2 (-> this slices arg0))
         (a1-3 (-> this edges (-> v1-2 start-edge)))
         (v1-5 (-> this edges (-> v1-2 end-edge)))
         )
    (set! (-> arg1 slice-corners 0 quad) (-> a1-3 left quad))
    (vector-copy! (-> arg1 slice-corners 1) (-> a1-3 right))
    (vector-copy! (-> arg1 slice-corners 2) (-> v1-5 right))
    (vector-copy! (-> arg1 slice-corners 3) (-> v1-5 left))
    )
  (let ((v1-8 (new 'stack-no-clear 'vector))
        (a0-6 (new 'stack-no-clear 'vector))
        )
    (countdown (a1-8 4)
      (vector-! a0-6 (-> arg1 slice-corners (logand (+ a1-8 1) 3)) (-> arg1 slice-corners a1-8))
      (vector-! v1-8 (the-as vector (-> arg1 search-sphere)) (-> arg1 slice-corners a1-8))
      (if (< (- (* (-> a0-6 z) (-> v1-8 x)) (* (-> a0-6 x) (-> v1-8 z))) 0.0)
          (return #f)
          )
      )
    )
  (let ((v1-11 (new 'stack-no-clear 'vector))
        (a0-7 (new 'stack-no-clear 'vector))
        )
    (vector-! v1-11 (-> arg1 slice-corners 2) (-> arg1 slice-corners 0))
    (vector-! a0-7 (the-as vector (-> arg1 search-sphere)) (-> arg1 slice-corners 0))
    (let ((f0-5 (- (* (-> v1-11 z) (-> a0-7 x)) (* (-> v1-11 x) (-> a0-7 z))))
          (s4-0 (new 'stack-no-clear 'vector))
          (s3-0 (new 'stack-no-clear 'vector))
          )
      (cond
        ((< f0-5 0.0)
         (vector-! s4-0 (-> arg1 slice-corners 1) (-> arg1 slice-corners 0))
         (vector-cross! s3-0 s4-0 v1-11)
         )
        (else
          (vector-! s4-0 (-> arg1 slice-corners 3) (-> arg1 slice-corners 0))
          (vector-cross! s3-0 v1-11 s4-0)
          )
        )
      (vector-normalize! s3-0 1.0)
      (set-vector! s4-0 0.0 -1.0 0.0 1.0)
      (let ((f0-10 (intersect-ray-plane (-> arg1 search-sphere) s4-0 (-> arg1 slice-corners 0) s3-0)))
        (vector+float*! (-> arg1 pt-on-slice) (the-as vector (-> arg1 search-sphere)) s4-0 f0-10)
        )
      )
    )
  (if (< (- (-> arg1 search-sphere y) (-> arg1 pt-on-slice y)) -8192.0)
      (return #f)
      )
  (set! (-> arg1 slice-id) arg0)
  #t
  )

(defmethod race-mesh-method-17 ((this race-mesh) (arg0 race-mesh-slice-query))
  (set! (-> arg0 slice-id) -1)
  (let* ((s4-0 (-> this hash))
         (v1-2 (max 0 (min
                        (the int (/ (- (-> arg0 search-sphere x) (-> s4-0 origin x)) (-> s4-0 cell-length)))
                        (+ (-> s4-0 cells-wide) -1)
                        )
                    )
               )
         (a0-4 (max 0 (min
                        (the int (/ (- (-> arg0 search-sphere z) (-> s4-0 origin z)) (-> s4-0 cell-length)))
                        (+ (-> s4-0 cells-tall) -1)
                        )
                    )
               )
         (s3-0 (the-as object (+ (the-as uint (-> s4-0 cells)) (* (+ (* a0-4 (-> s4-0 cells-wide)) v1-2) 4))))
         (s1-0 (-> (the-as race-mesh-hash-cell s3-0) slice-count))
         )
    (when (nonzero? s1-0)
      (let ((s2-0 (new 'stack-no-clear 'race-mesh-slice-query)))
        (mem-copy! (the-as pointer s2-0) (the-as pointer arg0) 112)
        (while (nonzero? s1-0)
          (+! s1-0 -1)
          (let ((a1-7 (-> (&-> s4-0 slice-table 0 edge-index-array (+ (-> (the-as (pointer int16) s3-0)) s1-0)) 0)))
            (when (race-mesh-method-19 this (the-as int a1-7) s2-0)
              (if (or (= (-> arg0 slice-id) -1)
                      (< (vector-vector-distance-squared (-> s2-0 pt-on-slice) (-> arg0 search-sphere))
                         (vector-vector-distance-squared (-> arg0 pt-on-slice) (-> arg0 search-sphere))
                         )
                      )
                  (mem-copy! (the-as pointer arg0) (the-as pointer s2-0) 112)
                  )
              )
            )
          )
        )
      #f
      )
    )
  )

;; WARN: Return type mismatch vector vs none.
(defmethod race-mesh-method-15 ((this race-mesh) (arg0 int) (arg1 race-mesh-slice-query))
  (local-vars (v1-8 symbol))
  (set! (-> arg1 slice-id) arg0)
  (let* ((v1-1 (-> this slices arg0))
         (a1-3 (-> this edges (-> v1-1 start-edge)))
         (v1-4 (-> this edges (-> v1-1 end-edge)))
         )
    (set! (-> arg1 slice-corners 0 quad) (-> a1-3 left quad))
    (vector-copy! (-> arg1 slice-corners 1) (-> a1-3 right))
    (vector-copy! (-> arg1 slice-corners 2) (-> v1-4 right))
    (vector-copy! (-> arg1 slice-corners 3) (-> v1-4 left))
    )
  (let ((v1-7 (new 'stack-no-clear 'vector))
        (a0-6 (new 'stack-no-clear 'vector))
        )
    (countdown (a1-8 4)
      (vector-! a0-6 (-> arg1 slice-corners (logand (+ a1-8 1) 3)) (-> arg1 slice-corners a1-8))
      (vector-! v1-7 (the-as vector (-> arg1 search-sphere)) (-> arg1 slice-corners a1-8))
      (when (< (- (* (-> a0-6 z) (-> v1-7 x)) (* (-> a0-6 x) (-> v1-7 z))) 0.0)
        (set! v1-8 #f)
        (goto cfg-6)
        )
      )
    )
  (set! v1-8 #t)
  (label cfg-6)
  (cond
    (v1-8
      (let ((v1-11 (new 'stack-no-clear 'vector))
            (a0-7 (new 'stack-no-clear 'vector))
            )
        (vector-! v1-11 (-> arg1 slice-corners 2) (-> arg1 slice-corners 0))
        (vector-! a0-7 (the-as vector (-> arg1 search-sphere)) (-> arg1 slice-corners 0))
        (let ((f0-5 (- (* (-> v1-11 z) (-> a0-7 x)) (* (-> v1-11 x) (-> a0-7 z))))
              (s5-0 (new 'stack-no-clear 'vector))
              (s4-0 (new 'stack-no-clear 'vector))
              )
          (cond
            ((< f0-5 0.0)
             (vector-! s5-0 (-> arg1 slice-corners 1) (-> arg1 slice-corners 0))
             (vector-cross! s4-0 s5-0 v1-11)
             )
            (else
              (vector-! s5-0 (-> arg1 slice-corners 3) (-> arg1 slice-corners 0))
              (vector-cross! s4-0 v1-11 s5-0)
              )
            )
          (vector-normalize! s4-0 1.0)
          (set-vector! s5-0 0.0 -1.0 0.0 1.0)
          (let ((f0-10 (intersect-ray-plane (-> arg1 search-sphere) s5-0 (-> arg1 slice-corners 0) s4-0)))
            (vector+float*! (-> arg1 pt-on-slice) (the-as vector (-> arg1 search-sphere)) s5-0 f0-10)
            )
          )
        )
      )
    (else
      (let ((s5-1 (new 'stack-no-clear 'vector))
            (f30-0 -1.0)
            )
        (countdown (s4-1 4)
          (let ((f0-11 (vector-segment-distance-point!
                         (-> arg1 search-sphere)
                         (-> arg1 slice-corners s4-1)
                         (-> arg1 slice-corners (logand (+ s4-1 1) 3))
                         s5-1
                         )
                       )
                )
            (when (or (< f30-0 0.0) (< f0-11 f30-0))
              (set! f30-0 f0-11)
              (vector-copy! (-> arg1 pt-on-slice) s5-1)
              )
            )
          )
        )
      )
    )
  (none)
  )

;; WARN: Return type mismatch symbol vs none.
(defmethod race-mesh-method-18 ((this race-mesh) (arg0 race-mesh-hash-search) (arg1 int) (arg2 int) (arg3 race-mesh-slice-query))
  (let* ((v1-3 (+ (* arg2 (-> this hash cells-wide)) arg1))
         (a0-1 (/ v1-3 8))
         (a1-2 (ash 1 (logand v1-3 7)))
         (a2-4 (-> (the-as race-mesh-hash-search (+ a0-1 (the-as int arg0))) cell-bits 0 data 0))
         )
    (when (not (logtest? a2-4 a1-2))
      (set! (-> arg0 cell-bits 0 data a0-1) (logior a2-4 a1-2))
      (let* ((v1-5 (the-as object (+ (the-as uint (-> this hash cells)) (* v1-3 4))))
             (s3-0 (&-> this hash slice-table 0 edge-index-array (-> (the-as (pointer int16) v1-5))))
             (s1-0 (-> (the-as race-mesh-hash-cell v1-5) slice-count))
             )
        (when (nonzero? s1-0)
          (let ((s2-0 (new 'stack-no-clear 'race-mesh-slice-query)))
            (mem-copy! (the-as pointer s2-0) (the-as pointer arg3) 112)
            (while (nonzero? s1-0)
              (+! s1-0 -1)
              (let* ((a1-7 (-> s3-0 0))
                     (v1-6 (shr a1-7 3))
                     (a0-10 (ash 1 (the-as int (logand a1-7 7))))
                     (a2-9 (-> arg0 slice-bits 0 data v1-6))
                     )
                (when (not (logtest? a2-9 a0-10))
                  (set! (-> arg0 slice-bits 0 data v1-6) (logior a2-9 a0-10))
                  (race-mesh-method-15 this (the-as int a1-7) s2-0)
                  (let ((f0-0 (vector-vector-distance-squared (-> s2-0 pt-on-slice) (-> arg3 search-sphere))))
                    (when (or (= (-> arg3 slice-id) -1) (< f0-0 (-> arg0 best-dist)))
                      (set! (-> arg0 best-dist) f0-0)
                      (mem-copy! (the-as pointer arg3) (the-as pointer s2-0) 112)
                      )
                    )
                  )
                )
              (set! s3-0 (&-> s3-0 1))
              )
            )
          )
        )
      )
    )
  (none)
  )

(defmethod race-mesh-method-16 ((this race-mesh) (arg0 race-mesh-slice-query))
  (set! (-> arg0 slice-id) -1)
  (let ((s4-0 (-> this hash))
        (s3-0 (new 'stack-no-clear 'race-mesh-hash-search))
        )
    (let ((v1-3 (/ (+ (-> this slice-count) 127) 128)))
      (when (< 4 v1-3)
        (break!)
        0
        )
      (while (nonzero? v1-3)
        (+! v1-3 -1)
        (set! (-> s3-0 slice-bits v1-3 quad) (the-as uint128 0))
        )
      )
    (set! (-> s3-0 cell-bits 0 quad) (the-as uint128 0))
    (set! (-> s3-0 cell-bits 1 quad) (the-as uint128 0))
    (let ((f0-1 (/ 1.0 (-> s4-0 cell-length)))
          (f1-2 (fmin (-> arg0 search-sphere r) (/ (-> s4-0 cell-length) 2)))
          )
      (let ((f3-1 (- (-> arg0 search-sphere x) f1-2))
            (f2-4 (- (-> arg0 search-sphere z) f1-2))
            )
        (set! (-> s3-0 bounds min x)
              (max 0 (min (the int (* (- f3-1 (-> s4-0 origin x)) f0-1)) (+ (-> s4-0 cells-wide) -1)))
              )
        (set! (-> s3-0 bounds min z)
              (max 0 (min (the int (* (- f2-4 (-> s4-0 origin z)) f0-1)) (+ (-> s4-0 cells-tall) -1)))
              )
        )
      (let ((f2-9 (+ (-> arg0 search-sphere x) f1-2))
            (f1-3 (+ (-> arg0 search-sphere z) f1-2))
            )
        (set! (-> s3-0 bounds max x)
              (max 0 (min (the int (* (- f2-9 (-> s4-0 origin x)) f0-1)) (+ (-> s4-0 cells-wide) -1)))
              )
        (set! (-> s3-0 bounds max z)
              (max 0 (min (the int (* (- f1-3 (-> s4-0 origin z)) f0-1)) (+ (-> s4-0 cells-tall) -1)))
              )
        )
      )
    (let ((s2-0 (-> s3-0 bounds min z)))
      (until (< (-> s3-0 bounds max z) s2-0)
        (let ((s1-0 (-> s3-0 bounds min x)))
          (until (< (-> s3-0 bounds max x) s1-0)
            (race-mesh-method-18 this s3-0 s1-0 s2-0 arg0)
            (+! s1-0 1)
            )
          )
        (+! s2-0 1)
        )
      )
    (when (and (= (-> arg0 slice-id) -1) (< (/ (-> s4-0 cell-length) 2) (-> arg0 search-sphere r)))
      (while (= (-> arg0 slice-id) -1)
        (set! (-> s3-0 bounds min x) (max 0 (+ (-> s3-0 bounds min x) -1)))
        (set! (-> s3-0 bounds min z) (max 0 (+ (-> s3-0 bounds min z) -1)))
        (set! (-> s3-0 bounds max x) (min (+ (-> s3-0 bounds max x) 1) (+ (-> s4-0 cells-wide) -1)))
        (set! (-> s3-0 bounds max z) (min (+ (-> s3-0 bounds max z) 1) (+ (-> s4-0 cells-tall) -1)))
        (let ((s2-1 (-> s3-0 bounds min x)))
          (until (< (-> s3-0 bounds max x) s2-1)
            (race-mesh-method-18 this s3-0 s2-1 (-> s3-0 bounds min z) arg0)
            (race-mesh-method-18 this s3-0 s2-1 (-> s3-0 bounds max z) arg0)
            (+! s2-1 1)
            )
          )
        (let ((s2-2 (-> s3-0 bounds min z)))
          (until (< (-> s3-0 bounds max z) s2-2)
            (race-mesh-method-18 this s3-0 (-> s3-0 bounds min x) s2-2 arg0)
            (race-mesh-method-18 this s3-0 (-> s3-0 bounds max x) s2-2 arg0)
            (+! s2-2 1)
            )
          )
        )
      )
    )
  0
  (none)
  )

;; WARN: Return type mismatch float vs none.
(defmethod race-mesh-method-14 ((this race-mesh) (arg0 race-mesh-slice-query))
  (let* ((f30-0 (vector-line-distance-point!
                  (-> arg0 pt-on-slice)
                  (-> arg0 slice-corners 0)
                  (-> arg0 slice-corners 1)
                  (the-as vector #f)
                  )
                )
         (f1-0 (vector-line-distance-point!
                 (-> arg0 pt-on-slice)
                 (-> arg0 slice-corners 2)
                 (-> arg0 slice-corners 3)
                 (the-as vector #f)
                 )
               )
         (f0-0 (+ f30-0 f1-0))
         (v1-1 (-> this slices (-> arg0 slice-id)))
         (f2-0 (-> this edges (-> v1-1 start-edge) left w))
         (f3-0 (-> this edges (-> v1-1 end-edge) left w))
         )
    (set! (-> arg0 lap-dist) (+ (* (/ f1-0 f0-0) f2-0) (* (/ f30-0 f0-0) f3-0)))
    )
  (none)
  )

(defmethod race-mesh-method-13 ((this race-mesh) (arg0 race-mesh-slice-query))
  (race-mesh-method-17 this arg0)
  (if (and (= (-> arg0 slice-id) -1) (< 0.0 (-> arg0 search-sphere r)))
      (race-mesh-method-16 this arg0)
      )
  (when (!= (-> arg0 slice-id) -1)
    (race-mesh-method-14 this arg0)
    0
    )
  (none)
  )
