summaryrefslogtreecommitdiff
path: root/src/assets/viz/2/quil/middlewares/navigation_3d.cljc
diff options
context:
space:
mode:
Diffstat (limited to 'src/assets/viz/2/quil/middlewares/navigation_3d.cljc')
-rw-r--r--src/assets/viz/2/quil/middlewares/navigation_3d.cljc188
1 files changed, 0 insertions, 188 deletions
diff --git a/src/assets/viz/2/quil/middlewares/navigation_3d.cljc b/src/assets/viz/2/quil/middlewares/navigation_3d.cljc
deleted file mode 100644
index 3471cfd..0000000
--- a/src/assets/viz/2/quil/middlewares/navigation_3d.cljc
+++ /dev/null
@@ -1,188 +0,0 @@
-(ns quil.middlewares.navigation-3d
- (:require [quil.core :as q]))
-
-(def ^:private missing-navigation-key-error
- (str "state map is missing :navigation-3d key. "
- "Did you accidentally removed it from the state in "
- ":update or any other handler?"))
-
-(defn- assert-state-has-navigation
- "Asserts that state map contains :navigation-2d object."
- [state]
- (when-not (:navigation-3d state)
- (throw #?(:clj (RuntimeException. missing-navigation-key-error)
- :cljs (js/Error. missing-navigation-key-error)))))
-
-(defn- default-position
- "Default position configuration. Check default configuration in
- 'camera' function."
- []
- {:position [(/ (q/width) 2.0)
- (/ (q/height) 2.0)
- (/ (q/height) 2.0 (q/tan (/ (* q/PI 60.0) 360.0)))]
- :straight [0 0 -1]
- :up [0 1 0]})
-
-(defn- rotate-by-axis-and-angle
- "Rotates vector v by angle with axis.
- Formula is taken from wiki:
- http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle"
- [v axis angle]
- (let [[a-x a-y a-z] axis
- [x y z] v
- cs (q/cos angle)
- -cs (- 1 cs)
- sn (q/sin angle)
- ; Matrix is
- ; [a b c]
- ; [d e f]
- ; [g h i]
- a (+ cs (* a-x a-x -cs))
- b (- (* a-x a-y -cs)
- (* a-z sn))
- c (+ (* a-x a-z -cs)
- (* a-y sn))
- d (+ (* a-x a-y -cs)
- (* a-z sn))
- e (+ cs (* a-y a-y -cs))
- f (- (* a-y a-z -cs)
- (* a-x sn))
- g (- (* a-x a-z -cs)
- (* a-y sn))
- h (+ (* a-y a-z -cs)
- (* a-x sn))
- i (+ cs (* a-z a-z -cs))]
- [(+ (* a x) (* b y) (* c z))
- (+ (* d x) (* e y) (* f z))
- (+ (* g x) (* h y) (* i z))]))
-
-(defn- rotate-lr
- "Rotates nav-3d configuration left-right. angle positive - rotate right,
- negative - left."
- [nav-3d angle]
- (update-in nav-3d [:straight] rotate-by-axis-and-angle (:up nav-3d) angle))
-
-(defn- cross-product
- "Vector cross-product: http://en.wikipedia.org/wiki/Cross_product"
- [[u1 u2 u3] [v1 v2 v3]]
- [(- (* u2 v3) (* u3 v2))
- (- (* u3 v1) (* u1 v3))
- (- (* u1 v2) (* u2 v1))])
-
-(defn- v-mult
- "Multiply vector v by scalar mult."
- [v mult]
- (mapv #(* % mult) v))
-
-(defn- v-plus
- "Sum of 2 vectors."
- [v1 v2]
- (mapv + v1 v2))
-
-(defn- v-opposite
- "Returns vector opposite to vector v."
- [v]
- (v-mult v -1))
-
-(defn- v-normalize
- "Normalize vector, returning vector
- which has same direction but with norm equals to 1."
- [v]
- (let [norm (->> (map q/sq v)
- (apply +)
- (q/sqrt))]
- (v-mult v (/ norm))))
-
-(defn- rotate-ud
- "Rotates nav-3d configuration up-down."
- [nav-3d angle]
- (let [axis (cross-product (:straight nav-3d) (:up nav-3d))
- rotate #(rotate-by-axis-and-angle % axis angle)]
- (-> nav-3d
- (update-in [:straight] rotate)
- (update-in [:up] rotate))))
-
-(defn- rotate
- "Mouse handler function which rotates nav-3d configuration.
- It uses mouse from event object and pixels-in-360 to calculate
- angles to rotate."
- [state event pixels-in-360]
- (assert-state-has-navigation state)
- (if (= 0 (:p-x event) (:p-y event))
- state
- (let [dx (- (:p-x event) (:x event))
- dy (- (:y event) (:p-y event))
- angle-lr (q/map-range dx 0 pixels-in-360 0 q/TWO-PI)
- angle-ud (q/map-range dy 0 pixels-in-360 0 q/TWO-PI)]
- (update-in state [:navigation-3d]
- #(-> %
- (rotate-lr angle-lr)
- (rotate-ud angle-ud))))))
-
-(def ^:private space (keyword " "))
-
-(defn- move
- "Keyboard handler function which moves nav-3d configuration.
- It uses keyboard key from event object to determing in which
- direction to move."
- [state event step-size]
- (assert-state-has-navigation state)
- (let [{:keys [up straight]} (:navigation-3d state)]
- (if-let [dir (condp = (:key event)
- :w straight
- :s (v-opposite straight)
- space (v-opposite up)
- :z up
- :d (cross-product straight up)
- :a (cross-product up straight)
- nil)]
- (update-in state [:navigation-3d :position]
- #(v-plus % (v-mult dir step-size)))
- state)))
-
-(defn- setup-3d-nav
- "Custom 'setup' function which creates initial position
- configuration and puts it to the state map."
- [user-setup user-settings]
- (let [initial-state (-> user-settings
- (select-keys [:straight :up :position])
- (->> (merge (default-position)))
- (update-in [:straight] v-normalize)
- (update-in [:up] v-normalize))]
- (update-in (user-setup) [:navigation-3d]
- #(merge initial-state %))))
-
-(defn navigation-3d
- "Enables navigation in 3D space. Similar to how it is done in
- shooters: WASD navigation, space is go up, z is go down,
- drag mouse to look around."
- [options]
- (let [; 3d-navigation related user settings
- user-settings (:navigation-3d options)
- pixels-in-360 (:pixels-in-360 user-settings 1000)
- step-size (:step-size user-settings 20)
- rotate-on (:rotate-on user-settings :mouse-dragged)
-
- ; user-provided handlers which will be overridden
- ; by 3d-navigation
- draw (:draw options (fn [state]))
- key-pressed (:key-pressed options (fn [state _] state))
- rotate-on-fn (rotate-on options (fn [state _] state))
- setup (:setup options (fn [] {}))]
- (assoc options
-
- :setup (partial setup-3d-nav setup user-settings)
-
- :draw (fn [state]
- (assert-state-has-navigation state)
- (let [{[c-x c-y c-z] :straight
- [u-x u-y u-z] :up
- [p-x p-y p-z] :position} (:navigation-3d state)]
- (q/camera p-x p-y p-z (+ p-x c-x) (+ p-y c-y) (+ p-z c-z) u-x u-y u-z))
- (draw state))
-
- :key-pressed (fn [state event]
- (key-pressed (move state event step-size) event))
-
- rotate-on (fn [state event]
- (rotate-on-fn (rotate state event pixels-in-360) event)) )))