Пример #1
0
 public Vec4(Vec3HighPrecision v, double w)
 {
     this.X = v.X;
     this.Y = v.Y;
     this.Z = v.Z;
     this.W = w;
 }
Пример #2
0
 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));
 }
Пример #3
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));
 }
Пример #4
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
                ));
 }
Пример #5
0
 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)
                 );
 }
Пример #6
0
 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)
                 );
 }
Пример #7
0
        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());
        }
Пример #8
0
        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
            });
        }
Пример #9
0
 public static double Dot(Vec3HighPrecision a, Vec3HighPrecision b)
 {
     return(a.X * b.X + a.Y * b.Y + a.Z * b.Z);
 }
Пример #10
0
 public static Vec3HighPrecision Sub(Vec3HighPrecision a, Vec3HighPrecision b)
 {
     return(new Vec3HighPrecision(a.X - b.X, a.Y - b.Y, a.Z - b.Z));
 }
Пример #11
0
 public static Vec3HighPrecision Mul(Vec3HighPrecision a, double x)
 {
     return(new Vec3HighPrecision(a.X * x, a.Y * x, a.Z * x));
 }
Пример #12
0
 public static Vec3HighPrecision Add(Vec3HighPrecision a, Vec3HighPrecision b)
 {
     return(new Vec3HighPrecision(a.X + b.X, a.Y + b.Y, a.Z + b.Z));
 }