(ns sliva.gfx (:require [sliva.data :refer [appstate]])) (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)) novi-objekti (conj (take (get-param :obj-limit) (get-param :objekti)) obj)] (.add scena obj) ;; pucaj sceno ane (set-param :objekti novi-objekti)))) (defn obj-anim [obj] (.rotateY obj (get-param :rotacija-y)) (.rotateZ obj (get-param :rotacija-z)) (.rotateX obj (get-param :rotacija-x)) (let [new-scale (+ (aget obj "scale" "x") (get-param :w-diff))] (aset obj "scale" "x" new-scale) (aset obj "scale" "y" new-scale) (aset obj "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 x y z]] (update-param :rotacija-x (fn [old] (+ old (/ x 1000)))) (update-param :rotacija-y (fn [old] (+ old (/ y 1000)))) (update-param :rotacija-z (fn [old] (+ old (/ z 1000)))))