2020-10-26 21:08:24 -04:00
|
|
|
;;-*-Lisp-*-
|
2020-09-04 14:44:23 -04:00
|
|
|
(in-package goal)
|
|
|
|
|
|
|
|
;; name: geometry.gc
|
|
|
|
;; name in dgo: geometry
|
|
|
|
;; dgos: GAME, ENGINE
|
|
|
|
|
2021-06-26 13:03:31 -04:00
|
|
|
(defun vector-flatten! ((dst vector) (src vector) (plane-normal vector))
|
|
|
|
"Get the projection of src onto a plane with the given normal
|
|
|
|
The normal should have magnitude 1.0."
|
|
|
|
(rlet ((acc :class vf)
|
|
|
|
(vf0 :class vf)
|
|
|
|
(vf1 :class vf) ;; src
|
|
|
|
(vf2 :class vf) ;; normal
|
|
|
|
(vf3 :class vf)
|
|
|
|
)
|
|
|
|
(init-vf0-vector)
|
|
|
|
(.lvf vf1 (&-> src quad))
|
|
|
|
(.lvf vf2 (&-> plane-normal quad))
|
|
|
|
(.mov.vf vf3 vf0 :mask #b1000)
|
|
|
|
(.outer.product.vf vf3 vf1 vf2) ;; has the right magnitude, but rotation is off by 90 degrees
|
|
|
|
(.outer.product.vf vf3 vf2 vf3) ;; rotate by 90 about normal of plane
|
|
|
|
(.svf (&-> dst quad) vf3)
|
|
|
|
dst
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
(defun vector-reflect! ((dst vector) (src vector) (plane-normal vector))
|
|
|
|
"Reflect a vector off of a plane."
|
|
|
|
(rlet ((acc :class vf)
|
|
|
|
(vf0 :class vf)
|
|
|
|
(vf1 :class vf)
|
|
|
|
(vf2 :class vf)
|
|
|
|
(vf3 :class vf)
|
|
|
|
)
|
|
|
|
;; we want to split the vector into normal / tangent components.
|
|
|
|
;; let src = T + N, where T dot plane-normal = 0.
|
|
|
|
;; then the reflection is T - N = 2 * T - src.
|
|
|
|
;; we can compute T from vector-flatten!'s trick
|
|
|
|
(init-vf0-vector)
|
|
|
|
(.lvf vf1 (&-> src quad))
|
|
|
|
(.lvf vf2 (&-> plane-normal quad))
|
|
|
|
(.mov.vf vf3 vf0 :mask #b1000)
|
|
|
|
(.outer.product.vf vf3 vf1 vf2)
|
|
|
|
(.outer.product.vf vf3 vf2 vf3) ;; vf3 is the projection on the plane
|
|
|
|
(.add.vf acc vf3 vf3 :mask #b111) ;; double that part
|
|
|
|
(.sub.mul.w.vf vf3 vf1 vf0 acc :mask #b111) ;; and subtract the original
|
|
|
|
(.svf (&-> dst quad) vf3)
|
|
|
|
dst
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
(defun vector-reflect-flat! ((dst vector) (src vector) (plane-normal vector))
|
|
|
|
"This is a weird one. It doesn't care about the value of src dot normal
|
|
|
|
and it effectively replaces the component of src normal to the plane with
|
|
|
|
the plane's normal. I think this requires src/normal to both be unit vectors
|
|
|
|
in order to make sense.
|
|
|
|
NOTE: src should point from positive halfspace to negative otherwise it
|
|
|
|
doesn't work."
|
|
|
|
(rlet ((acc :class vf)
|
|
|
|
(vf0 :class vf)
|
|
|
|
(vf1 :class vf)
|
|
|
|
(vf2 :class vf)
|
|
|
|
(vf3 :class vf)
|
|
|
|
)
|
|
|
|
(init-vf0-vector)
|
|
|
|
(.lvf vf1 (&-> src quad))
|
|
|
|
(.lvf vf2 (&-> plane-normal quad))
|
|
|
|
(.mov.vf vf3 vf0 :mask #b1000)
|
|
|
|
(.outer.product.vf vf3 vf1 vf2)
|
|
|
|
(.outer.product.vf vf3 vf2 vf3) ;; part on the plane (requires normal to be unit)
|
|
|
|
(.add.vf vf3 vf3 vf2 :mask #b111) ;; add normal to that.
|
|
|
|
(.svf (&-> dst quad) vf3)
|
|
|
|
dst
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
(defun vector-reflect-true-flat! ((dst vector) (src vector) (plane-normal vector))
|
|
|
|
"Not really a reflect. Same as flatten"
|
|
|
|
(rlet ((acc :class vf)
|
|
|
|
(vf0 :class vf)
|
|
|
|
(vf1 :class vf)
|
|
|
|
(vf2 :class vf)
|
|
|
|
(vf3 :class vf)
|
|
|
|
)
|
|
|
|
(init-vf0-vector)
|
|
|
|
(.lvf vf1 (&-> src quad))
|
|
|
|
(.lvf vf2 (&-> plane-normal quad))
|
|
|
|
(.mov.vf vf3 vf0 :mask #b1000)
|
|
|
|
(.outer.product.vf vf3 vf1 vf2)
|
|
|
|
(.outer.product.vf vf3 vf2 vf3)
|
|
|
|
(.svf (&-> dst quad) vf3)
|
|
|
|
dst
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
(defun vector-reflect-flat-above! ((dst vector) (src vector) (plane-normal vector))
|
|
|
|
"A hacked up version of reflect, probably to make their collision system work.
|
|
|
|
It is a less aggressive version of reflect that also has a limit to the output
|
|
|
|
normal component"
|
|
|
|
(rlet ((acc :class vf)
|
|
|
|
(vf0 :class vf)
|
|
|
|
(vf1 :class vf)
|
|
|
|
(vf2 :class vf)
|
|
|
|
(vf3 :class vf)
|
|
|
|
)
|
|
|
|
(init-vf0-vector)
|
|
|
|
(.lvf vf1 (&-> src quad))
|
|
|
|
(.lvf vf2 (&-> plane-normal quad))
|
|
|
|
(.mov.vf vf3 vf0 :mask #b1000)
|
|
|
|
(.outer.product.vf vf3 vf1 vf2)
|
|
|
|
(.outer.product.vf vf3 vf2 vf3)
|
|
|
|
(.svf (&-> dst quad) vf3)
|
|
|
|
|
|
|
|
;; dst is now the normal part of src
|
|
|
|
(let ((f0-0 (vector-length dst)) ;; length of normal
|
|
|
|
(f1-1 (vector-dot dst plane-normal))) ;; ?? this is always zero.
|
|
|
|
(let* ((f1-2 f1-1)
|
|
|
|
;; f1-3 = .02 * length of normal. f1-2 is always zero here
|
|
|
|
(f1-3 (- (* 0.02 f0-0) f1-2))
|
|
|
|
)
|
|
|
|
;; scale down and limit the normal component
|
|
|
|
(vector+float*! dst dst plane-normal (fmin 16384.0 (* 16.0 f1-3)))
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
;; TODO vector-segment-distance-point!
|
|
|
|
|
2021-05-07 20:54:20 -04:00
|
|
|
;; TODO - temporary for lights.gc
|
2021-05-16 12:43:50 -04:00
|
|
|
(define-extern vector-deg-slerp (function vector vector vector float vector))
|
|
|
|
;; TODO - temporary for transformq.gc
|
|
|
|
(define-extern forward-up-nopitch->quaternion (function quaternion vector vector quaternion))
|
|
|
|
(define-extern forward-up->quaternion (function quaternion vector vector quaternion))
|
|
|
|
(define-extern vector-flatten! (function vector vector vector vector))
|
2021-06-19 14:24:55 -04:00
|
|
|
|
|
|
|
;; TODO
|
|
|
|
(define-extern vector-3pt-cross! (function vector vector vector vector vector))
|
2021-06-26 13:03:31 -04:00
|
|
|
(define-extern curve-evaluate! (function vector float int int vector int int))
|