Updated, Textures Browser: texture name length is now taken into account when calculating the width of texture items.

Internal: moved thing helper shapes creation logic from ThingsMode to LinksCollector.
This commit is contained in:
m-x-d 2017-01-09 01:04:55 +03:00
parent a41058bef9
commit 2b24ce3c25
10 changed files with 278 additions and 236 deletions

View file

@ -1,6 +1,7 @@
#region ================== Namespaces
using System;
using System.Drawing;
using CodeImp.DoomBuilder.Data;
#endregion
@ -12,6 +13,7 @@ namespace CodeImp.DoomBuilder.Controls
#region ================== Variables
private string groupname;
private int groupnamewidth;
#endregion
@ -19,6 +21,7 @@ namespace CodeImp.DoomBuilder.Controls
public override bool IsPreviewLoaded { get { return true; } }
public override string TextureName { get { return groupname; } }
public override int TextureNameWidth { get { return groupnamewidth; } }
#endregion
@ -43,6 +46,9 @@ namespace CodeImp.DoomBuilder.Controls
default:
throw new NotImplementedException("Unsupported ItemType");
}
// Calculate name width
this.groupnamewidth = (int)Math.Ceiling(General.Interface.MeasureString(this.groupname, SystemFonts.MessageBoxFont, 10000, StringFormat.GenericTypographic).Width);
}
#endregion

View file

@ -351,7 +351,7 @@ namespace CodeImp.DoomBuilder.Controls
objectname.CharacterCasing = (uselongtexturenames ? CharacterCasing.Normal : CharacterCasing.Upper);
foreach(var item in items) item.ShowFullName = uselongtexturenames;
list.Refresh();
list.UpdateRectangles();
list.Focus();
}
}

View file

@ -29,6 +29,8 @@ namespace CodeImp.DoomBuilder.Controls
private bool showfullname;
protected ImageBrowserItemType itemtype;
private string tooltip;
private int namewidth;
private int shortnamewidth;
#endregion
@ -39,6 +41,7 @@ namespace CodeImp.DoomBuilder.Controls
public virtual bool IsPreviewLoaded { get { return icon.IsPreviewLoaded; } }
public bool ShowFullName { set { showfullname = value; } }
public virtual string TextureName { get { return (showfullname ? icon.Name : icon.ShortName); } }
public virtual int TextureNameWidth { get { return (showfullname ? namewidth : shortnamewidth); } }
public string ToolTip { get { return tooltip; } }
#endregion
@ -55,6 +58,10 @@ namespace CodeImp.DoomBuilder.Controls
this.showfullname = showfullname; //mxd
this.imageloaded = icon.IsPreviewLoaded; //mxd
this.tooltip = tooltip; //mxd
//mxd. Calculate names width
this.namewidth = (int)Math.Ceiling(General.Interface.MeasureString(icon.Name, SystemFonts.MessageBoxFont, 10000, StringFormat.GenericTypographic).Width);
this.shortnamewidth = (int)Math.Ceiling(General.Interface.MeasureString(icon.ShortName, SystemFonts.MessageBoxFont, 10000, StringFormat.GenericTypographic).Width);
}
#endregion

View file

@ -464,7 +464,7 @@ namespace CodeImp.DoomBuilder.Controls
if(selection.Count > 0) ScrollToItem(selection[0]);
}
private void UpdateRectangles()
internal void UpdateRectangles()
{
int w = ClientRectangle.Width - scrollbar.Width;
const int pad = 2;
@ -479,7 +479,7 @@ namespace CodeImp.DoomBuilder.Controls
Image preview = GetPreview(ti, imagesize);
int rw = w - cx;
int wid = (imagesize > 0 ? imagesize : preview.Width) + pad + pad;
int wid = Math.Max((imagesize > 0 ? imagesize : preview.Width), ti.TextureNameWidth) + pad + pad;
int hei = (imagesize > 0 ? imagesize : preview.Height) + pad + pad + font;
if(rw < wid)

View file

@ -108,6 +108,7 @@ namespace CodeImp.DoomBuilder.Data
// Load image if needed
if(!img.IsImageLoaded) img.LoadImage();
int imagewidth, imageheight;
Bitmap image = img.GetBitmap(); //mxd
if(!img.LoadFailed)
{
imagewidth = img.Width;
@ -115,7 +116,7 @@ namespace CodeImp.DoomBuilder.Data
}
else
{
Size size = img.GetBitmap().Size; //mxd
Size size = image.Size; //mxd
imagewidth = size.Width;
imageheight = size.Height;
}
@ -129,31 +130,40 @@ namespace CodeImp.DoomBuilder.Data
if(previewwidth < 1) previewwidth = 1;
if(previewheight < 1) previewheight = 1;
// Make new image
Bitmap preview = new Bitmap(previewwidth, previewheight, IMAGE_FORMAT);
Graphics g = Graphics.FromImage(preview);
g.PageUnit = GraphicsUnit.Pixel;
//g.CompositingQuality = CompositingQuality.HighQuality; //mxd
g.InterpolationMode = InterpolationMode.NearestNeighbor;
//g.SmoothingMode = SmoothingMode.HighQuality; //mxd
g.PixelOffsetMode = PixelOffsetMode.None;
//g.Clear(Color.Transparent); //mxd
// Draw image onto atlas
Rectangle atlasrect = new Rectangle(0, 0, previewwidth, previewheight);
RectangleF imgrect = General.MakeZoomedRect(new Size(imagewidth, imageheight), atlasrect);
if(imgrect.Width < 1.0f)
//mxd. Expected and actual image sizes and format match?
Bitmap preview;
if(previewwidth == imagewidth && previewheight == imageheight && image.PixelFormat == IMAGE_FORMAT)
{
imgrect.X -= 0.5f - imgrect.Width * 0.5f;
imgrect.Width = 1.0f;
preview = new Bitmap(image);
}
if(imgrect.Height < 1.0f)
else
{
imgrect.Y -= 0.5f - imgrect.Height * 0.5f;
imgrect.Height = 1.0f;
// Make new image
preview = new Bitmap(previewwidth, previewheight, IMAGE_FORMAT);
Graphics g = Graphics.FromImage(preview);
g.PageUnit = GraphicsUnit.Pixel;
//g.CompositingQuality = CompositingQuality.HighQuality; //mxd
g.InterpolationMode = InterpolationMode.NearestNeighbor;
//g.SmoothingMode = SmoothingMode.HighQuality; //mxd
g.PixelOffsetMode = PixelOffsetMode.None;
//g.Clear(Color.Transparent); //mxd
// Draw image onto atlas
Rectangle atlasrect = new Rectangle(0, 0, previewwidth, previewheight);
RectangleF imgrect = General.MakeZoomedRect(new Size(imagewidth, imageheight), atlasrect);
if(imgrect.Width < 1.0f)
{
imgrect.X -= 0.5f - imgrect.Width * 0.5f;
imgrect.Width = 1.0f;
}
if(imgrect.Height < 1.0f)
{
imgrect.Y -= 0.5f - imgrect.Height * 0.5f;
imgrect.Height = 1.0f;
}
g.DrawImage(image, imgrect);
g.Dispose();
}
g.DrawImage(img.GetBitmap(), imgrect);
g.Dispose();
// Unload image if no longer needed
if(!img.IsReferenced) img.UnloadImage();

View file

@ -1,4 +1,6 @@
using System;
#region ================== Namespaces
using System;
using System.Collections.Generic;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Map;
@ -6,10 +8,14 @@ using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.VisualModes;
#endregion
namespace CodeImp.DoomBuilder.GZBuilder.Data
{
public static class LinksCollector
public static class LinksCollector
{
#region ================== SpecialThings
private class SpecialThings
{
public readonly Dictionary<int, List<Thing>> PatrolPoints; // PatrolPoint tag, list of PatrolPoints
@ -34,6 +40,10 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
}
}
#endregion
#region ================== PathNode
private class PathNode
{
private readonly Thing thing;
@ -74,7 +84,17 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
}
}
public static IEnumerable<Line3D> MakeCircleLines(Vector3D pos, PixelColor color, float radius, int numsides)
#endregion
#region ================== Constants
private const int CIRCLE_SIDES = 24;
#endregion
#region ================== Shape creation methods
private static IEnumerable<Line3D> MakeCircleLines(Vector3D pos, PixelColor color, float radius, int numsides)
{
List<Line3D> result = new List<Line3D>(numsides);
Vector3D start = new Vector3D(pos.x, pos.y + radius, pos.z);
@ -90,7 +110,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
return result;
}
public static IEnumerable<Line3D> MakeRectangleLines(Vector3D pos, PixelColor color, float size)
private static IEnumerable<Line3D> MakeRectangleLines(Vector3D pos, PixelColor color, float size)
{
float halfsize = size / 2;
Vector3D tl = new Vector3D(pos.x - halfsize, pos.y - halfsize, pos.z);
@ -105,15 +125,21 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
new Line3D(bl, br, color, false),
new Line3D(bl, tl, color, false),
};
}
public static List<Line3D> GetThingLinks(IEnumerable<Thing> things) { return GetThingLinks(things, null); }
public static List<Line3D> GetThingLinks(IEnumerable<Thing> things, VisualBlockMap blockmap)
{
return GetThingLinks(GetSpecialThings(things, blockmap), blockmap);
}
private static SpecialThings GetSpecialThings(IEnumerable<Thing> things, VisualBlockMap blockmap)
#endregion
#region ================== GetHelperShapes
public static List<Line3D> GetHelperShapes(ICollection<Thing> things) { return GetHelperShapes(things, null); }
public static List<Line3D> GetHelperShapes(ICollection<Thing> things, VisualBlockMap blockmap)
{
var lines = GetHelperShapes(GetSpecialThings(things, blockmap), blockmap);
lines.AddRange(GetThingArgumentShapes(things, blockmap, CIRCLE_SIDES));
return lines;
}
private static SpecialThings GetSpecialThings(ICollection<Thing> things, VisualBlockMap blockmap)
{
SpecialThings result = new SpecialThings();
@ -189,7 +215,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
return result;
}
private static List<Line3D> GetThingLinks(SpecialThings result, VisualBlockMap blockmap)
private static List<Line3D> GetHelperShapes(SpecialThings result, VisualBlockMap blockmap)
{
var lines = new List<Line3D>();
var actormovertargets = new Dictionary<int, List<Thing>>();
@ -403,9 +429,19 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
}
}
// Process arg helpers
const int numsides = 24;
foreach(Thing t in General.Map.ThingsFilter.VisibleThings)
return lines;
}
#endregion
#region ================== GetThingArgumentShapes
// Create argument value/min/max shapes
private static List<Line3D> GetThingArgumentShapes(ICollection<Thing> things, VisualBlockMap blockmap, int numsides)
{
var lines = new List<Line3D>();
foreach(Thing t in things)
{
if(t.Action != 0) continue;
ThingTypeInfo tti = General.Map.Data.GetThingInfoEx(t.Type);
@ -416,20 +452,27 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
for(int i = 0; i < t.Args.Length; i++)
{
if(t.Args[i] != 0 && tti.Args[i].RenderStyle != ArgumentInfo.ArgumentRenderStyle.NONE)
if(t.Args[i] == 0) continue; // Avoid visual noise
var a = tti.Args[i]; //TODO: can this be null?
switch(a.RenderStyle)
{
switch(tti.Args[i].RenderStyle)
{
case ArgumentInfo.ArgumentRenderStyle.CIRCLE:
lines.AddRange(MakeCircleLines(pos, tti.Args[i].RenderColor, t.Args[i], numsides));
break;
case ArgumentInfo.ArgumentRenderStyle.CIRCLE:
lines.AddRange(MakeCircleLines(pos, a.RenderColor, t.Args[i], numsides));
if(a.MinRange > 0) lines.AddRange(MakeCircleLines(pos, a.MinRangeColor, a.MinRange, numsides));
if(a.MaxRange > 0) lines.AddRange(MakeCircleLines(pos, a.MaxRangeColor, a.MaxRange, numsides));
break;
case ArgumentInfo.ArgumentRenderStyle.RECTANGLE:
lines.AddRange(MakeRectangleLines(pos, tti.Args[i].RenderColor, t.Args[i]));
break;
case ArgumentInfo.ArgumentRenderStyle.RECTANGLE:
lines.AddRange(MakeRectangleLines(pos, a.RenderColor, t.Args[i]));
if(a.MinRange > 0) lines.AddRange(MakeRectangleLines(pos, a.MinRangeColor, a.MinRange));
if(a.MaxRange > 0) lines.AddRange(MakeRectangleLines(pos, a.MaxRangeColor, a.MaxRange));
break;
default: throw new NotImplementedException("Unknown ArgumentRenderStyle");
}
case ArgumentInfo.ArgumentRenderStyle.NONE:
break;
default: throw new NotImplementedException("Unknown ArgumentRenderStyle");
}
}
}
@ -437,6 +480,150 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
return lines;
}
#endregion
#region ================== GetDynamicLightShapes
public static List<Line3D> GetDynamicLightShapes(IEnumerable<Thing> things, bool highlight)
{
List<Line3D> circles = new List<Line3D>();
if(General.Map.DOOM) return circles;
const int linealpha = 128;
foreach(Thing t in things)
{
int lightid = Array.IndexOf(GZGeneral.GZ_LIGHTS, t.Type);
if(lightid == -1) continue;
// TODO: this basically duplicates VisualThing.UpdateLight()...
// Determine light radiii
int primaryradius;
int secondaryradius = 0;
if(lightid < GZGeneral.GZ_LIGHT_TYPES[2]) //if it's gzdoom light
{
int n;
if(lightid < GZGeneral.GZ_LIGHT_TYPES[0]) n = 0;
else if(lightid < GZGeneral.GZ_LIGHT_TYPES[1]) n = 10;
else n = 20;
DynamicLightType lightType = (DynamicLightType)(t.Type - 9800 - n);
if(lightType == DynamicLightType.SECTOR)
{
if(t.Sector == null) t.DetermineSector();
int scaler = (t.Sector != null ? t.Sector.Brightness / 4 : 2);
primaryradius = t.Args[3] * scaler;
}
else
{
primaryradius = t.Args[3] * 2; //works... that.. way in GZDoom
if(lightType > 0) secondaryradius = t.Args[4] * 2;
}
}
else //it's one of vavoom lights
{
primaryradius = t.Args[0] * 8;
}
// Check radii...
if(primaryradius < 1 && secondaryradius < 1) continue;
// Determine light color
PixelColor color;
if(highlight)
{
color = General.Colors.Highlight.WithAlpha(linealpha);
}
else
{
switch(t.Type)
{
case 1502: // Vavoom light
color = new PixelColor(linealpha, 255, 255, 255);
break;
case 1503: // Vavoom colored light
color = new PixelColor(linealpha, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]);
break;
default:
color = new PixelColor(linealpha, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]);
break;
}
}
// Add lines if visible
if(primaryradius > 0) circles.AddRange(MakeCircleLines(t.Position, color, primaryradius, CIRCLE_SIDES));
if(secondaryradius > 0) circles.AddRange(MakeCircleLines(t.Position, color, secondaryradius, CIRCLE_SIDES));
}
// Done
return circles;
}
#endregion
#region ================== GetAmbientSoundShapes
public static List<Line3D> GetAmbientSoundShapes(IEnumerable<Thing> things, bool highlight)
{
List<Line3D> circles = new List<Line3D>();
const int linealpha = 128;
foreach(Thing t in things)
{
ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type);
if(info == null) continue;
float minradius, maxradius;
if(info.AmbientSound != null)
{
minradius = info.AmbientSound.MinimumRadius;
maxradius = info.AmbientSound.MaximumRadius;
}
else if(!General.Map.DOOM && (info.ClassName == "AmbientSound" || info.ClassName == "AmbientSoundNoGravity"))
{
//arg0: ambient slot
//arg1: (optional) sound volume, in percent. 1 is nearly silent, 100 and above are full volume. If left to zero, full volume is also used.
//arg2: (optional) minimum distance, in map units, at which volume attenuation begins. Note that arg3 must also be set. If both are left to zero, normal rolloff is used instead.
//arg3: (optional) maximum distance, in map units, at which the sound can be heard. If left to zero or lower than arg2, normal rolloff is used instead.
//arg4: (optional) scalar by which to multiply the values of arg2 and arg3. If left to zero, no multiplication takes place.
if(t.Args[0] == 0 || !General.Map.Data.AmbientSounds.ContainsKey(t.Args[0]))
continue;
// Use custom radii?
if(t.Args[2] > 0 && t.Args[3] > 0 && t.Args[3] > t.Args[2])
{
minradius = t.Args[2] * (t.Args[4] != 0 ? t.Args[4] : 1.0f);
maxradius = t.Args[3] * (t.Args[4] != 0 ? t.Args[4] : 1.0f);
}
else
{
minradius = General.Map.Data.AmbientSounds[t.Args[0]].MinimumRadius;
maxradius = General.Map.Data.AmbientSounds[t.Args[0]].MaximumRadius;
}
}
else
{
continue;
}
// Determine color
PixelColor color = (highlight ? General.Colors.Highlight.WithAlpha(linealpha) : t.Color.WithAlpha(linealpha));
// Add lines if visible
if(minradius > 0) circles.AddRange(MakeCircleLines(t.Position, color, minradius, CIRCLE_SIDES));
if(maxradius > 0) circles.AddRange(MakeCircleLines(t.Position, color, maxradius, CIRCLE_SIDES));
}
return circles;
}
#endregion
#region ================== Utility
// Taken from Xabis' "curved interpolation points paths" patch.
private static float SplineLerp(float u, float p1, float p2, float p3, float p4)
{
@ -459,5 +646,7 @@ namespace CodeImp.DoomBuilder.GZBuilder.Data
if(thing.Sector != null) height += thing.Sector.FloorHeight;
return height;
}
#endregion
}
}

View file

@ -78,6 +78,7 @@ namespace CodeImp.DoomBuilder.Windows
void SetCursor(Cursor cursor);
void MessageBeep(MessageBeepType type);
SizeF MeasureString(string text, Font font); //mxd
SizeF MeasureString(string text, Font font, int width, StringFormat format); //mxd
/// <summary>
/// This moves the focus to the editing display.

View file

@ -4393,6 +4393,11 @@ namespace CodeImp.DoomBuilder.Windows
return graphics.MeasureString(text, font);
}
public SizeF MeasureString(string text, Font font, int width, StringFormat format)
{
return graphics.MeasureString(text, font, width, format);
}
#endregion
}
}

View file

@ -259,7 +259,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
eventlines.AddRange(dynamiclightshapes);
if(highlighted != null && !highlighted.IsDisposed)
eventlines.AddRange(GetDynamicLightShapes(new List<Thing> { highlighted } ));
eventlines.AddRange(LinksCollector.GetDynamicLightShapes(new List<Thing> { highlighted }, true));
}
//mxd. Ambient sound radii
@ -267,7 +267,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
eventlines.AddRange(ambientsoundshapes);
if(highlighted != null && !highlighted.IsDisposed)
eventlines.AddRange(GetAmbientSoundShapes(new List<Thing> { highlighted }));
eventlines.AddRange(LinksCollector.GetAmbientSoundShapes(new List<Thing> { highlighted }, true));
}
//mxd
@ -1073,190 +1073,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd
private void UpdateHelperObjects()
{
// Update event lines
persistenteventlines = LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings);
// Update event lines and argument shapes
persistenteventlines = LinksCollector.GetHelperShapes(General.Map.ThingsFilter.VisibleThings);
// Update light radii
dynamiclightshapes = GetDynamicLightShapes(General.Map.Map.Things);
dynamiclightshapes = LinksCollector.GetDynamicLightShapes(General.Map.ThingsFilter.VisibleThings, false);
// Update ambient sound radii
ambientsoundshapes = GetAmbientSoundShapes(General.Map.Map.Things);
// Update argument range shapes
persistenteventlines.AddRange(GetArgumentRangeShapes(General.Map.Map.Things));
}
//mxd
private List<Line3D> GetDynamicLightShapes(IEnumerable<Thing> things)
{
List<Line3D> circles = new List<Line3D>();
if(General.Map.DOOM) return circles;
const int linealpha = 128;
const int numsides = 24;
foreach(Thing t in things)
{
int lightid = Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, t.Type);
if(lightid == -1) continue;
// TODO: this basically duplicates VisualThing.UpdateLight()...
// Determine light radiii
int primaryradius;
int secondaryradius = 0;
if(lightid < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[2]) //if it's gzdoom light
{
int n;
if(lightid < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[0]) n = 0;
else if(lightid < GZBuilder.GZGeneral.GZ_LIGHT_TYPES[1]) n = 10;
else n = 20;
DynamicLightType lightType = (DynamicLightType)(t.Type - 9800 - n);
if(lightType == DynamicLightType.SECTOR)
{
if(t.Sector == null) t.DetermineSector();
int scaler = (t.Sector != null ? t.Sector.Brightness / 4 : 2);
primaryradius = t.Args[3] * scaler;
}
else
{
primaryradius = t.Args[3] * 2; //works... that.. way in GZDoom
if(lightType > 0) secondaryradius = t.Args[4] * 2;
}
}
else //it's one of vavoom lights
{
primaryradius = t.Args[0] * 8;
}
// Check radii...
if(primaryradius < 1 && secondaryradius < 1) continue;
// Determine light color
PixelColor color;
if(t == highlighted)
{
color = General.Colors.Highlight.WithAlpha(linealpha);
}
else
{
switch(t.Type)
{
case 1502: // Vavoom light
color = new PixelColor(linealpha, 255, 255, 255);
break;
case 1503: // Vavoom colored light
color = new PixelColor(linealpha, (byte)t.Args[1], (byte)t.Args[2], (byte)t.Args[3]);
break;
default:
color = new PixelColor(linealpha, (byte)t.Args[0], (byte)t.Args[1], (byte)t.Args[2]);
break;
}
}
// Add lines if visible
if(primaryradius > 0) circles.AddRange(LinksCollector.MakeCircleLines(t.Position, color, primaryradius, numsides));
if(secondaryradius > 0) circles.AddRange(LinksCollector.MakeCircleLines(t.Position, color, secondaryradius, numsides));
}
// Done
return circles;
}
//mxd
private List<Line3D> GetAmbientSoundShapes(IEnumerable<Thing> things)
{
List<Line3D> circles = new List<Line3D>();
const int linealpha = 128;
const int numsides = 24;
foreach(Thing t in things)
{
ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type);
if(info == null) continue;
float minradius, maxradius;
if(info.AmbientSound != null)
{
minradius = info.AmbientSound.MinimumRadius;
maxradius = info.AmbientSound.MaximumRadius;
}
else if(!General.Map.DOOM && (info.ClassName == "AmbientSound" || info.ClassName == "AmbientSoundNoGravity"))
{
//arg0: ambient slot
//arg1: (optional) sound volume, in percent. 1 is nearly silent, 100 and above are full volume. If left to zero, full volume is also used.
//arg2: (optional) minimum distance, in map units, at which volume attenuation begins. Note that arg3 must also be set. If both are left to zero, normal rolloff is used instead.
//arg3: (optional) maximum distance, in map units, at which the sound can be heard. If left to zero or lower than arg2, normal rolloff is used instead.
//arg4: (optional) scalar by which to multiply the values of arg2 and arg3. If left to zero, no multiplication takes place.
if(t.Args[0] == 0 || !General.Map.Data.AmbientSounds.ContainsKey(t.Args[0]))
continue;
// Use custom radii?
if(t.Args[2] > 0 && t.Args[3] > 0 && t.Args[3] > t.Args[2])
{
minradius = t.Args[2] * (t.Args[4] != 0 ? t.Args[4] : 1.0f);
maxradius = t.Args[3] * (t.Args[4] != 0 ? t.Args[4] : 1.0f);
}
else
{
minradius = General.Map.Data.AmbientSounds[t.Args[0]].MinimumRadius;
maxradius = General.Map.Data.AmbientSounds[t.Args[0]].MaximumRadius;
}
}
else
{
continue;
}
// Determine color
PixelColor color = (t == highlighted ? General.Colors.Highlight.WithAlpha(linealpha) : t.Color.WithAlpha(linealpha));
// Add lines if visible
if(minradius > 0) circles.AddRange(LinksCollector.MakeCircleLines(t.Position, color, minradius, numsides));
if(maxradius > 0) circles.AddRange(LinksCollector.MakeCircleLines(t.Position, color, maxradius, numsides));
}
return circles;
}
private List<Line3D> GetArgumentRangeShapes(IEnumerable<Thing> things)
{
List<Line3D> lines = new List<Line3D>();
const int numsides = 24;
foreach(Thing t in things)
{
ThingTypeInfo info = General.Map.Data.GetThingInfoEx(t.Type);
if(info == null) continue;
// Process argument based range finders
for(int i = 0; i < t.Args.Length; i++)
{
if(t.Args[i] == 0) continue; // Avoid visual noise
var a = info.Args[i];
switch(a.RenderStyle)
{
case ArgumentInfo.ArgumentRenderStyle.CIRCLE:
if(a.MinRange > 0) lines.AddRange(LinksCollector.MakeCircleLines(t.Position, a.MinRangeColor, a.MinRange, numsides));
if(a.MaxRange > 0) lines.AddRange(LinksCollector.MakeCircleLines(t.Position, a.MaxRangeColor, a.MaxRange, numsides));
break;
case ArgumentInfo.ArgumentRenderStyle.RECTANGLE:
if(a.MinRange > 0) lines.AddRange(LinksCollector.MakeRectangleLines(t.Position, a.MinRangeColor, a.MinRange));
if(a.MaxRange > 0) lines.AddRange(LinksCollector.MakeRectangleLines(t.Position, a.MaxRangeColor, a.MaxRange));
break;
case ArgumentInfo.ArgumentRenderStyle.NONE:break;
default: throw new NotImplementedException("Unknown ArgumentRenderStyle");
}
}
}
return lines;
ambientsoundshapes = LinksCollector.GetAmbientSoundShapes(General.Map.ThingsFilter.VisibleThings, false);
}
#endregion

View file

@ -518,7 +518,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
//mxd. Update event lines (still better than updating them on every frame redraw)
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap));
renderer.SetEventLines(LinksCollector.GetHelperShapes(General.Map.ThingsFilter.VisibleThings, blockmap));
}
//mxd
@ -1062,7 +1062,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
RebuildElementData();
//mxd. Update event lines
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap));
renderer.SetEventLines(LinksCollector.GetHelperShapes(General.Map.ThingsFilter.VisibleThings, blockmap));
}
// When returning to another mode
@ -3159,7 +3159,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Map.ThingsFilter.Update();
// Update event lines
renderer.SetEventLines(LinksCollector.GetThingLinks(General.Map.ThingsFilter.VisibleThings, blockmap));
renderer.SetEventLines(LinksCollector.GetHelperShapes(General.Map.ThingsFilter.VisibleThings, blockmap));
}
//mxd. We'll just use currently selected objects