Beispiel #1
0
        /// <summary>
        /// Creates a flat polygon.
        /// </summary>
        /// <param name="polygon2D">A 2D <see cref="GraphicsPath"/> representing the polygon.</param>
        /// <param name="triangulationResolution">The resolution that will be used to linearise curve segments in the <see cref="GraphicsPath"/>.</param>
        /// <param name="origin">A <see cref="Point3D"/> that will correspond to the origin of the 2D reference system.</param>
        /// <param name="xAxis">A <see cref="NormalizedVector3D"/> that will correspond to the x axis of the 2D reference system. This will be orthonormalised to the <paramref name="yAxis"/>.</param>
        /// <param name="yAxis">A <see cref="NormalizedVector3D"/> that will correspond to the y axis of the 2D reference system.</param>
        /// <param name="reverseTriangles">Indicates whether the order of the points (and thus the normals) of all the triangles returned by this method should be reversed.</param>
        /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <returns>A list of <see cref="Triangle3DElement"/>s that constitute the polygon.</returns>
        public static List <Element3D> CreatePolygon(GraphicsPath polygon2D, double triangulationResolution, Point3D origin, NormalizedVector3D xAxis, NormalizedVector3D yAxis, bool reverseTriangles, IEnumerable <IMaterial> fill, string tag = null, int zIndex = 0)
        {
            xAxis = (xAxis - yAxis * (xAxis * yAxis)).Normalize();

            List <GraphicsPath> triangles = polygon2D.Triangulate(triangulationResolution, true).ToList();

            List <Element3D> tbr = new List <Element3D>(triangles.Count);

            for (int i = 0; i < triangles.Count; i++)
            {
                Point p1 = triangles[i].Segments[0].Point;
                Point p2 = triangles[i].Segments[1].Point;
                Point p3 = triangles[i].Segments[2].Point;

                Point3D p13D = origin + xAxis * p1.X + yAxis * p1.Y;
                Point3D p23D = origin + xAxis * p2.X + yAxis * p2.Y;
                Point3D p33D = origin + xAxis * p3.X + yAxis * p3.Y;

                Triangle3DElement t = !reverseTriangles ? new Triangle3DElement(p13D, p23D, p33D) : new Triangle3DElement(p13D, p33D, p23D);
                t.Fill.AddRange(fill);
                t.Tag    = tag;
                t.ZIndex = zIndex;
                tbr.Add(t);
            }

            return(tbr);
        }
Beispiel #2
0
        private static (byte R, byte G, byte B, byte A) GetPixelColor(Triangle3DElement triangle, Point3D correspPoint, Camera camera, List <ILightSource> lights, List <double> obstructions)
        {
            NormalizedVector3D normal = triangle.GetNormalAt(correspPoint);

            byte R = 0;
            byte G = 0;
            byte B = 0;
            byte A = 0;

            for (int i = 0; i < triangle.Fill.Count; i++)
            {
                Colour col = triangle.Fill[i].GetColour(correspPoint, normal, camera, lights, obstructions);

                if (col.A == 1)
                {
                    R = (byte)(col.R * 255);
                    G = (byte)(col.G * 255);
                    B = (byte)(col.B * 255);
                    A = (byte)(col.A * 255);
                }
                else
                {
                    BlendFront(ref R, ref G, ref B, ref A, (byte)(col.R * 255), (byte)(col.G * 255), (byte)(col.B * 255), (byte)(col.A * 255));
                }
            }

            return(R, G, B, A);
        }
Beispiel #3
0
 /// <summary>
 /// Creates a new <see cref="VectorRendererTriangle3DElement"/> based on the specified base <paramref name="triangle"/>.
 /// </summary>
 /// <param name="triangle">The base <see cref="Triangle3DElement"/> from which all property values will be copied.</param>
 public VectorRendererTriangle3DElement(Triangle3DElement triangle) : this(triangle.Point1, triangle.Point2, triangle.Point3, triangle.Point1Normal, triangle.Point2Normal, triangle.Point3Normal)
 {
     this.CastsShadow    = triangle.CastsShadow;
     this.Fill           = triangle.Fill;
     this.ReceivesShadow = triangle.ReceivesShadow;
     this.Tag            = triangle.Tag;
     this.ZIndex         = triangle.ZIndex;
 }
Beispiel #4
0
        /// <inheritdoc/>
        public override Point3D Deproject(Point point, Triangle3DElement triangle)
        {
            Point3D rotatedPoint = new Point3D(point.X / ScaleFactor, point.Y / ScaleFactor, 0);

            Point3D projectedPoint   = RotationMatrix.Inverse() * (CameraRotationMatrix.Inverse() * rotatedPoint);
            Point3D cameraPlanePoint = projectedPoint + (Vector3D)this.Position;

            Point3D centroid = (Point3D)(((Vector3D)triangle[0] + (Vector3D)triangle[1] + (Vector3D)triangle[2]) * (1.0 / 3.0));

            Vector3D l = Direction;

            double d = ((centroid - cameraPlanePoint) * triangle.ActualNormal) / (l * triangle.ActualNormal);

            Point3D pt = cameraPlanePoint + l * d;

            return(pt);
        }
Beispiel #5
0
        /// <summary>
        /// Creates a quadrilater. All the vertices need not be coplanar.
        /// </summary>
        /// <param name="point1">The first vertex of the quadrilater.</param>
        /// <param name="point2">The second vertex of the quadrilater.</param>
        /// <param name="point3">The third vertex of the quadrilater.</param>
        /// <param name="point4">The fourth vertex of the quadrilater.</param>
        /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <returns>A list containing two <see cref="Triangle3DElement"/>s representing the quadrilater.</returns>
        public static List <Element3D> CreateRectangle(Point3D point1, Point3D point2, Point3D point3, Point3D point4, IEnumerable <IMaterial> fill, string tag = null, int zIndex = 0)
        {
            Triangle3DElement triangle1 = new Triangle3DElement(point1, point2, point3);

            triangle1.Fill.AddRange(fill);
            triangle1.Tag    = tag;
            triangle1.ZIndex = zIndex;

            Triangle3DElement triangle2 = new Triangle3DElement(point1, point3, point4);

            triangle2.Fill.AddRange(fill);
            triangle2.Tag    = tag;
            triangle2.ZIndex = zIndex;

            return(new List <Element3D> {
                triangle1, triangle2
            });
        }
Beispiel #6
0
        private static (byte R, byte G, byte B, byte A) GetPixelColorWithShadow(Triangle3DElement triangle, List <ILightSource> lights, IEnumerable <Triangle3DElement> shadowers, Point3D correspPoint, Camera camera)
        {
            List <double> pixelObstructions = new List <double>(lights.Count);

            for (int i = 0; i < lights.Count; i++)
            {
                if (!lights[i].CastsShadow)
                {
                    pixelObstructions.Add(0);
                }
                else
                {
                    pixelObstructions.Add(lights[i].GetObstruction(correspPoint, from el in shadowers where el != triangle select el));
                }
            }


            byte R = 0;
            byte G = 0;
            byte B = 0;
            byte A = 0;

            NormalizedVector3D normal = triangle.GetNormalAt(correspPoint);

            for (int i = 0; i < triangle.Fill.Count; i++)
            {
                Colour col = triangle.Fill[i].GetColour(correspPoint, normal, camera, lights, pixelObstructions);

                if (col.A == 1)
                {
                    R = (byte)(col.R * 255);
                    G = (byte)(col.G * 255);
                    B = (byte)(col.B * 255);
                    A = (byte)(col.A * 255);
                }
                else
                {
                    BlendFront(ref R, ref G, ref B, ref A, (byte)(col.R * 255), (byte)(col.G * 255), (byte)(col.B * 255), (byte)(col.A * 255));
                }
            }

            return(R, G, B, A);
        }
Beispiel #7
0
        /// <summary>
        /// Applies the transformation to a <see cref="Triangle3DElement"/>.
        /// </summary>
        /// <param name="triangle">The <see cref="Triangle3DElement"/> to which the transformation should be applied.</param>
        /// <returns>A <see cref="Triangle3DElement"/> corresponding to a triangle in which the transformation has been applied to the points from <paramref name="triangle" />. Properties are preserved between the two elements.</returns>
        public Triangle3DElement Apply(Triangle3DElement triangle)
        {
            Point3D p1 = this.Apply(triangle.Point1);
            Point3D p2 = this.Apply(triangle.Point2);
            Point3D p3 = this.Apply(triangle.Point3);

            if (!triangle.IsFlat)
            {
                Point3D p1Ref = triangle.Point1 + (Vector3D)triangle.Point1Normal;
                Point3D p2Ref = triangle.Point2 + (Vector3D)triangle.Point2Normal;
                Point3D p3Ref = triangle.Point3 + (Vector3D)triangle.Point3Normal;

                p1Ref = this.Apply(p1Ref);
                p2Ref = this.Apply(p2Ref);
                p3Ref = this.Apply(p3Ref);

                NormalizedVector3D n1 = (p1Ref - p1).Normalize();
                NormalizedVector3D n2 = (p2Ref - p2).Normalize();
                NormalizedVector3D n3 = (p3Ref - p3).Normalize();

                Triangle3DElement tbr = new Triangle3DElement(p1, p2, p3, n1, n2, n3)
                {
                    CastsShadow = triangle.CastsShadow, ReceivesShadow = triangle.ReceivesShadow, Tag = triangle.Tag, ZIndex = triangle.ZIndex
                };

                tbr.Fill.AddRange(triangle.Fill);

                return(tbr);
            }
            else
            {
                Triangle3DElement tbr = new Triangle3DElement(p1, p2, p3)
                {
                    CastsShadow = triangle.CastsShadow, ReceivesShadow = triangle.ReceivesShadow, Tag = triangle.Tag, ZIndex = triangle.ZIndex
                };

                tbr.Fill.AddRange(triangle.Fill);

                return(tbr);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Creates a tetrahedron inscribed in a sphere.
        /// </summary>
        /// <param name="center">The centre of the tetrahedron.</param>
        /// <param name="radius">The radius of the sphere in which the tetrahedron is inscribed.</param>
        /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <returns>A list of <see cref="Triangle3DElement"/>s that constitute the sphere.</returns>
        public static List <Element3D> CreateTetrahedron(Point3D center, double radius, IEnumerable <IMaterial> fill, string tag = null, int zIndex = 0)
        {
            Point3D tip   = new Point3D(center.X, center.Y - radius, center.Z);
            Point3D base1 = new Point3D(Math.Sqrt(8.0 / 9) * radius + center.X, center.Y + radius / 3, center.Z);
            Point3D base2 = new Point3D(-Math.Sqrt(2.0 / 9) * radius + center.X, center.Y + radius / 3, center.Z + Math.Sqrt(2.0 / 3) * radius);
            Point3D base3 = new Point3D(-Math.Sqrt(2.0 / 9) * radius + center.X, center.Y + radius / 3, center.Z - Math.Sqrt(2.0 / 3) * radius);

            Triangle3DElement faceTriangle1 = new Triangle3DElement(tip, base2, base1)
            {
                Tag = tag, ZIndex = zIndex
            };

            faceTriangle1.Fill.AddRange(fill);

            Triangle3DElement faceTriangle2 = new Triangle3DElement(tip, base3, base2)
            {
                Tag = tag, ZIndex = zIndex
            };

            faceTriangle2.Fill.AddRange(fill);

            Triangle3DElement faceTriangle3 = new Triangle3DElement(tip, base1, base3)
            {
                Tag = tag, ZIndex = zIndex
            };

            faceTriangle3.Fill.AddRange(fill);

            Triangle3DElement baseTriangle = new Triangle3DElement(base1, base2, base3)
            {
                Tag = tag, ZIndex = zIndex
            };

            baseTriangle.Fill.AddRange(fill);

            return(new List <Element3D>()
            {
                faceTriangle1, faceTriangle2, faceTriangle3, baseTriangle
            });
        }
Beispiel #9
0
        /// <summary>
        /// Creates a sphere.
        /// </summary>
        /// <param name="center">The centre of the sphere.</param>
        /// <param name="radius">The radius of the sphere.</param>
        /// <param name="steps">The number of meridians and parallels to use when generating the sphere.</param>
        /// <param name="fill">A collection of materials that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <param name="tag">A tag that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <param name="zIndex">A z-index that will be applied to the <see cref="Triangle3DElement"/>s returned by this method.</param>
        /// <returns>A list of <see cref="Triangle3DElement"/>s that constitute the sphere.</returns>
        public static List <Element3D> CreateSphere(Point3D center, double radius, int steps, IEnumerable <IMaterial> fill, string tag = null, int zIndex = 0)
        {
            List <Point3D> points = new List <Point3D>();

            for (int t = 0; t <= steps; t++)
            {
                for (int p = 0; p < steps * 2; p++)
                {
                    double theta = Math.PI / steps * t;
                    double phi   = Math.PI / steps * p;

                    double x = center.X + radius * Math.Sin(theta) * Math.Cos(phi);
                    double y = center.Y + radius * Math.Sin(theta) * Math.Sin(phi);
                    double z = center.Z + radius * Math.Cos(theta);

                    points.Add(new Point3D(x, y, z));

                    if (t == 0 || t == steps)
                    {
                        break;
                    }
                }
            }

            List <Element3D> tbr = new List <Element3D>(4 * steps + (points.Count - 2 - 2 * steps) * 2);

            for (int i = 0; i < points.Count - 1; i++)
            {
                if (i == 0)
                {
                    for (int j = 0; j < 2 * steps; j++)
                    {
                        Point3D p1 = points[i];
                        Point3D p3 = points[i + 1 + j];
                        Point3D p2 = points[i + 1 + (j + 1) % (2 * steps)];

                        Triangle3DElement tri = new Triangle3DElement(p1, p2, p3, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize());
                        tri.Fill.AddRange(fill);
                        tri.Tag    = tag;
                        tri.ZIndex = zIndex;
                        tbr.Add(tri);
                    }
                }
                else if (i >= points.Count - 1 - 2 * steps)
                {
                    Point3D p1 = points[i];
                    Point3D p3 = points[points.Count - 1];
                    Point3D p2 = points[points.Count - 1 - 2 * steps + (i - (points.Count - 1 - 2 * steps) + 1) % (2 * steps)];

                    Triangle3DElement tri = new Triangle3DElement(p1, p2, p3, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize());
                    tri.Fill.AddRange(fill);
                    tri.Tag    = tag;
                    tri.ZIndex = zIndex;
                    tbr.Add(tri);
                }
                else
                {
                    if ((i - 1) % (2 * steps) < 2 * steps - 1)
                    {
                        Point3D p4 = points[i + 2 * steps];
                        Point3D p3 = points[i + 2 * steps + 1];
                        Point3D p2 = points[i + 1];
                        Point3D p1 = points[i];

                        tbr.AddRange(CreateRectangle(p1, p2, p3, p4, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize(), (center - p4).Normalize(), fill, tag, zIndex));
                    }
                    else
                    {
                        Point3D p4 = points[i + 2 * steps];
                        Point3D p3 = points[(i / (2 * steps)) * 2 * steps + 1];
                        Point3D p2 = points[(i / (2 * steps) - 1) * 2 * steps + 1];
                        Point3D p1 = points[i];

                        tbr.AddRange(CreateRectangle(p1, p2, p3, p4, (center - p1).Normalize(), (center - p2).Normalize(), (center - p3).Normalize(), (center - p4).Normalize(), fill, tag, zIndex));
                    }
                }
            }

            return(tbr);
        }
Beispiel #10
0
        private unsafe void FillTriangleWithShadow(byte *imageData, Triangle3DElement triangle, Camera camera, List <ILightSource> lights, List <Triangle3DElement> shadowers)
        {
            Point[] triangle2D = triangle.GetProjection();

            int minX = int.MaxValue;
            int minY = int.MaxValue;

            int maxX = int.MinValue;
            int maxY = int.MinValue;

            for (int i = 0; i < triangle2D.Length; i++)
            {
                triangle2D[i] = new Point((triangle2D[i].X - camera.TopLeft.X) / camera.Size.Width * this.RenderWidth, (triangle2D[i].Y - camera.TopLeft.Y) / camera.Size.Height * this.RenderHeight);

                minX = Math.Min(minX, (int)triangle2D[i].X);
                minY = Math.Min(minY, (int)triangle2D[i].Y);

                maxX = Math.Max(maxX, (int)Math.Ceiling(triangle2D[i].X));
                maxY = Math.Max(maxY, (int)Math.Ceiling(triangle2D[i].Y));
            }

            minX = Math.Max(minX, 0);
            minY = Math.Max(minY, 0);

            maxX = Math.Min(maxX, this.RenderWidth - 1);
            maxY = Math.Min(maxY, this.RenderHeight - 1);

            List <Triangle3DElement> otherShadowers = new List <Triangle3DElement>(shadowers.Count);

            for (int i = 0; i < shadowers.Count; i++)
            {
                if (shadowers[i] != triangle)
                {
                    otherShadowers.Add(shadowers[i]);
                }
            }

            int totalPixels = (maxX - minX + 1) * (maxY - minY + 1);

            Parallel.For(0, totalPixels, index =>
            {
                int y = index / (maxX - minX + 1) + minY;
                int x = index % (maxX - minX + 1) + minX;

                if (Intersections2D.PointInTriangle(x, y, triangle2D[0], triangle2D[1], triangle2D[2]))
                {
                    Point3D correspPoint = camera.Deproject(new Point((double)x / this.RenderWidth * camera.Size.Width + camera.TopLeft.X, (double)y / this.RenderHeight * camera.Size.Height + camera.TopLeft.Y), triangle);

                    double zDepth = camera.ZDepth(correspPoint);

                    int prevZIndexBuffer = ZIndexBuffer[y * RenderWidth + x];

                    if (prevZIndexBuffer < triangle.ZIndex || (prevZIndexBuffer == triangle.ZIndex && ZBuffer[y * RenderWidth + x] > zDepth))
                    {
                        (byte R, byte G, byte B, byte A) = GetPixelColorWithShadow(triangle, lights, otherShadowers, x, y, correspPoint, camera);

                        if (A == 255)
                        {
                            imageData[y * RenderWidth * 4 + x * 4]     = R;
                            imageData[y * RenderWidth * 4 + x * 4 + 1] = G;
                            imageData[y * RenderWidth * 4 + x * 4 + 2] = B;
                            imageData[y * RenderWidth * 4 + x * 4 + 3] = A;
                        }
                        else
                        {
                            BlendFront(ref imageData[y * RenderWidth * 4 + x * 4], ref imageData[y * RenderWidth * 4 + x * 4 + 1], ref imageData[y * RenderWidth * 4 + x * 4 + 2], ref imageData[y * RenderWidth * 4 + x * 4 + 3], R, G, B, A);
                        }

                        ZBuffer[y * RenderWidth + x]      = zDepth;
                        ZIndexBuffer[y * RenderWidth + x] = triangle.ZIndex;
                    }
                    else if (imageData[y * RenderWidth * 4 + x * 4 + 3] < 255)
                    {
                        (byte R, byte G, byte B, byte A) = GetPixelColorWithShadow(triangle, lights, otherShadowers, x, y, correspPoint, camera);

                        BlendBack(R, G, B, A, ref imageData[y * RenderWidth * 4 + x * 4], ref imageData[y * RenderWidth * 4 + x * 4 + 1], ref imageData[y * RenderWidth * 4 + x * 4 + 2], ref imageData[y * RenderWidth * 4 + x * 4 + 3]);
                    }
                }
            });
        }
Beispiel #11
0
        private unsafe void FillTriangle(byte *imageData, Triangle3DElement triangle, Camera camera, List <ILightSource> lights, List <double> obstructions)
        {
            Point[] triangle2D = triangle.GetProjection();

            int minX = int.MaxValue;
            int minY = int.MaxValue;

            int maxX = int.MinValue;
            int maxY = int.MinValue;

            for (int i = 0; i < triangle2D.Length; i++)
            {
                triangle2D[i] = new Point((triangle2D[i].X - camera.TopLeft.X) / camera.Size.Width * this.RenderWidth, (triangle2D[i].Y - camera.TopLeft.Y) / camera.Size.Height * this.RenderHeight);

                minX = Math.Min(minX, (int)triangle2D[i].X);
                minY = Math.Min(minY, (int)triangle2D[i].Y);

                maxX = Math.Max(maxX, (int)Math.Ceiling(triangle2D[i].X));
                maxY = Math.Max(maxY, (int)Math.Ceiling(triangle2D[i].Y));
            }

            minX = Math.Max(minX, 0);
            minY = Math.Max(minY, 0);

            maxX = Math.Min(maxX, this.RenderWidth - 1);
            maxY = Math.Min(maxY, this.RenderHeight - 1);

            int totalPixels = (maxX - minX + 1) * (maxY - minY + 1);

            Parallel.For(0, totalPixels, index =>
            {
                int y = index / (maxX - minX + 1) + minY;
                int x = index % (maxX - minX + 1) + minX;

                if (Intersections2D.PointInTriangle(x, y, triangle2D[0], triangle2D[1], triangle2D[2]))
                {
                    Point3D correspPoint = camera.Deproject(new Point((double)x / this.RenderWidth * camera.Size.Width + camera.TopLeft.X, (double)y / this.RenderHeight * camera.Size.Height + camera.TopLeft.Y), triangle);

                    double zDepth = camera.ZDepth(correspPoint);

                    int prevZIndexBuffer = ZIndexBuffer[y * RenderWidth + x];

                    if (prevZIndexBuffer < triangle.ZIndex || (prevZIndexBuffer == triangle.ZIndex && ZBuffer[y * RenderWidth + x] > zDepth))
                    {
                        byte R = 0;
                        byte G = 0;
                        byte B = 0;
                        byte A = 0;

                        for (int i = 0; i < triangle.Fill.Count; i++)
                        {
                            Colour col = triangle.Fill[i].GetColour(correspPoint, triangle.GetNormalAt(correspPoint), camera, lights, obstructions);

                            if (col.A == 1)
                            {
                                R = (byte)(col.R * 255);
                                G = (byte)(col.G * 255);
                                B = (byte)(col.B * 255);
                                A = (byte)(col.A * 255);
                            }
                            else
                            {
                                BlendFront(ref R, ref G, ref B, ref A, (byte)(col.R * 255), (byte)(col.G * 255), (byte)(col.B * 255), (byte)(col.A * 255));
                            }
                        }

                        if (A == 255)
                        {
                            imageData[y * RenderWidth * 4 + x * 4]     = R;
                            imageData[y * RenderWidth * 4 + x * 4 + 1] = G;
                            imageData[y * RenderWidth * 4 + x * 4 + 2] = B;
                            imageData[y * RenderWidth * 4 + x * 4 + 3] = A;
                        }
                        else
                        {
                            BlendFront(ref imageData[y * RenderWidth * 4 + x * 4], ref imageData[y * RenderWidth * 4 + x * 4 + 1], ref imageData[y * RenderWidth * 4 + x * 4 + 2], ref imageData[y * RenderWidth * 4 + x * 4 + 3], R, G, B, A);
                        }

                        ZBuffer[y * RenderWidth + x]      = zDepth;
                        ZIndexBuffer[y * RenderWidth + x] = triangle.ZIndex;
                    }
                    else if (imageData[y * RenderWidth * 4 + x * 4 + 3] < 255)
                    {
                        byte R = 0;
                        byte G = 0;
                        byte B = 0;
                        byte A = 0;

                        for (int i = 0; i < triangle.Fill.Count; i++)
                        {
                            Colour col = triangle.Fill[i].GetColour(correspPoint, triangle.GetNormalAt(correspPoint), camera, lights, obstructions);

                            if (col.A == 1)
                            {
                                R = (byte)(col.R * 255);
                                G = (byte)(col.G * 255);
                                B = (byte)(col.B * 255);
                                A = (byte)(col.A * 255);
                            }
                            else
                            {
                                BlendFront(ref R, ref G, ref B, ref A, (byte)(col.R * 255), (byte)(col.G * 255), (byte)(col.B * 255), (byte)(col.A * 255));
                            }
                        }

                        BlendBack(R, G, B, A, ref imageData[y * RenderWidth * 4 + x * 4], ref imageData[y * RenderWidth * 4 + x * 4 + 1], ref imageData[y * RenderWidth * 4 + x * 4 + 2], ref imageData[y * RenderWidth * 4 + x * 4 + 3]);
                    }
                }
            });
        }
Beispiel #12
0
 /// <summary>
 /// Projects a <see cref="Point"/> in 2D units to obtain the corresponding <see cref="Point3D"/> on the specified element.
 /// </summary>
 /// <param name="point">The <see cref="Point"/> to project.</param>
 /// <param name="element">The <see cref="Triangle3DElement"/> on which the point should be projected.</param>
 /// <returns>A <see cref="Point3D"/> corresponding to the point on <paramref name="element"/> that, when projected with the current camera, corresponds to <paramref name="point"/>.</returns>
 public abstract Point3D Deproject(Point point, Triangle3DElement element);