From d01cc728df8ce7f4774e493f3295c442ac21e0e4 Mon Sep 17 00:00:00 2001 From: Jeremy Dormitzer Date: Sat, 9 Nov 2019 15:29:18 -0500 Subject: [PATCH] Add mouselook --- src/three_playground/core.cljs | 43 +++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/src/three_playground/core.cljs b/src/three_playground/core.cljs index b416ae6..c42b4af 100644 --- a/src/three_playground/core.cljs +++ b/src/three_playground/core.cljs @@ -2,9 +2,12 @@ (:require [goog.dom :as gdom] [goog.object :as obj] - [oops.core :refer [oset!+]] + [oops.core :refer [oset!+ oget+]] [three])) +(def mouselook-speed 0.008) +(def mouselook-max 0.6) + (defn get-app-element [] (gdom/getElement "app-canvas")) @@ -13,6 +16,13 @@ material (three/MeshBasicMaterial. #js {:color 0x10ed00})] (three/Mesh. geometry material))) +(defn register-entity + ([state id entity entity-state] + (-> (assoc-in state [:entities id] entity) + (assoc-in [:entity-state id] entity-state))) + ([state id entity] + (assoc-in state [:entities id] entity))) + (defn init-state [] (let [renderer (three/WebGLRenderer. #js {:canvas (get-app-element)}) scene (three/Scene.) @@ -25,16 +35,31 @@ cube (make-cube)] (.setSize renderer (.-innerWidth js/window) (.-innerHeight js/window)) (.add scene cube) - (atom {:running true - :renderer renderer - :entity-state {:cube {:rotation {:x 0 :y 0}} - :camera {:position {:z 5}}} - :entities {:scene scene - :cube cube - :camera camera}}))) + (atom (-> {:running true + :renderer renderer} + (register-entity :cube cube {:rotation {:x 0 :y 0}}) + (register-entity :scene scene) + (register-entity :camera camera {:position {:x 0 :y 0 :z 5} + :rotation {:x 0 :y 0 :z 0}}))))) (defonce app-state (init-state)) +;; TODO come up with a more elegant event listener system that fits into the rest of the architecture + +(.addEventListener + (get-app-element) + "mousemove" + (fn [event] + (swap! app-state #(assoc-in % [:entity-state :camera :rotation :x] + (- (get-in % [:entity-state :camera :rotation :x]) + (min mouselook-max + (* (.-movementY event) mouselook-speed))))) + (swap! app-state #(assoc-in % [:entity-state :camera :rotation :y] + (- (get-in % [:entity-state :camera :rotation :y]) + (min mouselook-max + (* (.-movementX event) mouselook-speed))))))) + + (defn update-state [state] (-> state (assoc-in [:entity-state :cube :rotation :x] @@ -62,7 +87,7 @@ (when target-state (doseq [path (map->paths target-state)] (let [str-path (map name path) - current (apply aget entity str-path) + current (oget+ entity str-path) new (get-in target-state path)] (when-not (= current new) (oset!+ entity str-path new))))))))