;;-*-Lisp-*-
(in-package goal)
(bundles "ENGINE.CGO" "GAME.CGO")
(require "kernel-defs.gc")
(define-extern collide-cache-using-line-sphere-test (function vector symbol))

(define-extern collide-cache-using-y-probe-test (function vector symbol))

(define-extern collide-cache-using-box-test (function vector symbol))

;; DECOMP BEGINS

;;;;;;;;;;;;;;;;;;;;;;;
;; Collide Helpers
;;;;;;;;;;;;;;;;;;;;;;;

(deftype collide-using-spheres-params (structure)
  ((spheres      (inline-array sphere))
   (num-spheres  uint32)
   (collide-with collide-kind)
   (proc         process-drawable)
   (ignore-pat   pat-surface)
   (solid-only   basic)))

;; primitive using sphere-sphere
(deftype collide-puss-sphere (structure)
  ((bsphere sphere :inline)
   (bbox4w  bounding-box4w :inline)))

(deftype collide-puss-work (structure)
  ((closest-pt     vector :inline)
   (tri-normal     vector :inline)
   (tri-bbox4w     bounding-box4w :inline)
   (spheres-bbox4w bounding-box4w :inline)
   (spheres        collide-puss-sphere 64 :inline))
  (:methods
   (collide-puss-work-method-9 (_type_ object object) symbol)
   (collide-puss-work-method-10 (_type_ object object) symbol)))

;; primitive using y probe
(deftype collide-puyp-work (structure)
  ((best-u     float)
   (ignore-pat pat-surface)
   (tri-out    collide-tri-result)
   (start-pos  vector :inline)
   (move-dist  vector :inline)))

;;;;;;;;;;;;;;;;;;;;;;;
;; Main Cache Types
;;;;;;;;;;;;;;;;;;;;;;;

;; The triangles stored in the cache.
;; This is a common return type of collision queries.
(deftype collide-cache-tri (structure)
  ((vertex     vector 3 :inline) ;; actual locations
   (extra-quad uint128 :offset 48)
   (pat        pat-surface :overlay-at extra-quad) ; metadata about the surface of this tri
   (prim-index uint16 :offset 52) ; in the collide-cache-prim list
   (user16     uint16 :offset 54)
   (user32     uint32 2 :offset 56)))

;; The primitives stored in the cache.
;; The "core" is extracted from the normal collide-shape-prim and placed inline here.
(deftype collide-cache-prim (structure)
  ((prim-core    collide-prim-core :inline)
   (extra-quad   uint128)
   (ccache       collide-cache :overlay-at extra-quad)
   (prim         collide-shape-prim :offset 36)
   (first-tri    uint16 :offset 40)
   (num-tris     uint16 :offset 42)
   (unused       uint8 4 :offset 44)
   (world-sphere vector :inline :overlay-at (-> prim-core world-sphere))
   (collide-as   collide-kind :overlay-at (-> prim-core collide-as))
   (action       collide-action :overlay-at (-> prim-core action))
   (offense      collide-offense :overlay-at (-> prim-core offense))
   (prim-type    int8 :overlay-at (-> prim-core prim-type)))
  (:methods
   (resolve-moving-sphere-tri (_type_ collide-tri-result collide-prim-core vector float collide-action) float)
   (resolve-moving-sphere-sphere (_type_ collide-tri-result collide-prim-core vector float collide-action) float)))

;; The actual cache!
(deftype collide-cache (basic)
  ((num-tris      int32)
   (num-prims     int32)
   (num-prims-u   uint32 :overlay-at num-prims)
   (ignore-mask   pat-surface)
   (proc          process-drawable)
   (collide-box   bounding-box :inline)
   (collide-box4w bounding-box4w :inline)
   (collide-with  collide-kind)
   (prims         collide-cache-prim 100 :inline)
   (tris          collide-cache-tri 461 :inline))
  (:methods
   (debug-draw (_type_) none)
   (fill-and-probe-using-line-sphere (_type_ vector vector float collide-kind process collide-tri-result pat-surface) float)
   (fill-and-probe-using-spheres (_type_ collide-using-spheres-params) symbol)
   (fill-and-probe-using-y-probe (_type_ vector float collide-kind process-drawable collide-tri-result pat-surface) float)
   (fill-using-bounding-box (_type_ bounding-box collide-kind process-drawable pat-surface) none)
   (fill-using-line-sphere (_type_ vector vector float collide-kind process-drawable pat-surface) none)
   (fill-using-spheres (_type_ collide-using-spheres-params) none)
   (fill-using-y-probe (_type_ vector float collide-kind process-drawable pat-surface) none)
   (initialize (_type_) none)
   (probe-using-line-sphere (_type_ vector vector float collide-kind collide-tri-result pat-surface) float)
   (probe-using-spheres (_type_ collide-using-spheres-params) symbol)
   (probe-using-y-probe (_type_ vector float collide-kind collide-tri-result pat-surface) float)
   (fill-from-background (_type_ (function bsp-header int collide-list none) (function collide-cache object none)) none)
   (fill-from-foreground-using-box (_type_) none)
   (fill-from-foreground-using-line-sphere (_type_) none)
   (fill-from-foreground-using-y-probe (_type_) none)
   (fill-from-water (_type_ water-control) none)
   (load-mesh-from-spad-in-box (_type_ collide-frag-mesh) none)
   (collide-cache-method-27 (_type_) none)
   (collide-cache-method-28 (_type_) none)
   (collide-cache-method-29 (_type_ collide-frag-mesh) none)
   (puyp-mesh (_type_ collide-puyp-work collide-cache-prim) none)
   (puyp-sphere (_type_ collide-puyp-work collide-cache-prim) vector)
   (unpack-background-collide-mesh (_type_ object object object) none)))

(deftype collide-list-item (structure)
  ((mesh collide-frag-mesh)
   (inst basic)))

(deftype collide-list (structure)
  ((num-items int32)
   (items     collide-list-item 256 :inline)))

(deftype collide-work (structure)
  ((collide-sphere-neg-r sphere :inline)
   (collide-box4w        bounding-box4w :inline)
   (inv-mat              matrix :inline)))

(define-perm *collide-work* collide-work (new 'global 'collide-work))

;; og:preserve-this
(defglobalconstant BIG_COLLIDE_CACHE_SIZE 5000)

(define-perm *collide-cache* collide-cache (new 'global 'collide-cache))

(#when PC_PORT
  ;; disgusting hack to let us overflow the collide cache up to 5k triangles
  (malloc 'global (* (size-of collide-cache-tri) BIG_COLLIDE_CACHE_SIZE))
  ;; but start it at the default.
  (define *collide-cache-max-tris* 460)
  (defmacro activate-big-collide-cache! ()
    `(set! *collide-cache-max-tris* BIG_COLLIDE_CACHE_SIZE)))

(define-perm *collide-list* collide-list (new 'global 'collide-list))
