Files
jak-project/goal_src/jak3/engine/anim/aligner-h.gc
T
water111 2a4d3d7a4a [decompiler] More inline vector functions (#3861)
This adds more recognition for inlined vector functions to the
decompiler, which can clean up a bunch of ugly looking code/`rlet`s.


![image](https://github.com/user-attachments/assets/1f7b4627-81bd-481b-b828-76b9f7ba13b3)

Unfortunately, this changes the numbering of ops in the decomp, since
all the vector instructions get combined in a single "operation" by the
decompiler. I really tried to avoid having this ever happen in the
decompiler and this is one of the few cases where it has. So I had to
update a bunch of type casts.

For that reason I haven't turned this on in Jak 2 yet, although I am
planning to do that at some point. (probably at the same time as porting
back a bunch of jak 3 improvements to jak 2)

---------

Co-authored-by: water111 <awaterford1111445@gmail.com>
2025-02-16 15:59:17 -05:00

88 lines
2.9 KiB
Common Lisp

;;-*-Lisp-*-
(in-package goal)
;; name: aligner-h.gc
;; name in dgo: aligner-h
;; dgos: GAME
;; +++align-opts
(defenum align-opts
:bitfield #t
:type uint32
(adjust-x-vel)
(adjust-y-vel)
(adjust-xz-vel)
(keep-other-velocities)
(adjust-quat) ;; 16
(alop0)
(alop1)
(alop2)
(alop3)
(alop4)
(alop5)
(no-gravity)
(ignore-y-if-zero)
)
;; ---align-opts
;; +++align-flags
(defenum align-flags
:bitfield #t
:type uint32
(disabled) ;; keep object velocity
)
;; ---align-flags
;; DECOMP BEGINS
(deftype align-control (basic)
"Align-control is a utility for moving a process-drawable based on its animation.
The animation format has two special parent-like joints: prejoint and align.
The prejoint is the parent for all joints, so it causes all bones to move.
The align joint has no children, but the convention is that moving align will
cause the entire process-drawable's root to move, effectively moving the entire character.
Most of the time, this is the preferable way to move a character as part of an animation -
it will update their velocity and when the animation ends or is canceled,
the offset in position from playing the animation will stay. For example, if Jak punches,
his velocity will increase due to the animated align in the punch animation.
To implement this, the align-control computes the relative transform between align frames.
To apply the position offset, typically the velocity is updated, then the normal per-frame
physics update will end up moving the position. For orientation, there is no concept of
angular velocity, so instead align-control directly modifies the quaternion.
Unlike normal animation evaluation, the alignment's blend is computed in a different way
that doesn't blend and instead just picks the most recently pushed animation."
((flags align-flags)
(process process-drawable)
(frame-group art-joint-anim)
(frame-num float)
(matrix matrix 2 :inline)
(transform transform 2 :inline)
(delta transformq :inline)
(last-speed meters)
(align transformq :inline :overlay-at (-> transform 0 trans data 0))
)
(:methods
(new (symbol type process) _type_)
(compute-delta-align! (_type_) transformq)
(align! (_type_ align-opts float float float) trsqv)
(adjust-root-no-gravity! (_type_ align-opts vector int float float) trsqv)
(first-transform (_type_) transform)
(second-transform (_type_) transform)
)
)
;; WARN: Return type mismatch object vs align-control.
(defmethod new align-control ((allocation symbol) (type-to-make type) (arg0 process))
(let ((this (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
(when (zero? this)
(go process-drawable-art-error "memory")
(return (the-as align-control 0))
)
(set! (-> this process) (the-as process-drawable arg0))
(the-as align-control this)
)
)