mirror of
https://github.com/open-goal/jak-project
synced 2026-08-08 02:31:30 -04:00
122de4ecf5
After spending the last month staring at and comparing Jak 3 and Jak 1 versions of a bunch of `target` code for my jetboard mod, I figured this would be a good opportunity to revive this ancient PR #1714 along with some other small misc fixes/improvements. Instead of directly replacing the old fields, I decided to opt for using overlay fields to maintain backwards compatibility with existing manual patches, files without ref tests and mods that might use these fields.
712 lines
26 KiB
Common Lisp
712 lines
26 KiB
Common Lisp
;;-*-Lisp-*-
|
|
(in-package goal)
|
|
(bundles "ENGINE.CGO" "GAME.CGO")
|
|
(require "engine/collide/pat-h.gc")
|
|
(require "engine/math/quaternion.gc")
|
|
(require "kernel/gkernel-h.gc")
|
|
(require "engine/math/transformq-h.gc")
|
|
(require "engine/game/game-h.gc")
|
|
(require "engine/engine/connect.gc")
|
|
|
|
;; What is collide-shape?
|
|
;; A collide shape is a group of collision geometry. Typically, each actor will have a single collide shape.
|
|
;; Each collide shape may contain a number of collide-shape-prim's.
|
|
|
|
;; There are subclasses of collide-shape-prim for different types of collision primitives.
|
|
;; The types are:
|
|
;; - mesh. A foreground collision mesh. This has a fixed max size, so something have multiple meshes.
|
|
;; - group. A list of other prims.
|
|
;; - sphere. A sphere.
|
|
|
|
;; The non-sphere classes also store a bsphere that must contain all collision geometry.
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; New vs. Old Collide System
|
|
;; There are, effectively, two systems for collision queries.
|
|
|
|
;; Things that are shared:
|
|
;; Both systems use "collide-shape".
|
|
;; Both systems track foreground collision objects through the lists:
|
|
;; - collide-player-list
|
|
;; - collide-hit-by-player-list
|
|
;; - collide-usually-hit-by-player-list
|
|
|
|
;; The "old" system:
|
|
;; - generally uses recursive traversals through the collide shape tree
|
|
;; - uses "collide-mesh-cache".
|
|
;; - can't collide with water or the background.
|
|
|
|
;; The "new" system:
|
|
;; - is the only way to collide with the background/water
|
|
;; - uses "collide-cache"
|
|
;; - generally dumps stuff into the collide-cache, then uses collide-cache functions
|
|
;; - does not support a few of the weirder collision checks
|
|
|
|
;; There is some duplicate implemenations because both the new and old system collide
|
|
;; foreground meshes. The new system can just import foreground collision meshes
|
|
;; into its collide cache.
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; Collision queries:
|
|
|
|
;; Push Away.
|
|
;; Some objects move on fixed paths (like platforms). When these move forward, they should "push away"
|
|
;; things they hit (generally, Jak). Push Away only works between foreground objects and uses the old system.
|
|
;; The do-push-aways! function should be called after moving a shape to push away things that you hit.
|
|
;; Internally, this uses things called SPAT/should-push-away-test.
|
|
;; The push-aways use the collide resolve system (described below) to actually push things aways
|
|
;; (you can't push-away something through a wall, for example.)
|
|
|
|
;; Collide Resolve. (made up name)
|
|
;; Some objects (like Jak) do not move on fixed paths, and will be stopped by walls or other obstacles.
|
|
;; This works on background and foreground objects, and uses the new system (it must, to handle background).
|
|
;; The fill-cache-integrate-and-collide! function should be called, which will fill the collide cache
|
|
;; and then do an iterative collision algorithm.
|
|
;; This will call the reaction function. The default "default-collision-reaction" function is in collide-shape.gc
|
|
;; will fill the touching list.
|
|
|
|
;; Nav Enemy Collision (made up name)
|
|
;; collide-shape-moving-method-58 and integrate-for-enemy-with-move-to-ground are nav-enemy specific.
|
|
;; the details aren't super well understood yet. But they basically try to go forward if they aren't blocked.
|
|
;; Uses find-overlapping-shapes as the detector. (old system)
|
|
|
|
;; Move To Ground.
|
|
;; move-to-ground. Does what it says. (new system)
|
|
|
|
;; detect-riders
|
|
;; for platforms, detect if somebody is on the platform. (on-platform-test)
|
|
;; uses old system. Sends event adds to rider list.
|
|
|
|
(declare-type touching-list structure)
|
|
|
|
(declare-type collide-shape-prim basic)
|
|
|
|
;; DECOMP BEGINS
|
|
|
|
;;;;;;;;;;;;;;;;;;;
|
|
;; Sticky Rider
|
|
;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; Rider: thing which rides on a moving thing. For example, Jak is a rider of the platforms.
|
|
;; Sticky: when you hit the platform, your velocity immediately changes to match the thing.
|
|
;; like when Jak lands on a platform.
|
|
|
|
(deftype collide-sticky-rider (structure)
|
|
((rider-handle handle)
|
|
(sticky-prim collide-shape-prim)
|
|
(prim-ry float)
|
|
(rider-local-pos vector :inline))
|
|
(:methods
|
|
(set-rider! (_type_ handle) symbol)))
|
|
|
|
(defmethod set-rider! ((this collide-sticky-rider) (arg0 handle))
|
|
"Set the rider and clear the primitive."
|
|
(set! (-> this rider-handle) arg0)
|
|
(set! (-> this sticky-prim) #f)
|
|
#f)
|
|
|
|
;; A collection of collide-sticky-riders
|
|
;; dynamic type. There's one collide-sticky-rider per rider.
|
|
(deftype collide-sticky-rider-group (basic)
|
|
((num-riders int32)
|
|
(allocated-riders int32)
|
|
(rider collide-sticky-rider 1 :inline))
|
|
(:methods
|
|
(new (symbol type int) _type_)
|
|
(add-rider! (_type_ process-drawable) collide-sticky-rider)
|
|
(reset! (_type_) int)))
|
|
|
|
(defmethod reset! ((this collide-sticky-rider-group))
|
|
"Reset all active riders"
|
|
(set! (-> this num-riders) 0)
|
|
0)
|
|
|
|
;; The rider will be pulled along by the object.
|
|
;; This includes possibly rotating the rider (if the platform spins, it spins Jak too).
|
|
(deftype pull-rider-info (structure)
|
|
((rider collide-sticky-rider)
|
|
(rider-cshape collide-shape-moving)
|
|
(rider-delta-ry float)
|
|
(rider-dest vector :inline)))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Collision Result
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; Most general collision result from colliding two collide shapes
|
|
;; this computes a "move-vec" and "u". If you move along "move-vec" by "u", you will move out of collsion.
|
|
;; It also tells you which primitives are colliding.
|
|
(deftype collide-shape-intersect (basic)
|
|
((move-vec vector :inline)
|
|
(best-u float)
|
|
(best-tri collide-tri-result :inline)
|
|
(best-from-prim collide-shape-prim)
|
|
(best-to-prim collide-shape-prim))
|
|
(:methods
|
|
(init! (_type_ vector) symbol)))
|
|
|
|
;; Collision with just overlap distance, no vector.
|
|
(deftype collide-overlap-result (structure)
|
|
((best-dist float)
|
|
(best-from-prim collide-shape-prim)
|
|
(best-to-prim collide-shape-prim)
|
|
(best-from-tri collide-tri-result :inline))
|
|
(:methods
|
|
(reset! (_type_) none)))
|
|
|
|
(defmethod reset! ((this collide-overlap-result))
|
|
"Reset the result."
|
|
(set! (-> this best-dist) 0.0)
|
|
(set! (-> this best-from-prim) #f)
|
|
(set! (-> this best-to-prim) #f)
|
|
(none))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Touching System
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; I believe this overlaps-others-params is used to do checks like "is enemy in range of attack".
|
|
;; but this isn't well understood yet
|
|
|
|
(deftype overlaps-others-params (structure)
|
|
((options uint32)
|
|
(tlist touching-list)))
|
|
|
|
;; The engine system is used to link collision checks with processes.
|
|
;; This allows you to have lists of processes where the process will remove itself when it dies.
|
|
(define *collide-hit-by-player-list* (new 'global 'engine 'collide-hit-by-player-list 768))
|
|
|
|
(define *collide-usually-hit-by-player-list* (new 'global 'engine 'collide-usually-hit-by-player-list 256))
|
|
|
|
(define *collide-hit-by-others-list* (new 'global 'engine 'collide-hit-by-others-list 96))
|
|
|
|
(define *collide-player-list* (new 'global 'engine 'collide-player-list 32))
|
|
|
|
(defenum collide-list-enum
|
|
(hit-by-player)
|
|
(usually-hit-by-player)
|
|
(hit-by-others)
|
|
(player))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Collision Primitive Base
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; These are the settings that can be set per primitive.
|
|
|
|
(defenum collide-kind
|
|
:type uint64
|
|
:bitfield #t
|
|
(background 0)
|
|
(cak-1 1) ;; hit by player
|
|
(cak-2 2) ;; usually hit by player
|
|
(cak-3 3) ;; hit by others
|
|
(target 4) ;; target
|
|
(water 5)
|
|
(powerup 6)
|
|
(crate 7)
|
|
(enemy 8) ;; also used for powerups
|
|
(wall-object 9) ;; also object. door, pusher (blockers?)
|
|
(projectile 10)
|
|
(ground-object 11) ;; object, like darkecobarray, platforms
|
|
(target-attack 12) ;; all target attacks
|
|
(mother-spider 13)
|
|
(cak-14 14) ;; unused
|
|
(blue-eco-suck 15) ;; manipy, orb-cache-top,
|
|
(unknown-16 16)
|
|
(unknown-17 17)
|
|
(unknown-18 18)
|
|
(unknown-19 19)
|
|
(unknown-20 20)
|
|
(unknown-21 21)
|
|
(unknown-22 22)
|
|
(unknown-23 23)
|
|
(unknown-24 24)
|
|
(unknown-25 25)
|
|
(unknown-26 26)
|
|
(unknown-27 27)
|
|
(unknown-28 28)
|
|
(unknown-29 29)
|
|
(unknown-30 30)
|
|
(unknown-31 31)
|
|
(unknown-32 32)
|
|
(unknown-33 33)
|
|
(unknown-34 34)
|
|
(unknown-35 35)
|
|
(unknown-36 36)
|
|
(unknown-37 37)
|
|
(unknown-38 38)
|
|
(unknown-39 39)
|
|
(unknown-40 40)
|
|
(unknown-41 41)
|
|
(unknown-42 42)
|
|
(unknown-43 43)
|
|
(unknown-44 44)
|
|
(unknown-45 45)
|
|
(unknown-46 46)
|
|
(unknown-47 47)
|
|
(unknown-48 48)
|
|
(unknown-49 49)
|
|
(unknown-50 50)
|
|
(unknown-51 51)
|
|
(unknown-52 52)
|
|
(unknown-53 53)
|
|
(unknown-54 54)
|
|
(unknown-55 55)
|
|
(unknown-56 56)
|
|
(unknown-57 57)
|
|
(unknown-58 58)
|
|
(unknown-59 59)
|
|
(unknown-60 60)
|
|
(unknown-61 61)
|
|
(unknown-62 62)
|
|
(unknown-63 63))
|
|
|
|
(defenum collide-action
|
|
:type uint32
|
|
:bitfield #t
|
|
(solid 0) ;; used for solid things
|
|
(rider-plat-sticky 1) ;; used for platforms in rider/platform interactions
|
|
(rider-target 2) ;; used for target in rider/platform interactions
|
|
(edgegrab-active 3) ;; set/cleared when entering/exiting edgegrab states
|
|
(rider-plat 4) ;; used for platforms in rider/platform interactions
|
|
(unused 5) ;; totally unused?
|
|
(edgegrab-possible 6) ;; used when edge grab checks should be done
|
|
(edgegrab-cam 7) ;; set/cleared when entering/exiting edgegrab states
|
|
(swingpole-active 8) ;; set/cleared when entering/exiting swingpole states
|
|
(racer 9) ;; set/cleared when entering/exiting racer states
|
|
(attackable 10) ;; used for something to do with attacking/damaging
|
|
(attackable-unused 11) ;; seems to relate to attacking - set in several places but never tested for?
|
|
(snowball 12) ;; set/cleared when entering/exiting snowball states
|
|
(tube 13) ;; set/cleared when entering/exiting tube states
|
|
(flut 14) ;; set/cleared when entering/exiting flutflut states
|
|
(racer-grounded 15) ;; set/cleared when entering/exiting certain racer states w/ extra conditions
|
|
(racer-unused 16) ;; seems to relate to racer - never set, only cleared in one place?
|
|
)
|
|
|
|
;; this field is a bit confusing. you have to have a higher offense to win against an object.
|
|
;; so a normal crate has an offense of 1, meaning you have to do _more_ than just touch it to go through it.
|
|
;; a scout fly crate has 2, so you have to do _more_ than an normal attack.
|
|
;; This system is _only_ for going through objects - there's more logic for deciding if you can break it.
|
|
(defenum collide-offense
|
|
:type int8
|
|
(no-offense 0)
|
|
(touch 1) ;; just have to touch
|
|
(normal-attack 2) ;; any attack (like a normal crate)
|
|
(strong-attack 3) ;; hit with zoomer, slide, ground pound/flop, flut attack
|
|
(indestructible 4) ;; can't attack it.
|
|
)
|
|
|
|
;; Every primitive has a prim-core.
|
|
;; this is a 32-byte chunk of data that can be pulled out an put in collide caches
|
|
;; it stores the transformed world sphere and the collision settings
|
|
(deftype collide-prim-core (structure)
|
|
((world-sphere vector :inline)
|
|
(collide-as collide-kind)
|
|
(action collide-action)
|
|
(offense collide-offense)
|
|
(prim-type int8)
|
|
(extra uint8 2)
|
|
(quad uint128 2 :overlay-at (-> world-sphere quad))))
|
|
|
|
(declare-type collide-shape basic)
|
|
|
|
(declare-type collide-cache-prim structure)
|
|
|
|
(declare-type collide-shape-prim-group basic)
|
|
|
|
(declare-type collide-cache basic)
|
|
|
|
;; the base class for collision shapes.
|
|
(deftype collide-shape-prim (basic)
|
|
((cshape collide-shape)
|
|
(prim-id uint32)
|
|
(transform-index int8)
|
|
(prim-core collide-prim-core :inline)
|
|
(local-sphere vector :inline)
|
|
(collide-with collide-kind)
|
|
(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))
|
|
(radius meters :overlay-at (-> local-sphere w)))
|
|
(:methods
|
|
(new (symbol type collide-shape uint int) _type_)
|
|
(move-by-vector! (_type_ vector) none)
|
|
(find-prim-by-id (_type_ uint) collide-shape-prim)
|
|
(debug-draw-world-sphere (_type_) symbol)
|
|
(add-fg-prim-using-box (_type_ collide-cache) none)
|
|
(add-fg-prim-using-line-sphere (_type_ collide-cache) none)
|
|
(add-fg-prim-using-y-probe (_type_ collide-cache) none)
|
|
(overlaps-others-test (_type_ overlaps-others-params collide-shape-prim) symbol)
|
|
(overlaps-others-group (_type_ overlaps-others-params collide-shape-prim-group) symbol)
|
|
(unused-17 () none)
|
|
(collide-with-collide-cache-prim-mesh (_type_ collide-shape-intersect collide-cache-prim) none)
|
|
(collide-with-collide-cache-prim-sphere (_type_ collide-shape-intersect collide-cache-prim) none)
|
|
(add-to-bounding-box (_type_ collide-kind) symbol)
|
|
(num-mesh (_type_ collide-shape-prim) int)
|
|
(on-platform-test (_type_ collide-shape-prim collide-overlap-result float) none)
|
|
(should-push-away-test (_type_ collide-shape-prim collide-overlap-result) none)
|
|
(should-push-away-reverse-test (_type_ collide-shape-prim-group collide-overlap-result) none)
|
|
(update-transforms! (_type_ process-drawable) symbol)
|
|
(set-collide-as! (_type_ collide-kind) none)
|
|
(set-collide-with! (_type_ collide-kind) none)))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Specific Collision Implementation
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; generally, these store enough information to tell if you're in collision or not,
|
|
;; and if so, what the "pat" is. The meaning of "pat" is unknown, but it's a 32-bit
|
|
;; packed data that tells you the material/mode.
|
|
|
|
;; sphere collision
|
|
;; the pat is stored directly here.
|
|
;; I believe the "local sphere" is used as the sphere.
|
|
(deftype collide-shape-prim-sphere (collide-shape-prim)
|
|
((pat pat-surface))
|
|
(:methods
|
|
(new (symbol type collide-shape uint) _type_)))
|
|
|
|
;; mesh collision
|
|
;; the pats are stored per tri in the mesh.
|
|
;; These meshes interact with a cache automatically (a specific collide-shape-prim-mesh cache, not the
|
|
;; more general collide-cache)
|
|
(deftype collide-shape-prim-mesh (collide-shape-prim)
|
|
((mesh collide-mesh)
|
|
(mesh-id int32)
|
|
(mesh-cache-id uint64)
|
|
(mesh-cache-tris (inline-array collide-mesh-cache-tri)))
|
|
(:methods
|
|
(new (symbol type collide-shape uint uint) _type_)
|
|
(change-mesh (_type_ int) none)))
|
|
|
|
;; A group of collide-shape-prim's
|
|
(deftype collide-shape-prim-group (collide-shape-prim)
|
|
((num-prims int32)
|
|
(num-prims-u uint32 :overlay-at num-prims)
|
|
(allocated-prims int32)
|
|
(prim collide-shape-prim 1)
|
|
(prims collide-shape-prim :dynamic :overlay-at (-> prim 0)))
|
|
(:methods
|
|
(new (symbol type collide-shape uint int) _type_)
|
|
(append-prim (_type_ collide-shape-prim) none)
|
|
(add-to-non-empty-bounding-box (_type_ collide-kind) none)))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Collide Shape
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
;; This is sort of the "parent" of all collide prims for a process-drawable.
|
|
;; Each process-drawable (pd) should have one collide-shape, which is often the root.
|
|
;; It represents:
|
|
;; - the location of the thing in the world
|
|
;; - settings abouts collision/navigation
|
|
;; - riders
|
|
|
|
(declare-type collide-work structure)
|
|
|
|
(declare-type touching-shapes-entry structure)
|
|
|
|
(defenum nav-flags
|
|
:bitfield #t
|
|
:type uint8
|
|
(navf0 0)
|
|
(navf1 1)
|
|
(navf2 2)
|
|
(navf3 3)
|
|
(navf4 4)
|
|
(navf5 5)
|
|
(navf6 6)
|
|
(navf7 7))
|
|
|
|
;; we're a child of trsqv, so we store a full transform + derivative.
|
|
(deftype collide-shape (trsqv)
|
|
((process process-drawable)
|
|
(max-iteration-count uint8)
|
|
(nav-flags nav-flags)
|
|
(pad-byte uint8 2)
|
|
(pat-ignore-mask pat-surface)
|
|
(event-self symbol)
|
|
(event-other symbol)
|
|
(root-prim collide-shape-prim)
|
|
(riders collide-sticky-rider-group)
|
|
(backup-collide-as collide-kind)
|
|
(backup-collide-with collide-kind))
|
|
(:methods
|
|
(new (symbol type process-drawable collide-list-enum) _type_)
|
|
(move-by-vector! (_type_ vector) none)
|
|
(alloc-riders (_type_ int) none)
|
|
(move-to-point! (_type_ vector) none)
|
|
(debug-draw (_type_) none)
|
|
(fill-cache-for-shape! (_type_ float collide-kind) none)
|
|
(fill-cache-integrate-and-collide! (_type_ vector collide-kind) none)
|
|
(find-prim-by-id (_type_ uint) collide-shape-prim)
|
|
(detect-riders! (_type_) symbol)
|
|
(build-bounding-box-for-shape (_type_ bounding-box float collide-kind) symbol)
|
|
(integrate-and-collide! (_type_ vector) none)
|
|
(find-collision-meshes (_type_) symbol)
|
|
(on-platform (_type_ collide-shape collide-overlap-result) symbol)
|
|
(find-overlapping-shapes (_type_ overlaps-others-params) symbol)
|
|
(calc-shove-up (_type_ attack-info float) vector)
|
|
(should-push-away (_type_ collide-shape collide-overlap-result) symbol)
|
|
(pull-rider! (_type_ pull-rider-info) none)
|
|
(pull-riders! (_type_) symbol)
|
|
(do-push-aways! (_type_) symbol)
|
|
(set-root-prim! (_type_ collide-shape-prim) collide-shape-prim)
|
|
(update-transforms! (_type_) symbol)
|
|
(clear-collide-with-as (_type_) none)
|
|
(restore-collide-with-as (_type_) none)
|
|
(backup-collide-with-as (_type_) none)
|
|
(set-root-prim-collide-with! (_type_ collide-kind) none)
|
|
(set-root-prim-collide-as! (_type_ collide-kind) none)
|
|
(set-collide-kinds (_type_ int collide-kind collide-kind) none)
|
|
(set-collide-offense (_type_ int collide-offense) none)
|
|
(send-shove-back (_type_ process touching-shapes-entry float float float) none)))
|
|
|
|
(defenum cshape-moving-flags
|
|
:bitfield #t
|
|
:type uint64
|
|
(onsurf)
|
|
(onground)
|
|
(tsurf)
|
|
(twall)
|
|
(t-ceil)
|
|
(t-act)
|
|
(csmf06)
|
|
(csmf07)
|
|
(csmf08)
|
|
(csmf09)
|
|
(on-water)
|
|
(impact-surf)
|
|
(t-bckgnd)
|
|
(csmf13)
|
|
(t-ceil-sticky)
|
|
(csmf15)
|
|
(csmf16)
|
|
(csmf17)
|
|
(csmf18)
|
|
(csmf19)
|
|
(csmf20)
|
|
(csmf21)
|
|
(csmf22)
|
|
(csmf23)
|
|
(csmf24)
|
|
(csmf25)
|
|
(csmf26)
|
|
(csmf27)
|
|
(csmf28)
|
|
(csmf29))
|
|
|
|
(defenum cshape-reaction-flags
|
|
:bitfield #t
|
|
:type uint32
|
|
(csrf00)
|
|
(csrf01)
|
|
(csrf02)
|
|
(csrf03)
|
|
(csrf04)
|
|
(csrf05)
|
|
(csrf06)
|
|
(csrf07)
|
|
(csrf08)
|
|
(csrf09)
|
|
(csrf10)
|
|
(csrf11)
|
|
(csrf12)
|
|
(csrf13)
|
|
(csrf14)
|
|
(csrf15)
|
|
(csrf16)
|
|
(csrf17)
|
|
(csrf18)
|
|
(csrf19)
|
|
(csrf20)
|
|
(csrf21)
|
|
(csrf22)
|
|
(csrf23)
|
|
(csrf24)
|
|
(csrf25)
|
|
(csrf26)
|
|
(csrf27)
|
|
(csrf28)
|
|
(csrf29)
|
|
(csrf30)
|
|
(csrf31))
|
|
|
|
;; A collide-shape for independently moving objects
|
|
(deftype collide-shape-moving (collide-shape)
|
|
((rider-time time-frame)
|
|
(rider-last-move vector :inline)
|
|
(trans-old vector 3 :inline)
|
|
(poly-pat pat-surface)
|
|
(cur-pat pat-surface)
|
|
(ground-pat pat-surface)
|
|
(status cshape-moving-flags)
|
|
(old-status cshape-moving-flags)
|
|
(prev-status cshape-moving-flags)
|
|
(reaction-flag cshape-reaction-flags)
|
|
(reaction (function collide-shape-moving collide-shape-intersect vector vector cshape-moving-flags))
|
|
(no-reaction (function collide-shape-moving collide-shape-intersect vector vector none))
|
|
(local-normal vector :inline)
|
|
(surface-normal vector :inline)
|
|
(poly-normal vector :inline)
|
|
(ground-poly-normal vector :inline)
|
|
(ground-touch-point vector :inline)
|
|
(shadow-pos vector :inline)
|
|
(ground-impact-vel meters)
|
|
(surface-angle float)
|
|
(poly-angle float)
|
|
(touch-angle float)
|
|
(coverage float)
|
|
(dynam dynamics)
|
|
(surf surface))
|
|
(:methods
|
|
(set-and-handle-pat! (_type_ pat-surface) none)
|
|
(integrate-no-collide! (_type_ vector) none)
|
|
(collide-shape-moving-method-58 (_type_ vector) symbol)
|
|
(integrate-for-enemy-with-move-to-ground! (_type_ vector collide-kind float symbol symbol symbol) none)
|
|
(move-to-ground (_type_ float float symbol collide-kind) symbol)
|
|
(move-to-ground-point! (_type_ vector vector vector) none)
|
|
(compute-acc-due-to-gravity (_type_ vector float) vector)
|
|
(step-collison! (_type_ vector vector float) float)
|
|
(move-to-tri! (_type_ collide-tri-result vector) none)))
|
|
|
|
;;;;;;;;;;;;;;;;;;;;
|
|
;; Basic Methods
|
|
;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(defmethod new collide-shape-prim ((allocation symbol) (type-to-make type) (cshape collide-shape) (prim-id uint) (size-bytes int))
|
|
(let ((v0-0 (object-new allocation type-to-make size-bytes)))
|
|
(set! (-> v0-0 cshape) cshape)
|
|
(set! (-> v0-0 prim-id) prim-id)
|
|
(set! (-> v0-0 prim-core action) (collide-action))
|
|
(set! (-> v0-0 prim-core collide-as) (collide-kind))
|
|
(set! (-> v0-0 collide-with) (collide-kind))
|
|
(set! (-> v0-0 transform-index) -2)
|
|
(set! (-> v0-0 prim-core offense) (collide-offense no-offense))
|
|
(set! (-> v0-0 prim-core prim-type) -2)
|
|
v0-0))
|
|
|
|
(defmethod new collide-shape-prim-sphere ((allocation symbol) (type-to-make type) (cshape collide-shape) (prim-id uint))
|
|
"Allocate a new sphere primitive"
|
|
(let ((this (the collide-shape-prim-sphere
|
|
((method-of-type collide-shape-prim new) allocation type-to-make cshape prim-id (size-of collide-shape-prim-sphere)))))
|
|
(set! (-> this pat) (new 'static 'pat-surface :mode (pat-mode obstacle)))
|
|
(set! (-> this prim-core prim-type) -1)
|
|
this))
|
|
|
|
(defmethod new collide-shape-prim-mesh ((allocation symbol) (type-to-make type) (cshape collide-shape) (mesh-id uint) (prim-id uint))
|
|
"Allocate a new mesh primitive"
|
|
(let ((this (the collide-shape-prim-mesh
|
|
((method-of-type collide-shape-prim new) allocation type-to-make cshape prim-id (size-of collide-shape-prim-mesh)))))
|
|
(set! (-> this mesh) #f)
|
|
(set! (-> this mesh-id) (the-as int mesh-id))
|
|
(set! (-> this mesh-cache-id) (the-as uint 0))
|
|
(set! (-> this prim-core prim-type) 1)
|
|
(the-as collide-shape-prim-mesh this)))
|
|
|
|
(defmethod new collide-shape-prim-group ((allocation symbol) (type-to-make type) (cshape collide-shape) (elt-count uint) (prim-id int))
|
|
"Allocate a group of primitives."
|
|
(let ((this (the collide-shape-prim-group
|
|
((method-of-type collide-shape-prim new)
|
|
allocation
|
|
type-to-make
|
|
cshape
|
|
(the uint prim-id)
|
|
(the int (+ (-> type-to-make size) (* (+ elt-count -1) 4)))))))
|
|
(set! (-> this allocated-prims) (the int elt-count))
|
|
(set! (-> this num-prims) 0)
|
|
(set! (-> this prim-core prim-type) 0)
|
|
(while (nonzero? elt-count)
|
|
(+! elt-count -1)
|
|
(set! (-> this prim elt-count) (the collide-shape-prim #f))
|
|
(nop!))
|
|
this))
|
|
|
|
(defmethod length ((this collide-shape-prim-group))
|
|
"How many primitives are used?"
|
|
(-> this num-prims))
|
|
|
|
(defmethod asize-of ((this collide-shape-prim-group))
|
|
"How big is this in memory?"
|
|
(the-as int (+ (-> this type size) (* (+ (-> this allocated-prims) -1) 4))))
|
|
|
|
(defmethod new collide-shape ((allocation symbol) (type-to-make type) (proc process-drawable) (collide-list-kind collide-list-enum))
|
|
"Allocate a new collide-shape and add to a collide-list"
|
|
(let ((this (object-new allocation type-to-make (the int (-> type-to-make size)))))
|
|
(set! (-> this process) proc)
|
|
(set! (-> this max-iteration-count) 1)
|
|
(set! (-> this nav-flags) (nav-flags navf0))
|
|
(set! (-> this event-self) #f)
|
|
(set! (-> this event-other) #f)
|
|
(set! (-> this riders) #f)
|
|
(set! (-> this root-prim) #f)
|
|
(case (-> proc type symbol)
|
|
(('camera) (set! (-> this pat-ignore-mask) (new 'static 'pat-surface :nocamera #x1)))
|
|
(else (set! (-> this pat-ignore-mask) (new 'static 'pat-surface :noentity #x1))))
|
|
;; reset transformation to the origin.
|
|
(set! (-> this trans w) 1.0)
|
|
(quaternion-identity! (-> this quat))
|
|
(vector-identity! (-> this scale))
|
|
;; add us to right list.
|
|
(case collide-list-kind
|
|
(((collide-list-enum hit-by-player)) (add-connection *collide-hit-by-player-list* proc #f this #f #f))
|
|
(((collide-list-enum usually-hit-by-player)) (add-connection *collide-usually-hit-by-player-list* proc #f this #f #f))
|
|
(((collide-list-enum hit-by-others)) (add-connection *collide-hit-by-others-list* proc #f this #f #f))
|
|
(((collide-list-enum player)) (add-connection *collide-player-list* proc #f this #f #f))
|
|
(else (format 0 "Unsupported collide-list-enum in collide-shape constructor!~%")))
|
|
this))
|
|
|
|
(defmethod new collide-sticky-rider-group ((allocation symbol) (type-to-make type) (riders-amount int))
|
|
"Allocate a new collide-sticky-rider-group with space for riders-amount sticky riders."
|
|
(let ((this (object-new allocation
|
|
type-to-make
|
|
(the int (+ (-> type-to-make size) (the uint (* (1- riders-amount) (size-of collide-sticky-rider))))))))
|
|
(set! (-> this allocated-riders) riders-amount)
|
|
(set! (-> this num-riders) 0)
|
|
this))
|
|
|
|
(defmethod length ((this collide-sticky-rider-group))
|
|
(-> this num-riders))
|
|
|
|
(defmethod asize-of ((this collide-sticky-rider-group))
|
|
(the-as int (+ (-> this type size) (* (+ (-> this allocated-riders) -1) 32))))
|
|
|
|
(define *collide-shape-prim-backgnd*
|
|
(new 'static
|
|
'collide-shape-prim-mesh
|
|
:cshape #f
|
|
:prim-core
|
|
(new 'static
|
|
'collide-prim-core
|
|
:world-sphere
|
|
(new 'static 'vector :w 204800000.0)
|
|
:collide-as (collide-kind background)
|
|
:action (collide-action solid)
|
|
:offense (collide-offense indestructible)
|
|
:prim-type 2)
|
|
:local-sphere
|
|
(new 'static 'vector :w 204800000.0)
|
|
:mesh #f))
|
|
|
|
(define *collide-shape-prim-water*
|
|
(new 'static
|
|
'collide-shape-prim-mesh
|
|
:cshape #f
|
|
:prim-core
|
|
(new 'static
|
|
'collide-prim-core
|
|
:world-sphere
|
|
(new 'static 'vector :w 204800000.0)
|
|
:collide-as (collide-kind water)
|
|
:action (collide-action solid)
|
|
:offense (collide-offense indestructible)
|
|
:prim-type 2)
|
|
:local-sphere
|
|
(new 'static 'vector :w 204800000.0)
|
|
:mesh #f))
|