Visual mode: rewritten most of the 3d floor clipping and light/color assignment logic. As a result, 3d floors should look much closer to what's seen in GZDoom.

Fixed, Visual mode: glow effect was not updated when changing sector textures using the "Select Texture" action.
Browse Textures/Flats window: when textures list is focused, you can now start typing to change the Filter.
This commit is contained in:
MaxED 2015-11-20 14:31:54 +00:00
parent b7ebde6b7e
commit 098e9724d9
19 changed files with 434 additions and 391 deletions

View file

@ -115,6 +115,7 @@ namespace CodeImp.DoomBuilder.Controls
this.list.DrawItem += new System.Windows.Forms.DrawListViewItemEventHandler(this.list_DrawItem);
this.list.DoubleClick += new System.EventHandler(this.list_DoubleClick);
this.list.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.list_ItemSelectionChanged);
this.list.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.list_KeyPress);
//
// showsubdirtextures
//

View file

@ -19,6 +19,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Windows;
@ -273,6 +274,25 @@ namespace CodeImp.DoomBuilder.Controls
if(SelectedItemDoubleClicked != null) SelectedItemDoubleClicked();
}
//mxd. Transfer focus to Filter textbox
private void list_KeyPress(object sender, KeyPressEventArgs e)
{
objectname.Focus();
if(e.KeyChar == '\b') // Any better way to check for Backspace?..
{
if(!string.IsNullOrEmpty(objectname.Text) && objectname.SelectionStart > 0 && objectname.SelectionLength == 0)
{
int s = objectname.SelectionStart - 1;
objectname.Text = objectname.Text.Remove(s, 1);
objectname.SelectionStart = s;
}
}
else
{
objectname.AppendText(e.KeyChar.ToString(CultureInfo.InvariantCulture));
}
}
//mxd
private void cbMixMode_SelectedIndexChanged(object sender, EventArgs e)
{

View file

@ -147,7 +147,7 @@ float4 ps_main_highlight(PixelData pd) : COLOR
// Blend texture color and vertex color
float4 ncolor = tcolor * pd.color;
return float4(highlightcolor.rgb * highlightcolor.a + (ncolor.rgb - 0.4f * highlightcolor.a), ncolor.a + 0.25f);
return float4(highlightcolor.rgb * highlightcolor.a + (ncolor.rgb - 0.4f * highlightcolor.a), max(pd.color.a + 0.25f, 0.5f));
}
// Full-bright pixel shader with highlight
@ -159,7 +159,7 @@ float4 ps_fullbright_highlight(PixelData pd) : COLOR
// Blend texture color and vertex color
float4 ncolor = tcolor * pd.color;
return float4(highlightcolor.rgb * highlightcolor.a + (tcolor.rgb - 0.4f * highlightcolor.a), ncolor.a + 0.25f);
return float4(highlightcolor.rgb * highlightcolor.a + (tcolor.rgb - 0.4f * highlightcolor.a), max(pd.color.a + 0.25f, 0.5f));
}
//mxd. This adds fog color to current pixel color

View file

@ -1899,6 +1899,7 @@ namespace CodeImp.DoomBuilder.Windows
//
this.statuslabel.Image = global::CodeImp.DoomBuilder.Properties.Resources.Status2;
this.statuslabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.statuslabel.Margin = new System.Windows.Forms.Padding(2, 3, 0, 2);
this.statuslabel.Name = "statuslabel";
this.statuslabel.Size = new System.Drawing.Size(340, 18);
this.statuslabel.Spring = true;

View file

