Beispiel #1
0
            public Group BuildGroup(IReadOnlyList <Point> vertices, IReadOnlyList <Normal> normals)
            {
                var g = new Group();

                foreach (var f in _faces)
                {
                    for (var i = 1; i < f.Indices.Length - 1; i++)
                    {
                        var       p1 = vertices[f.Indices[0]];
                        var       p2 = vertices[f.Indices[i]];
                        var       p3 = vertices[f.Indices[i + 1]];
                        IGeometry t;
                        if (f.Normals[0].HasValue && f.Normals[i].HasValue && f.Normals[i + 1].HasValue)
                        {
                            var n1 = normals[f.Normals[0].Value];
                            var n2 = normals[f.Normals[i].Value];
                            // ReSharper disable once PossibleInvalidOperationException
                            var n3 = normals[f.Normals[i + 1].Value];
                            t = new SmoothTriangle(p1, p2, p3, n1, n2, n3);
                        }
                        else
                        {
                            t = new Triangle(p1, p2, p3);
                        }

                        g.AddChild(t);
                    }
                }

                return(g);
            }
Beispiel #2
0
        public void OBJ_FacesWithNormalVectors()
        {
            // Test Text:

            /*
             * v 0 1 0
             * v -1 0 0
             * v 1 0 0
             * vn -1 0 0
             * vn 1 0 0
             * vn 0 1 0
             * f 1//3 2//1 3//2
             * f 1/0/3 2/102/1 3/14/2
             */
            string[]       objInput = System.IO.File.ReadAllLines("C:\\Users\\prome\\source\\repos\\CS 4458\\RayTracer\\RayTracer\\objTests\\objTest7.txt");
            OBJ_File       parser   = OBJ_File.ParseOBJFile(objInput);
            Group          g        = parser.Groups[0];
            SmoothTriangle t1       = (SmoothTriangle)g.Shapes[0];
            SmoothTriangle t2       = (SmoothTriangle)g.Shapes[1];

            Assert.AreEqual(t1.P1, parser.Verticies[1]);
            Assert.AreEqual(t1.P2, parser.Verticies[2]);
            Assert.AreEqual(t1.P3, parser.Verticies[3]);
            Assert.AreEqual(t1.N1, parser.Normals[3]);
            Assert.AreEqual(t1.N2, parser.Normals[1]);
            Assert.AreEqual(t1.N3, parser.Normals[2]);
            Assert.AreEqual(t2, t1);
        }
Beispiel #3
0
        private static void TestCase08()
        {
            // Faces with normals
            var contents = "v 0 1 0" + NewLine +
                           "v -1 0 0" + NewLine +
                           "v 1 0 0" + NewLine +
                           NewLine +
                           "vn -1 0 0" + NewLine +
                           "vn 1 0 0" + NewLine +
                           "vn 0 1 0" + NewLine +
                           NewLine +
                           "f 1//3 2//1 3//2" + NewLine +
                           "f 1/0/3 2/102/1 3/14/2";
            var parser = new ObjParser();

            parser.ParseObjFile(contents.ToCharArray());

            Group g = parser.Groups["default"];

            Assert.Equal(2, g.Shapes.Count);

            SmoothTriangle t1 = g.Shapes[0] as SmoothTriangle;
            SmoothTriangle t2 = g.Shapes[1] as SmoothTriangle;

            Assert.NotNull(t1);
            Assert.NotNull(t2);
            Assert.Equal(parser.Vertices[0], t1.P1);
            Assert.Equal(parser.Vertices[1], t1.P2);
            Assert.Equal(parser.Vertices[2], t1.P3);
            Assert.Equal(parser.Normals[2], t1.N1);
            Assert.Equal(parser.Normals[0], t1.N2);
            Assert.Equal(parser.Normals[1], t1.N3);
            Assert.Equal(t1, t2);
        }
Beispiel #4
0
        private void ReadSmoothTriangle(string[] items, Group group)
        {
            var ns = items.Skip(1)
                     .Select(s => s.Split('/'))
                     .Select(s => new { VertexIndex = int.Parse(s[0]) - 1, NormalIndex = int.Parse(s[2]) - 1 })
                     .ToArray();

            var n1 = ns[0];

            for (int i = 0; i < ns.Length - 2; i++)
            {
                var      n2 = ns[i + 1];
                var      n3 = ns[i + 2];
                var      p1 = Vertices[n1.VertexIndex];
                var      p2 = Vertices[n2.VertexIndex];
                var      p3 = Vertices[n3.VertexIndex];
                Triangle triangle;
                if (Smooth)
                {
                    var norm1 = Normals[n1.NormalIndex];
                    var norm2 = Normals[n2.NormalIndex];
                    var norm3 = Normals[n3.NormalIndex];

                    triangle = new SmoothTriangle(p1, p2, p3, norm1, norm2, norm3);
                }
                else
                {
                    triangle = new Triangle(p1, p2, p3);
                }

                Triangles.Add(triangle);
                group.Add(triangle);
            }
        }
 public void Init()
 {
     _p1  = Tuple.Point(0, 1, 0);
     _p2  = Tuple.Point(-1, 0, 0);
     _p3  = Tuple.Point(1, 0, 0);
     _n1  = Tuple.Vector(0, 1, 0);
     _n2  = Tuple.Vector(-1, 0, 0);
     _n3  = Tuple.Vector(1, 0, 0);
     _tri = new SmoothTriangle(_p1, _p2, _p3, _n1, _n2, _n3);
 }
Beispiel #6
0
 public SmoothTriangleTests()
 {
     p1  = Helper.CreatePoint(0, 1, 0);
     p2  = Helper.CreatePoint(-1, 0, 0);
     p3  = Helper.CreatePoint(1, 0, 0);
     n1  = Helper.CreateVector(0, 1, 0);
     n2  = Helper.CreateVector(-1, 0, 0);
     n3  = Helper.CreateVector(1, 0, 0);
     tri = new SmoothTriangle(p1, p2, p3, n1, n2, n3);
 }
Beispiel #7
0
        public void Startup()
        {
            var p1 = new Point(0, 1, 0);
            var p2 = new Point(-1, 0, 0);
            var p3 = new Point(1, 0, 0);
            var n1 = new Vector(0, 1, 0);
            var n2 = new Vector(-1, 0, 0);
            var n3 = new Vector(1, 0, 0);

            tri = new SmoothTriangle(p1, p2, p3, n1, n2, n3);
        }
Beispiel #8
0
        public void setup()
        {
            p1 = new Point(0, 1, 0);
            p2 = new Point(-1, 0, 0);
            p3 = new Point(1, 0, 0);

            n1 = new Vector(0, 1, 0);
            n2 = new Vector(-1, 0, 0);
            n3 = new Vector(1, 0, 0);

            tri = new SmoothTriangle(p1, p2, p3, n1, n2, n3);
        }
Beispiel #9
0
        private static void TestCase01()
        {
            // Constructing a smooth triangle
            SmoothTriangle tri = ConstructSmoothTriangle();

            Assert.Equal(Tuple.Point(0, 1, 0), tri.P1);
            Assert.Equal(Tuple.Point(-1, 0, 0), tri.P2);
            Assert.Equal(Tuple.Point(1, 0, 0), tri.P3);
            Assert.Equal(Tuple.Vector(0, 1, 0), tri.N1);
            Assert.Equal(Tuple.Vector(-1, 0, 0), tri.N2);
            Assert.Equal(Tuple.Vector(1, 0, 0), tri.N3);
        }
Beispiel #10
0
        private static SmoothTriangle DefaultTriangle()
        {
            var p1  = new Point(0, 1, 0);
            var p2  = new Point(-1, 0, 0);
            var p3  = new Point(1, 0, 0);
            var n1  = new Normal(0, 1, 0);
            var n2  = new Normal(-1, 0, 0);
            var n3  = new Normal(1, 0, 0);
            var tri = new SmoothTriangle(p1, p2, p3, n1, n2, n3);

            return(tri);
        }
Beispiel #11
0
        public void TestSmoothTriangleBounds()
        {
            var p1    = new Point(-3, 7, 2);
            var p2    = new Point(6, 2, -4);
            var p3    = new Point(2, -1, -1);
            var n     = Vector.Zero;
            var shape = new SmoothTriangle(p1, p2, p3, n, n, n);
            var box   = shape.BoundsOf;

            Assert.AreEqual(box.Min, new Point(-3, -1, -4));
            Assert.AreEqual(box.Max, new Point(6, 7, 2));
        }
Beispiel #12
0
        public void SmoothTriangle_ShouldUseUvToInterpolateTheNormal()
        {
            var p1  = new Point(0, 1, 0);
            var p2  = new Point(-1, 0, 0);
            var p3  = new Point(1, 0, 0);
            var n1  = new Vector(0, 1, 0);
            var n2  = new Vector(-1, 0, 0);
            var n3  = new Vector(1, 0, 0);
            var tri = new SmoothTriangle(p1, p2, p3, n1, n2, n3);
            var i   = new Intersection(1, tri, 0.45, 0.25);
            var n   = tri.NormalAt(new Point(0, 0, 0), i);

            Assert.Equal(new Vector(-0.5547, 0.83205, 0), n, VectorComparer);
        }
Beispiel #13
0
        public void IntersectionWithSmoothTriangle_ShouldStoresUv()
        {
            var p1  = new Point(0, 1, 0);
            var p2  = new Point(-1, 0, 0);
            var p3  = new Point(1, 0, 0);
            var n1  = new Vector(0, 1, 0);
            var n2  = new Vector(-1, 0, 0);
            var n3  = new Vector(1, 0, 0);
            var tri = new SmoothTriangle(p1, p2, p3, n1, n2, n3);
            var r   = new Ray(new Point(-0.2, 0.3, -2), new Vector(0, 0, 1));
            var xs  = tri.LocalIntersect(r);

            Assert.Equal(0.45, xs[0].u, 2);
            Assert.Equal(0.25, xs[0].v, 2);
        }
Beispiel #14
0
        public void RequiresPointsAndNormals()
        {
            var p1  = new Point(0, 1, 0);
            var p2  = new Point(-1, 0, 0);
            var p3  = new Point(1, 0, 0);
            var n1  = new Normal(0, 1, 0);
            var n2  = new Normal(-1, 0, 0);
            var n3  = new Normal(1, 0, 0);
            var tri = new SmoothTriangle(p1, p2, p3, n1, n2, n3);

            tri.P1.Should().Be(p1);
            tri.P2.Should().Be(p2);
            tri.P3.Should().Be(p3);
            tri.N1.Should().Be(n1);
            tri.N2.Should().Be(n2);
            tri.N3.Should().Be(n3);
        }
Beispiel #15
0
        public void ConstructingSmoothTriangle()
        {
            var p1  = new Point(0, 1, 0);
            var p2  = new Point(-1, 0, 0);
            var p3  = new Point(1, 0, 0);
            var n1  = new Vector(0, 1, 0);
            var n2  = new Vector(-1, 0, 0);
            var n3  = new Vector(1, 0, 0);
            var tri = new SmoothTriangle(p1, p2, p3, n1, n2, n3);

            Assert.Equal(p1, tri.p1);
            Assert.Equal(p2, tri.p2);
            Assert.Equal(p3, tri.p3);
            Assert.Equal(n1, tri.n1);
            Assert.Equal(n2, tri.n2);
            Assert.Equal(n3, tri.n3);
        }
Beispiel #16
0
        public void PreparingTheNormalOnSmoothTriangle_ShouldWork()
        {
            var p1  = new Point(0, 1, 0);
            var p2  = new Point(-1, 0, 0);
            var p3  = new Point(1, 0, 0);
            var n1  = new Vector(0, 1, 0);
            var n2  = new Vector(-1, 0, 0);
            var n3  = new Vector(1, 0, 0);
            var tri = new SmoothTriangle(p1, p2, p3, n1, n2, n3);
            var i   = new Intersection(1, tri, 0.45, 0.25);
            var r   = new Ray(new Point(-0.2, 0.3, -2), new Vector(0, 0, 1));
            var xs  = new List <Intersection> {
                i
            };
            var comps = i.PrepareComputations(r, xs);

            Assert.Equal(new Vector(-0.5547, 0.83205, 0), comps.Normal, VectorComparer);
        }
Beispiel #17
0
    public OBJFileParser Create(int recursionLevel)
    {
        this.geometry = new OBJFileParser();
        this.middlePointIndexCache = new Dictionary <long, int>();
        this.index = 0;

        // create 12 vertices of a icosahedron
        var t = (1.0 + Math.Sqrt(5.0)) / 2.0;

        addVertex(new Point(-1, t, 0));
        addVertex(new Point(1, t, 0));
        addVertex(new Point(-1, -t, 0));
        addVertex(new Point(1, -t, 0));

        addVertex(new Point(0, -1, t));
        addVertex(new Point(0, 1, t));
        addVertex(new Point(0, -1, -t));
        addVertex(new Point(0, 1, -t));

        addVertex(new Point(t, 0, -1));
        addVertex(new Point(t, 0, 1));
        addVertex(new Point(-t, 0, -1));
        addVertex(new Point(-t, 0, 1));


        // create 20 triangles of the icosahedron
        var faces = new List <Tri>();

        // 5 faces around point 0
        faces.Add(new Tri(0, 11, 5));
        faces.Add(new Tri(0, 5, 1));
        faces.Add(new Tri(0, 1, 7));
        faces.Add(new Tri(0, 7, 10));
        faces.Add(new Tri(0, 10, 11));

        // 5 adjacent faces
        faces.Add(new Tri(1, 5, 9));
        faces.Add(new Tri(5, 11, 4));
        faces.Add(new Tri(11, 10, 2));
        faces.Add(new Tri(10, 7, 6));
        faces.Add(new Tri(7, 1, 8));

        // 5 faces around point 3
        faces.Add(new Tri(3, 9, 4));
        faces.Add(new Tri(3, 4, 2));
        faces.Add(new Tri(3, 2, 6));
        faces.Add(new Tri(3, 6, 8));
        faces.Add(new Tri(3, 8, 9));

        // 5 adjacent faces
        faces.Add(new Tri(4, 9, 5));
        faces.Add(new Tri(2, 4, 11));
        faces.Add(new Tri(6, 2, 10));
        faces.Add(new Tri(8, 6, 7));
        faces.Add(new Tri(9, 8, 1));


        // refine triangles
        for (int i = 0; i < recursionLevel; i++)
        {
            var faces2 = new List <Tri>();
            foreach (var tri in faces)
            {
                // replace triangle by 4 triangles
                int a = getMiddlePoint(tri.v1, tri.v2);
                int b = getMiddlePoint(tri.v2, tri.v3);
                int c = getMiddlePoint(tri.v3, tri.v1);

                faces2.Add(new Tri(tri.v1, a, c));
                faces2.Add(new Tri(tri.v2, b, a));
                faces2.Add(new Tri(tri.v3, c, b));
                faces2.Add(new Tri(a, b, c));
            }
            faces = faces2;
        }

        // done, now add triangles to mesh
        Point origin = new Point(0, 0, 0);

        foreach (var tri in faces)
        {
            // Create the point normals for the smoothing
            Vector n0 = (geometry.Verticies[tri.v1] - origin).Normalize();
            Vector n1 = (geometry.Verticies[tri.v2] - origin).Normalize();
            Vector n2 = (geometry.Verticies[tri.v3] - origin).Normalize();
            // texture map coordinates
            Point t0 = new Point((geometry.Verticies[tri.v1].X + 1) / 2, (geometry.Verticies[tri.v1].Y + 1) / 2, 0);
            Point t1 = new Point((geometry.Verticies[tri.v2].X + 1) / 2, (geometry.Verticies[tri.v2].Y + 1) / 2, 0);
            Point t2 = new Point((geometry.Verticies[tri.v3].X + 1) / 2, (geometry.Verticies[tri.v3].Y + 1) / 2, 0);

            // Create the texture maps for each vertex
            SmoothTriangle st = new SmoothTriangle(geometry.Verticies[tri.v1], geometry.Verticies[tri.v2], geometry.Verticies[tri.v3]);
            st.AddNormals(n0, n1, n2);
            st.AddTexture(t0, t1, t2);
            this.geometry.AddToCurrentGroup(st);
        }

        return(this.geometry);
    }
Beispiel #18
0
        public void TessellateSmoothSphere(int horizontalSteps, int verticalSteps)
        {
            double pi = 3.1415926535897932384;
            int    k  = 1;

            for (int j = 0; j <= horizontalSteps - 1; j++)
            {
                Vec3 v0 = new Vec3(0, 1, 0);

                Vec3 v1 = new Vec3(Math.Sin(2.0 * pi * j / horizontalSteps) * Math.Sin(pi * k / verticalSteps),
                                   Math.Cos(pi * k / verticalSteps),
                                   Math.Cos(2.0 * pi * j / horizontalSteps) * Math.Sin(pi * k / verticalSteps));

                Vec3 v2 = new Vec3(Math.Sin(2.0 * pi * (j + 1) / horizontalSteps) * Math.Sin(pi * k / verticalSteps),
                                   Math.Cos(pi * k / verticalSteps),
                                   Math.Cos(2.0 * pi * (j + 1) / horizontalSteps) * Math.Sin(pi * k / verticalSteps));

                SmoothTriangle triangle = new SmoothTriangle(v0, v1, v2);
                triangle.N0 = v0;
                triangle.N1 = v1;
                triangle.N2 = v2;
                AddObject(triangle);
            }

            k = verticalSteps - 1;

            for (int j = 0; j <= horizontalSteps - 1; j++)
            {
                Vec3 v0 = new Vec3(Math.Sin(2.0 * pi * j / horizontalSteps) * Math.Sin(pi * k / verticalSteps),
                                   Math.Cos(pi * k / verticalSteps),
                                   Math.Cos(2.0 * pi * j / horizontalSteps) * Math.Sin(pi * k / verticalSteps));

                Vec3 v1 = new Vec3(0, -1, 0);

                Vec3 v2 = new Vec3(Math.Sin(2.0 * pi * (j + 1) / horizontalSteps) * Math.Sin(pi * k / verticalSteps),
                                   Math.Cos(pi * k / verticalSteps),
                                   Math.Cos(2.0 * pi * (j + 1) / horizontalSteps) * Math.Sin(pi * k / verticalSteps));

                SmoothTriangle triangle = new SmoothTriangle(v0, v1, v2);
                triangle.N0 = v0;
                triangle.N1 = v1;
                triangle.N2 = v2;
                AddObject(triangle);
            }

            for (k = 1; k <= verticalSteps - 2; k++)
            {
                for (int j = 0; j <= horizontalSteps - 1; j++)
                {
                    Vec3 v0 = new Vec3(Math.Sin(2.0 * pi * j / horizontalSteps) * Math.Sin(pi * (k + 1) / verticalSteps),
                                       Math.Cos(pi * (k + 1) / verticalSteps),
                                       Math.Cos(2.0 * pi * j / horizontalSteps) * Math.Sin(pi * (k + 1) / verticalSteps));

                    Vec3 v1 = new Vec3(Math.Sin(2.0 * pi * (j + 1) / horizontalSteps) * Math.Sin(pi * (k + 1) / verticalSteps),
                                       Math.Cos(pi * (k + 1) / verticalSteps),
                                       Math.Cos(2.0 * pi * (j + 1) / horizontalSteps) * Math.Sin(pi * (k + 1) / verticalSteps));

                    Vec3 v2 = new Vec3(Math.Sin(2.0 * pi * j / horizontalSteps) * Math.Sin(pi * k / verticalSteps),
                                       Math.Cos(pi * k / verticalSteps),
                                       Math.Cos(2.0 * pi * j / horizontalSteps) * Math.Sin(pi * k / verticalSteps));

                    SmoothTriangle triangle = new SmoothTriangle(v0, v1, v2);
                    triangle.N0 = v0;
                    triangle.N1 = v1;
                    triangle.N2 = v2;
                    AddObject(triangle);

                    v0 = new Vec3(Math.Sin(2.0 * pi * (j + 1) / horizontalSteps) * Math.Sin(pi * k / verticalSteps),
                                  Math.Cos(pi * k / verticalSteps),
                                  Math.Cos(2.0 * pi * (j + 1) / horizontalSteps) * Math.Sin(pi * k / verticalSteps));

                    v1 = new Vec3(Math.Sin(2.0 * pi * j / horizontalSteps) * Math.Sin(pi * k / verticalSteps),
                                  Math.Cos(pi * k / verticalSteps),
                                  Math.Cos(2.0 * pi * j / horizontalSteps) * Math.Sin(pi * k / verticalSteps));

                    v2 = new Vec3(Math.Sin(2.0 * pi * (j + 1) / horizontalSteps) * Math.Sin(pi * (k + 1) / verticalSteps),
                                  Math.Cos(pi * (k + 1) / verticalSteps),
                                  Math.Cos(2.0 * pi * (j + 1) / horizontalSteps) * Math.Sin(pi * (k + 1) / verticalSteps));

                    triangle    = new SmoothTriangle(v0, v1, v2);
                    triangle.N0 = v0;
                    triangle.N1 = v1;
                    triangle.N2 = v2;
                    AddObject(triangle);
                }
            }
        }