mirror of
https://git.do.srb2.org/STJr/ZoneBuilder.git
synced 2025-01-31 05:00:34 +00:00
Added, Game configurations: added "ignoreddirectories" parameter. It lists directory names to be ignored when loading PK3/PK7/Directory resources.
Added, Game configurations: added "ignoredextensions" parameter. It lists file extensions to be ignored when loading PK3/PK7/Directory resources. Updated: sector triangulation logic now works ~20% faster. Changed: a case when a pk3/pk7 archive contains several entries with identical filename is now treated as a warning, not as an error. Fixed, Visual mode: absolute floor/ceiling brightness should not be affected by brightness transfer effects (like 3d floors). Fixed, Draw Lines mode: in some cases unclosed sectors were created when several points were successively drawn at the same location. Updated documentation.
This commit is contained in:
parent
50a547a570
commit
41ae6b3c55
3 changed files with 91 additions and 53 deletions
|
@ -374,18 +374,18 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
Vertex found = null;
|
||||
|
||||
// Go for all sides to find the right-most side
|
||||
foreach(KeyValuePair<Sidedef, bool> sd in sides)
|
||||
foreach(Sidedef sd in sides.Keys)
|
||||
{
|
||||
// First found?
|
||||
if((found == null) && !ignores.ContainsKey(sd.Key.Line.Start)) found = sd.Key.Line.Start;
|
||||
if((found == null) && !ignores.ContainsKey(sd.Key.Line.End)) found = sd.Key.Line.End;
|
||||
if((found == null) && !ignores.ContainsKey(sd.Line.Start)) found = sd.Line.Start;
|
||||
if((found == null) && !ignores.ContainsKey(sd.Line.End)) found = sd.Line.End;
|
||||
|
||||
// Compare?
|
||||
if(found != null)
|
||||
{
|
||||
// Check if more to the right than the previous found
|
||||
if((sd.Key.Line.Start.Position.x > found.Position.x) && !ignores.ContainsKey(sd.Key.Line.Start)) found = sd.Key.Line.Start;
|
||||
if((sd.Key.Line.End.Position.x > found.Position.x) && !ignores.ContainsKey(sd.Key.Line.End)) found = sd.Key.Line.End;
|
||||
if((sd.Line.Start.Position.x > found.Position.x) && !ignores.ContainsKey(sd.Line.Start)) found = sd.Line.Start;
|
||||
if((sd.Line.End.Position.x > found.Position.x) && !ignores.ContainsKey(sd.Line.End)) found = sd.Line.End;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,11 +779,16 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// This checks if a given ear is a valid (no intersections from reflex vertices)
|
||||
private static bool CheckValidEar(EarClipVertex[] t, LinkedList<EarClipVertex> reflexes)
|
||||
{
|
||||
//mxd
|
||||
Vector2D pos0 = t[0].Position;
|
||||
Vector2D pos1 = t[1].Position;
|
||||
Vector2D pos2 = t[2].Position;
|
||||
|
||||
// Go for all reflex vertices
|
||||
foreach(EarClipVertex rv in reflexes)
|
||||
{
|
||||
// Not one of the triangle corners?
|
||||
if((rv.Position != t[0].Position) && (rv.Position != t[1].Position) && (rv.Position != t[2].Position))
|
||||
if((rv.Position != pos0) && (rv.Position != pos1) && (rv.Position != pos2))
|
||||
{
|
||||
// Return false on intersection
|
||||
if(PointInsideTriangle(t, rv.MainListNode)) return false;
|
||||
|
@ -797,11 +802,12 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// This returns the 3-vertex array triangle for an ear
|
||||
private static EarClipVertex[] GetTriangle(EarClipVertex v)
|
||||
{
|
||||
EarClipVertex[] t = new EarClipVertex[3];
|
||||
t[0] = (v.MainListNode.Previous == null) ? v.MainListNode.List.Last.Value : v.MainListNode.Previous.Value;
|
||||
t[1] = v;
|
||||
t[2] = (v.MainListNode.Next == null) ? v.MainListNode.List.First.Value : v.MainListNode.Next.Value;
|
||||
return t;
|
||||
return new []
|
||||
{
|
||||
(v.MainListNode.Previous == null) ? v.MainListNode.List.Last.Value : v.MainListNode.Previous.Value,
|
||||
v,
|
||||
(v.MainListNode.Next == null) ? v.MainListNode.List.First.Value : v.MainListNode.Next.Value
|
||||
};
|
||||
}
|
||||
|
||||
// This checks if a vertex is reflex (corner > 180 deg) or convex (corner < 180 deg)
|
||||
|
@ -820,18 +826,23 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// If the triangle has no area, there can never be a point inside
|
||||
if(TriangleHasArea(t))
|
||||
{
|
||||
float lineside01 = Line2D.GetSideOfLine(t[0].Position, t[1].Position, p.Value.Position);
|
||||
float lineside12 = Line2D.GetSideOfLine(t[1].Position, t[2].Position, p.Value.Position);
|
||||
float lineside20 = Line2D.GetSideOfLine(t[2].Position, t[0].Position, p.Value.Position);
|
||||
//mxd
|
||||
Vector2D pos0 = t[0].Position;
|
||||
Vector2D pos1 = t[1].Position;
|
||||
Vector2D pos2 = t[2].Position;
|
||||
|
||||
float lineside01 = Line2D.GetSideOfLine(pos0, pos1, p.Value.Position);
|
||||
float lineside12 = Line2D.GetSideOfLine(pos1, pos2, p.Value.Position);
|
||||
float lineside20 = Line2D.GetSideOfLine(pos2, pos0, p.Value.Position);
|
||||
float u_on_line = 0.5f;
|
||||
|
||||
// If point p is on the line of an edge, find out where on the edge segment p is.
|
||||
if(lineside01 == 0.0f)
|
||||
u_on_line = Line2D.GetNearestOnLine(t[0].Position, t[1].Position, p.Value.Position);
|
||||
u_on_line = Line2D.GetNearestOnLine(pos0, pos1, p.Value.Position);
|
||||
else if(lineside12 == 0.0f)
|
||||
u_on_line = Line2D.GetNearestOnLine(t[1].Position, t[2].Position, p.Value.Position);
|
||||
u_on_line = Line2D.GetNearestOnLine(pos1, pos2, p.Value.Position);
|
||||
else if(lineside20 == 0.0f)
|
||||
u_on_line = Line2D.GetNearestOnLine(t[2].Position, t[0].Position, p.Value.Position);
|
||||
u_on_line = Line2D.GetNearestOnLine(pos2, pos0, p.Value.Position);
|
||||
|
||||
// If any of the lineside results are 0 then that means the point p lies on that edge and we
|
||||
// need to test if the lines adjacent to the point p are in the triangle or not.
|
||||
|
@ -877,9 +888,10 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// Line is inside triangle, because p2 is
|
||||
return true;
|
||||
}
|
||||
|
||||
// Test if p2 is on an edge of the triangle and if it is we would
|
||||
// like to know where on the edge segment p2 is
|
||||
else if(s01 == 0.0f)
|
||||
if(s01 == 0.0f)
|
||||
{
|
||||
p2_on_edge = Line2D.GetNearestOnLine(t[0].Position, t[1].Position, p2);
|
||||
p1_on_same_edge = Line2D.GetSideOfLine(t[0].Position, t[1].Position, p1);
|
||||
|
@ -912,13 +924,10 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
Line2D t20 = new Line2D(t[2].Position, t[0].Position);
|
||||
float pu, pt;
|
||||
|
||||
// Test intersections
|
||||
t01.GetIntersection(p, out pu, out pt);
|
||||
if(!float.IsNaN(pu) && (pu >= 0.0f) && (pu <= 1.0f) && (pt >= 0.0f) && (pt <= 1.0f)) return true;
|
||||
t12.GetIntersection(p, out pu, out pt);
|
||||
if(!float.IsNaN(pu) && (pu >= 0.0f) && (pu <= 1.0f) && (pt >= 0.0f) && (pt <= 1.0f)) return true;
|
||||
t20.GetIntersection(p, out pu, out pt);
|
||||
if(!float.IsNaN(pu) && (pu >= 0.0f) && (pu <= 1.0f) && (pt >= 0.0f) && (pt <= 1.0f)) return true;
|
||||
//mxd. Test intersections
|
||||
if(t01.GetIntersection(p, out pu, out pt)) return true;
|
||||
if(t12.GetIntersection(p, out pu, out pt)) return true;
|
||||
if(t20.GetIntersection(p, out pu, out pt)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -926,24 +935,33 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
// This checks if the triangle has an area greater than 0
|
||||
private static bool TriangleHasArea(EarClipVertex[] t)
|
||||
{
|
||||
return ((t[0].Position.x * (t[1].Position.y - t[2].Position.y) +
|
||||
t[1].Position.x * (t[2].Position.y - t[0].Position.y) +
|
||||
t[2].Position.x * (t[0].Position.y - t[1].Position.y)) != 0.0f);
|
||||
Vector2D tp0 = t[0].Position;
|
||||
Vector2D tp1 = t[1].Position;
|
||||
Vector2D tp2 = t[2].Position;
|
||||
|
||||
return ((tp0.x * (tp1.y - tp2.y) +
|
||||
tp1.x * (tp2.y - tp0.y) +
|
||||
tp2.x * (tp0.y - tp1.y)) != 0.0f);
|
||||
}
|
||||
|
||||
// This adds an array of vertices
|
||||
private static void AddTriangleToList(EarClipVertex[] triangle, List<Vector2D> verticeslist, List<Sidedef> sidedefslist, bool last)
|
||||
{
|
||||
//mxd
|
||||
EarClipVertex v0 = triangle[0];
|
||||
EarClipVertex v1 = triangle[1];
|
||||
EarClipVertex v2 = triangle[2];
|
||||
|
||||
// Create triangle
|
||||
verticeslist.Add(triangle[0].Position);
|
||||
sidedefslist.Add(triangle[0].Sidedef);
|
||||
verticeslist.Add(triangle[1].Position);
|
||||
sidedefslist.Add(triangle[1].Sidedef);
|
||||
verticeslist.Add(triangle[2].Position);
|
||||
if(!last) sidedefslist.Add(null); else sidedefslist.Add(triangle[2].Sidedef);
|
||||
verticeslist.Add(v0.Position);
|
||||
sidedefslist.Add(v0.Sidedef);
|
||||
verticeslist.Add(v1.Position);
|
||||
sidedefslist.Add(v1.Sidedef);
|
||||
verticeslist.Add(v2.Position);
|
||||
sidedefslist.Add(!last ? null : v2.Sidedef);
|
||||
|
||||
// Modify the first earclipvertex of this triangle, it no longer lies along a sidedef
|
||||
triangle[0].Sidedef = null;
|
||||
v0.Sidedef = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -546,6 +546,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
pos.y > General.Map.Config.TopBoundary || pos.y < General.Map.Config.BottomBoundary)
|
||||
return false;
|
||||
|
||||
//mxd. Avoid zero-length lines...
|
||||
if(points.Count > 0)
|
||||
{
|
||||
Vector2D delta = points[points.Count - 1].pos - pos;
|
||||
if((Math.Abs(delta.x) <= 0.001f) && (Math.Abs(delta.y) <= 0.001f))
|
||||
return true;
|
||||
}
|
||||
|
||||
DrawnVertex newpoint = new DrawnVertex();
|
||||
newpoint.pos = pos;
|
||||
newpoint.stitch = stitch;
|
||||
|
|
|
@ -60,6 +60,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
private bool floorchanged;
|
||||
private bool ceilingchanged;
|
||||
|
||||
//mxd. Absolute lights are not affected by brightness transfers...
|
||||
private bool lightfloorabsolute;
|
||||
private bool lightceilingabsolute;
|
||||
private int lightfloor;
|
||||
private int lightceiling;
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Properties
|
||||
|
@ -299,18 +305,17 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
// Fetch ZDoom fields
|
||||
int color = sector.Fields.GetValue("lightcolor", -1);
|
||||
int flight = sector.Fields.GetValue("lightfloor", 0);
|
||||
bool fabs = sector.Fields.GetValue("lightfloorabsolute", false);
|
||||
int clight = sector.Fields.GetValue("lightceiling", 0);
|
||||
bool cabs = sector.Fields.GetValue("lightceilingabsolute", false);
|
||||
//int alpha = sector.Fields.GetValue("lightalpha", 255);
|
||||
lightfloor = sector.Fields.GetValue("lightfloor", 0);
|
||||
lightfloorabsolute = sector.Fields.GetValue("lightfloorabsolute", false);
|
||||
lightceiling = sector.Fields.GetValue("lightceiling", 0);
|
||||
lightceilingabsolute = sector.Fields.GetValue("lightceilingabsolute", false);
|
||||
|
||||
// Determine colors & light levels
|
||||
PixelColor lightcolor = PixelColor.FromInt(color);
|
||||
if(!fabs) flight = sector.Brightness + flight;
|
||||
if(!cabs) clight = sector.Brightness + clight;
|
||||
PixelColor floorbrightness = PixelColor.FromInt(mode.CalculateBrightness(flight));
|
||||
PixelColor ceilingbrightness = PixelColor.FromInt(mode.CalculateBrightness(clight));
|
||||
if(!lightfloorabsolute) lightfloor = sector.Brightness + lightfloor;
|
||||
if(!lightceilingabsolute) lightceiling = sector.Brightness + lightceiling;
|
||||
PixelColor floorbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightfloor));
|
||||
PixelColor ceilingbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightceiling));
|
||||
PixelColor floorcolor = PixelColor.Modulate(lightcolor, floorbrightness);
|
||||
PixelColor ceilingcolor = PixelColor.Modulate(lightcolor, ceilingbrightness);
|
||||
floor.color = floorcolor.WithAlpha(255).ToInt();
|
||||
|
@ -369,7 +374,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
lightlevels[lightlevels.Count - 1].colorbelow = stored.colorbelow;
|
||||
lightlevels[lightlevels.Count - 1].brightnessbelow = stored.brightnessbelow;
|
||||
lightlevels[lightlevels.Count - 1].color = GetLevelColor(stored);
|
||||
lightlevels[lightlevels.Count - 1].color = GetLevelColor(stored, lightlevels[lightlevels.Count - 1]);
|
||||
}
|
||||
|
||||
//mxd. Cast light properties from top to bottom
|
||||
|
@ -390,12 +395,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
l.colorbelow = stored.colorbelow;
|
||||
l.brightnessbelow = stored.brightnessbelow;
|
||||
l.color = GetLevelColor(stored);
|
||||
l.color = GetLevelColor(stored, l);
|
||||
}
|
||||
else if(l.restrictlighting)
|
||||
{
|
||||
if(!pl.restrictlighting && pl != ceiling) stored = pl;
|
||||
l.color = GetLevelColor(stored);
|
||||
l.color = GetLevelColor(stored, l);
|
||||
|
||||
// This is the bottom side of extrafloor with "restrict lighting" flag. Make it cast stored light props.
|
||||
if(l.type == SectorLevelType.Ceiling)
|
||||
|
@ -406,10 +411,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// Use light and color settings from previous layer
|
||||
l.colorbelow = pl.colorbelow;
|
||||
l.brightnessbelow = pl.brightnessbelow;
|
||||
l.color = GetLevelColor(pl);
|
||||
l.color = GetLevelColor(pl, l);
|
||||
|
||||
// Also colorize previous layer using next higher level color
|
||||
if(i + 2 < lightlevels.Count) pl.color = GetLevelColor(lightlevels[i + 2]);
|
||||
if(i + 2 < lightlevels.Count) pl.color = GetLevelColor(lightlevels[i + 2], pl);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -452,7 +457,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
if(src.colorbelow.a > 0 && src.brightnessbelow != -1)
|
||||
{
|
||||
// Only surface brightness is retained when a glowing flat is used as extrafloor texture
|
||||
if(!l.affectedbyglow) l.color = GetLevelColor(src);
|
||||
if(!l.affectedbyglow) l.color = GetLevelColor(src, l);
|
||||
|
||||
// Transfer brightnessbelow and colorbelow if current level is not extrafloor top
|
||||
if(!(l.extrafloor && l.type == SectorLevelType.Floor))
|
||||
|
@ -604,9 +609,16 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
|
||||
//mxd
|
||||
private int GetLevelColor(SectorLevel src)
|
||||
private int GetLevelColor(SectorLevel src, SectorLevel target)
|
||||
{
|
||||
PixelColor brightness = PixelColor.FromInt(mode.CalculateBrightness(src.brightnessbelow));
|
||||
PixelColor brightness;
|
||||
if(lightfloorabsolute && target == floor)
|
||||
brightness = PixelColor.FromInt(mode.CalculateBrightness(lightfloor));
|
||||
else if(lightceilingabsolute && target == ceiling)
|
||||
brightness = PixelColor.FromInt(mode.CalculateBrightness(lightceiling));
|
||||
else
|
||||
brightness = PixelColor.FromInt(mode.CalculateBrightness(src.brightnessbelow));
|
||||
|
||||
PixelColor color = PixelColor.Modulate(src.colorbelow, brightness);
|
||||
return color.WithAlpha(255).ToInt();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue