Skip to content

Instantly share code, notes, and snippets.

@nvbn
Created June 28, 2015 14:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nvbn/b57eda355b74d08e049e to your computer and use it in GitHub Desktop.
Save nvbn/b57eda355b74d08e049e to your computer and use it in GitHub Desktop.
vr with cljs
(ns vr-cljs.core)
(enable-console-print!)
(defn get-camera
"Creates camera with desired aspect ratio."
[]
(doto (js/THREE.PerspectiveCamera. 75 (/ (.-innerWidth js/window)
(.-innerHeight js/window))
0.1 1000)
(.. -position (set 0 5 0))))
(defn get-canvas
"Returns canvas that will be fullscreened after a click."
[]
(let [canvas (.getElementById js/document "canvas")]
(.addEventListener canvas "click" #(.webkitRequestFullscreen canvas))
canvas))
(defn get-renderer
"Creates renderer for both eyes."
[]
(let [canvas (get-canvas)
webgl (js/THREE.WebGLRenderer. #js {:canvas canvas})
renderer (js/THREE.StereoEffect. webgl)]
(.setSize renderer (.-innerWidth js/window) (.-innerHeight js/window))
renderer))
(defn set-orientational-contorlls
"Set in atom controlls that tracks device (and head) movements."
[controlls camera e]
(when (and (.-alpha e) (not @controlls))
(let [ctrls (js/THREE.DeviceOrientationControls. camera true)]
(.connect ctrls)
(.update ctrls)
(reset! controlls ctrls))))
(defn get-controlls
"Returns atom with controlls."
[camera]
(let [controlls (atom)]
(.addEventListener js/window "deviceorientation"
#(set-orientational-contorlls controlls camera %))
controlls))
(def scene (js/THREE.Scene.))
(def camera (get-camera))
(def renderer (get-renderer))
(def controlls (get-controlls camera))
(defn create-rect
"Creates a rect with given color and xyz."
[color x y z]
(js/THREE.Mesh. (js/THREE.BoxGeometry. x y z)
(js/THREE.MeshBasicMaterial. #js {:color color})))
; Creates white rect:
(def rect (create-rect "white" 1 1 1))
(.. rect -position (set 1 1 0))
(.add scene rect)
; Creates yellow rect:
(def other-rect (create-rect "yellow" 1 2 3))
(.. other-rect -position (set -0.5 -2 0))
(.add scene other-rect)
(defn do-render
"Called on each render."
[]
; Rotates white rect:
(set! (.. rect -rotation -x)
(+ (.. rect -rotation -x) 0.01))
(set! (.. rect -rotation -y)
(+ (.. rect -rotation -y) 0.01))
; Rotates yellow rect:
(set! (.. other-rect -rotation -x)
(- (.. other-rect -rotation -x) 0.1))
(set! (.. other-rect -rotation -y)
(+ (.. other-rect -rotation -y) 0.1)))
(defn render
"Called on each render. This function not reloads on changes."
[]
(js/requestAnimationFrame render)
(when @controlls
(.update @controlls))
(.updateProjectionMatrix camera)
(do-render)
(.render renderer scene camera))
; Not reload render function when code changed:
(defonce render-started (atom false))
(when-not @render-started
(render)
(reset! render-started true))
<!DOCTYPE html>
<html>
<head>
<script src="compiled/goog/base.js"></script>
<script src="three.js"></script>
<script src="DeviceOrientationControls.js"></script>
<script src="StereoEffect.js"></script>
<style>
body {
margin: 0;
}
canvas {
width: 100%;
height: 100%
}
</style>
</head>
<body>
<canvas id='canvas'></canvas>
<script src="compiled/main.js"></script>
</body>
</html>
(defproject vr-cljs "0.1.3"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.7.0-beta3"]
[org.clojure/clojurescript "0.0-3269"]
[org.clojure/core.async "0.1.346.0-17112a-alpha"]
[cljsjs/three "0.0.70-0"]]
:plugins [[lein-cljsbuild "1.0.6"]
[lein-figwheel "0.3.3"]]
:profiles {:dev
{:cljsbuild {:builds {:main {:source-paths ["src"]
:figwheel {:websocket-host "192.168.0.107"}
:compiler {:output-to "resources/public/compiled/main.js"
:output-dir "resources/public/compiled"
:asset-path "/compiled"
:main vr-cljs.core
:source-map true
:optimizations :none
:pretty-print false}}}}
:figwheel {:nrepl-port 7888}}})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment