namespace OpenTK.Tests open Xunit open FsCheck open FsCheck.Xunit open System open System.Runtime.InteropServices open OpenTK module Vector4 = [ |])>] module Constructors = // [] let ``Triple value constructor sets all components to the correct values`` (x, y, z, w) = let v = Vector4(x, y, z, w) Assert.Equal(x, v.X) Assert.Equal(y, v.Y) Assert.Equal(z, v.Z) Assert.Equal(w, v.W) [] let ``Single value constructor sets all components to the correct values`` (a : float32) = let v = Vector4(a) Assert.Equal(a, v.X) Assert.Equal(a, v.Y) Assert.Equal(a, v.Z) Assert.Equal(a, v.W) [] let ``Vector2 value constructor sets all components to the correct values`` (x, y) = let v1 = Vector2(x, y) let v2 = Vector4(v1) Assert.Equal(v1.X, v2.X) Assert.Equal(v1.Y, v2.Y) Assert.Equal(x, v2.X) Assert.Equal(y, v2.Y) Assert.Equal(0.0f, v2.Z) Assert.Equal(0.0f, v2.W) [] let ``Vector3 value constructor sets all components to the correct values`` (x, y, z) = let v1 = Vector3(x, y, z) let v2 = Vector4(v1) Assert.Equal(v1.X, v2.X) Assert.Equal(v1.Y, v2.Y) Assert.Equal(v1.Z, v2.Z) Assert.Equal(x, v2.X) Assert.Equal(y, v2.Y) Assert.Equal(z, v2.Z) Assert.Equal(0.0f, v2.W) [] let ``Vector3 value and scalar constructor sets all components to the correct values`` (x, y, z, w) = let v1 = Vector3(x, y, z) let v2 = Vector4(v1, w) Assert.Equal(v1.X, v2.X) Assert.Equal(v1.Y, v2.Y) Assert.Equal(v1.Z, v2.Z) Assert.Equal(x, v2.X) Assert.Equal(y, v2.Y) Assert.Equal(z, v2.Z) Assert.Equal(w, v2.W) [] let ``Vector4 value constructor sets all components to the correct values`` (x, y, z, w) = let v1 = Vector4(x, y, z, w) let v2 = Vector4(v1) Assert.Equal(v1.X, v2.X) Assert.Equal(v1.Y, v2.Y) Assert.Equal(v1.Z, v2.Z) Assert.Equal(v1.W, v2.W) Assert.Equal(x, v2.X) Assert.Equal(y, v2.Y) Assert.Equal(z, v2.Z) Assert.Equal(w, v2.W) [ |])>] module Indexing = // [] let ``Index operator accesses the correct components`` (x, y, z, w) = let v = Vector4(x, y, z, w) Assert.Equal(x, v.[0]) Assert.Equal(y, v.[1]) Assert.Equal(z, v.[2]) Assert.Equal(w, v.[3]) [] let ``Indexed set operator throws exception for negative indices`` (x, y, z, w) = let mutable v = Vector4(x, y, z, w) (fun() -> v.[-1] <- x) |> Assert.Throws |> ignore [] let ``Indexed get operator throws exception for negative indices`` (x, y, z, w) = let mutable v = Vector4(x, y, z, w) (fun() -> v.[-1] |> ignore) |> Assert.Throws |> ignore [] let ``Indexed set operator throws exception for large indices`` (x, y, z, w) = let mutable v = Vector4(x, y, z, w) (fun() -> v.[4] <- x) |> Assert.Throws |> ignore [] let ``Indexed get operator throws exception for large indices`` (x, y, z, w) = let mutable v = Vector4(x, y, z, w) (fun() -> v.[4] |> ignore) |> Assert.Throws |> ignore [ |])>] module Length = // [] let ``Length method follows the pythagorean theorem`` (x, y, z, w) = let v = Vector4(x, y, z, w) let l = System.Math.Sqrt((float)(x * x + y * y + z * z + w * w)) Assert.Equal((float32)l, v.Length) [] let ``Fast length method is the same as one divided by the fast inverse square`` (x, y, z, w) = let v = Vector4(x, y, z, w) let l = 1.0f / MathHelper.InverseSqrtFast(x * x + y * y + z * z + w * w) Assert.Equal(l, v.LengthFast) [] let ``Length squared method returns each component squared and summed`` (x, y, z, w) = let v = Vector4(x, y, z, w) let lsq = x * x + y * y + z * z + w * w Assert.Equal(lsq, v.LengthSquared) [ |])>] module Normalization = // [] let ``Normalization creates a new unit length vector with the correct components`` (x, y, z, w) = let v = Vector4(x, y, z, w) let l = v.Length let norm = v.Normalized() Assert.ApproximatelyEqual(v.X / l, norm.X) Assert.ApproximatelyEqual(v.Y / l, norm.Y) Assert.ApproximatelyEqual(v.Z / l, norm.Z) Assert.ApproximatelyEqual(v.W / l, norm.W) [] let ``Normalization of instance transforms the instance into a unit length vector with the correct components`` (x, y, z, w) = let v = Vector4(x, y, z, w) let l = v.Length let norm = Vector4(x, y, z, w) norm.Normalize() Assert.ApproximatelyEqual(v.X / l, norm.X) Assert.ApproximatelyEqual(v.Y / l, norm.Y) Assert.ApproximatelyEqual(v.Z / l, norm.Z) Assert.ApproximatelyEqual(v.W / l, norm.W) [] let ``Fast approximate normalization of instance transforms the instance into a unit length vector with the correct components`` (x, y, z, w) = let v = Vector4(x, y, z, w) let norm = Vector4(x, y, z, w) norm.NormalizeFast() let scale = MathHelper.InverseSqrtFast(x * x + y * y + z * z + w * w) Assert.ApproximatelyEqual(v.X * scale, norm.X) Assert.ApproximatelyEqual(v.Y * scale, norm.Y) Assert.ApproximatelyEqual(v.Z * scale, norm.Z) Assert.ApproximatelyEqual(v.W * scale, norm.W) [] let ``Normalization by reference is the same as division by magnitude`` (a : Vector4) = let norm = a / a.Length let vRes = Vector4.Normalize(ref a) Assert.ApproximatelyEqual(norm, vRes) [] let ``Normalization is the same as division by magnitude`` (a : Vector4) = let norm = a / a.Length Assert.ApproximatelyEqual(norm, Vector4.Normalize(a)); [] let ``Fast approximate normalization by reference is the same as multiplication by the fast inverse square`` (a : Vector4) = let scale = MathHelper.InverseSqrtFast(a.X * a.X + a.Y * a.Y + a.Z * a.Z + a.W * a.W) let norm = a * scale let vRes = Vector4.NormalizeFast(ref a) Assert.ApproximatelyEqual(norm, vRes) [] let ``Fast approximate normalization is the same as multiplication by the fast inverse square`` (a : Vector4) = let scale = MathHelper.InverseSqrtFast(a.X * a.X + a.Y * a.Y + a.Z * a.Z + a.W * a.W) let norm = a * scale Assert.ApproximatelyEqual(norm, Vector4.NormalizeFast(a)); [ |])>] module Addition = // [] let ``Vector4 addition is the same as component addition`` (a : Vector4, b : Vector4) = let c = a + b Assert.ApproximatelyEqual(a.X + b.X,c.X) Assert.ApproximatelyEqual(a.Y + b.Y,c.Y) Assert.ApproximatelyEqual(a.Z + b.Z,c.Z) Assert.ApproximatelyEqual(a.W + b.W,c.W) [] let ``Vector4 addition is commutative`` (a : Vector4, b : Vector4) = let c = a + b let c2 = b + a Assert.ApproximatelyEqual(c, c2) [] let ``Vector4 addition is associative`` (a : Vector4, b : Vector4, c : Vector4) = let r1 = (a + b) + c let r2 = a + (b + c) Assert.ApproximatelyEqual(r1, r2) [] let ``Static Vector4 addition method is the same as component addition`` (a : Vector4, b : Vector4) = let v1 = Vector4(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W) let sum = Vector4.Add(a, b) Assert.ApproximatelyEqual(v1, sum) [] let ``Static Vector4 addition method by reference is the same as component addition`` (a : Vector4, b : Vector4) = let v1 = Vector4(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W) let sum = Vector4.Add(ref a, ref b) Assert.ApproximatelyEqual(v1, sum) [ |])>] module Subtraction = // [] let ``Vector4 subtraction is the same as component subtraction`` (a : Vector4, b : Vector4) = let c = a - b Assert.Equal(a.X - b.X,c.X) Assert.Equal(a.Y - b.Y,c.Y) Assert.Equal(a.Z - b.Z,c.Z) Assert.Equal(a.W - b.W,c.W) [] let ``Static Vector4 subtraction method is the same as component addition`` (a : Vector4, b : Vector4) = let v1 = Vector4(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W) let sum = Vector4.Subtract(a, b) Assert.ApproximatelyEqual(v1, sum) [] let ``Static Vector4 subtraction method by reference is the same as component addition`` (a : Vector4, b : Vector4) = let v1 = Vector4(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W) let sum = Vector4.Subtract(ref a, ref b) Assert.ApproximatelyEqual(v1, sum) [ |])>] module Multiplication = // [] let ``Vector4 multiplication is the same as component multiplication`` (a : Vector4, b : Vector4) = let c = a * b Assert.Equal(a.X * b.X,c.X) Assert.Equal(a.Y * b.Y,c.Y) Assert.Equal(a.Z * b.Z,c.Z) Assert.Equal(a.W * b.W,c.W) [] let ``Vector4 multiplication is commutative`` (a : Vector4, b : Vector4) = let r1 = a * b let r2 = b * a Assert.Equal(r1, r2) [] let ``Left-handed Vector4-scalar multiplication is the same as component-scalar multiplication`` (a : Vector4, f : float32) = let r = a * f Assert.Equal(a.X * f,r.X) Assert.Equal(a.Y * f,r.Y) Assert.Equal(a.Z * f,r.Z) Assert.Equal(a.W * f,r.W) [] let ``Right-handed Vector4-scalar multiplication is the same as component-scalar multiplication`` (a : Vector4, f : float32) = let r = f * a Assert.Equal(a.X * f,r.X) Assert.Equal(a.Y * f,r.Y) Assert.Equal(a.Z * f,r.Z) Assert.Equal(a.W * f,r.W) [] let ``Static method Vector4-scalar multiplication is the same as component-scalar multiplication`` (a : Vector4, f : float32) = let r = Vector4.Multiply(a, f) Assert.Equal(a.X * f,r.X) Assert.Equal(a.Y * f,r.Y) Assert.Equal(a.Z * f,r.Z) Assert.Equal(a.W * f,r.W) [] let ``Vector4-Matrix4 multiplication using right-handed notation is the same as vector/row multiplication and summation`` (a : Matrix4, b : Vector4) = let res = a*b let c1 = b.X * a.M11 + b.Y * a.M12 + b.Z * a.M13 + b.W * a.M14 let c2 = b.X * a.M21 + b.Y * a.M22 + b.Z * a.M23 + b.W * a.M24 let c3 = b.X * a.M31 + b.Y * a.M32 + b.Z * a.M33 + b.W * a.M34 let c4 = b.X * a.M41 + b.Y * a.M42 + b.Z * a.M43 + b.W * a.M44 let exp = Vector4(c1, c2, c3, c4) Assert.Equal(exp, res) [] let ``Vector4-Matrix4 multiplication using left-handed notation is the same as vector/column multiplication and summation`` (a : Matrix4, b : Vector4) = let res = b*a let c1 = b.X * a.M11 + b.Y * a.M21 + b.Z * a.M31 + b.W * a.M41 let c2 = b.X * a.M12 + b.Y * a.M22 + b.Z * a.M32 + b.W * a.M42 let c3 = b.X * a.M13 + b.Y * a.M23 + b.Z * a.M33 + b.W * a.M43 let c4 = b.X * a.M14 + b.Y * a.M24 + b.Z * a.M34 + b.W * a.M44 let exp = Vector4(c1, c2, c3, c4) Assert.Equal(exp, res) [] let ``Static Vector4 multiplication method is the same as component multiplication`` (a : Vector4, b : Vector4) = let v1 = Vector4(a.X * b.X, a.Y * b.Y, a.Z * b.Z, a.W * b.W) let sum = Vector4.Multiply(a, b) Assert.ApproximatelyEqual(v1, sum) [] let ``Static Vector4 multiplication method by reference is the same as component multiplication`` (a : Vector4, b : Vector4) = let v1 = Vector4(a.X * b.X, a.Y * b.Y, a.Z * b.Z, a.W * b.W) let sum = Vector4.Multiply(ref a, ref b) Assert.ApproximatelyEqual(v1, sum) [ |])>] module Division = // [] let ``Vector4-float division is the same as component-float division`` (a : Vector4, f : float32) = if not (approxEq f 0.0f) then // we don't support diving by zero. let r = a / f Assert.ApproximatelyEqual(a.X / f, r.X) Assert.ApproximatelyEqual(a.Y / f, r.Y) Assert.ApproximatelyEqual(a.Z / f, r.Z) Assert.ApproximatelyEqual(a.W / f, r.W) [] let ``Static Vector4-Vector4 division method is the same as component division`` (a : Vector4, b : Vector4) = let v1 = Vector4(a.X / b.X, a.Y / b.Y, a.Z / b.Z, a.W / b.W) let sum = Vector4.Divide(a, b) Assert.ApproximatelyEqual(v1, sum) [] let ``Static Vector4-Vector4 divison method by reference is the same as component division`` (a : Vector4, b : Vector4) = let v1 = Vector4(a.X / b.X, a.Y / b.Y, a.Z / b.Z, a.W / b.W) let sum = Vector4.Divide(ref a, ref b) Assert.ApproximatelyEqual(v1, sum) [] let ``Static Vector4-scalar division method is the same as component division`` (a : Vector4, b : float32) = let v1 = Vector4(a.X / b, a.Y / b, a.Z / b, a.W / b) let sum = Vector4.Divide(a, b) Assert.ApproximatelyEqual(v1, sum) [] let ``Static Vector4-scalar divison method by reference is the same as component division`` (a : Vector4, b : float32) = let v1 = Vector4(a.X / b, a.Y / b, a.Z / b, a.W / b) let sum = Vector4.Divide(ref a, b) Assert.ApproximatelyEqual(v1, sum) [ |])>] module Negation = // [] let ``Vector negation operator negates all components`` (x, y, z, w) = let v = Vector4(x, y, z, w) let vNeg = -v Assert.Equal(-x, vNeg.X) Assert.Equal(-y, vNeg.Y) Assert.Equal(-z, vNeg.Z) Assert.Equal(-w, vNeg.W) [ |])>] module Equality = // [] let ``Vector equality operator is by component`` (x, y, z, w) = let v1 = Vector4(x, y, z, w) let v2 = Vector4(x, y, z, w) let equality = v1 = v2 Assert.True(equality) [] let ``Vector inequality operator is by component`` (x, y, z, w) = let v1 = Vector4(x, y, z, w) let v2 = Vector4(x + 1.0f , y + 1.0f, z + 1.0f, w + 1.0f) let inequality = v1 <> v2 Assert.True(inequality) [] let ``Vector equality method is by component`` (x, y, z, w) = let v1 = Vector4(x, y, z, w) let v2 = Vector4(x, y, z, w) let notVector = Matrix2() let equality = v1.Equals(v2) let inequalityByOtherType = v1.Equals(notVector) Assert.True(equality) Assert.False(inequalityByOtherType) [] let ``Vector equality method returns false for other classes`` (x, y, z, w) = let v1 = Vector4(x, y, z, w) let notVector = Matrix2() let inequalityByOtherType = v1.Equals(notVector) Assert.False(inequalityByOtherType) [ |])>] module Swizzling = // [] let ``Vector swizzling returns the correct composite for X-primary components`` (x, y, z, w) = let v = Vector4(x, y, z, w) let xyzw = v let xywz = Vector4(x, y, w, z) let xzyw = Vector4(x, z, y, w) let xzwy = Vector4(x, z, w, y) let xwyz = Vector4(x, w, y, z) let xwzy = Vector4(x, w, z, y) let xyz = Vector3(x, y, z) let xyw = Vector3(x, y, w) let xzy = Vector3(x, z, y) let xzw = Vector3(x, z, w) let xwy = Vector3(x, w, y) let xwz = Vector3(x, w, z) let xy = Vector2(x, y) let xz = Vector2(x, z) let xw = Vector2(x, w) // X primary Assert.Equal(xyzw, v) Assert.Equal(xywz, v.Xywz) Assert.Equal(xzyw, v.Xzyw) Assert.Equal(xzwy, v.Xzwy) Assert.Equal(xwyz, v.Xwyz) Assert.Equal(xwzy, v.Xwzy) Assert.Equal(xyz, v.Xyz) Assert.Equal(xyw, v.Xyw) Assert.Equal(xzy, v.Xzy) Assert.Equal(xzw, v.Xzw) Assert.Equal(xwy, v.Xwy) Assert.Equal(xwz, v.Xwz) Assert.Equal(xy, v.Xy) Assert.Equal(xz, v.Xz) Assert.Equal(xw, v.Xw) [] let ``Vector swizzling returns the correct composite for Y-primary components`` (x, y, z, w) = let v = Vector4(x, y, z, w) let yxzw = Vector4(y, x, z, w) let yxwz = Vector4(y, x, w, z) let yyzw = Vector4(y, y, z, w) let yywz = Vector4(y, y, w, z) let yzxw = Vector4(y, z, x, w) let yzwx = Vector4(y, z, w, x) let ywxz = Vector4(y, w, x, z) let ywzx = Vector4(y, w, z, x) let yxz = Vector3(y, x, z) let yxw = Vector3(y, x, w) let yzx = Vector3(y, z, x) let yzw = Vector3(y, z, w) let ywx = Vector3(y, w, x) let ywz = Vector3(y, w, z) let yx = Vector2(y, x) let yz = Vector2(y, z) let yw = Vector2(y, w) // Y primary Assert.Equal(yxzw, v.Yxzw) Assert.Equal(yxwz, v.Yxwz) Assert.Equal(yyzw, v.Yyzw) Assert.Equal(yywz, v.Yywz) Assert.Equal(yzxw, v.Yzxw) Assert.Equal(yzwx, v.Yzwx) Assert.Equal(ywxz, v.Ywxz) Assert.Equal(ywzx, v.Ywzx) Assert.Equal(yxz, v.Yxz) Assert.Equal(yxw, v.Yxw) Assert.Equal(yzx, v.Yzx) Assert.Equal(yzw, v.Yzw) Assert.Equal(ywx, v.Ywx) Assert.Equal(ywz, v.Ywz) Assert.Equal(yx, v.Yx) Assert.Equal(yz, v.Yz) Assert.Equal(yw, v.Yw) [] let ``Vector swizzling returns the correct composite for Z-primary components`` (x, y, z, w) = let v = Vector4(x, y, z, w) let zxyw = Vector4(z, x, y, w) let zxwy = Vector4(z, x, w, y) let zyxw = Vector4(z, y, x, w) let zywx = Vector4(z, y, w, x) let zwxy = Vector4(z, w, x, y) let zwyx = Vector4(z, w, y, x) let zwzy = Vector4(z, w, z, y) let zxy = Vector3(z, x, y) let zxw = Vector3(z, x, w) let zyx = Vector3(z, y, x) let zyw = Vector3(z, y, w) let zwx = Vector3(z, w, x) let zwy = Vector3(z, w, y) let zx = Vector2(z, x) let zy = Vector2(z, y) let zw = Vector2(z, w) // Z primary Assert.Equal(zxyw, v.Zxyw) Assert.Equal(zxwy, v.Zxwy) Assert.Equal(zyxw, v.Zyxw) Assert.Equal(zywx, v.Zywx) Assert.Equal(zwxy, v.Zwxy) Assert.Equal(zwyx, v.Zwyx) Assert.Equal(zwzy, v.Zwzy) Assert.Equal(zxy, v.Zxy) Assert.Equal(zxw, v.Zxw) Assert.Equal(zyx, v.Zyx) Assert.Equal(zyw, v.Zyw) Assert.Equal(zwx, v.Zwx) Assert.Equal(zwy, v.Zwy) Assert.Equal(zx, v.Zx) Assert.Equal(zy, v.Zy) Assert.Equal(zw, v.Zw) [] let ``Vector swizzling returns the correct composite for W-primary components`` (x, y, z, w) = let v = Vector4(x, y, z, w) let wxyz = Vector4(w, x, y, z) let wxzy = Vector4(w, x, z, y) let wyxz = Vector4(w, y, x, z) let wyzx = Vector4(w, y, z, x) let wzxy = Vector4(w, z, x, y) let wzyx = Vector4(w, z, y, x) let wzyw = Vector4(w, z, y, w) let wxy = Vector3(w, x, y) let wxz = Vector3(w, x, z) let wyx = Vector3(w, y, x) let wyz = Vector3(w, y, z) let wzx = Vector3(w, z, x) let wzy = Vector3(w, z, y) let wx = Vector2(w, x) let wy = Vector2(w, y) let wz = Vector2(w, z) // W primary Assert.Equal(wxyz, v.Wxyz) Assert.Equal(wxzy, v.Wxzy) Assert.Equal(wyxz, v.Wyxz) Assert.Equal(wyzx, v.Wyzx) Assert.Equal(wzxy, v.Wzxy) Assert.Equal(wzyx, v.Wzyx) Assert.Equal(wzyw, v.Wzyw) Assert.Equal(wxy, v.Wxy) Assert.Equal(wxz, v.Wxz) Assert.Equal(wyx, v.Wyx) Assert.Equal(wyz, v.Wyz) Assert.Equal(wzx, v.Wzx) Assert.Equal(wzy, v.Wzy) Assert.Equal(wx, v.Wx) Assert.Equal(wy, v.Wy) Assert.Equal(wz, v.Wz) [ |])>] module Interpolation = // [] let ``Linear interpolation is by component`` (a : Vector4, b : Vector4, q) = let blend = q let rX = blend * (b.X - a.X) + a.X let rY = blend * (b.Y - a.Y) + a.Y let rZ = blend * (b.Z - a.Z) + a.Z let rW = blend * (b.W - a.W) + a.W let vExp = Vector4(rX, rY, rZ, rW) Assert.Equal(vExp, Vector4.Lerp(a, b, q)) let vRes = Vector4.Lerp(ref a, ref b, q) Assert.Equal(vExp, vRes) [] let ``Barycentric interpolation follows the barycentric formula`` (a : Vector4, b : Vector4, c : Vector4, u, v) = let r = a + u * (b - a) + v * (c - a) Assert.Equal(r, Vector4.BaryCentric(a, b, c, u, v)) let vRes = Vector4.BaryCentric(ref a, ref b, ref c, u, v) Assert.Equal(r, vRes) [ |])>] module ``Vector products`` = // [] let ``Dot product method follows the dot product formula`` (a : Vector4, b : Vector4) = let dot = a.X * b.X + a.Y * b.Y + a.Z * b.Z + a.W * b.W Assert.Equal(dot, Vector4.Dot(a, b)); let vRes = Vector4.Dot(ref a, ref b) Assert.Equal(dot, vRes) [ |])>] module ``Component min and max`` = // [] let ``Min selects the vector with lesser magnitude given two vectors`` (x, y, z, w, a, b, c, d) = let v1 = Vector4(x, y, z, w) let v2 = Vector4(a, b, c, d) let l1 = v1.LengthSquared let l2 = v2.LengthSquared let vMin = Vector4.Min(v1, v2) if vMin = v1 then let v1ShorterThanv2 = l1 < l2 Assert.True(v1ShorterThanv2) else let v2ShorterThanv1 = l2 < l1 Assert.True(v2ShorterThanv1) [] let ``Max selects the vector with greater magnitude given two vectors`` (x, y, z, w, a, b, c, d) = let v1 = Vector4(x, y, z, w) let v2 = Vector4(a, b, c, d) let l1 = v1.LengthSquared let l2 = v2.LengthSquared let vMin = Vector4.Max(v1, v2) if vMin = v1 then let v1LongerThanOrEqualTov2 = l1 >= l2 Assert.True(v1LongerThanOrEqualTov2) else let v2LongerThanv1 = l2 > l1 Assert.True(v2LongerThanv1) [ |])>] module Clamping = // [] let ``Clamping one vector between two other vectors clamps all components between corresponding components`` (a : Vector4, b : Vector4, w : Vector4) = let res = Vector4.Clamp(w, a, b) let expX = if w.X < a.X then a.X else if w.X > b.X then b.X else w.X let expY = if w.Y < a.Y then a.Y else if w.Y > b.Y then b.Y else w.Y let expZ = if w.Z < a.Z then a.Z else if w.Z > b.Z then b.Z else w.Z let expW = if w.W < a.W then a.W else if w.W > b.W then b.W else w.W Assert.Equal(expX, res.X) Assert.Equal(expY, res.Y) Assert.Equal(expZ, res.Z) Assert.Equal(expW, res.W) [] let ``Clamping one vector between two other vectors by reference clamps all components`` (a : Vector4, b : Vector4, w : Vector4) = let res = Vector4.Clamp(ref w, ref a, ref b) let expX = if w.X < a.X then a.X else if w.X > b.X then b.X else w.X let expY = if w.Y < a.Y then a.Y else if w.Y > b.Y then b.Y else w.Y let expZ = if w.Z < a.Z then a.Z else if w.Z > b.Z then b.Z else w.Z let expW = if w.W < a.W then a.W else if w.W > b.W then b.W else w.W Assert.Equal(expX, res.X) Assert.Equal(expY, res.Y) Assert.Equal(expZ, res.Z) Assert.Equal(expW, res.W) [ |])>] module ``Unit vectors``= // [] let ``Unit X is correct`` = let unitX = Vector4(1.0f, 0.0f, 0.0f, 0.0f) Assert.Equal(Vector4.UnitX, unitX) [] let ``Unit Y is correct`` = let unitY = Vector4(0.0f, 1.0f, 0.0f, 0.0f) Assert.Equal(Vector4.UnitY, unitY) [] let ``Unit Z is correct`` = let unitZ = Vector4(0.0f, 0.0f, 1.0f, 0.0f) Assert.Equal(Vector4.UnitZ, unitZ) [] let ``Unit W is correct`` = let unitW = Vector4(0.0f, 0.0f, 0.0f, 1.0f) Assert.Equal(Vector4.UnitW, unitW) [] let ``Unit zero is correct`` = let unitZero = Vector4(0.0f, 0.0f, 0.0f, 0.0f) Assert.Equal(Vector4.Zero, unitZero) [] let ``Unit one is correct`` = let unitOne = Vector4(1.0f, 1.0f, 1.0f, 1.0f) Assert.Equal(Vector4.One, unitOne) [ |])>] module Serialization = // [] let ``The absolute size of a Vector4 is always the size of its components`` (v : Vector4) = let expectedSize = sizeof * 4 Assert.Equal(expectedSize, Vector4.SizeInBytes) Assert.Equal(expectedSize, Marshal.SizeOf(Vector4())) [ |])>] module Transformation = // [] let ``Transformation by quaternion is the same as multiplication by quaternion and its conjugate`` (v : Vector4, q : Quaternion) = let vectorQuat = Quaternion(v.X, v.Y, v.Z, v.W) let inverse = Quaternion.Invert(q) let transformedQuat = q * vectorQuat * inverse let transformedVector = Vector4(transformedQuat.X, transformedQuat.Y, transformedQuat.Z, transformedQuat.W) Assert.Equal(transformedVector, Vector4.Transform(v, q)) [] let ``Transformation by quaternion by reference is the same as multiplication by quaternion and its conjugate`` (v : Vector4, q : Quaternion) = let vectorQuat = Quaternion(v.X, v.Y, v.Z, v.W) let inverse = Quaternion.Invert(q) let transformedQuat = q * vectorQuat * inverse let transformedVector = Vector4(transformedQuat.X, transformedQuat.Y,transformedQuat.Z, transformedQuat.W) Assert.Equal(transformedVector, Vector4.Transform(ref v, ref q))