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.DrawItem += new System.Windows.Forms.DrawListViewItemEventHandler(this.list_DrawItem);
this.list.DoubleClick += new System.EventHandler(this.list_DoubleClick); this.list.DoubleClick += new System.EventHandler(this.list_DoubleClick);
this.list.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.list_ItemSelectionChanged); this.list.ItemSelectionChanged += new System.Windows.Forms.ListViewItemSelectionChangedEventHandler(this.list_ItemSelectionChanged);
this.list.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.list_KeyPress);
// //
// showsubdirtextures // showsubdirtextures
// //

View file

@ -19,6 +19,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Globalization;
using System.Windows.Forms; using System.Windows.Forms;
using CodeImp.DoomBuilder.Data; using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Windows; using CodeImp.DoomBuilder.Windows;
@ -273,6 +274,25 @@ namespace CodeImp.DoomBuilder.Controls
if(SelectedItemDoubleClicked != null) SelectedItemDoubleClicked(); 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 //mxd
private void cbMixMode_SelectedIndexChanged(object sender, EventArgs e) 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 // Blend texture color and vertex color
float4 ncolor = tcolor * pd.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 // Full-bright pixel shader with highlight
@ -159,7 +159,7 @@ float4 ps_fullbright_highlight(PixelData pd) : COLOR
// Blend texture color and vertex color // Blend texture color and vertex color
float4 ncolor = tcolor * pd.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 //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.Image = global::CodeImp.DoomBuilder.Properties.Resources.Status2;
this.statuslabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft; 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.Name = "statuslabel";
this.statuslabel.Size = new System.Drawing.Size(340, 18); this.statuslabel.Size = new System.Drawing.Size(340, 18);
this.statuslabel.Spring = true; this.statuslabel.Spring = true;

View file

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

View file

@ -167,6 +167,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
List<WallPolygon> polygons = new List<WallPolygon>(poly); List<WallPolygon> polygons = new List<WallPolygon>(poly);
List<WorldVertex> verts = new List<WorldVertex>(); List<WorldVertex> verts = new List<WorldVertex>();
//mxd. Do complicated light level shenanigans only when there are extrafloors
if(sd.LightLevels.Count > 2)
{
SectorLevel prevlight = null; //mxd SectorLevel prevlight = null; //mxd
// Go for all levels to build geometry // Go for all levels to build geometry
@ -177,10 +181,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Skip current light level when it's between TYPE1 and TYPE1_BOTTOM //mxd. Skip current light level when it's between TYPE1 and TYPE1_BOTTOM
if(prevlight != null if(prevlight != null
&& prevlight.type == SectorLevelType.Light && l.type == SectorLevelType.Light && prevlight.type == SectorLevelType.Light && l.type == SectorLevelType.Light
&& (prevlight.lighttype == LightLevelType.TYPE1 && l.lighttype != LightLevelType.TYPE1_BOTTOM)) && (prevlight.lighttype == LightLevelType.TYPE1 && l.lighttype != LightLevelType.TYPE1_BOTTOM)) continue;
continue;
if((l != sd.Floor) && (l != sd.Ceiling) && (l.type != SectorLevelType.Floor || l.alpha < 255)) if((l != sd.Floor) && (l != sd.Ceiling) && (l.type != SectorLevelType.Floor || l.splitsides /*(l.alpha < 255)*/))
{ {
// Go for all polygons // Go for all polygons
int num = polygons.Count; int num = polygons.Count;
@ -196,18 +199,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd. Determine color //mxd. Determine color
int lightlevel; int lightlevel;
if(l.disablelighting) //sidedef part is not affected by 3d floor brightness // Sidedef part is not affected by 3d floor brightness
{ if(l.disablelighting || !l.extrafloor)
lightlevel = lightabsolute ? lightvalue : l.brightnessbelow + lightvalue; lightlevel = (lightabsolute ? lightvalue : l.brightnessbelow + lightvalue);
} // 3d floor transfers brightness below it ignoring sidedef's brightness
else if(l.restrictlighting || (l.type == SectorLevelType.Floor && l.alpha < 255)) //only happens to a sidedef part inside of a non-opaque 3d floor. else
{
lightlevel = l.sector.Brightness;
}
else // "Regular" 3d floor transfers brightness below it ignoring sidedef's brightness.
{
lightlevel = l.brightnessbelow; lightlevel = l.brightnessbelow;
}
PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef)); //mxd PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef)); //mxd
np.color = PixelColor.Modulate(l.colorbelow, wallbrightness).WithAlpha(255).ToInt(); np.color = PixelColor.Modulate(l.colorbelow, wallbrightness).WithAlpha(255).ToInt();
@ -232,6 +229,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
//mxd //mxd
if(l.type == SectorLevelType.Light) prevlight = l; if(l.type == SectorLevelType.Light) prevlight = l;
} }
}
// Go for all polygons to make geometry // Go for all polygons to make geometry
foreach(WallPolygon p in polygons) foreach(WallPolygon p in polygons)
@ -446,6 +444,46 @@ namespace CodeImp.DoomBuilder.BuilderModes
poly = newp; 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 //mxd
protected void GetLightValue(out int lightvalue, out bool lightabsolute) protected void GetLightValue(out int lightvalue, out bool lightabsolute)
{ {
@ -755,14 +793,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
else if(this is VisualMiddleDouble) 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; offsety = (options.Bounds.Y - Sidedef.GetHighHeight() - Sidedef.GetLowHeight()) * scaley - Sidedef.OffsetY;
}
else else
{
offsety = options.Bounds.Y * scaley - Sidedef.OffsetY; offsety = options.Bounds.Y * scaley - Sidedef.OffsetY;
} }
}
else else
{ {
offsety = Tools.GetSidedefOffsetY(Sidedef, geometrytype, options.Bounds.Y * scaley - Sidedef.OffsetY - options.ControlSideOffsetY, scaley, true) % Texture.Height; offsety = Tools.GetSidedefOffsetY(Sidedef, geometrytype, options.Bounds.Y * scaley - Sidedef.OffsetY - options.ControlSideOffsetY, scaley, true) % Texture.Height;
@ -878,22 +912,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
// Change ceiling // Change ceiling
case 1: case 1:
if(!this.Sector.Ceiling.Changed) if(!this.Sector.Ceiling.Changed) this.Sector.Ceiling.OnChangeTargetHeight(amount);
this.Sector.Ceiling.OnChangeTargetHeight(amount);
break; break;
// Change floor // Change floor
case 2: case 2:
if(!this.Sector.Floor.Changed) if(!this.Sector.Floor.Changed) this.Sector.Floor.OnChangeTargetHeight(amount);
this.Sector.Floor.OnChangeTargetHeight(amount);
break; break;
// Change both // Change both
case 3: case 3:
if(!this.Sector.Floor.Changed) if(!this.Sector.Floor.Changed) this.Sector.Floor.OnChangeTargetHeight(amount);
this.Sector.Floor.OnChangeTargetHeight(amount); if(!this.Sector.Ceiling.Changed) this.Sector.Ceiling.OnChangeTargetHeight(amount);
if(!this.Sector.Ceiling.Changed)
this.Sector.Ceiling.OnChangeTargetHeight(amount);
break; break;
} }
} }
@ -1131,7 +1161,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update the parts for this sidedef! // Update the parts for this sidedef!
if(mode.VisualSectorExists(sd.Sector)) 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); VisualSidedefParts parts = vs.GetSidedefParts(sd);
parts.SetupAllParts(); parts.SetupAllParts();
} }

View file

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

View file

@ -13,7 +13,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
// Linedef that is used to create this effect // Linedef that is used to create this effect
// The sector can be found by linedef.Front.Sector // The sector can be found by linedef.Front.Sector
private Linedef linedef; private readonly Linedef linedef;
// Floor and ceiling planes // Floor and ceiling planes
private SectorLevel floor; private SectorLevel floor;
@ -25,12 +25,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Vavoom type? // Vavoom type?
private bool vavoomtype; private bool vavoomtype;
//mxd. Translucent 3d-floor? //mxd. Render backsides?
private bool renderinside; private bool renderinside;
//mxd. Dirty hack to emulate GZDoom behaviour? //mxd. Dirty hack to emulate GZDoom behaviour?
private bool sloped3dfloor; 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? //mxd. Ignore Bottom Height?
private bool ignorebottomheight; private bool ignorebottomheight;
@ -41,8 +47,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
public Linedef Linedef { get { return linedef; } } public Linedef Linedef { get { return linedef; } }
public bool VavoomType { get { return vavoomtype; } } public bool VavoomType { get { return vavoomtype; } }
public bool RenderInside { get { return renderinside; } } //mxd public bool RenderInside { get { return renderinside; } } //mxd
public bool RenderAdditive { get { return renderadditive; } } //mxd
public bool IgnoreBottomHeight { get { return ignorebottomheight; } } //mxd public bool IgnoreBottomHeight { get { return ignorebottomheight; } } //mxd
public bool Sloped3dFloor { get { return sloped3dfloor; } } //mxd public bool Sloped3dFloor { get { return sloped3dfloor; } } //mxd
public bool ClipSidedefs { get { return clipsides; } } //mxd
//mxd. 3D-Floor Flags //mxd. 3D-Floor Flags
[Flags] [Flags]
@ -107,26 +115,33 @@ namespace CodeImp.DoomBuilder.BuilderModes
// For non-vavoom types, we must switch the level types // For non-vavoom types, we must switch the level types
if(linedef.Args[1] != (int)FloorTypes.VavoomStyle) 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; vavoomtype = false;
alpha = linedef.Args[3]; alpha = General.Clamp(linedef.Args[3], 0, 255);
sd.Ceiling.CopyProperties(floor); sd.Ceiling.CopyProperties(floor);
sd.Floor.CopyProperties(ceiling); sd.Floor.CopyProperties(ceiling);
floor.type = SectorLevelType.Floor; floor.type = SectorLevelType.Floor;
floor.plane = sd.Ceiling.plane.GetInverted(); floor.plane = sd.Ceiling.plane.GetInverted();
ceiling.type = SectorLevelType.Ceiling; 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 //mxd
renderinside = ( (((linedef.Args[1] & (int)FloorTypes.Swimmable) == (int)FloorTypes.Swimmable) && (linedef.Args[1] & (int)FloorTypes.NonSolid) != (int)FloorTypes.NonSolid) ) clipsides = (!renderinside && !renderadditive && alpha > 254 && !ignorebottomheight);
|| ((linedef.Args[1] & (int)FloorTypes.RenderInside) == (int)FloorTypes.RenderInside);
ignorebottomheight = ((linedef.Args[2] & (int)Flags.IgnoreBottomHeight) == (int)Flags.IgnoreBottomHeight);
// A 3D floor's color is always that of the sector it is placed in // 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 else
{ {
vavoomtype = true; vavoomtype = true;
renderadditive = false; //mxd
clipsides = true; //mxd
floor.type = SectorLevelType.Ceiling; floor.type = SectorLevelType.Ceiling;
floor.plane = sd.Ceiling.plane; floor.plane = sd.Ceiling.plane;
ceiling.type = SectorLevelType.Floor; ceiling.type = SectorLevelType.Floor;
@ -134,15 +149,22 @@ namespace CodeImp.DoomBuilder.BuilderModes
alpha = 255; alpha = 255;
// A 3D floor's color is always that of the sector it is placed in // 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 // Apply alpha
floor.alpha = alpha; floor.alpha = alpha;
ceiling.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... //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(ceiling.plane.Normal.GetAngleZ()) != 270 ||
Angle2D.RadToDeg(floor.plane.Normal.GetAngleZ()) != 90)); Angle2D.RadToDeg(floor.plane.Normal.GetAngleZ()) != 90));
@ -150,17 +172,25 @@ namespace CodeImp.DoomBuilder.BuilderModes
if(!vavoomtype) if(!vavoomtype)
{ {
bool disablelighting = ((linedef.Args[2] & (int)Flags.DisableLighting) == (int)Flags.DisableLighting); //mxd 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 restrictlighting = (alpha < 255 || renderadditive || renderinside) && ((linedef.Args[2] & (int)Flags.RestrictLighting) == (int)Flags.RestrictLighting); //mxd
if(disablelighting || restrictlighting) if(disablelighting || restrictlighting)
{ {
floor.brightnessbelow = -1;
floor.restrictlighting = restrictlighting; //mxd floor.restrictlighting = restrictlighting; //mxd
floor.disablelighting = disablelighting; //mxd floor.disablelighting = disablelighting; //mxd
if(disablelighting) //mxd
{
floor.color = 0;
floor.brightnessbelow = -1;
floor.colorbelow = PixelColor.FromInt(0); floor.colorbelow = PixelColor.FromInt(0);
}
ceiling.disablelighting = disablelighting; //mxd
ceiling.restrictlighting = restrictlighting; //mxd
ceiling.color = 0; ceiling.color = 0;
ceiling.brightnessbelow = -1; ceiling.brightnessbelow = -1;
ceiling.disablelighting = true; //mxd
ceiling.colorbelow = PixelColor.FromInt(0); ceiling.colorbelow = PixelColor.FromInt(0);
} }
} }

