namespace Aardvark.Base

type V2i(x : int, y : int) = 
    member __.X = x
    interface NoSRTP.IHasX<int> with member x.X = x.X
    member __.Y = y
    interface NoSRTP.IHasY<int> with member x.Y = x.Y
    member __.XX = V2i(x, x)
    member __.XY = V2i(x, y)
    interface NoSRTP.IHasXY<V2i> with member x.XY = x.XY
    member __.YX = V2i(y, x)
    member __.YY = V2i(y, y)
    static member Zero = V2i(0, 0)
    static member One = V2i(1, 1)
    static member OO = V2i(0, 0)
    static member OI = V2i(0, 1)
    static member IO = V2i(1, 0)
    static member II = V2i(1, 1)
    static member (~-) (v : V2i) = V2i(-v.X, -v.Y)
    static member (+) (l : V2i, r : V2i) = V2i(l.X + r.X, l.Y + r.Y)
    static member (-) (l : V2i, r : V2i) = V2i(l.X - r.X, l.Y - r.Y)
    static member (*) (l : V2i, r : V2i) = V2i(l.X * r.X, l.Y * r.Y)
    static member (/) (l : V2i, r : V2i) = V2i(l.X / r.X, l.Y / r.Y)
    static member (*) (l : V2i, r : int) = V2i(l.X * r, l.Y * r)
    static member (/) (l : V2i, r : int) = V2i(l.X / r, l.Y / r)
    static member (*) (l : int, r : V2i) = V2i(l * r.X, l * r.Y)
    static member (/) (l : int, r : V2i) = V2i(l / r.X, l / r.Y)
    static member Dot(l : V2i, r : V2i) = l.X * r.X + l.Y * r.Y
    member __.Dot(r : V2i) = x * r.X + y * r.Y
    interface NoSRTP.IHasDot<V2i, int> with member x.Dot(r) = x.Dot(r)
    member __.LengthSquared = x*x + y*y
    interface NoSRTP.IHasLengthSquared<int> with member x.LengthSquared = x.LengthSquared
    member __.Length = sqrt (float (x*x + y*y))
    interface NoSRTP.IHasLength<float> with member x.Length = x.Length
    member __.Abs = V2i(abs x, abs y)
    static member Min(l : V2i, r : V2i) = V2i(min l.X r.X, min l.Y r.Y)
    static member Max(l : V2i, r : V2i) = V2i(max l.X r.X, max l.Y r.Y)
    static member Distance(l : V2i, r : V2i) = (l - r).Length
    override __.GetHashCode() = HashCode.Combine(x.GetHashCode(), y.GetHashCode())
    override __.Equals(o) = match o with | :? V2i as o -> x = o.X && y = o.Y | _ -> false
    override __.ToString() = sprintf "[%d, %d]" x y
    interface System.IComparable with
        member __.CompareTo(o) = 
            match o with 
            | :? V2i as o -> 
                let mutable a = 0
                if (a <- compare x o.X; a <> 0) then a
                else compare y o.Y
            | _ -> failwith "uncomparable"
    member __.AnyGreater(o : V2i) = x > o.X || y > o.Y
    static member AnyGreater(l : V2i, r : V2i) = l.AnyGreater(r)
    member __.AnyGreaterOrEqual(o : V2i) = x >= o.X || y >= o.Y
    static member AnyGreaterOrEqual(l : V2i, r : V2i) = l.AnyGreaterOrEqual(r)
    member __.AnySmaller(o : V2i) = x < o.X || y < o.Y
    static member AnySmaller(l : V2i, r : V2i) = l.AnySmaller(r)
    member __.AnySmallerOrEqual(o : V2i) = x <= o.X || y <= o.Y
    static member AnySmallerOrEqual(l : V2i, r : V2i) = l.AnySmallerOrEqual(r)
    member __.AnyEqual(o : V2i) = x = o.X || y = o.Y
    static member AnyEqual(l : V2i, r : V2i) = l.AnyEqual(r)
    member __.AnyDifferent(o : V2i) = x <> o.X || y <> o.Y
    static member AnyDifferent(l : V2i, r : V2i) = l.AnyDifferent(r)
    member __.AllGreater(o : V2i) = x > o.X && y > o.Y
    static member AllGreater(l : V2i, r : V2i) = l.AllGreater(r)
    member __.AllGreaterOrEqual(o : V2i) = x >= o.X && y >= o.Y
    static member AllGreaterOrEqual(l : V2i, r : V2i) = l.AllGreaterOrEqual(r)
    member __.AllSmaller(o : V2i) = x < o.X && y < o.Y
    static member AllSmaller(l : V2i, r : V2i) = l.AllSmaller(r)
    member __.AllSmallerOrEqual(o : V2i) = x <= o.X && y <= o.Y
    static member AllSmallerOrEqual(l : V2i, r : V2i) = l.AllSmallerOrEqual(r)
    member __.AllEqual(o : V2i) = x = o.X && y = o.Y
    static member AllEqual(l : V2i, r : V2i) = l.AllEqual(r)
    member __.AllDifferent(o : V2i) = x <> o.X && y <> o.Y
    static member AllDifferent(l : V2i, r : V2i) = l.AllDifferent(r)
type V3i(x : int, y : int, z : int) = 
    member __.X = x
    interface NoSRTP.IHasX<int> with member x.X = x.X
    member __.Y = y
    interface NoSRTP.IHasY<int> with member x.Y = x.Y
    member __.Z = z
    interface NoSRTP.IHasZ<int> with member x.Z = x.Z
    member __.XX = V2i(x, x)
    member __.XY = V2i(x, y)
    interface NoSRTP.IHasXY<V2i> with member x.XY = x.XY
    member __.XZ = V2i(x, z)
    member __.YX = V2i(y, x)
    member __.YY = V2i(y, y)
    member __.YZ = V2i(y, z)
    interface NoSRTP.IHasYZ<V2i> with member x.YZ = x.YZ
    member __.ZX = V2i(z, x)
    member __.ZY = V2i(z, y)
    member __.ZZ = V2i(z, z)
    member __.XXX = V3i(x, x, x)
    member __.XXY = V3i(x, x, y)
    member __.XXZ = V3i(x, x, z)
    member __.XYX = V3i(x, y, x)
    member __.XYY = V3i(x, y, y)
    member __.XYZ = V3i(x, y, z)
    interface NoSRTP.IHasXYZ<V3i> with member x.XYZ = x.XYZ
    member __.XZX = V3i(x, z, x)
    member __.XZY = V3i(x, z, y)
    member __.XZZ = V3i(x, z, z)
    member __.YXX = V3i(y, x, x)
    member __.YXY = V3i(y, x, y)
    member __.YXZ = V3i(y, x, z)
    member __.YYX = V3i(y, y, x)
    member __.YYY = V3i(y, y, y)
    member __.YYZ = V3i(y, y, z)
    member __.YZX = V3i(y, z, x)
    member __.YZY = V3i(y, z, y)
    member __.YZZ = V3i(y, z, z)
    member __.ZXX = V3i(z, x, x)
    member __.ZXY = V3i(z, x, y)
    member __.ZXZ = V3i(z, x, z)
    member __.ZYX = V3i(z, y, x)
    member __.ZYY = V3i(z, y, y)
    member __.ZYZ = V3i(z, y, z)
    member __.ZZX = V3i(z, z, x)
    member __.ZZY = V3i(z, z, y)
    member __.ZZZ = V3i(z, z, z)
    static member Zero = V3i(0, 0, 0)
    static member One = V3i(1, 1, 1)
    static member OOO = V3i(0, 0, 0)
    static member OOI = V3i(0, 0, 1)
    static member OIO = V3i(0, 1, 0)
    static member OII = V3i(0, 1, 1)
    static member IOO = V3i(1, 0, 0)
    static member IOI = V3i(1, 0, 1)
    static member IIO = V3i(1, 1, 0)
    static member III = V3i(1, 1, 1)
    static member (~-) (v : V3i) = V3i(-v.X, -v.Y, -v.Z)
    static member (+) (l : V3i, r : V3i) = V3i(l.X + r.X, l.Y + r.Y, l.Z + r.Z)
    static member (-) (l : V3i, r : V3i) = V3i(l.X - r.X, l.Y - r.Y, l.Z - r.Z)
    static member (*) (l : V3i, r : V3i) = V3i(l.X * r.X, l.Y * r.Y, l.Z * r.Z)
    static member (/) (l : V3i, r : V3i) = V3i(l.X / r.X, l.Y / r.Y, l.Z / r.Z)
    static member (*) (l : V3i, r : int) = V3i(l.X * r, l.Y * r, l.Z * r)
    static member (/) (l : V3i, r : int) = V3i(l.X / r, l.Y / r, l.Z / r)
    static member (*) (l : int, r : V3i) = V3i(l * r.X, l * r.Y, l * r.Z)
    static member (/) (l : int, r : V3i) = V3i(l / r.X, l / r.Y, l / r.Z)
    static member Dot(l : V3i, r : V3i) = l.X * r.X + l.Y * r.Y + l.Z * r.Z
    member __.Dot(r : V3i) = x * r.X + y * r.Y + z * r.Z
    interface NoSRTP.IHasDot<V3i, int> with member x.Dot(r) = x.Dot(r)
    static member Cross(l : V3i, r : V3i) = V3i(l.Y * r.Z - l.Z * r.Y, l.Z * r.X - l.X * r.Z, l.X * r.Y - l.Y * r.X)
    member __.Cross(r : V3i) = V3i(y * r.Z - z * r.Y, z * r.X - x * r.Z, x * r.Y - y * r.X)
    interface NoSRTP.IHasCross<V3i, V3i> with member x.Cross(r) = x.Cross(r)
    member __.LengthSquared = x*x + y*y + z*z
    interface NoSRTP.IHasLengthSquared<int> with member x.LengthSquared = x.LengthSquared
    member __.Length = sqrt (float (x*x + y*y + z*z))
    interface NoSRTP.IHasLength<float> with member x.Length = x.Length
    member __.Abs = V3i(abs x, abs y, abs z)
    static member Min(l : V3i, r : V3i) = V3i(min l.X r.X, min l.Y r.Y, min l.Z r.Z)
    static member Max(l : V3i, r : V3i) = V3i(max l.X r.X, max l.Y r.Y, max l.Z r.Z)
    static member Distance(l : V3i, r : V3i) = (l - r).Length
    override __.GetHashCode() = HashCode.Combine(x.GetHashCode(), y.GetHashCode(), z.GetHashCode())
    override __.Equals(o) = match o with | :? V3i as o -> x = o.X && y = o.Y && z = o.Z | _ -> false
    override __.ToString() = sprintf "[%d, %d, %d]" x y z
    interface System.IComparable with
        member __.CompareTo(o) = 
            match o with 
            | :? V3i as o -> 
                let mutable a = 0
                if (a <- compare x o.X; a <> 0) then a
                elif (a <- compare y o.Y; a <> 0) then a
                else compare z o.Z
            | _ -> failwith "uncomparable"
    member __.AnyGreater(o : V3i) = x > o.X || y > o.Y || z > o.Z
    static member AnyGreater(l : V3i, r : V3i) = l.AnyGreater(r)
    member __.AnyGreaterOrEqual(o : V3i) = x >= o.X || y >= o.Y || z >= o.Z
    static member AnyGreaterOrEqual(l : V3i, r : V3i) = l.AnyGreaterOrEqual(r)
    member __.AnySmaller(o : V3i) = x < o.X || y < o.Y || z < o.Z
    static member AnySmaller(l : V3i, r : V3i) = l.AnySmaller(r)
    member __.AnySmallerOrEqual(o : V3i) = x <= o.X || y <= o.Y || z <= o.Z
    static member AnySmallerOrEqual(l : V3i, r : V3i) = l.AnySmallerOrEqual(r)
    member __.AnyEqual(o : V3i) = x = o.X || y = o.Y || z = o.Z
    static member AnyEqual(l : V3i, r : V3i) = l.AnyEqual(r)
    member __.AnyDifferent(o : V3i) = x <> o.X || y <> o.Y || z <> o.Z
    static member AnyDifferent(l : V3i, r : V3i) = l.AnyDifferent(r)
    member __.AllGreater(o : V3i) = x > o.X && y > o.Y && z > o.Z
    static member AllGreater(l : V3i, r : V3i) = l.AllGreater(r)
    member __.AllGreaterOrEqual(o : V3i) = x >= o.X && y >= o.Y && z >= o.Z
    static member AllGreaterOrEqual(l : V3i, r : V3i) = l.AllGreaterOrEqual(r)
    member __.AllSmaller(o : V3i) = x < o.X && y < o.Y && z < o.Z
    static member AllSmaller(l : V3i, r : V3i) = l.AllSmaller(r)
    member __.AllSmallerOrEqual(o : V3i) = x <= o.X && y <= o.Y && z <= o.Z
    static member AllSmallerOrEqual(l : V3i, r : V3i) = l.AllSmallerOrEqual(r)
    member __.AllEqual(o : V3i) = x = o.X && y = o.Y && z = o.Z
    static member AllEqual(l : V3i, r : V3i) = l.AllEqual(r)
    member __.AllDifferent(o : V3i) = x <> o.X && y <> o.Y && z <> o.Z
    static member AllDifferent(l : V3i, r : V3i) = l.AllDifferent(r)
    new(v : V2i, l : int) = V3i(v.X, v.Y, l)
type V4i(x : int, y : int, z : int, w : int) = 
    member __.X = x
    interface NoSRTP.IHasX<int> with member x.X = x.X
    member __.Y = y
    interface NoSRTP.IHasY<int> with member x.Y = x.Y
    member __.Z = z
    interface NoSRTP.IHasZ<int> with member x.Z = x.Z
    member __.W = w
    interface NoSRTP.IHasW<int> with member x.W = x.W
    member __.XX = V2i(x, x)
    member __.XY = V2i(x, y)
    interface NoSRTP.IHasXY<V2i> with member x.XY = x.XY
    member __.XZ = V2i(x, z)
    member __.XW = V2i(x, w)
    member __.YX = V2i(y, x)
    member __.YY = V2i(y, y)
    member __.YZ = V2i(y, z)
    interface NoSRTP.IHasYZ<V2i> with member x.YZ = x.YZ
    member __.YW = V2i(y, w)
    member __.ZX = V2i(z, x)
    member __.ZY = V2i(z, y)
    member __.ZZ = V2i(z, z)
    member __.ZW = V2i(z, w)
    interface NoSRTP.IHasZW<V2i> with member x.ZW = x.ZW
    member __.WX = V2i(w, x)
    member __.WY = V2i(w, y)
    member __.WZ = V2i(w, z)
    member __.WW = V2i(w, w)
    member __.XXX = V3i(x, x, x)
    member __.XXY = V3i(x, x, y)
    member __.XXZ = V3i(x, x, z)
    member __.XXW = V3i(x, x, w)
    member __.XYX = V3i(x, y, x)
    member __.XYY = V3i(x, y, y)
    member __.XYZ = V3i(x, y, z)
    interface NoSRTP.IHasXYZ<V3i> with member x.XYZ = x.XYZ
    member __.XYW = V3i(x, y, w)
    member __.XZX = V3i(x, z, x)
    member __.XZY = V3i(x, z, y)
    member __.XZZ = V3i(x, z, z)
    member __.XZW = V3i(x, z, w)
    member __.XWX = V3i(x, w, x)
    member __.XWY = V3i(x, w, y)
    member __.XWZ = V3i(x, w, z)
    member __.XWW = V3i(x, w, w)
    member __.YXX = V3i(y, x, x)
    member __.YXY = V3i(y, x, y)
    member __.YXZ = V3i(y, x, z)
    member __.YXW = V3i(y, x, w)
    member __.YYX = V3i(y, y, x)
    member __.YYY = V3i(y, y, y)
    member __.YYZ = V3i(y, y, z)
    member __.YYW = V3i(y, y, w)
    member __.YZX = V3i(y, z, x)
    member __.YZY = V3i(y, z, y)
    member __.YZZ = V3i(y, z, z)
    member __.YZW = V3i(y, z, w)
    interface NoSRTP.IHasYZW<V3i> with member x.YZW = x.YZW
    member __.YWX = V3i(y, w, x)
    member __.YWY = V3i(y, w, y)
    member __.YWZ = V3i(y, w, z)
    member __.YWW = V3i(y, w, w)
    member __.ZXX = V3i(z, x, x)
    member __.ZXY = V3i(z, x, y)
    member __.ZXZ = V3i(z, x, z)
    member __.ZXW = V3i(z, x, w)
    member __.ZYX = V3i(z, y, x)
    member __.ZYY = V3i(z, y, y)
    member __.ZYZ = V3i(z, y, z)
    member __.ZYW = V3i(z, y, w)
    member __.ZZX = V3i(z, z, x)
    member __.ZZY = V3i(z, z, y)
    member __.ZZZ = V3i(z, z, z)
    member __.ZZW = V3i(z, z, w)
    member __.ZWX = V3i(z, w, x)
    member __.ZWY = V3i(z, w, y)
    member __.ZWZ = V3i(z, w, z)
    member __.ZWW = V3i(z, w, w)
    member __.WXX = V3i(w, x, x)
    member __.WXY = V3i(w, x, y)
    member __.WXZ = V3i(w, x, z)
    member __.WXW = V3i(w, x, w)
    member __.WYX = V3i(w, y, x)
    member __.WYY = V3i(w, y, y)
    member __.WYZ = V3i(w, y, z)
    member __.WYW = V3i(w, y, w)
    member __.WZX = V3i(w, z, x)
    member __.WZY = V3i(w, z, y)
    member __.WZZ = V3i(w, z, z)
    member __.WZW = V3i(w, z, w)
    member __.WWX = V3i(w, w, x)
    member __.WWY = V3i(w, w, y)
    member __.WWZ = V3i(w, w, z)
    member __.WWW = V3i(w, w, w)
    member __.XXXX = V4i(x, x, x, x)
    member __.XXXY = V4i(x, x, x, y)
    member __.XXXZ = V4i(x, x, x, z)
    member __.XXXW = V4i(x, x, x, w)
    member __.XXYX = V4i(x, x, y, x)
    member __.XXYY = V4i(x, x, y, y)
    member __.XXYZ = V4i(x, x, y, z)
    member __.XXYW = V4i(x, x, y, w)
    member __.XXZX = V4i(x, x, z, x)
    member __.XXZY = V4i(x, x, z, y)
    member __.XXZZ = V4i(x, x, z, z)
    member __.XXZW = V4i(x, x, z, w)
    member __.XXWX = V4i(x, x, w, x)
    member __.XXWY = V4i(x, x, w, y)
    member __.XXWZ = V4i(x, x, w, z)
    member __.XXWW = V4i(x, x, w, w)
    member __.XYXX = V4i(x, y, x, x)
    member __.XYXY = V4i(x, y, x, y)
    member __.XYXZ = V4i(x, y, x, z)
    member __.XYXW = V4i(x, y, x, w)
    member __.XYYX = V4i(x, y, y, x)
    member __.XYYY = V4i(x, y, y, y)
    member __.XYYZ = V4i(x, y, y, z)
    member __.XYYW = V4i(x, y, y, w)
    member __.XYZX = V4i(x, y, z, x)
    member __.XYZY = V4i(x, y, z, y)
    member __.XYZZ = V4i(x, y, z, z)
    member __.XYZW = V4i(x, y, z, w)
    interface NoSRTP.IHasXYZW<V4i> with member x.XYZW = x.XYZW
    member __.XYWX = V4i(x, y, w, x)
    member __.XYWY = V4i(x, y, w, y)
    member __.XYWZ = V4i(x, y, w, z)
    member __.XYWW = V4i(x, y, w, w)
    member __.XZXX = V4i(x, z, x, x)
    member __.XZXY = V4i(x, z, x, y)
    member __.XZXZ = V4i(x, z, x, z)
    member __.XZXW = V4i(x, z, x, w)
    member __.XZYX = V4i(x, z, y, x)
    member __.XZYY = V4i(x, z, y, y)
    member __.XZYZ = V4i(x, z, y, z)
    member __.XZYW = V4i(x, z, y, w)
    member __.XZZX = V4i(x, z, z, x)
    member __.XZZY = V4i(x, z, z, y)
    member __.XZZZ = V4i(x, z, z, z)
    member __.XZZW = V4i(x, z, z, w)
    member __.XZWX = V4i(x, z, w, x)
    member __.XZWY = V4i(x, z, w, y)
    member __.XZWZ = V4i(x, z, w, z)
    member __.XZWW = V4i(x, z, w, w)
    member __.XWXX = V4i(x, w, x, x)
    member __.XWXY = V4i(x, w, x, y)
    member __.XWXZ = V4i(x, w, x, z)
    member __.XWXW = V4i(x, w, x, w)
    member __.XWYX = V4i(x, w, y, x)
    member __.XWYY = V4i(x, w, y, y)
    member __.XWYZ = V4i(x, w, y, z)
    member __.XWYW = V4i(x, w, y, w)
    member __.XWZX = V4i(x, w, z, x)
    member __.XWZY = V4i(x, w, z, y)
    member __.XWZZ = V4i(x, w, z, z)
    member __.XWZW = V4i(x, w, z, w)
    member __.XWWX = V4i(x, w, w, x)
    member __.XWWY = V4i(x, w, w, y)
    member __.XWWZ = V4i(x, w, w, z)
    member __.XWWW = V4i(x, w, w, w)
    member __.YXXX = V4i(y, x, x, x)
    member __.YXXY = V4i(y, x, x, y)
    member __.YXXZ = V4i(y, x, x, z)
    member __.YXXW = V4i(y, x, x, w)
    member __.YXYX = V4i(y, x, y, x)
    member __.YXYY = V4i(y, x, y, y)
    member __.YXYZ = V4i(y, x, y, z)
    member __.YXYW = V4i(y, x, y, w)
    member __.YXZX = V4i(y, x, z, x)
    member __.YXZY = V4i(y, x, z, y)
    member __.YXZZ = V4i(y, x, z, z)
    member __.YXZW = V4i(y, x, z, w)
    member __.YXWX = V4i(y, x, w, x)
    member __.YXWY = V4i(y, x, w, y)
    member __.YXWZ = V4i(y, x, w, z)
    member __.YXWW = V4i(y, x, w, w)
    member __.YYXX = V4i(y, y, x, x)
    member __.YYXY = V4i(y, y, x, y)
    member __.YYXZ = V4i(y, y, x, z)
    member __.YYXW = V4i(y, y, x, w)
    member __.YYYX = V4i(y, y, y, x)
    member __.YYYY = V4i(y, y, y, y)
    member __.YYYZ = V4i(y, y, y, z)
    member __.YYYW = V4i(y, y, y, w)
    member __.YYZX = V4i(y, y, z, x)
    member __.YYZY = V4i(y, y, z, y)
    member __.YYZZ = V4i(y, y, z, z)
    member __.YYZW = V4i(y, y, z, w)
    member __.YYWX = V4i(y, y, w, x)
    member __.YYWY = V4i(y, y, w, y)
    member __.YYWZ = V4i(y, y, w, z)
    member __.YYWW = V4i(y, y, w, w)
    member __.YZXX = V4i(y, z, x, x)
    member __.YZXY = V4i(y, z, x, y)
    member __.YZXZ = V4i(y, z, x, z)
    member __.YZXW = V4i(y, z, x, w)
    member __.YZYX = V4i(y, z, y, x)
    member __.YZYY = V4i(y, z, y, y)
    member __.YZYZ = V4i(y, z, y, z)
    member __.YZYW = V4i(y, z, y, w)
    member __.YZZX = V4i(y, z, z, x)
    member __.YZZY = V4i(y, z, z, y)
    member __.YZZZ = V4i(y, z, z, z)
    member __.YZZW = V4i(y, z, z, w)
    member __.YZWX = V4i(y, z, w, x)
    member __.YZWY = V4i(y, z, w, y)
    member __.YZWZ = V4i(y, z, w, z)
    member __.YZWW = V4i(y, z, w, w)
    member __.YWXX = V4i(y, w, x, x)
    member __.YWXY = V4i(y, w, x, y)
    member __.YWXZ = V4i(y, w, x, z)
    member __.YWXW = V4i(y, w, x, w)
    member __.YWYX = V4i(y, w, y, x)
    member __.YWYY = V4i(y, w, y, y)
    member __.YWYZ = V4i(y, w, y, z)
    member __.YWYW = V4i(y, w, y, w)
    member __.YWZX = V4i(y, w, z, x)
    member __.YWZY = V4i(y, w, z, y)
    member __.YWZZ = V4i(y, w, z, z)
    member __.YWZW = V4i(y, w, z, w)
    member __.YWWX = V4i(y, w, w, x)
    member __.YWWY = V4i(y, w, w, y)
    member __.YWWZ = V4i(y, w, w, z)
    member __.YWWW = V4i(y, w, w, w)
    member __.ZXXX = V4i(z, x, x, x)
    member __.ZXXY = V4i(z, x, x, y)
    member __.ZXXZ = V4i(z, x, x, z)
    member __.ZXXW = V4i(z, x, x, w)
    member __.ZXYX = V4i(z, x, y, x)
    member __.ZXYY = V4i(z, x, y, y)
    member __.ZXYZ = V4i(z, x, y, z)
    member __.ZXYW = V4i(z, x, y, w)
    member __.ZXZX = V4i(z, x, z, x)
    member __.ZXZY = V4i(z, x, z, y)
    member __.ZXZZ = V4i(z, x, z, z)
    member __.ZXZW = V4i(z, x, z, w)
    member __.ZXWX = V4i(z, x, w, x)
    member __.ZXWY = V4i(z, x, w, y)
    member __.ZXWZ = V4i(z, x, w, z)
    member __.ZXWW = V4i(z, x, w, w)
    member __.ZYXX = V4i(z, y, x, x)
    member __.ZYXY = V4i(z, y, x, y)
    member __.ZYXZ = V4i(z, y, x, z)
    member __.ZYXW = V4i(z, y, x, w)
    member __.ZYYX = V4i(z, y, y, x)
    member __.ZYYY = V4i(z, y, y, y)
    member __.ZYYZ = V4i(z, y, y, z)
    member __.ZYYW = V4i(z, y, y, w)
    member __.ZYZX = V4i(z, y, z, x)
    member __.ZYZY = V4i(z, y, z, y)
    member __.ZYZZ = V4i(z, y, z, z)
    member __.ZYZW = V4i(z, y, z, w)
    member __.ZYWX = V4i(z, y, w, x)
    member __.ZYWY = V4i(z, y, w, y)
    member __.ZYWZ = V4i(z, y, w, z)
    member __.ZYWW = V4i(z, y, w, w)
    member __.ZZXX = V4i(z, z, x, x)
    member __.ZZXY = V4i(z, z, x, y)
    member __.ZZXZ = V4i(z, z, x, z)
    member __.ZZXW = V4i(z, z, x, w)
    member __.ZZYX = V4i(z, z, y, x)
    member __.ZZYY = V4i(z, z, y, y)
    member __.ZZYZ = V4i(z, z, y, z)
    member __.ZZYW = V4i(z, z, y, w)
    member __.ZZZX = V4i(z, z, z, x)
    member __.ZZZY = V4i(z, z, z, y)
    member __.ZZZZ = V4i(z, z, z, z)
    member __.ZZZW = V4i(z, z, z, w)
    member __.ZZWX = V4i(z, z, w, x)
    member __.ZZWY = V4i(z, z, w, y)
    member __.ZZWZ = V4i(z, z, w, z)
    member __.ZZWW = V4i(z, z, w, w)
    member __.ZWXX = V4i(z, w, x, x)
    member __.ZWXY = V4i(z, w, x, y)
    member __.ZWXZ = V4i(z, w, x, z)
    member __.ZWXW = V4i(z, w, x, w)
    member __.ZWYX = V4i(z, w, y, x)
    member __.ZWYY = V4i(z, w, y, y)
    member __.ZWYZ = V4i(z, w, y, z)
    member __.ZWYW = V4i(z, w, y, w)
    member __.ZWZX = V4i(z, w, z, x)
    member __.ZWZY = V4i(z, w, z, y)
    member __.ZWZZ = V4i(z, w, z, z)
    member __.ZWZW = V4i(z, w, z, w)
    member __.ZWWX = V4i(z, w, w, x)
    member __.ZWWY = V4i(z, w, w, y)
    member __.ZWWZ = V4i(z, w, w, z)
    member __.ZWWW = V4i(z, w, w, w)
    member __.WXXX = V4i(w, x, x, x)
    member __.WXXY = V4i(w, x, x, y)
    member __.WXXZ = V4i(w, x, x, z)
    member __.WXXW = V4i(w, x, x, w)
    member __.WXYX = V4i(w, x, y, x)
    member __.WXYY = V4i(w, x, y, y)
    member __.WXYZ = V4i(w, x, y, z)
    member __.WXYW = V4i(w, x, y, w)
    member __.WXZX = V4i(w, x, z, x)
    member __.WXZY = V4i(w, x, z, y)
    member __.WXZZ = V4i(w, x, z, z)
    member __.WXZW = V4i(w, x, z, w)
    member __.WXWX = V4i(w, x, w, x)
    member __.WXWY = V4i(w, x, w, y)
    member __.WXWZ = V4i(w, x, w, z)
    member __.WXWW = V4i(w, x, w, w)
    member __.WYXX = V4i(w, y, x, x)
    member __.WYXY = V4i(w, y, x, y)
    member __.WYXZ = V4i(w, y, x, z)
    member __.WYXW = V4i(w, y, x, w)
    member __.WYYX = V4i(w, y, y, x)
    member __.WYYY = V4i(w, y, y, y)
    member __.WYYZ = V4i(w, y, y, z)
    member __.WYYW = V4i(w, y, y, w)
    member __.WYZX = V4i(w, y, z, x)
    member __.WYZY = V4i(w, y, z, y)
    member __.WYZZ = V4i(w, y, z, z)
    member __.WYZW = V4i(w, y, z, w)
    member __.WYWX = V4i(w, y, w, x)
    member __.WYWY = V4i(w, y, w, y)
    member __.WYWZ = V4i(w, y, w, z)
    member __.WYWW = V4i(w, y, w, w)
    member __.WZXX = V4i(w, z, x, x)
    member __.WZXY = V4i(w, z, x, y)
    member __.WZXZ = V4i(w, z, x, z)
    member __.WZXW = V4i(w, z, x, w)
    member __.WZYX = V4i(w, z, y, x)
    member __.WZYY = V4i(w, z, y, y)
    member __.WZYZ = V4i(w, z, y, z)
    member __.WZYW = V4i(w, z, y, w)
    member __.WZZX = V4i(w, z, z, x)
    member __.WZZY = V4i(w, z, z, y)
    member __.WZZZ = V4i(w, z, z, z)
    member __.WZZW = V4i(w, z, z, w)
    member __.WZWX = V4i(w, z, w, x)
    member __.WZWY = V4i(w, z, w, y)
    member __.WZWZ = V4i(w, z, w, z)
    member __.WZWW = V4i(w, z, w, w)
    member __.WWXX = V4i(w, w, x, x)
    member __.WWXY = V4i(w, w, x, y)
    member __.WWXZ = V4i(w, w, x, z)
    member __.WWXW = V4i(w, w, x, w)
    member __.WWYX = V4i(w, w, y, x)
    member __.WWYY = V4i(w, w, y, y)
    member __.WWYZ = V4i(w, w, y, z)
    member __.WWYW = V4i(w, w, y, w)
    member __.WWZX = V4i(w, w, z, x)
    member __.WWZY = V4i(w, w, z, y)
    member __.WWZZ = V4i(w, w, z, z)
    member __.WWZW = V4i(w, w, z, w)
    member __.WWWX = V4i(w, w, w, x)
    member __.WWWY = V4i(w, w, w, y)
    member __.WWWZ = V4i(w, w, w, z)
    member __.WWWW = V4i(w, w, w, w)
    static member Zero = V4i(0, 0, 0, 0)
    static member One = V4i(1, 1, 1, 1)
    static member OOOO = V4i(0, 0, 0, 0)
    static member OOOI = V4i(0, 0, 0, 1)
    static member OOIO = V4i(0, 0, 1, 0)
    static member OOII = V4i(0, 0, 1, 1)
    static member OIOO = V4i(0, 1, 0, 0)
    static member OIOI = V4i(0, 1, 0, 1)
    static member OIIO = V4i(0, 1, 1, 0)
    static member OIII = V4i(0, 1, 1, 1)
    static member IOOO = V4i(1, 0, 0, 0)
    static member IOOI = V4i(1, 0, 0, 1)
    static member IOIO = V4i(1, 0, 1, 0)
    static member IOII = V4i(1, 0, 1, 1)
    static member IIOO = V4i(1, 1, 0, 0)
    static member IIOI = V4i(1, 1, 0, 1)
    static member IIIO = V4i(1, 1, 1, 0)
    static member IIII = V4i(1, 1, 1, 1)
    static member (~-) (v : V4i) = V4i(-v.X, -v.Y, -v.Z, -v.W)
    static member (+) (l : V4i, r : V4i) = V4i(l.X + r.X, l.Y + r.Y, l.Z + r.Z, l.W + r.W)
    static member (-) (l : V4i, r : V4i) = V4i(l.X - r.X, l.Y - r.Y, l.Z - r.Z, l.W - r.W)
    static member (*) (l : V4i, r : V4i) = V4i(l.X * r.X, l.Y * r.Y, l.Z * r.Z, l.W * r.W)
    static member (/) (l : V4i, r : V4i) = V4i(l.X / r.X, l.Y / r.Y, l.Z / r.Z, l.W / r.W)
    static member (*) (l : V4i, r : int) = V4i(l.X * r, l.Y * r, l.Z * r, l.W * r)
    static member (/) (l : V4i, r : int) = V4i(l.X / r, l.Y / r, l.Z / r, l.W / r)
    static member (*) (l : int, r : V4i) = V4i(l * r.X, l * r.Y, l * r.Z, l * r.W)
    static member (/) (l : int, r : V4i) = V4i(l / r.X, l / r.Y, l / r.Z, l / r.W)
    static member Dot(l : V4i, r : V4i) = l.X * r.X + l.Y * r.Y + l.Z * r.Z + l.W * r.W
    member __.Dot(r : V4i) = x * r.X + y * r.Y + z * r.Z + w * r.W
    interface NoSRTP.IHasDot<V4i, int> with member x.Dot(r) = x.Dot(r)
    member __.LengthSquared = x*x + y*y + z*z + w*w
    interface NoSRTP.IHasLengthSquared<int> with member x.LengthSquared = x.LengthSquared
    member __.Length = sqrt (float (x*x + y*y + z*z + w*w))
    interface NoSRTP.IHasLength<float> with member x.Length = x.Length
    member __.Abs = V4i(abs x, abs y, abs z, abs w)
    static member Min(l : V4i, r : V4i) = V4i(min l.X r.X, min l.Y r.Y, min l.Z r.Z, min l.W r.W)
    static member Max(l : V4i, r : V4i) = V4i(max l.X r.X, max l.Y r.Y, max l.Z r.Z, max l.W r.W)
    static member Distance(l : V4i, r : V4i) = (l - r).Length
    override __.GetHashCode() = HashCode.Combine(x.GetHashCode(), y.GetHashCode(), z.GetHashCode(), w.GetHashCode())
    override __.Equals(o) = match o with | :? V4i as o -> x = o.X && y = o.Y && z = o.Z && w = o.W | _ -> false
    override __.ToString() = sprintf "[%d, %d, %d, %d]" x y z w
    interface System.IComparable with
        member __.CompareTo(o) = 
            match o with 
            | :? V4i as o -> 
                let mutable a = 0
                if (a <- compare x o.X; a <> 0) then a
                elif (a <- compare y o.Y; a <> 0) then a
                elif (a <- compare z o.Z; a <> 0) then a
                else compare w o.W
            | _ -> failwith "uncomparable"
    member __.AnyGreater(o : V4i) = x > o.X || y > o.Y || z > o.Z || w > o.W
    static member AnyGreater(l : V4i, r : V4i) = l.AnyGreater(r)
    member __.AnyGreaterOrEqual(o : V4i) = x >= o.X || y >= o.Y || z >= o.Z || w >= o.W
    static member AnyGreaterOrEqual(l : V4i, r : V4i) = l.AnyGreaterOrEqual(r)
    member __.AnySmaller(o : V4i) = x < o.X || y < o.Y || z < o.Z || w < o.W
    static member AnySmaller(l : V4i, r : V4i) = l.AnySmaller(r)
    member __.AnySmallerOrEqual(o : V4i) = x <= o.X || y <= o.Y || z <= o.Z || w <= o.W
    static member AnySmallerOrEqual(l : V4i, r : V4i) = l.AnySmallerOrEqual(r)
    member __.AnyEqual(o : V4i) = x = o.X || y = o.Y || z = o.Z || w = o.W
    static member AnyEqual(l : V4i, r : V4i) = l.AnyEqual(r)
    member __.AnyDifferent(o : V4i) = x <> o.X || y <> o.Y || z <> o.Z || w <> o.W
    static member AnyDifferent(l : V4i, r : V4i) = l.AnyDifferent(r)
    member __.AllGreater(o : V4i) = x > o.X && y > o.Y && z > o.Z && w > o.W
    static member AllGreater(l : V4i, r : V4i) = l.AllGreater(r)
    member __.AllGreaterOrEqual(o : V4i) = x >= o.X && y >= o.Y && z >= o.Z && w >= o.W
    static member AllGreaterOrEqual(l : V4i, r : V4i) = l.AllGreaterOrEqual(r)
    member __.AllSmaller(o : V4i) = x < o.X && y < o.Y && z < o.Z && w < o.W
    static member AllSmaller(l : V4i, r : V4i) = l.AllSmaller(r)
    member __.AllSmallerOrEqual(o : V4i) = x <= o.X && y <= o.Y && z <= o.Z && w <= o.W
    static member AllSmallerOrEqual(l : V4i, r : V4i) = l.AllSmallerOrEqual(r)
    member __.AllEqual(o : V4i) = x = o.X && y = o.Y && z = o.Z && w = o.W
    static member AllEqual(l : V4i, r : V4i) = l.AllEqual(r)
    member __.AllDifferent(o : V4i) = x <> o.X && y <> o.Y && z <> o.Z && w <> o.W
    static member AllDifferent(l : V4i, r : V4i) = l.AllDifferent(r)
    new(v : V3i, l : int) = V4i(v.X, v.Y, v.Z, l)