@ -42,7 +42,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables
protected BaseVisualMode mode;
protected readonly BaseVisualMode mode;
protected long setuponloadedtexture;
// This is only used to see if this object has already received a change
@ -632,11 +632,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update the visual sector
if(mode.VisualSectorExists(s))
{
BaseVisualSector vs = (mode.GetVisualSector(s) as BaseVisualSector);
if(fillceilings)
vs.Ceiling.Setup();
else
vs.Floor.Setup();
BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(s);
if(fillceilings) vs.Ceiling.Setup();
else vs.Floor.Setup();
}
}
@ -909,6 +907,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
Sector.Rebuild();
}
//mxd
public virtual void OnChangeTextureRotation(float angle)
{
if(!General.Map.UDMF) return;

View file

@ -167,72 +167,70 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
List<WallPolygon> polygons = new List<WallPolygon>(poly);
List<WorldVertex> verts = new List<WorldVertex>();
SectorLevel prevlight = null; //mxd
// Go for all levels to build geometry
for(int i = sd.LightLevels.Count - 1; i >= 0; i--)
//mxd. Do complicated light level shenanigans only when there are extrafloors
if(sd.LightLevels.Count > 2)
{
SectorLevel l = sd.LightLevels[i];
SectorLevel prevlight = null; //mxd
//mxd. Skip current light level when it's between TYPE1 and TYPE1_BOTTOM
if(prevlight != null
&& prevlight.type == SectorLevelType.Light && l.type == SectorLevelType.Light
&& (prevlight.lighttype == LightLevelType.TYPE1 && l.lighttype != LightLevelType.TYPE1_BOTTOM))
continue;
if((l != sd.Floor) && (l != sd.Ceiling) && (l.type != SectorLevelType.Floor || l.alpha < 255))
// Go for all levels to build geometry
for(int i = sd.LightLevels.Count - 1; i >= 0; i--)
{
// Go for all polygons
int num = polygons.Count;
Plane plane = (l.type == SectorLevelType.Floor ? l.plane.GetInverted() : l.plane); //mxd
for(int pi = 0; pi < num; pi++)
SectorLevel l = sd.LightLevels[i];
//mxd. Skip current light level when it's between TYPE1 and TYPE1_BOTTOM
if(prevlight != null
&& prevlight.type == SectorLevelType.Light && l.type == SectorLevelType.Light
&& (prevlight.lighttype == LightLevelType.TYPE1 && l.lighttype != LightLevelType.TYPE1_BOTTOM)) continue;
if((l != sd.Floor) && (l != sd.Ceiling) && (l.type != SectorLevelType.Floor || l.splitsides /*(l.alpha < 255)*/))
{
// Split by plane
WallPolygon p = polygons[pi];
WallPolygon np = SplitPoly(ref p, plane, false);
if(np.Count > 0)
// Go for all polygons
int num = polygons.Count;
Plane plane = (l.type == SectorLevelType.Floor ? l.plane.GetInverted() : l.plane); //mxd
for(int pi = 0; pi < num; pi++)
{
//mxd. Determine color
int lightlevel;
// Split by plane
WallPolygon p = polygons[pi];
WallPolygon np = SplitPoly(ref p, plane, false);
if(np.Count > 0)
{
//mxd. Determine color
int lightlevel;
if(l.disablelighting) //sidedef part is not affected by 3d floor brightness
{
lightlevel = lightabsolute ? lightvalue : l.brightnessbelow + lightvalue;
}
else if(l.restrictlighting || (l.type == SectorLevelType.Floor && l.alpha < 255)) //only happens to a sidedef part inside of a non-opaque 3d floor.
{
lightlevel = l.sector.Brightness;
}
else // "Regular" 3d floor transfers brightness below it ignoring sidedef's brightness.
{
lightlevel = l.brightnessbelow;
}
// Sidedef part is not affected by 3d floor brightness
if(l.disablelighting || !l.extrafloor)
lightlevel = (lightabsolute ? lightvalue : l.brightnessbelow + lightvalue);
// 3d floor transfers brightness below it ignoring sidedef's brightness
else
lightlevel = l.brightnessbelow;
PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef)); //mxd
np.color = PixelColor.Modulate(l.colorbelow, wallbrightness).WithAlpha(255).ToInt();
if(p.Count == 0)
{
polygons[pi] = np;
PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef)); //mxd
np.color = PixelColor.Modulate(l.colorbelow, wallbrightness).WithAlpha(255).ToInt();
if(p.Count == 0)
{
polygons[pi] = np;
}
else
{
polygons[pi] = p;
polygons.Add(np);
}
}
else
{
polygons[pi] = p;
polygons.Add(np);
}
}
else
{
polygons[pi] = p;
}
}
}
//mxd
if(l.type == SectorLevelType.Light) prevlight = l;
//mxd
if(l.type == SectorLevelType.Light) prevlight = l;
}
}
// Go for all polygons to make geometry
foreach(WallPolygon p in polygons)
{
@ -446,6 +444,46 @@ namespace CodeImp.DoomBuilder.BuilderModes
poly = newp;
}
//mxd. This clips given polys by extrafloors
protected void ClipExtraFloors(List<WallPolygon> polygons, List<Effect3DFloor> extrafloors, bool clipalways)
{
foreach(Effect3DFloor ef in extrafloors)
{
//mxd. Walls should be clipped by 3D floors
if(ef.ClipSidedefs || clipalways)
{
int num = polygons.Count;
for(int pi = 0; pi < num; pi++)
{
// Split by floor plane of 3D floor
WallPolygon p = polygons[pi];
WallPolygon np = SplitPoly(ref p, ef.Ceiling.plane, true);
if(np.Count > 0)
{
// Split part below floor by the ceiling plane of 3D floor
// and keep only the part below the ceiling (front)
SplitPoly(ref np, ef.Floor.plane, true);
if(p.Count == 0)
{
polygons[pi] = np;
}
else
{
polygons[pi] = p;
polygons.Add(np);
}
}
else
{
polygons[pi] = p;
}
}
}
}
}
//mxd
protected void GetLightValue(out int lightvalue, out bool lightabsolute)
{
@ -754,14 +792,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
else if(this is VisualMiddleDouble)
{
if (Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
{
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
offsety = (options.Bounds.Y - Sidedef.GetHighHeight() - Sidedef.GetLowHeight()) * scaley - Sidedef.OffsetY;
}
else
{
offsety = options.Bounds.Y * scaley - Sidedef.OffsetY;
}
}
else
{
@ -878,22 +912,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
// Change ceiling
case 1:
if(!this.Sector.Ceiling.Changed)
this.Sector.Ceiling.OnChangeTargetHeight(amount);
if(!this.Sector.Ceiling.Changed) this.Sector.Ceiling.OnChangeTargetHeight(amount);
break;
// Change floor
case 2:
if(!this.Sector.Floor.Changed)
this.Sector.Floor.OnChangeTargetHeight(amount);
if(!this.Sector.Floor.Changed) this.Sector.Floor.OnChangeTargetHeight(amount);
break;
// Change both
case 3:
if(!this.Sector.Floor.Changed)
this.Sector.Floor.OnChangeTargetHeight(amount);
if(!this.Sector.Ceiling.Changed)
this.Sector.Ceiling.OnChangeTargetHeight(amount);
if(!this.Sector.Floor.Changed) this.Sector.Floor.OnChangeTargetHeight(amount);
if(!this.Sector.Ceiling.Changed) this.Sector.Ceiling.OnChangeTargetHeight(amount);
break;
}
}
@ -1131,7 +1161,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update the parts for this sidedef!
if(mode.VisualSectorExists(sd.Sector))
{
BaseVisualSector vs = (mode.GetVisualSector(sd.Sector) as BaseVisualSector);
BaseVisualSector vs = (BaseVisualSector)mode.GetVisualSector(sd.Sector);
VisualSidedefParts parts = vs.GetSidedefParts(sd);
parts.SetupAllParts();
}

View file

@ -2771,6 +2771,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
General.Interface.RedrawDisplay();
GetTargetEventReceiver(false).OnSelectTexture();
UpdateChangedObjects();
RebuildElementData(); //mxd. Extrafloors or Glow effects may've been changed
renderer.SetCrosshairBusy(false);
PostAction();
}

View file

