diff --git a/goal_src/jak2/engine/collide/collide-shape-h.gc b/goal_src/jak2/engine/collide/collide-shape-h.gc index 24cb16b97..1b30d5a20 100644 --- a/goal_src/jak2/engine/collide/collide-shape-h.gc +++ b/goal_src/jak2/engine/collide/collide-shape-h.gc @@ -671,3 +671,21 @@ ) (define-perm *collide-rider-pool* collide-rider-pool (new 'global 'collide-rider-pool)) + +(defmacro normalized-heading-to-quaternion! (quat heading) + "Modified for PC. This does a clever trick, but it doesn't work if the heading is exactly + [0, 0, -1] because this tries to normalize a quaternion that's all 0's. + I think that, on ps2, something prevents the heading from being exactly 0, 0, -1, + but this doesn't happen on PC. A similar thing happened with Jak 1's punch glitch, + where some trig functions were slightly off from returning exactly 0.0 and 1.0 on ps2 + rounding only." + `(begin + (if (and (= (-> ,heading x) 0.0) + (= (+ 1.0 (-> ,heading z)) 0.0) + ) + (quaternion-set! ,quat 0.0 1.0 0.0 0.0) + (quaternion-set! ,quat 0.0 (-> ,heading x) 0.0 (+ 1.0 (-> ,heading z))) + ) + (quaternion-normalize! ,quat) + ) + ) \ No newline at end of file diff --git a/goal_src/jak2/engine/nav/nav-enemy.gc b/goal_src/jak2/engine/nav/nav-enemy.gc index a02bec662..51e35b354 100644 --- a/goal_src/jak2/engine/nav/nav-enemy.gc +++ b/goal_src/jak2/engine/nav/nav-enemy.gc @@ -559,21 +559,9 @@ ) (set! (-> s5-0 y) 0.0) (vector-normalize! s5-0 1.0) - (quaternion-set! (-> obj root-override2 quat) 0.0 (-> s5-0 x) 0.0 (+ 1.0 (-> s5-0 z))) - ;; modified for PC: - ;; this code is doing a clever way to go from heading vector to quaternion, but it doesn't handle the case where - ;; the heading is exactly pointing along -z. So we do this manually - ;; There's two possible theories for how this worked on ps2: - ;; - it was just wrong, but instead of giving nans, it just points the guard in the wrong direction - ;; - the code that generates the heading on PS2 can't generate (0, 0, -1) exactly. - ;; (this was the case for punch glitch - the trig function acos couldn't reach 1.0 exactly with PS2 - ;; float rounding rules). - (when (and (= (-> s5-0 x) 0.0) - (= (+ 1.0 (-> s5-0 z)) 0.0) ;; actually the condition that causes problems - ) - (quaternion-set! (-> obj root-override2 quat) 0.0 1.0 0.0 0.0) - ) + ;; modified for PC, see comment near definition in collide-shape-h.gc + (normalized-heading-to-quaternion! (-> obj root-override2 quat) s5-0) ) (quaternion-normalize! (-> obj root-override2 quat)) 0 diff --git a/goal_src/jak2/levels/city/common/citizen.gc b/goal_src/jak2/levels/city/common/citizen.gc index 3f2643a87..513de4b71 100644 --- a/goal_src/jak2/levels/city/common/citizen.gc +++ b/goal_src/jak2/levels/city/common/citizen.gc @@ -610,8 +610,8 @@ (let ((gp-0 (new 'stack-no-clear 'quaternion)) (s5-1 (-> obj root-override2 quat)) ) - (quaternion-set! gp-0 0.0 (-> s3-0 x) 0.0 (+ 1.0 (-> s3-0 z))) - (quaternion-normalize! gp-0) + ;; modified for PC, see comment near definition in collide-shape-h.gc + (normalized-heading-to-quaternion! gp-0 s3-0) (quaternion-pseudo-seek s5-1 s5-1 diff --git a/goal_src/jak2/levels/stadium/stadium-obs.gc b/goal_src/jak2/levels/stadium/stadium-obs.gc index 41cfdbd49..93fc9388e 100644 --- a/goal_src/jak2/levels/stadium/stadium-obs.gc +++ b/goal_src/jak2/levels/stadium/stadium-obs.gc @@ -1777,8 +1777,7 @@ This commonly includes things such as: ) (set! (-> s4-0 y) 0.0) (vector-normalize! s4-0 1.0) - (quaternion-set! s5-0 0.0 (-> s4-0 x) 0.0 (+ 1.0 (-> s4-0 z))) - (quaternion-normalize! s5-0) + (normalized-heading-to-quaternion! s5-0 s4-0) ;; changed to avoid NaN issue (quaternion-slerp! (-> self root-override2 quat) (-> self root-override2 quat)