(disc {:keys [radius divisions stacks inner-radius stack-power], :or {stacks 1, inner-radius 0, stack-power 1}})

Source

(defn disc [{:keys [radius divisions stacks inner-radius stack-power], :or {stacks 1, inner-radius 0, stack-power 1}}] (let [num-vertices (* (inc divisions) (inc stacks)) radius-span (- radius inner-radius) points-per-stack (inc divisions)] (-> (fn [m stack] (let [stack-radius (+ inner-radius (* radius-span (math pow (/ stack stacks) stack-power)))] (-> (fn [m i] (let [first-index (:first-index m) theta (-> 2 (* (math PI)) (* i) (/ divisions)) x (* stack-radius (math cos theta)) z (* stack-radius (math sin theta))] (-> m (update :positions (fn [positions] (-> positions (conj! x) (conj! 0) (conj! z)))) (update :normals (fn [normals] (-> normals (conj! 0) (conj! 1) (conj! 0)))) (update :texcoords (fn [texcoords] (-> texcoords (conj! (- 1 (/ i divisions))) (conj! (/ stack stacks))))) (update :indices (fn [indices] (if (and (pos? stack) (not= i divisions)) (let [a (+ first-index i 1) b (+ first-index i) c (-> first-index (+ i) (- points-per-stack)) d (-> first-index (+ (inc i)) (- points-per-stack))] (-> indices (conj! a) (conj! b) (conj! c) (conj! a) (conj! c) (conj! d))) indices)))))) (reduce m (range (inc divisions))) (update :first-index + (inc divisions))))) (reduce {:first-index 0, :positions (transient []), :normals (transient []), :texcoords (transient []), :indices (transient [])} (range (inc stacks))) (dissoc :first-index) (update :positions persistent!) (update :normals persistent!) (update :texcoords persistent!) (update :indices persistent!))))