@ -13,7 +13,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
// Linedef that is used to create this effect
// The sector can be found by linedef.Front.Sector
private Linedef linedef;
private readonly Linedef linedef;
// Floor and ceiling planes
private SectorLevel floor;
@ -25,12 +25,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Vavoom type?
private bool vavoomtype;
//mxd. Translucent 3d-floor?
//mxd. Render backsides?
private bool renderinside;
//mxd. Dirty hack to emulate GZDoom behaviour?
private bool sloped3dfloor;
//mxd. Render using Additive pass?
private bool renderadditive;
//mxd. Sidedef should be clipped by floor/ceiling?
private bool clipsides;
//mxd. Ignore Bottom Height?
private bool ignorebottomheight;
@ -41,8 +47,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
public Linedef Linedef { get { return linedef; } }
public bool VavoomType { get { return vavoomtype; } }
public bool RenderInside { get { return renderinside; } } //mxd
public bool RenderAdditive { get { return renderadditive; } } //mxd
public bool IgnoreBottomHeight { get { return ignorebottomheight; } } //mxd
public bool Sloped3dFloor { get { return sloped3dfloor; } } //mxd
public bool ClipSidedefs { get { return clipsides; } } //mxd
//mxd. 3D-Floor Flags
[Flags]
@ -107,26 +115,33 @@ namespace CodeImp.DoomBuilder.BuilderModes
// For non-vavoom types, we must switch the level types
if(linedef.Args[1] != (int)FloorTypes.VavoomStyle)
{
//mxd. check for Swimmable/RenderInside/RenderAdditive flags
renderadditive = (linedef.Args[2] & (int)Flags.RenderAdditive) == (int)Flags.RenderAdditive;
renderinside = ((((linedef.Args[1] & (int)FloorTypes.Swimmable) == (int)FloorTypes.Swimmable) && (linedef.Args[1] & (int)FloorTypes.NonSolid) != (int)FloorTypes.NonSolid))
|| ((linedef.Args[1] & (int)FloorTypes.RenderInside) == (int)FloorTypes.RenderInside);
ignorebottomheight = ((linedef.Args[2] & (int)Flags.IgnoreBottomHeight) == (int)Flags.IgnoreBottomHeight);
vavoomtype = false;
alpha = linedef.Args[3];
alpha = General.Clamp(linedef.Args[3], 0, 255);
sd.Ceiling.CopyProperties(floor);
sd.Floor.CopyProperties(ceiling);
floor.type = SectorLevelType.Floor;
floor.plane = sd.Ceiling.plane.GetInverted();
ceiling.type = SectorLevelType.Ceiling;
ceiling.plane = sd.Floor.plane.GetInverted();
ceiling.plane = (ignorebottomheight ? sd.Ceiling.plane : sd.Floor.plane.GetInverted()); //mxd. Use upper plane when "ignorebottomheight" flag is set
//mxd. check for Swimmable/RenderInside setting
renderinside = ( (((linedef.Args[1] & (int)FloorTypes.Swimmable) == (int)FloorTypes.Swimmable) && (linedef.Args[1] & (int)FloorTypes.NonSolid) != (int)FloorTypes.NonSolid) )
|| ((linedef.Args[1] & (int)FloorTypes.RenderInside) == (int)FloorTypes.RenderInside);
ignorebottomheight = ((linedef.Args[2] & (int)Flags.IgnoreBottomHeight) == (int)Flags.IgnoreBottomHeight);
//mxd
clipsides = (!renderinside && !renderadditive && alpha > 254 && !ignorebottomheight);
// A 3D floor's color is always that of the sector it is placed in
floor.color = 0;
// (unless it's affected by glow) - mxd
if(sd.CeilingGlow == null || !sd.CeilingGlow.Fullbright) floor.color = 0;
}
else
{
vavoomtype = true;
renderadditive = false; //mxd
clipsides = true; //mxd
floor.type = SectorLevelType.Ceiling;
floor.plane = sd.Ceiling.plane;
ceiling.type = SectorLevelType.Floor;
@ -134,33 +149,48 @@ namespace CodeImp.DoomBuilder.BuilderModes
alpha = 255;
// A 3D floor's color is always that of the sector it is placed in
ceiling.color = 0;
// (unless it's affected by glow) - mxd
if(sd.FloorGlow == null || !sd.FloorGlow.Fullbright) ceiling.color = 0;
}
// Apply alpha
floor.alpha = alpha;
ceiling.alpha = alpha;
//mxd
floor.extrafloor = true;
ceiling.extrafloor = true;
floor.splitsides = !clipsides;
ceiling.splitsides = (!clipsides && !ignorebottomheight); // if "ignorebottomheight" flag is set, both ceiling and floor will be at the same level and sidedef clipping with floor level will fail resulting in incorrect light props transfer in some cases
//mxd. Check slopes, cause GZDoom can't handle sloped translucent 3d floors...
sloped3dfloor = (alpha < 255 &&
sloped3dfloor = ((alpha < 255 || renderadditive) &&
(Angle2D.RadToDeg(ceiling.plane.Normal.GetAngleZ()) != 270 ||
Angle2D.RadToDeg(floor.plane.Normal.GetAngleZ()) != 90));
// Do not adjust light? (works only for non-vavoom types)
if(!vavoomtype)
{
bool disablelighting = ((linedef.Args[2] & (int) Flags.DisableLighting) == (int) Flags.DisableLighting); //mxd
bool restrictlighting = alpha < 255 && ((linedef.Args[2] & (int) Flags.RestrictLighting) == (int) Flags.RestrictLighting); //mxd
bool disablelighting = ((linedef.Args[2] & (int)Flags.DisableLighting) == (int)Flags.DisableLighting); //mxd
bool restrictlighting = (alpha < 255 || renderadditive || renderinside) && ((linedef.Args[2] & (int)Flags.RestrictLighting) == (int)Flags.RestrictLighting); //mxd
if(disablelighting || restrictlighting)
{
floor.brightnessbelow = -1;
floor.restrictlighting = restrictlighting; //mxd
floor.disablelighting = disablelighting; //mxd
floor.colorbelow = PixelColor.FromInt(0);
if(disablelighting) //mxd
{
floor.color = 0;
floor.brightnessbelow = -1;
floor.colorbelow = PixelColor.FromInt(0);
}
ceiling.disablelighting = disablelighting; //mxd
ceiling.restrictlighting = restrictlighting; //mxd
ceiling.color = 0;
ceiling.brightnessbelow = -1;
ceiling.disablelighting = true; //mxd
ceiling.colorbelow = PixelColor.FromInt(0);
}
}

View file

@ -46,7 +46,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Original floor and ceiling levels
private readonly SectorLevel floor;
private readonly SectorLevel floorbase; // mxd. Sector floor level, unaffected by glow / light properties transfer
private readonly SectorLevel ceiling;
private readonly SectorLevel ceilingbase; // mxd. Sector ceiling level, unaffected by glow / light properties transfer
// This helps keeping track of changes
// otherwise we update ceiling/floor too much
@ -86,7 +88,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.alleffects = new List<SectorEffect>(1);
this.updatesectors = new Dictionary<Sector, bool>(2);
this.floor = new SectorLevel(sector, SectorLevelType.Floor);
this.floorbase = new SectorLevel(sector, SectorLevelType.Floor); //mxd
this.ceiling = new SectorLevel(sector, SectorLevelType.Ceiling);
this.ceilingbase = new SectorLevel(sector, SectorLevelType.Ceiling); //mxd
BasicSetup();
@ -271,6 +275,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
ceiling.color = ceilingcolor.WithAlpha(255).ToInt();
ceiling.brightnessbelow = sector.Brightness;
ceiling.colorbelow = lightcolor.WithAlpha(255);
//mxd. Store a copy of initial settings
floor.CopyProperties(floorbase);
ceiling.CopyProperties(ceilingbase);
}
//mxd
@ -294,73 +302,122 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update all effects
foreach(SectorEffect e in alleffects) e.Update();
// Sort the levels (only if there are more than 2 sector levels - mxd)
if (lightlevels.Count > 2)
//mxd. Do complicated light level shenanigans only when there are extrafloors
if(lightlevels.Count > 2)
{
// Sort the levels
SectorLevelComparer comparer = new SectorLevelComparer(sector);
lightlevels.Sort(0, lightlevels.Count, comparer); //mxd. Was lightlevels.Sort(1, lightlevels.Count - 2, comparer);
}
lightlevels.Sort(0, lightlevels.Count, comparer);
//mxd. 3d floors can be above the real ceiling, so let's find it first...
int startindex = lightlevels.Count - 2;
for(int i = lightlevels.Count - 2; i >= 0; i--)
{
if(lightlevels[i].type == SectorLevelType.Ceiling && lightlevels[i].sector.Index == sector.Index)
// Now that we know the levels in this sector (and in the right order)
// we can determine the lighting in between and on the levels.
SectorLevel stored = ceilingbase;
//mxd. Special cases...
if(lightlevels[lightlevels.Count - 1].disablelighting)
{
startindex = i;
break;
lightlevels[lightlevels.Count - 1].colorbelow = stored.colorbelow;
lightlevels[lightlevels.Count - 1].brightnessbelow = stored.brightnessbelow;
lightlevels[lightlevels.Count - 1].color = stored.colorbelow.ToInt();
}
}
// Now that we know the levels in this sector (and in the right order) we
// can determine the lighting in between and on the levels.
// Start from the absolute ceiling and go down to 'cast' the lighting
SectorLevel stored = ceiling; //mxd
for(int i = startindex; i >= 0; i--)
{
SectorLevel l = lightlevels[i];
SectorLevel pl = lightlevels[i + 1];
if(l.lighttype == LightLevelType.TYPE1) stored = pl; //mxd
//mxd. If the real floor has "lightfloor" value and the 3d floor above it doesn't cast down light, use real floor's brightness
if(General.Map.UDMF && l == floor && lightlevels.Count > 2 && (pl.disablelighting || pl.restrictlighting) && l.sector.Fields.ContainsKey("lightfloor"))
//mxd. Cast light properties from top to bottom
for(int i = lightlevels.Count - 2; i >= 0; i--)
{
int light = l.sector.Fields.GetValue("lightfloor", pl.brightnessbelow);
pl.brightnessbelow = (l.sector.Fields.GetValue("lightfloorabsolute", false) ? light : l.sector.Brightness + light);
}
// Set color when no color is specified, or when a 3D floor is placed above the absolute floor
//mxd. Or when lightlevel is above a floor/ceiling level
bool uselightlevellight = ((l.type != SectorLevelType.Light) && pl != null && pl.type == SectorLevelType.Light); //mxd
if((l.color == 0) || ((l == floor) && (lightlevels.Count > 2)) || uselightlevellight)
{
PixelColor floorbrightness = PixelColor.FromInt(mode.CalculateBrightness(pl.brightnessbelow));
PixelColor floorcolor = PixelColor.Modulate(pl.colorbelow, floorbrightness);
l.color = floorcolor.WithAlpha(255).ToInt();
SectorLevel l = lightlevels[i];
SectorLevel pl = lightlevels[i + 1];
if(uselightlevellight) l.brightnessbelow = pl.brightnessbelow;
}
//mxd. Bottom TYPE1 border requires special handling...
else if(l.lighttype == LightLevelType.TYPE1_BOTTOM)
{
//Use brightness and color from previous light level when it's between TYPE1 and TYPE1_BOTTOM levels
if(pl.type == SectorLevelType.Light && pl.lighttype != LightLevelType.TYPE1)
if(l.lighttype == LightLevelType.TYPE1)
{
l.brightnessbelow = pl.brightnessbelow;
l.colorbelow = pl.colorbelow;
stored = pl;
}
//Use brightness and color from the light level above TYPE1 level
else if(stored.type == SectorLevelType.Light)
// Use stored light params when "disablelighting" flag is set
else if(l.disablelighting)
{
l.brightnessbelow = stored.brightnessbelow;
l.colorbelow = stored.colorbelow;
l.brightnessbelow = stored.brightnessbelow;
l.color = stored.colorbelow.ToInt();
}
// Otherwise light values from the real ceiling are used
}
else if(l.restrictlighting)
{
if(!pl.restrictlighting && pl != ceiling) stored = pl;
l.color = stored.color;
if(l.colorbelow.a == 0) l.colorbelow = pl.colorbelow;
if(l.brightnessbelow == -1) l.brightnessbelow = pl.brightnessbelow;
// This is the bottom side of extrafloor with "restrict lighting" flag. Make it cast stored light props.
if(l.type == SectorLevelType.Ceiling)
{
// Special case: 2 intersecting extrafloors with "restrictlighting" flag...
if(pl.restrictlighting && pl.type == SectorLevelType.Floor && pl.sector.Index != l.sector.Index)
{
// Use light and color settings from previous layer
l.colorbelow = pl.colorbelow;
l.brightnessbelow = pl.brightnessbelow;
l.color = pl.colorbelow.ToInt();
// Also colorize previous layer using next higher level color
if(i + 2 < lightlevels.Count)
pl.color = lightlevels[i + 2].colorbelow.ToInt();
}
else
{
l.colorbelow = stored.colorbelow;
l.brightnessbelow = stored.brightnessbelow;
}
}
}
// Bottom TYPE1 border requires special handling...
else if(l.lighttype == LightLevelType.TYPE1_BOTTOM)
{
// Use brightness and color from previous light level when it's between TYPE1 and TYPE1_BOTTOM levels
if(pl.type == SectorLevelType.Light && pl.lighttype != LightLevelType.TYPE1)
{
l.brightnessbelow = pl.brightnessbelow;
l.colorbelow = pl.colorbelow;
}
// Use brightness and color from the light level above TYPE1 level
else if(stored.type == SectorLevelType.Light)
{
l.brightnessbelow = stored.brightnessbelow;
l.colorbelow = stored.colorbelow;
}
// Otherwise light values from the real ceiling are used
}
else if(l.lighttype == LightLevelType.UNKNOWN)
{
// Use stored light level when previous one has "disablelighting" flag
// or is the lower boundary of an extrafloor with "restrictlighting" flag
SectorLevel src = (pl.disablelighting || (pl.restrictlighting && pl.type == SectorLevelType.Ceiling) ? stored : pl);
if((src == l) || (src == ceiling && l == floor && src.LightPropertiesMatch(ceilingbase)))
{
// Don't change anything when light properties were reset before hitting floor
// (otherwise floor UDMF brightness will be lost)
continue;
}
// Transfer color and brightness if previous level has them
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)
{
PixelColor brightness = PixelColor.FromInt(mode.CalculateBrightness(src.brightnessbelow));
PixelColor color = PixelColor.Modulate(src.colorbelow, brightness);
l.color = color.WithAlpha(255).ToInt();
}
// Transfer brightnessbelow and colorbelow if current level is not extrafloor top
if(!(l.extrafloor && l.type == SectorLevelType.Floor))
{
l.brightnessbelow = src.brightnessbelow;
l.colorbelow = src.colorbelow;
}
}
// Store bottom extrafloor level if it doesn't have "restrictlighting" or "restrictlighting" flags set
if(l.extrafloor && l.type == SectorLevelType.Ceiling && !l.restrictlighting && !l.disablelighting) stored = l;
}
}
}
//mxd. Apply ceiling glow effect?