View file

@ -46,7 +46,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Original floor and ceiling levels // Original floor and ceiling levels
private readonly SectorLevel floor; 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 ceiling;
private readonly SectorLevel ceilingbase; // mxd. Sector ceiling level, unaffected by glow / light properties transfer
// This helps keeping track of changes // This helps keeping track of changes
// otherwise we update ceiling/floor too much // otherwise we update ceiling/floor too much
@ -86,7 +88,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.alleffects = new List<SectorEffect>(1); this.alleffects = new List<SectorEffect>(1);
this.updatesectors = new Dictionary<Sector, bool>(2); this.updatesectors = new Dictionary<Sector, bool>(2);
this.floor = new SectorLevel(sector, SectorLevelType.Floor); this.floor = new SectorLevel(sector, SectorLevelType.Floor);
this.floorbase = new SectorLevel(sector, SectorLevelType.Floor); //mxd
this.ceiling = new SectorLevel(sector, SectorLevelType.Ceiling); this.ceiling = new SectorLevel(sector, SectorLevelType.Ceiling);
this.ceilingbase = new SectorLevel(sector, SectorLevelType.Ceiling); //mxd
BasicSetup(); BasicSetup();
@ -271,6 +275,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
ceiling.color = ceilingcolor.WithAlpha(255).ToInt(); ceiling.color = ceilingcolor.WithAlpha(255).ToInt();
ceiling.brightnessbelow = sector.Brightness; ceiling.brightnessbelow = sector.Brightness;
ceiling.colorbelow = lightcolor.WithAlpha(255); ceiling.colorbelow = lightcolor.WithAlpha(255);
//mxd. Store a copy of initial settings
floor.CopyProperties(floorbase);
ceiling.CopyProperties(ceilingbase);
} }
//mxd //mxd
@ -294,54 +302,70 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Update all effects // Update all effects
foreach(SectorEffect e in alleffects) e.Update(); foreach(SectorEffect e in alleffects) e.Update();
// Sort the levels (only if there are more than 2 sector levels - mxd) //mxd. Do complicated light level shenanigans only when there are extrafloors
if(lightlevels.Count > 2) if(lightlevels.Count > 2)
{ {
// Sort the levels
SectorLevelComparer comparer = new SectorLevelComparer(sector); 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);
// 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)
{
lightlevels[lightlevels.Count - 1].colorbelow = stored.colorbelow;
lightlevels[lightlevels.Count - 1].brightnessbelow = stored.brightnessbelow;
lightlevels[lightlevels.Count - 1].color = stored.colorbelow.ToInt();
} }
//mxd. 3d floors can be above the real ceiling, so let's find it first... //mxd. Cast light properties from top to bottom
int startindex = lightlevels.Count - 2;
for(int i = lightlevels.Count - 2; i >= 0; i--) for(int i = lightlevels.Count - 2; i >= 0; i--)
{
if(lightlevels[i].type == SectorLevelType.Ceiling && lightlevels[i].sector.Index == sector.Index)
{
startindex = i;
break;
}
}
// 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 l = lightlevels[i];
SectorLevel pl = lightlevels[i + 1]; SectorLevel pl = lightlevels[i + 1];
if(l.lighttype == LightLevelType.TYPE1) stored = pl; //mxd if(l.lighttype == LightLevelType.TYPE1)
//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"))
{ {
int light = l.sector.Fields.GetValue("lightfloor", pl.brightnessbelow); stored = pl;
pl.brightnessbelow = (l.sector.Fields.GetValue("lightfloorabsolute", false) ? light : l.sector.Brightness + light);
} }
// Use stored light params when "disablelighting" flag is set
// Set color when no color is specified, or when a 3D floor is placed above the absolute floor else if(l.disablelighting)
//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)); l.colorbelow = stored.colorbelow;
PixelColor floorcolor = PixelColor.Modulate(pl.colorbelow, floorbrightness); l.brightnessbelow = stored.brightnessbelow;
l.color = floorcolor.WithAlpha(255).ToInt(); l.color = stored.colorbelow.ToInt();
if(uselightlevellight) l.brightnessbelow = pl.brightnessbelow;
} }
//mxd. Bottom TYPE1 border requires special handling... else if(l.restrictlighting)
{
if(!pl.restrictlighting && pl != ceiling) stored = pl;
l.color = stored.color;
// 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) else if(l.lighttype == LightLevelType.TYPE1_BOTTOM)
{ {
// Use brightness and color from previous light level when it's between TYPE1 and TYPE1_BOTTOM levels // Use brightness and color from previous light level when it's between TYPE1 and TYPE1_BOTTOM levels
@ -358,9 +382,42 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
// Otherwise light values from the real ceiling are used // 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(l.colorbelow.a == 0) l.colorbelow = pl.colorbelow; if((src == l) || (src == ceiling && l == floor && src.LightPropertiesMatch(ceilingbase)))
if(l.brightnessbelow == -1) l.brightnessbelow = pl.brightnessbelow; {
// 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? //mxd. Apply ceiling glow effect?

View file

@ -36,6 +36,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
public bool disablelighting; //mxd public bool disablelighting; //mxd
public bool restrictlighting; //mxd public bool restrictlighting; //mxd
public bool affectedbyglow; //mxd public bool affectedbyglow; //mxd
public bool extrafloor; //mxd
public bool splitsides; //mxd
// Constructor // Constructor
public SectorLevel(Sector s, SectorLevelType type) public SectorLevel(Sector s, SectorLevelType type)
@ -43,6 +45,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
this.type = type; this.type = type;
this.sector = s; this.sector = s;
this.alpha = 255; this.alpha = 255;
this.splitsides = true; //mxd
} }
// Copy constructor // Copy constructor
@ -62,8 +65,46 @@ namespace CodeImp.DoomBuilder.BuilderModes
target.color = this.color; target.color = this.color;
target.brightnessbelow = this.brightnessbelow; target.brightnessbelow = this.brightnessbelow;
target.colorbelow = this.colorbelow; target.colorbelow = this.colorbelow;
target.affectedbyglow = this.affectedbyglow; //mxd
target.disablelighting = this.disablelighting; //mxd target.disablelighting = this.disablelighting; //mxd
target.restrictlighting = this.restrictlighting; //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); float diff = (float)Math.Round(x.plane.GetZ(center) - y.plane.GetZ(center), 3);
if(diff == 0) 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 xislight = (x.type == SectorLevelType.Light || x.type == SectorLevelType.Glow);
bool yislight = (y.type == SectorLevelType.Light || y.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 if(extrafloor.Sloped3dFloor) //mxd
this.RenderPass = RenderPass.Mask; 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; this.RenderPass = RenderPass.Additive;
else if(level.alpha < 255) else if(level.alpha < 255)
this.RenderPass = RenderPass.Alpha; this.RenderPass = RenderPass.Alpha;
@ -187,10 +187,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Return texture coordinates // Return texture coordinates
protected override Point GetTextureOffset() protected override Point GetTextureOffset()
{ {
Point p = new Point(); return new Point { X = (int)Sector.Sector.Fields.GetValue("xpanningceiling", 0.0f),
p.X = (int)Sector.Sector.Fields.GetValue("xpanningceiling", 0.0f); Y = (int)Sector.Sector.Fields.GetValue("ypanningceiling", 0.0f) };
p.Y = (int)Sector.Sector.Fields.GetValue("ypanningceiling", 0.0f);
return p;
} }
// Move texture coordinates // Move texture coordinates
@ -377,7 +375,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
else else
{ {
//if a map is not in UDMF format, or this ceiling is part of 3D-floor... //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); base.OnChangeTargetBrightness(up);
return; return;
@ -595,7 +593,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
isFront = true; isFront = true;
break; 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; slopeSource = side.Line;
break; break;

View file

@ -165,7 +165,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
if(extrafloor.Sloped3dFloor) //mxd if(extrafloor.Sloped3dFloor) //mxd
this.RenderPass = RenderPass.Mask; 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; this.RenderPass = RenderPass.Additive;
else if(level.alpha < 255) else if(level.alpha < 255)
this.RenderPass = RenderPass.Alpha; this.RenderPass = RenderPass.Alpha;
@ -189,10 +189,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Return texture coordinates // Return texture coordinates
protected override Point GetTextureOffset() protected override Point GetTextureOffset()
{ {
Point p = new Point(); return new Point { X = (int)Sector.Sector.Fields.GetValue("xpanningfloor", 0.0f),
p.X = (int)Sector.Sector.Fields.GetValue("xpanningfloor", 0.0f); Y = (int)Sector.Sector.Fields.GetValue("ypanningfloor", 0.0f) };
p.Y = (int)Sector.Sector.Fields.GetValue("ypanningfloor", 0.0f);
return p;
} }
// Move texture coordinates // Move texture coordinates
@ -363,7 +361,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
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); ((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); Sector.ExtraFloors[0].OnChangeTargetBrightness(up);
else else
base.OnChangeTargetBrightness(up); base.OnChangeTargetBrightness(up);

View file

@ -184,43 +184,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
CropPoly(ref poly, osd.Ceiling.plane, true); CropPoly(ref poly, osd.Ceiling.plane, true);
// Cut out pieces that overlap 3D floors in this sector // Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1); List<WallPolygon> polygons = new List<WallPolygon> { poly };
polygons.Add(poly); ClipExtraFloors(polygons, sd.ExtraFloors, false); //mxd
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;
}
}
}
}
if(polygons.Count > 0) if(polygons.Count > 0)
{ {

View file

@ -228,12 +228,16 @@ namespace CodeImp.DoomBuilder.BuilderModes
CropPoly(ref poly, extrafloor.Ceiling.plane, false); CropPoly(ref poly, extrafloor.Ceiling.plane, false);
// Cut out pieces that overlap 3D floors in this sector // Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1); List<WallPolygon> polygons = new List<WallPolygon> { poly };
polygons.Add(poly); bool translucent = (extrafloor.RenderAdditive || extrafloor.Alpha < 255);
foreach(Effect3DFloor ef in sd.ExtraFloors) foreach(Effect3DFloor ef in sd.ExtraFloors)
{ {
//mxd. Walls of solid 3D floors shouldn't be clipped by translucent 3D floors //mxd. Our poly should be clipped when our ond other extrafloors are both solid or both translucent,
if(extrafloor.Alpha < 255 || (!extrafloor.RenderInside && !ef.RenderInside && extrafloor.Alpha == 255 && ef.Alpha == 255)) // 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; int num = polygons.Count;
for(int pi = 0; pi < num; pi++) for(int pi = 0; pi < num; pi++)
@ -272,14 +276,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
List<WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute); List<WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute);
if(verts.Count > 2) if(verts.Count > 2)
{ {
if(extrafloor.Sloped3dFloor) //mxd if(extrafloor.Sloped3dFloor) this.RenderPass = RenderPass.Mask; //mxd
this.RenderPass = RenderPass.Mask; else if(extrafloor.RenderAdditive) this.RenderPass = RenderPass.Additive; //mxd
else if((extrafloor.Linedef.Args[2] & (int) Effect3DFloor.Flags.RenderAdditive) != 0) //mxd else if(extrafloor.Alpha < 255) this.RenderPass = RenderPass.Alpha;
this.RenderPass = RenderPass.Additive; else this.RenderPass = RenderPass.Mask;
else if(extrafloor.Alpha < 255)
this.RenderPass = RenderPass.Alpha;
else
this.RenderPass = RenderPass.Mask;
if(extrafloor.Alpha < 255) if(extrafloor.Alpha < 255)
{ {
@ -290,8 +290,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
for(int i = 0; i < verts.Count; i++) for(int i = 0; i < verts.Count; i++)
{ {
WorldVertex v = verts[i]; WorldVertex v = verts[i];
PixelColor c = PixelColor.FromInt(v.c); v.c = PixelColor.FromInt(v.c).WithAlpha(alpha).ToInt();
v.c = c.WithAlpha(alpha).ToInt();
verts[i] = v; verts[i] = v;
} }
} }

View file

@ -12,7 +12,8 @@ using CodeImp.DoomBuilder.Data;
#endregion #endregion
namespace CodeImp.DoomBuilder.BuilderModes { namespace CodeImp.DoomBuilder.BuilderModes
{
//mxd. Used to render translucent 3D floor's inner sides //mxd. Used to render translucent 3D floor's inner sides
internal sealed class VisualMiddleBack : BaseVisualGeometrySidedef internal sealed class VisualMiddleBack : BaseVisualGeometrySidedef
{ {
@ -190,26 +191,34 @@ namespace CodeImp.DoomBuilder.BuilderModes {
// Determine initial color // Determine initial color
int lightlevel; int lightlevel;
PixelColor levelcolor; //mxd
if(((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.DisableLighting) != 0)) if(((sourceside.Line.Args[2] & (int)Effect3DFloor.Flags.DisableLighting) != 0))
{
lightlevel = lightabsolute ? lightvalue : sd.Ceiling.brightnessbelow + lightvalue; lightlevel = lightabsolute ? lightvalue : sd.Ceiling.brightnessbelow + lightvalue;
levelcolor = sd.Ceiling.colorbelow; //mxd
}
else else
{
lightlevel = lightabsolute ? lightvalue : sourceside.Sector.Brightness + lightvalue; lightlevel = lightabsolute ? lightvalue : sourceside.Sector.Brightness + lightvalue;
levelcolor = extrafloor.Floor.colorbelow; //mxd
}
//mxd. This calculates light with doom-style wall shading //mxd. This calculates light with doom-style wall shading
PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lightlevel, Sidedef)); 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); fogfactor = CalculateFogDensity(lightlevel);
poly.color = wallcolor.WithAlpha(255).ToInt();
// Cut off the part above the 3D floor and below the 3D ceiling // Cut off the part above the 3D floor and below the 3D ceiling
CropPoly(ref poly, bottom, false); CropPoly(ref poly, bottom, false);
CropPoly(ref poly, top, false); CropPoly(ref poly, top, false);
// Cut out pieces that overlap 3D floors in this sector // Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1); List<WallPolygon> polygons = new List<WallPolygon> { poly };
polygons.Add(poly);
foreach(Effect3DFloor ef in sd.ExtraFloors) foreach(Effect3DFloor ef in sd.ExtraFloors)
{
//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)
{ {
int num = polygons.Count; int num = polygons.Count;
for(int pi = 0; pi < num; pi++) for(int pi = 0; pi < num; pi++)
@ -240,6 +249,7 @@ namespace CodeImp.DoomBuilder.BuilderModes {
} }
} }
} }
}
// Process the polygon and create vertices // Process the polygon and create vertices
if(polygons.Count > 0) if(polygons.Count > 0)
@ -247,28 +257,18 @@ namespace CodeImp.DoomBuilder.BuilderModes {
List<WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute); List<WorldVertex> verts = CreatePolygonVertices(polygons, tp, sd, lightvalue, lightabsolute);
if(verts.Count > 2) if(verts.Count > 2)
{ {
if((extrafloor.Linedef.Args[2] & (int) Effect3DFloor.Flags.RenderAdditive) != 0) //mxd if(extrafloor.Sloped3dFloor) this.RenderPass = RenderPass.Mask; //mxd
this.RenderPass = RenderPass.Additive; else if(extrafloor.RenderAdditive) this.RenderPass = RenderPass.Additive; //mxd
else if(extrafloor.Alpha < 255) else if(extrafloor.Alpha < 255) this.RenderPass = RenderPass.Alpha;
this.RenderPass = RenderPass.Alpha; else this.RenderPass = RenderPass.Mask;
else
this.RenderPass = RenderPass.Mask;
if(extrafloor.Alpha < 255) //mxd. Inner sides always have extrafloor color
{
// Apply alpha to vertices
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]; WorldVertex v = verts[i];
PixelColor c = PixelColor.FromInt(v.c); v.c = wallcolor;
v.c = c.WithAlpha(alpha).ToInt();
verts[i] = v; verts[i] = v;
} }
}
}
base.SetVertices(verts); base.SetVertices(verts);
return true; return true;

View file

@ -216,47 +216,13 @@ namespace CodeImp.DoomBuilder.BuilderModes
CropPoly(ref poly, bottomclipplane, true); CropPoly(ref poly, bottomclipplane, true);
} }
// Cut out pieces that overlap 3D floors in this sector //mxd. In(G)ZDoom, middle sidedef parts are not clipped by extrafloors of any type...
List<WallPolygon> polygons = new List<WallPolygon>(1); List<WallPolygon> polygons = new List<WallPolygon> { poly };
polygons.Add(poly); //ClipExtraFloors(polygons, sd.ExtraFloors, true); //mxd
foreach(Effect3DFloor ef in sd.ExtraFloors) //ClipExtraFloors(polygons, osd.ExtraFloors, true); //mxd
{
//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) //if(polygons.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)
{
// Keep top and bottom planes for intersection testing // Keep top and bottom planes for intersection testing
top = osd.Ceiling.plane; top = osd.Ceiling.plane;
bottom = osd.Floor.plane; bottom = osd.Floor.plane;
@ -272,8 +238,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
for(int i = 0; i < verts.Count; i++) for(int i = 0; i < verts.Count; i++)
{ {
WorldVertex v = verts[i]; WorldVertex v = verts[i];
PixelColor c = PixelColor.FromInt(v.c); v.c = PixelColor.FromInt(v.c).WithAlpha(alpha).ToInt();
v.c = c.WithAlpha(alpha).ToInt();
verts[i] = v; verts[i] = v;
} }
} }
@ -281,7 +246,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
base.SetVertices(verts); base.SetVertices(verts);
return true; return true;
} }
} //}
base.SetVertices(null); //mxd base.SetVertices(null); //mxd
return false; return false;

View file

@ -183,43 +183,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
poly.color = wallcolor.WithAlpha(255).ToInt(); poly.color = wallcolor.WithAlpha(255).ToInt();
// Cut out pieces that overlap 3D floors in this sector // Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1); List<WallPolygon> polygons = new List<WallPolygon> { poly };
polygons.Add(poly); ClipExtraFloors(polygons, sd.ExtraFloors, false); //mxd
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;
}
}
}
}
if(polygons.Count > 0) if(polygons.Count > 0)
{ {

View file

@ -175,43 +175,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
CropPoly(ref poly, osd.Ceiling.plane, false); CropPoly(ref poly, osd.Ceiling.plane, false);
// Cut out pieces that overlap 3D floors in this sector // Cut out pieces that overlap 3D floors in this sector
List<WallPolygon> polygons = new List<WallPolygon>(1); List<WallPolygon> polygons = new List<WallPolygon> { poly };
polygons.Add(poly); ClipExtraFloors(polygons, sd.ExtraFloors, false); //mxd
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;
}
}
}
}
if(polygons.Count > 0) if(polygons.Count > 0)
{ {