First attempt at rendering polyobject previews.

This commit is contained in:
spherallic 2022-03-05 13:12:25 +01:00
parent 953312482d
commit 2f55a6897a
2 changed files with 388 additions and 244 deletions

View File

@ -68,6 +68,8 @@ namespace CodeImp.DoomBuilder.Rendering
void PlotVerticesSet(ICollection<Vertex> vertices); void PlotVerticesSet(ICollection<Vertex> vertices);
void RenderThing(Thing t, PixelColor c, float alpha); void RenderThing(Thing t, PixelColor c, float alpha);
void RenderThingSet(ICollection<Thing> things, float alpha); void RenderThingSet(ICollection<Thing> things, float alpha);
void RenderWaypoints();
void RenderPolyobjects();
void RenderNiGHTSPath(); void RenderNiGHTSPath();
void RenderRectangle(RectangleF rect, float bordersize, PixelColor c, bool transformrect); void RenderRectangle(RectangleF rect, float bordersize, PixelColor c, bool transformrect);
void RenderRectangleFilled(RectangleF rect, PixelColor c, bool transformrect); void RenderRectangleFilled(RectangleF rect, PixelColor c, bool transformrect);

View File

@ -124,6 +124,21 @@ namespace CodeImp.DoomBuilder.Rendering
// Presentation // Presentation
private Presentation present; private Presentation present;
// SRB2 stuff
private List<Thing> axes;
private List<Thing> axistransferlines;
private List<Thing> waypoints;
private List<Thing> polyanchors;
private List<Thing> polyspawns;
private List<Linedef> firstlines;
private Vector2D[] starts;
private Vector2D[] ends;
private TextLabel waypointlabel;
private TextLabel spawnlabel;
private TextLabel anchorlabel;
#endregion #endregion
#region ================== Properties #region ================== Properties
@ -156,6 +171,39 @@ namespace CodeImp.DoomBuilder.Rendering
// Create rendertargets // Create rendertargets
CreateRendertargets(); CreateRendertargets();
anchorlabel = new TextLabel(3) // create sequence ID label
{
Text = "0",
AlignX = TextAlignmentX.Center,
AlignY = TextAlignmentY.Middle,
Color = General.Colors.GetNiGHTSColor(8),
Backcolor = General.Colors.Background,
Scale = 16f,
TransformCoords = true
};
spawnlabel = new TextLabel(3) // create sequence ID label
{
Text = "0",
AlignX = TextAlignmentX.Center,
AlignY = TextAlignmentY.Middle,
Color = General.Colors.GetNiGHTSColor(7),
Backcolor = General.Colors.Background,
Scale = 16f,
TransformCoords = true
};
waypointlabel = new TextLabel(3) // create sequence ID label
{
Text = "0",
AlignX = TextAlignmentX.Center,
AlignY = TextAlignmentY.Middle,
Color = General.Colors.WaypointColor,
Backcolor = General.Colors.Background,
Scale = 16f,
TransformCoords = true
};
// We have no destructor // We have no destructor
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
@ -164,7 +212,7 @@ namespace CodeImp.DoomBuilder.Rendering
public override void Dispose() public override void Dispose()
{ {
// Not already disposed? // Not already disposed?
if(!isdisposed) if (!isdisposed)
{ {
// Destroy rendertargets // Destroy rendertargets
DestroyRendertargets(); DestroyRendertargets();
@ -194,7 +242,7 @@ namespace CodeImp.DoomBuilder.Rendering
General.Plugins.OnPresentDisplayBegin(); General.Plugins.OnPresentDisplayBegin();
// Start drawing // Start drawing
if(graphics.StartRendering(true, General.Colors.Background.ToColorValue(), graphics.BackBuffer, graphics.DepthBuffer)) if (graphics.StartRendering(true, General.Colors.Background.ToColorValue(), graphics.BackBuffer, graphics.DepthBuffer))
{ {
// Renderstates that count for this whole sequence // Renderstates that count for this whole sequence
graphics.Device.SetRenderState(RenderState.CullMode, Cull.None); graphics.Device.SetRenderState(RenderState.CullMode, Cull.None);
@ -205,12 +253,12 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Shaders.Display2D.Begin(); graphics.Shaders.Display2D.Begin();
// Go for all layers // Go for all layers
foreach(PresentLayer layer in present.layers) foreach (PresentLayer layer in present.layers)
{ {
int aapass; int aapass;
// Set blending mode // Set blending mode
switch(layer.blending) switch (layer.blending)
{ {
case BlendingMode.None: case BlendingMode.None:
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false); graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
@ -242,14 +290,14 @@ namespace CodeImp.DoomBuilder.Rendering
} }
// Check which pass to use // Check which pass to use
if(layer.antialiasing && General.Settings.QualityDisplay) aapass = 0; else aapass = 1; if (layer.antialiasing && General.Settings.QualityDisplay) aapass = 0; else aapass = 1;
// Render layer // Render layer
switch(layer.layer) switch (layer.layer)
{ {
// BACKGROUND // BACKGROUND
case RendererLayer.Background: case RendererLayer.Background:
if((backimageverts == null) || (General.Map.Grid.Background.Texture == null)) break; if ((backimageverts == null) || (General.Map.Grid.Background.Texture == null)) break;
graphics.Device.SetTexture(0, General.Map.Grid.Background.Texture); graphics.Device.SetTexture(0, General.Map.Grid.Background.Texture);
graphics.Shaders.Display2D.Texture1 = General.Map.Grid.Background.Texture; graphics.Shaders.Display2D.Texture1 = General.Map.Grid.Background.Texture;
graphics.Shaders.Display2D.SetSettings(1f / windowsize.Width, 1f / windowsize.Height, FSAA_FACTOR, layer.alpha, false); graphics.Shaders.Display2D.SetSettings(1f / windowsize.Width, 1f / windowsize.Height, FSAA_FACTOR, layer.alpha, false);
@ -359,12 +407,12 @@ namespace CodeImp.DoomBuilder.Rendering
public void DestroyRendertargets() public void DestroyRendertargets()
{ {
// Trash rendertargets // Trash rendertargets
if(plottertex != null) plottertex.Dispose(); if (plottertex != null) plottertex.Dispose();
if(thingstex != null) thingstex.Dispose(); if (thingstex != null) thingstex.Dispose();
if(overlaytex != null) overlaytex.Dispose(); if (overlaytex != null) overlaytex.Dispose();
if(surfacetex != null) surfacetex.Dispose(); if (surfacetex != null) surfacetex.Dispose();
if(backtex != null) backtex.Dispose(); if (backtex != null) backtex.Dispose();
if(screenverts != null) screenverts.Dispose(); if (screenverts != null) screenverts.Dispose();
plottertex = null; plottertex = null;
thingstex = null; thingstex = null;
backtex = null; backtex = null;
@ -373,13 +421,13 @@ namespace CodeImp.DoomBuilder.Rendering
surfacetex = null; surfacetex = null;
// Trash things batch buffer // Trash things batch buffer
if(thingsvertices != null) thingsvertices.Dispose(); if (thingsvertices != null) thingsvertices.Dispose();
thingsvertices = null; thingsvertices = null;
lastgridscale = -1f; lastgridscale = -1f;
lastgridsize = 0; lastgridsize = 0;
// Trash font // Trash font
if(font != null) font.Dispose(); if (font != null) font.Dispose();
font = null; font = null;
} }
@ -513,8 +561,8 @@ namespace CodeImp.DoomBuilder.Rendering
minlinenormallength = linenormalsize * 2f; //mxd minlinenormallength = linenormalsize * 2f; //mxd
vertexsize = (int)(1.7f * General.Settings.GZVertexScale2D * scale + 0.5f); //mxd. added GZVertexScale2D vertexsize = (int)(1.7f * General.Settings.GZVertexScale2D * scale + 0.5f); //mxd. added GZVertexScale2D
if(vertexsize < 0) vertexsize = 0; if (vertexsize < 0) vertexsize = 0;
if(vertexsize > 4) vertexsize = 4; if (vertexsize > 4) vertexsize = 4;
Matrix scaling = Matrix.Scaling((1f / windowsize.Width) * 2f, (1f / windowsize.Height) * -2f, 1f); Matrix scaling = Matrix.Scaling((1f / windowsize.Width) * 2f, (1f / windowsize.Height) * -2f, 1f);
Matrix translate = Matrix.Translation(-(float)windowsize.Width * 0.5f, -(float)windowsize.Height * 0.5f, 0f); Matrix translate = Matrix.Translation(-(float)windowsize.Width * 0.5f, -(float)windowsize.Height * 0.5f, 0f);
@ -529,7 +577,7 @@ namespace CodeImp.DoomBuilder.Rendering
// This sets the world matrix for transformation // This sets the world matrix for transformation
private void SetWorldTransformation(bool transform) private void SetWorldTransformation(bool transform)
{ {
if(transform) if (transform)
{ {
Matrix translate = Matrix.Translation(translatex, translatey, 0f); Matrix translate = Matrix.Translation(translatex, translatey, 0f);
Matrix scaling = Matrix.Scaling(scale, -scale, 1f); Matrix scaling = Matrix.Scaling(scale, -scale, 1f);
@ -565,14 +613,14 @@ namespace CodeImp.DoomBuilder.Rendering
public PixelColor DetermineThingColor(Thing t) public PixelColor DetermineThingColor(Thing t)
{ {
// Determine color // Determine color
if(t.Selected) return General.Colors.Selection; if (t.Selected) return General.Colors.Selection;
//mxd. If thing is light, set it's color to light color: //mxd. If thing is light, set it's color to light color:
if(Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, t.SRB2Type) != -1) if (Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, t.SRB2Type) != -1)
{ {
if(t.SRB2Type == 1502) //vavoom light if (t.SRB2Type == 1502) //vavoom light
return new PixelColor(255, 255, 255, 255); return new PixelColor(255, 255, 255, 255);
if(t.SRB2Type == 1503) //vavoom colored light if (t.SRB2Type == 1503) //vavoom colored light
return new PixelColor(255, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]); return new PixelColor(255, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]);
return new PixelColor(255, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]); return new PixelColor(255, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]);
} }
@ -584,25 +632,25 @@ namespace CodeImp.DoomBuilder.Rendering
public int DetermineVertexColor(Vertex v) public int DetermineVertexColor(Vertex v)
{ {
// Determine color // Determine color
if(v.Selected) return ColorCollection.SELECTION; if (v.Selected) return ColorCollection.SELECTION;
return ColorCollection.VERTICES; return ColorCollection.VERTICES;
} }
// This returns the color for a linedef // This returns the color for a linedef
public PixelColor DetermineLinedefColor(Linedef l) public PixelColor DetermineLinedefColor(Linedef l)
{ {
if(l.Selected) return General.Colors.Selection; if (l.Selected) return General.Colors.Selection;
//mxd. Impassable lines //mxd. Impassable lines
if(l.ImpassableFlag) if (l.ImpassableFlag)
{ {
if(l.ColorPresetIndex != -1) if (l.ColorPresetIndex != -1)
return General.Map.ConfigSettings.LinedefColorPresets[l.ColorPresetIndex].Color; return General.Map.ConfigSettings.LinedefColorPresets[l.ColorPresetIndex].Color;
return General.Colors.Linedefs; return General.Colors.Linedefs;
} }
//mxd. Passable lines //mxd. Passable lines
if(l.ColorPresetIndex != -1) if (l.ColorPresetIndex != -1)
return General.Map.ConfigSettings.LinedefColorPresets[l.ColorPresetIndex].Color.WithAlpha(General.Settings.DoubleSidedAlphaByte); return General.Map.ConfigSettings.LinedefColorPresets[l.ColorPresetIndex].Color.WithAlpha(General.Settings.DoubleSidedAlphaByte);
return General.Colors.Linedefs.WithAlpha(General.Settings.DoubleSidedAlphaByte); return General.Colors.Linedefs.WithAlpha(General.Settings.DoubleSidedAlphaByte);
} }
@ -613,26 +661,26 @@ namespace CodeImp.DoomBuilder.Rendering
HashSet<int> tags = new HashSet<int>(); HashSet<int> tags = new HashSet<int>();
//find lines with 3d floor action and collect sector tags //find lines with 3d floor action and collect sector tags
foreach(Linedef l in General.Map.Map.Linedefs) foreach (Linedef l in General.Map.Map.Linedefs)
{ {
//MascaraSnake: 3D floor handling //MascaraSnake: 3D floor handling
if(l.Is3DFloor) if (l.Is3DFloor)
{ {
if (!General.Map.FormatInterface.HasLinedefParameters) l.Set3DFloorArgs(); if (!General.Map.FormatInterface.HasLinedefParameters) l.Set3DFloorArgs();
int sectortag = (General.Map.UDMF || (l.Args[1] & 8) != 0) ? l.Args[0] : l.Args[0] + (l.Args[4] << 8); int sectortag = (General.Map.UDMF || (l.Args[1] & 8) != 0) ? l.Args[0] : l.Args[0] + (l.Args[4] << 8);
if(sectortag != 0 && !tags.Contains(sectortag)) tags.Add(sectortag); if (sectortag != 0 && !tags.Contains(sectortag)) tags.Add(sectortag);
} }
} }
//find lines, which are related to sectors with 3d floors, and collect their valuable indices //find lines, which are related to sectors with 3d floors, and collect their valuable indices
foreach(Linedef l in General.Map.Map.Linedefs) foreach (Linedef l in General.Map.Map.Linedefs)
{ {
if(l.Front != null && l.Front.Sector != null && l.Front.Sector.Tag != 0 && tags.Overlaps(l.Front.Sector.Tags)) if (l.Front != null && l.Front.Sector != null && l.Front.Sector.Tag != 0 && tags.Overlaps(l.Front.Sector.Tags))
{ {
l.ExtraFloorFlag = true; l.ExtraFloorFlag = true;
continue; continue;
} }
if(l.Back != null && l.Back.Sector != null && l.Back.Sector.Tag != 0 && tags.Overlaps(l.Back.Sector.Tags)) if (l.Back != null && l.Back.Sector != null && l.Back.Sector.Tag != 0 && tags.Overlaps(l.Back.Sector.Tags))
{ {
l.ExtraFloorFlag = true; l.ExtraFloorFlag = true;
continue; continue;
@ -649,7 +697,7 @@ namespace CodeImp.DoomBuilder.Rendering
// This begins a drawing session // This begins a drawing session
public unsafe bool StartPlotter(bool clear) public unsafe bool StartPlotter(bool clear)
{ {
if(renderlayer != RenderLayers.None) if (renderlayer != RenderLayers.None)
{ {
#if DEBUG #if DEBUG
throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!"); throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!");
@ -659,10 +707,10 @@ namespace CodeImp.DoomBuilder.Rendering
} }
renderlayer = RenderLayers.Plotter; renderlayer = RenderLayers.Plotter;
try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch(Exception) { } try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch (Exception) { }
// Rendertargets available? // Rendertargets available?
if(plottertex != null) if (plottertex != null)
{ {
// Lock structures rendertarget memory // Lock structures rendertarget memory
plotlocked = plottertex.LockRectangle(0, LockFlags.NoSystemLock); plotlocked = plottertex.LockRectangle(0, LockFlags.NoSystemLock);
@ -671,7 +719,7 @@ namespace CodeImp.DoomBuilder.Rendering
plotter = new Plotter((PixelColor*)plotlocked.Data.DataPointer.ToPointer(), plotlocked.Pitch / sizeof(PixelColor), structsize.Height, structsize.Width, structsize.Height); plotter = new Plotter((PixelColor*)plotlocked.Data.DataPointer.ToPointer(), plotlocked.Pitch / sizeof(PixelColor), structsize.Height, structsize.Width, structsize.Height);
// Redraw grid when structures image was cleared // Redraw grid when structures image was cleared
if(clear) if (clear)
{ {
plotter.Clear(); plotter.Clear();
RenderBackgroundGrid(); RenderBackgroundGrid();
@ -691,7 +739,7 @@ namespace CodeImp.DoomBuilder.Rendering
// This begins a drawing session // This begins a drawing session
public bool StartThings(bool clear) public bool StartThings(bool clear)
{ {
if(renderlayer != RenderLayers.None) if (renderlayer != RenderLayers.None)
{ {
#if DEBUG #if DEBUG
throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!"); throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!");
@ -701,14 +749,14 @@ namespace CodeImp.DoomBuilder.Rendering
} }
renderlayer = RenderLayers.Things; renderlayer = RenderLayers.Things;
try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch(Exception) { } try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch (Exception) { }
// Rendertargets available? // Rendertargets available?
if(thingstex != null) if (thingstex != null)
{ {
// Set the rendertarget to the things texture // Set the rendertarget to the things texture
targetsurface = thingstex.GetSurfaceLevel(0); targetsurface = thingstex.GetSurfaceLevel(0);
if(graphics.StartRendering(clear, General.Colors.Background.WithAlpha(0).ToColorValue(), targetsurface, null)) if (graphics.StartRendering(clear, General.Colors.Background.WithAlpha(0).ToColorValue(), targetsurface, null))
{ {
// Ready for rendering // Ready for rendering
UpdateTransformations(); UpdateTransformations();
@ -728,7 +776,7 @@ namespace CodeImp.DoomBuilder.Rendering
// This begins a drawing session // This begins a drawing session
public bool StartOverlay(bool clear) public bool StartOverlay(bool clear)
{ {
if(renderlayer != RenderLayers.None) if (renderlayer != RenderLayers.None)
{ {
#if DEBUG #if DEBUG
throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!"); throw new InvalidOperationException("Renderer starting called before finished previous layer. Call Finish() first!");
@ -738,14 +786,14 @@ namespace CodeImp.DoomBuilder.Rendering
} }
renderlayer = RenderLayers.Overlay; renderlayer = RenderLayers.Overlay;
try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch(Exception) { } try { graphics.Device.SetRenderState(RenderState.FogEnable, false); } catch (Exception) { }
// Rendertargets available? // Rendertargets available?
if(overlaytex != null) if (overlaytex != null)
{ {
// Set the rendertarget to the things texture // Set the rendertarget to the things texture
targetsurface = overlaytex.GetSurfaceLevel(0); targetsurface = overlaytex.GetSurfaceLevel(0);
if(graphics.StartRendering(clear, General.Colors.Background.WithAlpha(0).ToColorValue(), targetsurface, null)) if (graphics.StartRendering(clear, General.Colors.Background.WithAlpha(0).ToColorValue(), targetsurface, null))
{ {
// Ready for rendering // Ready for rendering
UpdateTransformations(); UpdateTransformations();
@ -766,15 +814,15 @@ namespace CodeImp.DoomBuilder.Rendering
public void Finish() public void Finish()
{ {
// Clean up plotter // Clean up plotter
if(renderlayer == RenderLayers.Plotter) if (renderlayer == RenderLayers.Plotter)
{ {
if(plottertex != null) plottertex.UnlockRectangle(0); if (plottertex != null) plottertex.UnlockRectangle(0);
if(plotlocked.Data != null) plotlocked.Data.Dispose(); if (plotlocked.Data != null) plotlocked.Data.Dispose();
plotter = null; plotter = null;
} }
// Clean up things / overlay // Clean up things / overlay
if((renderlayer == RenderLayers.Things) || (renderlayer == RenderLayers.Overlay) || (renderlayer == RenderLayers.Surface)) if ((renderlayer == RenderLayers.Things) || (renderlayer == RenderLayers.Overlay) || (renderlayer == RenderLayers.Surface))
{ {
// Stop rendering // Stop rendering
graphics.FinishRendering(); graphics.FinishRendering();
@ -785,8 +833,8 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Device.DepthStencilSurface = graphics.DepthBuffer; graphics.Device.DepthStencilSurface = graphics.DepthBuffer;
graphics.Device.SetRenderTarget(0, graphics.BackBuffer); graphics.Device.SetRenderTarget(0, graphics.BackBuffer);
} }
catch(Exception) { } catch (Exception) { }
if(targetsurface != null) targetsurface.Dispose(); if (targetsurface != null) targetsurface.Dispose();
targetsurface = null; targetsurface = null;
} }
@ -802,7 +850,7 @@ namespace CodeImp.DoomBuilder.Rendering
private void SetupBackground() private void SetupBackground()
{ {
// Only if a background image is set // Only if a background image is set
if((General.Map.Grid.Background != null) && !(General.Map.Grid.Background is UnknownImage)) if ((General.Map.Grid.Background != null) && !(General.Map.Grid.Background is UnknownImage))
{ {
Vector2D backoffset = new Vector2D(General.Map.Grid.BackgroundX, General.Map.Grid.BackgroundY); Vector2D backoffset = new Vector2D(General.Map.Grid.BackgroundX, General.Map.Grid.BackgroundY);
Vector2D backimagesize = new Vector2D(General.Map.Grid.Background.ScaledWidth, General.Map.Grid.Background.ScaledHeight); Vector2D backimagesize = new Vector2D(General.Map.Grid.Background.ScaledWidth, General.Map.Grid.Background.ScaledHeight);
@ -844,7 +892,7 @@ namespace CodeImp.DoomBuilder.Rendering
private unsafe void RenderBackgroundGrid() private unsafe void RenderBackgroundGrid()
{ {
// Do we need to redraw grid? // Do we need to redraw grid?
if((lastgridsize != General.Map.Grid.GridSize) || (lastgridscale != scale) || if ((lastgridsize != General.Map.Grid.GridSize) || (lastgridscale != scale) ||
(lastgridx != offsetx) || (lastgridy != offsety)) (lastgridx != offsetx) || (lastgridy != offsety))
{ {
// Lock background rendertarget memory // Lock background rendertarget memory
@ -854,13 +902,13 @@ namespace CodeImp.DoomBuilder.Rendering
Plotter gridplotter = new Plotter((PixelColor*)lockedrect.Data.DataPointer.ToPointer(), lockedrect.Pitch / sizeof(PixelColor), backsize.Height, backsize.Width, backsize.Height); Plotter gridplotter = new Plotter((PixelColor*)lockedrect.Data.DataPointer.ToPointer(), lockedrect.Pitch / sizeof(PixelColor), backsize.Height, backsize.Width, backsize.Height);
gridplotter.Clear(); gridplotter.Clear();
if(General.Settings.RenderGrid) //mxd if (General.Settings.RenderGrid) //mxd
{ {
// Render normal grid // Render normal grid
RenderGrid(General.Map.Grid.GridSize, General.Colors.Grid, gridplotter); RenderGrid(General.Map.Grid.GridSize, General.Colors.Grid, gridplotter);
// Render 64 grid // Render 64 grid
if(General.Map.Grid.GridSize <= 64) RenderGrid(64f, General.Colors.Grid64, gridplotter); if (General.Map.Grid.GridSize <= 64) RenderGrid(64f, General.Colors.Grid64, gridplotter);
} }
else else
{ {
@ -918,8 +966,8 @@ namespace CodeImp.DoomBuilder.Rendering
Vector2D pos = new Vector2D(); Vector2D pos = new Vector2D();
//mxd. Increase rendered grid size if needed //mxd. Increase rendered grid size if needed
if(!General.Settings.DynamicGridSize && size * scale <= 6f) if (!General.Settings.DynamicGridSize && size * scale <= 6f)
do { size *= 2; } while(size * scale <= 6f); do { size *= 2; } while (size * scale <= 6f);
float sizeinv = 1f / size; float sizeinv = 1f / size;
// Determine map coordinates for view window // Determine map coordinates for view window
@ -938,10 +986,10 @@ namespace CodeImp.DoomBuilder.Rendering
float ystart = rbpos.y > General.Map.Config.BottomBoundary ? rbpos.y : General.Map.Config.BottomBoundary; float ystart = rbpos.y > General.Map.Config.BottomBoundary ? rbpos.y : General.Map.Config.BottomBoundary;
float yend = ltpos.y < General.Map.Config.TopBoundary ? ltpos.y : General.Map.Config.TopBoundary; float yend = ltpos.y < General.Map.Config.TopBoundary ? ltpos.y : General.Map.Config.TopBoundary;
for(float y = ystart; y < yend + size; y += size) for (float y = ystart; y < yend + size; y += size)
{ {
if(y > General.Map.Config.TopBoundary) y = General.Map.Config.TopBoundary; if (y > General.Map.Config.TopBoundary) y = General.Map.Config.TopBoundary;
else if(y < General.Map.Config.BottomBoundary) y = General.Map.Config.BottomBoundary; else if (y < General.Map.Config.BottomBoundary) y = General.Map.Config.BottomBoundary;
float from = tlb.x < 0 ? 0 : tlb.x; float from = tlb.x < 0 ? 0 : tlb.x;
float to = rbb.x > windowsize.Width ? windowsize.Width : rbb.x; float to = rbb.x > windowsize.Width ? windowsize.Width : rbb.x;
@ -957,10 +1005,10 @@ namespace CodeImp.DoomBuilder.Rendering
float xstart = ltpos.x > General.Map.Config.LeftBoundary ? ltpos.x : General.Map.Config.LeftBoundary; float xstart = ltpos.x > General.Map.Config.LeftBoundary ? ltpos.x : General.Map.Config.LeftBoundary;
float xend = rbpos.x < General.Map.Config.RightBoundary ? rbpos.x : General.Map.Config.RightBoundary; float xend = rbpos.x < General.Map.Config.RightBoundary ? rbpos.x : General.Map.Config.RightBoundary;
for(float x = xstart; x < xend + size; x += size) for (float x = xstart; x < xend + size; x += size)
{ {
if(x > General.Map.Config.RightBoundary) x = General.Map.Config.RightBoundary; if (x > General.Map.Config.RightBoundary) x = General.Map.Config.RightBoundary;
else if(x < General.Map.Config.LeftBoundary) x = General.Map.Config.LeftBoundary; else if (x < General.Map.Config.LeftBoundary) x = General.Map.Config.LeftBoundary;
float from = tlb.y < 0 ? 0 : tlb.y; float from = tlb.y < 0 ? 0 : tlb.y;
float to = rbb.y > windowsize.Height ? windowsize.Height : rbb.y; float to = rbb.y > windowsize.Height ? windowsize.Height : rbb.y;
@ -988,7 +1036,7 @@ namespace CodeImp.DoomBuilder.Rendering
private bool CreateThingBoxVerts(Thing t, ref FlatVertex[] verts, Dictionary<Thing, Vector2D> thingsByPosition, int offset, PixelColor c) private bool CreateThingBoxVerts(Thing t, ref FlatVertex[] verts, Dictionary<Thing, Vector2D> thingsByPosition, int offset, PixelColor c)
{ {
float thingsize = General.Settings.DrawThingsFixedSize ? General.Settings.DefaultThingSize : t.Size; float thingsize = General.Settings.DrawThingsFixedSize ? General.Settings.DefaultThingSize : t.Size;
if(thingsize * scale < MINIMUM_THING_RADIUS) return false; //mxd. Don't render tiny little things if (thingsize * scale < MINIMUM_THING_RADIUS) return false; //mxd. Don't render tiny little things
// Determine size // Determine size
float circlesize = (t.FixedSize && (scale > 1.0f) ? thingsize /* * THING_CIRCLE_SIZE*/ : thingsize * scale /* * THING_CIRCLE_SIZE*/); float circlesize = (t.FixedSize && (scale > 1.0f) ? thingsize /* * THING_CIRCLE_SIZE*/ : thingsize * scale /* * THING_CIRCLE_SIZE*/);
@ -997,7 +1045,7 @@ namespace CodeImp.DoomBuilder.Rendering
Vector2D screenpos = ((Vector2D)t.Position).GetTransformed(translatex, translatey, scale, -scale); Vector2D screenpos = ((Vector2D)t.Position).GetTransformed(translatex, translatey, scale, -scale);
// Check if the thing is actually on screen // Check if the thing is actually on screen
if(((screenpos.x + circlesize) <= 0.0f) || ((screenpos.x - circlesize) >= windowsize.Width) || if (((screenpos.x + circlesize) <= 0.0f) || ((screenpos.x - circlesize) >= windowsize.Width) ||
((screenpos.y + circlesize) <= 0.0f) || ((screenpos.y - circlesize) >= windowsize.Height)) ((screenpos.y + circlesize) <= 0.0f) || ((screenpos.y - circlesize) >= windowsize.Height))
return false; return false;
@ -1117,7 +1165,7 @@ namespace CodeImp.DoomBuilder.Rendering
private void RenderThingsBatch(ICollection<Thing> things, float alpha, bool fixedcolor, PixelColor c) private void RenderThingsBatch(ICollection<Thing> things, float alpha, bool fixedcolor, PixelColor c)
{ {
// Anything to render? // Anything to render?
if(things.Count > 0) if (things.Count > 0)
{ {
DataStream stream; DataStream stream;
@ -1157,33 +1205,33 @@ namespace CodeImp.DoomBuilder.Rendering
// Go for all things // Go for all things
int buffercount = 0; int buffercount = 0;
int totalcount = 0; int totalcount = 0;
foreach(Thing t in things) foreach (Thing t in things)
{ {
//mxd. Highlighted thing should be rendered separately //mxd. Highlighted thing should be rendered separately
if(!fixedcolor && t.Highlighted) continue; if (!fixedcolor && t.Highlighted) continue;
//collect models //collect models
if(t.IsModel) if (t.IsModel)
{ {
if(!modelsByType.ContainsKey(t.SRB2Type)) modelsByType.Add(t.SRB2Type, new List<Thing>()); if (!modelsByType.ContainsKey(t.SRB2Type)) modelsByType.Add(t.SRB2Type, new List<Thing>());
modelsByType[t.SRB2Type].Add(t); modelsByType[t.SRB2Type].Add(t);
} }
// Create vertices // Create vertices
PixelColor tc = fixedcolor ? c : DetermineThingColor(t); PixelColor tc = fixedcolor ? c : DetermineThingColor(t);
if(CreateThingBoxVerts(t, ref verts, thingsByPosition, buffercount * 6, tc)) if (CreateThingBoxVerts(t, ref verts, thingsByPosition, buffercount * 6, tc))
{ {
buffercount++; buffercount++;
//mxd //mxd
if(!thingsByType.ContainsKey(t.SRB2Type)) thingsByType.Add(t.SRB2Type, new List<Thing>()); if (!thingsByType.ContainsKey(t.SRB2Type)) thingsByType.Add(t.SRB2Type, new List<Thing>());
thingsByType[t.SRB2Type].Add(t); thingsByType[t.SRB2Type].Add(t);
} }
totalcount++; totalcount++;
// Buffer filled? // Buffer filled?
if(buffercount == locksize) if (buffercount == locksize)
{ {
// Write to buffer // Write to buffer
stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard); stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard);
@ -1202,12 +1250,12 @@ namespace CodeImp.DoomBuilder.Rendering
// Write to buffer // Write to buffer
stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard); stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard);
if(buffercount > 0) stream.WriteRange(verts, 0, buffercount * 6); if (buffercount > 0) stream.WriteRange(verts, 0, buffercount * 6);
thingsvertices.Unlock(); thingsvertices.Unlock();
stream.Dispose(); stream.Dispose();
// Draw what's still remaining // Draw what's still remaining
if(buffercount > 0) if (buffercount > 0)
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2);
// Done // Done
@ -1217,22 +1265,22 @@ namespace CodeImp.DoomBuilder.Rendering
int selectionColor = General.Colors.Selection.ToInt(); int selectionColor = General.Colors.Selection.ToInt();
graphics.Shaders.Things2D.BeginPass(1); graphics.Shaders.Things2D.BeginPass(1);
foreach(KeyValuePair<int, List<Thing>> group in thingsByType) foreach (KeyValuePair<int, List<Thing>> group in thingsByType)
{ {
// Find thing information // Find thing information
ThingTypeInfo info = General.Map.Data.GetThingInfo(group.Key); ThingTypeInfo info = General.Map.Data.GetThingInfo(group.Key);
// Find sprite texture // Find sprite texture
if(info.Sprite.Length == 0) continue; if (info.Sprite.Length == 0) continue;
ImageData sprite = General.Map.Data.GetSpriteImage(info.Sprite); ImageData sprite = General.Map.Data.GetSpriteImage(info.Sprite);
if(sprite == null) continue; if (sprite == null) continue;
if(!sprite.IsImageLoaded) if (!sprite.IsImageLoaded)
{ {
sprite.SetUsedInMap(true); sprite.SetUsedInMap(true);
continue; continue;
} }
if(sprite.Texture == null) sprite.CreateTexture(); if (sprite.Texture == null) sprite.CreateTexture();
graphics.Device.SetTexture(0, sprite.Texture); graphics.Device.SetTexture(0, sprite.Texture);
graphics.Shaders.Things2D.Texture1 = sprite.Texture; graphics.Shaders.Things2D.Texture1 = sprite.Texture;
@ -1249,12 +1297,12 @@ namespace CodeImp.DoomBuilder.Rendering
float spriteScale = (group.Value[0].FixedSize && (scale > 1.0f)) ? 1.0f : scale; float spriteScale = (group.Value[0].FixedSize && (scale > 1.0f)) ? 1.0f : scale;
float radius = General.Settings.DrawThingsFixedSize ? General.Settings.DefaultThingSize : info.Radius; float radius = General.Settings.DrawThingsFixedSize ? General.Settings.DefaultThingSize : info.Radius;
if(sprite.Width > sprite.Height) if (sprite.Width > sprite.Height)
{ {
spriteWidth = radius * spriteScale - THING_SPRITE_SHRINK * spriteScale; spriteWidth = radius * spriteScale - THING_SPRITE_SHRINK * spriteScale;
spriteHeight = spriteWidth * ((float)sprite.Height / sprite.Width); spriteHeight = spriteWidth * ((float)sprite.Height / sprite.Width);
} }
else if(sprite.Width < sprite.Height) else if (sprite.Width < sprite.Height)
{ {
spriteHeight = radius * spriteScale - THING_SPRITE_SHRINK * spriteScale; spriteHeight = radius * spriteScale - THING_SPRITE_SHRINK * spriteScale;
spriteWidth = spriteHeight * ((float)sprite.Width / sprite.Height); spriteWidth = spriteHeight * ((float)sprite.Width / sprite.Height);
@ -1265,19 +1313,19 @@ namespace CodeImp.DoomBuilder.Rendering
spriteHeight = spriteWidth; spriteHeight = spriteWidth;
} }
foreach(Thing t in group.Value) foreach (Thing t in group.Value)
{ {
if(t.IsModel && (General.Settings.GZDrawModelsMode == ModelRenderMode.ALL || (General.Settings.GZDrawModelsMode == ModelRenderMode.SELECTION && t.Selected) || (General.Settings.GZDrawModelsMode == ModelRenderMode.ACTIVE_THINGS_FILTER && alpha == 1.0f))) continue; if (t.IsModel && (General.Settings.GZDrawModelsMode == ModelRenderMode.ALL || (General.Settings.GZDrawModelsMode == ModelRenderMode.SELECTION && t.Selected) || (General.Settings.GZDrawModelsMode == ModelRenderMode.ACTIVE_THINGS_FILTER && alpha == 1.0f))) continue;
float thingsize = General.Settings.DrawThingsFixedSize ? General.Settings.DefaultThingSize : t.Size; float thingsize = General.Settings.DrawThingsFixedSize ? General.Settings.DefaultThingSize : t.Size;
float scaler = thingsize / radius; float scaler = thingsize / radius;
if(Math.Max(spriteWidth, spriteHeight) * scaler < MINIMUM_SPRITE_RADIUS) continue; //don't render tiny little sprites if (Math.Max(spriteWidth, spriteHeight) * scaler < MINIMUM_SPRITE_RADIUS) continue; //don't render tiny little sprites
CreateThingSpriteVerts(thingsByPosition[t], spriteWidth * scaler, spriteHeight * scaler, ref verts, buffercount * 6, t.Selected ? selectionColor : 0xFFFFFF); CreateThingSpriteVerts(thingsByPosition[t], spriteWidth * scaler, spriteHeight * scaler, ref verts, buffercount * 6, t.Selected ? selectionColor : 0xFFFFFF);
buffercount++; buffercount++;
totalcount++; totalcount++;
// Buffer filled? // Buffer filled?
if(buffercount == locksize) if (buffercount == locksize)
{ {
// Write to buffer // Write to buffer
stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard); stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard);
@ -1297,12 +1345,12 @@ namespace CodeImp.DoomBuilder.Rendering
// Write to buffer // Write to buffer
stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard); stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard);
if(buffercount > 0) stream.WriteRange(verts, 0, buffercount * 6); if (buffercount > 0) stream.WriteRange(verts, 0, buffercount * 6);
thingsvertices.Unlock(); thingsvertices.Unlock();
stream.Dispose(); stream.Dispose();
// Draw what's still remaining // Draw what's still remaining
if(buffercount > 0) if (buffercount > 0)
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2);
} }
@ -1322,16 +1370,16 @@ namespace CodeImp.DoomBuilder.Rendering
buffercount = 0; buffercount = 0;
totalcount = 0; totalcount = 0;
foreach(KeyValuePair<Thing, Vector2D> group in thingsByPosition) foreach (KeyValuePair<Thing, Vector2D> group in thingsByPosition)
{ {
if(!group.Key.IsDirectional) continue; if (!group.Key.IsDirectional) continue;
CreateThingArrowVerts(group.Key, ref verts, group.Value, buffercount * 6); CreateThingArrowVerts(group.Key, ref verts, group.Value, buffercount * 6);
buffercount++; buffercount++;
totalcount++; totalcount++;
// Buffer filled? // Buffer filled?
if(buffercount == locksize) if (buffercount == locksize)
{ {
// Write to buffer // Write to buffer
stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard); stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard);
@ -1350,19 +1398,19 @@ namespace CodeImp.DoomBuilder.Rendering
// Write to buffer // Write to buffer
stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard); stream = thingsvertices.Lock(0, locksize * 6 * FlatVertex.Stride, LockFlags.Discard);
if(buffercount > 0) stream.WriteRange(verts, 0, buffercount * 6); if (buffercount > 0) stream.WriteRange(verts, 0, buffercount * 6);
thingsvertices.Unlock(); thingsvertices.Unlock();
stream.Dispose(); stream.Dispose();
// Draw what's still remaining // Draw what's still remaining
if(buffercount > 0) if (buffercount > 0)
graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2); graphics.Device.DrawPrimitives(PrimitiveType.TriangleList, 0, buffercount * 2);
//Done with this pass //Done with this pass
graphics.Shaders.Things2D.EndPass(); graphics.Shaders.Things2D.EndPass();
//mxd. Render models //mxd. Render models
if(General.Settings.GZDrawModelsMode != ModelRenderMode.NONE) if (General.Settings.GZDrawModelsMode != ModelRenderMode.NONE)
{ {
// Set renderstates for rendering // Set renderstates for rendering
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false); graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
@ -1379,17 +1427,17 @@ namespace CodeImp.DoomBuilder.Rendering
Matrix viewscale = Matrix.Scaling(scale, -scale, 0.0f); Matrix viewscale = Matrix.Scaling(scale, -scale, 0.0f);
foreach(KeyValuePair<int, List<Thing>> group in modelsByType) foreach (KeyValuePair<int, List<Thing>> group in modelsByType)
{ {
ModelData mde = General.Map.Data.ModeldefEntries[@group.Key]; ModelData mde = General.Map.Data.ModeldefEntries[@group.Key];
foreach(Thing t in group.Value) foreach (Thing t in group.Value)
{ {
if((General.Settings.GZDrawModelsMode == ModelRenderMode.SELECTION && !t.Selected) || (General.Settings.GZDrawModelsMode == ModelRenderMode.ACTIVE_THINGS_FILTER && alpha < 1.0f)) continue; if ((General.Settings.GZDrawModelsMode == ModelRenderMode.SELECTION && !t.Selected) || (General.Settings.GZDrawModelsMode == ModelRenderMode.ACTIVE_THINGS_FILTER && alpha < 1.0f)) continue;
Vector2D screenpos = ((Vector2D)t.Position).GetTransformed(translatex, translatey, scale, -scale); Vector2D screenpos = ((Vector2D)t.Position).GetTransformed(translatex, translatey, scale, -scale);
float modelScale = scale * t.ActorScale.Width * t.ScaleX; float modelScale = scale * t.ActorScale.Width * t.ScaleX;
//should we render this model? //should we render this model?
if(((screenpos.x + mde.Model.Radius * modelScale) <= 0.0f) || ((screenpos.x - mde.Model.Radius * modelScale) >= windowsize.Width) || if (((screenpos.x + mde.Model.Radius * modelScale) <= 0.0f) || ((screenpos.x - mde.Model.Radius * modelScale) >= windowsize.Width) ||
((screenpos.y + mde.Model.Radius * modelScale) <= 0.0f) || ((screenpos.y - mde.Model.Radius * modelScale) >= windowsize.Height)) ((screenpos.y + mde.Model.Radius * modelScale) <= 0.0f) || ((screenpos.y - mde.Model.Radius * modelScale) >= windowsize.Height))
continue; continue;
@ -1408,7 +1456,7 @@ namespace CodeImp.DoomBuilder.Rendering
graphics.Shaders.Things2D.ApplySettings(); graphics.Shaders.Things2D.ApplySettings();
// Draw // Draw
foreach(Mesh mesh in mde.Model.Meshes) mesh.DrawSubset(0); foreach (Mesh mesh in mde.Model.Meshes) mesh.DrawSubset(0);
} }
} }
@ -1435,49 +1483,22 @@ namespace CodeImp.DoomBuilder.Rendering
RenderThingsBatch(things, alpha, false, new PixelColor()); RenderThingsBatch(things, alpha, false, new PixelColor());
} }
public void RenderNiGHTSPath()
{
if (!General.Settings.RenderNiGHTSPath) return;
ICollection<Thing> things = General.Map.Map.Things;
List<Thing> axes = new List<Thing>();
List<Thing> axistransferlines = new List<Thing>();
List<Thing> waypoints = new List<Thing>();
foreach (Thing t in things)
{
int type = t.SRB2Type;
if (type == General.Map.FormatInterface.AxisType) axes.Add(t);
if (type == General.Map.FormatInterface.AxisTransferLineType) axistransferlines.Add(t);
if (type == General.Map.FormatInterface.WaypointType) waypoints.Add(t);
}
//Sort waypoints by angle
waypoints.Sort((x,y) => (x.AngleDoom.CompareTo(y.AngleDoom)));
//Sort by axis number and mare number.
axistransferlines.Sort((x, y) => (x.GetFlagsValue() | (x.Parameter)<<16).CompareTo((y.GetFlagsValue() | (y.Parameter) << 16)));
//Render (zoom tube) waypoint sequences. //Render (zoom tube) waypoint sequences.
public void RenderWaypoints()
{
int i = 0; int i = 0;
int size = waypoints.Count; int size = waypoints.Count;
int seqStart = 0; int seqStart = 0;
TextLabel[] sequencelabels = new TextLabel[256];
while (i < size) while (i < size)
{ {
int iNext = i + 1; int iNext = i + 1;
if (waypoints[i].AngleDoom % 256 == 0) // start of a new sequence? if (waypoints[i].AngleDoom % 256 == 0) // start of a new sequence?
{ {
seqStart = i; seqStart = i;
sequencelabels[waypoints[i].AngleDoom / 256] = new TextLabel(3) // create sequence ID label waypointlabel.Text = (waypoints[i].AngleDoom / 256).ToString();
{ waypointlabel.Left = waypoints[i].Position.x;
Text = (waypoints[i].AngleDoom / 256).ToString(), waypointlabel.Top = waypoints[i].Position.y;
AlignX = TextAlignmentX.Center, RenderText(waypointlabel);
AlignY = TextAlignmentY.Middle,
Color = General.Colors.WaypointColor,
Backcolor = General.Colors.Background,
Scale = 16f,
TransformCoords = true,
Rectangle = new RectangleF(waypoints[i].Position.x, waypoints[i].Position.y, 0.0f, 0.0f)
};
} }
if (iNext < size && waypoints[iNext].AngleDoom == waypoints[i].AngleDoom + 1) if (iNext < size && waypoints[iNext].AngleDoom == waypoints[i].AngleDoom + 1)
{ {
@ -1502,13 +1523,134 @@ namespace CodeImp.DoomBuilder.Rendering
} }
i = iNext; i = iNext;
} }
}
for (i = 0; i < 256; i++) public void RenderPolyobjects()
if (sequencelabels[i] != null) RenderText(sequencelabels[i]); {
starts = new Vector2D[4096];
ends = new Vector2D[4096];
int i = 0, j = 0, k = 0, v = 0;
while (i < polyanchors.Count && j < polyspawns.Count && k < firstlines.Count)
{
while (j + 1 < polyspawns.Count && polyanchors[i].AngleDoom > polyspawns[j].AngleDoom)
{
// Mark invalid spawnpoints
spawnlabel.Text = polyspawns[j].AngleDoom.ToString();
spawnlabel.Left = polyspawns[j].Position.x;
spawnlabel.Top = polyspawns[j].Position.y;
spawnlabel.Color = PixelColor.FromColor(Color.Red);
RenderText(spawnlabel);
j++;
}
while (k+1 < firstlines.Count && polyanchors[i].AngleDoom > firstlines[k].Tag) k++;
Sector s = null;
if (polyanchors[i].AngleDoom == firstlines[k].Tag)
s = firstlines[k].Back.Sector;
if (polyanchors[i].AngleDoom == polyspawns[j].AngleDoom && s != null)
{
while (j+1 < polyspawns.Count && polyspawns[j].AngleDoom == polyspawns[j + 1].AngleDoom)
{
spawnlabel.Text = polyspawns[j].AngleDoom.ToString();
spawnlabel.Left = polyspawns[j].Position.x;
spawnlabel.Top = polyspawns[j].Position.y;
spawnlabel.Color = PixelColor.FromColor(Color.Red);
RenderText(spawnlabel);
j++;
}
float xdiff = polyanchors[i].Position.x - polyspawns[j].Position.x;
float ydiff = polyanchors[i].Position.y - polyspawns[j].Position.y;
foreach (Sidedef side in s.Sidedefs)
{
Vector2D start = side.Line.Start.Position;
Vector2D end = side.Line.End.Position;
start.x -= xdiff;
start.y -= ydiff;
end.x -= xdiff;
end.y -= ydiff;
starts[v] = start;
ends[v] = end;
v++;
}
anchorlabel.Color = General.Colors.GetNiGHTSColor(8);
spawnlabel.Color = General.Colors.GetNiGHTSColor(7);
spawnlabel.Text = polyspawns[j].AngleDoom.ToString();
spawnlabel.Left = polyspawns[j].Position.x;
spawnlabel.Top = polyspawns[j].Position.y;
RenderText(spawnlabel);
}
else
{
// Mark invalid points
anchorlabel.Color = PixelColor.FromColor(Color.Red);
}
anchorlabel.Text = polyanchors[i].AngleDoom.ToString();
anchorlabel.Left = polyanchors[i].Position.x;
anchorlabel.Top = polyanchors[i].Position.y;
RenderText(anchorlabel);
i++;
}
RenderLines(starts, ends, 1.0f, General.Colors.GetNiGHTSColor(7), true);
}
public void RenderNiGHTSPath()
{
if (!General.Settings.RenderNiGHTSPath)
{
return;
}
axes = new List<Thing>();
axistransferlines = new List<Thing>();
waypoints = new List<Thing>();
polyanchors = new List<Thing>();
polyspawns = new List<Thing>();
firstlines = new List<Linedef>();
foreach (Thing t in General.Map.Map.Things)
{
int type = t.SRB2Type;
if (type == General.Map.FormatInterface.AxisType) axes.Add(t);
if (type == General.Map.FormatInterface.AxisTransferLineType) axistransferlines.Add(t);
if (type == General.Map.FormatInterface.WaypointType) waypoints.Add(t);
if (type == 760) polyanchors.Add(t);
if (type == 761 || type == 762) polyspawns.Add(t);
}
foreach (Linedef l in General.Map.Map.Linedefs)
{
if (l.Action == 20) firstlines.Add(l);
}
//Sort waypoints by angle
waypoints.Sort((x,y) => (x.AngleDoom.CompareTo(y.AngleDoom)));
// Sort polyobject stuff by "angle"/tag
polyanchors.Sort((x, y) => (x.AngleDoom.CompareTo(y.AngleDoom)));
polyspawns.Sort((x, y) => (x.AngleDoom.CompareTo(y.AngleDoom)));
firstlines.Sort((x, y) => (x.Tag.CompareTo(y.Tag)));
//Sort by axis number and mare number.
axistransferlines.Sort((x, y) => (x.GetFlagsValue() | (x.Parameter)<<16).CompareTo((y.GetFlagsValue() | (y.Parameter) << 16)));
//Render zoom tubes and polyobjects
RenderWaypoints();
RenderPolyobjects();
//Render axis transfer lines. //Render axis transfer lines.
i = 0; int i = 0;
size = axistransferlines.Count; int size = axistransferlines.Count;
while (i < size - 1) while (i < size - 1)
{ {
int iNext = i; int iNext = i;