mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-12 07:01:21 +00:00
working on visual mode
This commit is contained in:
parent
71282714ac
commit
fe5d5a2001
12 changed files with 381 additions and 64 deletions
|
@ -652,6 +652,7 @@
|
||||||
<EmbeddedResource Include="Resources\Crosshair.png" />
|
<EmbeddedResource Include="Resources\Crosshair.png" />
|
||||||
<EmbeddedResource Include="Resources\CrosshairBusy.png" />
|
<EmbeddedResource Include="Resources\CrosshairBusy.png" />
|
||||||
<Content Include="Resources\DB2.ico" />
|
<Content Include="Resources\DB2.ico" />
|
||||||
|
<Compile Include="VisualModes\IVisualPickable.cs" />
|
||||||
<Compile Include="General\BinaryHeap.cs" />
|
<Compile Include="General\BinaryHeap.cs" />
|
||||||
<Compile Include="Geometry\Plane.cs" />
|
<Compile Include="Geometry\Plane.cs" />
|
||||||
<Compile Include="Geometry\ProjectedFrustum2D.cs" />
|
<Compile Include="Geometry\ProjectedFrustum2D.cs" />
|
||||||
|
|
|
@ -109,6 +109,7 @@
|
||||||
<Compile Include="VisualModes\BaseVisualSector.cs" />
|
<Compile Include="VisualModes\BaseVisualSector.cs" />
|
||||||
<Compile Include="ClassicModes\DragVerticesMode.cs" />
|
<Compile Include="ClassicModes\DragVerticesMode.cs" />
|
||||||
<Compile Include="ClassicModes\LinedefsMode.cs" />
|
<Compile Include="ClassicModes\LinedefsMode.cs" />
|
||||||
|
<Compile Include="VisualModes\BaseVisualThing.cs" />
|
||||||
<Compile Include="VisualModes\VisualCeiling.cs" />
|
<Compile Include="VisualModes\VisualCeiling.cs" />
|
||||||
<Compile Include="VisualModes\VisualFloor.cs" />
|
<Compile Include="VisualModes\VisualFloor.cs" />
|
||||||
<Compile Include="VisualModes\VisualLower.cs" />
|
<Compile Include="VisualModes\VisualLower.cs" />
|
||||||
|
|
|
@ -100,6 +100,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
return new BaseVisualSector(s);
|
return new BaseVisualSector(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This creates a visual thing
|
||||||
|
protected override VisualThing CreateVisualThing(Thing t)
|
||||||
|
{
|
||||||
|
return new BaseVisualThing(t);
|
||||||
|
}
|
||||||
|
|
||||||
// This locks the target so that it isn't changed until unlocked
|
// This locks the target so that it isn't changed until unlocked
|
||||||
public void LockTarget()
|
public void LockTarget()
|
||||||
{
|
{
|
||||||
|
@ -122,26 +128,36 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
VisualPickResult newtarget = PickObject(start, start + delta);
|
VisualPickResult newtarget = PickObject(start, start + delta);
|
||||||
|
|
||||||
// Object changed?
|
// Object changed?
|
||||||
if(newtarget.geometry != target.geometry)
|
if(newtarget.picked != target.picked)
|
||||||
{
|
{
|
||||||
// Any result?
|
// Any result?
|
||||||
if(newtarget.geometry != null)
|
if(newtarget.picked != null)
|
||||||
{
|
{
|
||||||
if(newtarget.geometry.Sidedef != null)
|
VisualGeometry prevgeo = null;
|
||||||
|
if((target.picked != null) && (target.picked is VisualGeometry))
|
||||||
|
prevgeo = (target.picked as VisualGeometry);
|
||||||
|
|
||||||
|
// Geometry picked?
|
||||||
|
if(newtarget.picked is VisualGeometry)
|
||||||
{
|
{
|
||||||
if((target.geometry != null) && (target.geometry.Sidedef == null)) General.Interface.HideInfo();
|
VisualGeometry pickedgeo = (newtarget.picked as VisualGeometry);
|
||||||
General.Interface.ShowLinedefInfo(newtarget.geometry.Sidedef.Line);
|
|
||||||
|
if(pickedgeo.Sidedef != null)
|
||||||
|
{
|
||||||
|
if((prevgeo != null) && (prevgeo.Sidedef == null)) General.Interface.HideInfo();
|
||||||
|
General.Interface.ShowLinedefInfo(pickedgeo.Sidedef.Line);
|
||||||
}
|
}
|
||||||
else if(newtarget.geometry.Sidedef == null)
|
else if(pickedgeo.Sidedef == null)
|
||||||
{
|
{
|
||||||
if((target.geometry == null) || (target.geometry.Sidedef != null)) General.Interface.HideInfo();
|
if((prevgeo == null) || (prevgeo.Sidedef != null)) General.Interface.HideInfo();
|
||||||
General.Interface.ShowSectorInfo(newtarget.geometry.Sector.Sector);
|
General.Interface.ShowSectorInfo(pickedgeo.Sector.Sector);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
General.Interface.HideInfo();
|
General.Interface.HideInfo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
General.Interface.HideInfo();
|
General.Interface.HideInfo();
|
||||||
|
@ -155,9 +171,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// This changes the target's height
|
// This changes the target's height
|
||||||
private void ChangeTargetHeight(int amount)
|
private void ChangeTargetHeight(int amount)
|
||||||
{
|
{
|
||||||
if(target.geometry is BaseVisualGeometrySector)
|
if(target.picked is BaseVisualGeometrySector)
|
||||||
{
|
{
|
||||||
BaseVisualGeometrySector vgs = (target.geometry as BaseVisualGeometrySector);
|
BaseVisualGeometrySector vgs = (target.picked as BaseVisualGeometrySector);
|
||||||
vgs.ChangeHeight(amount);
|
vgs.ChangeHeight(amount);
|
||||||
|
|
||||||
// Rebuild sector
|
// Rebuild sector
|
||||||
|
@ -240,25 +256,25 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
[BeginAction("visualselect", BaseAction = true)]
|
[BeginAction("visualselect", BaseAction = true)]
|
||||||
public void BeginSelect()
|
public void BeginSelect()
|
||||||
{
|
{
|
||||||
if(target.geometry != null) (target.geometry as BaseVisualGeometry).OnSelectBegin();
|
if(target.picked != null) (target.picked as BaseVisualGeometry).OnSelectBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
[EndAction("visualselect", BaseAction = true)]
|
[EndAction("visualselect", BaseAction = true)]
|
||||||
public void EndSelect()
|
public void EndSelect()
|
||||||
{
|
{
|
||||||
if(target.geometry != null) (target.geometry as BaseVisualGeometry).OnSelectEnd();
|
if(target.picked != null) (target.picked as BaseVisualGeometry).OnSelectEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
[BeginAction("visualedit", BaseAction = true)]
|
[BeginAction("visualedit", BaseAction = true)]
|
||||||
public void BeginEdit()
|
public void BeginEdit()
|
||||||
{
|
{
|
||||||
if(target.geometry != null) (target.geometry as BaseVisualGeometry).OnEditBegin();
|
if(target.picked != null) (target.picked as BaseVisualGeometry).OnEditBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
[EndAction("visualedit", BaseAction = true)]
|
[EndAction("visualedit", BaseAction = true)]
|
||||||
public void EndEdit()
|
public void EndEdit()
|
||||||
{
|
{
|
||||||
if(target.geometry != null) (target.geometry as BaseVisualGeometry).OnEditEnd();
|
if(target.picked != null) (target.picked as BaseVisualGeometry).OnEditEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
[BeginAction("raisesector8")]
|
[BeginAction("raisesector8")]
|
||||||
|
|
67
Source/BuilderModes/VisualModes/BaseVisualThing.cs
Normal file
67
Source/BuilderModes/VisualModes/BaseVisualThing.cs
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||||
|
* This program is released under GNU General Public License
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Namespaces
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using CodeImp.DoomBuilder.Windows;
|
||||||
|
using CodeImp.DoomBuilder.IO;
|
||||||
|
using CodeImp.DoomBuilder.Map;
|
||||||
|
using CodeImp.DoomBuilder.Rendering;
|
||||||
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
|
using CodeImp.DoomBuilder.Editing;
|
||||||
|
using CodeImp.DoomBuilder.VisualModes;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
{
|
||||||
|
internal class BaseVisualThing : VisualThing
|
||||||
|
{
|
||||||
|
#region ================== Constants
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Variables
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Properties
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Constructor / Disposer
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public BaseVisualThing(Thing t) : base(t)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Methods
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
48
Source/VisualModes/IVisualPickable.cs
Normal file
48
Source/VisualModes/IVisualPickable.cs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
|
||||||
|
#region ================== Copyright (c) 2007 Pascal vd Heiden
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com
|
||||||
|
* This program is released under GNU General Public License
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Namespaces
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using CodeImp.DoomBuilder.Map;
|
||||||
|
using SlimDX.Direct3D9;
|
||||||
|
using SlimDX;
|
||||||
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using CodeImp.DoomBuilder.Data;
|
||||||
|
using CodeImp.DoomBuilder.Editing;
|
||||||
|
using CodeImp.DoomBuilder.IO;
|
||||||
|
using CodeImp.DoomBuilder.Rendering;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
namespace CodeImp.DoomBuilder.VisualModes
|
||||||
|
{
|
||||||
|
public interface IVisualPickable
|
||||||
|
{
|
||||||
|
bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir);
|
||||||
|
bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray);
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,12 +44,14 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
|
|
||||||
// Members
|
// Members
|
||||||
private List<Linedef> lines;
|
private List<Linedef> lines;
|
||||||
|
private List<Thing> things;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Properties
|
#region ================== Properties
|
||||||
|
|
||||||
public List<Linedef> Lines { get { return lines; } }
|
public List<Linedef> Lines { get { return lines; } }
|
||||||
|
public List<Thing> Things { get { return things; } }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -58,7 +60,8 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
// Constructor for empty block
|
// Constructor for empty block
|
||||||
internal VisualBlockEntry()
|
internal VisualBlockEntry()
|
||||||
{
|
{
|
||||||
lines = new List<Linedef>();
|
lines = new List<Linedef>(2);
|
||||||
|
things = new List<Thing>(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -271,6 +271,20 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This puts a thing in the blockmap
|
||||||
|
public void AddThingsSet(ICollection<Thing> things)
|
||||||
|
{
|
||||||
|
foreach(Thing t in things) AddThing(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This puts a thing in the blockmap
|
||||||
|
public void AddThing(Thing t)
|
||||||
|
{
|
||||||
|
Point p = GetBlockCoordinates(t.Position);
|
||||||
|
VisualBlockEntry block = GetBlock(p);
|
||||||
|
block.Things.Add(t);
|
||||||
|
}
|
||||||
|
|
||||||
// This puts a whole set of linedefs in the blocks they cross
|
// This puts a whole set of linedefs in the blocks they cross
|
||||||
public void AddLinedefsSet(ICollection<Linedef> lines)
|
public void AddLinedefsSet(ICollection<Linedef> lines)
|
||||||
{
|
{
|
||||||
|
|
|
@ -40,7 +40,7 @@ using CodeImp.DoomBuilder.Rendering;
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.VisualModes
|
namespace CodeImp.DoomBuilder.VisualModes
|
||||||
{
|
{
|
||||||
public abstract class VisualGeometry : IComparable<VisualGeometry>
|
public abstract class VisualGeometry : IVisualPickable, IComparable<VisualGeometry>
|
||||||
{
|
{
|
||||||
#region ================== Variables
|
#region ================== Variables
|
||||||
|
|
||||||
|
|
|
@ -76,8 +76,10 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
|
|
||||||
// Map
|
// Map
|
||||||
protected VisualBlockMap blockmap;
|
protected VisualBlockMap blockmap;
|
||||||
|
protected Dictionary<Thing, VisualThing> allthings;
|
||||||
protected Dictionary<Sector, VisualSector> allsectors;
|
protected Dictionary<Sector, VisualSector> allsectors;
|
||||||
protected List<VisualBlockEntry> visibleblocks;
|
protected List<VisualBlockEntry> visibleblocks;
|
||||||
|
protected List<VisualThing> visiblethings;
|
||||||
protected Dictionary<Sector, VisualSector> visiblesectors;
|
protected Dictionary<Sector, VisualSector> visiblesectors;
|
||||||
protected List<VisualGeometry> visiblegeometry;
|
protected List<VisualGeometry> visiblegeometry;
|
||||||
|
|
||||||
|
@ -105,9 +107,11 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
this.camanglez = Angle2D.PI;
|
this.camanglez = Angle2D.PI;
|
||||||
this.blockmap = new VisualBlockMap();
|
this.blockmap = new VisualBlockMap();
|
||||||
this.allsectors = new Dictionary<Sector, VisualSector>(General.Map.Map.Sectors.Count);
|
this.allsectors = new Dictionary<Sector, VisualSector>(General.Map.Map.Sectors.Count);
|
||||||
|
this.allthings = new Dictionary<Thing,VisualThing>(General.Map.Map.Things.Count);
|
||||||
this.visibleblocks = new List<VisualBlockEntry>();
|
this.visibleblocks = new List<VisualBlockEntry>();
|
||||||
this.visiblesectors = new Dictionary<Sector, VisualSector>(50);
|
this.visiblesectors = new Dictionary<Sector, VisualSector>(50);
|
||||||
this.visiblegeometry = new List<VisualGeometry>(200);
|
this.visiblegeometry = new List<VisualGeometry>(200);
|
||||||
|
this.visiblethings = new List<VisualThing>(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disposer
|
// Disposer
|
||||||
|
@ -122,7 +126,9 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
visiblesectors = null;
|
visiblesectors = null;
|
||||||
visiblegeometry = null;
|
visiblegeometry = null;
|
||||||
visibleblocks = null;
|
visibleblocks = null;
|
||||||
|
visiblethings = null;
|
||||||
allsectors = null;
|
allsectors = null;
|
||||||
|
allthings = null;
|
||||||
blockmap = null;
|
blockmap = null;
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
|
@ -199,9 +205,11 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
base.OnUndoEnd();
|
base.OnUndoEnd();
|
||||||
|
|
||||||
allsectors.Clear();
|
allsectors.Clear();
|
||||||
|
allthings.Clear();
|
||||||
visiblesectors.Clear();
|
visiblesectors.Clear();
|
||||||
visibleblocks.Clear();
|
visibleblocks.Clear();
|
||||||
visiblegeometry.Clear();
|
visiblegeometry.Clear();
|
||||||
|
visiblethings.Clear();
|
||||||
|
|
||||||
// Make new blockmap
|
// Make new blockmap
|
||||||
if(blockmap != null)
|
if(blockmap != null)
|
||||||
|
@ -230,9 +238,11 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
base.OnRedoEnd();
|
base.OnRedoEnd();
|
||||||
|
|
||||||
allsectors.Clear();
|
allsectors.Clear();
|
||||||
|
allthings.Clear();
|
||||||
visiblesectors.Clear();
|
visiblesectors.Clear();
|
||||||
visibleblocks.Clear();
|
visibleblocks.Clear();
|
||||||
visiblegeometry.Clear();
|
visiblegeometry.Clear();
|
||||||
|
visiblethings.Clear();
|
||||||
|
|
||||||
// Make new blockmap
|
// Make new blockmap
|
||||||
if(blockmap != null)
|
if(blockmap != null)
|
||||||
|
@ -349,8 +359,10 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
// Fill visiblity collections
|
// Fill visiblity collections
|
||||||
visiblesectors = new Dictionary<Sector, VisualSector>(visiblesectors.Count);
|
visiblesectors = new Dictionary<Sector, VisualSector>(visiblesectors.Count);
|
||||||
visiblegeometry = new List<VisualGeometry>(visiblegeometry.Capacity);
|
visiblegeometry = new List<VisualGeometry>(visiblegeometry.Capacity);
|
||||||
|
visiblethings = new List<VisualThing>(visiblethings.Capacity);
|
||||||
foreach(VisualBlockEntry block in visibleblocks)
|
foreach(VisualBlockEntry block in visibleblocks)
|
||||||
{
|
{
|
||||||
|
// Lines
|
||||||
foreach(Linedef ld in block.Lines)
|
foreach(Linedef ld in block.Lines)
|
||||||
{
|
{
|
||||||
// Line not already processed?
|
// Line not already processed?
|
||||||
|
@ -372,6 +384,25 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Things
|
||||||
|
foreach(Thing t in block.Things)
|
||||||
|
{
|
||||||
|
VisualThing vt;
|
||||||
|
|
||||||
|
if(allthings.ContainsKey(t))
|
||||||
|
{
|
||||||
|
vt = allthings[t];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Create new visual thing
|
||||||
|
vt = CreateVisualThing(t);
|
||||||
|
allthings.Add(t, vt);
|
||||||
|
}
|
||||||
|
|
||||||
|
visiblethings.Add(vt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find camera sector
|
// Find camera sector
|
||||||
|
@ -475,7 +506,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
Vector3D delta = to - from;
|
Vector3D delta = to - from;
|
||||||
|
|
||||||
// Setup no result
|
// Setup no result
|
||||||
result.geometry = null;
|
result.picked = null;
|
||||||
result.hitpos = new Vector3D();
|
result.hitpos = new Vector3D();
|
||||||
result.u_ray = 1.0f;
|
result.u_ray = 1.0f;
|
||||||
|
|
||||||
|
@ -485,14 +516,14 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
// Make collections
|
// Make collections
|
||||||
Dictionary<Linedef, Linedef> lines = new Dictionary<Linedef, Linedef>(blocks.Count * 10);
|
Dictionary<Linedef, Linedef> lines = new Dictionary<Linedef, Linedef>(blocks.Count * 10);
|
||||||
Dictionary<Sector, VisualSector> sectors = new Dictionary<Sector, VisualSector>(blocks.Count * 10);
|
Dictionary<Sector, VisualSector> sectors = new Dictionary<Sector, VisualSector>(blocks.Count * 10);
|
||||||
List<VisualGeometry> potentialgeometry = new List<VisualGeometry>(blocks.Count * 10);
|
List<IVisualPickable> pickables = new List<IVisualPickable>(blocks.Count * 10);
|
||||||
|
|
||||||
// Add geometry from the camera sector
|
// Add geometry from the camera sector
|
||||||
if((camsector != null) && allsectors.ContainsKey(camsector))
|
if((camsector != null) && allsectors.ContainsKey(camsector))
|
||||||
{
|
{
|
||||||
VisualSector vs = allsectors[camsector];
|
VisualSector vs = allsectors[camsector];
|
||||||
sectors.Add(camsector, vs);
|
sectors.Add(camsector, vs);
|
||||||
potentialgeometry.AddRange(vs.FixedGeometry);
|
foreach(VisualGeometry g in vs.FixedGeometry) pickables.Add(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go for all lines to see which ones we intersect
|
// Go for all lines to see which ones we intersect
|
||||||
|
@ -531,16 +562,18 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
if(!sectors.ContainsKey(ld.Front.Sector))
|
if(!sectors.ContainsKey(ld.Front.Sector))
|
||||||
{
|
{
|
||||||
sectors.Add(ld.Front.Sector, vs);
|
sectors.Add(ld.Front.Sector, vs);
|
||||||
potentialgeometry.AddRange(vs.FixedGeometry);
|
foreach(VisualGeometry g in vs.FixedGeometry) pickables.Add(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add sidedef if on the front side
|
// Add sidedef if on the front side
|
||||||
if(side < 0.0f)
|
if(side < 0.0f)
|
||||||
{
|
{
|
||||||
int previndex = potentialgeometry.Count;
|
List<VisualGeometry> sidedefgeo = vs.GetSidedefGeometry(ld.Front);
|
||||||
potentialgeometry.AddRange(vs.GetSidedefGeometry(ld.Front));
|
foreach(VisualGeometry g in sidedefgeo)
|
||||||
for(int i = previndex; i < potentialgeometry.Count; i++)
|
{
|
||||||
potentialgeometry[i].SetPickResults(intersect, u);
|
g.SetPickResults(intersect, u);
|
||||||
|
pickables.Add(g);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -557,16 +590,18 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
if(!sectors.ContainsKey(ld.Back.Sector))
|
if(!sectors.ContainsKey(ld.Back.Sector))
|
||||||
{
|
{
|
||||||
sectors.Add(ld.Back.Sector, vs);
|
sectors.Add(ld.Back.Sector, vs);
|
||||||
potentialgeometry.AddRange(vs.FixedGeometry);
|
foreach(VisualGeometry g in vs.FixedGeometry) pickables.Add(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add sidedef if on the front side
|
// Add sidedef if on the front side
|
||||||
if(side > 0.0f)
|
if(side > 0.0f)
|
||||||
{
|
{
|
||||||
int previndex = potentialgeometry.Count;
|
List<VisualGeometry> sidedefgeo = vs.GetSidedefGeometry(ld.Back);
|
||||||
potentialgeometry.AddRange(vs.GetSidedefGeometry(ld.Back));
|
foreach(VisualGeometry g in sidedefgeo)
|
||||||
for(int i = previndex; i < potentialgeometry.Count; i++)
|
{
|
||||||
potentialgeometry[i].SetPickResults(intersect, u);
|
g.SetPickResults(intersect, u);
|
||||||
|
pickables.Add(g);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -580,24 +615,24 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
// This is still too much for accurate intersection testing, so we do a fast reject pass first.
|
// This is still too much for accurate intersection testing, so we do a fast reject pass first.
|
||||||
Vector3D direction = to - from;
|
Vector3D direction = to - from;
|
||||||
direction = direction.GetNormal();
|
direction = direction.GetNormal();
|
||||||
List<VisualGeometry> likelygeometry = new List<VisualGeometry>(potentialgeometry.Count);
|
List<IVisualPickable> potentialpicks = new List<IVisualPickable>(pickables.Count);
|
||||||
foreach(VisualGeometry g in potentialgeometry)
|
foreach(IVisualPickable p in pickables)
|
||||||
{
|
{
|
||||||
if(g.PickFastReject(from, to, direction)) likelygeometry.Add(g);
|
if(p.PickFastReject(from, to, direction)) potentialpicks.Add(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we do an accurate intersection test for all resulting geometry
|
// Now we do an accurate intersection test for all resulting geometry
|
||||||
// We keep only the closest hit!
|
// We keep only the closest hit!
|
||||||
foreach(VisualGeometry g in likelygeometry)
|
foreach(IVisualPickable p in potentialpicks)
|
||||||
{
|
{
|
||||||
float u = result.u_ray;
|
float u = result.u_ray;
|
||||||
if(g.PickAccurate(from, to, direction, ref u))
|
if(p.PickAccurate(from, to, direction, ref u))
|
||||||
{
|
{
|
||||||
// Closer than previous find?
|
// Closer than previous find?
|
||||||
if((u > 0.0f) && (u < result.u_ray))
|
if((u > 0.0f) && (u < result.u_ray))
|
||||||
{
|
{
|
||||||
result.u_ray = u;
|
result.u_ray = u;
|
||||||
result.geometry = g;
|
result.picked = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -616,6 +651,9 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
// This creates a visual sector
|
// This creates a visual sector
|
||||||
protected abstract VisualSector CreateVisualSector(Sector s);
|
protected abstract VisualSector CreateVisualSector(Sector s);
|
||||||
|
|
||||||
|
// This creates a visual thing
|
||||||
|
protected abstract VisualThing CreateVisualThing(Thing t);
|
||||||
|
|
||||||
// This returns a visual sector
|
// This returns a visual sector
|
||||||
protected VisualSector GetVisualSector(Sector s)
|
protected VisualSector GetVisualSector(Sector s)
|
||||||
{
|
{
|
||||||
|
@ -632,6 +670,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
protected virtual void FillBlockMap()
|
protected virtual void FillBlockMap()
|
||||||
{
|
{
|
||||||
blockmap.AddLinedefsSet(General.Map.Map.Linedefs);
|
blockmap.AddLinedefsSet(General.Map.Map.Linedefs);
|
||||||
|
blockmap.AddThingsSet(General.Map.Map.Things);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Processing
|
// Processing
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
public struct VisualPickResult
|
public struct VisualPickResult
|
||||||
{
|
{
|
||||||
// Members
|
// Members
|
||||||
public VisualGeometry geometry;
|
public IVisualPickable picked;
|
||||||
public float u_ray;
|
public float u_ray;
|
||||||
public Vector3D hitpos;
|
public Vector3D hitpos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
internal List<VisualGeometry> AllGeometry { get { return allgeometry; } }
|
internal List<VisualGeometry> AllGeometry { get { return allgeometry; } }
|
||||||
internal VertexBuffer GeometryBuffer { get { return geobuffer; } }
|
internal VertexBuffer GeometryBuffer { get { return geobuffer; } }
|
||||||
internal bool NeedsUpdateGeo { get { return updategeo; } set { updategeo |= value; } }
|
internal bool NeedsUpdateGeo { get { return updategeo; } set { updategeo |= value; } }
|
||||||
|
|
||||||
public bool IsDisposed { get { return isdisposed; } }
|
public bool IsDisposed { get { return isdisposed; } }
|
||||||
public Sector Sector { get { return sector; } }
|
public Sector Sector { get { return sector; } }
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ using CodeImp.DoomBuilder.Rendering;
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.VisualModes
|
namespace CodeImp.DoomBuilder.VisualModes
|
||||||
{
|
{
|
||||||
public abstract class VisualThing : IComparable<VisualThing>
|
public abstract class VisualThing : IVisualPickable, ID3DResource, IComparable<VisualThing>
|
||||||
{
|
{
|
||||||
#region ================== Constants
|
#region ================== Constants
|
||||||
|
|
||||||
|
@ -51,11 +51,32 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
// Thing
|
// Thing
|
||||||
private Thing thing;
|
private Thing thing;
|
||||||
|
|
||||||
|
// Texture
|
||||||
|
private ImageData texture;
|
||||||
|
|
||||||
|
// Geometry
|
||||||
|
private WorldVertex[] spritevertices;
|
||||||
|
private WorldVertex[] cagevertices;
|
||||||
|
private VertexBuffer geobuffer;
|
||||||
|
private bool updategeo;
|
||||||
|
private int spritetriangles;
|
||||||
|
private int cagetriangles;
|
||||||
|
|
||||||
|
// Disposing
|
||||||
|
private bool isdisposed = false;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Properties
|
#region ================== Properties
|
||||||
|
|
||||||
|
internal VertexBuffer GeometryBuffer { get { return geobuffer; } }
|
||||||
|
internal bool NeedsUpdateGeo { get { return updategeo; } }
|
||||||
|
internal int SpriteTriangles { get { return spritetriangles; } }
|
||||||
|
internal int CageTriangles { get { return cagetriangles; } }
|
||||||
|
internal int CageOffset { get { return spritevertices.Length; } }
|
||||||
|
|
||||||
public Thing Thing { get { return thing; } }
|
public Thing Thing { get { return thing; } }
|
||||||
|
public bool IsDisposed { get { return isdisposed; } }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -66,16 +87,122 @@ namespace CodeImp.DoomBuilder.VisualModes
|
||||||
{
|
{
|
||||||
// Initialize
|
// Initialize
|
||||||
this.thing = t;
|
this.thing = t;
|
||||||
|
|
||||||
|
// Register as resource
|
||||||
|
General.Map.Graphics.RegisterResource(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disposer
|
||||||
|
public virtual void Dispose()
|
||||||
|
{
|
||||||
|
// Not already disposed?
|
||||||
|
if(!isdisposed)
|
||||||
|
{
|
||||||
|
// Clean up
|
||||||
|
if(geobuffer != null) geobuffer.Dispose();
|
||||||
|
geobuffer = null;
|
||||||
|
|
||||||
|
// Unregister resource
|
||||||
|
General.Map.Graphics.UnregisterResource(this);
|
||||||
|
|
||||||
|
// Done
|
||||||
|
isdisposed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Methods
|
#region ================== Methods
|
||||||
|
|
||||||
|
// This is called before a device is reset
|
||||||
|
// (when resized or display adapter was changed)
|
||||||
|
public void UnloadResource()
|
||||||
|
{
|
||||||
|
// Trash geometry buffer
|
||||||
|
if(geobuffer != null) geobuffer.Dispose();
|
||||||
|
geobuffer = null;
|
||||||
|
updategeo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is called resets when the device is reset
|
||||||
|
// (when resized or display adapter was changed)
|
||||||
|
public void ReloadResource()
|
||||||
|
{
|
||||||
|
// Make new geometry
|
||||||
|
//Update();
|
||||||
|
}
|
||||||
|
|
||||||
// This compares for sorting by sprite
|
// This compares for sorting by sprite
|
||||||
public int CompareTo(VisualThing other)
|
public int CompareTo(VisualThing other)
|
||||||
{
|
{
|
||||||
return 0;
|
return Math.Sign(this.texture.LongName - other.texture.LongName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This sets the vertices for the thing sprite
|
||||||
|
protected void SetSpriteVertices(ICollection<WorldVertex> verts)
|
||||||
|
{
|
||||||
|
// Copy vertices
|
||||||
|
spritevertices = new WorldVertex[verts.Count];
|
||||||
|
verts.CopyTo(spritevertices, 0);
|
||||||
|
spritetriangles = spritevertices.Length / 3;
|
||||||
|
updategeo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This sets the vertices for the thing cage
|
||||||
|
protected void SetCageVertices(ICollection<WorldVertex> verts)
|
||||||
|
{
|
||||||
|
// Copy vertices
|
||||||
|
cagevertices = new WorldVertex[verts.Count];
|
||||||
|
verts.CopyTo(cagevertices, 0);
|
||||||
|
cagetriangles = cagevertices.Length / 3;
|
||||||
|
updategeo = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This updates the visual sector
|
||||||
|
public void Update()
|
||||||
|
{
|
||||||
|
// Trash geometry buffer
|
||||||
|
if(geobuffer != null) geobuffer.Dispose();
|
||||||
|
geobuffer = null;
|
||||||
|
|
||||||
|
// Count the number of vertices there are
|
||||||
|
int numverts = spritevertices.Length + cagevertices.Length;
|
||||||
|
|
||||||
|
// Any vertics?
|
||||||
|
if(numverts > 0)
|
||||||
|
{
|
||||||
|
// Make a new buffer
|
||||||
|
geobuffer = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * numverts,
|
||||||
|
Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default);
|
||||||
|
|
||||||
|
// Fill the buffer
|
||||||
|
DataStream bufferstream = geobuffer.Lock(0, WorldVertex.Stride * numverts, LockFlags.Discard);
|
||||||
|
bufferstream.WriteRange<WorldVertex>(spritevertices);
|
||||||
|
bufferstream.WriteRange<WorldVertex>(cagevertices);
|
||||||
|
geobuffer.Unlock();
|
||||||
|
bufferstream.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done
|
||||||
|
updategeo = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is called when the thing must be tested for line intersection. This should reject
|
||||||
|
/// as fast as possible to rule out all geometry that certainly does not touch the line.
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is called when the thing must be tested for line intersection. This should perform
|
||||||
|
/// accurate hit detection and set u_ray to the position on the ray where this hits the geometry.
|
||||||
|
/// </summary>
|
||||||
|
public virtual bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref float u_ray)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
Loading…
Reference in a new issue