mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
@ work on (G)ZDoom Editing plugin
This commit is contained in:
parent
1830eee6c9
commit
a0b87ebd06
8 changed files with 224 additions and 96 deletions
|
@ -119,6 +119,12 @@ namespace CodeImp.DoomBuilder.Geometry
|
|||
return new Vector3D(a.x / s, a.y / s, a.z / s);
|
||||
}
|
||||
|
||||
// This scales a vector
|
||||
public static Vector3D operator /(Vector3D a, Vector3D b)
|
||||
{
|
||||
return new Vector3D(a.x / b.x, a.y / b.y, a.z / b.z);
|
||||
}
|
||||
|
||||
// This compares a vector
|
||||
public static bool operator ==(Vector3D a, Vector3D b)
|
||||
{
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
<Compile Include="VisualModes\SectorData.cs" />
|
||||
<Compile Include="VisualModes\SectorLevel.cs" />
|
||||
<Compile Include="VisualModes\SectorLevelType.cs" />
|
||||
<Compile Include="VisualModes\TexturePlane.cs" />
|
||||
<Compile Include="VisualModes\VisualActionResult.cs" />
|
||||
<Compile Include="VisualModes\VisualCeiling.cs" />
|
||||
<Compile Include="VisualModes\VisualFloor.cs" />
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
u_ray = pickrayu;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Events
|
||||
|
|
|
@ -538,13 +538,9 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
SectorData sd = GetSectorData(General.Map.VisualCamera.Sector);
|
||||
if(!sd.Built) sd.BuildLevels(this);
|
||||
|
||||
Vector3D feetposition = General.Map.VisualCamera.Position - new Vector3D(0, 0, cameraflooroffset - 7.0f);
|
||||
SectorLevel floorlevel = sd.GetLevelBelow(feetposition);
|
||||
SectorLevel ceillevel = sd.GetLevelAbove(feetposition);
|
||||
if(floorlevel == null) floorlevel = sd.Levels[0];
|
||||
if(ceillevel == null) ceillevel = sd.Levels[sd.Levels.Count - 1];
|
||||
|
||||
// Camera below floor level?
|
||||
Vector3D feetposition = General.Map.VisualCamera.Position - new Vector3D(0, 0, cameraflooroffset - 7.0f);
|
||||
SectorLevel floorlevel = sd.GetFloorBelow(feetposition) ?? sd.Levels[0];
|
||||
float floorheight = floorlevel.plane.GetZ(General.Map.VisualCamera.Position);
|
||||
if(General.Map.VisualCamera.Position.z < (floorheight + cameraflooroffset + 0.01f))
|
||||
{
|
||||
|
@ -559,20 +555,35 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
// Fall down
|
||||
gravity.z += (float)(GRAVITY * deltatime);
|
||||
if(gravity.z > 3.0f) gravity.z = 3.0f;
|
||||
General.Map.VisualCamera.Position += gravity;
|
||||
|
||||
// Test if we don't go through a floor
|
||||
SectorLevel newfloorlevel = sd.GetFloorBelow(feetposition + gravity) ?? sd.Levels[0];
|
||||
if(newfloorlevel != floorlevel)
|
||||
{
|
||||
// Stay above floor
|
||||
gravity = new Vector3D(0.0f, 0.0f, 0.0f);
|
||||
General.Map.VisualCamera.Position = new Vector3D(General.Map.VisualCamera.Position.x,
|
||||
General.Map.VisualCamera.Position.y,
|
||||
floorheight + cameraflooroffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply gravity vector
|
||||
General.Map.VisualCamera.Position += gravity;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Camera above ceiling level?
|
||||
|
||||
// Camera above ceiling?
|
||||
feetposition = General.Map.VisualCamera.Position - new Vector3D(0, 0, cameraflooroffset - 7.0f);
|
||||
SectorLevel ceillevel = sd.GetCeilingAbove(feetposition) ?? sd.Levels[sd.Levels.Count - 1];
|
||||
float ceilheight = ceillevel.plane.GetZ(General.Map.VisualCamera.Position);
|
||||
if(General.Map.VisualCamera.Position.z > (ceilheight - cameraceilingoffset))
|
||||
if(General.Map.VisualCamera.Position.z > (ceilheight - cameraceilingoffset - 0.01f))
|
||||
{
|
||||
// Stay below ceiling
|
||||
General.Map.VisualCamera.Position = new Vector3D(General.Map.VisualCamera.Position.x,
|
||||
General.Map.VisualCamera.Position.y,
|
||||
ceilheight - cameraceilingoffset);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -288,6 +288,28 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
return found;
|
||||
}
|
||||
|
||||
// This returns the level above the given point
|
||||
public SectorLevel GetCeilingAbove(Vector3D pos)
|
||||
{
|
||||
SectorLevel found = null;
|
||||
float dist = float.MaxValue;
|
||||
|
||||
foreach(SectorLevel l in levels)
|
||||
{
|
||||
if(l.type == SectorLevelType.Ceiling)
|
||||
{
|
||||
float d = l.plane.GetZ(pos) - pos.z;
|
||||
if((d > 0.0f) && (d < dist))
|
||||
{
|
||||
dist = d;
|
||||
found = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
// This returns the level below the given point
|
||||
public SectorLevel GetLevelBelow(Vector3D pos)
|
||||
{
|
||||
|
@ -307,6 +329,28 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
return found;
|
||||
}
|
||||
|
||||
// This returns the floor below the given point
|
||||
public SectorLevel GetFloorBelow(Vector3D pos)
|
||||
{
|
||||
SectorLevel found = null;
|
||||
float dist = float.MaxValue;
|
||||
|
||||
foreach(SectorLevel l in levels)
|
||||
{
|
||||
if(l.type == SectorLevelType.Floor)
|
||||
{
|
||||
float d = pos.z - l.plane.GetZ(pos);
|
||||
if((d > 0.0f) && (d < dist))
|
||||
{
|
||||
dist = d;
|
||||
found = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
56
Source/Plugins/GZDoomEditing/VisualModes/TexturePlane.cs
Normal file
56
Source/Plugins/GZDoomEditing/VisualModes/TexturePlane.cs
Normal file
|
@ -0,0 +1,56 @@
|
|||
#region === Copyright (c) 2010 Pascal van der Heiden ===
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Rendering;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.GZDoomEditing
|
||||
{
|
||||
internal struct TexturePlane
|
||||
{
|
||||
// Geometry coordinates (left-top, right-top and right-bottom)
|
||||
public Vector3D vlt;
|
||||
public Vector3D vrt;
|
||||
public Vector3D vrb;
|
||||
|
||||
// Texture coordinates on the points above
|
||||
public Vector2D tlt;
|
||||
public Vector2D trt;
|
||||
public Vector2D trb;
|
||||
|
||||
// This returns interpolated texture coordinates for the point p on the plane defined by vlt, vrt and vrb
|
||||
public Vector2D GetTextureCoordsAt(Vector3D p)
|
||||
{
|
||||
// Delta vectors
|
||||
Vector3D v31 = vrb - vlt;
|
||||
Vector3D v21 = vrt - vlt;
|
||||
Vector3D vp1 = p - vlt;
|
||||
|
||||
// Compute dot products
|
||||
float d00 = Vector3D.DotProduct(v31, v31);
|
||||
float d01 = Vector3D.DotProduct(v31, v21);
|
||||
float d02 = Vector3D.DotProduct(v31, vp1);
|
||||
float d11 = Vector3D.DotProduct(v21, v21);
|
||||
float d12 = Vector3D.DotProduct(v21, vp1);
|
||||
|
||||
// Compute barycentric coordinates
|
||||
float invd = 1.0f / (d00 * d11 - d01 * d01);
|
||||
float u = (d11 * d02 - d01 * d12) * invd;
|
||||
float v = (d00 * d12 - d01 * d02) * invd;
|
||||
|
||||
// Delta texture coordinates
|
||||
Vector2D t21 = trt - tlt;
|
||||
Vector2D t31 = trb - tlt;
|
||||
|
||||
// Lerp
|
||||
return tlt + t31 * u + t21 * v;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,111 +65,121 @@ namespace CodeImp.DoomBuilder.GZDoomEditing
|
|||
// This builds the geometry. Returns false when no geometry created.
|
||||
public override bool Setup()
|
||||
{
|
||||
SectorData sd = mode.GetSectorData(Sidedef.Sector);
|
||||
int brightness = mode.CalculateBrightness(Sidedef.Sector.Brightness);
|
||||
|
||||
// Calculate size of this wall part
|
||||
float geotop = (float)Sidedef.Sector.CeilHeight;
|
||||
float geobottom = (float)Sidedef.Sector.FloorHeight;
|
||||
float geoheight = geotop - geobottom;
|
||||
if(geoheight > 0.001f)
|
||||
// Texture given?
|
||||
if((Sidedef.MiddleTexture.Length > 0) && (Sidedef.MiddleTexture[0] != '-'))
|
||||
{
|
||||
Vector2D t1 = new Vector2D();
|
||||
Vector2D t2 = new Vector2D();
|
||||
|
||||
// Texture given?
|
||||
if((Sidedef.MiddleTexture.Length > 0) && (Sidedef.MiddleTexture[0] != '-'))
|
||||
// Load texture
|
||||
base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongMiddleTexture);
|
||||
if(base.Texture == null)
|
||||
{
|
||||
// Load texture
|
||||
base.Texture = General.Map.Data.GetTextureImage(Sidedef.LongMiddleTexture);
|
||||
if(base.Texture == null)
|
||||
{
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = Sidedef.LongMiddleTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!base.Texture.IsImageLoaded)
|
||||
setuponloadedtexture = Sidedef.LongMiddleTexture;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use missing texture
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = 0;
|
||||
}
|
||||
|
||||
// Get texture scaled size
|
||||
Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);
|
||||
|
||||
// Determine texture coordinates
|
||||
// See http://doom.wikia.com/wiki/Texture_alignment
|
||||
// We just use pixels for coordinates for now
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
{
|
||||
// When lower unpegged is set, the middle texture is bound to the bottom
|
||||
t1.y = tsz.y - geoheight;
|
||||
}
|
||||
t2.x = t1.x + Sidedef.Line.Length;
|
||||
t2.y = t1.y + geoheight;
|
||||
|
||||
// Apply texture offset
|
||||
if (General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
|
||||
{
|
||||
t1 += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
t2 += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
setuponloadedtexture = Sidedef.LongMiddleTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
t2 += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
if(!base.Texture.IsImageLoaded)
|
||||
setuponloadedtexture = Sidedef.LongMiddleTexture;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use missing texture
|
||||
base.Texture = General.Map.Data.MissingTexture3D;
|
||||
setuponloadedtexture = 0;
|
||||
}
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
t1 /= tsz;
|
||||
t2 /= tsz;
|
||||
// Get texture scaled size
|
||||
Vector2D tsz = new Vector2D(base.Texture.ScaledWidth, base.Texture.ScaledHeight);
|
||||
|
||||
// Determine texture coordinates plane as they would be in normal circumstances.
|
||||
// We can then use this plane to find any texture coordinate we need.
|
||||
// The logic here is the same as in the original VisualMiddleSingle (except that
|
||||
// the values are stored in a TexturePlane)
|
||||
TexturePlane tp = new TexturePlane();
|
||||
if(Sidedef.Line.IsFlagSet(General.Map.Config.LowerUnpeggedFlag))
|
||||
{
|
||||
// When lower unpegged is set, the middle texture is bound to the bottom
|
||||
tp.tlt.y = tsz.y - (Sidedef.Sector.CeilHeight - Sidedef.Sector.FloorHeight);
|
||||
}
|
||||
tp.trb.x = tp.tlt.x + Sidedef.Line.Length;
|
||||
tp.trb.y = tp.tlt.y + (Sidedef.Sector.CeilHeight - Sidedef.Sector.FloorHeight);
|
||||
|
||||
// Get world coordinates for geometry
|
||||
Vector2D v1, v2;
|
||||
if(Sidedef.IsFront)
|
||||
// Apply texture offset
|
||||
if (General.Map.Config.ScaledTextureOffsets && !base.Texture.WorldPanning)
|
||||
{
|
||||
tp.tlt += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
tp.trb += new Vector2D(Sidedef.OffsetX * base.Texture.Scale.x, Sidedef.OffsetY * base.Texture.Scale.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.tlt += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
tp.trb += new Vector2D(Sidedef.OffsetX, Sidedef.OffsetY);
|
||||
}
|
||||
|
||||
// Transform pixel coordinates to texture coordinates
|
||||
tp.tlt /= tsz;
|
||||
tp.trb /= tsz;
|
||||
|
||||
// Left top and right bottom of the geometry that
|
||||
if(Sidedef.IsFront)
|
||||
{
|
||||
tp.vlt = new Vector3D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y, Sidedef.Sector.CeilHeight);
|
||||
tp.vrb = new Vector3D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y, Sidedef.Sector.FloorHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
tp.vlt = new Vector3D(Sidedef.Line.End.Position.x, Sidedef.Line.End.Position.y, Sidedef.Sector.CeilHeight);
|
||||
tp.vrb = new Vector3D(Sidedef.Line.Start.Position.x, Sidedef.Line.Start.Position.y, Sidedef.Sector.FloorHeight);
|
||||
}
|
||||
|
||||
// Make the right-top coordinates
|
||||
tp.trt = new Vector2D(tp.trb.x, tp.tlt.y);
|
||||
tp.vrt = new Vector3D(tp.vrb.x, tp.vrb.y, tp.vlt.z);
|
||||
|
||||
// Go for all levels to build geometry
|
||||
List<WorldVertex> verts = new List<WorldVertex>();
|
||||
for(int i = 0; i < (sd.Levels.Count - 1); i++)
|
||||
{
|
||||
SectorLevel lb = sd.Levels[i];
|
||||
SectorLevel lt = sd.Levels[i + 1];
|
||||
if(lt.type != SectorLevelType.Floor)
|
||||
{
|
||||
v1 = Sidedef.Line.Start.Position;
|
||||
v2 = Sidedef.Line.End.Position;
|
||||
}
|
||||
else
|
||||
{
|
||||
v1 = Sidedef.Line.End.Position;
|
||||
v2 = Sidedef.Line.Start.Position;
|
||||
}
|
||||
PixelColor wallbrightness = PixelColor.FromInt(mode.CalculateBrightness(lt.brightnessbelow));
|
||||
PixelColor wallcolor = PixelColor.Modulate(lt.colorbelow, wallbrightness);
|
||||
int c = wallcolor.WithAlpha(255).ToInt();
|
||||
|
||||
// Make vertices
|
||||
WorldVertex[] verts = new WorldVertex[6];
|
||||
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, brightness, t1.x, t2.y);
|
||||
verts[1] = new WorldVertex(v1.x, v1.y, geotop, brightness, t1.x, t1.y);
|
||||
verts[2] = new WorldVertex(v2.x, v2.y, geotop, brightness, t2.x, t1.y);
|
||||
verts[3] = verts[0];
|
||||
verts[4] = verts[2];
|
||||
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, brightness, t2.x, t2.y);
|
||||
Vector3D vlb = new Vector3D(tp.vlt.x, tp.vlt.y, lb.plane.GetZ(tp.vlt));
|
||||
Vector3D vlt = new Vector3D(tp.vlt.x, tp.vlt.y, lt.plane.GetZ(tp.vlt));
|
||||
Vector3D vrb = new Vector3D(tp.vrb.x, tp.vrb.y, lb.plane.GetZ(tp.vrb));
|
||||
Vector3D vrt = new Vector3D(tp.vrt.x, tp.vrt.y, lt.plane.GetZ(tp.vrt));
|
||||
Vector2D tlb = tp.GetTextureCoordsAt(vlb);
|
||||
Vector2D tlt = tp.GetTextureCoordsAt(vlt);
|
||||
Vector2D trb = tp.GetTextureCoordsAt(vrb);
|
||||
Vector2D trt = tp.GetTextureCoordsAt(vrt);
|
||||
|
||||
// Keep properties
|
||||
base.top = geotop;
|
||||
base.bottom = geobottom;
|
||||
|
||||
// Apply vertices
|
||||
verts.Add(new WorldVertex(vlb.x, vlb.y, vlb.z, c, tlb.x, tlb.y));
|
||||
verts.Add(new WorldVertex(vlt.x, vlt.y, vlt.z, c, tlt.x, tlt.y));
|
||||
verts.Add(new WorldVertex(vrt.x, vrt.y, vrt.z, c, trt.x, trt.y));
|
||||
verts.Add(new WorldVertex(vlb.x, vlb.y, vlb.z, c, tlb.x, tlb.y));
|
||||
verts.Add(new WorldVertex(vrt.x, vrt.y, vrt.z, c, trt.x, trt.y));
|
||||
verts.Add(new WorldVertex(vrb.x, vrb.y, vrb.z, c, trb.x, trb.y));
|
||||
}
|
||||
}
|
||||
|
||||
if(verts.Count > 0)
|
||||
{
|
||||
base.SetVertices(verts);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No geometry for invisible wall
|
||||
base.top = geotop;
|
||||
base.bottom = geobottom;
|
||||
WorldVertex[] verts = new WorldVertex[0];
|
||||
base.SetVertices(verts);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Methods
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue