;;-*-Lisp-*-
(in-package goal)

;; name: rigid-body.gc
;; name in dgo: rigid-body
;; dgos: GAME

(deftype rigid-body-stack (structure)
  ((vec vector :inline)
   (mat matrix :inline)
    )
  )

;; DECOMP BEGINS

(deftype rigid-body-work (structure)
  ((max-ang-momentum  float)
   (max-ang-velocity  float)
   )
  )


(define *rigid-body-work* (new 'static 'rigid-body-work))

(defmethod new rigid-body-control ((allocation symbol) (type-to-make type) (arg0 process))
  (let ((v0-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
    (set! (-> v0-0 process) arg0)
    v0-0
    )
  )

(defmethod relocate ((this rigid-body-control) (offset int))
  (&+! (-> this process) offset)
  this
  )

(defmethod rigid-body-info-method-9 ((this rigid-body-info))
  (let ((f24-0 (-> this mass))
        (f28-0 (-> this inertial-tensor-box 0))
        (f30-0 (-> this inertial-tensor-box 1))
        (f26-0 (-> this inertial-tensor-box 2))
        )
    (let ((f0-0 f24-0))
      (set! (-> this inv-mass) (/ 1.0 f0-0))
      )
    (matrix-identity! (-> this inertial-tensor))
    (matrix-identity! (-> this inv-inertial-tensor))
    (let ((f0-4 (/ f24-0 12)))
      (let* ((f1-1 f30-0)
             (f1-3 (* f1-1 f1-1))
             (f2-0 f26-0)
             )
        (set! (-> this inertial-tensor rvec x) (* f0-4 (+ f1-3 (* f2-0 f2-0))))
        )
      (let ((f1-6 f28-0))
        (set! (-> this inertial-tensor uvec y) (* f0-4 (+ (* f1-6 f1-6) (* f26-0 f26-0))))
        )
      (set! (-> this inertial-tensor fvec z) (* f0-4 (+ (* f28-0 f28-0) (* f30-0 f30-0))))
      )
    )
  (let ((f0-6 (-> this inertial-tensor rvec x)))
    (set! (-> this inv-inertial-tensor rvec x) (/ 1.0 f0-6))
    )
  (let ((f0-9 (-> this inertial-tensor uvec y)))
    (set! (-> this inv-inertial-tensor uvec y) (/ 1.0 f0-9))
    )
  (let ((f0-12 (-> this inertial-tensor fvec z)))
    (set! (-> this inv-inertial-tensor fvec z) (/ 1.0 f0-12))
    )
  0
  (none)
  )

(defmethod reset-force-and-torque! ((this rigid-body-control))
  (set! (-> this force quad) (the-as uint128 0))
  (set! (-> this torque quad) (the-as uint128 0))
  0
  (none)
  )

(defmethod reset-momentum! ((this rigid-body-control))
  (set! (-> this lin-momentum quad) (the-as uint128 0))
  (set! (-> this ang-momentum quad) (the-as uint128 0))
  0
  (none)
  )

(defmethod rigid-body-control-method-26 ((this rigid-body-control))
  (when #t
    (quaternion->matrix (-> this matrix) (the-as quaternion (-> this rot)))
    (let ((s5-0 (new 'stack-no-clear 'vector)))
      (vector-rotate*! s5-0 (-> this info cm-offset-joint) (-> this matrix))
      (vector-! (-> this matrix trans) (-> this position) s5-0)
      )
    )
  0
  (none)
  )

(defmethod rigid-body-control-method-28 ((this rigid-body-control) (arg0 vector) (arg1 quaternion))
  (let ((s3-0 (new 'stack-no-clear 'rigid-body-stack)))
    (quaternion->matrix (-> s3-0 mat) arg1)
    (vector-rotate*! (-> s3-0 vec) (-> this info cm-offset-joint) (-> s3-0 mat))
    (vector+! (-> this position) arg0 (-> s3-0 vec))
    )
  (quaternion-copy! (the-as quaternion (-> this rot)) arg1)
  (quaternion-normalize! (the-as quaternion (-> this rot)))
  (rigid-body-control-method-26 this)
  0
  (none)
  )

(defmethod init! ((this rigid-body-control)
                 (arg0 rigid-body-info)
                 (arg1 vector)
                 (arg2 quaternion)
                 (arg3 (function rigid-body-object float))
                 )
  (set! (-> this info) arg0)
  (set! (-> this force-callback) (the-as (function rigid-body-object float none) arg3))
  (rigid-body-info-method-9 (-> this info))
  (let ((v1-2 this))
    (set! (-> v1-2 force quad) (the-as uint128 0))
    (set! (-> v1-2 torque quad) (the-as uint128 0))
    )
  0
  (reset-momentum! this)
  (rigid-body-control-method-28 this arg1 arg2)
  (init-velocities! this)
  (set! (-> this linear-damping) (-> arg0 linear-damping))
  (set! (-> this angular-damping) (-> arg0 angular-damping))
  (set! (-> this friction-factor) (-> arg0 friction-factor))
  (set! (-> this bounce-factor) (-> arg0 bounce-factor))
  0
  (none)
  )

;; WARN: Return type mismatch vector vs none.
(defmethod rigid-body-control-method-23 ((this rigid-body-control) (arg0 vector) (arg1 vector))
  (let ((v1-0 (new 'stack-no-clear 'inline-array 'vector 2)))
    (vector-! (-> v1-0 0) arg0 (-> this position))
    (vector-cross! (-> v1-0 1) (-> this ang-velocity) (-> v1-0 0))
    (vector+! arg1 (-> v1-0 1) (-> this lin-velocity))
    )
  (none)
  )

;; WARN: Return type mismatch vector vs none.
(defmethod rigid-body-control-method-24 ((this rigid-body-control) (arg0 vector) (arg1 vector))
  (let ((v1-0 (new 'stack-no-clear 'inline-array 'vector 2)))
    (vector-! (-> v1-0 0) arg0 (-> this position))
    (vector-cross! (-> v1-0 1) (-> this torque) (-> v1-0 0))
    (vector-float*! (-> v1-0 1) (-> v1-0 1) (/ 1.0 (vector-length-squared (-> v1-0 0))))
    (vector+! arg1 (-> v1-0 1) (-> this force))
    )
  (none)
  )

(defun matrix-3x3-triple-transpose-product ((arg0 matrix) (arg1 matrix) (arg2 matrix))
  (let ((s5-0 (new 'stack-no-clear 'inline-array 'matrix 3)))
    (matrix-copy! (-> s5-0 0) arg1)
    (vector-reset! (-> s5-0 0 trans))
    (matrix-transpose! (-> s5-0 1) (-> s5-0 0))
    (matrix*! (-> s5-0 2) arg2 (-> s5-0 0))
    (matrix*! arg0 (-> s5-0 1) (-> s5-0 2))
    )
  arg0
  )

(defmethod rigid-body-control-method-12 ((this rigid-body-control) (arg0 float))
  (vector+*! (-> this lin-momentum) (-> this lin-momentum) (-> this force) arg0)
  (vector+*! (-> this ang-momentum) (-> this ang-momentum) (-> this torque) arg0)
  (let* ((f0-3 (* 500000000.0 (-> this info mass)))
         (f1-1 f0-3)
         )
    (if (< (* f1-1 f1-1) (vector-length-squared (-> this ang-momentum)))
        (vector-normalize! (-> this ang-momentum) f0-3)
        )
    )
  (set! (-> this force quad) (the-as uint128 0))
  (set! (-> this torque quad) (the-as uint128 0))
  0
  0
  (none)
  )

(defmethod init-velocities! ((this rigid-body-control))
  (let ((v1-0 (-> this info)))
    (vector-float*! (-> this lin-velocity) (-> this lin-momentum) (-> v1-0 inv-mass))
    (matrix-3x3-triple-transpose-product (-> this inv-i-world) (-> this matrix) (-> v1-0 inv-inertial-tensor))
    )
  (vector-rotate*! (-> this ang-velocity) (-> this ang-momentum) (-> this inv-i-world))
  0
  (none)
  )

(defmethod rigid-body-control-method-14 ((this rigid-body-control) (arg0 float))
  (vector+*! (-> this position) (-> this position) (-> this lin-velocity) arg0)
  (let ((s4-0 (new 'stack-no-clear 'quaternion)))
    (set! (-> (the-as vector (&-> s4-0 x)) quad) (-> this ang-velocity quad))
    (set! (-> s4-0 w) 0.0)
    (quaternion*! s4-0 s4-0 (the-as quaternion (-> this rot)))
    (quaternion-float*! s4-0 s4-0 0.5)
    (+! (-> this rot x) (* (-> s4-0 x) arg0))
    (+! (-> this rot y) (* (-> s4-0 y) arg0))
    (+! (-> this rot z) (* (-> s4-0 z) arg0))
    (+! (-> this rot w) (* (-> s4-0 w) arg0))
    )
  (quaternion-normalize! (the-as quaternion (-> this rot)))
  (rigid-body-control-method-26 this)
  0
  (none)
  )

(defun damping-time-adjust ((arg0 float) (arg1 float))
  (let ((f0-0 0.0)
        (f1-0 1.0)
        (f2-2 (* -1.0 (- 1.0 arg0) arg1))
        (f3-3 0.016666668)
        )
    (fmax f0-0 (+ f1-0 (* f2-2 (/ 1.0 f3-3))))
    )
  )

(defmethod rigid-body-control-method-9 ((this rigid-body-control) (arg0 collide-shape-moving) (arg1 float))
  (rigid-body-control-method-12 this arg1)
  (-> this info)
  (let* ((v1-3 (-> this lin-momentum))
         (a0-2 (-> this lin-momentum))
         (f3-0 (-> this linear-damping))
         (f2-0 arg1)
         (f0-0 0.0)
         (f1-0 1.0)
         (f2-1 (* -1.0 (- 1.0 f3-0) f2-0))
         (f3-3 0.016666668)
         )
    (vector-float*! v1-3 a0-2 (fmax f0-0 (+ f1-0 (* f2-1 (/ 1.0 f3-3)))))
    )
  (let* ((v1-5 (-> this ang-momentum))
         (a0-3 (-> this ang-momentum))
         (f3-6 (-> this angular-damping))
         (f2-3 arg1)
         (f0-3 0.0)
         (f1-2 1.0)
         (f2-4 (* -1.0 (- 1.0 f3-6) f2-3))
         (f3-9 0.016666668)
         )
    (vector-float*! v1-5 a0-3 (fmax f0-3 (+ f1-2 (* f2-4 (/ 1.0 f3-9)))))
    )
  (init-velocities! this)
  (if (logtest? (-> this flags) (rigid-body-flag enable-collision))
      (rbody-collision arg0 this arg1)
      (rigid-body-control-method-14 this arg1)
      )
  0
  (none)
  )

(defmethod collide-with-all-collide-cache-prims ((this collide-shape-moving) (arg0 matrix) (arg1 collide-query))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf1 :class vf)
         (vf2 :class vf)
         (vf3 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         (vf6 :class vf)
         (vf7 :class vf)
         (vf8 :class vf)
         )
    (init-vf0-vector)
    (let ((s4-0 *collide-cache*)
          (s3-0 (-> this root-prim))
          (s2-0 1)
          )
      (when (zero? (-> s3-0 prim-core prim-type))
        (let ((v1-2 s3-0))
          (set! s3-0 (-> (the-as collide-shape-prim-group v1-2) child 0))
          (set! s2-0 (the-as int (-> v1-2 specific 0)))
          )
        )
      (b! #t cfg-13 :delay (nop!))
      (label cfg-3)
      (+! s2-0 -1)
      (let ((v1-4 -1))
        (b! (!= (-> s3-0 prim-core prim-type) v1-4) cfg-12 :delay (nop!))
        )
      (.lvf vf5 (&-> s3-0 local-sphere quad))
      (.lvf vf1 (&-> arg0 rvec quad))
      (.lvf vf2 (&-> arg0 uvec quad))
      (.lvf vf3 (&-> arg0 fvec quad))
      (.lvf vf4 (&-> arg0 trans quad))
      (.lvf vf6 (&-> s3-0 prim-core world-sphere quad))
      (.mul.x.vf acc vf1 vf5)
      (.add.mul.y.vf acc vf2 vf5 acc)
      (.add.mul.z.vf acc vf3 vf5 acc)
      (.add.mul.w.vf.xyz vf7 vf4 vf0 acc)
      (.sub.vf.xyz vf8 vf7 vf6)
      (.svf (&-> arg1 move-dist quad) vf8)
      (let ((s1-0 (the-as collide-cache-prim (-> s4-0 prims))))
        (countdown (s0-0 (-> s4-0 num-prims))
          (when (logtest? (-> s3-0 prim-core collide-with) (-> s1-0 prim-core collide-as))
            (if (>= (-> s1-0 prim-core prim-type) 0)
                (collide-with-collide-cache-prim-mesh s3-0 arg1 s1-0)
                (collide-with-collide-cache-prim-sphere s3-0 arg1 s1-0)
                )
            )
          (&+! s1-0 48)
          )
        )
      (label cfg-12)
      (&+! s3-0 80)
      (label cfg-13)
      (b! (nonzero? s2-0) cfg-3 :delay (nop!))
      )
    0
    (none)
    )
  )

(defun transform-rigid-body-prims ((arg0 collide-shape-prim) (arg1 matrix))
  (rlet ((acc :class vf)
         (vf0 :class vf)
         (vf1 :class vf)
         (vf2 :class vf)
         (vf3 :class vf)
         (vf4 :class vf)
         (vf5 :class vf)
         )
    (init-vf0-vector)
    (let ((v1-0 arg0)
          (a0-1 1)
          )
      (when (zero? (-> v1-0 prim-core prim-type))
        (let ((a0-2 (the-as collide-shape-prim-group v1-0)))
          (set! v1-0 (-> a0-2 child 0))
          (set! a0-1 (the-as int (-> a0-2 num-children)))
          )
        )
      (while (nonzero? a0-1)
        (+! a0-1 -1)
        (.lvf vf5 (&-> v1-0 local-sphere quad))
        (.lvf vf1 (&-> arg1 rvec quad))
        (.lvf vf2 (&-> arg1 uvec quad))
        (.lvf vf3 (&-> arg1 fvec quad))
        (.lvf vf4 (&-> arg1 trans quad))
        (.mul.x.vf acc vf1 vf5)
        (.add.mul.y.vf acc vf2 vf5 acc)
        (.add.mul.z.vf acc vf3 vf5 acc)
        (.add.mul.w.vf.xyz vf5 vf4 vf0 acc)
        (.svf (&-> v1-0 prim-core world-sphere quad) vf5)
        (&+! v1-0 80)
        )
      )
    #f
    )
  )

(deftype rigid-body-move-work (structure)
  ((cquery           collide-query      :inline)
   (best-dist        float              :overlay-at (-> cquery best-u))
   (mat              matrix             :inline)
   (impact-info      rigid-body-impact  :inline)
   (impact-info2     rigid-body-impact  :inline)
   (orig-position    vector             :inline)
   (orig-rotation    quaternion         :inline)
   (force            vector             :inline)
   (vel              vector             :inline)
   (p-body           vector             :inline)
   (tmp              vector             :inline)
   (tangent-dir      vector             :inline)
   (proc2            process-focusable)
   (rbody2           rigid-body-control)
   (vel-dot-norm     float)
   (denom            float)
   (denom2           float)
   (time-step        float)
   (time-step-scale  float)
   (step-count       int8)
   )
  )


(defmethod rbody-collision ((this collide-shape-moving) (arg0 rigid-body-control) (arg1 float))
  (rlet ((acc :class vf)
         (Q :class vf)
         (vf0 :class vf)
         (vf6 :class vf)
         (vf7 :class vf)
         (vf8 :class vf)
         (vf9 :class vf)
         )
    (init-vf0-vector)
    (let ((s5-0 (new 'stack-no-clear 'rigid-body-move-work)))
      (set! (-> s5-0 time-step) arg1)
      (set! (-> s5-0 time-step-scale) 1.0)
      (set! (-> s5-0 step-count) 0)
      (until (not (and (< 0.05 (-> s5-0 time-step-scale)) (< (-> s5-0 step-count) (the-as int (-> this max-iteration-count))))
                  )
        (set! (-> s5-0 cquery best-dist) -100000000.0)
        (set! (-> s5-0 cquery best-my-prim) #f)
        (set! (-> s5-0 cquery best-other-prim) #f)
        (vector-copy! (-> s5-0 orig-position) (-> arg0 position))
        (quaternion-copy! (-> s5-0 orig-rotation) (the-as quaternion (-> arg0 rot)))
        (rigid-body-control-method-14 arg0 (* (-> s5-0 time-step-scale) (-> s5-0 time-step)))
        (mem-copy! (the-as pointer (-> s5-0 mat)) (the-as pointer (-> arg0 matrix)) 64)
        (vector-copy! (-> arg0 position) (-> s5-0 orig-position))
        (quaternion-copy! (the-as quaternion (-> arg0 rot)) (-> s5-0 orig-rotation))
        (rigid-body-control-method-26 arg0)
        (transform-rigid-body-prims (-> this root-prim) (-> arg0 matrix))
        (collide-with-all-collide-cache-prims this (-> s5-0 mat) (-> s5-0 cquery))
        (let ((f30-0 (-> s5-0 cquery best-dist)))
          (b! (>= f30-0 0.0) cfg-3 :delay #f)
          (rigid-body-control-method-14 arg0 (* (-> s5-0 time-step-scale) (-> s5-0 time-step)))
          (init-velocities! arg0)
          (transform-rigid-body-prims (-> this root-prim) (-> arg0 matrix))
          (set! (-> s5-0 time-step-scale) 0.0)
          (b! #t cfg-55 :delay (nop!))
          (label cfg-3)
          (update-from-step-size *touching-list* f30-0)
          (rigid-body-control-method-14 arg0 (* (-> s5-0 time-step-scale) (-> s5-0 time-step) f30-0))
          )
        (init-velocities! arg0)
        (transform-rigid-body-prims (-> this root-prim) (-> arg0 matrix))
        (let* ((a2-3 (-> s5-0 mat))
               (a3-0 (-> arg0 matrix))
               (v1-21 (-> a3-0 rvec quad))
               (a0-19 (-> a3-0 uvec quad))
               (a1-12 (-> a3-0 fvec quad))
               (a3-1 (-> a3-0 trans quad))
               )
          (set! (-> a2-3 rvec quad) v1-21)
          (set! (-> a2-3 uvec quad) a0-19)
          (set! (-> a2-3 fvec quad) a1-12)
          (set! (-> a2-3 trans quad) a3-1)
          )
        (set! (-> s5-0 rbody2) #f)
        (set! (-> s5-0 proc2) #f)
        (when (-> s5-0 cquery best-other-prim)
          (set! (-> s5-0 proc2) (the-as process-focusable (-> s5-0 cquery best-other-prim cshape process)))
          (let ((v1-28 (-> s5-0 proc2 rbody)))
            (when (nonzero? v1-28)
              (set! (-> s5-0 rbody2) v1-28)
              (cond
                ((logtest? (-> v1-28 flags) (rigid-body-flag active))
                 (if (not (logtest? (-> v1-28 flags) (rigid-body-flag enable-physics)))
                     (send-event (-> s5-0 proc2) 'enable-physics)
                     )
                 )
                (else
                  (set! (-> s5-0 rbody2) #f)
                  )
                )
              )
            )
          )
        (let ((v1-33 (-> s5-0 cquery best-my-prim)))
          (.lvf vf7 (&-> (-> s5-0 cquery) best-other-tri intersect quad))
          (.lvf vf6 (&-> v1-33 prim-core world-sphere quad))
          (.sub.vf vf8 vf6 vf7)
          (.mul.vf.xyz vf9 vf8 vf8)
          (.mul.x.vf.w acc vf0 vf9)
          (.add.mul.y.vf.w acc vf0 vf9 acc)
          (.add.mul.z.vf.w vf9 vf0 vf9 acc)
          (.isqrt.vf Q vf0 vf9 :fsf #b11 :ftf #b11)
          (.mov.vf.w vf8 vf0)
          (.mov.vf.w vf7 vf0)
          (.wait.vf)
          (.mul.vf.xyz vf8 vf8 Q)
          (.nop.vf)
          (.nop.vf)
          (.nop.vf)
          (.svf (&-> s5-0 impact-info normal quad) vf8)
          (.svf (&-> s5-0 impact-info point quad) vf7)
          (set! (-> s5-0 impact-info prim-id) (-> v1-33 prim-id))
          )
        (set! (-> s5-0 impact-info pat) (-> s5-0 cquery best-other-tri pat))
        (rigid-body-control-method-23 arg0 (-> s5-0 impact-info point) (-> s5-0 impact-info velocity))
        (when (-> s5-0 rbody2)
          (init-velocities! (-> s5-0 rbody2))
          (rigid-body-control-method-23 (-> s5-0 rbody2) (-> s5-0 impact-info point) (-> s5-0 vel))
          (vector-! (-> s5-0 impact-info velocity) (-> s5-0 impact-info velocity) (-> s5-0 vel))
          )
        (set! (-> s5-0 impact-info impulse) 0.0)
        (set! (-> s5-0 vel-dot-norm)
              (+ -409.6 (vector-dot (-> s5-0 impact-info velocity) (-> s5-0 impact-info normal)))
              )
        (set! (-> s5-0 denom) 0.0)
        (set! (-> s5-0 denom2) 0.0)
        (b! (>= (-> s5-0 vel-dot-norm) 0.0) cfg-50)
        (vector-! (-> s5-0 p-body) (-> s5-0 impact-info point) (-> arg0 position))
        (vector-cross! (-> s5-0 tmp) (-> s5-0 p-body) (-> s5-0 impact-info normal))
        (vector-rotate*! (-> s5-0 tmp) (-> s5-0 tmp) (-> arg0 inv-i-world))
        (vector-cross! (-> s5-0 tmp) (-> s5-0 tmp) (-> s5-0 p-body))
        (set! (-> s5-0 denom) (+ (-> arg0 info inv-mass) (vector-dot (-> s5-0 impact-info normal) (-> s5-0 tmp))))
        (let ((f30-1 (-> arg0 bounce-factor)))
          (cond
            ((-> s5-0 proc2)
             (set! f30-1
                   (cond
                     ((-> s5-0 rbody2)
                      (vector-! (-> s5-0 p-body) (-> s5-0 impact-info point) (-> s5-0 rbody2 position))
                      (vector-cross! (-> s5-0 tmp) (-> s5-0 p-body) (-> s5-0 impact-info normal))
                      (vector-rotate*! (-> s5-0 tmp) (-> s5-0 tmp) (-> s5-0 rbody2 inv-i-world))
                      (vector-cross! (-> s5-0 tmp) (-> s5-0 tmp) (-> s5-0 p-body))
                      (set! (-> s5-0 denom2)
                            (+ (-> s5-0 rbody2 info inv-mass) (vector-dot (-> s5-0 impact-info normal) (-> s5-0 tmp)))
                            )
                      (fmax
                        (fmax f30-1 (-> s5-0 rbody2 bounce-factor))
                        (* (-> arg0 info bounce-mult-factor) (-> s5-0 rbody2 info bounce-mult-factor))
                        )
                      )
                     (else
                       (let ((a0-46 (as-type (-> s5-0 proc2) process-focusable)))
                         (if a0-46
                             (set! (-> s5-0 denom2) (get-inv-mass a0-46))
                             )
                         )
                       f30-1
                       )
                     )
                   )
             )
            (else
              )
            )
          (set! (-> s5-0 impact-info impulse)
                (* (+ 1.0 f30-1) (- (-> s5-0 vel-dot-norm)) (/ 1.0 (+ (-> s5-0 denom) (-> s5-0 denom2))))
                )
          )
        (set! (-> s5-0 impact-info process) (-> s5-0 proc2))
        (when (-> s5-0 proc2)
          (set! (-> s5-0 impact-info2 point quad) (-> s5-0 impact-info point quad))
          (vector-float*! (-> s5-0 impact-info2 normal) (-> s5-0 impact-info normal) -1.0)
          (vector-float*! (-> s5-0 impact-info2 velocity) (-> s5-0 impact-info velocity) -1.0)
          (set! (-> s5-0 impact-info2 impulse) (-> s5-0 impact-info impulse))
          (set! (-> s5-0 impact-info2 pat) (-> s5-0 impact-info pat))
          (set! (-> s5-0 impact-info2 prim-id) (-> s5-0 cquery best-other-prim prim-id))
          (set! (-> s5-0 impact-info2 process) (-> arg0 process))
          (send-event (-> s5-0 proc2) 'impact-impulse :from (-> arg0 process) (-> s5-0 impact-info2))
          (if (or (-> s5-0 rbody2) (let ((a0-53 (-> s5-0 proc2 root)))
                                     (logtest? (-> a0-53 penetrated-by) (penetrate vehicle))
                                     )
                  )
              0
              (set! (-> s5-0 impact-info impulse)
                    (* (-> s5-0 impact-info impulse) (/ (+ (-> s5-0 denom) (-> s5-0 denom2)) (-> s5-0 denom)))
                    )
              )
          )
        (send-event (-> arg0 process) 'impact-impulse :from (-> arg0 process) (-> s5-0 impact-info))
        (vector-float*! (-> s5-0 force) (-> s5-0 impact-info normal) (-> s5-0 impact-info impulse))
        (let ((f30-2 (-> arg0 info mass)))
          (if (-> s5-0 rbody2)
              (set! f30-2 (fmin f30-2 (-> s5-0 rbody2 info mass)))
              )
          (vector+float*!
            (-> s5-0 tangent-dir)
            (-> s5-0 impact-info velocity)
            (-> s5-0 impact-info normal)
            (- (-> s5-0 vel-dot-norm))
            )
          (vector-normalize! (-> s5-0 tangent-dir) 1.0)
          (let ((f0-39 (* -1.0 (fmin
                                 (* (vector-dot (-> s5-0 tangent-dir) (-> s5-0 impact-info velocity)) f30-2)
                                 (* (-> arg0 friction-factor) (-> s5-0 impact-info impulse))
                                 )
                          )
                       )
                )
            (vector+float*! (-> s5-0 force) (-> s5-0 force) (-> s5-0 tangent-dir) f0-39)
            )
          )
        (apply-impact! arg0 (-> s5-0 impact-info point) (-> s5-0 force))
        (when (-> s5-0 rbody2)
          (vector-float*! (-> s5-0 force) (-> s5-0 force) -1.0)
          (apply-impact! (-> s5-0 rbody2) (-> s5-0 impact-info point) (-> s5-0 force))
          )
        (rigid-body-control-method-12 arg0 1.0)
        (init-velocities! arg0)
        (let ((f30-3 (-> s5-0 cquery best-dist)))
          (when (< f30-3 0.0001)
            (vector+float*! (-> arg0 position) (-> arg0 position) (-> s5-0 impact-info normal) 40.96)
            (rigid-body-control-method-26 arg0)
            )
          (set! (-> s5-0 time-step-scale) (- (-> s5-0 time-step-scale) (* f30-3 (-> s5-0 time-step-scale))))
          )
        (when (-> s5-0 rbody2)
          (rigid-body-control-method-12 (-> s5-0 rbody2) 1.0)
          (init-velocities! (-> s5-0 rbody2))
          0
          )
        (+! (-> s5-0 step-count) 1)
        )
      (b! #t cfg-53 :delay (nop!))
      (label cfg-50)
      (when (-> s5-0 rbody2)
        (set! (-> arg0 blocked-by) (the-as process-focusable (-> s5-0 cquery best-other-prim cshape process)))
        0
        )
      (vector+float*! (-> arg0 position) (-> arg0 position) (-> s5-0 impact-info normal) 40.96)
      (rigid-body-control-method-26 arg0)
      0
      (label cfg-53)
      (when (< 0.0 (-> s5-0 time-step-scale))
        (rigid-body-control-method-14 arg0 (* (-> s5-0 time-step-scale) (-> s5-0 time-step)))
        (init-velocities! arg0)
        (transform-rigid-body-prims (-> this root-prim) (-> arg0 matrix))
        (set! (-> s5-0 time-step-scale) 0.0)
        )
      (label cfg-55)
      (let ((f0-53 (* (- 1.0 (-> s5-0 time-step-scale)) (-> s5-0 time-step))))
        (set! (-> arg0 time-remaining) (- (-> arg0 time-remaining) f0-53))
        )
      )
    0
    (none)
    )
  )

(defmethod apply-impact! ((this rigid-body-control) (arg0 vector) (arg1 vector))
  (vector+! (-> this force) (-> this force) arg1)
  (let ((v1-1 (new 'stack-no-clear 'inline-array 'vector 2)))
    (vector-! (-> v1-1 0) arg0 (-> this position))
    (vector-cross! (-> v1-1 1) (-> v1-1 0) arg1)
    (vector+! (-> this torque) (-> this torque) (-> v1-1 1))
    )
  0
  (none)
  )

(defmethod rigid-body-control-method-22 ((this rigid-body-control) (arg0 vector) (arg1 vector))
  (let ((v1-0 (new 'stack-no-clear 'inline-array 'vector 2)))
    (vector-! (-> v1-0 0) arg0 (-> this position))
    (vector-cross! (-> v1-0 1) (-> v1-0 0) arg1)
    (vector+! (-> this torque) (-> this torque) (-> v1-0 1))
    )
  0
  (none)
  )

(defmethod rigid-body-control-method-21 ((this rigid-body-control) (arg0 vector) (arg1 vector) (arg2 float))
  (vector+! (-> this force) (-> this force) arg1)
  (let* ((t0-2 (vector-! (new 'stack-no-clear 'vector) arg0 (-> this position)))
         (v1-3 (vector-cross! (new 'stack-no-clear 'vector) t0-2 arg1))
         )
    (let ((f0-0 (vector-length t0-2)))
      (if (< arg2 f0-0)
          (vector-float*! v1-3 v1-3 (/ arg2 f0-0))
          )
      )
    (vector+! (-> this torque) (-> this torque) v1-3)
    )
  0
  (none)
  )

(defmethod rigid-body-control-method-19 ((this rigid-body-control) (arg0 vector) (arg1 vector))
  (let ((s5-0 (new 'stack-no-clear 'vector))
        (s4-0 (new 'stack-no-clear 'vector))
        )
    (vector-rotate*! s4-0 arg1 (-> this matrix))
    (vector-rotate*! s5-0 arg0 (-> this matrix))
    (vector+! s5-0 s5-0 (-> this position))
    (apply-impact! this s5-0 s4-0)
    )
  0
  (none)
  )

(defmethod add-force! ((this rigid-body-control) (arg0 vector))
  (vector+! (-> this force) (-> this force) arg0)
  0
  (none)
  )

(defmethod rigid-body-control-method-25 ((this rigid-body-control) (arg0 vector))
  (let ((gp-0 (new 'stack-no-clear 'vector)))
    (vector-rotate*! gp-0 (-> this info cm-offset-joint) (-> this matrix))
    (vector-! arg0 (-> this position) gp-0)
    )
  arg0
  )

(defmethod debug-print-force-torque ((this rigid-body-control) (arg0 object))
  (format arg0 "  force ~M ~M ~M" (-> this force x) (-> this force y) (-> this force z))
  (format arg0 "  torque ~M ~M ~M~%" (-> this torque x) (-> this torque y) (-> this torque z))
  0
  (none)
  )

(defmethod debug-print-momentum ((this rigid-body-control) (arg0 object))
  (format arg0 "  lin-mom ~M ~M ~M" (-> this lin-momentum x) (-> this lin-momentum y) (-> this lin-momentum z))
  (format
    arg0
    "  ang-mom ~M ~M ~M~%"
    (-> this ang-momentum x)
    (-> this ang-momentum y)
    (-> this ang-momentum z)
    )
  0
  (none)
  )

(defmethod debug-print-velocity ((this rigid-body-control) (arg0 object))
  (format arg0 "  lin-vel ~M ~M ~M" (-> this lin-velocity x) (-> this lin-velocity y) (-> this lin-velocity z))
  (format
    arg0
    "  ang-vel ~f ~f ~f~%"
    (-> this ang-velocity x)
    (-> this ang-velocity y)
    (-> this ang-velocity z)
    )
  0
  (none)
  )

(defmethod debug-print-pos-rot ((this rigid-body-control) (arg0 object))
  (format arg0 "  position ~M ~M ~M" (-> this position x) (-> this position y) (-> this position z))
  (format arg0 "  rotation ~f ~f ~f ~f~%" (-> this rot x) (-> this rot y) (-> this rot z) (-> this rot w))
  0
  (none)
  )

(defmethod debug-print-info ((this rigid-body-control) (arg0 object))
  (debug-print-force-torque this arg0)
  (debug-print-pos-rot this arg0)
  (debug-print-momentum this arg0)
  (debug-print-velocity this arg0)
  0
  (none)
  )

;; WARN: Return type mismatch int vs object.
(defmethod rigid-body-control-method-10 ((this rigid-body-control) (arg0 rigid-body-object) (arg1 float) (arg2 float))
  (let* ((s4-1 (max 1 (min 4 (+ (the int (* 0.9999 (/ arg1 arg2))) 1))))
         (f30-0 (/ arg1 (the float s4-1)))
         (s3-0 (-> this force-callback))
         )
    (while (nonzero? s4-1)
      (+! s4-1 -1)
      (s3-0 arg0 f30-0)
      (rigid-body-control-method-9 this (-> arg0 root) f30-0)
      )
    )
  0
  )

(defmethod update-rbody-transform! ((this rigid-body-control) (arg0 collide-shape-moving))
  (quaternion-copy! (-> arg0 quat) (the-as quaternion (-> this rot)))
  (rigid-body-control-method-25 this (-> arg0 trans))
  (vector-copy! (-> arg0 transv) (-> this lin-velocity))
  0
  (none)
  )

(defmethod get-inv-mass ((this rigid-body-object))
  (-> this info info inv-mass)
  )

(defmethod rigid-body-object-method-37 ((this rigid-body-object))
  (let ((a0-1 (-> this info name)))
    (when (nonzero? a0-1)
      (set! (-> this info) (the-as rigid-body-object-constants (-> a0-1 value)))
      (set! (-> this rbody info) (-> this info info))
      )
    )
  (rigid-body-info-method-9 (-> this info info))
  (set! (-> this rbody force-callback) (method-of-object this apply-gravity!))
  0
  (none)
  )

(defmethod rigid-body-object-method-53 ((this rigid-body-object) (arg0 float))
  (when (logtest? (-> this flags) (rigid-body-object-flag player-impulse-force player-contact-force))
    (when (logtest? (-> this flags) (rigid-body-object-flag player-impulse-force))
      (logclear! (-> this flags) (rigid-body-object-flag player-impulse-force))
      (vector-float*! (-> this player-force) (-> this player-force) (/ 1.0 arg0))
      )
    (apply-impact! (-> this rbody) (-> this player-force-position) (-> this player-force))
    )
  0
  (none)
  )

(defmethod apply-gravity! ((this rigid-body-object) (arg0 float))
  (let ((a1-1 (new 'stack-no-clear 'vector)))
    (vector-reset! a1-1)
    (set! (-> a1-1 y) (* -1.0 (-> this info extra gravity) (-> this rbody info mass)))
    (add-force! (-> this rbody) a1-1)
    )
  0
  (none)
  )

(defmethod rigid-body-object-method-32 ((this rigid-body-object))
  (rigid-body-control-method-10 (-> this rbody) this (seconds-per-frame) (-> this max-time-step))
  (logclear! (-> this flags) (rigid-body-object-flag player-impulse-force player-contact-force))
  0
  (none)
  )

(defmethod rigid-body-object-method-54 ((this rigid-body-object))
  (rigid-body-control-method-10 (-> this rbody) this (-> this rbody time-remaining) (-> this max-time-step))
  0
  (none)
  )

(defmethod clear-impulse-force-flag! ((this rigid-body-object))
  (logclear! (-> this flags) (rigid-body-object-flag player-impulse-force player-contact-force))
  0
  (none)
  )

;; WARN: Return type mismatch int vs object.
(defmethod go-idle ((this rigid-body-object))
  (go (method-of-object this idle))
  0
  )

(defmethod alloc-rbody-control! ((this rigid-body-object) (arg0 rigid-body-object-constants))
  (set! (-> this info) arg0)
  (set! (-> this rbody) (new 'process 'rigid-body-control this))
  (update-transforms (-> this root))
  (init!
    (-> this rbody)
    (-> this info info)
    (-> this root trans)
    (-> this root quat)
    (the-as (function rigid-body-object float) (method-of-object this apply-gravity!))
    )
  (rigid-body-object-method-37 this)
  (set! (-> this max-time-step) (-> arg0 extra max-time-step))
  (set! (-> this root max-iteration-count) (the-as uint 4))
  (when (nonzero? (-> this skel))
    (let ((v1-16 (-> this skel root-channel 0)))
      (set! (-> v1-16 num-func) num-func-identity)
      (set! (-> v1-16 frame-num) 0.0)
      )
    )
  0
  (none)
  )

(defmethod init-collision! ((this rigid-body-object))
  (let ((s5-0 (new 'process 'collide-shape-moving this (collide-list-enum hit-by-player))))
    (set! (-> s5-0 dynam) (copy *standard-dynamics* 'process))
    (set! (-> s5-0 reaction) cshape-reaction-default)
    (set! (-> s5-0 no-reaction)
          (the-as (function collide-shape-moving collide-query vector vector object) nothing)
          )
    (let ((s4-0 (new 'process 'collide-shape-prim-sphere s5-0 (the-as uint 0))))
      (set! (-> s4-0 prim-core collide-as) (collide-spec pusher))
      (set! (-> s4-0 prim-core collide-with) (collide-spec jak player-list))
      (set! (-> s4-0 prim-core action) (collide-action solid))
      (set! (-> s4-0 transform-index) 3)
      (set-vector! (-> s4-0 local-sphere) 0.0 0.0 0.0 12288.0)
      (set! (-> s5-0 total-prims) (the-as uint 1))
      (set! (-> s5-0 root-prim) s4-0)
      )
    (pusher-init s5-0)
    (set! (-> s5-0 nav-radius) (* 0.75 (-> s5-0 root-prim local-sphere w)))
    (let ((v1-16 (-> s5-0 root-prim)))
      (set! (-> s5-0 backup-collide-as) (-> v1-16 prim-core collide-as))
      (set! (-> s5-0 backup-collide-with) (-> v1-16 prim-core collide-with))
      )
    (set! (-> this root) s5-0)
    )
  0
  (none)
  )

(define *rigid-body-object-constants* (new 'static 'rigid-body-object-constants
                                        :info (new 'static 'rigid-body-info
                                          :mass 2.0
                                          :inv-mass 0.5
                                          :linear-damping 1.0
                                          :angular-damping 1.0
                                          :bounce-factor 0.5
                                          :friction-factor 0.1
                                          :cm-offset-joint (new 'static 'vector :w 1.0)
                                          :inertial-tensor-box (new 'static 'array meters 3 (meters 4) (meters 4) (meters 4))
                                          )
                                        :extra (new 'static 'rigid-body-object-extra-info
                                          :max-time-step 0.033333335
                                          :gravity (meters 80)
                                          :idle-distance (meters 50)
                                          :attack-force-scale 1.0
                                          )
                                        :name '*rigid-body-object-constants*
                                        )
        )

(defmethod init-rbody-control! ((this rigid-body-object))
  (alloc-rbody-control! this *rigid-body-object-constants*)
  0
  (none)
  )

;; WARN: Return type mismatch int vs object.
(defmethod init-from-entity! ((this rigid-body-object) (arg0 entity-actor))
  "Set up a newly created process from the entity that created it."
  (init-collision! this)
  (process-drawable-from-entity! this arg0)
  (init-rbody-control! this)
  (go-idle this)
  0
  )

(defmethod rigid-body-object-method-38 ((this rigid-body-object))
  0
  (none)
  )

;; WARN: Return type mismatch int vs object.
(defmethod rigid-body-object-method-30 ((this rigid-body-object))
  (ja-post)
  0
  )

(defmethod rbody-post ((this rigid-body-object))
  (rigid-body-object-method-32 this)
  (rigid-body-object-method-38 this)
  (update-rbody-transform! (-> this rbody) (-> this root))
  (rigid-body-object-method-30 this)
  (update-transforms (-> this root))
  0
  (none)
  )

(defmethod rigid-body-object-method-42 ((this rigid-body-object))
  (logior! (-> this flags) (rigid-body-object-flag enable-collision))
  (let ((v1-3 (-> this root root-prim)))
    (set! (-> v1-3 prim-core collide-as) (-> this root backup-collide-as))
    (set! (-> v1-3 prim-core collide-with) (-> this root backup-collide-with))
    )
  0
  (none)
  )

(defmethod rigid-body-object-method-43 ((this rigid-body-object))
  (logclear! (-> this flags) (rigid-body-object-flag enable-collision))
  (let ((v1-3 (-> this root root-prim)))
    (set! (-> v1-3 prim-core collide-as) (collide-spec))
    (set! (-> v1-3 prim-core collide-with) (collide-spec))
    )
  0
  0
  (none)
  )

(defmethod apply-momentum! ((this rigid-body-object))
  (when (not (logtest? (-> this rbody flags) (rigid-body-flag enable-physics)))
    (logior! (-> this rbody flags) (rigid-body-flag enable-physics))
    (rigid-body-control-method-28 (-> this rbody) (-> this root trans) (-> this root quat))
    (vector-float*! (-> this rbody lin-momentum) (-> this root transv) (-> this info info mass))
    (vector-reset! (-> this rbody ang-momentum))
    )
  0
  (none)
  )

(defmethod disable-physics! ((this rigid-body-object))
  (logclear! (-> this rbody flags) (rigid-body-flag enable-physics))
  0
  (none)
  )

(defmethod impulse-handler ((this rigid-body-object))
  (logior! (-> this flags) (rigid-body-object-flag disturbed))
  (set-time! (-> this disturbed-time))
  (if (not (logtest? (-> this rbody flags) (rigid-body-flag enable-physics)))
      (apply-momentum! this)
      )
  0
  (none)
  )

;; WARN: Return type mismatch int vs object.
(defmethod go-active ((this rigid-body-object))
  (go (method-of-object this active))
  0
  )

(defmethod apply-damage ((this rigid-body-object) (arg0 float) (arg1 rigid-body-impact))
  0
  (none)
  )

(defmethod on-impact ((this rigid-body-object) (arg0 rigid-body-impact))
  0
  (none)
  )

(defmethod init-rbody-impact-from-tshape! ((this rigid-body-object) (arg0 rigid-body-impact) (arg1 touching-shapes-entry))
  (set! (-> arg0 process) #f)
  (set! (-> arg0 prim-id) (the-as uint 0))
  (vector-reset! (-> arg0 normal))
  (vector-reset! (-> arg0 velocity))
  (vector-copy! (-> arg0 point) (-> this root trans))
  (when arg1
    (let ((s3-0 (-> arg1 head)))
      (when s3-0
        (get-intersect-point (-> arg0 point) s3-0 (-> this root) arg1)
        (let ((s5-1 (get-touched-prim s3-0 (-> this root) arg1)))
          (when s5-1
            (set! (-> arg0 prim-id) (-> s5-1 prim-id))
            (vector-! (-> arg0 normal) (-> arg0 point) (-> s5-1 prim-core world-sphere))
            (vector-normalize! (-> arg0 normal) 1.0)
            (vector+float*!
              (-> arg0 point)
              (-> s5-1 prim-core world-sphere)
              (-> arg0 normal)
              (-> s5-1 prim-core world-sphere w)
              )
            )
          )
        )
      )
    )
  0
  (none)
  )

(defmethod impulse-force<-penetrate ((this rigid-body-object) (arg0 rigid-body-impact) (arg1 attack-info) (arg2 penetrate))
  (local-vars (f1-1 float))
  0.0
  (let ((f0-1 0.0))
    (cond
      ((logtest? (penetrate jak-red-shockwave) arg2)
       (set! f0-1 (* 81920.0 (-> arg1 control)))
       (set! f1-1 (-> arg1 damage))
       )
      ((logtest? arg2 (penetrate punch))
       (set! f0-1 40960.0)
       (set! f1-1 4.0)
       )
      ((logtest? arg2 (penetrate flop spin))
       (set! f0-1 20480.0)
       (set! f1-1 2.0)
       )
      ((logtest? (attack-mask vehicle-damage-factor) (-> arg1 mask))
       (set! f1-1 (* (-> arg1 damage) (-> arg1 vehicle-damage-factor)))
       (if (logtest? (attack-mask vehicle-impulse-factor) (-> arg1 mask))
           (set! f0-1 (* 49152.0 (-> arg1 vehicle-impulse-factor) (-> arg1 damage)))
           )
       0
       )
      (else
        (set! f0-1 8192.0)
        (set! f1-1 2.0)
        )
      )
    (set! (-> arg0 impulse) (* f0-1 (-> this info extra attack-force-scale)))
    )
  (apply-damage this f1-1 arg0)
  0
  (none)
  )

(defmethod attack-handler ((this rigid-body-object)
                          (arg0 process-drawable)
                          (arg1 attack-info)
                          (arg2 touching-shapes-entry)
                          (arg3 penetrate)
                          )
  (when arg2
    (let ((s5-0 (new 'stack-no-clear 'rigid-body-impact)))
      (init-rbody-impact-from-tshape! this s5-0 arg2)
      (if (logtest? (attack-mask attacker-velocity) (-> arg1 mask))
          (vector-copy! (-> s5-0 velocity) (-> arg1 attacker-velocity))
          (vector-! (-> s5-0 velocity) (-> s5-0 point) (-> arg0 root trans))
          )
      (impulse-force<-penetrate this s5-0 arg1 arg3)
      (impulse-handler this)
      (let ((s4-1 (new 'stack-no-clear 'vector)))
        (vector-copy! s4-1 (-> s5-0 velocity))
        (vector-normalize! s4-1 1.0)
        (vector-float*! s4-1 s4-1 (-> s5-0 impulse))
        (apply-impact! (-> this rbody) (-> s5-0 point) s4-1)
        (rigid-body-control-method-12 (-> this rbody) 1.0)
        (init-velocities! (-> this rbody))
        (when #f
          (add-debug-x #t (bucket-id debug-no-zbuf1) (-> s5-0 point) *color-blue*)
          (add-debug-vector #t (bucket-id debug-no-zbuf1) (-> s5-0 point) s4-1 (meters 0.00024414062) *color-blue*)
          )
        )
      (on-impact this s5-0)
      )
    (if (and (-> this next-state) (= (-> this next-state name) 'idle))
        (go-active this)
        )
    #t
    )
  )

(defmethod touch-handler ((this rigid-body-object) (arg0 process-focusable) (arg1 touching-shapes-entry))
  (b!
    (or (not (logtest? (process-mask target crate enemy) (-> arg0 mask)))
        (and (logtest? (-> arg0 mask) (process-mask target)) (focus-test? arg0 dangerous pilot))
        )
    cfg-17
    :delay (nop!)
    )
  (let ((s5-0 (new 'stack-no-clear 'rigid-body-impact))
        (s4-0 (new 'stack-no-clear 'vector))
        (f30-0 (get-inv-mass arg0))
        )
    (init-rbody-impact-from-tshape! this s5-0 arg1)
    (if (logtest? (-> this rbody flags) (rigid-body-flag enable-physics))
        (rigid-body-control-method-23 (-> this rbody) (-> s5-0 point) (-> s5-0 velocity))
        (vector-copy! (-> s5-0 velocity) (-> this root transv))
        )
    (let ((v1-17 (-> arg0 root)))
      (vector-copy! s4-0 (-> v1-17 transv))
      (vector-! (-> s5-0 velocity) (-> v1-17 transv) (-> s5-0 velocity))
      )
    (let ((f0-1 (vector-dot (-> s5-0 velocity) (-> s5-0 normal))))
      (when (< f0-1 0.0)
        (set! (-> s5-0 impulse) (/ f0-1 (+ f30-0 (-> this info info inv-mass))))
        (vector+float*! s4-0 s4-0 (-> s5-0 normal) (* -3.1 f30-0 (-> s5-0 impulse)))
        (set! (-> s4-0 y) (fmax (* 49152.0 f30-0) (-> s4-0 y)))
        (impulse-handler this)
        (let ((a2-4 (new 'stack-no-clear 'vector)))
          (vector-float*! a2-4 (-> s5-0 normal) (-> s5-0 impulse))
          (apply-impact! (-> this rbody) (-> s5-0 point) a2-4)
          )
        (rigid-body-control-method-12 (-> this rbody) 1.0)
        (init-velocities! (-> this rbody))
        (when #f
          (add-debug-x #t (bucket-id debug-no-zbuf1) (-> s5-0 point) *color-blue*)
          (add-debug-vector
            #t
            (bucket-id debug-no-zbuf1)
            (-> s5-0 point)
            (-> s5-0 normal)
            (- (-> s5-0 impulse))
            *color-blue*
            )
          )
        (on-impact this s5-0)
        (if (and (-> this next-state) (= (-> this next-state name) 'idle))
            (go-active this)
            )
        )
      )
    )
  (label cfg-17)
  #t
  )

(defmethod rbody-event-handler ((this rigid-body-object) (arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (case arg2
    (('impact-impulse)
     (let ((s5-1 (-> arg3 param 0)))
       (if (!= this arg0)
           (impulse-handler this)
           )
       (on-impact this (the-as rigid-body-impact s5-1))
       )
     (if (and (-> this next-state) (= (-> this next-state name) 'idle))
         (go-active this)
         )
     #t
     )
    (('touched)
     (if (= this *debug-actor*)
         (format *stdcon* "rigid-body-object got touched~%")
         )
     (when (zero? (-> (the-as process-focusable arg0) rbody))
       (let ((s3-0 (as-type arg0 process-focusable)))
         (when s3-0
           (when (logtest? (-> s3-0 mask) (process-mask target))
             (logior! (-> this flags) (rigid-body-object-flag player-touching))
             (set-time! (-> this player-touch-time))
             (impulse-handler this)
             )
           (if (not (logtest? (-> s3-0 mask) (process-mask target)))
               (touch-handler this (the-as process-focusable s3-0) (the-as touching-shapes-entry (-> arg3 param 0)))
               )
           )
         )
       )
     )
    (('attack)
     (let ((s3-1 (the-as object (-> arg3 param 1)))
           (t0-1 (get-penetrate-using-from-attack-event (the-as process-drawable arg0) arg3))
           )
       (when (!= (-> (the-as attack-info s3-1) id) (-> this incoming-attack-id))
         (set! (-> this incoming-attack-id) (-> (the-as attack-info s3-1) id))
         (attack-handler
           this
           (the-as process-drawable arg0)
           (the-as attack-info s3-1)
           (the-as touching-shapes-entry (-> arg3 param 0))
           t0-1
           )
         )
       )
     )
    (('edge-grabbed 'pilot-edge-grab)
     (let ((s5-2 (the-as object (-> arg3 param 0))))
       (when (not (logtest? (-> this flags) (rigid-body-object-flag player-impulse-force)))
         (let ((a0-25 (as-type arg0 process-focusable)))
           (when a0-25
             (let ((f0-1 (/ 163840.0 (get-inv-mass a0-25))))
               (logior! (-> this flags) (rigid-body-object-flag player-touching player-edge-grabbing player-contact-force))
               (vector-copy! (-> this player-force-position) (-> (the-as attack-info s5-2) attacker-velocity))
               (vector-reset! (-> this player-force))
               (set! (-> this player-force y) (* -1.0 f0-1))
               )
             )
           )
         )
       )
     (not (logtest? (-> this focus-status) (focus-status dead inactive)))
     )
    (('ridden)
     (let ((v1-47 (the-as object (-> arg3 param 0))))
       (when (the-as uint v1-47)
         (let ((a0-34 (as-type (handle->process (-> (the-as focus v1-47) handle)) process-focusable)))
           (when (and a0-34
                      (logtest? (-> a0-34 mask) (process-mask target))
                      (not (logtest? (-> (the-as process-focusable a0-34) focus-status) (focus-status on-water under-water)))
                      )
             (when (not (logtest? (-> this flags) (rigid-body-object-flag player-impulse-force)))
               (logior! (-> this flags) (rigid-body-object-flag player-touching player-standing-on player-contact-force))
               (vector-copy! (-> this player-force-position) (-> (the-as process-focusable a0-34) root trans))
               (vector-reset! (-> this player-force))
               (let ((f0-4 (/ 163840.0 (get-inv-mass (the-as process-focusable a0-34))))
                     (f1-1 1.0)
                     )
                 (set! (-> this player-force y) (* -1.0 f0-4 f1-1))
                 )
               )
             )
           )
         )
       )
     )
    (('bonk)
     (when #t
       (let ((s4-1 (as-type arg0 process-focusable)))
         (when s4-1
           (logior! (-> this flags) (rigid-body-object-flag player-touching player-impulse-force))
           (set-time! (-> this player-touch-time))
           (impulse-handler this)
           (vector-copy! (-> this player-force-position) (-> (the-as process-focusable s4-1) root trans))
           (let ((f30-2 (* 0.00012207031 (the-as float (-> arg3 param 1))))
                 (f0-9 (/ 163840.0 (get-inv-mass (the-as process-focusable s4-1))))
                 )
             (vector-reset! (-> this player-force))
             (set! (-> this player-force y) (* (/ f0-9 -10) f30-2))
             )
           )
         )
       )
     )
    (('enable-physics)
     (impulse-handler this)
     )
    )
  )

(defbehavior rigid-body-object-event-handler rigid-body-object ((arg0 process) (arg1 int) (arg2 symbol) (arg3 event-message-block))
  (rbody-event-handler self arg0 arg1 arg2 arg3)
  )

(defstate idle (rigid-body-object)
  :virtual #t
  :trans (behavior ()
    (if (and *target* (and (>= (-> self info extra idle-distance)
                               (vector-vector-distance (-> self root trans) (-> *target* control trans))
                               )
                           (not (logtest? (focus-status teleporting) (-> *target* focus-status)))
                           )
             )
        (go-virtual active)
        )
    )
  :code sleep-code
  :post ja-post
  )

(defstate active (rigid-body-object)
  :virtual #t
  :event rigid-body-object-event-handler
  :trans (behavior ()
    (if (or (not *target*) (or (< (+ 4096.0 (-> self info extra idle-distance))
                                  (vector-vector-distance (-> self root trans) (-> *target* control trans))
                                  )
                               (focus-test? *target* teleporting)
                               )
            )
        (go-virtual idle)
        )
    )
  :code sleep-code
  :post (behavior ()
    (rbody-post self)
    )
  )