View file

@ -36,6 +36,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
public bool disablelighting; //mxd
public bool restrictlighting; //mxd
public bool affectedbyglow; //mxd
public bool extrafloor; //mxd
public bool splitsides; //mxd
// Constructor
public SectorLevel(Sector s, SectorLevelType type)
@ -43,6 +45,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.type = type;
this.sector = s;
this.alpha = 255;
this.splitsides = true; //mxd
}
// Copy constructor
@ -62,8 +65,46 @@ namespace CodeImp.DoomBuilder.BuilderModes
target.color = this.color;
target.brightnessbelow = this.brightnessbelow;
target.colorbelow = this.colorbelow;
target.affectedbyglow = this.affectedbyglow; //mxd
target.disablelighting = this.disablelighting; //mxd
target.restrictlighting = this.restrictlighting; //mxd
target.splitsides = this.splitsides; //mxd
}
//mxd. Compare light properties
public bool LightPropertiesMatch(SectorLevel other)
{
return (this.type == other.type && this.lighttype == other.lighttype && this.alpha == other.alpha && this.splitsides == other.splitsides
&& this.color == other.color && this.brightnessbelow == other.brightnessbelow && this.colorbelow.ToInt() == other.colorbelow.ToInt()
&& this.disablelighting == other.disablelighting && this.restrictlighting == other.restrictlighting);
}
#if DEBUG
//mxd. Handy when debugging
public override string ToString()
{
switch(type)
{
case SectorLevelType.Ceiling: return (extrafloor ? "ExtraCeiling" : "Ceiling");
case SectorLevelType.Floor: return (extrafloor ? "ExtraFloor" : "Floor");
case SectorLevelType.Glow: return "Glow Level";
case SectorLevelType.Light: return "Light Level (" + GetLightType() + ")";
default: return "Unknown Level Type!!!";
}
}
//mxd. Handy when debugging
private string GetLightType()
{
switch(lighttype)
{
case LightLevelType.TYPE0: return "Type 0";
case LightLevelType.TYPE1: return "Type 1";
case LightLevelType.TYPE1_BOTTOM: return "Type 1 (bottom)";
case LightLevelType.TYPE2: return "Type 2";
default: return "Unknown";
}
}
#endif
}
}

