mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-31 04:40:55 +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\CrosshairBusy.png" />
|
||||
<Content Include="Resources\DB2.ico" />
|
||||
<Compile Include="VisualModes\IVisualPickable.cs" />
|
||||
<Compile Include="General\BinaryHeap.cs" />
|
||||
<Compile Include="Geometry\Plane.cs" />
|
||||
<Compile Include="Geometry\ProjectedFrustum2D.cs" />
|
||||
|
|
|
@ -109,6 +109,7 @@
|
|||
<Compile Include="VisualModes\BaseVisualSector.cs" />
|
||||
<Compile Include="ClassicModes\DragVerticesMode.cs" />
|
||||
<Compile Include="ClassicModes\LinedefsMode.cs" />
|
||||
<Compile Include="VisualModes\BaseVisualThing.cs" />
|
||||
<Compile Include="VisualModes\VisualCeiling.cs" />
|
||||
<Compile Include="VisualModes\VisualFloor.cs" />
|
||||
<Compile Include="VisualModes\VisualLower.cs" />
|
||||
|
|
|
@ -100,6 +100,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
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
|
||||
public void LockTarget()
|
||||
{
|
||||
|
@ -122,24 +128,34 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
VisualPickResult newtarget = PickObject(start, start + delta);
|
||||
|
||||
// Object changed?
|
||||
if(newtarget.geometry != target.geometry)
|
||||
if(newtarget.picked != target.picked)
|
||||
{
|
||||
// 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();
|
||||
General.Interface.ShowLinedefInfo(newtarget.geometry.Sidedef.Line);
|
||||
}
|
||||
else if(newtarget.geometry.Sidedef == null)
|
||||
{
|
||||
if((target.geometry == null) || (target.geometry.Sidedef != null)) General.Interface.HideInfo();
|
||||
General.Interface.ShowSectorInfo(newtarget.geometry.Sector.Sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
General.Interface.HideInfo();
|
||||
VisualGeometry pickedgeo = (newtarget.picked as VisualGeometry);
|
||||
|
||||
if(pickedgeo.Sidedef != null)
|
||||
{
|
||||
if((prevgeo != null) && (prevgeo.Sidedef == null)) General.Interface.HideInfo();
|
||||
General.Interface.ShowLinedefInfo(pickedgeo.Sidedef.Line);
|
||||
}
|
||||
else if(pickedgeo.Sidedef == null)
|
||||
{
|
||||
if((prevgeo == null) || (prevgeo.Sidedef != null)) General.Interface.HideInfo();
|
||||
General.Interface.ShowSectorInfo(pickedgeo.Sector.Sector);
|
||||
}
|
||||
else
|
||||
{
|
||||
General.Interface.HideInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -155,9 +171,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
// This changes the target's height
|
||||
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);
|
||||
|
||||
// Rebuild sector
|
||||
|
@ -240,25 +256,25 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
[BeginAction("visualselect", BaseAction = true)]
|
||||
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)]
|
||||
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)]
|
||||
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)]
|
||||
public void EndEdit()
|
||||
{
|
||||
if(target.geometry != null) (target.geometry as BaseVisualGeometry).OnEditEnd();
|
||||
if(target.picked != null) (target.picked as BaseVisualGeometry).OnEditEnd();
|
||||
}
|
||||
|
||||
[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,21 +44,24 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
|
||||
// Members
|
||||
private List<Linedef> lines;
|
||||
private List<Thing> things;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Properties
|
||||
|
||||
public List<Linedef> Lines { get { return lines; } }
|
||||
public List<Thing> Things { get { return things; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor
|
||||
|
||||
|
||||
// Constructor for empty block
|
||||
internal VisualBlockEntry()
|
||||
{
|
||||
lines = new List<Linedef>();
|
||||
lines = new List<Linedef>(2);
|
||||
things = new List<Thing>(2);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -271,6 +271,20 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
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
|
||||
public void AddLinedefsSet(ICollection<Linedef> lines)
|
||||
{
|
||||
|
|
|
@ -40,7 +40,7 @@ using CodeImp.DoomBuilder.Rendering;
|
|||
|
||||
namespace CodeImp.DoomBuilder.VisualModes
|
||||
{
|
||||
public abstract class VisualGeometry : IComparable<VisualGeometry>
|
||||
public abstract class VisualGeometry : IVisualPickable, IComparable<VisualGeometry>
|
||||
{
|
||||
#region ================== Variables
|
||||
|
||||
|
|
|
@ -76,8 +76,10 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
|
||||
// Map
|
||||
protected VisualBlockMap blockmap;
|
||||
protected Dictionary<Thing, VisualThing> allthings;
|
||||
protected Dictionary<Sector, VisualSector> allsectors;
|
||||
protected List<VisualBlockEntry> visibleblocks;
|
||||
protected List<VisualThing> visiblethings;
|
||||
protected Dictionary<Sector, VisualSector> visiblesectors;
|
||||
protected List<VisualGeometry> visiblegeometry;
|
||||
|
||||
|
@ -105,11 +107,13 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
this.camanglez = Angle2D.PI;
|
||||
this.blockmap = new VisualBlockMap();
|
||||
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.visiblesectors = new Dictionary<Sector, VisualSector>(50);
|
||||
this.visiblegeometry = new List<VisualGeometry>(200);
|
||||
this.visiblethings = new List<VisualThing>(100);
|
||||
}
|
||||
|
||||
|
||||
// Disposer
|
||||
public override void Dispose()
|
||||
{
|
||||
|
@ -122,7 +126,9 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
visiblesectors = null;
|
||||
visiblegeometry = null;
|
||||
visibleblocks = null;
|
||||
visiblethings = null;
|
||||
allsectors = null;
|
||||
allthings = null;
|
||||
blockmap = null;
|
||||
|
||||
// Done
|
||||
|
@ -199,9 +205,11 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
base.OnUndoEnd();
|
||||
|
||||
allsectors.Clear();
|
||||
allthings.Clear();
|
||||
visiblesectors.Clear();
|
||||
visibleblocks.Clear();
|
||||
visiblegeometry.Clear();
|
||||
visiblethings.Clear();
|
||||
|
||||
// Make new blockmap
|
||||
if(blockmap != null)
|
||||
|
@ -230,10 +238,12 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
base.OnRedoEnd();
|
||||
|
||||
allsectors.Clear();
|
||||
allthings.Clear();
|
||||
visiblesectors.Clear();
|
||||
visibleblocks.Clear();
|
||||
visiblegeometry.Clear();
|
||||
|
||||
visiblethings.Clear();
|
||||
|
||||
// Make new blockmap
|
||||
if(blockmap != null)
|
||||
{
|
||||
|
@ -335,7 +345,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
#endregion
|
||||
|
||||
#region ================== Visibility Culling
|
||||
|
||||
|
||||
// This preforms visibility culling
|
||||
private void DoCulling()
|
||||
{
|
||||
|
@ -349,8 +359,10 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
// Fill visiblity collections
|
||||
visiblesectors = new Dictionary<Sector, VisualSector>(visiblesectors.Count);
|
||||
visiblegeometry = new List<VisualGeometry>(visiblegeometry.Capacity);
|
||||
visiblethings = new List<VisualThing>(visiblethings.Capacity);
|
||||
foreach(VisualBlockEntry block in visibleblocks)
|
||||
{
|
||||
// Lines
|
||||
foreach(Linedef ld in block.Lines)
|
||||
{
|
||||
// Line not already processed?
|
||||
|
@ -358,7 +370,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
{
|
||||
// Add line if not added yet
|
||||
visiblelines.Add(ld, ld);
|
||||
|
||||
|
||||
// Which side of the line is the camera on?
|
||||
if(ld.SideOfLine(campos2d) < 0)
|
||||
{
|
||||
|
@ -372,8 +384,27 @@ 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
|
||||
Linedef nld = MapSet.NearestLinedef(visiblelines.Values, campos2d);
|
||||
if(nld != null)
|
||||
|
@ -419,7 +450,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
private void ProcessSidedefCulling(Sidedef sd)
|
||||
{
|
||||
VisualSector vs;
|
||||
|
||||
|
||||
// Find the visualsector and make it if needed
|
||||
if(allsectors.ContainsKey(sd.Sector))
|
||||
{
|
||||
|
@ -432,7 +463,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
vs = CreateVisualSector(sd.Sector);
|
||||
allsectors.Add(sd.Sector, vs);
|
||||
}
|
||||
|
||||
|
||||
// Add to visible sectors if not added yet
|
||||
if(!visiblesectors.ContainsKey(sd.Sector))
|
||||
{
|
||||
|
@ -475,7 +506,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
Vector3D delta = to - from;
|
||||
|
||||
// Setup no result
|
||||
result.geometry = null;
|
||||
result.picked = null;
|
||||
result.hitpos = new Vector3D();
|
||||
result.u_ray = 1.0f;
|
||||
|
||||
|
@ -485,14 +516,14 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
// Make collections
|
||||
Dictionary<Linedef, Linedef> lines = new Dictionary<Linedef, Linedef>(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
|
||||
if((camsector != null) && allsectors.ContainsKey(camsector))
|
||||
{
|
||||
VisualSector vs = allsectors[camsector];
|
||||
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
|
||||
|
@ -531,16 +562,18 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
if(!sectors.ContainsKey(ld.Front.Sector))
|
||||
{
|
||||
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
|
||||
if(side < 0.0f)
|
||||
{
|
||||
int previndex = potentialgeometry.Count;
|
||||
potentialgeometry.AddRange(vs.GetSidedefGeometry(ld.Front));
|
||||
for(int i = previndex; i < potentialgeometry.Count; i++)
|
||||
potentialgeometry[i].SetPickResults(intersect, u);
|
||||
List<VisualGeometry> sidedefgeo = vs.GetSidedefGeometry(ld.Front);
|
||||
foreach(VisualGeometry g in sidedefgeo)
|
||||
{
|
||||
g.SetPickResults(intersect, u);
|
||||
pickables.Add(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -557,16 +590,18 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
if(!sectors.ContainsKey(ld.Back.Sector))
|
||||
{
|
||||
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
|
||||
if(side > 0.0f)
|
||||
{
|
||||
int previndex = potentialgeometry.Count;
|
||||
potentialgeometry.AddRange(vs.GetSidedefGeometry(ld.Back));
|
||||
for(int i = previndex; i < potentialgeometry.Count; i++)
|
||||
potentialgeometry[i].SetPickResults(intersect, u);
|
||||
List<VisualGeometry> sidedefgeo = vs.GetSidedefGeometry(ld.Back);
|
||||
foreach(VisualGeometry g in sidedefgeo)
|
||||
{
|
||||
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.
|
||||
Vector3D direction = to - from;
|
||||
direction = direction.GetNormal();
|
||||
List<VisualGeometry> likelygeometry = new List<VisualGeometry>(potentialgeometry.Count);
|
||||
foreach(VisualGeometry g in potentialgeometry)
|
||||
List<IVisualPickable> potentialpicks = new List<IVisualPickable>(pickables.Count);
|
||||
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
|
||||
// We keep only the closest hit!
|
||||
foreach(VisualGeometry g in likelygeometry)
|
||||
foreach(IVisualPickable p in potentialpicks)
|
||||
{
|
||||
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?
|
||||
if((u > 0.0f) && (u < result.u_ray))
|
||||
{
|
||||
result.u_ray = u;
|
||||
result.geometry = g;
|
||||
result.picked = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -615,6 +650,9 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
|
||||
// This creates a visual sector
|
||||
protected abstract VisualSector CreateVisualSector(Sector s);
|
||||
|
||||
// This creates a visual thing
|
||||
protected abstract VisualThing CreateVisualThing(Thing t);
|
||||
|
||||
// This returns a visual sector
|
||||
protected VisualSector GetVisualSector(Sector s)
|
||||
|
@ -632,6 +670,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
protected virtual void FillBlockMap()
|
||||
{
|
||||
blockmap.AddLinedefsSet(General.Map.Map.Linedefs);
|
||||
blockmap.AddThingsSet(General.Map.Map.Things);
|
||||
}
|
||||
|
||||
// Processing
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
public struct VisualPickResult
|
||||
{
|
||||
// Members
|
||||
public VisualGeometry geometry;
|
||||
public IVisualPickable picked;
|
||||
public float u_ray;
|
||||
public Vector3D hitpos;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ namespace CodeImp.DoomBuilder.VisualModes
|
|||
internal List<VisualGeometry> AllGeometry { get { return allgeometry; } }
|
||||
internal VertexBuffer GeometryBuffer { get { return geobuffer; } }
|
||||
internal bool NeedsUpdateGeo { get { return updategeo; } set { updategeo |= value; } }
|
||||
|
||||
public bool IsDisposed { get { return isdisposed; } }
|
||||
public Sector Sector { get { return sector; } }
|
||||
|
||||
|
|
|
@ -40,44 +40,171 @@ using CodeImp.DoomBuilder.Rendering;
|
|||
|
||||
namespace CodeImp.DoomBuilder.VisualModes
|
||||
{
|
||||
public abstract class VisualThing : IComparable<VisualThing>
|
||||
public abstract class VisualThing : IVisualPickable, ID3DResource, IComparable<VisualThing>
|
||||
{
|
||||
#region ================== Constants
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
#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 bool IsDisposed { get { return isdisposed; } }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region ================== Constructor / Destructor
|
||||
|
||||
|
||||
// Constructor
|
||||
public VisualThing(Thing t)
|
||||
{
|
||||
// Initialize
|
||||
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
|
||||
|
||||
|
||||
#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
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue