(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))