Beispiel #1
0
        /// <summary>
        /// Does a perspective-correct, 3-way interpolation of vertex data based on projected point.
        /// Only ProjectedPosition, WorldPosition and Color/ColorTolerance have meaning here.
        /// </summary>
        /// <param name="x">2D Screen-Space pixel X coordinate</param>
        /// <param name="y">2D Screen-Space pixel Y coordinate</param>
        /// <returns>Perspective-correct interpolated Vertex value for this point.</returns>
        override public Vertex GetVertex(double x, double y)
        {
            Vertex  interpolation   = new Vertex();
            Point3D currRasterPoint = new Point3D(x, y, 0);
            Weights screenWeights   = ComputeScreenWeights(currRasterPoint); // This gets us screen weights
            // Use screen weights to find current Z
            Point3D currProjectedPoint = new Point3D(x, y, WeightedSum(vertex1.ProjectedPosition.Z, vertex2.ProjectedPosition.Z, vertex3.ProjectedPosition.Z, screenWeights));

            interpolation.ProjectedPosition = currProjectedPoint;
            // Now that we have currProjectedPoint, we can go ahead and compute other weights
            Weights homogeneousWeights = ComputeHomogeneousWeights(currProjectedPoint);
            // Now we can use the perspectiveCorrectionFactor and the homogeneousWeights to
            // find the perspective-correct weights.
            Weights pcWeights = ComputePerspectiveCorrectWeights(homogeneousWeights);

            // Position ( Eye Space )
            interpolation.Position = Interpolator.WeightedSum(vertex1.Position, vertex2.Position, vertex3.Position, pcWeights);

            // Normal - ignored
            // Texture Coordinates - ignored

            // Color - force V1 since all magic lines are the same
            interpolation.Color = vertex1.Color;

            // Color Error - force black by default
            interpolation.ColorTolerance = Color.FromArgb(0x00, 0x00, 0x00, 0x00);
            if (pixelOnEdge)
            {
                // Since numerical precision makes these borderline cases inaccurate,
                // we set the tolerance of this pixel to ignore it.
                interpolation.ColorTolerance = Color.FromArgb(0x00, 0xFF, 0xFF, 0xFF);
            }
            return(interpolation);
        }
Beispiel #2
0
        private Edge GetClippingPlaneEdge(Point3D p1, Point3D p2, Point3D p3, double planeDepth)
        {
            double z1 = p1.Z - planeDepth;
            double z2 = p2.Z - planeDepth;
            double z3 = p3.Z - planeDepth;

            bool ss12 = MathEx.SameSign(z1, z2);
            bool ss23 = MathEx.SameSign(z2, z3);
            bool ss31 = MathEx.SameSign(z3, z1);

            // We can determine where the clipping plane intersects the Triangle by performing "same sign" tests
            //  on the z values of the projected vertices
            //
            //      1-------------3
            //       \  /     \  /      The internal lines represent edges created by the clipping plane
            //        \/b     a\/       . if 1 & 2 are on the same side of the plane and 3 is not
            //         \   c   /            - create and return segment a
            //          \-----/         . if 2 & 3 are on the same side of the plane and 1 is not
            //           \   /              - create and return segment b
            //            \ /           . if 3 & 1 are on the same side of the plane and 2 is not
            //             2                - create and return segment c
            //                          . otherwise, the clipping plane does not intersect this triangle
            //                              - return null

            if (ss12 && !ss23)
            {
                // Segment a
                Weights w1    = Interpolator.GetWeightsToXYPlane(p1, p3, planeDepth);
                Weights w2    = Interpolator.GetWeightsToXYPlane(p2, p3, planeDepth);
                Point3D start = Interpolator.WeightedSum(p1, p3, w1);
                Point3D end   = Interpolator.WeightedSum(p2, p3, w2);
                return(new Edge(start, end));
            }
            if (ss23 && !ss31)
            {
                // Segment b
                Weights w1    = Interpolator.GetWeightsToXYPlane(p1, p2, planeDepth);
                Weights w2    = Interpolator.GetWeightsToXYPlane(p1, p3, planeDepth);
                Point3D start = Interpolator.WeightedSum(p1, p2, w1);
                Point3D end   = Interpolator.WeightedSum(p1, p3, w2);
                return(new Edge(start, end));
            }
            if (ss31 && !ss12)
            {
                // Segment c
                Weights w1    = Interpolator.GetWeightsToXYPlane(p1, p2, planeDepth);
                Weights w2    = Interpolator.GetWeightsToXYPlane(p2, p3, planeDepth);
                Point3D start = Interpolator.WeightedSum(p1, p2, w1);
                Point3D end   = Interpolator.WeightedSum(p2, p3, w2);
                return(new Edge(start, end));
            }

            return(null);
        }
            private Vertex GetVertexAheadOfCamera(Vertex v1, Vertex v2)
            {
                // At this point, being ahead of camera is being in -z
                Weights weights = Interpolator.GetWeightsToXYPlane(v1.PositionAsPoint3D, v2.PositionAsPoint3D, -distanceAheadOfCamera);

                Vertex result = new Vertex();
                result.Color = Interpolator.WeightedSum(v1.Color, v2.Color, weights);
                result.ColorTolerance = Interpolator.WeightedSum(v1.ColorTolerance, v2.ColorTolerance, weights);
                result.ModelSpacePosition = Interpolator.WeightedSum(v1.ModelSpacePosition, v2.ModelSpacePosition, weights);
                result.Position = Interpolator.WeightedSum(v1.Position, v2.Position, weights);
                result.TextureCoordinates = Interpolator.WeightedSum(v1.TextureCoordinates, v2.TextureCoordinates, weights);

                result.ModelSpaceNormal = MathEx.Normalize(Interpolator.WeightedSum(v1.ModelSpaceNormal, v2.ModelSpaceNormal, weights));
                result.Normal = MathEx.Normalize(Interpolator.WeightedSum(v1.Normal, v2.Normal, weights));

                return result;
            }
Beispiel #4
0
            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) });
            }