type V2d(x : float, y : float) = 
    member __.X = x
    interface NoSRTP.IHasX<float> with member x.X = x.X
    member __.Y = y
    interface NoSRTP.IHasY<float> with member x.Y = x.Y
    member __.XX = V2d(x, x)
    member __.XY = V2d(x, y)
    interface NoSRTP.IHasXY<V2d> with member x.XY = x.XY
    member __.YX = V2d(y, x)
    member __.YY = V2d(y, y)
    static member Zero = V2d(0.0, 0.0)
    static member One = V2d(1.0, 1.0)
    static member OO = V2d(0.0, 0.0)
    static member OI = V2d(0.0, 1.0)
    static member IO = V2d(1.0, 0.0)
    static member II = V2d(1.0, 1.0)
    static member (~-) (v : V2d) = V2d(-v.X, -v.Y)
    static member (+) (l : V2d, r : V2d) = V2d(l.X + r.X, l.Y + r.Y)
    static member (-) (l : V2d, r : V2d) = V2d(l.X - r.X, l.Y - r.Y)
    static member (*) (l : V2d, r : V2d) = V2d(l.X * r.X, l.Y * r.Y)
    static member (/) (l : V2d, r : V2d) = V2d(l.X / r.X, l.Y / r.Y)
    static member (*) (l : V2d, r : float) = V2d(l.X * r, l.Y * r)
    static member (/) (l : V2d, r : float) = V2d(l.X / r, l.Y / r)
    static member (*) (l : float, r : V2d) = V2d(l * r.X, l * r.Y)
    static member (/) (l : float, r : V2d) = V2d(l / r.X, l / r.Y)
    static member Dot(l : V2d, r : V2d) = l.X * r.X + l.Y * r.Y
    member __.Dot(r : V2d) = x * r.X + y * r.Y
    interface NoSRTP.IHasDot<V2d, float> with member x.Dot(r) = x.Dot(r)
    member __.LengthSquared = x*x + y*y
    interface NoSRTP.IHasLengthSquared<float> with member x.LengthSquared = x.LengthSquared
    member __.Length = sqrt (x*x + y*y)
    interface NoSRTP.IHasLength<float> with member x.Length = x.Length
    member this.Normalized = let l = this.Length in V2d(x/l, y/l)
    interface NoSRTP.IHasNormalized<V2d> with member x.Normalized = x.Normalized
    member __.Abs = V2d(abs x, abs y)
    member __.IsNaN = Fun.IsNaN(x) || Fun.IsNaN(y)
    static member Min(l : V2d, r : V2d) = V2d(min l.X r.X, min l.Y r.Y)
    static member Max(l : V2d, r : V2d) = V2d(max l.X r.X, max l.Y r.Y)
    static member Distance(l : V2d, r : V2d) = (l - r).Length
    override __.GetHashCode() = HashCode.Combine(x.GetHashCode(), y.GetHashCode())
    override __.Equals(o) = match o with | :? V2d as o -> x = o.X && y = o.Y | _ -> false
    override __.ToString() = sprintf "[%f, %f]" x y
    interface System.IComparable with
        member __.CompareTo(o) = 
            match o with 
            | :? V2d as o -> 
                let mutable a = 0
                if (a <- compare x o.X; a <> 0) then a
                else compare y o.Y
            | _ -> failwith "uncomparable"
    member __.AnyGreater(o : V2d) = x > o.X || y > o.Y
    static member AnyGreater(l : V2d, r : V2d) = l.AnyGreater(r)
    member __.AnyGreaterOrEqual(o : V2d) = x >= o.X || y >= o.Y
    static member AnyGreaterOrEqual(l : V2d, r : V2d) = l.AnyGreaterOrEqual(r)
    member __.AnySmaller(o : V2d) = x < o.X || y < o.Y
    static member AnySmaller(l : V2d, r : V2d) = l.AnySmaller(r)
    member __.AnySmallerOrEqual(o : V2d) = x <= o.X || y <= o.Y
    static member AnySmallerOrEqual(l : V2d, r : V2d) = l.AnySmallerOrEqual(r)
    member __.AnyEqual(o : V2d) = x = o.X || y = o.Y
    static member AnyEqual(l : V2d, r : V2d) = l.AnyEqual(r)
    member __.AnyDifferent(o : V2d) = x <> o.X || y <> o.Y
    static member AnyDifferent(l : V2d, r : V2d) = l.AnyDifferent(r)
    member __.AllGreater(o : V2d) = x > o.X && y > o.Y
    static member AllGreater(l : V2d, r : V2d) = l.AllGreater(r)
    member __.AllGreaterOrEqual(o : V2d) = x >= o.X && y >= o.Y
    static member AllGreaterOrEqual(l : V2d, r : V2d) = l.AllGreaterOrEqual(r)
    member __.AllSmaller(o : V2d) = x < o.X && y < o.Y
    static member AllSmaller(l : V2d, r : V2d) = l.AllSmaller(r)
    member __.AllSmallerOrEqual(o : V2d) = x <= o.X && y <= o.Y
    static member AllSmallerOrEqual(l : V2d, r : V2d) = l.AllSmallerOrEqual(r)
    member __.AllEqual(o : V2d) = x = o.X && y = o.Y
    static member AllEqual(l : V2d, r : V2d) = l.AllEqual(r)
    member __.AllDifferent(o : V2d) = x <> o.X && y <> o.Y
    static member AllDifferent(l : V2d, r : V2d) = l.AllDifferent(r)
    new(v : V2i) = V2d(float v.X, float v.Y)
type V3d(x : float, y : float, z : float) = 
    member __.X = x
    interface NoSRTP.IHasX<float> with member x.X = x.X
    member __.Y = y
    interface NoSRTP.IHasY<float> with member x.Y = x.Y
    member __.Z = z
    interface NoSRTP.IHasZ<float> with member x.Z = x.Z
    member __.XX = V2d(x, x)
    member __.XY = V2d(x, y)
    interface NoSRTP.IHasXY<V2d> with member x.XY = x.XY
    member __.XZ = V2d(x, z)
    member __.YX = V2d(y, x)
    member __.YY = V2d(y, y)
    member __.YZ = V2d(y, z)
    interface NoSRTP.IHasYZ<V2d> with member x.YZ = x.YZ
    member __.ZX = V2d(z, x)
    member __.ZY = V2d(z, y)
    member __.ZZ = V2d(z, z)
    member __.XXX = V3d(x, x, x)
    member __.XXY = V3d(x, x, y)
    member __.XXZ = V3d(x, x, z)
    member __.XYX = V3d(x, y, x)
    member __.XYY = V3d(x, y, y)
    member __.XYZ = V3d(x, y, z)
    interface NoSRTP.IHasXYZ<V3d> with member x.XYZ = x.XYZ
    member __.XZX = V3d(x, z, x)
    member __.XZY = V3d(x, z, y)
    member __.XZZ = V3d(x, z, z)
    member __.YXX = V3d(y, x, x)
    member __.YXY = V3d(y, x, y)
    member __.YXZ = V3d(y, x, z)
    member __.YYX = V3d(y, y, x)
    member __.YYY = V3d(y, y, y)
    member __.YYZ = V3d(y, y, z)
    member __.YZX = V3d(y, z, x)
    member __.YZY = V3d(y, z, y)
    member __.YZZ = V3d(y, z, z)
    member __.ZXX = V3d(z, x, x)
    member __.ZXY = V3d(z, x, y)
    member __.ZXZ = V3d(z, x, z)
    member __.ZYX = V3d(z, y, x)
    member __.ZYY = V3d(z, y, y)
    member __.ZYZ = V3d(z, y, z)
    member __.ZZX = V3d(z, z, x)
    member __.ZZY = V3d(z, z, y)
    member __.ZZZ = V3d(z, z, z)
    static member Zero = V3d(0.0, 0.0, 0.0)
    static member One = V3d(1.0, 1.0, 1.0)
    static member OOO = V3d(0.0, 0.0, 0.0)
    static member OOI = V3d(0.0, 0.0, 1.0)
    static member OIO = V3d(0.0, 1.0, 0.0)
    static member OII = V3d(0.0, 1.0, 1.0)
    static member IOO = V3d(1.0, 0.0, 0.0)
    static member IOI = V3d(1.0, 0.0, 1.0)
    static member IIO = V3d(1.0, 1.0, 0.0)
    static member III = V3d(1.0, 1.0, 1.0)
    static member (~-) (v : V3d) = V3d(-v.X, -v.Y, -v.Z)
    static member (+) (l : V3d, r : V3d) = V3d(l.X + r.X, l.Y + r.Y, l.Z + r.Z)
    static member (-) (l : V3d, r : V3d) = V3d(l.X - r.X, l.Y - r.Y, l.Z - r.Z)
    static member (*) (l : V3d, r : V3d) = V3d(l.X * r.X, l.Y * r.Y, l.Z * r.Z)
    static member (/) (l : V3d, r : V3d) = V3d(l.X / r.X, l.Y / r.Y, l.Z / r.Z)
    static member (*) (l : V3d, r : float) = V3d(l.X * r, l.Y * r, l.Z * r)
    static member (/) (l : V3d, r : float) = V3d(l.X / r, l.Y / r, l.Z / r)
    static member (*) (l : float, r : V3d) = V3d(l * r.X, l * r.Y, l * r.Z)
    static member (/) (l : float, r : V3d) = V3d(l / r.X, l / r.Y, l / r.Z)
    static member Dot(l : V3d, r : V3d) = l.X * r.X + l.Y * r.Y + l.Z * r.Z
    member __.Dot(r : V3d) = x * r.X + y * r.Y + z * r.Z
    interface NoSRTP.IHasDot<V3d, float> with member x.Dot(r) = x.Dot(r)
    static member Cross(l : V3d, r : V3d) = V3d(l.Y * r.Z - l.Z * r.Y, l.Z * r.X - l.X * r.Z, l.X * r.Y - l.Y * r.X)
    member __.Cross(r : V3d) = V3d(y * r.Z - z * r.Y, z * r.X - x * r.Z, x * r.Y - y * r.X)
    interface NoSRTP.IHasCross<V3d, V3d> with member x.Cross(r) = x.Cross(r)
    member __.LengthSquared = x*x + y*y + z*z
    interface NoSRTP.IHasLengthSquared<float> with member x.LengthSquared = x.LengthSquared
    member __.Length = sqrt (x*x + y*y + z*z)
    interface NoSRTP.IHasLength<float> with member x.Length = x.Length
    member this.Normalized = let l = this.Length in V3d(x/l, y/l, z/l)
    interface NoSRTP.IHasNormalized<V3d> with member x.Normalized = x.Normalized
    member __.Abs = V3d(abs x, abs y, abs z)
    member __.IsNaN = Fun.IsNaN(x) || Fun.IsNaN(y) || Fun.IsNaN(z)
    static member Min(l : V3d, r : V3d) = V3d(min l.X r.X, min l.Y r.Y, min l.Z r.Z)
    static member Max(l : V3d, r : V3d) = V3d(max l.X r.X, max l.Y r.Y, max l.Z r.Z)
    static member Distance(l : V3d, r : V3d) = (l - r).Length
    override __.GetHashCode() = HashCode.Combine(x.GetHashCode(), y.GetHashCode(), z.GetHashCode())
    override __.Equals(o) = match o with | :? V3d as o -> x = o.X && y = o.Y && z = o.Z | _ -> false
    override __.ToString() = sprintf "[%f, %f, %f]" x y z
    interface System.IComparable with
        member __.CompareTo(o) = 
            match o with 
            | :? V3d as o -> 
                let mutable a = 0
                if (a <- compare x o.X; a <> 0) then a
                elif (a <- compare y o.Y; a <> 0) then a
                else compare z o.Z
            | _ -> failwith "uncomparable"
    member __.AnyGreater(o : V3d) = x > o.X || y > o.Y || z > o.Z
    static member AnyGreater(l : V3d, r : V3d) = l.AnyGreater(r)
    member __.AnyGreaterOrEqual(o : V3d) = x >= o.X || y >= o.Y || z >= o.Z
    static member AnyGreaterOrEqual(l : V3d, r : V3d) = l.AnyGreaterOrEqual(r)
    member __.AnySmaller(o : V3d) = x < o.X || y < o.Y || z < o.Z
    static member AnySmaller(l : V3d, r : V3d) = l.AnySmaller(r)
    member __.AnySmallerOrEqual(o : V3d) = x <= o.X || y <= o.Y || z <= o.Z
    static member AnySmallerOrEqual(l : V3d, r : V3d) = l.AnySmallerOrEqual(r)
    member __.AnyEqual(o : V3d) = x = o.X || y = o.Y || z = o.Z
    static member AnyEqual(l : V3d, r : V3d) = l.AnyEqual(r)
    member __.AnyDifferent(o : V3d) = x <> o.X || y <> o.Y || z <> o.Z
    static member AnyDifferent(l : V3d, r : V3d) = l.AnyDifferent(r)
    member __.AllGreater(o : V3d) = x > o.X && y > o.Y && z > o.Z
    static member AllGreater(l : V3d, r : V3d) = l.AllGreater(r)
    member __.AllGreaterOrEqual(o : V3d) = x >= o.X && y >= o.Y && z >= o.Z
    static member AllGreaterOrEqual(l : V3d, r : V3d) = l.AllGreaterOrEqual(r)
    member __.AllSmaller(o : V3d) = x < o.X && y < o.Y && z < o.Z
    static member AllSmaller(l : V3d, r : V3d) = l.AllSmaller(r)
    member __.AllSmallerOrEqual(o : V3d) = x <= o.X && y <= o.Y && z <= o.Z
    static member AllSmallerOrEqual(l : V3d, r : V3d) = l.AllSmallerOrEqual(r)
    member __.AllEqual(o : V3d) = x = o.X && y = o.Y && z = o.Z
    static member AllEqual(l : V3d, r : V3d) = l.AllEqual(r)
    member __.AllDifferent(o : V3d) = x <> o.X && y <> o.Y && z <> o.Z
    static member AllDifferent(l : V3d, r : V3d) = l.AllDifferent(r)
    new(v : V2d, l : float) = V3d(v.X, v.Y, l)
    new(v : V3i) = V3d(float v.X, float v.Y, float v.Z)
