-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchapter_0_10e.cljs
84 lines (75 loc) · 2.9 KB
/
chapter_0_10e.cljs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
(ns noc.chapter-0-10e
(:require
[quil.sketch :as ap :include-macros true]
[quil.core :as q]))
(def size [640 240])
(defn init-terrain [cell-size width height]
(let [cols (quot width cell-size)
rows (quot height cell-size)]
{:cell-size cell-size
:w width
:h height
:cols cols
:rows rows
:zoff 0.0
:cells []}))
;; My initial naive impl
#_(defn tick-terrain [{:keys [cols rows zoff] :as terrain}]
(let [updated-cells (vec (map-indexed
(fn [i _]
(vec (map-indexed
(fn [j _]
(q/map-range (q/noise (+ (* i 0.1) zoff) (+ (* j 0.1) zoff) zoff) 0 1 -120 120))
(range rows))))
(range cols)))
new-zoff (+ zoff 0.01)]
(assoc terrain :cells updated-cells :zoff new-zoff)))
;; Using transients to try and speed it up
(defn tick-terrain [{:keys [cols rows zoff] :as terrain}]
(let [updated-cells (persistent!
(reduce
(fn [acc i]
(assoc! acc i
(persistent!
(reduce
(fn [inner-acc j]
(assoc! inner-acc j
(q/map-range (q/noise (+ (* i 0.1) zoff) (+ (* j 0.1) zoff) zoff) 0 1 -120 120)))
(transient []) (range rows)))))
(transient []) (range cols)))
new-zoff (+ zoff 0.01)]
(assoc terrain :cells updated-cells :zoff new-zoff)))
(defn init-state [{:keys [width height]}]
{:terrain
(tick-terrain (init-terrain 20 800 400))
:theta 0.0})
(defn setup! [{:keys [width height terrain]}]
(q/background 255))
(defn tick [state]
(-> state
(update :terrain tick-terrain)
(update :theta #(+ % 0.0025))))
(defn draw-terrain! [{:keys [cells cell-size cols rows w h]}]
(doseq [x (range (dec cols))]
;; Quil bug https://github.com/quil/quil/issues/415
(.beginShape (ap/current-applet) (aget js/p5.prototype "QUAD_STRIP"))
(doseq [y (range rows)]
(q/stroke 0)
(let [current-elevation (get-in cells [x y])
current-shade (q/map-range current-elevation -120 120 0 255)
x-coordinate (- (* x cell-size) (/ w 2))
y-coordinate (- (* y cell-size) (/ h 2))]
(q/fill current-shade 255)
(q/vertex x-coordinate y-coordinate current-elevation)
(q/vertex (+ x-coordinate cell-size) y-coordinate (get-in cells [(inc x) y]))))
(q/end-shape)))
(defn draw! [{:keys [terrain theta] :as state}]
(q/background 255)
(q/push-style)
(q/push-matrix)
(q/translate 0 20 -200)
(q/rotate-x (/ q/PI 3))
(q/rotate-z theta)
(draw-terrain! terrain)
(q/pop-matrix)
(q/pop-style))