Last active
August 29, 2015 14:14
-
-
Save selfsame/2ffa721f656a04e81665 to your computer and use it in GitHub Desktop.
flock.clj
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 flock | |
(:use hard.core hard.input hard.spatial) | |
(:import [UnityEngine])) | |
(declare pump initial make-boid) | |
(def FLOCKS (atom {})) | |
(def HASH (bucket-hash 10)) | |
(arcadia.core/defcomponent Boid | |
[^Vector3 heading ^float idle ^Boolean debug] | |
(Awake [this] | |
(set! (.idle this) (float (* (rand) 1.5)))) | |
(Start [this] | |
(initial this)) | |
(Update [this] | |
(pump this))) | |
(arcadia.core/defcomponent Flock | |
[^Int32 size | |
^GameObject species | |
^float max-speed | |
^float turn-speed | |
^float distance | |
^float rule-center | |
^float rule-heading | |
^float rule-seperate | |
^Boolean debug] | |
(Start [this] | |
(swap! FLOCKS #(conj % | |
{(.gameObject this) | |
(mapv | |
(fn [_] (make-boid (.gameObject this) (.species this))) | |
(range (int (.size this))))}))) | |
(Update [this])) | |
(defn rand-in [lb ub] (+ lb (* (rand) (- ub lb)))) | |
(defn- median [group f] | |
(let [combined (reduce #(v+ %1 (f %2)) [0 0 0] group)] | |
(vdiv combined (count group)))) | |
(defn center [group] (median group ->v3)) | |
(defn alignment [group] (median group #(->v3 (.forward (.transform %))))) | |
(defn separate [group]) | |
(defn rand-v3 [sc] | |
(let [nsc (* sc -1)] | |
[(rand-in nsc sc)(rand-in nsc sc)(rand-in nsc sc)])) | |
(defn make-boid [parent species] | |
(let [me (clone! species)] | |
(position! me (rand-v3 20)) | |
(rotate! me (rand-v3 360)) | |
(.AddComponent me Boid) | |
(parent! me parent) me)) | |
(defn initial [bcomp] (store (.gameObject bcomp) HASH)) | |
(defn simmer [me other] | |
(let [vv (->v3 (v- (->v3 other) me))] | |
{:h (.forward (.transform other)) :v vv :d (.magnitude vv)})) | |
(defn n-n [gob sep] | |
(let [me (vec3 gob) | |
others (bucket-others gob HASH) | |
data (mapv #(simmer me %) others) | |
combined (reduce | |
(fn [res next] | |
(let [d (- (:d next) sep)] | |
{:h (v+ (:h res) (v* (:h next) (:d next))) | |
:v (v+ (:v res) (v* (:v next) d))})) | |
{:h [0 0 0] :v [0 0 0]} | |
data)] | |
(conj combined {:count (count others)}))) | |
(defn pump [bcomp] | |
(let [gob (.gameObject bcomp) | |
delta (UnityEngine.Time/deltaTime) | |
me (->v3 gob) | |
flock (parent-component gob Flock) | |
forward (.forward (.transform gob)) | |
speed (.max-speed flock) | |
idle (.idle bcomp) | |
ready (< idle 0.0)] | |
(when ready | |
(let [data (n-n gob (.distance flock)) | |
num (inc (:count data)) | |
r1 (.rule-center flock) | |
r2 (.rule-heading flock) | |
r3 (.rule-seperate flock) | |
rule1 (.normalized (->v3 (vdiv (:v data) num))) | |
rule2 (.normalized (->v3 (vdiv (:h data) num))) | |
heading (.normalized (->v3 (v+ (v* rule1 r1) (v* rule2 r2))))] | |
(set! (.heading bcomp) heading) | |
(store gob HASH))) | |
(if ready | |
(set! (.idle bcomp) (float (+ 0.2 (* (rand) 0.4)))) | |
(set! (.idle bcomp) (float (- idle delta)))) | |
(.LookAt | |
(.transform gob) | |
(Vector3/Lerp | |
(->v3 (v+ me forward)) | |
(->v3 (v+ me (.heading bcomp))) (* delta (.turn-speed flock)))) | |
(position! gob (v+ me (v* forward (* speed delta 8)))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment