(plane {:keys [width depth subdivisions-width subdivisions-depth], :or {width 1, depth 1, subdivisions-width 1, subdivisions-depth 1}})

Source

(defn plane [{:keys [width depth subdivisions-width subdivisions-depth], :or {width 1, depth 1, subdivisions-width 1, subdivisions-depth 1}}] (let [num-verts-across (inc subdivisions-width)] (-> (fn [m z] (reduce (fn [m x] (let [u (/ x subdivisions-width) v (/ z subdivisions-depth)] (-> m (update :positions (fn [positions] (-> positions (conj! (- (* width u) (* width 0.5))) (conj! 0) (conj! (- (* depth v) (* depth 0.5)))))) (update :normals (fn [normals] (-> normals (conj! 0) (conj! 1) (conj! 0)))) (update :texcoords (fn [texcoords] (-> texcoords (conj! u) (conj! v))))))) m (range (inc subdivisions-width)))) (reduce {:positions (transient []), :normals (transient []), :texcoords (transient [])} (range (inc subdivisions-depth))) (assoc :indices (reduce (fn [indices z] (reduce (fn [indices x] (-> indices (conj! (-> z (* num-verts-across) (+ x))) (conj! (-> z inc (* num-verts-across) (+ x))) (conj! (-> z (* num-verts-across) (+ (inc x)))) (conj! (-> z inc (* num-verts-across) (+ x))) (conj! (-> z inc (* num-verts-across) (+ (inc x)))) (conj! (-> z (* num-verts-across) (+ (inc x)))))) indices (range subdivisions-width))) (transient []) (range subdivisions-depth))) (update :positions persistent!) (update :normals persistent!) (update :texcoords persistent!) (update :indices persistent!))))