   [v1 v2]
   (< (angle-between v1 v2) TOLERANCE))
 
+(defn faceforward
+  "flip normal"
+  [n v]
+  (if (neg? (dot n v))
+    (sub n)
+    n))
+
 ;;(perpendicular (Vec3. 1 2 0) (Vec3. 4 3 0))
 ;;(perpendicular (Vec2. 1 0))
 

  (mult [_ v] (Vec3. (* x v) (* y v) (* z v)))
  (emult [_ v] 
    (let [^Vec3 v v] (Vec3. (* x (.x v)) (* y (.y v)) (* z (.z v)))))
  (div [_ v] (Vec3. (/ x v) (/ y v) (/ z v)))
  (abs [_] (Vec3. (m/abs x) (m/abs y) (m/abs z)))
  (mx [_] (max x y z))
  (mn [_] (min x y z))
  (sum [_] (+ x y z)) 
  (interpolate [_ v2 t f]
    (let [^Vec3 v2 v2] (Vec3. (f x (.x v2) t)

  (mult [_ v] (Vec2. (* x v) (* y v)))
  (emult [_ v] 
    (let [^Vec2 v v] (Vec2. (* x (.x v)) (* y (.y v)))))
  (div [_ v] 
    (let [v1 (/ 1.0 v)] (Vec2. (* x v1) (* y v1))))
  (abs [_] (Vec2. (m/abs x) (m/abs y)))
  (mx [_] (max x y))
  (mn [_] (min x y))
  (emx [_ v]
    (let [^Vec2 v v] (max (.x v) x) (max (.y v) y)))
  (emn [_ v]
    (let [^Vec2 v v] (min (.x v) x) (min (.y v) y)))
  (maxdim [_]
    (if (> x y) 0 1))
  (mindim [_]
    (if (< x y) 0 1))
  (base-from [v]
    [v (perpendicular v)])
  (sum [_] (+ x y)) 
  (interpolate [_ v2 t f]
    (let [^Vec2 v2 v2] (Vec2. (f x (.x v2) t)
