mirror of
https://git.do.srb2.org/STJr/ZoneBuilder.git
synced 2025-04-22 17:44:06 +00:00
Only rebuild effects that have changed
This commit is contained in:
parent
8ef05744f9
commit
5b4b6acda5
4 changed files with 188 additions and 114 deletions
|
@ -788,10 +788,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
else s.Fields.Add("rotationceiling", new UniValue(UniversalType.Float, rotation));
|
||||
}
|
||||
}
|
||||
|
||||
// This rebuilds the sector data
|
||||
// This requires that the blockmap is up-to-date!
|
||||
internal void RebuildElementData()
|
||||
|
||||
// This rebuilds the sector data
|
||||
// This requires that the blockmap is up-to-date!
|
||||
internal void RebuildElementData(bool markedOnly = false)
|
||||
{
|
||||
//mxd
|
||||
Sector[] sectorsWithEffects = null;
|
||||
|
@ -819,8 +819,20 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
Dictionary<int, List<Sector>> sectortags = new Dictionary<int, List<Sector>>();
|
||||
List<Thing> slopethings = new List<Thing>();
|
||||
sectordata = new Dictionary<Sector, SectorData>(General.Map.Map.Sectors.Count);
|
||||
thingdata = new Dictionary<Thing, ThingData>(General.Map.Map.Things.Count);
|
||||
|
||||
if (sectordata == null)
|
||||
sectordata = new Dictionary<Sector, SectorData>(General.Map.Map.Sectors.Count);
|
||||
foreach (Sector sector in General.Map.Map.Sectors)
|
||||
{
|
||||
if (!markedOnly || sector.Marked)
|
||||
{
|
||||
RemoveSectorDependencies(sector);
|
||||
sectordata[sector] = new SectorData(this, sector);
|
||||
}
|
||||
}
|
||||
|
||||
if (!markedOnly)
|
||||
thingdata = new Dictionary<Thing, ThingData>(General.Map.Map.Things.Count);
|
||||
|
||||
if (bsp.IsDeactivated && !String.IsNullOrEmpty(bsp.ErrorMessage))
|
||||
MessageBox.Show("Could not load the map's nodes: " + bsp.ErrorMessage + " Defaulting to blockmap.", "Error loading nodes!", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
@ -867,6 +879,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
sectortags[tag].Add(s);
|
||||
}
|
||||
|
||||
if (markedOnly && !s.Marked)
|
||||
continue;
|
||||
|
||||
if (General.Map.SRB2) s.Fields.Clear(); //Reset fake UDMF properties (since the linedef special that set them might no longer be there)
|
||||
else
|
||||
{
|
||||
|
@ -929,7 +944,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
if (l.IsRegularSlope)
|
||||
{
|
||||
if (!General.Map.FormatInterface.HasLinedefParameters) l.SetSlopeArgs();
|
||||
if (((l.Args[0] == 1) || (l.Args[1] == 1)) && (l.Front != null))
|
||||
if (((l.Args[0] == 1) || (l.Args[1] == 1)) && (l.Front != null) && (!markedOnly || l.Front.Sector.Marked || l.Marked))
|
||||
{
|
||||
SectorData sd = GetSectorData(l.Front.Sector);
|
||||
sd.AddEffectLineSlope(l);
|
||||
|
@ -941,7 +956,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
l.SetSlopeArgs();
|
||||
}
|
||||
}
|
||||
if (((l.Args[0] == 2) || (l.Args[1] == 2)) && (l.Back != null))
|
||||
if (((l.Args[0] == 2) || (l.Args[1] == 2)) && (l.Back != null) && (!markedOnly || l.Back.Sector.Marked || l.Marked))
|
||||
{
|
||||
SectorData sd = GetSectorData(l.Back.Sector);
|
||||
sd.AddEffectLineSlope(l);
|
||||
|
@ -975,7 +990,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
|
||||
// Copy slope to front sector
|
||||
if (l.Front != null)
|
||||
if (l.Front != null && (!markedOnly || l.Front.Sector.Marked || l.Marked))
|
||||
{
|
||||
if ((l.Args[0] > 0 || l.Args[1] > 0) || (l.Back != null && (floorCopyToFront || ceilingCopyToFront)))
|
||||
{
|
||||
|
@ -985,7 +1000,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
|
||||
// Copy slope to back sector
|
||||
if (l.Back != null)
|
||||
if (l.Back != null && (!markedOnly || l.Back.Sector.Marked || l.Marked))
|
||||
{
|
||||
if ((l.Args[2] > 0 || l.Args[3] > 0) || (l.Front != null && (floorCopyToBack || ceilingCopyToBack)))
|
||||
{
|
||||
|
@ -1024,9 +1039,15 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
ApplyFlatAlignment(l, l.Front.Sector, alignfloor, alignceiling, offset, rotation);
|
||||
else if (sectortags.ContainsKey(sectortag))
|
||||
{
|
||||
if (markedOnly && !(s.Marked || l.Marked))
|
||||
continue;
|
||||
List<Sector> sectors = sectortags[sectortag];
|
||||
foreach (Sector s in sectors)
|
||||
{
|
||||
if (markedOnly && !(s.Marked || l.Marked))
|
||||
continue;
|
||||
ApplyFlatAlignment(l, s, alignfloor, alignceiling, offset, rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1042,12 +1063,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
List<Sector> sectors = (sectortag == 65535) ? General.Map.Map.Sectors.ToList() : sectortags[sectortag];
|
||||
foreach (Sector s in sectors)
|
||||
{
|
||||
if (markedOnly && !(s.Marked || l.Marked))
|
||||
continue;
|
||||
|
||||
s.Fields.BeforeFieldsChange();
|
||||
if (s.Fields.ContainsKey("lightcolor")) s.Fields["lightcolor"] = new UniValue(UniversalType.Color, color);
|
||||
else s.Fields.Add("lightcolor", new UniValue(UniversalType.Color, color));
|
||||
//TODO: Find out why the alpha value is ignored.
|
||||
/*if (s.Fields.ContainsKey("lightalpha")) s.Fields["lightalpha"] = new UniValue(UniversalType.Integer, alpha);
|
||||
else s.Fields.Add("lightalpha", new UniValue(UniversalType.Integer, alpha));*/
|
||||
|
||||
(GetVisualSector(s) as BaseVisualSector).UpdateSectorGeometry(false);
|
||||
GetSectorData(l.Front.Sector).AddUpdateSector(s, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1097,7 +1124,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
if ((int)t.AngleDoom == l.Tag) slopevertices.Add(t);
|
||||
}
|
||||
}
|
||||
if (slopevertices.Count >= 3)
|
||||
if (slopevertices.Count >= 3 && (!markedOnly || s.Marked || l.Marked
|
||||
|| slopevertices[0].Marked || slopevertices[1].Marked || slopevertices[2].Marked))
|
||||
{
|
||||
SectorData sd = GetSectorData(s);
|
||||
sd.AddEffectSRB2ThingVertexSlope(slopevertices, slopefloor, blockmap, bsp);
|
||||
|
@ -1120,6 +1148,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
List<Sector> sectors = (sectortag == 65535) ? General.Map.Map.Sectors.ToList() : sectortags[sectortag];
|
||||
foreach (Sector s in sectors)
|
||||
{
|
||||
if (markedOnly && !(s.Marked || l.Marked))
|
||||
continue;
|
||||
|
||||
SectorData sd = GetSectorData(s);
|
||||
sd.AddEffect3DFloor(l);
|
||||
}
|
||||
|
@ -1138,6 +1169,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
List<Sector> sectors = sectortags[l.Args[0]];
|
||||
foreach (Sector s in sectors)
|
||||
{
|
||||
if (markedOnly && !(s.Marked || l.Marked))
|
||||
continue;
|
||||
|
||||
SectorData sd = GetSectorData(s);
|
||||
sd.AddEffectBrightnessLevel(l);
|
||||
}
|
||||
|
@ -1151,6 +1185,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
List<Sector> sectors = sectortags[l.Args[0]];
|
||||
foreach (Sector s in sectors)
|
||||
{
|
||||
if (markedOnly && !(s.Marked || l.Marked))
|
||||
continue;
|
||||
|
||||
SectorData sd = GetSectorData(s);
|
||||
sd.AddEffectTransferFloorBrightness(l);
|
||||
}
|
||||
|
@ -1164,6 +1201,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
List<Sector> sectors = sectortags[l.Args[0]];
|
||||
foreach (Sector s in sectors)
|
||||
{
|
||||
if (markedOnly && !(s.Marked || l.Marked))
|
||||
continue;
|
||||
|
||||
SectorData sd = GetSectorData(s);
|
||||
sd.AddEffectTransferCeilingBrightness(l);
|
||||
}
|
||||
|
@ -1184,7 +1224,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
case 9511:
|
||||
case 9510:
|
||||
t.DetermineSector(blockmap);
|
||||
if (t.Sector != null)
|
||||
if (t.Sector != null && (!markedOnly || t.Sector.Marked || t.Marked))
|
||||
{
|
||||
SectorData sd = GetSectorData(t.Sector);
|
||||
sd.AddEffectCopySlope(t);
|
||||
|
@ -1195,7 +1235,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
case 9501:
|
||||
case 9500:
|
||||
t.DetermineSector(blockmap);
|
||||
if (t.Sector != null)
|
||||
if (t.Sector != null && (!markedOnly || t.Sector.Marked || t.Marked))
|
||||
{
|
||||
SectorData sd = GetSectorData(t.Sector);
|
||||
sd.AddEffectThingLineSlope(t);
|
||||
|
@ -1206,7 +1246,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
case 9503:
|
||||
case 9502:
|
||||
t.DetermineSector(blockmap);
|
||||
if (t.Sector != null)
|
||||
if (t.Sector != null && (!markedOnly || t.Sector.Marked || t.Marked))
|
||||
{
|
||||
SectorData sd = GetSectorData(t.Sector);
|
||||
sd.AddEffectThingSlope(t);
|
||||
|
@ -1216,7 +1256,44 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void MarkDependentSectors(MapElement element)
|
||||
{
|
||||
Dictionary<Sector, bool> sectorsToUpdate;
|
||||
|
||||
if (element is Sector)
|
||||
sectorsToUpdate = GetSectorData(element as Sector).UpdateAlso;
|
||||
else if (element is Vertex && vertexdata != null)
|
||||
sectorsToUpdate = GetVertexData(element as Vertex).UpdateAlso;
|
||||
else if (element is Thing)
|
||||
sectorsToUpdate = GetThingData(element as Thing).UpdateAlso;
|
||||
else
|
||||
return;
|
||||
|
||||
foreach (KeyValuePair<Sector, bool> updateAlso in sectorsToUpdate)
|
||||
{
|
||||
if (updateAlso.Key.Marked)
|
||||
continue;
|
||||
updateAlso.Key.Marked = true;
|
||||
MarkDependentSectors(updateAlso.Key);
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveSectorDependencies(Sector sector)
|
||||
{
|
||||
foreach (KeyValuePair<MapElement, bool> updatedBy in GetSectorData(sector).updatedBy)
|
||||
{
|
||||
MapElement element = updatedBy.Key;
|
||||
|
||||
if (element is Sector)
|
||||
GetSectorData(element as Sector).UpdateAlso.Remove(sector);
|
||||
else if (element is Vertex)
|
||||
GetVertexData(element as Vertex).UpdateAlso.Remove(sector);
|
||||
else if (element is Thing)
|
||||
GetThingData(element as Thing).UpdateAlso.Remove(sector);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events
|
||||
|
@ -1467,102 +1544,104 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// and uses the marks to check what needs to be reloaded.
|
||||
protected override void ResourcesReloadedPartial()
|
||||
{
|
||||
bool sectorsmarked = false;
|
||||
|
||||
if(General.Map.UndoRedo.GeometryChanged)
|
||||
foreach (MapElement e in General.Map.Map.RemovedElements)
|
||||
{
|
||||
// Let the core do this (it will just dispose the sectors that were changed)
|
||||
base.ResourcesReloadedPartial();
|
||||
if (e is Sector)
|
||||
RemoveSectorDependencies(e as Sector);
|
||||
|
||||
MarkDependentSectors(e);
|
||||
}
|
||||
else
|
||||
|
||||
// Go for all vertices to mark linedefs that need updating
|
||||
foreach (Vertex v in General.Map.Map.Vertices)
|
||||
if (v.Marked)
|
||||
foreach (Linedef ld in v.Linedefs)
|
||||
ld.Marked = true;
|
||||
|
||||
foreach (Linedef l in General.Map.Map.Linedefs)
|
||||
{
|
||||
// Neighbour sectors must be updated as well
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
if (l.Marked)
|
||||
{
|
||||
if(s.Marked)
|
||||
{
|
||||
sectorsmarked = true;
|
||||
foreach(Sidedef sd in s.Sidedefs)
|
||||
{
|
||||
sd.Marked = true;
|
||||
if(sd.Other != null) sd.Other.Marked = true;
|
||||
}
|
||||
}
|
||||
if (l.Front != null)
|
||||
l.Front.Marked = true;
|
||||
if (l.Back != null)
|
||||
l.Back.Marked = true;
|
||||
}
|
||||
|
||||
// Go for all sidedefs to update
|
||||
foreach(Sidedef sd in General.Map.Map.Sidedefs)
|
||||
{
|
||||
if(sd.Marked && VisualSectorExists(sd.Sector))
|
||||
{
|
||||
BaseVisualSector vs = GetVisualSector(sd.Sector) as BaseVisualSector;
|
||||
VisualSidedefParts parts = vs.GetSidedefParts(sd);
|
||||
parts.SetupAllParts();
|
||||
}
|
||||
}
|
||||
|
||||
// Go for all sectors to update
|
||||
foreach(Sector s in General.Map.Map.Sectors)
|
||||
{
|
||||
if(s.Marked)
|
||||
{
|
||||
SectorData sd = GetSectorData(s);
|
||||
sd.Reset();
|
||||
|
||||
// UpdateSectorGeometry for associated sectors (sd.UpdateAlso) as well!
|
||||
foreach(KeyValuePair<Sector, bool> us in sd.UpdateAlso)
|
||||
{
|
||||
if(VisualSectorExists(us.Key))
|
||||
{
|
||||
BaseVisualSector vs = GetVisualSector(us.Key) as BaseVisualSector;
|
||||
vs.UpdateSectorGeometry(us.Value);
|
||||
}
|
||||
}
|
||||
|
||||
// And update for this sector ofcourse
|
||||
if(VisualSectorExists(s))
|
||||
{
|
||||
BaseVisualSector vs = GetVisualSector(s) as BaseVisualSector;
|
||||
vs.UpdateSectorGeometry(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!sectorsmarked)
|
||||
{
|
||||
// No sectors or geometry changed. So we only have
|
||||
// to update things when they have changed.
|
||||
foreach(KeyValuePair<Thing, VisualThing> vt in allthings)
|
||||
if((vt.Value != null) && vt.Key.Marked) (vt.Value as BaseVisualThing).Rebuild();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Things depend on the sector they are in and because we can't
|
||||
// easily determine which ones changed, we dispose all things
|
||||
foreach(KeyValuePair<Thing, VisualThing> vt in allthings)
|
||||
if(vt.Value != null) vt.Value.Dispose();
|
||||
|
||||
// Apply new lists
|
||||
allthings = new Dictionary<Thing, VisualThing>(allthings.Count);
|
||||
}
|
||||
|
||||
// Clear visibility collections
|
||||
visiblesectors.Clear();
|
||||
visibleblocks.Clear();
|
||||
visiblegeometry.Clear();
|
||||
visiblethings.Clear();
|
||||
|
||||
// Make new blockmap
|
||||
if(sectorsmarked || General.Map.UndoRedo.PopulationChanged)
|
||||
FillBlockMap();
|
||||
|
||||
RebuildElementData();
|
||||
UpdateChangedObjects();
|
||||
|
||||
// Visibility culling (this re-creates the needed resources)
|
||||
DoCulling();
|
||||
}
|
||||
|
||||
|
||||
// Go for all sidedefs to mark sectors that need updating
|
||||
foreach (Sidedef sd in General.Map.Map.Sidedefs)
|
||||
if (sd.Marked)
|
||||
sd.Sector.Marked = true;
|
||||
|
||||
// Mark sectors that depend on updated sectors/linedefs/sidedefs/vertices
|
||||
// Marking lines, sides and vertices also marks the sectors they are bound to,
|
||||
// so it will properly mark sectors that don't directly depend on other sectors
|
||||
foreach (Sector s in General.Map.Map.Sectors)
|
||||
if (s.Marked)
|
||||
MarkDependentSectors(s);
|
||||
|
||||
// Mark sectors that depend on updated vertices
|
||||
foreach (Vertex v in General.Map.Map.Vertices)
|
||||
if (v.Marked)
|
||||
MarkDependentSectors(v);
|
||||
|
||||
// Mark sectors that depend on updated things
|
||||
foreach (Thing t in General.Map.Map.Things)
|
||||
if (t.Marked)
|
||||
MarkDependentSectors(t);
|
||||
|
||||
// Neighbour sectors must be updated as well
|
||||
foreach (Sector s in General.Map.Map.Sectors)
|
||||
if (s.Marked)
|
||||
foreach (Sidedef sd in s.Sidedefs)
|
||||
if (sd.Other != null)
|
||||
sd.Other.Marked = true;
|
||||
|
||||
// Go for all sidedefs to mark sectors that need updating
|
||||
foreach (Sidedef sd in General.Map.Map.Sidedefs)
|
||||
if (sd.Marked)
|
||||
sd.Sector.Marked = true;
|
||||
|
||||
// Make new blockmap
|
||||
FillBlockMap();
|
||||
|
||||
RebuildElementData(true);
|
||||
|
||||
// Dispose if source was disposed or marked
|
||||
var newSectors = new Dictionary<Sector,VisualSector>(allsectors.Count);
|
||||
General.Test("!Rebuild sector list", () => {
|
||||
foreach (KeyValuePair<Sector, VisualSector> vs in allsectors)
|
||||
{
|
||||
if (vs.Value != null)
|
||||
{
|
||||
if(vs.Key.IsDisposed || vs.Key.Marked || (vs.Value as BaseVisualSector).Changed)
|
||||
vs.Value.Dispose();
|
||||
else
|
||||
newSectors.Add(vs.Key, vs.Value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Things depend on the sector they are in and because we can't
|
||||
// easily determine which ones changed, we dispose all things
|
||||
foreach (KeyValuePair<Thing, VisualThing> vt in allthings)
|
||||
if (vt.Value != null && (vt.Key.IsDisposed || vt.Key.Marked || (vt.Key.Sector != null && vt.Key.Sector.Marked)))
|
||||
vt.Value.Dispose();
|
||||
|
||||
// Apply new lists
|
||||
allsectors = newSectors;
|
||||
allthings = new Dictionary<Thing, VisualThing>(allthings.Count);
|
||||
|
||||
// Clear visibility collections
|
||||
visiblesectors.Clear();
|
||||
visibleblocks.Clear();
|
||||
visiblegeometry.Clear();
|
||||
visiblethings.Clear();
|
||||
|
||||
// Visibility culling (this re-creates the needed resources)
|
||||
DoCulling();
|
||||
|
||||
// Determine what we're aiming at now
|
||||
PickTarget();
|
||||
}
|
||||
|
@ -1640,16 +1719,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
base.OnRedoEnd();
|
||||
|
||||
//mxd. Effects may've become invalid
|
||||
if(sectordata != null && sectordata.Count > 0)
|
||||
RebuildElementData();
|
||||
|
||||
//mxd. As well as geometry...
|
||||
foreach(KeyValuePair<Sector, VisualSector> group in visiblesectors)
|
||||
{
|
||||
if(group.Value is BaseVisualSector) (group.Value as BaseVisualSector).Rebuild();
|
||||
}
|
||||
|
||||
RebuildSelectedObjectsList();
|
||||
}
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
public SectorLevel Ceiling { get { return ceiling; } }
|
||||
public BaseVisualMode Mode { get { return mode; } }
|
||||
public Dictionary<Sector, bool> UpdateAlso { get { return updatesectors; } }
|
||||
public Dictionary<MapElement, bool> updatedBy { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -91,6 +92,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
this.extrafloors = new List<Effect3DFloor>(1);
|
||||
this.alleffects = new List<SectorEffect>(1);
|
||||
this.updatesectors = new Dictionary<Sector, bool>(2);
|
||||
this.updatedBy = new Dictionary<MapElement, bool>(2);
|
||||
this.floor = new SectorLevel(sector, SectorLevelType.Floor);
|
||||
this.floorbase = new SectorLevel(sector, SectorLevelType.Floor); //mxd
|
||||
this.ceiling = new SectorLevel(sector, SectorLevelType.Ceiling);
|
||||
|
@ -203,6 +205,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
public void AddUpdateSector(Sector s, bool includeneighbours)
|
||||
{
|
||||
updatesectors[s] = includeneighbours;
|
||||
mode.GetSectorData(s).updatedBy[sector] = includeneighbours;
|
||||
}
|
||||
|
||||
// This adds a sector level
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
public void AddUpdateSector(Sector s, bool includeneighbours)
|
||||
{
|
||||
updatesectors[s] = includeneighbours;
|
||||
mode.GetSectorData(s).updatedBy[thing] = includeneighbours;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
public void AddUpdateSector(Sector s, bool includeneighbours)
|
||||
{
|
||||
updatesectors[s] = includeneighbours;
|
||||
mode.GetSectorData(s).updatedBy[vertex] = includeneighbours;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
Loading…
Reference in a new issue