Files
water111 637990314b wip: better stack var support (#4222)
Closes #736

---------

Co-authored-by: Hat Kid <6624576+Hat-Kid@users.noreply.github.com>
2026-04-19 00:14:44 +02:00

976 lines
35 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;; name: collide-cache.gc
;; name in dgo: collide-cache
;; dgos: GAME
;; DECOMP BEGINS
(defmethod reset ((this collide-cache))
(set! (-> this num-tris) 0)
(set! (-> this num-prims) 0)
(set! (-> this ignore-processes 0) #f)
(set! (-> this ignore-processes 1) #f)
(set! *already-printed-exeeded-max-cache-tris* #f)
0
(none)
)
(defmethod fill-from-bg ((this collide-cache)
(arg0 (function collide-hash int collide-list collide-query int))
(arg1 (function collide-cache collide-list collide-query none))
(arg2 collide-query)
)
(set! *already-printed-exeeded-max-cache-tris* #f)
(set! (-> *collide-list* num-items) 0)
(if *collide-list-boxes*
(add-debug-box
#t
(bucket-id debug)
(-> arg2 bbox min)
(-> arg2 bbox max)
(new 'static 'rgba :g #xff :b #xff :a #x80)
)
)
(dotimes (s3-0 (-> *level* length))
(let ((v1-7 (-> *level* level s3-0)))
(if (= (-> v1-7 status) 'active)
(arg0 (-> v1-7 bsp collide-hash) 0 *collide-list* arg2)
)
)
)
(if (> (-> *collide-list* num-items) 0)
(arg1 *collide-cache* *collide-list* arg2)
)
0
(none)
)
;; WARN: Function (method 21 collide-cache) has a return type of none, but the expression builder found a return statement.
(defmethod fill-from-water ((this collide-cache) (arg0 water-control))
(rlet ((vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
(vf3 :class vf)
(vf4 :class vf)
(vf5 :class vf)
)
(init-vf0-vector)
(if (or (not arg0) (zero? arg0))
(return #f)
)
(when (= (-> this num-prims) 100)
(if (and (= *cheat-mode* 'debug) (not *display-capture-mode*))
(format 0 "ERROR: Exceeded max number of collide-cache prims!~%")
)
(return #f)
)
(when (< 460 (+ (-> this num-tris) 2))
(if (and (= *cheat-mode* 'debug) (not *display-capture-mode*))
(print-exceeded-max-cache-tris)
)
(return #f)
)
(if (not (and (logtest? (-> arg0 flags) (water-flag active))
(logtest? (-> arg0 flags) (water-flag can-ground))
(logtest? (-> arg0 flags) (water-flag swim-ground under-water))
(logtest? (water-flag over-water) (-> arg0 flags))
(not (logtest? (water-flag jump-out) (-> arg0 flags)))
)
)
(return #f)
)
(let ((v1-31 (-> arg0 collide-height)))
(.lvf vf1 (&-> this collide-box min quad))
(.lvf vf3 (&-> this collide-box max quad))
(let ((a2-6 (-> this num-prims-u32))
(a3-4 (the-as (inline-array collide-cache-tri) (-> this tris (-> this num-tris))))
)
(.mov vf5 v1-31)
(.add.x.vf.y vf1 vf0 vf5)
(set! (-> a3-4 0 clear-flags) (the-as uint128 0))
(set! (-> a3-4 0 prim-index) a2-6)
(.add.x.vf.y vf3 vf0 vf5)
(set! (-> a3-4 1 clear-flags) (the-as uint128 0))
(set! (-> a3-4 1 prim-index) a2-6)
(.mov.vf vf2 vf1)
(.mov.vf vf4 vf1)
(.add.z.vf.z vf2 vf0 vf3)
(.add.x.vf.x vf4 vf0 vf3)
(.svf (&-> a3-4 0 vertex 0 quad) vf1)
(.svf (&-> a3-4 0 vertex 1 quad) vf2)
(.svf (&-> a3-4 0 vertex 2 quad) vf3)
(set! (-> a3-4 0 pat) (new 'static 'pat-surface :material (pat-material waterbottom) :nogrind #x1))
(set! (-> a3-4 0 collide-ptr) arg0)
(.svf (&-> a3-4 1 vertex 0 quad) vf1)
(.svf (&-> a3-4 1 vertex 1 quad) vf3)
(.svf (&-> a3-4 1 vertex 2 quad) vf4)
(set! (-> a3-4 1 pat) (new 'static 'pat-surface :material (pat-material waterbottom)))
(set! (-> a3-4 1 collide-ptr) arg0)
)
)
(let ((v1-34 *collide-shape-prim-water*)
(a1-5 (-> this prims (-> this num-prims)))
)
(set! (-> a1-5 first-tri) (the-as uint (-> this num-tris)))
(set! (-> a1-5 num-tris) (the-as uint 2))
(set! (-> a1-5 prim) v1-34)
(set! (-> a1-5 ccache) this)
(set! (-> a1-5 prim-core world-sphere quad) (-> v1-34 prim-core world-sphere quad))
(set! (-> a1-5 prim-core quad 1) (-> v1-34 prim-core quad 1))
)
(+! (-> this num-prims) 1)
(+! (-> this num-tris) 2)
0
(none)
)
)
(defmethod fill-using-bounding-box ((this collide-cache) (arg0 collide-query))
(rlet ((vf0 :class vf)
(vf1 :class vf)
(vf2 :class vf)
(vf3 :class vf)
(vf4 :class vf)
)
(init-vf0-vector)
(+! (-> *collide-stats* calls) 1)
(new 'static 'vector :x 0.5)
(nop!)
(let ((v1-4 (-> arg0 collide-with-s32)))
(nop!)
(let ((a0-2 (-> arg0 ignore-process0)))
(nop!)
(let ((a1-1 (-> arg0 ignore-process1)))
(nop!)
(let ((a2-0 (-> arg0 ignore-pat-s32)))
(nop!)
(.lvf vf1 (&-> arg0 bbox min quad))
(nop!)
(.lvf vf2 (&-> arg0 bbox max quad))
(nop!)
(set! (-> this ignore-processes 0) (the-as process a0-2))
(nop!)
(set! (-> this ignore-processes 1) (the-as process a1-1))
(.mov.vf.w vf1 vf0)
(nop!)
(.mov.vf.w vf2 vf0)
(set! (-> this ignore-mask) (the-as pat-surface a2-0))
)
)
)
(.ftoi.vf vf3 vf1)
(nop!)
(.ftoi.vf vf4 vf2)
(set! (-> this num-tris) 0)
(nop!)
(.svf (&-> this collide-box min quad) vf1)
(nop!)
(.svf (&-> this collide-box max quad) vf2)
(nop!)
(.svf (&-> this collide-box4w min quad) vf3)
(nop!)
(.svf (&-> this collide-box4w max quad) vf4)
(nop!)
(.svf (&-> arg0 bbox4w min quad) vf3)
(nop!)
(.svf (&-> arg0 bbox4w max quad) vf4)
(nop!)
(set! (-> this num-prims) 0)
(nop!)
(set! (-> this collide-with) (the-as collide-spec v1-4))
)
0
(when (logtest? (-> arg0 collide-with) (collide-spec backgnd))
(fill-from-bg
this
(the-as
(function collide-hash int collide-list collide-query int)
(method-of-type collide-hash drawable-method-11)
)
collide-list-fill-bg-using-box
arg0
)
(dotimes (s4-0 (-> *level* length))
(let ((v1-15 (-> *level* level s4-0)))
(when (= (-> v1-15 status) 'active)
(let ((a0-6 (-> v1-15 bsp hfrag-drawable)))
(if (nonzero? a0-6)
(bounding-box-query (the-as hfragment a0-6) this arg0)
)
)
)
)
)
(let ((a0-7 (-> this num-tris)))
(when (> a0-7 0)
(let ((v1-22 (-> this prims))
(a1-9 *collide-shape-prim-backgnd*)
)
(set! (-> v1-22 0 num-tris) (the-as uint a0-7))
(set! (-> v1-22 0 prim) a1-9)
(set! (-> this num-prims) 1)
(set! (-> v1-22 0 first-tri) (the-as uint 0))
(set! (-> v1-22 0 ccache) this)
(set! (-> v1-22 0 prim-core world-sphere quad) (-> a1-9 prim-core world-sphere quad))
(set! (-> v1-22 0 prim-core quad 1) (-> a1-9 prim-core quad 1))
)
)
)
(+! (-> *collide-stats* output) (-> this num-tris))
)
(when (logtest? (-> arg0 collide-with) (collide-spec water))
(let ((v1-29 (-> arg0 ignore-process0)))
(if v1-29
(fill-from-water this (-> (the-as process-drawable v1-29) water))
)
)
)
(if (logtest? (-> arg0 collide-with) (collide-spec hit-by-player-list hit-by-others-list player-list))
(fill-from-fg-boxes this)
)
0
(none)
)
)
(defmethod fill-using-line-sphere ((this collide-cache) (arg0 collide-query))
;; og:preserve-this float -> uint
(local-vars (v1-11 uint) (v1-20 float))
(rlet ((acc :class vf)
(Q :class vf)
(vf0 :class vf)
(vf1 :class vf)
(vf10 :class vf)
(vf11 :class vf)
(vf12 :class vf)
(vf13 :class vf)
(vf14 :class vf)
(vf15 :class vf)
(vf16 :class vf)
(vf17 :class vf)
(vf18 :class vf)
(vf19 :class vf)
(vf2 :class vf)
(vf20 :class vf)
(vf22 :class vf)
(vf23 :class vf)
(vf3 :class vf)
(vf4 :class vf)
(vf5 :class vf)
(vf6 :class vf)
(vf7 :class vf)
(vf8 :class vf)
(vf9 :class vf)
)
(init-vf0-vector)
(+! (-> *collide-stats* calls) 1)
(let ((v1-3 0))
(if (< (fabs (-> arg0 move-dist x)) 4096.0)
(+! v1-3 1)
)
(if (< (fabs (-> arg0 move-dist y)) 4096.0)
(+! v1-3 1)
)
(if (< (fabs (-> arg0 move-dist z)) 4096.0)
(+! v1-3 1)
)
(when (< 1 v1-3)
(set-from-point-offset-pad! (-> arg0 bbox) (-> arg0 start-pos) (-> arg0 move-dist) (-> arg0 radius))
(fill-using-bounding-box this arg0)
(b! #t cfg-55 :delay (nop!))
(the-as none 0)
)
)
(nop!)
(let ((v1-10 (-> arg0 ignore-pat-s32)))
(nop!)
(let ((a0-14 (-> arg0 ignore-process0)))
(nop!)
(let ((a1-3 (-> arg0 ignore-process1)))
(nop!)
(let ((a2-1 (-> arg0 collide-with-s32)))
(nop!)
(.lvf vf9 (&-> arg0 exit-planes 0 quad))
(nop!)
(.lvf vf3 (&-> arg0 move-dist quad))
(nop!)
(.mov.vf vf13 vf0)
(nop!)
(.lvf vf1 (&-> arg0 start-pos quad))
(.mul.vf vf8 vf3 vf3)
(nop!)
(.add.vf vf2 vf1 vf3)
(set! (-> this ignore-mask) (the-as pat-surface v1-10))
(.add.y.vf.x vf8 vf8 vf8)
(set! (-> this num-tris) 0)
(.min.vf vf4 vf1 vf2)
(set! (-> this num-prims) 0)
(.max.vf vf5 vf1 vf2)
(set! (-> this collide-with) (the-as collide-spec a2-1))
)
(.sub.w.vf.xyz vf10 vf0 vf9)
(set! (-> this ignore-processes 0) (the-as process a0-14))
(.add.z.vf.x vf8 vf8 vf8)
(set! (-> this ignore-processes 1) (the-as process a1-3))
)
)
)
(.sub.w.vf.xyz vf4 vf4 vf9)
(nop!)
(.add.w.vf.xyz vf5 vf5 vf9)
(nop!)
(.ftoi.vf vf15 vf10)
(nop!)
(.isqrt.vf Q vf0 vf8 :fsf #b11 :ftf #b0)
(nop!)
(.add.w.vf.xyz vf11 vf0 vf9)
(nop!)
(nop!)
(nop!)
(nop!)
(.svf (&-> arg0 local-box4w min quad) vf15)
(.ftoi.vf vf6 vf4)
(.svf (&-> this collide-box min quad) vf4)
(.ftoi.vf vf7 vf5)
(.svf (&-> this collide-box max quad) vf5)
(nop!)
(.svf (&-> arg0 bbox min quad) vf4)
(nop!)
(.svf (&-> arg0 bbox max quad) vf5)
(nop!)
(.svf (&-> this collide-box4w min quad) vf6)
(nop!)
(.svf (&-> this collide-box4w max quad) vf7)
(nop!)
(.svf (&-> arg0 bbox4w min quad) vf6)
(nop!)
(.svf (&-> arg0 bbox4w max quad) vf7)
(.wait.vf)
(nop!)
(.add.vf.x vf8 vf0 Q)
(nop!)
(.mul.x.vf vf12 vf3 vf8)
(nop!)
(.nop.vf)
(nop!)
(.div.vf Q vf0 vf8 :fsf #b11 :ftf #b0)
(nop!)
(.mul.vf vf22 vf12 vf12)
(nop!)
(.abs.vf vf23 vf12)
(nop!)
(.add.y.vf.x vf22 vf22 vf22)
(.mov v1-11 vf23)
(.wait.vf)
(nop!)
(.add.vf.x vf8 vf0 Q)
(nop!)
(b! (zero? v1-11) cfg-12 :likely-delay (.add.z.vf.x vf13 vf0 vf12))
(.sub.y.vf.x vf13 vf0 vf12)
(nop!)
(.isqrt.vf Q vf0 vf22 :fsf #b11 :ftf #b0)
(nop!)
(.add.x.vf.y vf13 vf0 vf12)
(nop!)
(.wait.vf)
(nop!)
(.mul.vf.xy vf13 vf13 Q)
(nop!)
(label cfg-12)
(.outer.product.a.vf acc vf12 vf13)
(nop!)
(.add.x.vf.x vf11 vf11 vf8)
(nop!)
(.outer.product.b.vf vf14 vf13 vf12 acc)
(nop!)
(.ftoi.vf vf16 vf11)
(nop!)
(.mov.vf vf17 vf12)
(nop!)
(.mov.vf vf18 vf13)
(nop!)
(.mov.vf vf19 vf14)
(nop!)
(.mov.vf.yzw vf17 vf0)
(.svf (&-> arg0 local-box4w max quad) vf16)
(.mov.vf.xzw vf18 vf0)
(nop!)
(.mov.vf.xyw vf19 vf0)
(nop!)
(.add.x.vf.y vf17 vf17 vf13)
(nop!)
(.add.y.vf.x vf18 vf18 vf12)
(nop!)
(.add.z.vf.x vf19 vf19 vf12)
(nop!)
(.add.x.vf.z vf17 vf17 vf14)
(nop!)
(.add.y.vf.z vf18 vf18 vf14)
(nop!)
(.add.z.vf.y vf19 vf19 vf13)
(nop!)
(.mul.x.vf acc vf17 vf1)
(nop!)
(.add.mul.y.vf acc vf18 vf1 acc)
(.svf (&-> arg0 inv-mat rvec quad) vf17)
(.add.mul.z.vf vf20 vf19 vf1 acc)
(.svf (&-> arg0 inv-mat uvec quad) vf18)
(.sub.vf vf20 vf0 vf20)
(.svf (&-> arg0 inv-mat fvec quad) vf19)
(nop!)
(.svf (&-> arg0 inv-mat trans quad) vf20)
(set! (-> arg0 rlength x) (if (= (-> arg0 move-dist x) 0.0)
0.0
(/ 1.0 (-> arg0 move-dist x))
)
)
(set! (-> arg0 rlength y) (if (= (-> arg0 move-dist y) 0.0)
0.0
(/ 1.0 (-> arg0 move-dist y))
)
)
(set! (-> arg0 rlength z) (if (= (-> arg0 move-dist z) 0.0)
0.0
(/ 1.0 (-> arg0 move-dist z))
)
)
(let ((f0-19 1.0))
(.lvf vf1 (&-> (-> arg0 move-dist) quad))
(.add.w.vf.x vf2 vf0 vf0)
(.mul.vf vf1 vf1 vf1)
(.mul.x.vf.x acc vf2 vf1)
(.add.mul.y.vf.x acc vf2 vf1 acc)
(.add.mul.z.vf.x vf1 vf2 vf1 acc)
(.mov v1-20 vf1)
(set! (-> arg0 rlength w) (/ f0-19 v1-20))
)
(set! (-> arg0 exit-planes 0 x) (if (< 0.0 (-> arg0 move-dist x))
0.0
100000000000000000000000000000000000000.0
)
)
(set! (-> arg0 exit-planes 0 y) (if (< 0.0 (-> arg0 move-dist y))
0.0
100000000000000000000000000000000000000.0
)
)
(set! (-> arg0 exit-planes 0 z) (if (< 0.0 (-> arg0 move-dist z))
0.0
100000000000000000000000000000000000000.0
)
)
(set! (-> arg0 exit-planes 1 x) (if (< (-> arg0 move-dist x) 0.0)
0.0
100000000000000000000000000000000000000.0
)
)
(set! (-> arg0 exit-planes 1 y) (if (< (-> arg0 move-dist y) 0.0)
0.0
100000000000000000000000000000000000000.0
)
)
(set! (-> arg0 exit-planes 1 z) (if (< (-> arg0 move-dist z) 0.0)
0.0
100000000000000000000000000000000000000.0
)
)
(when (logtest? (-> arg0 collide-with) (collide-spec backgnd))
(fill-from-bg
this
(the-as
(function collide-hash int collide-list collide-query int)
(method-of-type collide-hash drawable-method-12)
)
collide-list-fill-bg-using-line-sphere
arg0
)
(dotimes (s4-0 (-> *level* length))
(let ((v1-36 (-> *level* level s4-0)))
(when (= (-> v1-36 status) 'active)
(let ((a0-18 (-> v1-36 bsp hfrag-drawable)))
(if (nonzero? a0-18)
(line-sphere-query (the-as hfragment a0-18) this arg0)
)
)
)
)
)
(let ((a0-19 (-> this num-tris)))
(when (> a0-19 0)
(let ((v1-43 (-> this prims))
(a1-11 *collide-shape-prim-backgnd*)
)
(set! (-> v1-43 0 num-tris) (the-as uint a0-19))
(set! (-> v1-43 0 prim) a1-11)
(set! (-> this num-prims) 1)
(set! (-> v1-43 0 first-tri) (the-as uint 0))
(set! (-> v1-43 0 ccache) this)
(set! (-> v1-43 0 prim-core world-sphere quad) (-> a1-11 prim-core world-sphere quad))
(set! (-> v1-43 0 prim-core quad 1) (-> a1-11 prim-core quad 1))
)
)
)
(+! (-> *collide-stats* output) (-> this num-tris))
)
(when (logtest? (-> arg0 collide-with) (collide-spec water))
(let ((a1-13 (-> (the-as process-drawable (-> arg0 ignore-process0)) water)))
(if (nonzero? a1-13)
(fill-from-water this a1-13)
)
)
)
(if (logtest? (-> arg0 collide-with) (collide-spec hit-by-player-list hit-by-others-list player-list))
(fill-from-fg-line-sphere this arg0)
)
0
(label cfg-55)
(none)
)
)
(defmethod fill-from-fg-boxes ((this collide-cache))
(let ((s5-0 (-> this collide-with)))
(set! *actor-list-length* 0)
(if (logtest? s5-0 (collide-spec hit-by-others-list))
(set! *actor-list-length* (add-an-object *actor-hash* (-> this collide-box) *actor-list* 256))
)
(when (logtest? s5-0 (collide-spec player-list))
(let ((a0-2 (-> *collide-player-list* alive-list next0)))
*collide-player-list*
(let ((v1-13 (-> a0-2 next0)))
(while (!= a0-2 (-> *collide-player-list* alive-list-end))
(let* ((a0-3 (-> (the-as connection a0-2) param1))
(a1-1 (-> (the-as collide-shape a0-3) root-prim))
)
(when (logtest? s5-0 (-> a1-1 prim-core collide-as))
(let ((a1-2 (-> a1-1 prim-core)))
(when (and (>= (+ (-> a1-2 world-sphere x) (-> a1-2 world-sphere w)) (-> this collide-box min x))
(>= (-> this collide-box max x) (- (-> a1-2 world-sphere x) (-> a1-2 world-sphere w)))
(>= (+ (-> a1-2 world-sphere y) (-> a1-2 world-sphere w)) (-> this collide-box min y))
(>= (-> this collide-box max y) (- (-> a1-2 world-sphere y) (-> a1-2 world-sphere w)))
(>= (+ (-> a1-2 world-sphere z) (-> a1-2 world-sphere w)) (-> this collide-box min z))
(>= (-> this collide-box max z) (- (-> a1-2 world-sphere z) (-> a1-2 world-sphere w)))
)
(when (< *actor-list-length* 256)
(set! (-> *actor-list* *actor-list-length*) (the-as collide-shape a0-3))
(set! *actor-list-length* (+ *actor-list-length* 1))
)
)
)
)
)
(set! a0-2 v1-13)
*collide-player-list*
(set! v1-13 (-> v1-13 next0))
)
)
)
)
(when (logtest? s5-0 (collide-spec hit-by-player-list))
(let ((a0-5 (-> *collide-hit-by-player-list* alive-list next0)))
*collide-hit-by-player-list*
(let ((v1-21 (-> a0-5 next0)))
(while (!= a0-5 (-> *collide-hit-by-player-list* alive-list-end))
(let* ((a0-6 (-> (the-as connection a0-5) param1))
(a1-13 (-> (the-as collide-shape a0-6) root-prim))
)
(when (logtest? s5-0 (-> a1-13 prim-core collide-as))
(let ((a1-14 (-> a1-13 prim-core)))
(when (and (>= (+ (-> a1-14 world-sphere x) (-> a1-14 world-sphere w)) (-> this collide-box min x))
(>= (-> this collide-box max x) (- (-> a1-14 world-sphere x) (-> a1-14 world-sphere w)))
(>= (+ (-> a1-14 world-sphere y) (-> a1-14 world-sphere w)) (-> this collide-box min y))
(>= (-> this collide-box max y) (- (-> a1-14 world-sphere y) (-> a1-14 world-sphere w)))
(>= (+ (-> a1-14 world-sphere z) (-> a1-14 world-sphere w)) (-> this collide-box min z))
(>= (-> this collide-box max z) (- (-> a1-14 world-sphere z) (-> a1-14 world-sphere w)))
)
(when (< *actor-list-length* 256)
(set! (-> *actor-list* *actor-list-length*) (the-as collide-shape a0-6))
(set! *actor-list-length* (+ *actor-list-length* 1))
)
)
)
)
)
(set! a0-5 v1-21)
*collide-hit-by-player-list*
(set! v1-21 (-> v1-21 next0))
)
)
)
)
(dotimes (s4-0 *actor-list-length*)
(let ((v1-26 (-> *actor-list* s4-0)))
(when (logtest? s5-0 (-> v1-26 root-prim prim-core collide-as))
(let ((a0-13 (-> v1-26 process)))
(if (not (or (= a0-13 (-> this ignore-processes 0)) (= a0-13 (-> this ignore-processes 1))))
(add-fg-prim-using-box (-> v1-26 root-prim) this)
)
)
)
)
)
)
0
(none)
)
;; WARN: Return type mismatch object vs none.
(defmethod add-fg-prim-using-box ((this collide-shape-prim) (arg0 collide-cache))
(format 0 "ERROR: Illegal collide-shape-prim type passed to collide-shape-prim::add-fg-prim-using-box!~%")
(none)
)
(defmethod-mips2c "(method 10 collide-shape-prim-mesh)" 10 collide-shape-prim-mesh)
(defmethod-mips2c "(method 10 collide-shape-prim-sphere)" 10 collide-shape-prim-sphere)
(defmethod-mips2c "(method 10 collide-shape-prim-group)" 10 collide-shape-prim-group)
(defmethod fill-from-fg-line-sphere ((this collide-cache) (arg0 collide-query))
(let ((s4-0 (-> arg0 collide-with)))
(set! *actor-list-length* 0)
(if (logtest? s4-0 (collide-spec hit-by-others-list))
(set! *actor-list-length* (fill-actor-list-for-sphere
*actor-hash*
(-> arg0 start-pos)
(-> arg0 move-dist)
(-> arg0 radius)
*actor-list*
256
-1
)
)
)
(let ((f30-0 0.0)
(s3-0 (new 'stack-no-clear 'matrix))
)
(let ((f0-1 (vector-length-squared (-> arg0 move-dist))))
(if (< 0.0 f0-1)
(set! f30-0 (/ 1.0 f0-1))
)
)
(when (logtest? s4-0 (collide-spec player-list))
(let ((v1-17 (-> *collide-player-list* alive-list next0)))
*collide-player-list*
(let ((s2-0 (-> v1-17 next0)))
(while (!= v1-17 (-> *collide-player-list* alive-list-end))
(let* ((s1-0 (-> (the-as connection v1-17) param1))
(v1-18 (-> (the-as collide-shape s1-0) root-prim))
)
(when (logtest? s4-0 (-> v1-18 prim-core collide-as))
(let ((s0-0 (-> v1-18 prim-core)))
(vector-! (-> s3-0 uvec) (-> s0-0 world-sphere) (-> arg0 start-pos))
(let* ((f1-2 (* (vector-dot (-> arg0 move-dist) (-> s3-0 uvec)) f30-0))
(f0-6 (fmax 0.0 (fmin 1.0 f1-2)))
)
(vector+float*! (-> s3-0 rvec) (-> arg0 start-pos) (-> arg0 move-dist) f0-6)
)
(when (< (vector-vector-distance-squared (-> s3-0 rvec) (-> s0-0 world-sphere))
(square (+ (-> arg0 radius) (-> s0-0 world-sphere w)))
)
(when (< *actor-list-length* 256)
(set! (-> *actor-list* *actor-list-length*) (the-as collide-shape s1-0))
(set! *actor-list-length* (+ *actor-list-length* 1))
)
)
)
)
)
(set! v1-17 s2-0)
*collide-player-list*
(set! s2-0 (-> s2-0 next0))
)
)
)
)
(when (logtest? s4-0 (collide-spec hit-by-player-list))
(let ((v1-38 (-> *collide-hit-by-player-list* alive-list next0)))
*collide-hit-by-player-list*
(let ((s2-1 (-> v1-38 next0)))
(while (!= v1-38 (-> *collide-hit-by-player-list* alive-list-end))
(let* ((s1-1 (-> (the-as connection v1-38) param1))
(v1-39 (-> (the-as collide-shape s1-1) root-prim))
)
(when (logtest? s4-0 (-> v1-39 prim-core collide-as))
(let ((s0-1 (-> v1-39 prim-core)))
(vector-! (-> s3-0 uvec) (-> s0-1 world-sphere) (-> arg0 start-pos))
(let* ((f1-8 (* (vector-dot (-> arg0 move-dist) (-> s3-0 uvec)) f30-0))
(f0-11 (fmax 0.0 (fmin 1.0 f1-8)))
)
(vector+float*! (-> s3-0 rvec) (-> arg0 start-pos) (-> arg0 move-dist) f0-11)
)
(when (< (vector-vector-distance-squared (-> s3-0 rvec) (-> s0-1 world-sphere))
(square (+ (-> arg0 radius) (-> s0-1 world-sphere w)))
)
(when (< *actor-list-length* 256)
(set! (-> *actor-list* *actor-list-length*) (the-as collide-shape s1-1))
(set! *actor-list-length* (+ *actor-list-length* 1))
)
)
)
)
)
(set! v1-38 s2-1)
*collide-hit-by-player-list*
(set! s2-1 (-> s2-1 next0))
)
)
)
)
)
(dotimes (s3-1 *actor-list-length*)
(let ((v1-58 (-> *actor-list* s3-1)))
(when (logtest? s4-0 (-> v1-58 root-prim prim-core collide-as))
(let ((a0-37 (-> v1-58 process)))
(if (not (or (= a0-37 (-> this ignore-processes 0)) (= a0-37 (-> this ignore-processes 1))))
(add-fg-prim-using-line-sphere (-> v1-58 root-prim) this arg0)
)
)
)
)
)
)
0
(none)
)
;; WARN: Return type mismatch object vs none.
(defmethod add-fg-prim-using-line-sphere ((this collide-shape-prim) (arg0 collide-cache) (arg1 object))
(format
0
"ERROR: Illegal collide-shape-prim type passed to collide-shape-prim::add-fg-prim-using-line-sphere!~%"
)
(none)
)
(defmethod-mips2c "(method 11 collide-shape-prim-mesh)" 11 collide-shape-prim-mesh)
(defmethod-mips2c "(method 11 collide-shape-prim-sphere)" 11 collide-shape-prim-sphere)
(defmethod-mips2c "(method 11 collide-shape-prim-group)" 11 collide-shape-prim-group)
(defmethod fill-and-probe-using-line-sphere ((this collide-cache) (arg0 collide-query))
(fill-using-line-sphere this arg0)
(probe-using-line-sphere this arg0)
)
(deftype collide-puls-work (structure)
((ignore-pat pat-surface)
(bsphere sphere :inline)
(move-dist vector :inline)
)
)
(defmethod probe-using-line-sphere ((this collide-cache) (arg0 collide-query))
(rlet ((vf0 :class vf)
(vf2 :class vf)
(vf3 :class vf)
(vf4 :class vf)
)
(init-vf0-vector)
(let ((s5-0 (new 'stack-no-clear 'collide-puls-work)))
(.lvf vf4 (&-> arg0 exit-planes 0 quad))
(.lvf vf3 (&-> arg0 start-pos quad))
(.lvf vf2 (&-> arg0 move-dist quad))
(set! (-> s5-0 ignore-pat) (-> arg0 ignore-pat))
(.mul.w.vf.w vf3 vf0 vf4)
(.svf (&-> s5-0 move-dist quad) vf2)
(.svf (&-> s5-0 bsphere quad) vf3)
(let ((s4-0 (the-as object (-> this prims)))
(f30-0 -100000000.0)
)
(countdown (s3-0 (-> this num-prims))
(when (and (logtest? (-> arg0 collide-with) (-> (the-as collide-cache-prim s4-0) prim-core collide-as))
(logtest? (-> arg0 action-mask) (-> (the-as collide-cache-prim s4-0) prim-core action))
)
(cond
((>= (-> (the-as collide-cache-prim s4-0) prim-core prim-type) 0)
(let ((f0-0 ((method-of-type collide-cache-prim resolve-moving-sphere-tri)
(the-as collide-cache-prim s4-0)
arg0
(-> s5-0 bsphere)
(-> s5-0 move-dist)
f30-0
(collide-action solid)
)
)
)
(if (>= f0-0 0.0)
(set! f30-0 f0-0)
)
)
)
(else
(when (not (logtest? (-> arg0 ignore-pat)
(-> (the-as collide-shape-prim-sphere (-> (the-as collide-cache-prim s4-0) prim)) pat)
)
)
(let ((f0-1 ((method-of-type collide-cache-prim resolve-moving-sphere-sphere)
(the-as collide-cache-prim s4-0)
arg0
(-> s5-0 bsphere)
(-> s5-0 move-dist)
f30-0
(collide-action solid)
)
)
)
(if (>= f0-1 0.0)
(set! f30-0 f0-1)
)
)
)
)
)
)
(set! s4-0 (-> (the-as (inline-array collide-cache-prim) s4-0) 1))
)
f30-0
)
)
)
)
(deftype lsmi-work (structure)
((best-u float)
(orig-best-u float)
(action uint32)
(cquery collide-query :inline)
)
)
(defmethod-mips2c "(method 9 collide-cache-prim)" 9 collide-cache-prim)
(defmethod-mips2c "(method 10 collide-cache-prim)" 10 collide-cache-prim)
;; this function is a cleaned up version of the MIPS2C'd (method 10 collide-cache-prim)
;; as far as I know, it works correctly, but I'm too scared to use it as the default
;; in case there's a subtle bug.
#|
(defmethod resolve-moving-sphere-sphere ((this collide-cache-prim)
(result collide-query)
(other sphere)
(move-dist vector)
(best-dist float)
(action collide-action))
"Update the `result` collide query with the result of moving `other` by `move-dist`
If best-dist is positive, it indicates a fraction of move-dist where we know there is already a collision.
So, collisions after this point should be ignored.
Additionally, the fraction along move-dist to have collision is returned, or a negative number if no collision is possible.
Note that a collision that occurs in move-dist, but after best-dist will return a negative number."
;; treat the incoming sphere as the "moving sphere", do collision detection:
(let* ((sphere-collide-pt (new 'stack-no-clear 'vector))
(u (moving-sphere-sphere-intersect
other ;; the incoming sphere's position/radius
move-dist ;; the delta position of incoming sphere, if no collision happens
(-> this world-sphere) ;; our position/radius
sphere-collide-pt ;; resulting position of sphere collision
))
)
;; if we are moving away from collision, there is no collision to report
(when (< u 0.0)
(return u)
)
;; if a previous prim has already found a closer collision, ignore this one.
(when (>= best-dist 0.0) ;; only if we've found something.
(when (<= best-dist u)
(return -100000000.0)
)
)
;; vector pointing from our center to the intersect point
;; if the incoming sphere moves this way, it will move it out of collision.
(let* ((escape-dir (vector-! (new 'stack-no-clear 'vector) sphere-collide-pt (-> this world-sphere)))
)
;; next, we'll reject collision if we collide with a solid, but our velocity is moving us out of collision
(when (and (logtest? action (collide-action solid))
(>= (vector-dot escape-dir move-dist) 0.0)
)
(return -100000000.0)
)
;; we'll now accept this as the real collision!
(set! (-> result best-my-tri intersect quad) (-> sphere-collide-pt quad))
(let ((p (the collide-shape-prim-sphere (-> this prim))))
(set! (-> result best-my-tri pat) (-> p pat))
(set! (-> result best-my-tri collide-ptr) p)
)
(vector-normalize! escape-dir 1.0)
(vector-copy! (-> result best-my-tri normal) escape-dir)
;; we need to fake a triangle for the collision result.
;; to do this, we need to find a vector that's perpendicular to our normal
(let ((triangle-rot (new 'stack-no-clear 'matrix)))
(vector-copy! (-> triangle-rot vector 0) escape-dir)
(cond
((and (= (-> escape-dir x) 0.0) (= (-> escape-dir y) 0.0))
;; unlikely case that escape is exactly along z. If this happens, pick unit x.
(set-vector! (-> triangle-rot vector 1) (-> escape-dir z) 0.0 0.0 1.0)
)
(else
;; normal case that there's some x/y component
(set-vector! (-> triangle-rot vector 1) (- 0.0 (-> escape-dir y)) (-> escape-dir x) 0.0 1.0)
(vector-normalize! (-> triangle-rot vector 1) 1.0)
)
)
;; pick final axis
(vector-cross! (-> triangle-rot vector 2)
(-> triangle-rot vector 0)
(-> triangle-rot vector 1))
;; position
(set! (-> triangle-rot quad 3)
(-> sphere-collide-pt quad))
;; transform
(vector-matrix*! (-> result best-my-tri vertex 0)
(new 'static 'vector :y 4096.0 :w 1.0)
triangle-rot)
(vector-matrix*! (-> result best-my-tri vertex 1)
(new 'static 'vector :y -4096.0 :z 4096.0 :w 1.0)
triangle-rot)
(vector-matrix*! (-> result best-my-tri vertex 2)
(new 'static 'vector :y -4096.0 :z -4096.0 :w 1.0)
triangle-rot)
)
u
)
)
)
|#
(defmethod fill-and-probe-using-spheres ((this collide-cache) (arg0 collide-query))
(fill-using-spheres this arg0)
(probe-using-spheres this arg0)
)
(defmethod fill-using-spheres ((this collide-cache) (arg0 collide-query))
(new 'stack-no-clear 'bounding-box)
(set-from-spheres!
(-> arg0 bbox)
(the-as (inline-array sphere) (-> arg0 best-dist))
(the-as int (-> arg0 best-other-prim))
)
(fill-using-bounding-box this arg0)
(none)
)
(defmethod-mips2c "(method 17 collide-cache)" 17 collide-cache)
(defmethod-mips2c "(method 9 collide-puss-work)" 9 collide-puss-work)
(defmethod-mips2c "(method 10 collide-puss-work)" 10 collide-puss-work)