public static QPoint Intersect(QLine m, QLine n) { QPoint point, temp; point.x = Matrix.Det(m.a, m.b); point.y = Matrix.Det(n.a, n.b); float det = Matrix.Det(m.a - m.b, n.a - n.b); temp.x = Matrix.Det(new QPoint(point.x, (m.a - m.b).x), new QPoint(point.y, (n.a - n.b).x)) / det; temp.y = Matrix.Det(new QPoint(point.x, (m.a - m.b).y), new QPoint(point.y, (n.a - n.b).y)) / det; return(temp); }
public static QLine RotateLine(QLine line, float angle) { QLine res; float psin = Sin(angle); float pcos = Cos(angle); res.a.x = line.a.x * psin - line.a.y * pcos; res.b.x = line.b.x * psin - line.b.y * pcos; res.a.y = line.a.x * pcos + line.a.y * psin; res.b.y = line.b.x * pcos + line.b.y * psin; return(res); }
public static void ClipLine(ref QLine line) { QPoint vec = line.a - line.b; const float y0 = 1e-4f; if (line.a.y < 0) { line.a.y = y0; line.a.x = line.b.x + vec.x * (y0 - line.b.y) / vec.y; return; } if (line.b.y < 0) { line.b.y = y0; line.b.x = line.a.x + vec.x * (y0 - line.a.y) / vec.y; } }
private static void DrawSectors() { var renderedSectors = new RedBlackTree <int, object>() { }; var sectorQueue = new Queue(); int currentSector = player.sector; var secRender = new SectorRendering(currentSector, 0, window.Width - 1); int[] yTop = new int[window.Width]; int[] yBottom = Enumerable.Repeat(window.Height - 1, window.Width).ToArray(); GL.Begin(PrimitiveType.Lines); do { var sector = World.sectors[currentSector]; for (int i = 0; i < sector.numPoints; i++) { int vertexIndex = sector.vertices[i]; int vertexIndexNext = sector.vertices[i + 1]; QLine temp = new QLine(World.vertices[vertexIndex], World.vertices[vertexIndexNext]); temp.a -= player.pos; temp.b -= player.pos; QLine trans = RotateLine(temp, player.viewAngle); // x for x, y for z if (trans.a.y < 0 && trans.b.y < 0) { return; } ClipLine(ref trans); QPoint[] scales = new QPoint[2] { new QPoint(x_scale / trans.a.y, y_scale / trans.a.y), new QPoint(x_scale / trans.b.y, y_scale / trans.b.y) }; int x1 = window.Width / 2 - (int)(trans.a.x * scales[0].x); int x2 = window.Width / 2 - (int)(trans.b.x * scales[1].x); if (x1 >= x2 || x2 < secRender.sx1 || x1 > secRender.sx2) { continue; } float yCeil = World.sectors[currentSector].ceilHeight - player.height; float yFloor = World.sectors[currentSector].floorHeight - player.height; int neighbor = World.sectors[currentSector].neighbors[i]; float nyCeil = 0.0f, nyFloor = 0.0f; if (neighbor >= 0) { nyCeil = World.sectors[currentSector].ceilHeight - player.height; nyFloor = World.sectors[currentSector].floorHeight - player.height; } // TODO: ADD YAW int y1a = window.Height / 2 - (int)(yCeil * scales[0].y); int y2a = window.Height / 2 - (int)(yCeil * scales[1].y); int y1b = window.Height / 2 - (int)(yFloor * scales[0].y); int y2b = window.Height / 2 - (int)(yFloor * scales[1].y); int ny1a = window.Height / 2 - (int)(nyCeil * scales[0].y); int ny2a = window.Height / 2 - (int)(nyCeil * scales[1].y); int ny1b = window.Height / 2 - (int)(nyFloor * scales[0].y); int ny2b = window.Height / 2 - (int)(nyFloor * scales[1].y); int beginX = Math.Max(x1, secRender.sx1); int endX = Math.Min(x2, secRender.sx2); for (int x = beginX; x <= endX; x++) { int cya = (x - x1) * (y2a - y1a) / (x2 - x1) + y1a; Clamp(ref cya, yTop[x], yBottom[x]); int cyb = (x - x1) * (y2b - y1b) / (x2 - x1) + y1b; Clamp(ref cyb, yTop[x], yBottom[x]); GL.Color3(Color.Gray); GL.Vertex2(x, yTop[x]); GL.Vertex2(x, cya - 1); GL.Color3(Color.CadetBlue); GL.Vertex2(x, yBottom[x]); GL.Vertex2(x, cyb + 1); if (neighbor >= 0) { int cnya = (x - x1) * (ny2a - ny1a) / (x2 - x1) + ny1a; Clamp(ref cnya, yTop[x], yBottom[x]); int cnyb = (x - x1) * (ny2b - ny1b) / (x2 - x1) + ny1b; Clamp(ref cnyb, yTop[x], yBottom[x]); if (x == x1 || x == x2) { GL.Color3(Color.Black); } else { GL.Color3(Color.White); } GL.Vertex2(x, cya); GL.Vertex2(x, cnya); int max = Math.Max(cya, cnya); Clamp(ref max, yTop[x], window.Height - 1); yTop[x] = max; // Shrink the remaining window below these ceilings /* If our floor is lower than their floor, render bottom wall */ if (x == x1 || x == x2) { GL.Color3(Color.Black); } else { GL.Color3(Color.White); } GL.Vertex2(x, cnyb); GL.Vertex2(x, cyb); int min = Math.Max(cyb, cnyb); Clamp(ref min, 0, yBottom[x]); yBottom[x] = min; } else { } } } } while (sectorQueue.Count > 0); GL.End(); }
public Wall(QLine a, Color b) { line = a; clr = b; }