Last active
January 20, 2017 04:03
-
-
Save minikomi/f513a1a897f6e739f41592232902c4a4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns fractal.core | |
(:require [arcadia.core :as a] | |
[arcadia.linear :as l]) | |
(:import | |
[UnityEngine Mesh | |
Material Time MeshFilter WaitForSeconds | |
MonoBehaviour | |
Color | |
MeshRenderer Shader] | |
[System.Collections IEnumerator] | |
MonoObj | |
)) | |
(defn get-fractal [] | |
(or (first (a/objects-named "Fractal")) | |
(GameObject. "Fractal"))) | |
(def shared-material (Material. (Shader/Find "Standard"))) | |
(defn rotate-fractal [go] | |
(.. go transform | |
(Rotate | |
(* 35 Time/deltaTime) | |
(* -20 Time/deltaTime) 0))) | |
(defn init-fractal [] | |
(when-let [f (a/object-named "Fractal")] | |
(a/destroy f)) | |
(let [f (a/create-primitive :cube)] | |
(set! (.. f name) "Fractal") | |
(set! (.. (a/cmpt f MeshRenderer) material) shared-material) | |
(a/set-state! f | |
:max-depth 4) | |
(a/set-state! f | |
:child-scale 0.5) | |
(a/hook+ f :update #'rotate-fractal) | |
f)) | |
(defn do-later [n f] | |
(let [waited (volatile! false) | |
coro-root (a/object-typed MonoBehaviour)] | |
(.StartCoroutine | |
coro-root | |
(reify IEnumerator | |
(MoveNext [this] | |
(if @waited | |
(f) | |
(do | |
(vswap! waited not) | |
true))) | |
(get_Current [this] (WaitForSeconds. n)))))) | |
(def colors (mapv (fn [[r g b]] (Color. (/ r 255) (/ g 255) (/ b 255))) | |
[[120 120 0] | |
[120 120 120] | |
[0 120 0] | |
[0 120 120] | |
])) | |
(def shared-mat (MeshRenderer.)) | |
(def cube-pool | |
(atom | |
(vec | |
(take 6000 | |
(repeatedly | |
(fn [] | |
(let [c (a/create-primitive :sphere)] | |
(.SetActive c false) | |
c))))))) | |
(defn reset-pool [] | |
(doseq [c @cube-pool] | |
(.SetActive c false))) | |
(defn get-cube [] | |
(or (some #(and (not (.activeSelf %)) %) @cube-pool) | |
(let [new-cube (a/create-primitive :cube)] | |
(swap! cube-pool conj new-cube) | |
new-cube | |
))) | |
(defn create-dirs [down?] | |
(let [base-dirs | |
[[0 Vector3/up Quaternion/identity] | |
[1 Vector3/right (Quaternion/Euler 0 0 -90.0)] | |
[2 Vector3/left (Quaternion/Euler 0 0 90.0)] | |
[3 Vector3/forward (Quaternion/Euler 90.0 0 0)] | |
[4 Vector3/back (Quaternion/Euler -90.0 0 0)]]] | |
(if down? | |
(conj base-dirs [5 Vector3/down (Quaternion/Euler 0 -90.0 0)]) | |
base-dirs | |
))) | |
(defn fractal-step [^GameObject parent | |
depth | |
down?] | |
(when (> (a/state (get-fractal) :max-depth) depth) | |
(doseq [[n | |
direction | |
orientation] | |
(create-dirs down?)] | |
(let [^GameObject new-child (get-cube)] | |
(.SetActive new-child true) | |
(set! (.. new-child transform localScale) | |
(l/v3* Vector3/one (a/state (get-fractal) :child-scale))) | |
(set! (.. new-child transform localPosition) | |
(l/v3* direction (+ 0.5 | |
(* 0.5 | |
(a/state (get-fractal) :child-scale))))) | |
(set! (.. new-child transform localRotation) | |
orientation) | |
(set! (.. (a/cmpt new-child MeshRenderer) material) | |
(.. (a/cmpt parent MeshRenderer) material)) | |
(set! (.. (a/cmpt new-child MeshRenderer) material color) | |
(get colors (mod (+ depth n) (count colors)))) | |
(a/child+ parent new-child) | |
(do-later | |
(+ n (rand 4)) | |
(fn [] (fractal-step new-child | |
(inc depth) | |
(and down? (= n 5))))))))) | |
(comment | |
(a/destroy (get-fractal)) | |
(init-fractal) | |
(reset-pool) | |
(fractal-build (get-fractal) 0 true) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment