sliva/src/sliva/gfx.cljs

150 lines
5.0 KiB
Clojure

(ns sliva.gfx
(:require [sliva.data :refer [appstate initial-vizual-params]]))
(defn get-param [param]
(get-in @appstate [:vizual param]))
(defn set-param [param val]
(swap! appstate assoc-in [:vizual param] val))
(defn update-param [param fun]
(swap! appstate update-in [:vizual param] fun))
;; Inicializacija ;;
(def scena (THREE.Scene.))
(def kamera (THREE.PerspectiveCamera.
(get-param :FOV)
(/ (.-innerWidth js/window)
(.-innerHeight js/window)) 0.1 2000))
(aset kamera "position" "z" (get-param :odmik-kamere))
(aset kamera "aspect" (/ (.-innerWidth js/window)
(.-innerHeight js/window)))
(.updateProjectionMatrix kamera)
(def izris (THREE.WebGLRenderer. (js-obj "alpha" true)))
(.setSize izris (.-innerWidth js/window) (.-innerHeight js/window))
;; Crno ozadje
(.setClearColor izris (get-param :bg-barva) 1)
(defn dodaj-obj [sirina]
(let [barva (js/THREE.Color.)
mat (js/THREE.LineBasicMaterial.)
geo (js/THREE.Geometry.)
koti (.-vertices geo)
zamik (/ sirina 2)
-zamik (* -1 zamik)]
;; Nastavi barvo novega objekta
(.setHSL barva
(* (get-param :stevec)
(get-param :zacetna-barva))
(get-param :saturacija)
(get-param :svetlost))
(aset mat "color" barva)
;; Kvadratek (za nov objekt)
(.push koti (js/THREE.Vector3. -zamik 0 0) (js/THREE.Vector3. 0 zamik 0))
(.push koti (js/THREE.Vector3. -zamik 0 0) (js/THREE.Vector3. 0 -zamik 0))
(.push koti (js/THREE.Vector3. zamik 0 0) (js/THREE.Vector3. 0 zamik 0))
(.push koti (js/THREE.Vector3. zamik 0 0) (js/THREE.Vector3. 0 -zamik 0))
(let [obj (js/THREE.Line. geo mat (.-LineSegments js/THREE))
position (.-position obj)
stari-objekti (drop (get-param :obj-limit) (get-param :objekti))
novi-objekti (conj (take (get-param :obj-limit) (get-param :objekti))
obj)]
(.add scena obj)
(->> stari-objekti
(run! (fn [old-obj]
(.remove scena old-obj))))
;; pucaj sceno ane
(set-param :objekti novi-objekti))))
(defn obj-anim [obj]
(let [position (.-position obj)
new-scale (+ (aget obj "scale" "x")
(get-param :w-diff))]
(doto position
(.setX (+ (.-x position) (get-param :center-x)))
(.setY (+ (.-y position) (get-param :center-y)))
(.setZ (+ (.-z position) (get-param :center-z))))
(doto obj
(.rotateY (get-param :rotacija-y))
(.rotateZ (get-param :rotacija-z))
(.rotateX (get-param :rotacija-x))
(aset "scale" "x" new-scale)
(aset "scale" "y" new-scale)
(aset "scale" "z" new-scale))
(.offsetHSL (aget obj "material" "color") (get-param :zamik-barve) 0 0)))
(defn cam-rotate []
(.translateX kamera (get-param :rotacija-kamere))
(.translateZ kamera (- (get-param :odmik-kamere)
(.sqrt js/Math (+ (.pow js/Math (get-param :odmik-kamere) 2)
(.pow js/Math (get-param :rotacija-kamere) 2)))))
(.lookAt kamera (.-position scena)))
(defn render []
(if (get-in @appstate [:vizual :animiraj])
(.requestAnimationFrame js/window render))
(set-param :stevec (inc (get-param :stevec)))
(if (= 0 (rem (get-param :stevec) (get-param :gostota-obj)))
(dodaj-obj (get-param :lik-sirina)))
(.render izris scena kamera)
(run! obj-anim (get-param :objekti))
(cam-rotate))
;; Hendlaj risajz
(defn on-window-resize[]
(let [sirina (.-innerWidth js/window)
visina (.-innerHeight js/window)]
(aset kamera "aspect" (/ sirina visina))
(.updateProjectionMatrix kamera)
(.setSize izris sirina visina)))
(defn start-render [container]
(.appendChild container (.-domElement izris))
(swap! appstate assoc-in [:vizual :animiraj] true)
(.addEventListener js/window "resize" on-window-resize false)
(render))
(defn stop-render [container]
(swap! appstate assoc-in [:vizual :animiraj] false)
(.removeEventListener js/window "resize" on-window-resize false)
(.removeChild container (.-firstChild container)))
(defn spin-objects [[cas a b g]]
(let [divizija 10000]
(set-param :rotacija-x (/ a divizija))
(set-param :rotacija-y (/ b divizija))
(set-param :rotacija-z (/ g divizija))))
;;(update-param :rotacija-x (fn [old] (+ old (/ a 100000))))
;;(update-param :rotacija-y (fn [old] (+ old (/ b 100000))))
;;(update-param :rotacija-z (fn [old] (+ old (/ g 100000)))))
(defn displace-objects [[cas x y z]]
(update-param :center-x (fn [old] (+ old (/ x 25))))
(update-param :center-y (fn [old] (+ old (/ y 25))))
(update-param :center-z (fn [old] (+ old (/ z 25)))))
(defn vizual-reset []
(console.log "stari obj" (get-param :objekti))
(->> (get-param :objekti)
(run! (fn [obj] (.remove scena obj))))
(swap! appstate update-in [:vizual] (fn [old] (merge old initial-vizual-params))))
(defn vizual-update [[param val]]
(console.log "apdejt vizual?" param val)
(set-param (keyword param) val))