Created
October 26, 2014 08:52
-
-
Save nasser/0762bd6dc6cc63219e5a to your computer and use it in GitHub Desktop.
This file contains 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 user | |
(:use arcadia.core) | |
(:import [UnityEngine | |
Vector3 | |
Time | |
Gizmos | |
Color | |
Debug | |
Plane | |
Mathf])) | |
(defmacro v [x y z] | |
`(Vector3. ~x ~y ~z)) | |
(def mesh {:faces [{:vertices [(v 0 1 0) | |
(v 1 2 0) | |
(v 1 2 1) | |
(v 0 1 1)]} | |
{:vertices [(v 0 0 0) | |
(v 1 -1 0) | |
(v 1 -1 1) | |
(v 0 0 1)]} | |
{:vertices [(v 1 -1 0) | |
(v 1 2 0) | |
(v 1 2 1) | |
(v 1 -1 1)]} | |
{:vertices [(v 0 0 0) | |
(v 0 1 0) | |
(v 0 1 1) | |
(v 0 0 1)]} | |
{:vertices [ | |
(v 1 2 1) | |
(v 0 1 1) | |
(v 0 0 1) | |
(v 1 -1 1) | |
]} | |
{:vertices [(v 0 0 0) | |
(v 0 1 0) | |
(v 1 2 0) | |
(v 1 -1 0)]}]}) | |
(defn edges [{:keys [vertices]}] | |
(->> vertices | |
cycle | |
(take (inc (count vertices))) | |
(partition 2 1) | |
(map set) | |
set)) | |
(defn vertices [{:keys [vertices]}] | |
(set vertices)) | |
(defn normal [[a b c]] | |
(.normalized (vx (v- a b) (v- b c)))) | |
(defn v+ [^Vector3 a ^Vector3 b] (Vector3/op_Addition a b)) | |
(defn v- [^Vector3 a ^Vector3 b] (Vector3/op_Subtraction a b)) | |
(defn v* [a b] (Vector3/op_Multiply a b)) | |
(defn v÷ [a b] (Vector3/op_Division a b)) | |
(defn vx [^Vector3 a ^Vector3 b] (Vector3/Cross a b)) | |
(defn centroid [vs] | |
(v÷ (reduce v+ vs) | |
(count vs))) | |
(defn ortho [^Vector3 v] | |
(Vector3. 2 2 (- (.x v) (.y v)))) | |
(defn parallel? [^Vector3 a ^Vector3 b] | |
(let [angle (Vector3/Angle a b)] | |
(or (Mathf/Approximately 0.0 angle) | |
(Mathf/Approximately 180.0 angle)))) | |
(defn gizmo-color [^Color c] | |
(set! Gizmos/color c)) | |
(defn gizmo-line [^Vector3 from ^Vector3 to] | |
(Gizmos/DrawLine from to)) | |
(defn gizmo-ray [^Vector3 from ^Vector3 dir] | |
(Gizmos/DrawRay from dir)) | |
(defn gizmo-point [^Vector3 v] | |
(Gizmos/DrawSphere v 0.075)) | |
(defn double-cross [^Vector3 n ^Vector3 v] | |
(.normalized (Vector3/Cross n (Vector3/Cross n v)))) | |
(defn face->plane [f] | |
(let [n (normal (f :vertices))] | |
{:normal n | |
:distance (Vector3/Dot n (centroid (f :vertices)))})) | |
(defn gizmo-face-plane [f] | |
(let [c (centroid (f :vertices)) | |
n (normal (f :vertices)) | |
pv1 (.normalized (apply v- (take 2 (f :vertices)))) | |
pv2 (.normalized (Vector3/Cross n pv1))] | |
(gizmo-ray c n) | |
(doseq [x (range -10 10) | |
y (range -10 10)] | |
(let [c (reduce v+ [c | |
(v* pv1 x) | |
(v* pv2 y)])] | |
(gizmo-ray c pv1) | |
(gizmo-ray c pv2) | |
(gizmo-ray c (v* -1 pv1)) | |
(gizmo-ray c (v* -1 pv2)))))) | |
(defn gizmo-plane [p] | |
(let [n (.normalized (p :normal)) | |
c (v* (p :distance) n) | |
crossh (.normalized | |
(Vector3/Cross n (Vector3/Cross Vector3/right n))) | |
crossv (.normalized | |
(Vector3/Cross n (Vector3/Cross Vector3/up n)))] | |
(gizmo-ray c n) | |
(doseq [x (range -10 10) | |
y (range -10 10)] | |
(let [c (reduce v+ [c | |
(v* crossh x) | |
(v* crossv y)])] | |
(gizmo-ray c crossh) | |
(gizmo-ray c crossv) | |
(gizmo-ray c (v* -1 crossh)) | |
(gizmo-ray c (v* -1 crossv)) )))) | |
(defn gizmo-face [f] | |
(let [verts (f :vertices) | |
closed-verts (conj verts (first verts)) | |
edges (partition 2 1 closed-verts)] | |
;; draw sides | |
(gizmo-color Color/white) | |
(doseq [e edges] | |
(apply gizmo-line e)) | |
;; draw normal | |
(gizmo-color Color/yellow) | |
(let [c (centroid (f :vertices))] | |
(gizmo-line c | |
(v+ c | |
(v* 0.2 (normal (f :vertices)))))))) | |
(defn gizmo-mesh [m] | |
(doseq [f (m :faces)] | |
(gizmo-face f))) | |
(defn plane* [a b c] | |
(Plane. a b c)) | |
(defn intersect-2-planes [{d1 :distance | |
n1 :normal | |
:keys [distance normal]} | |
{d2 :distance | |
n2 :normal | |
:keys [distance normal]}] | |
(let [n1 (.normalized n1) | |
n2 (.normalized n2) | |
pos1 (v* d1 n1) | |
pos2 (v* d2 n2) | |
line-vec (Vector3/Cross n1 n2) | |
ldir (Vector3/Cross n2 line-vec) | |
den (Vector3/Dot n1 ldir) | |
p1-to-p2 (v- pos1 pos2) | |
t (/ (Vector3/Dot n1 p1-to-p2) den) | |
line-point (v+ pos2 (v* t ldir))] | |
{:point line-point | |
:direction line-vec})) | |
(defn intersect-line-plane [{:keys [point direction]} | |
{:keys [distance normal]}] | |
(let [direction (.normalized direction) | |
normal (.normalized normal) | |
plane-point (v* distance normal) | |
dot-num (Vector3/Dot (v- plane-point point) normal) | |
dot-den (Vector3/Dot direction normal) | |
len (/ dot-num dot-den) | |
v (v* direction len)] | |
(v+ point v))) | |
(defn intersect-3-planes [p1 p2 p3] | |
(let [l (intersect-2-planes p1 p2)] | |
(intersect-line-plane l p3))) | |
(defn intersect [p1 p2 p3] | |
(let [d1 (:distance p1) | |
n1 (:normal p1) | |
d2 (:distance p2) | |
n2 (:normal p2) | |
d3 (:distance p3) | |
n3 (:normal p3)] | |
(v÷ (reduce v+ [(v* (- d1) (Vector3/Cross n2 n3)) | |
(v* (- d2) (Vector3/Cross n3 n1)) | |
(v* (- d3) (Vector3/Cross n1 n2))]) | |
(Vector3/Dot n1 | |
(Vector3/Cross n2 n3))))) | |
(do | |
(defn gizmos [] | |
(gizmo-mesh mesh) | |
(let [p {:normal (Vector3. -1 (+ (* 0.2 (Mathf/Sin Time/time)) 0.5) 0.5) | |
:distance (- 0 5 (* 2 (Mathf/Sin Time/time)))} | |
face (nth (mesh :faces) 2)] | |
(gizmo-color Color/yellow) | |
(gizmo-plane p) | |
; (doseq [f faces] | |
; (gizmo-face-plane face)) | |
; (gizmo-face-plane face) | |
(doseq [v (face :vertices)] | |
(gizmo-color Color/white) | |
(gizmo-point v) | |
(let [vfaces (filter #(and ((vertices %) v) | |
(not= % face)) | |
(mesh :faces)) | |
v* (apply intersect-3-planes p (map face->plane vfaces))] | |
(gizmo-color Color/cyan) | |
(gizmo-point v*) | |
(gizmo-line v v*))) | |
)) | |
(UnityEditor.SceneView/RepaintAll)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment