コード例 #1
0
 public PortalMapLineSegment(PointF a, PointF b)
 {
     LineSegment = new Line()
     {
         pt1 = a, pt2 = b
     };
     Normal       = GameForm.Normal(LineSegment);
     LinkedSector = null;
 }
コード例 #2
0
 public PortalMapLineSegment(PointF a, PointF b, Color c, bool isPortal = false, PortalMapSector linkedSector = null)
 {
     LineSegment = new Line()
     {
         pt1 = a, pt2 = b
     };
     Normal       = GameForm.Normal(LineSegment);
     LineColor    = c;
     IsPortal     = isPortal;
     LinkedSector = linkedSector;
 }
コード例 #3
0
        //
        // Recursive Portal Render stuff
        //
        public void RenderPortalSector(Graphics g, PointF viewLocation, float viewAngle, Line FOV_AB, Line FOV_CD, PointF n1, PointF n2, PointF n3, PointF n4, PointF screenOffset, PortalMapSector sector, PortalMapSector lastSector = null, bool topDown = false)
        {
            float px = viewLocation.X;
            float py = viewLocation.Y;

            foreach (PortalMapLineSegment edge in sector.LineSegments)
            {
                float vx1 = edge.LineSegment.pt1.X;
                float vy1 = edge.LineSegment.pt1.Y;
                float vx2 = edge.LineSegment.pt2.X;
                float vy2 = edge.LineSegment.pt2.Y;

                float tx1 = vx1 - px; float ty1 = vy1 - py;
                float tx2 = vx2 - px; float ty2 = vy2 - py;
                float angle = viewAngle;

                // Rotate them around the player's view
                float tz1 = (float)(tx1 * Math.Cos(angle) + ty1 * Math.Sin(angle));
                float tz2 = (float)(tx2 * Math.Cos(angle) + ty2 * Math.Sin(angle));
                tx1 = (float)(tx1 * Math.Sin(angle) - ty1 * Math.Cos(angle));
                tx2 = (float)(tx2 * Math.Sin(angle) - ty2 * Math.Cos(angle));

                Line AB = new Line();
                AB.pt1.X = tx1; AB.pt1.Y = tz1;
                AB.pt2.X = tx2; AB.pt2.Y = tz2;

                Line[]   hull = { FOV_AB, new Line()
                                  {
                                      pt1 = FOV_AB.pt1, pt2 = FOV_CD.pt1
                                  },
                                  FOV_CD,   new Line()
                                  {
                                      pt1 = FOV_AB.pt2, pt2 = FOV_CD.pt2
                                  } };
                PointF[] normals = { n1, n3, n2, n4 };

                Line?t = LineIntersection2D(AB, hull, normals, 4);

                if (t != null)
                {
                    if (edge.IsPortal && edge.LinkedSector != lastSector) // Need to do view frustm culling first ....
                    {
                        // Should be adjusting frustum to portal, this could still lead to draw artifacts ... overlaps and such ...
                        RenderPortalSector(g, viewLocation, viewAngle, FOV_AB, FOV_CD, n1, n2, n3, n4, screenOffset, edge.LinkedSector, sector, topDown);
                    }

                    PointF i1 = t == null ? new Point() : (PointF)t?.pt1;
                    PointF i2 = t == null ? new Point() : (PointF)t?.pt2;

                    // Do 3D (2.5D) render now ...
                    if (!topDown)
                    {
                        tx1 = i1.X; tz1 = i1.Y; tx2 = i2.X; tz2 = i2.Y;

                        // Render ...
                        float height = 5.0f;

                        //float focalLength = Math.Abs(fovNearY2);// + Math.Abs(fovNearY2);
                        float x1 = tx1 * focalLength / tz1;
                        float y1a = -height * focalLength / tz1; float y1b = height * focalLength / tz1;
                        float x2 = tx2 * focalLength / tz2;
                        float y2a = -height * focalLength / tz2; float y2b = height * focalLength / tz2;

                        for (float x = x1; x <= x2; x++)
                        {
                            float ya = y1a + (x - x1) * (y2a - y1a) / (x2 - x1);
                            float yb = y1b + (x - x1) * (y2b - y1b) / (x2 - x1);

                            float zDepth = (tz1 + (x - x1) * (tz2 - tz1) / (x2 - x1));
                            Color c;
                            if (!float.IsNaN(zDepth)) // Ah ... basically an edge with a delta x of 0 !! !! Bug! Crashing on Paralell to viewport ??? Also slow in this case ...
                            {
                                c = Color.FromArgb(
                                    (1 - zDepth > 1) ? edge.LineColor.R : (int)((1 - (zDepth / 100)) * edge.LineColor.R),
                                    (1 - zDepth > 1) ? edge.LineColor.G : (int)((1 - (zDepth / 100)) * edge.LineColor.G),
                                    (1 - zDepth > 1) ? edge.LineColor.B : (int)((1 - (zDepth / 100)) * edge.LineColor.B));
                            }
                            else
                            {
                                c = Color.Purple;
                            }
                            Pen p = new Pen(c);
                            //Pen p = map[i].pen;

                            bool drawFloorCeiling = true;
                            bool drawPortals      = false;
                            if (edge.IsPortal && drawPortals)
                            {
                                Pen gp1 = new Pen(new LinearGradientBrush(new Point(0, 50), new Point(0, 0),
                                                                          Color.Black, Color.DarkGray));
                                Pen gp2 = new Pen(new LinearGradientBrush(new Point(0, 0), new Point(0, 50),
                                                                          Color.Black, Color.Blue));
                                if (drawFloorCeiling)
                                {
                                    g.DrawLine(gp1, 50 - x, 0, 50 - x, 50 + -ya);              // Ceiling
                                    g.DrawLine(gp2, 50 - x, 50 + yb, 50 - x, 140);             // Floor
                                }

                                g.DrawLine(Pens.Red, 50 - x, 50 + ya, 50 - x, 50 + yb);   // Wall
                            }
                            else if (!edge.IsPortal)
                            {
                                Pen gp1 = new Pen(new LinearGradientBrush(new Point(0, 50), new Point(0, 0),
                                                                          Color.Black, Color.DarkGray));
                                Pen gp2 = new Pen(new LinearGradientBrush(new Point(0, 0), new Point(0, 50),
                                                                          Color.Black, Color.Blue));
                                if (drawFloorCeiling)
                                {
                                    g.DrawLine(gp1, 50 - x, 0, 50 - x, 50 + -ya);              // Ceiling
                                    g.DrawLine(gp2, 50 - x, 50 + yb, 50 - x, 140);             // Floor
                                }

                                g.DrawLine(p, 50 - x, 50 + ya, 50 - x, 50 + yb);   // Wall

                                //Graphics.FromImage(ScreenBuffer).DrawImage(viewport[2], 215, 5);
                                //this.CreateGraphics().DrawImage(ScreenBuffer, 0, 0, ClientSize.Width, ClientSize.Height);
                            }
                        }

                        g.DrawLine(new Pen(edge.LineColor), screenOffset.X - x1, screenOffset.Y + y1a, screenOffset.X - x2, screenOffset.Y + y2a); // top (1-2 b)
                        g.DrawLine(new Pen(edge.LineColor), screenOffset.X - x1, screenOffset.Y + y1b, screenOffset.X - x2, screenOffset.Y + y2b); // bottom (1-2 b)
                        g.DrawLine(Pens.Red, screenOffset.X - x1, screenOffset.Y + y1a, screenOffset.X - x1, screenOffset.Y + y1b);                // left (1)
                        g.DrawLine(Pens.Red, screenOffset.X - x2, screenOffset.Y + y2a, screenOffset.X - x2, screenOffset.Y + y2b);                // right (2)
                    }

                    // Draw top down map ...
                    // Cool to draw this on top of 3d view !
                    if (topDown)
                    {
                        // Draw unclipped ...
                        g.DrawLine(Pens.Red, screenOffset.X - tx1, screenOffset.Y - tz1, screenOffset.X - tx2, screenOffset.Y - tz2);
                        // Draw clipped ...
                        PointF sA = VectorSubtract2D(screenOffset, i1);
                        PointF sB = VectorSubtract2D(screenOffset, i2);
                        g.DrawLine(new Pen(edge.LineColor), sA, sB);
                    }
                }
            }
        }