Files
jak-project/goal_src/jak2/engine/data/art-h.gc
T
Hat Kid 710f3ac117 custom levels: etie and build actor support for jak2/3 (#3851)
Custom levels for Jak 2/3 now support envmapped TIE geometry. The TIE
extract was also changed to ignore materials that have the specular flag
set, but are missing a roughness texture.

Jak 2/3 now also support the `build-actor` tool.

The `build-custom-level` and `build-actor` macros now have a few new
options:

- Both now have a `force-run` option (`#f` by default) that, when set to
`#t`, will always run level/art group generation even if the output
files are up to date.
- `build-custom-level` has a `gen-fr3` option (`#t` by default) that,
when set to `#f`, will skip generating the FR3 file for the custom level
and only generate the GOAL level file to skip the potentially slow
process of finding and adding art groups and textures. Useful for when
you want to temporarily edit only the GOAL side of the level (such as
entity placement, etc.).
- `build-actor` has a `texture-bucket` option (default 0) which will
determine what DMA sink group the model will be placed in, which is
useful to determine the draw order of the model. Previously, this was
omitted, resulting in shadows not drawing over custom actors because the
actors were put in a bucket that is drawn after shadows (this behavior
can be restored with `:texture-bucket #f`).
2025-02-01 18:04:26 +01:00

449 lines
13 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;; name: art-h.gc
;; name in dgo: art-h
;; dgos: ENGINE, GAME
(declare-type res-lump basic)
(declare-type merc-ctrl art-element)
(declare-type joint-control basic)
(declare-type effect-control basic)
(declare-type ripple-control basic)
(declare-type shadow-control basic)
(declare-type shadow-geo basic)
(declare-type merc-eye-anim-block structure)
(defenum draw-control-status
:type uint16
:bitfield #t
(close-to-screen 0) ;; 1
(no-draw 1) ;; 2
(no-draw-temp 2) ;; 4
(on-screen 3) ;; 8
(uninited 4) ;; 16
(no-draw-bounds 5) ;; 32
(no-closest-distance 6) ;; 64
(math-skel 7) ;; 128
(force-vu1 8) ;; 256
(no-draw-bounds2 9) ;; 512
(force-fade 10) ;; 1024
(warp-cross-fade 11) ;; 2048
(lod-set 12) ;; 4096
(disable-fog 13) ;; 8192
(hud 14) ;; 16384
)
(defenum draw-control-data-format
:type uint8
:bitfield #f
(pris 0)
(merc 1)
)
(defenum draw-control-global-effect
:type uint8
:bitfield #t
(bit-0 0)
(bit-1 1) ;; 2
(title-light 2) ;; 4
(disable-envmap 3) ;; 8
)
;; DECOMP BEGINS
(deftype joint-anim (basic)
((name string)
(number int16)
(length int16)
)
)
(deftype joint-anim-matrix (joint-anim)
((data matrix :inline :dynamic :offset 16)
)
)
(deftype joint-anim-transformq (joint-anim)
((data transformq :inline :dynamic :offset 16)
)
)
(deftype joint-anim-drawable (joint-anim)
((data drawable :dynamic)
)
)
(deftype joint-anim-frame (structure)
((matrices matrix 2 :inline)
(data transformq :inline :dynamic)
)
(:methods
(new (symbol type int) _type_)
)
)
;; WARN: Return type mismatch structure vs joint-anim-frame.
(defmethod new joint-anim-frame ((allocation symbol) (type-to-make type) (arg0 int))
(let ((v1-1 (max 0 (+ arg0 -2))))
(the-as
joint-anim-frame
(new-dynamic-structure allocation type-to-make (the-as int (+ (-> type-to-make size) (* 48 v1-1))))
)
)
)
(deftype joint-anim-compressed-hdr (structure)
((control-bits uint32 14)
(num-joints uint32)
(matrix-bits uint32)
)
)
(deftype joint-anim-compressed-fixed (structure)
((hdr joint-anim-compressed-hdr :inline)
(offset-64 uint32)
(offset-32 uint32)
(offset-16 uint32)
(reserved uint32)
(data vector 133 :inline)
)
)
(deftype joint-anim-compressed-frame (structure)
((offset-64 uint32)
(offset-32 uint32)
(offset-16 uint32)
(reserved uint32)
(data vector 133 :inline)
)
)
(deftype joint-anim-compressed-control (structure)
((num-frames uint16)
(flags uint16)
(fixed-qwc uint32)
(frame-qwc uint32)
(fixed joint-anim-compressed-fixed)
(data joint-anim-compressed-frame :dynamic)
)
)
(deftype art (basic)
((name string :offset 8)
(length int32)
(extra res-lump)
)
(:methods
(login (_type_) _type_)
(get-art-by-name-method (_type_ string type) basic)
(get-art-idx-by-name-method (_type_ string type) int)
(needs-link? (_type_) symbol)
)
)
(deftype art-element (art)
((pad uint8 12)
)
)
(deftype art-mesh-anim (art-element)
((data basic :dynamic)
)
)
(deftype art-joint-anim (art-element)
((speed float :overlay-at (-> pad 0))
(artist-base float :overlay-at (-> pad 4))
(artist-step float :overlay-at (-> pad 8))
(eye-anim merc-eye-anim-block :offset 4)
(master-art-group-name string)
(master-art-group-index int32)
(blend-shape-anim (pointer int8))
(frames joint-anim-compressed-control)
)
)
(deftype art-group (art)
((info file-info :offset 4)
(data art-element :dynamic :offset 32)
)
(:methods
(relocate (_type_ kheap (pointer uint8)) none :replace)
(link-art! (_type_) art-group)
(unlink-art! (_type_) int)
)
)
(deftype art-mesh-geo (art-element)
((data basic :dynamic)
)
)
(deftype art-joint-geo (art-element)
((data joint :dynamic)
)
)
(deftype art-joint-anim-manager-slot (structure)
((anim art-joint-anim)
(comp-data uint32)
(time-stamp uint64)
)
)
(deftype art-joint-anim-manager (basic)
((kheap kheap :inline)
(free-index int32)
(slot art-joint-anim-manager-slot 64 :inline)
)
(:methods
(new (symbol type int) _type_)
(decompress (_type_ art-joint-anim) art-joint-anim)
(update-time-stamp (_type_ art-joint-anim) art-joint-anim)
(unload-from-slot (_type_ int) art-joint-anim)
(used-bytes-for-slot (_type_ int) int)
(unload-from-level (_type_ level) none)
)
)
(defmethod new art-joint-anim-manager ((allocation symbol) (type-to-make type) (arg0 int))
(let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
(let ((s4-0 (-> gp-0 kheap)))
(set! (-> s4-0 base) (kmalloc (the-as kheap (-> allocation value)) arg0 (kmalloc-flags) "heap"))
(set! (-> s4-0 current) (-> s4-0 base))
(set! (-> s4-0 top-base) (&+ (-> s4-0 base) arg0))
(set! (-> s4-0 top) (-> s4-0 top-base))
)
(dotimes (v1-6 64)
(set! (-> gp-0 slot v1-6 anim) #f)
)
(set! (-> gp-0 free-index) 0)
gp-0
)
)
(deftype skeleton-group (art-group)
((art-group-name string)
(jgeo int32)
(janim int32)
(bounds vector :inline)
(radius meters :overlay-at (-> bounds data 3))
(mgeo int16 6)
(max-lod int32)
(lod-dist float 6)
(longest-edge meters)
(texture-level int8)
(version int8)
(shadow int8)
(sort int8)
(origin-joint-index int8)
(shadow-joint-index int8)
(light-index uint8)
(pad uint8)
)
(:methods
(add-to-loading-level (_type_) skeleton-group)
)
)
(deftype lod-group (structure)
((geo merc-ctrl)
(dist meters)
)
:pack-me
)
(deftype lod-set (structure)
((lod lod-group 6 :inline)
(max-lod int8)
)
(:methods
(setup-lods! (_type_ skeleton-group art-group entity) _type_)
)
)
(deftype draw-control (basic)
((process process-drawable)
(status draw-control-status)
(data-format draw-control-data-format)
(global-effect draw-control-global-effect)
(art-group art-group)
(jgeo art-joint-geo)
(mgeo merc-ctrl)
(dma-add-func (function process-drawable draw-control symbol object none))
(skeleton skeleton)
(lod-set lod-set :inline)
(max-lod int8 :overlay-at (-> lod-set max-lod))
(force-lod int8)
(cur-lod int8)
(desired-lod int8)
(ripple ripple-control)
(longest-edge meters)
(longest-edge? uint32 :overlay-at longest-edge)
(light-index uint8)
(shadow-mask uint8)
(level-index uint8)
(death-draw-overlap uint8)
(death-timer uint8)
(death-timer-org uint8)
(death-vertex-skip uint16)
(death-effect uint32)
(shadow shadow-geo)
(shadow-ctrl shadow-control)
(distance meters)
(origin vector :inline)
(bounds vector :inline)
(radius meters :overlay-at (-> bounds data 3))
(color-mult rgbaf :inline)
(color-emissive rgbaf :inline)
(effect-mask uint64)
(seg-mask uint64)
(origin-joint-index uint8)
(shadow-joint-index uint8)
(force-fade uint8)
(default-texture-page uint8)
(shadow-values uint32)
)
(:methods
(new (symbol type process symbol) _type_)
(get-skeleton-origin (_type_) vector)
(lod-set! (_type_ int) none)
(lods-assign! (_type_ lod-set) none)
(setup-masks (_type_ int int) none)
(setup-cspace-and-add (_type_ art-joint-geo symbol) cspace-array)
(do-joint-math (_type_ cspace-array joint-control) none)
)
)
(defmethod get-skeleton-origin ((this draw-control))
(-> this skeleton bones 0 transform trans)
)
;; og:preserve-this
;; look up the index of an art element in an art group.
(desfun art-elt-index (ag-name elt-name)
(if (number? elt-name)
elt-name
(let ((ag-info (hash-table-try-ref *art-info* (symbol->string ag-name))))
(if (not (car ag-info))
(error (symbol->string ag-name))
(let ((elt-info (hash-table-try-ref (cdr ag-info) (symbol->string elt-name))))
(if (not (car elt-info))
(error (symbol->string ag-name))
(cadr (cdr elt-info)))
)
)
)
)
)
(defmacro joint-node-index (jg-name name)
(let ((jg-info (hash-table-try-ref *jg-info* (symbol->string jg-name))))
(if (not (car jg-info))
-1
(let ((joint-node (hash-table-try-ref (cdr jg-info) (if (integer? name) (int->string name) (symbol->string name)))))
(if (not (car joint-node))
-1
(cadr (cdr joint-node)))
)
)
)
)
(defmacro joint-node (jg name)
`(-> self node-list data (joint-node-index ,jg ,name))
)
(defmacro defskelgroup (name ag-name joint-geom joint-anim lods
&key (shadow 0)
&key bounds
&key (longest-edge 0.0)
&key (texture-level 0)
&key (sort 0)
&key (version 7) ;; do NOT use this!
&key (origin-joint-index 0)
&key (shadow-joint-index 0)
&key (light-index 0)
)
"define a new static skeleton group"
`(let ((skel (new 'static 'skeleton-group
:name ,(symbol->string name)
:info #f ;; all skeleton-groups seem to have these as #f
:extra #f
:art-group-name ,(symbol->string ag-name)
:bounds ,bounds
:longest-edge ,longest-edge
:version ,version
:max-lod ,(- (length lods) 1)
:shadow ,(art-elt-index (string->symbol-format "{}-ag" ag-name) shadow)
:texture-level ,texture-level
:sort ,sort
:origin-joint-index ,origin-joint-index
:shadow-joint-index ,shadow-joint-index
:light-index ,light-index
)))
;; set joint geometry and joint bones
(set! (-> skel jgeo) ,(art-elt-index (string->symbol-format "{}-ag" ag-name) joint-geom))
(set! (-> skel janim) ,(art-elt-index (string->symbol-format "{}-ag" ag-name) joint-anim))
;; set lods
,@(apply-i (lambda (x i)
`(begin
(set! (-> skel mgeo ,i) ,(art-elt-index (string->symbol-format "{}-ag" ag-name) (car x)))
(set! (-> skel lod-dist ,i) ,(cadr x))
)
) lods)
;; define skel group
(define ,name skel)
;; add to level
(add-to-loading-level ,name)
)
)
(defmacro def-actor (name &key (idle #f) &key (lods #f) &key (art (idle-ja)) &key (joints ()) &key (shadow 0) &key bounds &key (longest-edge 0.0) &key (texture-level 0) &key (sort 0) &key (version 7) &key (origin-joint-index 0) &key (shadow-joint-index 0) &key (light-index 0))
`(begin
(def-art-elt ,(string->symbol-format "{}-ag" name) ,(string->symbol-format "{}-lod0-jg" name) 0)
(def-art-elt ,(string->symbol-format "{}-ag" name) ,(string->symbol-format "{}-lod0-mg" name) 1)
,@(apply-i (lambda (x i)
`(def-art-elt ,(string->symbol-format "{}-ag" name) ,(string->symbol-format "{}-{}" name x) ,(+ i 2)))
art)
,@(apply-i (lambda (x i) `(def-joint-node ,(string->symbol-format "{}-lod0-jg" name) ,(symbol->string x) ,(1+ i))) joints)
(defskelgroup ,(string->symbol-format "*{}-sg*" name)
,name
,(string->symbol-format "{}-lod0-jg" name)
,(if idle (string->symbol-format "{}-{}" name idle) (string->symbol-format "{}-{}" name (car art)))
,(if lods
`(,@(apply (lambda (x) `(,(string->symbol-format "{}-{}-mg" name (car x)) (meters ,(cadr x)))) lods))
`((,(string->symbol-format "{}-lod0-mg" name) (meters 999999))))
:version ,version
:shadow ,shadow
:bounds (static-spherem ,@bounds)
:longest-edge ,longest-edge
:texture-level ,texture-level
:sort ,sort
:origin-joint-index ,origin-joint-index
:shadow-joint-index ,shadow-joint-index
:light-index ,light-index)))
(import "goal_src/jak2/engine/data/art-elts.gc")
(import "goal_src/jak2/engine/data/joint-nodes.gc")