mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 22:41:46 +00:00
Sectors, Linedefs, Things modes: optimized text label rendering.
Fixed, Things mode: in some cases selection labels were not updated after editing a thing. Fixed, Things mode: selection labels were positioned incorrectly on things with FixedSize setting. Fixed, Sectors mode: fixed a crash when selecting self-referencing sector when selection labels were enabled. Fixed, Visual mode: in some cases Auto-align texture actions were not working when "use long texture names" Map Options setting was enabled. Fixed, MD2/MD3 loader: available animation frames upper bound check was performed incorrectly, which would cause a crash in some very special cases. Fixed, Game configurations: most Hexen/ZDoom teleport actions use TeleportDests as teleport targets, not MapSpots.
This commit is contained in:
parent
a4428cf244
commit
ee12da96a1
13 changed files with 174 additions and 121 deletions
|
@ -1453,9 +1453,9 @@ teleport
|
||||||
|
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Target MapSpot Tag";
|
title = "Target Teleport Dest. Tag";
|
||||||
type = 14;
|
type = 14;
|
||||||
targetclasses = "MapSpot,MapSpotGravity";
|
targetclasses = "TeleportDest,TeleportDest2,TeleportDest3";
|
||||||
}
|
}
|
||||||
|
|
||||||
arg1
|
arg1
|
||||||
|
@ -1472,9 +1472,9 @@ teleport
|
||||||
|
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Target MapSpot Tag";
|
title = "Target Teleport Dest. Tag";
|
||||||
type = 14;
|
type = 14;
|
||||||
targetclasses = "MapSpot,MapSpotGravity";
|
targetclasses = "TeleportDest,TeleportDest2,TeleportDest3";
|
||||||
}
|
}
|
||||||
|
|
||||||
arg1
|
arg1
|
||||||
|
|
|
@ -2128,9 +2128,9 @@ zdoom
|
||||||
|
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Target MapSpot Tag";
|
title = "Target Teleport Dest. Tag";
|
||||||
type = 14;
|
type = 14;
|
||||||
targetclasses = "MapSpot,MapSpotGravity";
|
targetclasses = "TeleportDest,TeleportDest2,TeleportDest3";
|
||||||
}
|
}
|
||||||
arg1
|
arg1
|
||||||
{
|
{
|
||||||
|
@ -2196,17 +2196,20 @@ zdoom
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Thing Tag";
|
title = "Thing Tag";
|
||||||
|
tooltip = "The TID of the actor(s) to teleport.\nIf 0, teleports the activator only.";
|
||||||
type = 14;
|
type = 14;
|
||||||
}
|
}
|
||||||
arg1
|
arg1
|
||||||
{
|
{
|
||||||
title = "Source Teleport Dest. Tag";
|
title = "Source Teleport Dest. Tag";
|
||||||
type = 14;
|
type = 14;
|
||||||
|
targetclasses = "TeleportDest,TeleportDest2,TeleportDest3";
|
||||||
}
|
}
|
||||||
arg2
|
arg2
|
||||||
{
|
{
|
||||||
title = "Target Teleport Dest. Tag";
|
title = "Target Teleport Dest. Tag";
|
||||||
type = 14;
|
type = 14;
|
||||||
|
targetclasses = "TeleportDest,TeleportDest2,TeleportDest3";
|
||||||
}
|
}
|
||||||
arg3
|
arg3
|
||||||
{
|
{
|
||||||
|
@ -2233,15 +2236,15 @@ zdoom
|
||||||
}
|
}
|
||||||
arg1
|
arg1
|
||||||
{
|
{
|
||||||
title = "Source MapSpot Tag";
|
title = "Source Tag";
|
||||||
|
tooltip = "The spot relative to which to teleport.";
|
||||||
type = 14;
|
type = 14;
|
||||||
targetclasses = "MapSpot,MapSpotGravity";
|
|
||||||
}
|
}
|
||||||
arg2
|
arg2
|
||||||
{
|
{
|
||||||
title = "Target MapSpot Tag";
|
title = "Target Teleport Dest. Tag";
|
||||||
type = 14;
|
type = 14;
|
||||||
targetclasses = "MapSpot,MapSpotGravity";
|
targetclasses = "TeleportDest,TeleportDest2,TeleportDest3";
|
||||||
}
|
}
|
||||||
arg3
|
arg3
|
||||||
{
|
{
|
||||||
|
@ -2252,6 +2255,7 @@ zdoom
|
||||||
arg4
|
arg4
|
||||||
{
|
{
|
||||||
title = "Group Thing Tag";
|
title = "Group Thing Tag";
|
||||||
|
tooltip = "The TID of the thing(s) to teleport.\nIf 0, teleports all actors in the sector";
|
||||||
type = 14;
|
type = 14;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2262,9 +2266,9 @@ zdoom
|
||||||
|
|
||||||
arg0
|
arg0
|
||||||
{
|
{
|
||||||
title = "Target MapSpot Tag";
|
title = "Target Teleport Dest. Tag";
|
||||||
type = 14;
|
type = 14;
|
||||||
targetclasses = "MapSpot,MapSpotGravity";
|
targetclasses = "TeleportDest,TeleportDest2,TeleportDest3";
|
||||||
}
|
}
|
||||||
arg1
|
arg1
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,7 @@ namespace CodeImp.DoomBuilder
|
||||||
|
|
||||||
private DebugMessageType filters;
|
private DebugMessageType filters;
|
||||||
private static long starttime = -1;
|
private static long starttime = -1;
|
||||||
|
private static int counter;
|
||||||
private static DebugConsole me;
|
private static DebugConsole me;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -159,6 +160,24 @@ namespace CodeImp.DoomBuilder
|
||||||
starttime = -1;
|
starttime = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void IncrementCounter() { IncrementCounter(1); }
|
||||||
|
public static void IncrementCounter(int incrementby)
|
||||||
|
{
|
||||||
|
counter += incrementby;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ResetCounter(string message)
|
||||||
|
{
|
||||||
|
if(message.Contains("%"))
|
||||||
|
message = message.Replace("%", counter.ToString());
|
||||||
|
else
|
||||||
|
message = message.TrimEnd() + ": " + counter;
|
||||||
|
|
||||||
|
WriteLine(DebugMessageType.SPECIAL, message);
|
||||||
|
|
||||||
|
counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public static void StartProfiler()
|
public static void StartProfiler()
|
||||||
{
|
{
|
||||||
#if PROFILE
|
#if PROFILE
|
||||||
|
|
|
@ -590,7 +590,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
palette = null;
|
palette = null;
|
||||||
|
|
||||||
//mxd. Dispose models
|
//mxd. Dispose models
|
||||||
foreach(KeyValuePair<int, ModelData> i in modeldefentries) i.Value.Dispose();
|
foreach(ModelData md in modeldefentries.Values) md.Dispose();
|
||||||
|
|
||||||
// Dispose containers
|
// Dispose containers
|
||||||
foreach(DataReader c in containers) c.Dispose();
|
foreach(DataReader c in containers) c.Dispose();
|
||||||
|
@ -2052,7 +2052,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
public void ReloadModeldef()
|
public void ReloadModeldef()
|
||||||
{
|
{
|
||||||
if(modeldefentries != null)
|
if(modeldefentries != null)
|
||||||
foreach(KeyValuePair<int, ModelData> group in modeldefentries) group.Value.Dispose();
|
foreach(ModelData md in modeldefentries.Values) md.Dispose();
|
||||||
|
|
||||||
// Bail out when not supported by current game configuration
|
// Bail out when not supported by current game configuration
|
||||||
if(string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return;
|
if(string.IsNullOrEmpty(General.Map.Config.DecorateGames)) return;
|
||||||
|
@ -2105,15 +2105,13 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
General.MainWindow.DisplayReady();
|
General.MainWindow.DisplayReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. This parses modeldefs. Should be called after all DECORATE actors are parsed and actorsByClass dictionary created
|
//mxd. This parses modeldefs. Should be called after all DECORATE actors are parsed
|
||||||
private void LoadModeldefs(Dictionary<string, int> actorsbyclass)
|
private void LoadModeldefs(Dictionary<string, int> actorsbyclass)
|
||||||
{
|
{
|
||||||
//if no actors defined in DECORATE or game config...
|
// Abort if no classnames are defined in DECORATE or game config...
|
||||||
if(actorsbyclass.Count == 0) return;
|
if(actorsbyclass.Count == 0) return;
|
||||||
|
|
||||||
Dictionary<string, ModelData> modeldefentriesbyname = new Dictionary<string, ModelData>(StringComparer.Ordinal);
|
|
||||||
ModeldefParser parser = new ModeldefParser(actorsbyclass);
|
ModeldefParser parser = new ModeldefParser(actorsbyclass);
|
||||||
|
|
||||||
foreach(DataReader dr in containers)
|
foreach(DataReader dr in containers)
|
||||||
{
|
{
|
||||||
currentreader = dr;
|
currentreader = dr;
|
||||||
|
@ -2122,30 +2120,21 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
foreach(TextResourceData data in streams)
|
foreach(TextResourceData data in streams)
|
||||||
{
|
{
|
||||||
// Parse the data
|
// Parse the data
|
||||||
if(parser.Parse(data, true))
|
parser.Parse(data, true);
|
||||||
{
|
|
||||||
foreach(KeyValuePair<string, ModelData> g in parser.Entries)
|
|
||||||
{
|
|
||||||
if(modeldefentriesbyname.ContainsKey(g.Key))
|
|
||||||
General.ErrorLogger.Add(ErrorType.Warning, "Model definition for actor \"" + g.Key + "\" is double defined in \"" + Path.Combine(data.Source.Location.GetDisplayName(), data.Filename) + "\"");
|
|
||||||
|
|
||||||
modeldefentriesbyname[g.Key] = g.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Modeldefs are independable, so parsing fail in one file should not affect the others
|
// Modeldefs are independable, so parsing fail in one file should not affect the others
|
||||||
if(parser.HasError) parser.LogError();
|
if(parser.HasError) parser.LogError();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. Add to text resources collection
|
// Add to text resources collection
|
||||||
textresources[parser.ScriptType] = new HashSet<TextResource>(parser.TextResources.Values);
|
textresources[parser.ScriptType] = new HashSet<TextResource>(parser.TextResources.Values);
|
||||||
currentreader = null;
|
currentreader = null;
|
||||||
|
|
||||||
foreach(KeyValuePair<string, ModelData> e in modeldefentriesbyname)
|
foreach(KeyValuePair<string, ModelData> e in parser.Entries)
|
||||||
{
|
{
|
||||||
if(actorsbyclass.ContainsKey(e.Key))
|
if(actorsbyclass.ContainsKey(e.Key))
|
||||||
modeldefentries[actorsbyclass[e.Key]] = modeldefentriesbyname[e.Key];
|
modeldefentries[actorsbyclass[e.Key]] = parser.Entries[e.Key];
|
||||||
else if(!decorate.ActorsByClass.ContainsKey(e.Key))
|
else if(!decorate.ActorsByClass.ContainsKey(e.Key))
|
||||||
General.ErrorLogger.Add(ErrorType.Warning, "MODELDEF model \"" + e.Key + "\" doesn't match any Decorate actor class");
|
General.ErrorLogger.Add(ErrorType.Warning, "MODELDEF model \"" + e.Key + "\" doesn't match any Decorate actor class");
|
||||||
}
|
}
|
||||||
|
@ -2228,7 +2217,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. Add to text resources collection
|
// Add to text resources collection
|
||||||
textresources[parser.ScriptType] = new HashSet<TextResource>(parser.TextResources.Values);
|
textresources[parser.ScriptType] = new HashSet<TextResource>(parser.TextResources.Values);
|
||||||
currentreader = null;
|
currentreader = null;
|
||||||
|
|
||||||
|
|
|
@ -354,9 +354,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
int ofsEnd = br.ReadInt32(); //Relative offset from SURFACE_START to where the Surface object ends.
|
int ofsEnd = br.ReadInt32(); //Relative offset from SURFACE_START to where the Surface object ends.
|
||||||
|
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if(frame < 0 || frame > numFrames)
|
if(frame < 0 || frame >= numFrames)
|
||||||
{
|
{
|
||||||
return "invalid frame number! (frame number: " + frame + ", total frames: " + numFrames + ")";
|
return "frame " + frame + " is outside of model's frame range [0.." + (numFrames - 1) + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Polygons
|
// Polygons
|
||||||
|
@ -453,15 +453,9 @@ namespace CodeImp.DoomBuilder.GZBuilder.MD3
|
||||||
int num_frames = br.ReadInt32(); //Total number of frames
|
int num_frames = br.ReadInt32(); //Total number of frames
|
||||||
|
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
if(num_frames == 0)
|
if(frame < 0 || frame >= num_frames)
|
||||||
{
|
{
|
||||||
result.Errors = "model has 0 frames.";
|
result.Errors = "frame " + frame + " is outside of model's frame range [0.." + (num_frames - 1) + "]";
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(num_frames < frame || frame < 0)
|
|
||||||
{
|
|
||||||
result.Errors = "invalid target frame! (target frame: " + frame + ", total frames: " + num_frames + ")";
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1833,6 +1833,14 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
((sd.LongMiddleTexture == texturelongname) && (sd.MiddleRequired() || sd.LongMiddleTexture != MapSet.EmptyLongName)) ;
|
((sd.LongMiddleTexture == texturelongname) && (sd.MiddleRequired() || sd.LongMiddleTexture != MapSet.EmptyLongName)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd. This checks if any of the sidedef texture match the given textures
|
||||||
|
public static bool SidedefTextureMatch(Sidedef sd, HashSet<long> texturelongnames)
|
||||||
|
{
|
||||||
|
return (texturelongnames.Contains(sd.LongHighTexture) && sd.HighRequired()) ||
|
||||||
|
(texturelongnames.Contains(sd.LongLowTexture) && sd.LowRequired()) ||
|
||||||
|
(texturelongnames.Contains(sd.LongMiddleTexture) && (sd.MiddleRequired() || sd.LongMiddleTexture != MapSet.EmptyLongName));
|
||||||
|
}
|
||||||
|
|
||||||
//mxd. This converts offsetY from/to "normalized" offset for given wall part
|
//mxd. This converts offsetY from/to "normalized" offset for given wall part
|
||||||
public static float GetSidedefOffsetY(Sidedef side, VisualGeometryType part, float offset, float scaleY, bool fromNormalized)
|
public static float GetSidedefOffsetY(Sidedef side, VisualGeometryType part, float offset, float scaleY, bool fromNormalized)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1603,11 +1603,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
public void RenderText(TextLabel label)
|
public void RenderText(TextLabel label)
|
||||||
{
|
{
|
||||||
//mxd. Update the text if needed
|
//mxd. Update the text if needed
|
||||||
RectangleF bbox = label.Update(translatex, translatey, scale, -scale);
|
label.Update(translatex, translatey, scale, -scale);
|
||||||
|
if(label.SkipRendering) return;
|
||||||
//mxd. Have graphics / on screen?
|
|
||||||
if(label.VertexBuffer == null || (bbox.Right < 0.1f) || (bbox.Left > windowsize.Width) || (bbox.Bottom < 0.1f) || (bbox.Top > windowsize.Height))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Set renderstates for rendering
|
// Set renderstates for rendering
|
||||||
graphics.Device.SetRenderState(RenderState.CullMode, Cull.None);
|
graphics.Device.SetRenderState(RenderState.CullMode, Cull.None);
|
||||||
|
@ -1637,18 +1634,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
foreach(TextLabel label in labels)
|
foreach(TextLabel label in labels)
|
||||||
{
|
{
|
||||||
// Update the text if needed
|
// Update the text if needed
|
||||||
RectangleF bbox = label.Update(translatex, translatey, scale, -scale);
|
label.Update(translatex, translatey, scale, -scale);
|
||||||
|
if(label.SkipRendering) skipped++;
|
||||||
// Have graphics / on screen?
|
|
||||||
if(label.VertexBuffer == null || (bbox.Right < 0.1f) || (bbox.Left > windowsize.Width) || (bbox.Bottom < 0.1f) || (bbox.Top > windowsize.Height))
|
|
||||||
{
|
|
||||||
label.SkipRendering = true;
|
|
||||||
skipped++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
label.SkipRendering = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(labels.Count == skipped) return;
|
if(labels.Count == skipped) return;
|
||||||
|
|
|
@ -47,7 +47,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
// Text settings
|
// Text settings
|
||||||
private string text;
|
private string text;
|
||||||
private RectangleF rect;
|
private RectangleF rect;
|
||||||
private RectangleF absview; //mxd
|
|
||||||
private bool transformcoords;
|
private bool transformcoords;
|
||||||
private PixelColor color;
|
private PixelColor color;
|
||||||
private PixelColor backcolor;
|
private PixelColor backcolor;
|
||||||
|
@ -64,6 +63,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
private float lastscalex;
|
private float lastscalex;
|
||||||
private float lastscaley;
|
private float lastscaley;
|
||||||
|
|
||||||
|
//mxd. Rendering
|
||||||
|
private bool skiprendering;
|
||||||
|
|
||||||
// Disposing
|
// Disposing
|
||||||
private bool isdisposed;
|
private bool isdisposed;
|
||||||
|
|
||||||
|
@ -90,7 +92,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
public bool DrawBackground { get { return drawbg; } set { if(drawbg != value) { drawbg = value; textureupdateneeded = true; } } } //mxd
|
public bool DrawBackground { get { return drawbg; } set { if(drawbg != value) { drawbg = value; textureupdateneeded = true; } } } //mxd
|
||||||
internal Texture Texture { get { return texture; } } //mxd
|
internal Texture Texture { get { return texture; } } //mxd
|
||||||
internal VertexBuffer VertexBuffer { get { return textbuffer; } }
|
internal VertexBuffer VertexBuffer { get { return textbuffer; } }
|
||||||
internal bool SkipRendering; //mxd
|
internal bool SkipRendering { get { return skiprendering; } } //mxd
|
||||||
|
|
||||||
// Disposing
|
// Disposing
|
||||||
public bool IsDisposed { get { return isdisposed; } }
|
public bool IsDisposed { get { return isdisposed; } }
|
||||||
|
@ -117,6 +119,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
// Register as resource
|
// Register as resource
|
||||||
General.Map.Graphics.RegisterResource(this);
|
General.Map.Graphics.RegisterResource(this);
|
||||||
|
|
||||||
|
//mxd. Create the buffer
|
||||||
|
this.textbuffer = new VertexBuffer(General.Map.Graphics.Device, 4 * FlatVertex.Stride,
|
||||||
|
Usage.Dynamic | Usage.WriteOnly, VertexFormat.None, Pool.Default);
|
||||||
|
|
||||||
// We have no destructor
|
// We have no destructor
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
@ -143,7 +149,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
#region ================== Methods
|
#region ================== Methods
|
||||||
|
|
||||||
// This updates the text if needed
|
// This updates the text if needed
|
||||||
internal RectangleF Update(float translatex, float translatey, float scalex, float scaley)
|
internal void Update(float translatex, float translatey, float scalex, float scaley)
|
||||||
{
|
{
|
||||||
// Check if transformation changed and needs to be updated
|
// Check if transformation changed and needs to be updated
|
||||||
if(transformcoords && (translatex != lasttranslatex || translatey != lasttranslatey ||
|
if(transformcoords && (translatex != lasttranslatex || translatey != lasttranslatey ||
|
||||||
|
@ -156,6 +162,36 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
updateneeded = true;
|
updateneeded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update if needed
|
||||||
|
if(updateneeded || textureupdateneeded)
|
||||||
|
{
|
||||||
|
// Only build when there are any vertices
|
||||||
|
if(text.Length > 0)
|
||||||
|
{
|
||||||
|
// Transform?
|
||||||
|
RectangleF absview;
|
||||||
|
if(transformcoords)
|
||||||
|
{
|
||||||
|
// Calculate absolute coordinates
|
||||||
|
Vector2D lt = new Vector2D(rect.Left, rect.Top);
|
||||||
|
Vector2D rb = new Vector2D(rect.Right, rect.Bottom);
|
||||||
|
lt = lt.GetTransformed(translatex, translatey, scalex, scaley);
|
||||||
|
rb = rb.GetTransformed(translatex, translatey, scalex, scaley);
|
||||||
|
absview = new RectangleF((float)Math.Round(lt.x), (float)Math.Round(lt.y), rb.x - lt.x, rb.y - lt.y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Fixed coordinates
|
||||||
|
absview = rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
//mxd. Skip when not on screen...
|
||||||
|
RectangleF abssize = absview;
|
||||||
|
abssize.Inflate(textsize.Width / 2, textsize.Height / 2);
|
||||||
|
Size windowsize = General.Map.Graphics.RenderTarget.ClientSize;
|
||||||
|
skiprendering = (abssize.Right < 0.1f) || (abssize.Left > windowsize.Width) || (abssize.Bottom < 0.1f) || (abssize.Top > windowsize.Height);
|
||||||
|
if(skiprendering) return;
|
||||||
|
|
||||||
//mxd. Update texture if needed
|
//mxd. Update texture if needed
|
||||||
if(textureupdateneeded)
|
if(textureupdateneeded)
|
||||||
{
|
{
|
||||||
|
@ -180,28 +216,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
Pool.Managed, General.Map.Graphics.PostFilter, General.Map.Graphics.MipGenerateFilter, 0);
|
Pool.Managed, General.Map.Graphics.PostFilter, General.Map.Graphics.MipGenerateFilter, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update if needed
|
|
||||||
if(updateneeded || textureupdateneeded)
|
|
||||||
{
|
|
||||||
// Only build when there are any vertices
|
|
||||||
if(text.Length > 0)
|
|
||||||
{
|
|
||||||
// Transform?
|
|
||||||
if(transformcoords)
|
|
||||||
{
|
|
||||||
// Calculate absolute coordinates
|
|
||||||
Vector2D lt = new Vector2D(rect.Left, rect.Top);
|
|
||||||
Vector2D rb = new Vector2D(rect.Right, rect.Bottom);
|
|
||||||
lt = lt.GetTransformed(translatex, translatey, scalex, scaley);
|
|
||||||
rb = rb.GetTransformed(translatex, translatey, scalex, scaley);
|
|
||||||
absview = new RectangleF((float)Math.Round(lt.x), (float)Math.Round(lt.y), rb.x - lt.x, rb.y - lt.y);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Fixed coordinates
|
|
||||||
absview = rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Align the text horizontally
|
// Align the text horizontally
|
||||||
float beginx = 0;
|
float beginx = 0;
|
||||||
switch(alignx)
|
switch(alignx)
|
||||||
|
@ -220,14 +234,6 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
case TextAlignmentY.Bottom: beginy = absview.Y + absview.Height - textsize.Height; break;
|
case TextAlignmentY.Bottom: beginy = absview.Y + absview.Height - textsize.Height; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we have to make a new buffer?
|
|
||||||
if(textbuffer == null)
|
|
||||||
{
|
|
||||||
// Create the buffer
|
|
||||||
textbuffer = new VertexBuffer(General.Map.Graphics.Device, 4 * FlatVertex.Stride,
|
|
||||||
Usage.Dynamic | Usage.WriteOnly, VertexFormat.None, Pool.Default);
|
|
||||||
}
|
|
||||||
|
|
||||||
//mxd. Lock the buffer
|
//mxd. Lock the buffer
|
||||||
using(DataStream stream = textbuffer.Lock(0, 4 * FlatVertex.Stride, LockFlags.Discard | LockFlags.NoSystemLock))
|
using(DataStream stream = textbuffer.Lock(0, 4 * FlatVertex.Stride, LockFlags.Discard | LockFlags.NoSystemLock))
|
||||||
{
|
{
|
||||||
|
@ -241,16 +247,14 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No faces in polygon
|
// No faces in polygon
|
||||||
if(textbuffer != null) textbuffer.Dispose(); //mxd
|
|
||||||
textsize = new SizeF();
|
textsize = new SizeF();
|
||||||
|
skiprendering = true; //mxd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text updated
|
// Text updated
|
||||||
updateneeded = false;
|
updateneeded = false;
|
||||||
textureupdateneeded = false; //mxd
|
textureupdateneeded = false; //mxd
|
||||||
}
|
}
|
||||||
|
|
||||||
return absview; //mxd
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
|
|
|
@ -606,7 +606,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
if(requiredsize > group.Key.Labels[i].radius)
|
if(requiredsize > group.Key.Labels[i].radius)
|
||||||
{
|
{
|
||||||
requiredsize = (General.Interface.MeasureString(group.Value[1], l.Font).Width / 2) / renderer.Scale;
|
requiredsize = (General.Interface.MeasureString(group.Value[1], l.Font).Width / 2) / renderer.Scale;
|
||||||
l.Text = (requiredsize > group.Key.Labels[i].radius ? "+" : group.Value[1]);
|
if(requiredsize > group.Key.Labels[i].radius)
|
||||||
|
l.Text = (requiredsize > group.Key.Labels[i].radius * 4 ? string.Empty : "+");
|
||||||
|
else
|
||||||
|
l.Text = group.Value[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -197,6 +197,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
List<TextLabel> torender = new List<TextLabel>(orderedselection.Count);
|
List<TextLabel> torender = new List<TextLabel>(orderedselection.Count);
|
||||||
foreach(Sector s in orderedselection)
|
foreach(Sector s in orderedselection)
|
||||||
{
|
{
|
||||||
|
//mxd. Self-referencing (and probably some other) sectors don't have labels...
|
||||||
|
if(labels[s].Length == 0) continue;
|
||||||
|
|
||||||
// Render labels
|
// Render labels
|
||||||
TextLabel[] labelarray = labels[s];
|
TextLabel[] labelarray = labels[s];
|
||||||
float requiredsize = (labelarray[0].TextSize.Height / 2) / renderer.Scale;
|
float requiredsize = (labelarray[0].TextSize.Height / 2) / renderer.Scale;
|
||||||
|
@ -238,7 +241,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
if(requiredsize > group.Key.Labels[i].radius)
|
if(requiredsize > group.Key.Labels[i].radius)
|
||||||
{
|
{
|
||||||
requiredsize = (General.Interface.MeasureString(group.Value[1], l.Font).Width / 2) / renderer.Scale;
|
requiredsize = (General.Interface.MeasureString(group.Value[1], l.Font).Width / 2) / renderer.Scale;
|
||||||
l.Text = (requiredsize > group.Key.Labels[i].radius ? "+" : group.Value[1]);
|
if(requiredsize > group.Key.Labels[i].radius)
|
||||||
|
l.Text = (requiredsize > group.Key.Labels[i].radius * 4 ? string.Empty : "+");
|
||||||
|
else
|
||||||
|
l.Text = group.Value[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -277,7 +277,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
if(requiredsize > group.Key.Labels[i].radius)
|
if(requiredsize > group.Key.Labels[i].radius)
|
||||||
{
|
{
|
||||||
requiredsize = (General.Interface.MeasureString(group.Value[1], l.Font).Width / 2) / renderer.Scale;
|
requiredsize = (General.Interface.MeasureString(group.Value[1], l.Font).Width / 2) / renderer.Scale;
|
||||||
l.Text = (requiredsize > group.Key.Labels[i].radius ? "+" : group.Value[1]);
|
if(requiredsize > group.Key.Labels[i].radius)
|
||||||
|
l.Text = (requiredsize > group.Key.Labels[i].radius * 4 ? string.Empty : "+");
|
||||||
|
else
|
||||||
|
l.Text = group.Value[1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -541,14 +544,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
//mxd. Update helper lines
|
//mxd. Update helper lines
|
||||||
UpdateHelperObjects();
|
UpdateHelperObjects();
|
||||||
|
|
||||||
|
//mxd. Update selection info
|
||||||
|
UpdateSelectionInfo();
|
||||||
|
|
||||||
// Update display
|
// Update display
|
||||||
General.Interface.RedrawDisplay();
|
General.Interface.RedrawDisplay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. Update selection info
|
|
||||||
UpdateSelectionInfo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
editpressed = false;
|
editpressed = false;
|
||||||
|
@ -964,9 +967,20 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
Vector2D v = thing.Position;
|
Vector2D v = thing.Position;
|
||||||
TextLabel l = new TextLabel();
|
TextLabel l = new TextLabel();
|
||||||
l.TransformCoords = true;
|
l.TransformCoords = true;
|
||||||
|
|
||||||
|
if(thing.FixedSize)
|
||||||
|
{
|
||||||
|
l.Rectangle = new RectangleF(v.x, v.y, 0f, 0f);
|
||||||
|
l.AlignX = TextAlignmentX.Center;
|
||||||
|
l.AlignY = TextAlignmentY.Middle;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
l.Rectangle = new RectangleF(v.x - thing.Size + 1, v.y + thing.Size - 1, 0f, 0f);
|
l.Rectangle = new RectangleF(v.x - thing.Size + 1, v.y + thing.Size - 1, 0f, 0f);
|
||||||
l.AlignX = TextAlignmentX.Left;
|
l.AlignX = TextAlignmentX.Left;
|
||||||
l.AlignY = TextAlignmentY.Top;
|
l.AlignY = TextAlignmentY.Top;
|
||||||
|
}
|
||||||
|
|
||||||
l.Color = (thing == highlighted ? General.Colors.Selection : General.Colors.Highlight);
|
l.Color = (thing == highlighted ? General.Colors.Selection : General.Colors.Highlight);
|
||||||
l.Backcolor = General.Colors.Background.WithAlpha(255);
|
l.Backcolor = General.Colors.Background.WithAlpha(255);
|
||||||
l.DrawBackground = true;
|
l.DrawBackground = true;
|
||||||
|
|
|
@ -3732,6 +3732,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
first.controlSide = start.Sidedef;
|
first.controlSide = start.Sidedef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//mxd
|
||||||
|
HashSet<long> texturehashes = new HashSet<long> { texture.LongName };
|
||||||
|
|
||||||
first.forward = true;
|
first.forward = true;
|
||||||
todo.Push(first);
|
todo.Push(first);
|
||||||
|
|
||||||
|
@ -3761,11 +3764,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
// Add sidedefs forward (connected to the right vertex)
|
// Add sidedefs forward (connected to the right vertex)
|
||||||
Vertex v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
|
Vertex v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
|
||||||
AddSidedefsForAlignment(todo, v, true, forwardoffset, 1.0f, texture.LongName, false);
|
AddSidedefsForAlignment(todo, v, true, forwardoffset, 1.0f, texturehashes, false);
|
||||||
|
|
||||||
// Add sidedefs backward (connected to the left vertex)
|
// Add sidedefs backward (connected to the left vertex)
|
||||||
v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
|
v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
|
||||||
AddSidedefsForAlignment(todo, v, false, backwardoffset, 1.0f, texture.LongName, false);
|
AddSidedefsForAlignment(todo, v, false, backwardoffset, 1.0f, texturehashes, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -3787,11 +3790,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
// Add sidedefs backward (connected to the left vertex)
|
// Add sidedefs backward (connected to the left vertex)
|
||||||
Vertex v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
|
Vertex v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
|
||||||
AddSidedefsForAlignment(todo, v, false, backwardoffset, 1.0f, texture.LongName, false);
|
AddSidedefsForAlignment(todo, v, false, backwardoffset, 1.0f, texturehashes, false);
|
||||||
|
|
||||||
// Add sidedefs forward (connected to the right vertex)
|
// Add sidedefs forward (connected to the right vertex)
|
||||||
v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
|
v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
|
||||||
AddSidedefsForAlignment(todo, v, true, forwardoffset, 1.0f, texture.LongName, false);
|
AddSidedefsForAlignment(todo, v, true, forwardoffset, 1.0f, texturehashes, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3821,6 +3824,24 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
else
|
else
|
||||||
first.controlSide = start.Sidedef;
|
first.controlSide = start.Sidedef;
|
||||||
|
|
||||||
|
//mxd. We potentially need to deal with 2 textures (because of long and short texture names)...
|
||||||
|
HashSet<long> texturehashes = new HashSet<long> { texture.LongName };
|
||||||
|
switch(start.GeometryType)
|
||||||
|
{
|
||||||
|
case VisualGeometryType.WALL_LOWER:
|
||||||
|
texturehashes.Add(first.controlSide.LongLowTexture);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VisualGeometryType.WALL_MIDDLE:
|
||||||
|
case VisualGeometryType.WALL_MIDDLE_3D:
|
||||||
|
texturehashes.Add(first.controlSide.LongMiddleTexture);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VisualGeometryType.WALL_UPPER:
|
||||||
|
texturehashes.Add(first.controlSide.LongHighTexture);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
List<BaseVisualGeometrySidedef> selectedVisualSides = new List<BaseVisualGeometrySidedef>();
|
List<BaseVisualGeometrySidedef> selectedVisualSides = new List<BaseVisualGeometrySidedef>();
|
||||||
if(checkSelectedSidedefParts && !singleselection)
|
if(checkSelectedSidedefParts && !singleselection)
|
||||||
|
@ -3904,9 +3925,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Get the align job to do
|
// Get the align job to do
|
||||||
SidedefAlignJob j = todo.Pop();
|
SidedefAlignJob j = todo.Pop();
|
||||||
|
|
||||||
bool matchtop = (!j.sidedef.Marked && (!singleselection || j.sidedef.LongHighTexture == texture.LongName) && j.sidedef.HighRequired());
|
bool matchtop = (!j.sidedef.Marked && (!singleselection || texturehashes.Contains(j.sidedef.LongHighTexture)) && j.sidedef.HighRequired());
|
||||||
bool matchbottom = (!j.sidedef.Marked && (!singleselection || j.sidedef.LongLowTexture == texture.LongName) && j.sidedef.LowRequired());
|
bool matchbottom = (!j.sidedef.Marked && (!singleselection || texturehashes.Contains(j.sidedef.LongLowTexture)) && j.sidedef.LowRequired());
|
||||||
bool matchmid = ((!singleselection || j.controlSide.LongMiddleTexture == texture.LongName) && (j.controlSide.MiddleRequired() || j.controlSide.LongMiddleTexture != MapSet.EmptyLongName)); //mxd
|
bool matchmid = ((!singleselection || texturehashes.Contains(j.controlSide.LongMiddleTexture)) && (j.controlSide.MiddleRequired() || j.controlSide.LongMiddleTexture != MapSet.EmptyLongName)); //mxd
|
||||||
|
|
||||||
//mxd. If there's a selection, check if matched part is actually selected
|
//mxd. If there's a selection, check if matched part is actually selected
|
||||||
if(checkSelectedSidedefParts && !singleselection)
|
if(checkSelectedSidedefParts && !singleselection)
|
||||||
|
@ -4037,11 +4058,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
// Add sidedefs backward (connected to the left vertex)
|
// Add sidedefs backward (connected to the left vertex)
|
||||||
v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
|
v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
|
||||||
AddSidedefsForAlignment(todo, v, false, backwardoffset, j.scaleY, texture.LongName, true);
|
AddSidedefsForAlignment(todo, v, false, backwardoffset, j.scaleY, texturehashes, true);
|
||||||
|
|
||||||
// Add sidedefs forward (connected to the right vertex)
|
// Add sidedefs forward (connected to the right vertex)
|
||||||
v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
|
v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
|
||||||
AddSidedefsForAlignment(todo, v, true, forwardoffset, j.scaleY, texture.LongName, true);
|
AddSidedefsForAlignment(todo, v, true, forwardoffset, j.scaleY, texturehashes, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4133,17 +4154,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
// Add sidedefs forward (connected to the right vertex)
|
// Add sidedefs forward (connected to the right vertex)
|
||||||
v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
|
v = j.sidedef.IsFront ? j.sidedef.Line.End : j.sidedef.Line.Start;
|
||||||
AddSidedefsForAlignment(todo, v, true, forwardoffset, j.scaleY, texture.LongName, true);
|
AddSidedefsForAlignment(todo, v, true, forwardoffset, j.scaleY, texturehashes, true);
|
||||||
|
|
||||||
// Add sidedefs backward (connected to the left vertex)
|
// Add sidedefs backward (connected to the left vertex)
|
||||||
v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
|
v = j.sidedef.IsFront ? j.sidedef.Line.Start : j.sidedef.Line.End;
|
||||||
AddSidedefsForAlignment(todo, v, false, backwardoffset, j.scaleY, texture.LongName, true);
|
AddSidedefsForAlignment(todo, v, false, backwardoffset, j.scaleY, texturehashes, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This adds the matching, unmarked sidedefs from a vertex for texture alignment
|
// This adds the matching, unmarked sidedefs from a vertex for texture alignment
|
||||||
private void AddSidedefsForAlignment(Stack<SidedefAlignJob> stack, Vertex v, bool forward, float offsetx, float scaleY, long texturelongname, bool udmf)
|
private void AddSidedefsForAlignment(Stack<SidedefAlignJob> stack, Vertex v, bool forward, float offsetx, float scaleY, HashSet<long> texturelongnames, bool udmf)
|
||||||
{
|
{
|
||||||
foreach(Linedef ld in v.Linedefs)
|
foreach(Linedef ld in v.Linedefs)
|
||||||
{
|
{
|
||||||
|
@ -4156,7 +4177,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
foreach(Sidedef s in controlSides)
|
foreach(Sidedef s in controlSides)
|
||||||
{
|
{
|
||||||
if(!singleselection || Tools.SidedefTextureMatch(s, texturelongname))
|
if(!singleselection || Tools.SidedefTextureMatch(s, texturelongnames))
|
||||||
{
|
{
|
||||||
SidedefAlignJob nj = new SidedefAlignJob();
|
SidedefAlignJob nj = new SidedefAlignJob();
|
||||||
nj.forward = forward;
|
nj.forward = forward;
|
||||||
|
@ -4174,7 +4195,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
foreach(Sidedef s in controlSides)
|
foreach(Sidedef s in controlSides)
|
||||||
{
|
{
|
||||||
if(!singleselection || Tools.SidedefTextureMatch(s, texturelongname))
|
if(!singleselection || Tools.SidedefTextureMatch(s, texturelongnames))
|
||||||
{
|
{
|
||||||
SidedefAlignJob nj = new SidedefAlignJob();
|
SidedefAlignJob nj = new SidedefAlignJob();
|
||||||
nj.forward = forward;
|
nj.forward = forward;
|
||||||
|
|
|
@ -239,6 +239,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
if(translucent && !othertranslucent && !ef.ClipSidedefs) continue;
|
if(translucent && !othertranslucent && !ef.ClipSidedefs) continue;
|
||||||
if(ef.ClipSidedefs == extrafloor.ClipSidedefs || ef.ClipSidedefs)
|
if(ef.ClipSidedefs == extrafloor.ClipSidedefs || ef.ClipSidedefs)
|
||||||
{
|
{
|
||||||
|
//TODO: find out why ef can be not updated at this point
|
||||||
|
//TODO: [this crashed on me once when performing auto-align on myriad of textures on BoA C1M0]
|
||||||
|
if(ef.Floor == null || ef.Ceiling == null) ef.Update();
|
||||||
|
|
||||||
int num = polygons.Count;
|
int num = polygons.Count;
|
||||||
for(int pi = 0; pi < num; pi++)
|
for(int pi = 0; pi < num; pi++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue