|
|
@ -47,6 +47,28 @@ |
|
|
|
(defun radians-to-degrees (angle-radians float &return float) |
|
|
|
(return (/ (* angle-radians 180.f) g-pi))) |
|
|
|
|
|
|
|
;; See https://www.computerenhance.com/p/turns-are-better-than-radians |
|
|
|
(defun turns-to-radians (num-turns float &return float) |
|
|
|
(return (* num-turns 2.f g-pi))) |
|
|
|
|
|
|
|
(defun radians-to-turns (radians float &return float) |
|
|
|
(return (/ radians 2.f g-pi))) |
|
|
|
|
|
|
|
(defun turns-to-degrees (turns float &return float) |
|
|
|
(return (* turns 360.f))) |
|
|
|
|
|
|
|
(defun degrees-to-turns (degrees float &return float) |
|
|
|
(return (/ degrees 360.f))) |
|
|
|
|
|
|
|
;; Normalize turn to a range of 0.f to +1.f |
|
|
|
(defun normalize-turns (num-turns float &return float) |
|
|
|
(var normalized-turns float num-turns) |
|
|
|
;; Remove redundant turns |
|
|
|
(set normalized-turns (- normalized-turns (truncf normalized-turns))) |
|
|
|
(when (< normalized-turns 0.f) |
|
|
|
(set normalized-turns (+ 1.f normalized-turns))) |
|
|
|
(return normalized-turns)) |
|
|
|
|
|
|
|
;; |
|
|
|
;; Vectors |
|
|
|
;; |
|
|
@ -120,17 +142,49 @@ |
|
|
|
(< (vec-x point-to-test) (vec-x bottom-right)) |
|
|
|
(< (vec-y point-to-test) (vec-y bottom-right))))) |
|
|
|
|
|
|
|
(defun vec2-equals-tolerance (vec-a vec2 vec-b vec2 tolerance float |
|
|
|
&return bool) |
|
|
|
(var difference vec2 (vec2-subtract vec-a vec-b)) |
|
|
|
;; TODO This doesn't quite solve the nan angles issue |
|
|
|
(when (and (< (fabs (field difference X)) tolerance) |
|
|
|
(< (fabs (field difference Y)) tolerance)) |
|
|
|
(return true)) |
|
|
|
(return false)) |
|
|
|
|
|
|
|
;; Turns will be signed, i.e. -0.25 instead of 0.75. Call normalize-turns if you want the latter |
|
|
|
(defun get-angle-turns-between-vec2 (vec-a vec2 vec-b vec2 &return float) |
|
|
|
(var c-minimum-vector-difference-for-angles (const float) 0.01f) |
|
|
|
(when (vec2-equals-tolerance vec-a vec-b c-minimum-vector-difference-for-angles) |
|
|
|
(return 0.f)) |
|
|
|
(var vec-a-normalized vec2 (vec2-normalize vec-a)) |
|
|
|
(var vec-b-normalized vec2 (vec2-normalize vec-b)) |
|
|
|
(var angle float |
|
|
|
(acosf (vec2-dot |
|
|
|
vec-a-normalized |
|
|
|
vec-b-normalized))) |
|
|
|
;; We need to find the perpendicular vector to know which way we need to rotate |
|
|
|
(var perpendicular vec2 vec-a-normalized) |
|
|
|
;; In 2D we can find the perpendicular vector by swapping the axes and negating one |
|
|
|
(var temp float (field perpendicular X)) |
|
|
|
(set (field perpendicular X) (field perpendicular Y)) |
|
|
|
(set (field perpendicular Y) (negate temp)) |
|
|
|
(var sign float (vec2-dot vec-b-normalized perpendicular)) |
|
|
|
(set angle (radians-to-turns angle)) |
|
|
|
(when (> sign 0.f) |
|
|
|
(set angle (negate angle))) |
|
|
|
(return angle)) |
|
|
|
|
|
|
|
;; Expand vector to each of its components |
|
|
|
;; TODO: Change to any, prevent multiple eval? |
|
|
|
(defmacro vec-xy (vec symbol) |
|
|
|
;; TODO: Prevent multiple eval? |
|
|
|
(defmacro vec-xy (vec any) |
|
|
|
(tokenize-push output |
|
|
|
(field (token-splice vec) X) |
|
|
|
(field (token-splice vec) Y)) |
|
|
|
(return true)) |
|
|
|
|
|
|
|
;; Expand vector to each of its components |
|
|
|
;; TODO: Change to any, prevent multiple eval? |
|
|
|
(defmacro vec-xyz (vec symbol) |
|
|
|
;; TODO: Prevent multiple eval? |
|
|
|
(defmacro vec-xyz (vec any) |
|
|
|
(tokenize-push output |
|
|
|
(field (token-splice vec) X) |
|
|
|
(field (token-splice vec) Y) |
|
|
@ -138,8 +192,8 @@ |
|
|
|
(return true)) |
|
|
|
|
|
|
|
;; Expand vector to each of its components |
|
|
|
;; TODO: Change to any, prevent multiple eval? |
|
|
|
(defmacro vec-xyzw (vec symbol) |
|
|
|
;; TODO: Prevent multiple eval? |
|
|
|
(defmacro vec-xyzw (vec any) |
|
|
|
(tokenize-push output |
|
|
|
(field (token-splice vec) X) |
|
|
|
(field (token-splice vec) Y) |
|
|
@ -187,6 +241,26 @@ |
|
|
|
(tokenize-push output (mat4-diagonal 1.f)) |
|
|
|
(return true)) |
|
|
|
|
|
|
|
(defstruct mat2 |
|
|
|
elements (array 2 (array 2 float))) |
|
|
|
|
|
|
|
(defun mat2-rotate-turns (num-turns float &return mat2) |
|
|
|
(var angle float (turns-to-radians num-turns)) |
|
|
|
(var rotation-matrix mat2 (array |
|
|
|
(array (array (cosf angle) (negate (sinf angle))) |
|
|
|
(array (sinf angle) (cosf angle))))) |
|
|
|
(return rotation-matrix)) |
|
|
|
|
|
|
|
(defun mat2-transform-vec2 (mat mat2 vector vec2 &return vec2) |
|
|
|
(var result vec2) |
|
|
|
(set (field result X) |
|
|
|
(+ (* (at 0 0 (field mat elements)) (field vector X)) |
|
|
|
(* (at 0 1 (field mat elements)) (field vector Y)))) |
|
|
|
(set (field result Y) |
|
|
|
(+ (* (at 1 0 (field mat elements)) (field vector X)) |
|
|
|
(* (at 1 1 (field mat elements)) (field vector Y)))) |
|
|
|
(return result)) |
|
|
|
|
|
|
|
;; Must multiply in reverse order of desired transformation (first arg = last transform operation) |
|
|
|
(def-c-function-alias mat4-multiply HMM_MultiplyMat4) ;; (left mat4 right mat4 &return mat4) |
|
|
|
|
|
|
|