type V4d(x : float, y : float, z : float, w : float) = 
    member __.X = x
    interface NoSRTP.IHasX<float> with member x.X = x.X
    member __.Y = y
    interface NoSRTP.IHasY<float> with member x.Y = x.Y
    member __.Z = z
    interface NoSRTP.IHasZ<float> with member x.Z = x.Z
    member __.W = w
    interface NoSRTP.IHasW<float> with member x.W = x.W
    member __.XX = V2d(x, x)
    member __.XY = V2d(x, y)
    interface NoSRTP.IHasXY<V2d> with member x.XY = x.XY
    member __.XZ = V2d(x, z)
    member __.XW = V2d(x, w)
    member __.YX = V2d(y, x)
    member __.YY = V2d(y, y)
    member __.YZ = V2d(y, z)
    interface NoSRTP.IHasYZ<V2d> with member x.YZ = x.YZ
    member __.YW = V2d(y, w)
    member __.ZX = V2d(z, x)
    member __.ZY = V2d(z, y)
    member __.ZZ = V2d(z, z)
    member __.ZW = V2d(z, w)
    interface NoSRTP.IHasZW<V2d> with member x.ZW = x.ZW
    member __.WX = V2d(w, x)
    member __.WY = V2d(w, y)
    member __.WZ = V2d(w, z)
    member __.WW = V2d(w, w)
    member __.XXX = V3d(x, x, x)
    member __.XXY = V3d(x, x, y)
    member __.XXZ = V3d(x, x, z)
    member __.XXW = V3d(x, x, w)
    member __.XYX = V3d(x, y, x)
    member __.XYY = V3d(x, y, y)
    member __.XYZ = V3d(x, y, z)
    interface NoSRTP.IHasXYZ<V3d> with member x.XYZ = x.XYZ
    member __.XYW = V3d(x, y, w)
    member __.XZX = V3d(x, z, x)
    member __.XZY = V3d(x, z, y)
    member __.XZZ = V3d(x, z, z)
    member __.XZW = V3d(x, z, w)
    member __.XWX = V3d(x, w, x)
    member __.XWY = V3d(x, w, y)
    member __.XWZ = V3d(x, w, z)
    member __.XWW = V3d(x, w, w)
    member __.YXX = V3d(y, x, x)
    member __.YXY = V3d(y, x, y)
    member __.YXZ = V3d(y, x, z)
    member __.YXW = V3d(y, x, w)
    member __.YYX = V3d(y, y, x)
    member __.YYY = V3d(y, y, y)
    member __.YYZ = V3d(y, y, z)
    member __.YYW = V3d(y, y, w)
    member __.YZX = V3d(y, z, x)
    member __.YZY = V3d(y, z, y)
    member __.YZZ = V3d(y, z, z)
    member __.YZW = V3d(y, z, w)
    interface NoSRTP.IHasYZW<V3d> with member x.YZW = x.YZW
    member __.YWX = V3d(y, w, x)
    member __.YWY = V3d(y, w, y)
    member __.YWZ = V3d(y, w, z)
    member __.YWW = V3d(y, w, w)
    member __.ZXX = V3d(z, x, x)
    member __.ZXY = V3d(z, x, y)
    member __.ZXZ = V3d(z, x, z)
    member __.ZXW = V3d(z, x, w)
    member __.ZYX = V3d(z, y, x)
    member __.ZYY = V3d(z, y, y)
    member __.ZYZ = V3d(z, y, z)
    member __.ZYW = V3d(z, y, w)
    member __.ZZX = V3d(z, z, x)
    member __.ZZY = V3d(z, z, y)
    member __.ZZZ = V3d(z, z, z)
    member __.ZZW = V3d(z, z, w)
    member __.ZWX = V3d(z, w, x)
    member __.ZWY = V3d(z, w, y)
    member __.ZWZ = V3d(z, w, z)
    member __.ZWW = V3d(z, w, w)
    member __.WXX = V3d(w, x, x)
    member __.WXY = V3d(w, x, y)
    member __.WXZ = V3d(w, x, z)
    member __.WXW = V3d(w, x, w)
    member __.WYX = V3d(w, y, x)
    member __.WYY = V3d(w, y, y)
    member __.WYZ = V3d(w, y, z)
    member __.WYW = V3d(w, y, w)
    member __.WZX = V3d(w, z, x)
    member __.WZY = V3d(w, z, y)
    member __.WZZ = V3d(w, z, z)
    member __.WZW = V3d(w, z, w)
    member __.WWX = V3d(w, w, x)
    member __.WWY = V3d(w, w, y)
    member __.WWZ = V3d(w, w, z)
    member __.WWW = V3d(w, w, w)
    member __.XXXX = V4d(x, x, x, x)
    member __.XXXY = V4d(x, x, x, y)
    member __.XXXZ = V4d(x, x, x, z)
    member __.XXXW = V4d(x, x, x, w)
    member __.XXYX = V4d(x, x, y, x)
    member __.XXYY = V4d(x, x, y, y)
    member __.XXYZ = V4d(x, x, y, z)
    member __.XXYW = V4d(x, x, y, w)
    member __.XXZX = V4d(x, x, z, x)
    member __.XXZY = V4d(x, x, z, y)
    member __.XXZZ = V4d(x, x, z, z)
    member __.XXZW = V4d(x, x, z, w)
    member __.XXWX = V4d(x, x, w, x)
    member __.XXWY = V4d(x, x, w, y)
    member __.XXWZ = V4d(x, x, w, z)
    member __.XXWW = V4d(x, x, w, w)
    member __.XYXX = V4d(x, y, x, x)
    member __.XYXY = V4d(x, y, x, y)
    member __.XYXZ = V4d(x, y, x, z)
    member __.XYXW = V4d(x, y, x, w)
    member __.XYYX = V4d(x, y, y, x)
    member __.XYYY = V4d(x, y, y, y)
    member __.XYYZ = V4d(x, y, y, z)
    member __.XYYW = V4d(x, y, y, w)
    member __.XYZX = V4d(x, y, z, x)
    member __.XYZY = V4d(x, y, z, y)
    member __.XYZZ = V4d(x, y, z, z)
    member __.XYZW = V4d(x, y, z, w)
    interface NoSRTP.IHasXYZW<V4d> with member x.XYZW = x.XYZW
    member __.XYWX = V4d(x, y, w, x)
    member __.XYWY = V4d(x, y, w, y)
    member __.XYWZ = V4d(x, y, w, z)
    member __.XYWW = V4d(x, y, w, w)
    member __.XZXX = V4d(x, z, x, x)
    member __.XZXY = V4d(x, z, x, y)
    member __.XZXZ = V4d(x, z, x, z)
    member __.XZXW = V4d(x, z, x, w)
    member __.XZYX = V4d(x, z, y, x)
    member __.XZYY = V4d(x, z, y, y)
    member __.XZYZ = V4d(x, z, y, z)
    member __.XZYW = V4d(x, z, y, w)
    member __.XZZX = V4d(x, z, z, x)
    member __.XZZY = V4d(x, z, z, y)
    member __.XZZZ = V4d(x, z, z, z)
    member __.XZZW = V4d(x, z, z, w)
    member __.XZWX = V4d(x, z, w, x)
    member __.XZWY = V4d(x, z, w, y)
    member __.XZWZ = V4d(x, z, w, z)
    member __.XZWW = V4d(x, z, w, w)
    member __.XWXX = V4d(x, w, x, x)
    member __.XWXY = V4d(x, w, x, y)
    member __.XWXZ = V4d(x, w, x, z)
    member __.XWXW = V4d(x, w, x, w)
    member __.XWYX = V4d(x, w, y, x)
    member __.XWYY = V4d(x, w, y, y)
    member __.XWYZ = V4d(x, w, y, z)
    member __.XWYW = V4d(x, w, y, w)
    member __.XWZX = V4d(x, w, z, x)
    member __.XWZY = V4d(x, w, z, y)
    member __.XWZZ = V4d(x, w, z, z)
    member __.XWZW = V4d(x, w, z, w)
    member __.XWWX = V4d(x, w, w, x)
    member __.XWWY = V4d(x, w, w, y)
    member __.XWWZ = V4d(x, w, w, z)
    member __.XWWW = V4d(x, w, w, w)
    member __.YXXX = V4d(y, x, x, x)
    member __.YXXY = V4d(y, x, x, y)
    member __.YXXZ = V4d(y, x, x, z)
    member __.YXXW = V4d(y, x, x, w)
    member __.YXYX = V4d(y, x, y, x)
    member __.YXYY = V4d(y, x, y, y)
    member __.YXYZ = V4d(y, x, y, z)
    member __.YXYW = V4d(y, x, y, w)
    member __.YXZX = V4d(y, x, z, x)
    member __.YXZY = V4d(y, x, z, y)
    member __.YXZZ = V4d(y, x, z, z)
    member __.YXZW = V4d(y, x, z, w)
    member __.YXWX = V4d(y, x, w, x)
    member __.YXWY = V4d(y, x, w, y)
    member __.YXWZ = V4d(y, x, w, z)
    member __.YXWW = V4d(y, x, w, w)
    member __.YYXX = V4d(y, y, x, x)
    member __.YYXY = V4d(y, y, x, y)
    member __.YYXZ = V4d(y, y, x, z)
    member __.YYXW = V4d(y, y, x, w)
    member __.YYYX = V4d(y, y, y, x)
    member __.YYYY = V4d(y, y, y, y)
    member __.YYYZ = V4d(y, y, y, z)
    member __.YYYW = V4d(y, y, y, w)
    member __.YYZX = V4d(y, y, z, x)
    member __.YYZY = V4d(y, y, z, y)
    member __.YYZZ = V4d(y, y, z, z)
    member __.YYZW = V4d(y, y, z, w)
    member __.YYWX = V4d(y, y, w, x)
    member __.YYWY = V4d(y, y, w, y)
    member __.YYWZ = V4d(y, y, w, z)
    member __.YYWW = V4d(y, y, w, w)
    member __.YZXX = V4d(y, z, x, x)
    member __.YZXY = V4d(y, z, x, y)
    member __.YZXZ = V4d(y, z, x, z)
    member __.YZXW = V4d(y, z, x, w)
    member __.YZYX = V4d(y, z, y, x)
    member __.YZYY = V4d(y, z, y, y)
    member __.YZYZ = V4d(y, z, y, z)
    member __.YZYW = V4d(y, z, y, w)
    member __.YZZX = V4d(y, z, z, x)
    member __.YZZY = V4d(y, z, z, y)
    member __.YZZZ = V4d(y, z, z, z)
    member __.YZZW = V4d(y, z, z, w)
    member __.YZWX = V4d(y, z, w, x)
    member __.YZWY = V4d(y, z, w, y)
    member __.YZWZ = V4d(y, z, w, z)
    member __.YZWW = V4d(y, z, w, w)
    member __.YWXX = V4d(y, w, x, x)
    member __.YWXY = V4d(y, w, x, y)
    member __.YWXZ = V4d(y, w, x, z)
    member __.YWXW = V4d(y, w, x, w)
    member __.YWYX = V4d(y, w, y, x)
    member __.YWYY = V4d(y, w, y, y)
    member __.YWYZ = V4d(y, w, y, z)
    member __.YWYW = V4d(y, w, y, w)
    member __.YWZX = V4d(y, w, z, x)
    member __.YWZY = V4d(y, w, z, y)
    member __.YWZZ = V4d(y, w, z, z)
    member __.YWZW = V4d(y, w, z, w)
    member __.YWWX = V4d(y, w, w, x)
    member __.YWWY = V4d(y, w, w, y)
    member __.YWWZ = V4d(y, w, w, z)
    member __.YWWW = V4d(y, w, w, w)
    member __.ZXXX = V4d(z, x, x, x)
    member __.ZXXY = V4d(z, x, x, y)
    member __.ZXXZ = V4d(z, x, x, z)
    member __.ZXXW = V4d(z, x, x, w)
    member __.ZXYX = V4d(z, x, y, x)
    member __.ZXYY = V4d(z, x, y, y)
    member __.ZXYZ = V4d(z, x, y, z)
    member __.ZXYW = V4d(z, x, y, w)
    member __.ZXZX = V4d(z, x, z, x)
    member __.ZXZY = V4d(z, x, z, y)
    member __.ZXZZ = V4d(z, x, z, z)
    member __.ZXZW = V4d(z, x, z, w)
    member __.ZXWX = V4d(z, x, w, x)
    member __.ZXWY = V4d(z, x, w, y)
    member __.ZXWZ = V4d(z, x, w, z)
    member __.ZXWW = V4d(z, x, w, w)
    member __.ZYXX = V4d(z, y, x, x)
    member __.ZYXY = V4d(z, y, x, y)
    member __.ZYXZ = V4d(z, y, x, z)
    member __.ZYXW = V4d(z, y, x, w)
    member __.ZYYX = V4d(z, y, y, x)
    member __.ZYYY = V4d(z, y, y, y)
    member __.ZYYZ = V4d(z, y, y, z)
    member __.ZYYW = V4d(z, y, y, w)
    member __.ZYZX = V4d(z, y, z, x)
    member __.ZYZY = V4d(z, y, z, y)
    member __.ZYZZ = V4d(z, y, z, z)
    member __.ZYZW = V4d(z, y, z, w)
    member __.ZYWX = V4d(z, y, w, x)
    member __.ZYWY = V4d(z, y, w, y)
    member __.ZYWZ = V4d(z, y, w, z)
    member __.ZYWW = V4d(z, y, w, w)
    member __.ZZXX = V4d(z, z, x, x)
    member __.ZZXY = V4d(z, z, x, y)
    member __.ZZXZ = V4d(z, z, x, z)
    member __.ZZXW = V4d(z, z, x, w)
    member __.ZZYX = V4d(z, z, y, x)
    member __.ZZYY = V4d(z, z, y, y)
    member __.ZZYZ = V4d(z, z, y, z)
    member __.ZZYW = V4d(z, z, y, w)
    member __.ZZZX = V4d(z, z, z, x)
    member __.ZZZY = V4d(z, z, z, y)
    member __.ZZZZ = V4d(z, z, z, z)
    member __.ZZZW = V4d(z, z, z, w)
    member __.ZZWX = V4d(z, z, w, x)
    member __.ZZWY = V4d(z, z, w, y)
    member __.ZZWZ = V4d(z, z, w, z)
    member __.ZZWW = V4d(z, z, w, w)
    member __.ZWXX = V4d(z, w, x, x)
    member __.ZWXY = V4d(z, w, x, y)
    member __.ZWXZ = V4d(z, w, x, z)
    member __.ZWXW = V4d(z, w, x, w)
    member __.ZWYX = V4d(z, w, y, x)
    member __.ZWYY = V4d(z, w, y, y)
    member __.ZWYZ = V4d(z, w, y, z)
    member __.ZWYW = V4d(z, w, y, w)
    member __.ZWZX = V4d(z, w, z, x)
    member __.ZWZY = V4d(z, w, z, y)
    member __.ZWZZ = V4d(z, w, z, z)
    member __.ZWZW = V4d(z, w, z, w)
    member __.ZWWX = V4d(z, w, w, x)
    member __.ZWWY = V4d(z, w, w, y)
    member __.ZWWZ = V4d(z, w, w, z)
    member __.ZWWW = V4d(z, w, w, w)
    member __.WXXX = V4d(w, x, x, x)
    member __.WXXY = V4d(w, x, x, y)
    member __.WXXZ = V4d(w, x, x, z)
    member __.WXXW = V4d(w, x, x, w)
    member __.WXYX = V4d(w, x, y, x)
    member __.WXYY = V4d(w, x, y, y)
    member __.WXYZ = V4d(w, x, y, z)
    member __.WXYW = V4d(w, x, y, w)
    member __.WXZX = V4d(w, x, z, x)
    member __.WXZY = V4d(w, x, z, y)
    member __.WXZZ = V4d(w, x, z, z)
    member __.WXZW = V4d(w, x, z, w)
    member __.WXWX = V4d(w, x, w, x)
    member __.WXWY = V4d(w, x, w, y)
    member __.WXWZ = V4d(w, x, w, z)
    member __.WXWW = V4d(w, x, w, w)
    member __.WYXX = V4d(w, y, x, x)
    member __.WYXY = V4d(w, y, x, y)
    member __.WYXZ = V4d(w, y, x, z)
    member __.WYXW = V4d(w, y, x, w)
    member __.WYYX = V4d(w, y, y, x)
    member __.WYYY = V4d(w, y, y, y)
    member __.WYYZ = V4d(w, y, y, z)
    member __.WYYW = V4d(w, y, y, w)
    member __.WYZX = V4d(w, y, z, x)
    member __.WYZY = V4d(w, y, z, y)
    member __.WYZZ = V4d(w, y, z, z)
    member __.WYZW = V4d(w, y, z, w)
    member __.WYWX = V4d(w, y, w, x)
    member __.WYWY = V4d(w, y, w, y)
    member __.WYWZ = V4d(w, y, w, z)
    member __.WYWW = V4d(w, y, w, w)
    member __.WZXX = V4d(w, z, x, x)
    member __.WZXY = V4d(w, z, x, y)
    member __.WZXZ = V4d(w, z, x, z)
    member __.WZXW = V4d(w, z, x, w)
    member __.WZYX = V4d(w, z, y, x)
    member __.WZYY = V4d(w, z, y, y)
    member __.WZYZ = V4d(w, z, y, z)
    member __.WZYW = V4d(w, z, y, w)
    member __.WZZX = V4d(w, z, z, x)
    member __.WZZY = V4d(w, z, z, y)
    member __.WZZZ = V4d(w, z, z, z)
    member __.WZZW = V4d(w, z, z, w)
    member __.WZWX = V4d(w, z, w, x)
    member __.WZWY = V4d(w, z, w, y)
    member __.WZWZ = V4d(w, z, w, z)
    member __.WZWW = V4d(w, z, w, w)
    member __.WWXX = V4d(w, w, x, x)
    member __.WWXY = V4d(w, w, x, y)
    member __.WWXZ = V4d(w, w, x, z)
    member __.WWXW = V4d(w, w, x, w)
    member __.WWYX = V4d(w, w, y, x)
    member __.WWYY = V4d(w, w, y, y)
    member __.WWYZ = V4d(w, w, y, z)
    member __.WWYW = V4d(w, w, y, w)
    member __.WWZX = V4d(w, w, z, x)
    member __.WWZY = V4d(w, w, z, y)
    member __.WWZZ = V4d(w, w, z, z)
    member __.WWZW = V4d(w, w, z, w)
    member __.WWWX = V4d(w, w, w, x)
    member __.WWWY = V4d(w, w, w, y)
    member __.WWWZ = V4d(w, w, w, z)
    member __.WWWW = V4d(w, w, w, w)
    static member Zero = V4d(0.0, 0.0, 0.0, 0.0)
    static member One = V4d(1.0, 1.0, 1.0, 1.0)
    static member OOOO = V4d(0.0, 0.0, 0.0, 0.0)
    static member OOOI = V4d(0.0, 0.0, 0.0, 1.0)
    static member OOIO = V4d(0.0, 0.0, 1.0, 0.0)
    static member OOII = V4d(0.0, 0.0, 1.0, 1.0)
    static member OIOO = V4d(0.0, 1.0, 0.0, 0.0)
    static member OIOI = V4d(0.0, 1.0, 0.0, 1.0)
    static member OIIO = V4d(0.0, 1.0, 1.0, 0.0)
    static member OIII = V4d(0.0, 1.0, 1.0, 1.0)
    static member IOOO = V4d(1.0, 0.0, 0.0, 0.0)
    static member IOOI = V4d(1.0, 0.0, 0.0, 1.0)
    static member IOIO = V4d(1.0, 0.0, 1.0, 0.0)
    static member IOII = V4d(1.0, 0.0, 1.0, 1.0)
    static member IIOO = V4d(1.0, 1.0, 0.0, 0.0)
    static member IIOI = V4d(1.0, 1.0, 0.0, 1.0)
    static member IIIO = V4d(1.0, 1.0, 1.0, 0.0)
    static member IIII = V4d(1.0, 1.0, 1.0, 1.0)
    static member (~-) (v : V4d) = V4d(-v.X, -v.Y, -v.Z, -v.W)
    static member (+) (l : V4d, r : V4d) = V4d(l.X + r.X, l.Y + r.Y, l.Z + r.Z, l.W + r.W)
    static member (-) (l : V4d, r : V4d) = V4d(l.X - r.X, l.Y - r.Y, l.Z - r.Z, l.W - r.W)
    static member (*) (l : V4d, r : V4d) = V4d(l.X * r.X, l.Y * r.Y, l.Z * r.Z, l.W * r.W)
    static member (/) (l : V4d, r : V4d) = V4d(l.X / r.X, l.Y / r.Y, l.Z / r.Z, l.W / r.W)
    static member (*) (l : V4d, r : float) = V4d(l.X * r, l.Y * r, l.Z * r, l.W * r)
    static member (/) (l : V4d, r : float) = V4d(l.X / r, l.Y / r, l.Z / r, l.W / r)
    static member (*) (l : float, r : V4d) = V4d(l * r.X, l * r.Y, l * r.Z, l * r.W)
    static member (/) (l : float, r : V4d) = V4d(l / r.X, l / r.Y, l / r.Z, l / r.W)
    static member Dot(l : V4d, r : V4d) = l.X * r.X + l.Y * r.Y + l.Z * r.Z + l.W * r.W
    member __.Dot(r : V4d) = x * r.X + y * r.Y + z * r.Z + w * r.W
    interface NoSRTP.IHasDot<V4d, float> with member x.Dot(r) = x.Dot(r)
    member __.LengthSquared = x*x + y*y + z*z + w*w
    interface NoSRTP.IHasLengthSquared<float> with member x.LengthSquared = x.LengthSquared
    member __.Length = sqrt (x*x + y*y + z*z + w*w)
    interface NoSRTP.IHasLength<float> with member x.Length = x.Length
    member this.Normalized = let l = this.Length in V4d(x/l, y/l, z/l, w/l)
    interface NoSRTP.IHasNormalized<V4d> with member x.Normalized = x.Normalized
    member __.Abs = V4d(abs x, abs y, abs z, abs w)
    member __.IsNaN = Fun.IsNaN(x) || Fun.IsNaN(y) || Fun.IsNaN(z) || Fun.IsNaN(w)
    static member Min(l : V4d, r : V4d) = V4d(min l.X r.X, min l.Y r.Y, min l.Z r.Z, min l.W r.W)
    static member Max(l : V4d, r : V4d) = V4d(max l.X r.X, max l.Y r.Y, max l.Z r.Z, max l.W r.W)
    static member Distance(l : V4d, r : V4d) = (l - r).Length
    override __.GetHashCode() = HashCode.Combine(x.GetHashCode(), y.GetHashCode(), z.GetHashCode(), w.GetHashCode())
    override __.Equals(o) = match o with | :? V4d as o -> x = o.X && y = o.Y && z = o.Z && w = o.W | _ -> false
    override __.ToString() = sprintf "[%f, %f, %f, %f]" x y z w
    interface System.IComparable with
        member __.CompareTo(o) = 
            match o with 
            | :? V4d as o -> 
                let mutable a = 0
                if (a <- compare x o.X; a <> 0) then a
                elif (a <- compare y o.Y; a <> 0) then a
                elif (a <- compare z o.Z; a <> 0) then a
                else compare w o.W
            | _ -> failwith "uncomparable"
    member __.AnyGreater(o : V4d) = x > o.X || y > o.Y || z > o.Z || w > o.W
    static member AnyGreater(l : V4d, r : V4d) = l.AnyGreater(r)
    member __.AnyGreaterOrEqual(o : V4d) = x >= o.X || y >= o.Y || z >= o.Z || w >= o.W
    static member AnyGreaterOrEqual(l : V4d, r : V4d) = l.AnyGreaterOrEqual(r)
    member __.AnySmaller(o : V4d) = x < o.X || y < o.Y || z < o.Z || w < o.W
    static member AnySmaller(l : V4d, r : V4d) = l.AnySmaller(r)
    member __.AnySmallerOrEqual(o : V4d) = x <= o.X || y <= o.Y || z <= o.Z || w <= o.W
    static member AnySmallerOrEqual(l : V4d, r : V4d) = l.AnySmallerOrEqual(r)
    member __.AnyEqual(o : V4d) = x = o.X || y = o.Y || z = o.Z || w = o.W
    static member AnyEqual(l : V4d, r : V4d) = l.AnyEqual(r)
    member __.AnyDifferent(o : V4d) = x <> o.X || y <> o.Y || z <> o.Z || w <> o.W
    static member AnyDifferent(l : V4d, r : V4d) = l.AnyDifferent(r)
    member __.AllGreater(o : V4d) = x > o.X && y > o.Y && z > o.Z && w > o.W
    static member AllGreater(l : V4d, r : V4d) = l.AllGreater(r)
    member __.AllGreaterOrEqual(o : V4d) = x >= o.X && y >= o.Y && z >= o.Z && w >= o.W
    static member AllGreaterOrEqual(l : V4d, r : V4d) = l.AllGreaterOrEqual(r)
    member __.AllSmaller(o : V4d) = x < o.X && y < o.Y && z < o.Z && w < o.W
    static member AllSmaller(l : V4d, r : V4d) = l.AllSmaller(r)
    member __.AllSmallerOrEqual(o : V4d) = x <= o.X && y <= o.Y && z <= o.Z && w <= o.W
    static member AllSmallerOrEqual(l : V4d, r : V4d) = l.AllSmallerOrEqual(r)
    member __.AllEqual(o : V4d) = x = o.X && y = o.Y && z = o.Z && w = o.W
    static member AllEqual(l : V4d, r : V4d) = l.AllEqual(r)
    member __.AllDifferent(o : V4d) = x <> o.X && y <> o.Y && z <> o.Z && w <> o.W
    static member AllDifferent(l : V4d, r : V4d) = l.AllDifferent(r)
    new(v : V3d, l : float) = V4d(v.X, v.Y, v.Z, l)
    new(v : V4i) = V4d(float v.X, float v.Y, float v.Z, float v.W)
