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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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)); }
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); }
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); }
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); }
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); }
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); }
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); }
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); } } }