public Triangle[] CreateScreenSpaceLines(Point3D begin, Point3D end, double thickness, Color color) { VerticesBehindCamera behind = VerticesBehindCamera.None; if (begin.Z >= 0) { behind |= VerticesBehindCamera.Vertex1; } if (end.Z >= 0) { behind |= VerticesBehindCamera.Vertex2; } switch (behind) { case VerticesBehindCamera.Vertex1: { // 'begin' is behind the camera. Replace it with a new point that isn't. Weights weights = Interpolator.GetWeightsToXYPlane(begin, end, -distanceAheadOfCamera); begin = Interpolator.WeightedSum(begin, end, weights); break; } case VerticesBehindCamera.Vertex2: { // 'end' is behind the camera. Replace it with a new point that isn't. Weights weights = Interpolator.GetWeightsToXYPlane(begin, end, -distanceAheadOfCamera); end = Interpolator.WeightedSum(begin, end, weights); break; } case VerticesBehindCamera.Vertex1And2: return(new Triangle[0]); default: break; } return(new Triangle[] { new ScreenSpaceLineTriangle(begin, end, thickness, color, projection), new ScreenSpaceLineTriangle(end, begin, thickness, color, projection) }); }
private void ReorderVertices(ref Vertex v1, ref Vertex v2, ref Vertex v3, VerticesBehindCamera behind) { Vertex temp = null; switch (behind) { case VerticesBehindCamera.None: case VerticesBehindCamera.AllVertices: case VerticesBehindCamera.Vertex1: case VerticesBehindCamera.Vertex1And2: // Do nothing break; case VerticesBehindCamera.Vertex2: case VerticesBehindCamera.Vertex2And3: // Rotate CCW temp = v1; v1 = v2; v2 = v3; v3 = temp; break; case VerticesBehindCamera.Vertex3: case VerticesBehindCamera.Vertex1And3: // Rotate CW temp = v1; v1 = v3; v3 = v2; v2 = temp; break; } }
public Triangle[] CreateTriangles(Vertex v1, Vertex v2, Vertex v3) { VerticesBehindCamera behind = VerticesBehindCamera.None; if (v1.PositionZ >= 0) { behind |= VerticesBehindCamera.Vertex1; } if (v2.PositionZ >= 0) { behind |= VerticesBehindCamera.Vertex2; } if (v3.PositionZ >= 0) { behind |= VerticesBehindCamera.Vertex3; } // Set v1 (and possibly v2) as the clipped vertex (vertices) // We do this to simplify the tessellation code (in the 'switch' block below) ReorderVertices(ref v1, ref v2, ref v3, behind); switch (behind) { case VerticesBehindCamera.Vertex1: case VerticesBehindCamera.Vertex2: case VerticesBehindCamera.Vertex3: { // The two triangles created are 2-3-4 and 2-4-5 // Vertices 4 and 5 are actually just in front of the camera plane (unlike the picture shows) // // 3---------2 ^ camera look direction // \ ." / | // \ ." / | // <-----4---5-------> camera plane (NOT the near clipping plane) // \ / // 1 behind the camera // Vertex v4 = GetVertexAheadOfCamera(v1, v3); Vertex v5 = GetVertexAheadOfCamera(v1, v2); return new Triangle[]{ new Triangle( v2, v3, v4, projection ), new Triangle( v2, v4, v5, projection ) }; } case VerticesBehindCamera.Vertex1And2: case VerticesBehindCamera.Vertex1And3: case VerticesBehindCamera.Vertex2And3: { // The triangle created is 3-4-5 // Vertices 4 and 5 are actually just in front of the camera plane (unlike the picture shows) // // 3 ^ camera look direction // / \ | // / \ | // <----4-----5------> camera plane (NOT the near clipping plane) // / \ // 1---------2 behind the camera Vertex v4 = GetVertexAheadOfCamera(v1, v3); Vertex v5 = GetVertexAheadOfCamera(v2, v3); return new Triangle[] { new Triangle(v3, v4, v5, projection) }; } case VerticesBehindCamera.AllVertices: return new Triangle[0]; case VerticesBehindCamera.None: default: return new Triangle[] { new Triangle(v1, v2, v3, projection) }; } }