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
|
||||
|
||||
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)
|
||||
{
|
||||
crc.Update(value);
|
||||
|
|
|
@ -448,8 +448,11 @@ namespace CodeImp.DoomBuilder
|
|||
if(map.Sidedefs.Count > io.MaxSidedefs)
|
||||
{
|
||||
// Compress sidedefs
|
||||
oldstatus = General.MainWindow.Status;
|
||||
General.MainWindow.DisplayStatus(StatusType.Busy, "Compressing sidedefs...");
|
||||
outputset.CompressSidedefs();
|
||||
|
||||
General.MainWindow.DisplayStatus(oldstatus);
|
||||
|
||||
// Check if it still doesnt fit
|
||||
if(map.Sidedefs.Count > io.MaxSidedefs)
|
||||
{
|
||||
|
|
|
@ -2435,9 +2435,98 @@ namespace CodeImp.DoomBuilder.Map
|
|||
}
|
||||
|
||||
// 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
|
||||
|
|
|
@ -23,6 +23,7 @@ using System.Globalization;
|
|||
using System.Text;
|
||||
using CodeImp.DoomBuilder.IO;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Types;
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -210,6 +211,19 @@ namespace CodeImp.DoomBuilder.Map
|
|||
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
|
||||
// And possibly also the offsets
|
||||
|
@ -392,7 +406,8 @@ namespace CodeImp.DoomBuilder.Map
|
|||
sector = newsector;
|
||||
|
||||
// Attach to sector
|
||||
sectorlistitem = sector.AttachSidedef(this);
|
||||
if(sector != null)
|
||||
sectorlistitem = sector.AttachSidedef(this);
|
||||
|
||||
General.Map.IsChanged = true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue