mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-26 13:51:40 +00:00
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:
parent
b7ebde6b7e
commit
098e9724d9
19 changed files with 434 additions and 391 deletions
|
@ -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
|
||||
//
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
1
Source/Core/Windows/MainForm.Designer.cs
generated
1
Source/Core/Windows/MainForm.Designer.cs
generated
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -167,6 +167,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
{
|
||||
List<WallPolygon> polygons = new List<WallPolygon>(poly);
|
||||
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
|
||||
|
||||
// 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
|
||||
if(prevlight != null
|
||||
&& prevlight.type == SectorLevelType.Light && l.type == SectorLevelType.Light
|
||||
&& (prevlight.lighttype == LightLevelType.TYPE1 && l.lighttype != LightLevelType.TYPE1_BOTTOM))
|
||||
continue;
|
||||
&& (prevlight.lighttype == LightLevelType.TYPE1 && l.lighttype != LightLevelType.TYPE1_BOTTOM)) 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
|
||||
int num = polygons.Count;
|
||||
|
@ -196,18 +199,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
//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.
|
||||
{
|
||||
// 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();
|
||||
|
@ -232,6 +229,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
//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,15 +792,11 @@ 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
|
||||
{
|
||||
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
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,63 +302,79 @@ 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);
|
||||
|
||||
// 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...
|
||||
int startindex = lightlevels.Count - 2;
|
||||
//mxd. Cast light properties from top to bottom
|
||||
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 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"))
|
||||
if(l.lighttype == LightLevelType.TYPE1)
|
||||
{
|
||||
int light = l.sector.Fields.GetValue("lightfloor", pl.brightnessbelow);
|
||||
pl.brightnessbelow = (l.sector.Fields.GetValue("lightfloorabsolute", false) ? light : l.sector.Brightness + light);
|
||||
stored = pl;
|
||||
}
|
||||
|
||||
// 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)
|
||||
// Use stored light params when "disablelighting" flag is set
|
||||
else if(l.disablelighting)
|
||||
{
|
||||
PixelColor floorbrightness = PixelColor.FromInt(mode.CalculateBrightness(pl.brightnessbelow));
|
||||
PixelColor floorcolor = PixelColor.Modulate(pl.colorbelow, floorbrightness);
|
||||
l.color = floorcolor.WithAlpha(255).ToInt();
|
||||
|
||||
if(uselightlevellight) l.brightnessbelow = pl.brightnessbelow;
|
||||
l.colorbelow = stored.colorbelow;
|
||||
l.brightnessbelow = stored.brightnessbelow;
|
||||
l.color = stored.colorbelow.ToInt();
|
||||
}
|
||||
//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)
|
||||
{
|
||||
//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
|
||||
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
|
||||
// Use brightness and color from the light level above TYPE1 level
|
||||
else if(stored.type == SectorLevelType.Light)
|
||||
{
|
||||
l.brightnessbelow = stored.brightnessbelow;
|
||||
|
@ -358,9 +382,42 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
// 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(l.brightnessbelow == -1) l.brightnessbelow = pl.brightnessbelow;
|
||||
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?
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -595,7 +593,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,26 +191,34 @@ 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)
|
||||
{
|
||||
//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;
|
||||
for(int pi = 0; pi < num; pi++)
|
||||
|
@ -240,6 +249,7 @@ namespace CodeImp.DoomBuilder.BuilderModes {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Process the polygon and create vertices
|
||||
if(polygons.Count > 0)
|
||||
|
@ -247,28 +257,18 @@ 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)
|
||||
{
|
||||
// Apply alpha to vertices
|
||||
byte alpha = (byte) General.Clamp(extrafloor.Alpha, 0, 255);
|
||||
if(alpha < 255)
|
||||
{
|
||||
//mxd. Inner sides always have extrafloor color
|
||||
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 = wallcolor;
|
||||
verts[i] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.SetVertices(verts);
|
||||
return true;
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue