public PortalMapLineSegment(PointF a, PointF b) { LineSegment = new Line() { pt1 = a, pt2 = b }; Normal = GameForm.Normal(LineSegment); LinkedSector = null; }
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; }
// // 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); } } } }