View file

@ -27,6 +27,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
float diff = (float)Math.Round(x.plane.GetZ(center) - y.plane.GetZ(center), 3);
if(diff == 0)
{
//mxd. Push extrafloors above extraceilings
if(x.extrafloor && y.extrafloor && x.lighttype == LightLevelType.UNKNOWN && y.lighttype == LightLevelType.UNKNOWN)
{
if(x.type == SectorLevelType.Floor) return (y.type == SectorLevelType.Ceiling ? 1 : 0);
return (y.type == SectorLevelType.Floor ? -1 : 0);
}
bool xislight = (x.type == SectorLevelType.Light || x.type == SectorLevelType.Glow);
bool yislight = (y.type == SectorLevelType.Light || y.type == SectorLevelType.Glow);

View file

@ -163,7 +163,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
if(extrafloor.Sloped3dFloor) //mxd
this.RenderPass = RenderPass.Mask;
else if((extrafloor.Linedef.Args[2] & (int)Effect3DFloor.Flags.RenderAdditive) != 0) //mxd
else if(extrafloor.RenderAdditive) //mxd
this.RenderPass = RenderPass.Additive;
else if(level.alpha < 255)
this.RenderPass = RenderPass.Alpha;
@ -187,10 +187,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Return texture coordinates
protected override Point GetTextureOffset()
{
Point p = new Point();
p.X = (int)Sector.Sector.Fields.GetValue("xpanningceiling", 0.0f);
p.Y = (int)Sector.Sector.Fields.GetValue("ypanningceiling", 0.0f);
return p;
return new Point { X = (int)Sector.Sector.Fields.GetValue("xpanningceiling", 0.0f),
Y = (int)Sector.Sector.Fields.GetValue("ypanningceiling", 0.0f) };
}
// Move texture coordinates
@ -357,19 +355,19 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Sector brightness change
public override void OnChangeTargetBrightness(bool up)
{
if (level != null && level.sector != Sector.Sector)
if(level != null && level.sector != Sector.Sector)
{
int index = -1;
for (int i = 0; i < Sector.ExtraCeilings.Count; i++)
for(int i = 0; i < Sector.ExtraCeilings.Count; i++)
{
if (Sector.ExtraCeilings[i] == this)
if(Sector.ExtraCeilings[i] == this)
{
index = i + 1;
break;
}
}
if (index > -1 && index < Sector.ExtraCeilings.Count)
if(index > -1 && index < Sector.ExtraCeilings.Count)
((BaseVisualSector)mode.GetVisualSector(Sector.ExtraCeilings[index].level.sector)).Floor.OnChangeTargetBrightness(up);
else
base.OnChangeTargetBrightness(up);
@ -377,7 +375,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else
{
//if a map is not in UDMF format, or this ceiling is part of 3D-floor...
if(!General.Map.UDMF || Sector.Sector != level.sector)
if(!General.Map.UDMF || (level != null && Sector.Sector != level.sector))
{
base.OnChangeTargetBrightness(up);
return;
@ -594,8 +592,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
slopeSource = side.Line;
isFront = true;
break;
}
else if(side.Line.Args[1] == 2 && side.Line.Back != null && side.Line.Back == side)
}
if(side.Line.Args[1] == 2 && side.Line.Back != null && side.Line.Back == side)
{
slopeSource = side.Line;
break;

View file

@ -165,7 +165,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{
if(extrafloor.Sloped3dFloor) //mxd
this.RenderPass = RenderPass.Mask;
else if((extrafloor.Linedef.Args[2] & (int)Effect3DFloor.Flags.RenderAdditive) != 0) //mxd
else if(extrafloor.RenderAdditive) //mxd
this.RenderPass = RenderPass.Additive;
else if(level.alpha < 255)
this.RenderPass = RenderPass.Alpha;
@ -189,10 +189,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Return texture coordinates
protected override Point GetTextureOffset()
{
Point p = new Point();
p.X = (int)Sector.Sector.Fields.GetValue("xpanningfloor", 0.0f);
p.Y = (int)Sector.Sector.Fields.GetValue("ypanningfloor", 0.0f);
return p;
return new Point { X = (int)Sector.Sector.Fields.GetValue("xpanningfloor", 0.0f),
Y = (int)Sector.Sector.Fields.GetValue("ypanningfloor", 0.0f) };
}
// Move texture coordinates
@ -359,11 +357,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Sector brightness change
public override void OnChangeTargetBrightness(bool up)
{
if (level != null)
if(level != null)
{
if (level.sector != Sector.Sector) //this floor is part of 3D-floor
if(level.sector != Sector.Sector) //this floor is part of 3D-floor
((BaseVisualSector)mode.GetVisualSector(level.sector)).Floor.OnChangeTargetBrightness(up);
else if (Sector.ExtraFloors.Count > 0) //this is actual floor of a sector with extrafloors
else if(Sector.ExtraFloors.Count > 0 && !Sector.ExtraFloors[0].ExtraFloor.Floor.restrictlighting) //this is actual floor of a sector with extrafloors
Sector.ExtraFloors[0].OnChangeTargetBrightness(up);
else
base.OnChangeTargetBrightness(up);

View file

@ -184,43 +184,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
CropPoly(ref poly, osd.Ceiling.plane, true);
// Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1);
polygons.Add(poly);
foreach(Effect3DFloor ef in sd.ExtraFloors)
{
//mxd. Walls should be clipped by solid 3D floors
if(!ef.RenderInside && ef.Alpha == 255)
{
int num = polygons.Count;
for(int pi = 0; pi < num; pi++)
{
// Split by floor plane of 3D floor
WallPolygon p = polygons[pi];
WallPolygon np = SplitPoly(ref p, ef.Ceiling.plane, true);
if(np.Count > 0)
{
// Split part below floor by the ceiling plane of 3D floor
// and keep only the part below the ceiling (front)
SplitPoly(ref np, ef.Floor.plane, true);
if(p.Count == 0)
{
polygons[pi] = np;
}
else
{
polygons[pi] = p;
polygons.Add(np);
}
}
else
{
polygons[pi] = p;
}
}
}
}
List<WallPolygon> polygons = new List<WallPolygon> { poly };
ClipExtraFloors(polygons, sd.ExtraFloors, false); //mxd
if(polygons.Count > 0)
{

View file

@ -228,12 +228,16 @@ namespace CodeImp.DoomBuilder.BuilderModes
CropPoly(ref poly, extrafloor.Ceiling.plane, false);
// Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1);
polygons.Add(poly);
List<WallPolygon> polygons = new List<WallPolygon> { poly };
bool translucent = (extrafloor.RenderAdditive || extrafloor.Alpha < 255);
foreach(Effect3DFloor ef in sd.ExtraFloors)
{
//mxd. Walls of solid 3D floors shouldn't be clipped by translucent 3D floors
if(extrafloor.Alpha < 255 || (!extrafloor.RenderInside && !ef.RenderInside && extrafloor.Alpha == 255 && ef.Alpha == 255))
//mxd. Our poly should be clipped when our ond other extrafloors are both solid or both translucent,
// or when only our extrafloor is translucent.
// Our poly should not be clipped when our extrafloor is translucent and the other one isn't and both have renderinside setting.
bool othertranslucent = (ef.RenderAdditive || ef.Alpha < 255);
if(translucent && !othertranslucent && !ef.ClipSidedefs) continue;
if(ef.ClipSidedefs == extrafloor.ClipSidedefs || ef.ClipSidedefs)
{
int num = polygons.Count;
for(int pi = 0; pi < num; pi++)
@ -267,31 +271,26 @@ namespace CodeImp.DoomBuilder.BuilderModes
}
// Process the polygon and create vertices
if (polygons.Count > 0)
if(polygons.Count > 0)
{
List<WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute);
if (verts.Count > 2)
if(verts.Count > 2)
{
if(extrafloor.Sloped3dFloor) //mxd
this.RenderPass = RenderPass.Mask;
else if((extrafloor.Linedef.Args[2] & (int) Effect3DFloor.Flags.RenderAdditive) != 0) //mxd
this.RenderPass = RenderPass.Additive;
else if(extrafloor.Alpha < 255)
this.RenderPass = RenderPass.Alpha;
else
this.RenderPass = RenderPass.Mask;
if(extrafloor.Sloped3dFloor) this.RenderPass = RenderPass.Mask; //mxd
else if(extrafloor.RenderAdditive) this.RenderPass = RenderPass.Additive; //mxd
else if(extrafloor.Alpha < 255) this.RenderPass = RenderPass.Alpha;
else this.RenderPass = RenderPass.Mask;
if (extrafloor.Alpha < 255)
if(extrafloor.Alpha < 255)
{
// Apply alpha to vertices
byte alpha = (byte) General.Clamp(extrafloor.Alpha, 0, 255);
if (alpha < 255)
byte alpha = (byte)General.Clamp(extrafloor.Alpha, 0, 255);
if(alpha < 255)
{
for (int i = 0; i < verts.Count; i++)
for(int i = 0; i < verts.Count; i++)
{
WorldVertex v = verts[i];
PixelColor c = PixelColor.FromInt(v.c);
v.c = c.WithAlpha(alpha).ToInt();
v.c = PixelColor.FromInt(v.c).WithAlpha(alpha).ToInt();
verts[i] = v;
}
}

View file

@ -12,7 +12,8 @@ using CodeImp.DoomBuilder.Data;
#endregion
namespace CodeImp.DoomBuilder.BuilderModes {
namespace CodeImp.DoomBuilder.BuilderModes
{
//mxd. Used to render translucent 3D floor's inner sides
internal sealed class VisualMiddleBack : BaseVisualGeometrySidedef
{
@ -77,23 +78,23 @@ namespace CodeImp.DoomBuilder.BuilderModes {
//mxd. which texture we must use?
long longtexture = 0;
if ((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.UseUpperTexture) != 0)
if((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.UseUpperTexture) != 0)
{
if (Sidedef.Other.LongHighTexture != MapSet.EmptyLongName)
if(Sidedef.Other.LongHighTexture != MapSet.EmptyLongName)
longtexture = Sidedef.Other.LongHighTexture;
}
else if ((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.UseLowerTexture) != 0)
else if((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.UseLowerTexture) != 0)
{
if(Sidedef.Other.LongLowTexture != MapSet.EmptyLongName)
longtexture = Sidedef.Other.LongLowTexture;
}
else if ((sourceside.LongMiddleTexture != MapSet.EmptyLongName))
else if((sourceside.LongMiddleTexture != MapSet.EmptyLongName))
{
longtexture = sourceside.LongMiddleTexture;
}
// Texture given?
if (longtexture != 0)
if(longtexture != 0)
{
// Load texture
base.Texture = General.Map.Data.GetTextureImage(longtexture);
@ -102,7 +103,7 @@ namespace CodeImp.DoomBuilder.BuilderModes {
base.Texture = General.Map.Data.UnknownTexture3D;
setuponloadedtexture = longtexture;
}
else if (!base.Texture.IsImageLoaded)
else if(!base.Texture.IsImageLoaded)
{
setuponloadedtexture = longtexture;
}
@ -190,53 +191,62 @@ namespace CodeImp.DoomBuilder.BuilderModes {
// Determine initial color
int lightlevel;
PixelColor levelcolor; //mxd
if(((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.DisableLighting) != 0))
{
lightlevel = lightabsolute ? lightvalue : sd.Ceiling.brightnessbelow + lightvalue;
levelcolor = sd.Ceiling.colorbelow; //mxd
}
else
{
lightlevel = lightabsolute ? lightvalue : sourceside.Sector.Brightness + lightvalue;
levelcolor = extrafloor.Floor.colorbelow; //mxd
}
//mxd. This calculates light with doom-style wall shading
PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef));
PixelColor wallcolor = PixelColor.Modulate(sd.Ceiling.colorbelow, wallbrightness);
int wallcolor = PixelColor.Modulate(levelcolor, wallbrightness).WithAlpha((byte)extrafloor.Alpha).ToInt();
fogfactor = CalculateFogDensity(lightlevel);
poly.color = wallcolor.WithAlpha(255).ToInt();
// Cut off the part above the 3D floor and below the 3D ceiling
CropPoly(ref poly, bottom, false);
CropPoly(ref poly, top, false);
// Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1);
polygons.Add(poly);
List<WallPolygon> polygons = new List<WallPolygon> { poly };
foreach(Effect3DFloor ef in sd.ExtraFloors)
{
int num = polygons.Count;
for(int pi = 0; pi < num; pi++)
//mxd. Our poly should be clipped when our ond other extrafloors are both solid or both translucent,
// or when only our extrafloor is translucent
if(ef.ClipSidedefs == extrafloor.ClipSidedefs || ef.ClipSidedefs)
{
// Split by floor plane of 3D floor
WallPolygon p = polygons[pi];
WallPolygon np = SplitPoly(ref p, ef.Ceiling.plane, true);
if(np.Count > 0)
int num = polygons.Count;
for(int pi = 0; pi < num; pi++)
{
// Split part below floor by the ceiling plane of 3D floor
// and keep only the part below the ceiling (front)
SplitPoly(ref np, ef.Floor.plane, true);
// Split by floor plane of 3D floor
WallPolygon p = polygons[pi];
WallPolygon np = SplitPoly(ref p, ef.Ceiling.plane, true);
if(p.Count == 0)
if(np.Count > 0)
{
polygons[pi] = np;
}
else
// Split part below floor by the ceiling plane of 3D floor
// and keep only the part below the ceiling (front)
SplitPoly(ref np, ef.Floor.plane, true);
if(p.Count == 0)
{
polygons[pi] = np;
}
else
{
polygons[pi] = p;
polygons.Add(np);
}
}
else
{
polygons[pi] = p;
polygons.Add(np);
}
}
else
{
polygons[pi] = p;
}
}
}
@ -247,27 +257,17 @@ namespace CodeImp.DoomBuilder.BuilderModes {
List<WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute);
if(verts.Count > 2)
{
if((extrafloor.Linedef.Args[2] & (int) Effect3DFloor.Flags.RenderAdditive) != 0) //mxd
this.RenderPass = RenderPass.Additive;
else if(extrafloor.Alpha < 255)
this.RenderPass = RenderPass.Alpha;
else
this.RenderPass = RenderPass.Mask;
if(extrafloor.Sloped3dFloor) this.RenderPass = RenderPass.Mask; //mxd
else if(extrafloor.RenderAdditive) this.RenderPass = RenderPass.Additive; //mxd
else if(extrafloor.Alpha < 255) this.RenderPass = RenderPass.Alpha;
else this.RenderPass = RenderPass.Mask;
if(extrafloor.Alpha < 255)
//mxd. Inner sides always have extrafloor color
for(int i = 0; i < verts.Count; i++)
{
// Apply alpha to vertices
byte alpha = (byte) General.Clamp(extrafloor.Alpha, 0, 255);
if(alpha < 255)
{
for(int i = 0; i < verts.Count; i++)
{
WorldVertex v = verts[i];
PixelColor c = PixelColor.FromInt(v.c);
v.c = c.WithAlpha(alpha).ToInt();
verts[i] = v;
}
}
WorldVertex v = verts[i];
v.c = wallcolor;
verts[i] = v;
}
base.SetVertices(verts);
@ -288,9 +288,9 @@ namespace CodeImp.DoomBuilder.BuilderModes {
public override string GetTextureName()
{
//mxd
if ((extrafloor.Linedef.Args[2] & (int)Effect3DFloor.Flags.UseUpperTexture) != 0)
if((extrafloor.Linedef.Args[2] & (int)Effect3DFloor.Flags.UseUpperTexture) != 0)
return Sidedef.HighTexture;
if ((extrafloor.Linedef.Args[2] & (int)Effect3DFloor.Flags.UseLowerTexture) != 0)
if((extrafloor.Linedef.Args[2] & (int)Effect3DFloor.Flags.UseLowerTexture) != 0)
return Sidedef.LowTexture;
return extrafloor.Linedef.Front.MiddleTexture;
}
@ -299,9 +299,9 @@ namespace CodeImp.DoomBuilder.BuilderModes {
protected override void SetTexture(string texturename)
{
//mxd
if ((extrafloor.Linedef.Args[2] & (int)Effect3DFloor.Flags.UseUpperTexture) != 0)
if((extrafloor.Linedef.Args[2] & (int)Effect3DFloor.Flags.UseUpperTexture) != 0)
Sidedef.Other.SetTextureHigh(texturename);
if ((extrafloor.Linedef.Args[2] & (int)Effect3DFloor.Flags.UseLowerTexture) != 0)
if((extrafloor.Linedef.Args[2] & (int)Effect3DFloor.Flags.UseLowerTexture) != 0)
Sidedef.Other.SetTextureLow(texturename);
else
extrafloor.Linedef.Front.SetTextureMid(texturename);

View file

@ -147,7 +147,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
tp.tlt.y = tsz.y - (geotop - geobottom);
if (zoffset > 0) tp.tlt.y -= zoffset; //mxd
if(zoffset > 0) tp.tlt.y -= zoffset; //mxd
tp.trb.x = tp.tlt.x + Sidedef.Line.Length;
tp.trb.y = tp.tlt.y + (Sidedef.Sector.CeilHeight - (Sidedef.Sector.FloorHeight + floorbias));
@ -216,47 +216,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
CropPoly(ref poly, bottomclipplane, true);
}
// Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1);
polygons.Add(poly);
foreach(Effect3DFloor ef in sd.ExtraFloors)
{
//mxd. Walls should be clipped by solid 3D floors
if(!ef.RenderInside && ef.Alpha == 255)
{
int num = polygons.Count;
for(int pi = 0; pi < num; pi++)
{
// Split by floor plane of 3D floor
WallPolygon p = polygons[pi];
WallPolygon np = SplitPoly(ref p, ef.Ceiling.plane, true);
//mxd. In(G)ZDoom, middle sidedef parts are not clipped by extrafloors of any type...
List<WallPolygon> polygons = new List<WallPolygon> { poly };
//ClipExtraFloors(polygons, sd.ExtraFloors, true); //mxd
//ClipExtraFloors(polygons, osd.ExtraFloors, true); //mxd
if(np.Count > 0)
{
// Split part below floor by the ceiling plane of 3D floor
// and keep only the part below the ceiling (front)
SplitPoly(ref np, ef.Floor.plane, true);
if(p.Count == 0)
{
polygons[pi] = np;
}
else
{
polygons[pi] = p;
polygons.Add(np);
}
}
else
{
polygons[pi] = p;
}
}
}
}
if(polygons.Count > 0)
{
//if(polygons.Count > 0)
//{
// Keep top and bottom planes for intersection testing
top = osd.Ceiling.plane;
bottom = osd.Floor.plane;
@ -272,8 +238,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
for(int i = 0; i < verts.Count; i++)
{
WorldVertex v = verts[i];
PixelColor c = PixelColor.FromInt(v.c);
v.c = c.WithAlpha(alpha).ToInt();
v.c = PixelColor.FromInt(v.c).WithAlpha(alpha).ToInt();
verts[i] = v;
}
}
@ -281,7 +246,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.SetVertices(verts);
return true;
}
}
//}
base.SetVertices(null); //mxd
return false;

View file

@ -183,49 +183,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
poly.color = wallcolor.WithAlpha(255).ToInt();
// Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1);
polygons.Add(poly);
foreach(Effect3DFloor ef in sd.ExtraFloors)
{
//mxd. Walls should be clipped by solid 3D floors
if(!ef.RenderInside && ef.Alpha == 255)
{
int num = polygons.Count;
for(int pi = 0; pi < num; pi++)
{
// Split by floor plane of 3D floor
WallPolygon p = polygons[pi];
WallPolygon np = SplitPoly(ref p, ef.Ceiling.plane, true);
List<WallPolygon> polygons = new List<WallPolygon> { poly };
ClipExtraFloors(polygons, sd.ExtraFloors, false); //mxd
if(np.Count > 0)
{
// Split part below floor by the ceiling plane of 3D floor
// and keep only the part below the ceiling (front)
SplitPoly(ref np, ef.Floor.plane, true);
if(p.Count == 0)
{
polygons[pi] = np;
}
else
{
polygons[pi] = p;
polygons.Add(np);
}
}
else
{
polygons[pi] = p;
}
}
}
}
if (polygons.Count > 0)
if(polygons.Count > 0)
{
// Process the polygon and create vertices
List<WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute);
if (verts.Count > 2)
if(verts.Count > 2)
{
base.SetVertices(verts);
return true;

View file

@ -175,43 +175,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
CropPoly(ref poly, osd.Ceiling.plane, false);
// Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1);
polygons.Add(poly);
foreach(Effect3DFloor ef in sd.ExtraFloors)
{
//mxd. Walls should be clipped by solid 3D floors
if(!ef.RenderInside && ef.Alpha == 255)
{
int num = polygons.Count;
for(int pi = 0; pi < num; pi++)
{
// Split by floor plane of 3D floor
WallPolygon p = polygons[pi];
WallPolygon np = SplitPoly(ref p, ef.Ceiling.plane, true);
if(np.Count > 0)
{
// Split part below floor by the ceiling plane of 3D floor
// and keep only the part below the ceiling (front)
SplitPoly(ref np, ef.Floor.plane, true);
if(p.Count == 0)
{
polygons[pi] = np;
}
else
{
polygons[pi] = p;
polygons.Add(np);
}
}
else
{
polygons[pi] = p;
}
}
}
}
List<WallPolygon> polygons = new List<WallPolygon> { poly };
ClipExtraFloors(polygons, sd.ExtraFloors, false); //mxd
if(polygons.Count > 0)
{