mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 22:41:46 +00:00
Added automatic sidedefs compression when number of sidedefs exceeds the maximum sidedefs
This commit is contained in:
parent
2907da9341
commit
396ba7f764
4 changed files with 119 additions and 4 deletions
|
@ -62,6 +62,14 @@ namespace CodeImp.DoomBuilder
|
||||||
|
|
||||||
#region ================== Methods
|
#region ================== Methods
|
||||||
|
|
||||||
|
public void Add(long value)
|
||||||
|
{
|
||||||
|
uint lo = (uint)((ulong)value & 0x00000000FFFFFFFF);
|
||||||
|
uint hi = (uint)(((ulong)value & 0xFFFFFFFF00000000) >> 32);
|
||||||
|
crc.Update(unchecked((int)lo));
|
||||||
|
crc.Update(unchecked((int)hi));
|
||||||
|
}
|
||||||
|
|
||||||
public void Add(int value)
|
public void Add(int value)
|
||||||
{
|
{
|
||||||
crc.Update(value);
|
crc.Update(value);
|
||||||
|
|
|
@ -448,8 +448,11 @@ namespace CodeImp.DoomBuilder
|
||||||
if(map.Sidedefs.Count > io.MaxSidedefs)
|
if(map.Sidedefs.Count > io.MaxSidedefs)
|
||||||
{
|
{
|
||||||
// Compress sidedefs
|
// Compress sidedefs
|
||||||
|
oldstatus = General.MainWindow.Status;
|
||||||
|
General.MainWindow.DisplayStatus(StatusType.Busy, "Compressing sidedefs...");
|
||||||
outputset.CompressSidedefs();
|
outputset.CompressSidedefs();
|
||||||
|
General.MainWindow.DisplayStatus(oldstatus);
|
||||||
|
|
||||||
// Check if it still doesnt fit
|
// Check if it still doesnt fit
|
||||||
if(map.Sidedefs.Count > io.MaxSidedefs)
|
if(map.Sidedefs.Count > io.MaxSidedefs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2435,9 +2435,98 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
// This performs sidedefs compression
|
// This performs sidedefs compression
|
||||||
public void CompressSidedefs()
|
// Note: Only use this for saving, because this messes up the expected data structure horribly.
|
||||||
|
internal void CompressSidedefs()
|
||||||
{
|
{
|
||||||
// TODO: Make this happen
|
Dictionary<uint, List<Sidedef>> storedsides = new Dictionary<uint, List<Sidedef>>(sidedefs.Count);
|
||||||
|
int originalsidescount = sidedefs.Count;
|
||||||
|
double starttime = General.Clock.GetCurrentTime();
|
||||||
|
|
||||||
|
LinkedListNode<Sidedef> sn = sidedefs.First;
|
||||||
|
while(sn != null)
|
||||||
|
{
|
||||||
|
Sidedef stored = null;
|
||||||
|
LinkedListNode<Sidedef> nextsn = sn.Next;
|
||||||
|
|
||||||
|
// Check if checksum is stored
|
||||||
|
bool samesidedef = false;
|
||||||
|
uint checksum = sn.Value.GetChecksum();
|
||||||
|
bool checksumstored = storedsides.ContainsKey(checksum);
|
||||||
|
if(checksumstored)
|
||||||
|
{
|
||||||
|
List<Sidedef> othersides = storedsides[checksum];
|
||||||
|
foreach(Sidedef os in othersides)
|
||||||
|
{
|
||||||
|
// They must be in the same sector
|
||||||
|
if(sn.Value.Sector == os.Sector)
|
||||||
|
{
|
||||||
|
// Check if sidedefs are really the same
|
||||||
|
stored = os;
|
||||||
|
MemoryStream sidemem = new MemoryStream(1024);
|
||||||
|
SerializerStream sidedata = new SerializerStream(sidemem);
|
||||||
|
MemoryStream othermem = new MemoryStream(1024);
|
||||||
|
SerializerStream otherdata = new SerializerStream(othermem);
|
||||||
|
sn.Value.ReadWrite(sidedata);
|
||||||
|
os.ReadWrite(otherdata);
|
||||||
|
if(sidemem.Length == othermem.Length)
|
||||||
|
{
|
||||||
|
samesidedef = true;
|
||||||
|
sidemem.Seek(0, SeekOrigin.Begin);
|
||||||
|
othermem.Seek(0, SeekOrigin.Begin);
|
||||||
|
for(int i = 0; i < sidemem.Length; i++)
|
||||||
|
{
|
||||||
|
if(sidemem.ReadByte() != othermem.ReadByte())
|
||||||
|
{
|
||||||
|
samesidedef = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(samesidedef) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Same sidedef?
|
||||||
|
if(samesidedef)
|
||||||
|
{
|
||||||
|
// Replace with stored sidedef
|
||||||
|
bool isfront = sn.Value.IsFront;
|
||||||
|
sn.Value.Line.DetachSidedef(sn.Value);
|
||||||
|
if(isfront)
|
||||||
|
sn.Value.Line.AttachFront(stored);
|
||||||
|
else
|
||||||
|
sn.Value.Line.AttachBack(stored);
|
||||||
|
|
||||||
|
// Remove the sidedef
|
||||||
|
sn.Value.ChangeSector(null);
|
||||||
|
sidedefs.Remove(sn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Store this new one
|
||||||
|
if(checksumstored)
|
||||||
|
{
|
||||||
|
storedsides[checksum].Add(sn.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<Sidedef> newlist = new List<Sidedef>(4);
|
||||||
|
newlist.Add(sn.Value);
|
||||||
|
storedsides.Add(checksum, newlist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next
|
||||||
|
sn = nextsn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output info
|
||||||
|
double endtime = General.Clock.GetCurrentTime();
|
||||||
|
double deltatimesec = (endtime - starttime) / 1000.0d;
|
||||||
|
float ratio = 100.0f - (((float)sidedefs.Count / (float)originalsidescount) * 100.0f);
|
||||||
|
General.WriteLogLine("Sidedefs compressed: " + sidedefs.Count + " remaining out of " + originalsidescount + " (" + ratio.ToString("########0.00") + "%) in " + deltatimesec.ToString("########0.00") + " seconds");
|
||||||
}
|
}
|
||||||
|
|
||||||
// This converts flags and activations to UDMF fields
|
// This converts flags and activations to UDMF fields
|
||||||
|
|
|
@ -23,6 +23,7 @@ using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using CodeImp.DoomBuilder.IO;
|
using CodeImp.DoomBuilder.IO;
|
||||||
using CodeImp.DoomBuilder.Geometry;
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
|
using CodeImp.DoomBuilder.Types;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -210,6 +211,19 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
return map.GetIndexForSidedef(this);
|
return map.GetIndexForSidedef(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This creates a checksum from the sidedef properties
|
||||||
|
// Used for faster sidedefs compression
|
||||||
|
public uint GetChecksum()
|
||||||
|
{
|
||||||
|
CRC crc = new CRC();
|
||||||
|
crc.Add(sector.FixedIndex);
|
||||||
|
crc.Add(offsetx);
|
||||||
|
crc.Add(offsety);
|
||||||
|
crc.Add(longtexnamehigh);
|
||||||
|
crc.Add(longtexnamelow);
|
||||||
|
crc.Add(longtexnamemid);
|
||||||
|
return (uint)(crc.Value & 0x00000000FFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
// This copies textures to another sidedef
|
// This copies textures to another sidedef
|
||||||
// And possibly also the offsets
|
// And possibly also the offsets
|
||||||
|
@ -392,7 +406,8 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
sector = newsector;
|
sector = newsector;
|
||||||
|
|
||||||
// Attach to sector
|
// Attach to sector
|
||||||
sectorlistitem = sector.AttachSidedef(this);
|
if(sector != null)
|
||||||
|
sectorlistitem = sector.AttachSidedef(this);
|
||||||
|
|
||||||
General.Map.IsChanged = true;
|
General.Map.IsChanged = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue