public Vec4(Vec3HighPrecision v, double w) { this.X = v.X; this.Y = v.Y; this.Z = v.Z; this.W = w; }
public static Mat4HighPrecision Axes(Vec3HighPrecision X, Vec3HighPrecision Y, Vec3HighPrecision Z) { return(new Mat4HighPrecision(X.X, X.Y, X.Z, 0.0, Y.X, Y.Y, Y.Z, 0.0, Z.X, Z.Y, Z.Z, 0.0, 0.0, 0.0, 0.0, 1.0)); }
public static Mat4HighPrecision Translate(Vec3HighPrecision T) { return(new Mat4HighPrecision(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, T.X, T.Y, T.Z, 1.0)); }
public static Vec3HighPrecision Cross(Vec3HighPrecision a, Vec3HighPrecision b) { return(new Vec3HighPrecision( a.Y * b.Z - a.Z * b.Y, -(a.X * b.Z - a.Z * b.X), a.X * b.Y - a.Y * b.X )); }
public static void AssertAreEqual(Vec3HighPrecision a, Vec3HighPrecision b, string msg = "", int ulpAccuracy = 2) { Assert.That(a.X, Is.EqualTo(b.X).Within(ulpAccuracy).Ulps, string.Format("{0} ({1} != {2})", msg, a, b) ); Assert.That(a.Y, Is.EqualTo(b.Y).Within(ulpAccuracy).Ulps, string.Format("{0} ({1} != {2})", msg, a, b) ); Assert.That(a.Z, Is.EqualTo(b.Z).Within(ulpAccuracy).Ulps, string.Format("{0} ({1} != {2})", msg, a, b) ); }
public static void AssertAreEqual(Vec3HighPrecision a, Vec3HighPrecision b, string msg, double accuracy) { Assert.That(a.X, Is.EqualTo(b.X).Within(accuracy), string.Format("{0} ({1} != {2})", msg, a, b) ); Assert.That(a.Y, Is.EqualTo(b.Y).Within(accuracy), string.Format("{0} ({1} != {2})", msg, a, b) ); Assert.That(a.Z, Is.EqualTo(b.Z).Within(accuracy), string.Format("{0} ({1} != {2})", msg, a, b) ); }
public static Mat4HighPrecision AngleAxisRot(Vec3HighPrecision axis, double cosAngle, double sinAngle) { var k = axis; var c = cosAngle; var s = Math.Sqrt(1.0 - c * c) * Math.Sign(sinAngle); var cc = 1.0 - c; double kX = k.X, kY = k.Y, kZ = k.Z; return(new Mat4HighPrecision( c + kX * kX * cc, -kZ * s + kX * kY * cc, kY * s + kX * kZ * cc, 0.0, kZ * s + kX * kY * cc, c + kY * kY * cc, -kX * s + kY * kZ * cc, 0.0, -kY * s + kX * kZ * cc, kX * s + kY * kZ * cc, c + kZ * kZ * cc, 0.0, 0.0, 0.0, 0.0, 1.0 ).Transposed()); }
static UnwrappedMesh MakeUnwrappedMesh(IReadOnlyList <Vec3> vertices, IReadOnlyList <Tri> triangles, Action <UnwrapIter> pushAction, Func <UnwrapIter> popAction) { var connections = GenerateEdgeConnections(triangles); int firstTri = 0; if (triangles.Count <= firstTri) { throw new Exception("firstTri out of bounds"); } // transform first triangle on XZ plane Mat4HighPrecision firstRot; { var tri = triangles[firstTri]; var p0 = vertices[tri.p0]; var p1 = vertices[tri.p1]; var p2 = vertices[tri.p2]; var e0 = p1 - p0; var e1 = p2 - p0; var n = Vec3.Cross(e0, e1); firstRot = Mat4HighPrecision.Axes(e0.Normalized, n.Normalized, Vec3.Cross(e0, n).Normalized).Transposed(); } var firstTf = firstRot; var firstEdge = new Edge(triangles[firstTri].p0, triangles[firstTri].p1); var iteratedTris = new HashSet <int>(); List <Vec3> unwrappedVertices = new List <Vec3>(); List <Vec3> originalVertices = new List <Vec3>(); List <Tri> unwrappedTriangles = new List <Tri>(); originalVertices.Add(vertices[firstEdge.p0]); originalVertices.Add(vertices[firstEdge.p1]); unwrappedVertices.Add((new Vec4(vertices[firstEdge.p0], 1.0) * firstRot).ToVec3()); unwrappedVertices.Add((new Vec4(vertices[firstEdge.p1], 1.0) * firstRot).ToVec3()); pushAction(new UnwrapIter(firstTri, firstTf, firstEdge, 1, 0)); int N = 0; while (unwrappedTriangles.Count < triangles.Count) { var i = popAction(); if (iteratedTris.Contains(i.TriIndex)) { continue; } if (i.TriIndex >= triangles.Count) { throw new Exception("TriIndex " + i.TriIndex + " out of bounds, triangle count: " + triangles.Count); } iteratedTris.Add(i.TriIndex); var t = triangles[i.TriIndex]; var a = vertices[t.p0]; var b = vertices[t.p1]; var c = vertices[t.p2]; var p0 = (new Vec4(a, 1.0) * i.Transform).ToVec3(); var p1 = (new Vec4(b, 1.0) * i.Transform).ToVec3(); var p2 = (new Vec4(c, 1.0) * i.Transform).ToVec3(); var e01 = i.EdgeToUnwrap.Equals(new Edge(t.p0, t.p1)); var e12 = i.EdgeToUnwrap.Equals(new Edge(t.p1, t.p2)); var e20 = i.EdgeToUnwrap.Equals(new Edge(t.p2, t.p0)); //AssertOnXZPlane(p0,p1,p2, string.Format("Failed after dequeue, N={0}", N)); Vec3HighPrecision e0, e1, mp; if (e01) { e0 = p1 - p0; e1 = p2 - p0; mp = (p1 + p0) * 0.5; } else if (e12) { e0 = p2 - p1; e1 = p0 - p1; mp = (p2 + p1) * 0.5; } else if (e20) { e0 = p0 - p2; e1 = p1 - p2; mp = (p0 + p2) * 0.5; } else { throw new Exception("Unreachable code executed."); } var n = Vec3.Cross(e0, e1).Normalized; var rotDir = Math.Sign(Vec3.Dot(Vec3.Cross(n, new Vec3(0, 1, 0)), e0)); // rotate next triangle to XZ plane rotating around the shared edge with the previous triangle (which is already on XZ plane) var rot = Mat4HighPrecision.Translate(mp * -1.0) * Mat4HighPrecision.AngleAxisRot(e0.Normalized, n.Y, Math.Sqrt(1 - n.Y * n.Y) * rotDir) * Mat4HighPrecision.Translate(mp * 1.0); var ntf = i.Transform * rot; var np0 = (new Vec4(a, 1.0) * ntf).ToVec3(); var np1 = (new Vec4(b, 1.0) * ntf).ToVec3(); var np2 = (new Vec4(c, 1.0) * ntf).ToVec3(); int v0, v1, v2; if (e01) { v0 = i.UnwrappedInd1; v1 = i.UnwrappedInd0; v2 = unwrappedVertices.Count; unwrappedVertices.Add(np2); originalVertices.Add(c); } else if (e12) { v0 = unwrappedVertices.Count; v1 = i.UnwrappedInd1; v2 = i.UnwrappedInd0; unwrappedVertices.Add(np0); originalVertices.Add(a); } else if (e20) { v0 = i.UnwrappedInd0; v1 = unwrappedVertices.Count; v2 = i.UnwrappedInd1; unwrappedVertices.Add(np1); originalVertices.Add(b); } else { throw new Exception("Unreachable code executed."); } unwrappedTriangles.Add(new Tri(v0, v1, v2)); EnqueueNeighborTriangles(i.TriIndex, t, ntf, v0, v1, v2, pushAction, connections); N++; } return(new UnwrappedMesh { Vertices = unwrappedVertices, Triangles = unwrappedTriangles, VerticesOriginalPositions = originalVertices }); }
public static double Dot(Vec3HighPrecision a, Vec3HighPrecision b) { return(a.X * b.X + a.Y * b.Y + a.Z * b.Z); }
public static Vec3HighPrecision Sub(Vec3HighPrecision a, Vec3HighPrecision b) { return(new Vec3HighPrecision(a.X - b.X, a.Y - b.Y, a.Z - b.Z)); }
public static Vec3HighPrecision Mul(Vec3HighPrecision a, double x) { return(new Vec3HighPrecision(a.X * x, a.Y * x, a.Z * x)); }
public static Vec3HighPrecision Add(Vec3HighPrecision a, Vec3HighPrecision b) { return(new Vec3HighPrecision(a.X + b.X, a.Y + b.Y, a.Z + b.Z)); }