mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-07 08:21:59 +00:00
some 3D mode rendering
This commit is contained in:
parent
dee7a72413
commit
3c43547c6c
41 changed files with 1192 additions and 1387 deletions
BIN
Resources/MissingTexture3D.png
Normal file
BIN
Resources/MissingTexture3D.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 695 B |
|
@ -360,6 +360,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="Resources\Builder.ico" />
|
<Content Include="Resources\Builder.ico" />
|
||||||
|
<EmbeddedResource Include="Resources\MissingTexture3D.png" />
|
||||||
<None Include="Resources\MissingTexture.png" />
|
<None Include="Resources\MissingTexture.png" />
|
||||||
<None Include="Resources\UnknownImage.png" />
|
<None Include="Resources\UnknownImage.png" />
|
||||||
<None Include="Resources\treeview.png" />
|
<None Include="Resources\treeview.png" />
|
||||||
|
|
|
@ -36,22 +36,26 @@
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Editing\BaseVisualMode.cs" />
|
<Compile Include="VisualMode\BaseVisualMode.cs" />
|
||||||
<Compile Include="Editing\DragVerticesMode.cs" />
|
<Compile Include="VisualMode\BaseVisualSector.cs" />
|
||||||
<Compile Include="Editing\LinedefsMode.cs" />
|
<Compile Include="VerticesMode\DragVerticesMode.cs" />
|
||||||
<Compile Include="Editing\TriangulatorMode.cs" />
|
<Compile Include="LinedefsMode\LinedefsMode.cs" />
|
||||||
<Compile Include="Editing\VisualObject.cs" />
|
<Compile Include="VisualMode\VisualCeiling.cs" />
|
||||||
<Compile Include="Editing\WAuthorMode.cs" />
|
<Compile Include="VisualMode\VisualFloor.cs" />
|
||||||
<Compile Include="Editing\WAuthorTools.cs">
|
<Compile Include="VisualMode\VisualLower.cs" />
|
||||||
|
<Compile Include="VisualMode\VisualMiddle.cs" />
|
||||||
|
<Compile Include="Testing\WAuthorMode.cs" />
|
||||||
|
<Compile Include="Testing\WAuthorTools.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Editing\WAuthorTools.Designer.cs">
|
<Compile Include="Testing\WAuthorTools.Designer.cs">
|
||||||
<DependentUpon>WAuthorTools.cs</DependentUpon>
|
<DependentUpon>WAuthorTools.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Editing\SectorsMode.cs" />
|
<Compile Include="SectorsMode\SectorsMode.cs" />
|
||||||
<Compile Include="Editing\ThingsMode.cs" />
|
<Compile Include="ThingsMode\ThingsMode.cs" />
|
||||||
<Compile Include="Editing\VerticesMode.cs" />
|
<Compile Include="VerticesMode\VerticesMode.cs" />
|
||||||
|
<Compile Include="VisualMode\VisualUpper.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Builder.csproj">
|
<ProjectReference Include="..\Builder.csproj">
|
||||||
|
@ -76,7 +80,7 @@
|
||||||
<EmbeddedResource Include="Resources\SectorsMode.png" />
|
<EmbeddedResource Include="Resources\SectorsMode.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Editing\WAuthorTools.resx">
|
<EmbeddedResource Include="Testing\WAuthorTools.resx">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<DependentUpon>WAuthorTools.cs</DependentUpon>
|
<DependentUpon>WAuthorTools.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
@ -85,9 +89,6 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="Resources\VisualMode.png" />
|
<EmbeddedResource Include="Resources\VisualMode.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
|
||||||
<EmbeddedResource Include="Resources\TriangulatorMode.png" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
Other similar extension points exist, see Microsoft.Common.targets.
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
|
|
@ -1,535 +0,0 @@
|
||||||
|
|
||||||
#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.Interface;
|
|
||||||
using CodeImp.DoomBuilder.IO;
|
|
||||||
using CodeImp.DoomBuilder.Map;
|
|
||||||
using CodeImp.DoomBuilder.Rendering;
|
|
||||||
using CodeImp.DoomBuilder.Geometry;
|
|
||||||
using CodeImp.DoomBuilder.Editing;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Drawing;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
[EditMode(SwitchAction = "triangulatormode", // Action name used to switch to this mode
|
|
||||||
ButtonDesc = "Triangulator Mode", // Description on the button in toolbar/menu
|
|
||||||
ButtonImage = "TriangulatorMode.png", // Image resource name for the button
|
|
||||||
ButtonOrder = int.MaxValue)] // Position of the button (lower is more to the left)
|
|
||||||
|
|
||||||
public class TriangulatorMode : ClassicMode
|
|
||||||
{
|
|
||||||
#region ================== Constants
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ================== Variables
|
|
||||||
|
|
||||||
// Highlighted item
|
|
||||||
private Sector highlighted;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ================== Properties
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ================== Constructor / Disposer
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
public TriangulatorMode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disposer
|
|
||||||
public override void Dispose()
|
|
||||||
{
|
|
||||||
// Not already disposed?
|
|
||||||
if(!isdisposed)
|
|
||||||
{
|
|
||||||
// Clean up
|
|
||||||
|
|
||||||
// Dispose base
|
|
||||||
base.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ================== Methods
|
|
||||||
|
|
||||||
// Cancel mode
|
|
||||||
public override void Cancel()
|
|
||||||
{
|
|
||||||
base.Cancel();
|
|
||||||
|
|
||||||
// Return to this mode
|
|
||||||
General.Map.ChangeMode(new SectorsMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mode engages
|
|
||||||
public override void Engage()
|
|
||||||
{
|
|
||||||
base.Engage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mode disengages
|
|
||||||
public override void Disengage()
|
|
||||||
{
|
|
||||||
base.Disengage();
|
|
||||||
|
|
||||||
// Check which mode we are switching to
|
|
||||||
if(General.Map.NewMode is VerticesMode)
|
|
||||||
{
|
|
||||||
// Convert selection to vertices
|
|
||||||
|
|
||||||
// Clear selected sectors
|
|
||||||
General.Map.Map.ClearSelectedSectors();
|
|
||||||
}
|
|
||||||
else if(General.Map.NewMode is LinedefsMode)
|
|
||||||
{
|
|
||||||
// Convert selection to linedefs
|
|
||||||
|
|
||||||
// Clear selected sectors
|
|
||||||
General.Map.Map.ClearSelectedSectors();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide highlight info
|
|
||||||
General.Interface.HideInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This redraws the display
|
|
||||||
public unsafe override void RedrawDisplay()
|
|
||||||
{
|
|
||||||
// Start with a clear display
|
|
||||||
if(renderer.Start(true, true))
|
|
||||||
{
|
|
||||||
// Do not show things
|
|
||||||
renderer.SetThingsRenderOrder(false);
|
|
||||||
|
|
||||||
// Render lines and vertices
|
|
||||||
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
|
||||||
renderer.RenderVerticesSet(General.Map.Map.Vertices);
|
|
||||||
|
|
||||||
// Render highlighted item
|
|
||||||
if((highlighted != null) && !highlighted.IsDisposed)
|
|
||||||
renderer.RenderSector(highlighted, General.Colors.Highlight);
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This highlights a new item
|
|
||||||
protected void Highlight(Sector s)
|
|
||||||
{
|
|
||||||
// Update display
|
|
||||||
if(renderer.Start(false, false))
|
|
||||||
{
|
|
||||||
// Undraw previous highlight
|
|
||||||
if((highlighted != null) && !highlighted.IsDisposed)
|
|
||||||
renderer.RenderSector(highlighted);
|
|
||||||
|
|
||||||
// Set new highlight
|
|
||||||
highlighted = s;
|
|
||||||
|
|
||||||
// Render highlighted item
|
|
||||||
if((highlighted != null) && !highlighted.IsDisposed)
|
|
||||||
renderer.RenderSector(highlighted, General.Colors.Highlight);
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show highlight info
|
|
||||||
if((highlighted != null) && !highlighted.IsDisposed)
|
|
||||||
General.Interface.ShowSectorInfo(highlighted);
|
|
||||||
else
|
|
||||||
General.Interface.HideInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse moves
|
|
||||||
public override void MouseMove(MouseEventArgs e)
|
|
||||||
{
|
|
||||||
base.MouseMove(e);
|
|
||||||
|
|
||||||
// Find the nearest linedef within highlight range
|
|
||||||
Linedef l = General.Map.Map.NearestLinedef(mousemappos);
|
|
||||||
|
|
||||||
// Check on which side of the linedef the mouse is
|
|
||||||
float side = l.SideOfLine(mousemappos);
|
|
||||||
if(side > 0)
|
|
||||||
{
|
|
||||||
// Is there a sidedef here?
|
|
||||||
if(l.Back != null)
|
|
||||||
{
|
|
||||||
// Highlight if not the same
|
|
||||||
if(l.Back.Sector != highlighted) Highlight(l.Back.Sector);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Highlight nothing
|
|
||||||
if(highlighted != null) Highlight(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Is there a sidedef here?
|
|
||||||
if(l.Front != null)
|
|
||||||
{
|
|
||||||
// Highlight if not the same
|
|
||||||
if(l.Front.Sector != highlighted) Highlight(l.Front.Sector);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Highlight nothing
|
|
||||||
if(highlighted != null) Highlight(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse leaves
|
|
||||||
public override void MouseLeave(EventArgs e)
|
|
||||||
{
|
|
||||||
base.MouseLeave(e);
|
|
||||||
|
|
||||||
// Highlight nothing
|
|
||||||
Highlight(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse button pressed
|
|
||||||
public override void MouseDown(MouseEventArgs e)
|
|
||||||
{
|
|
||||||
base.MouseDown(e);
|
|
||||||
bool front, back;
|
|
||||||
|
|
||||||
// Which button is used?
|
|
||||||
if(e.Button == EditMode.SELECT_BUTTON)
|
|
||||||
{
|
|
||||||
// Item highlighted?
|
|
||||||
if((highlighted != null) && !highlighted.IsDisposed)
|
|
||||||
{
|
|
||||||
// Flip selection
|
|
||||||
highlighted.Selected = !highlighted.Selected;
|
|
||||||
|
|
||||||
// Make update lines selection
|
|
||||||
foreach(Sidedef sd in highlighted.Sidedefs)
|
|
||||||
{
|
|
||||||
if(sd.Line.Front != null) front = sd.Line.Front.Sector.Selected; else front = false;
|
|
||||||
if(sd.Line.Back != null) back = sd.Line.Back.Sector.Selected; else back = false;
|
|
||||||
sd.Line.Selected = front | back;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update display
|
|
||||||
if(renderer.Start(false, false))
|
|
||||||
{
|
|
||||||
// Redraw highlight to show selection
|
|
||||||
renderer.RenderSector(highlighted);
|
|
||||||
renderer.Finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse released
|
|
||||||
public override void MouseUp(MouseEventArgs e)
|
|
||||||
{
|
|
||||||
ICollection<Sector> selected;
|
|
||||||
TriangleList triangles;
|
|
||||||
|
|
||||||
base.MouseUp(e);
|
|
||||||
|
|
||||||
// Item highlighted?
|
|
||||||
if((highlighted != null) && !highlighted.IsDisposed)
|
|
||||||
{
|
|
||||||
// Which button is used?
|
|
||||||
if(e.Button == EditMode.SELECT_BUTTON)
|
|
||||||
{
|
|
||||||
// Anything selected?
|
|
||||||
selected = General.Map.Map.GetSectorsSelection(true);
|
|
||||||
if(selected.Count > 0)
|
|
||||||
{
|
|
||||||
// Remove highlight
|
|
||||||
Highlight(null);
|
|
||||||
|
|
||||||
// Clear selection
|
|
||||||
General.Map.Map.ClearSelectedSectors();
|
|
||||||
General.Map.Map.ClearSelectedLinedefs();
|
|
||||||
General.Interface.RedrawDisplay();
|
|
||||||
|
|
||||||
// Get a triangulator and bind events
|
|
||||||
EarClipTriangulator t = new EarClipTriangulator();
|
|
||||||
t.OnShowLine = new EarClipTriangulator.ShowLine(ShowLine);
|
|
||||||
t.OnShowPolygon = new EarClipTriangulator.ShowPolygon(ShowPolygon);
|
|
||||||
t.OnShowPoint = new EarClipTriangulator.ShowPoint(ShowPoint);
|
|
||||||
t.OnShowEarClip = new EarClipTriangulator.ShowEarClip(ShowEarClip);
|
|
||||||
|
|
||||||
// Triangulate this now!
|
|
||||||
triangles = t.Triangulate(General.GetByIndex<Sector>(selected, 0));
|
|
||||||
|
|
||||||
// Start with a clear display
|
|
||||||
if(renderer.Start(true, true))
|
|
||||||
{
|
|
||||||
// Do not show things
|
|
||||||
renderer.SetThingsRenderOrder(false);
|
|
||||||
|
|
||||||
// Render lines and vertices
|
|
||||||
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
|
||||||
renderer.RenderVerticesSet(General.Map.Map.Vertices);
|
|
||||||
|
|
||||||
// Go for all triangle vertices
|
|
||||||
for(int i = 0; i < triangles.Count; i += 3)
|
|
||||||
{
|
|
||||||
renderer.RenderLine(triangles[i + 0], triangles[i + 1], General.Colors.Selection);
|
|
||||||
renderer.RenderLine(triangles[i + 1], triangles[i + 2], General.Colors.Selection);
|
|
||||||
renderer.RenderLine(triangles[i + 2], triangles[i + 0], General.Colors.Selection);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
Thread.Sleep(200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Get a triangulator and bind events
|
|
||||||
EarClipTriangulator t = new EarClipTriangulator();
|
|
||||||
|
|
||||||
// Triangulate the whole map!
|
|
||||||
triangles = new TriangleList();
|
|
||||||
foreach(Sector s in General.Map.Map.Sectors)
|
|
||||||
triangles.AddRange(t.Triangulate(s));
|
|
||||||
|
|
||||||
// Start with a clear display
|
|
||||||
if(renderer.Start(true, true))
|
|
||||||
{
|
|
||||||
// Do not show things
|
|
||||||
renderer.SetThingsRenderOrder(false);
|
|
||||||
|
|
||||||
// Render lines and vertices
|
|
||||||
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
|
||||||
renderer.RenderVerticesSet(General.Map.Map.Vertices);
|
|
||||||
|
|
||||||
// Go for all triangle vertices
|
|
||||||
for(int i = 0; i < triangles.Count; i += 3)
|
|
||||||
{
|
|
||||||
renderer.RenderLine(triangles[i + 0], triangles[i + 1], General.Colors.Selection);
|
|
||||||
renderer.RenderLine(triangles[i + 1], triangles[i + 2], General.Colors.Selection);
|
|
||||||
renderer.RenderLine(triangles[i + 2], triangles[i + 0], General.Colors.Selection);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
Thread.Sleep(200);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This shows a point
|
|
||||||
private void ShowPoint(Vector2D v, int c)
|
|
||||||
{
|
|
||||||
for(int a = 0; a < 6; a++)
|
|
||||||
{
|
|
||||||
RedrawDisplay();
|
|
||||||
Thread.Sleep(10);
|
|
||||||
|
|
||||||
// Start with a clear display
|
|
||||||
if(renderer.Start(true, true))
|
|
||||||
{
|
|
||||||
// Do not show things
|
|
||||||
renderer.SetThingsRenderOrder(false);
|
|
||||||
|
|
||||||
// Render lines and vertices
|
|
||||||
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
|
||||||
renderer.RenderVerticesSet(General.Map.Map.Vertices);
|
|
||||||
|
|
||||||
// Show the point
|
|
||||||
renderer.RenderVertexAt(v, c);
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait a bit
|
|
||||||
Thread.Sleep(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This shows a line
|
|
||||||
private void ShowLine(Vector2D v1, Vector2D v2, PixelColor c)
|
|
||||||
{
|
|
||||||
// Start with a clear display
|
|
||||||
if(renderer.Start(true, true))
|
|
||||||
{
|
|
||||||
// Do not show things
|
|
||||||
renderer.SetThingsRenderOrder(false);
|
|
||||||
|
|
||||||
// Render lines and vertices
|
|
||||||
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
|
||||||
renderer.RenderVerticesSet(General.Map.Map.Vertices);
|
|
||||||
|
|
||||||
// Show the line
|
|
||||||
renderer.RenderLine(v1, v2, c);
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait a bit
|
|
||||||
Thread.Sleep(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This shows a polygon
|
|
||||||
private void ShowPolygon(Polygon p, PixelColor c)
|
|
||||||
{
|
|
||||||
LinkedListNode<EarClipVertex> v;
|
|
||||||
|
|
||||||
for(int a = 0; a < 5; a++)
|
|
||||||
{
|
|
||||||
RedrawDisplay();
|
|
||||||
Thread.Sleep(10);
|
|
||||||
|
|
||||||
// Start with a clear display
|
|
||||||
if(renderer.Start(true, true))
|
|
||||||
{
|
|
||||||
// Do not show things
|
|
||||||
renderer.SetThingsRenderOrder(false);
|
|
||||||
|
|
||||||
// Render lines and vertices
|
|
||||||
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
|
||||||
renderer.RenderVerticesSet(General.Map.Map.Vertices);
|
|
||||||
|
|
||||||
// Go for all vertices in the polygon
|
|
||||||
v = p.First;
|
|
||||||
while(v != null)
|
|
||||||
{
|
|
||||||
// Show the line
|
|
||||||
if(v.Next != null) renderer.RenderLine(v.Value.Position, v.Next.Value.Position, c);
|
|
||||||
v = v.Next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show last line as well
|
|
||||||
renderer.RenderLine(p.Last.Value.Position, p.First.Value.Position, c);
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait a bit
|
|
||||||
Thread.Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This shows a polygon
|
|
||||||
private void ShowEarClip(EarClipVertex[] found, LinkedList<EarClipVertex> remains)
|
|
||||||
{
|
|
||||||
EarClipVertex prev, first;
|
|
||||||
|
|
||||||
for(int a = 0; a < 5; a++)
|
|
||||||
{
|
|
||||||
// Start with a clear display
|
|
||||||
if(renderer.Start(true, true))
|
|
||||||
{
|
|
||||||
// Do not show things
|
|
||||||
renderer.SetThingsRenderOrder(false);
|
|
||||||
|
|
||||||
// Render lines and vertices
|
|
||||||
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
|
||||||
renderer.RenderVerticesSet(General.Map.Map.Vertices);
|
|
||||||
|
|
||||||
// Go for all remaining vertices
|
|
||||||
prev = null; first = null;
|
|
||||||
foreach(EarClipVertex v in remains)
|
|
||||||
{
|
|
||||||
// Show the line
|
|
||||||
if(prev != null) renderer.RenderLine(v.Position, prev.Position, PixelColor.FromColor(Color.OrangeRed));
|
|
||||||
if(prev == null) first = v;
|
|
||||||
prev = v;
|
|
||||||
|
|
||||||
if(v.IsReflex)
|
|
||||||
renderer.RenderVertexAt(v.Position, ColorCollection.SELECTION);
|
|
||||||
else
|
|
||||||
renderer.RenderVertexAt(v.Position, ColorCollection.VERTICES);
|
|
||||||
}
|
|
||||||
if(first != null) renderer.RenderLine(first.Position, prev.Position, PixelColor.FromColor(Color.OrangeRed));
|
|
||||||
|
|
||||||
if(found != null)
|
|
||||||
{
|
|
||||||
renderer.RenderLine(found[0].Position, found[1].Position, PixelColor.FromColor(Color.SkyBlue));
|
|
||||||
renderer.RenderLine(found[1].Position, found[2].Position, PixelColor.FromColor(Color.SkyBlue));
|
|
||||||
renderer.RenderLine(found[2].Position, found[0].Position, PixelColor.FromColor(Color.SkyBlue));
|
|
||||||
renderer.RenderVertexAt(found[1].Position, ColorCollection.ASSOCIATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
}
|
|
||||||
Thread.Sleep(10);
|
|
||||||
|
|
||||||
// Start with a clear display
|
|
||||||
if(renderer.Start(true, true))
|
|
||||||
{
|
|
||||||
// Do not show things
|
|
||||||
renderer.SetThingsRenderOrder(false);
|
|
||||||
|
|
||||||
// Render lines and vertices
|
|
||||||
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
|
||||||
renderer.RenderVerticesSet(General.Map.Map.Vertices);
|
|
||||||
|
|
||||||
// Go for all remaining vertices
|
|
||||||
prev = null; first = null;
|
|
||||||
foreach(EarClipVertex v in remains)
|
|
||||||
{
|
|
||||||
// Show the line
|
|
||||||
if(prev != null) renderer.RenderLine(v.Position, prev.Position, PixelColor.FromColor(Color.OrangeRed));
|
|
||||||
if(prev == null) first = v;
|
|
||||||
prev = v;
|
|
||||||
|
|
||||||
if(v.IsReflex)
|
|
||||||
renderer.RenderVertexAt(v.Position, ColorCollection.SELECTION);
|
|
||||||
else
|
|
||||||
renderer.RenderVertexAt(v.Position, ColorCollection.VERTICES);
|
|
||||||
}
|
|
||||||
if(first != null) renderer.RenderLine(first.Position, prev.Position, PixelColor.FromColor(Color.OrangeRed));
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
}
|
|
||||||
Thread.Sleep(20);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
|
@ -1,365 +0,0 @@
|
||||||
|
|
||||||
#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.Interface;
|
|
||||||
using CodeImp.DoomBuilder.IO;
|
|
||||||
using CodeImp.DoomBuilder.Map;
|
|
||||||
using CodeImp.DoomBuilder.Rendering;
|
|
||||||
using CodeImp.DoomBuilder.Geometry;
|
|
||||||
using CodeImp.DoomBuilder.Editing;
|
|
||||||
using CodeImp.DoomBuilder.Controls;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|
||||||
{
|
|
||||||
[EditMode(SwitchAction = "wauthormode",
|
|
||||||
ButtonDesc = "WadAuthor Mode",
|
|
||||||
ButtonImage = "WAuthor.png",
|
|
||||||
ButtonOrder = int.MinValue + 4,
|
|
||||||
ConfigSpecific = true)]
|
|
||||||
|
|
||||||
public class WAuthorMode : ClassicMode
|
|
||||||
{
|
|
||||||
#region ================== Constants
|
|
||||||
|
|
||||||
protected const float LINEDEF_HIGHLIGHT_RANGE = 10f;
|
|
||||||
protected const float VERTEX_HIGHLIGHT_RANGE = 8f;
|
|
||||||
protected const float THING_HIGHLIGHT_RANGE = 2f;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ================== Variables
|
|
||||||
|
|
||||||
// Tools
|
|
||||||
protected WAuthorTools tools;
|
|
||||||
|
|
||||||
// Highlighted item
|
|
||||||
protected object highlighted;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ================== Properties
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ================== Constructor / Disposer
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
public WAuthorMode()
|
|
||||||
{
|
|
||||||
// Initialize
|
|
||||||
tools = new WAuthorTools();
|
|
||||||
|
|
||||||
// Enable this and you'll have a floating window
|
|
||||||
//tools.Show(General.Interface);
|
|
||||||
//General.Interface.Focus();
|
|
||||||
|
|
||||||
// We have no destructor
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disposer
|
|
||||||
public override void Dispose()
|
|
||||||
{
|
|
||||||
// Not already disposed?
|
|
||||||
if(!isdisposed)
|
|
||||||
{
|
|
||||||
// Clean up
|
|
||||||
tools.Dispose();
|
|
||||||
|
|
||||||
// Dispose base
|
|
||||||
base.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ================== Methods
|
|
||||||
|
|
||||||
// Cancel mode
|
|
||||||
public override void Cancel()
|
|
||||||
{
|
|
||||||
base.Cancel();
|
|
||||||
|
|
||||||
// Return to this mode
|
|
||||||
General.Map.ChangeMode(new WAuthorMode());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mode engages
|
|
||||||
public override void Engage()
|
|
||||||
{
|
|
||||||
base.Engage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mode disengages
|
|
||||||
public override void Disengage()
|
|
||||||
{
|
|
||||||
base.Disengage();
|
|
||||||
|
|
||||||
// Clear selected vertices
|
|
||||||
General.Map.Map.ClearAllSelected();
|
|
||||||
|
|
||||||
// Hide highlight info
|
|
||||||
General.Interface.HideInfo();
|
|
||||||
}
|
|
||||||
|
|
||||||
// This redraws the display
|
|
||||||
public unsafe override void RedrawDisplay()
|
|
||||||
{
|
|
||||||
// Start with a clear display
|
|
||||||
if(renderer.Start(true, true))
|
|
||||||
{
|
|
||||||
// Render things
|
|
||||||
renderer.SetThingsRenderOrder(true);
|
|
||||||
renderer.RenderThingSet(General.Map.Map.Things);
|
|
||||||
|
|
||||||
// Render lines and vertices
|
|
||||||
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
|
||||||
renderer.RenderVerticesSet(General.Map.Map.Vertices);
|
|
||||||
|
|
||||||
// Render highlighted item
|
|
||||||
if(highlighted != null) DrawHighlight(true);
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This draws the highlighted item
|
|
||||||
protected void DrawHighlight(bool highlightcolor)
|
|
||||||
{
|
|
||||||
// With highlight color
|
|
||||||
if(highlightcolor)
|
|
||||||
{
|
|
||||||
// Vertex
|
|
||||||
if(highlighted is Vertex)
|
|
||||||
{
|
|
||||||
if((highlighted as Vertex).IsDisposed) return;
|
|
||||||
renderer.RenderVertex(highlighted as Vertex, ColorCollection.HIGHLIGHT);
|
|
||||||
}
|
|
||||||
// Linedef
|
|
||||||
else if(highlighted is Linedef)
|
|
||||||
{
|
|
||||||
if((highlighted as Linedef).IsDisposed) return;
|
|
||||||
renderer.RenderLinedef((highlighted as Linedef), General.Colors.Highlight);
|
|
||||||
renderer.RenderVertex((highlighted as Linedef).Start, renderer.DetermineVertexColor((highlighted as Linedef).Start));
|
|
||||||
renderer.RenderVertex((highlighted as Linedef).End, renderer.DetermineVertexColor((highlighted as Linedef).End));
|
|
||||||
}
|
|
||||||
// Sector
|
|
||||||
else if(highlighted is Sector)
|
|
||||||
{
|
|
||||||
if((highlighted as Sector).IsDisposed) return;
|
|
||||||
renderer.RenderSector((highlighted as Sector), General.Colors.Highlight);
|
|
||||||
}
|
|
||||||
// Thing
|
|
||||||
else if(highlighted is Thing)
|
|
||||||
{
|
|
||||||
if((highlighted as Thing).IsDisposed) return;
|
|
||||||
renderer.RenderThing((highlighted as Thing), General.Colors.Highlight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// With original color
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Vertex
|
|
||||||
if(highlighted is Vertex)
|
|
||||||
{
|
|
||||||
if((highlighted as Vertex).IsDisposed) return;
|
|
||||||
renderer.RenderVertex(highlighted as Vertex, renderer.DetermineVertexColor(highlighted as Vertex));
|
|
||||||
}
|
|
||||||
// Linedef
|
|
||||||
else if(highlighted is Linedef)
|
|
||||||
{
|
|
||||||
if((highlighted as Linedef).IsDisposed) return;
|
|
||||||
renderer.RenderLinedef((highlighted as Linedef), renderer.DetermineLinedefColor((highlighted as Linedef)));
|
|
||||||
renderer.RenderVertex((highlighted as Linedef).Start, renderer.DetermineVertexColor((highlighted as Linedef).Start));
|
|
||||||
renderer.RenderVertex((highlighted as Linedef).End, renderer.DetermineVertexColor((highlighted as Linedef).End));
|
|
||||||
}
|
|
||||||
// Sector
|
|
||||||
else if(highlighted is Sector)
|
|
||||||
{
|
|
||||||
if((highlighted as Sector).IsDisposed) return;
|
|
||||||
renderer.RenderSector((highlighted as Sector));
|
|
||||||
}
|
|
||||||
// Thing
|
|
||||||
else if(highlighted is Thing)
|
|
||||||
{
|
|
||||||
if((highlighted as Thing).IsDisposed) return;
|
|
||||||
renderer.RenderThing((highlighted as Thing), renderer.DetermineThingColor((highlighted as Thing)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This highlights a new item
|
|
||||||
protected void Highlight(object h)
|
|
||||||
{
|
|
||||||
// Changes?
|
|
||||||
if(highlighted != h)
|
|
||||||
{
|
|
||||||
// Update display
|
|
||||||
if(renderer.Start(false, false))
|
|
||||||
{
|
|
||||||
// Undraw previous highlight
|
|
||||||
if(highlighted != null) DrawHighlight(false);
|
|
||||||
|
|
||||||
// Set new highlight
|
|
||||||
highlighted = h;
|
|
||||||
|
|
||||||
// Render highlighted item
|
|
||||||
if(highlighted != null) DrawHighlight(true);
|
|
||||||
|
|
||||||
// Done
|
|
||||||
renderer.Finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide info
|
|
||||||
General.Interface.HideInfo();
|
|
||||||
|
|
||||||
// Anything highlighted?
|
|
||||||
if(highlighted != null)
|
|
||||||
{
|
|
||||||
// Show highlight info
|
|
||||||
if(highlighted is Vertex)
|
|
||||||
General.Interface.ShowVertexInfo(highlighted as Vertex);
|
|
||||||
else if(highlighted is Linedef)
|
|
||||||
General.Interface.ShowLinedefInfo(highlighted as Linedef);
|
|
||||||
else if(highlighted is Sector)
|
|
||||||
General.Interface.ShowSectorInfo(highlighted as Sector);
|
|
||||||
else if(highlighted is Thing)
|
|
||||||
General.Interface.ShowThingInfo(highlighted as Thing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse moves
|
|
||||||
public override void MouseMove(MouseEventArgs e)
|
|
||||||
{
|
|
||||||
base.MouseMove(e);
|
|
||||||
|
|
||||||
// Not holding any buttons?
|
|
||||||
if(e.Button == MouseButtons.None)
|
|
||||||
{
|
|
||||||
// Find the nearest items within highlight range
|
|
||||||
Vertex v = General.Map.Map.NearestVertexSquareRange(mousemappos, VERTEX_HIGHLIGHT_RANGE / renderer.Scale);
|
|
||||||
Thing t = General.Map.Map.NearestThingSquareRange(mousemappos, THING_HIGHLIGHT_RANGE / renderer.Scale);
|
|
||||||
Linedef l = General.Map.Map.NearestLinedef(mousemappos);
|
|
||||||
Sector s;
|
|
||||||
|
|
||||||
// Check on which side of the linedef the mouse is
|
|
||||||
float side = l.SideOfLine(mousemappos);
|
|
||||||
if(side > 0)
|
|
||||||
{
|
|
||||||
// Is there a sidedef here?
|
|
||||||
if(l.Back != null) s = l.Back.Sector;
|
|
||||||
else s = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Is there a sidedef here?
|
|
||||||
if(l.Front != null) s = l.Front.Sector;
|
|
||||||
else s = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Both a vertex and thing in range?
|
|
||||||
if((v != null) && (t != null))
|
|
||||||
{
|
|
||||||
// Highlight closest
|
|
||||||
float vd = v.DistanceToSq(mousemappos);
|
|
||||||
float td = t.DistanceToSq(mousemappos);
|
|
||||||
if(vd < td) Highlight(v); else Highlight(t);
|
|
||||||
}
|
|
||||||
// Vertex in range?
|
|
||||||
else if(v != null)
|
|
||||||
{
|
|
||||||
// Highlight vertex
|
|
||||||
Highlight(v);
|
|
||||||
}
|
|
||||||
// Thing in range?
|
|
||||||
else if(t != null)
|
|
||||||
{
|
|
||||||
// Highlight thing
|
|
||||||
Highlight(t);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Linedef within in range?
|
|
||||||
float ld = l.DistanceTo(mousemappos, true);
|
|
||||||
if(ld < (LINEDEF_HIGHLIGHT_RANGE / renderer.Scale))
|
|
||||||
{
|
|
||||||
// Highlight line
|
|
||||||
Highlight(l);
|
|
||||||
}
|
|
||||||
// Mouse inside a sector?
|
|
||||||
else if(s != null)
|
|
||||||
{
|
|
||||||
// Highlight sector
|
|
||||||
Highlight(s);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Highlight nothing
|
|
||||||
Highlight(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Maybe i'll finish this later, or not even include this mode at all, not sure yet.
|
|
||||||
|
|
||||||
// Mouse leaves
|
|
||||||
public override void MouseLeave(EventArgs e)
|
|
||||||
{
|
|
||||||
base.MouseLeave(e);
|
|
||||||
|
|
||||||
// Highlight nothing
|
|
||||||
Highlight(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse button pressed
|
|
||||||
public override void MouseDown(MouseEventArgs e)
|
|
||||||
{
|
|
||||||
base.MouseDown(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse released
|
|
||||||
public override void MouseUp(MouseEventArgs e)
|
|
||||||
{
|
|
||||||
base.MouseUp(e);
|
|
||||||
|
|
||||||
// This shows a popup menu
|
|
||||||
tools.LinedefPopup.Show(Cursor.Position);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mouse wants to drag
|
|
||||||
protected override void DragStart(MouseEventArgs e)
|
|
||||||
{
|
|
||||||
base.DragStart(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
116
Source/BuilderModes/Editing/WAuthorTools.Designer.cs
generated
116
Source/BuilderModes/Editing/WAuthorTools.Designer.cs
generated
|
@ -1,116 +0,0 @@
|
||||||
namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|
||||||
{
|
|
||||||
partial class WAuthorTools
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Required designer variable.
|
|
||||||
/// </summary>
|
|
||||||
private System.ComponentModel.IContainer components = null;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Clean up any resources being used.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
|
||||||
protected override void Dispose(bool disposing)
|
|
||||||
{
|
|
||||||
if(disposing && (components != null))
|
|
||||||
{
|
|
||||||
components.Dispose();
|
|
||||||
}
|
|
||||||
base.Dispose(disposing);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Windows Form Designer generated code
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Required method for Designer support - do not modify
|
|
||||||
/// the contents of this method with the code editor.
|
|
||||||
/// </summary>
|
|
||||||
private void InitializeComponent()
|
|
||||||
{
|
|
||||||
this.components = new System.ComponentModel.Container();
|
|
||||||
this.linedefpopup = new System.Windows.Forms.ContextMenuStrip(this.components);
|
|
||||||
this.propertiesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
|
|
||||||
this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.splitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.flipToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.curveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
|
||||||
this.linedefpopup.SuspendLayout();
|
|
||||||
this.SuspendLayout();
|
|
||||||
//
|
|
||||||
// linedefpopup
|
|
||||||
//
|
|
||||||
this.linedefpopup.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
|
||||||
this.propertiesToolStripMenuItem,
|
|
||||||
this.toolStripMenuItem1,
|
|
||||||
this.deleteToolStripMenuItem,
|
|
||||||
this.splitToolStripMenuItem,
|
|
||||||
this.flipToolStripMenuItem,
|
|
||||||
this.curveToolStripMenuItem});
|
|
||||||
this.linedefpopup.Name = "linedefpopup";
|
|
||||||
this.linedefpopup.Size = new System.Drawing.Size(147, 120);
|
|
||||||
//
|
|
||||||
// propertiesToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.propertiesToolStripMenuItem.Name = "propertiesToolStripMenuItem";
|
|
||||||
this.propertiesToolStripMenuItem.Size = new System.Drawing.Size(146, 22);
|
|
||||||
this.propertiesToolStripMenuItem.Text = "Properties...";
|
|
||||||
//
|
|
||||||
// toolStripMenuItem1
|
|
||||||
//
|
|
||||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
|
||||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(143, 6);
|
|
||||||
//
|
|
||||||
// deleteToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";
|
|
||||||
this.deleteToolStripMenuItem.Size = new System.Drawing.Size(146, 22);
|
|
||||||
this.deleteToolStripMenuItem.Text = "Delete";
|
|
||||||
//
|
|
||||||
// splitToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.splitToolStripMenuItem.Name = "splitToolStripMenuItem";
|
|
||||||
this.splitToolStripMenuItem.Size = new System.Drawing.Size(146, 22);
|
|
||||||
this.splitToolStripMenuItem.Text = "Split";
|
|
||||||
//
|
|
||||||
// flipToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.flipToolStripMenuItem.Name = "flipToolStripMenuItem";
|
|
||||||
this.flipToolStripMenuItem.Size = new System.Drawing.Size(146, 22);
|
|
||||||
this.flipToolStripMenuItem.Text = "Flip";
|
|
||||||
//
|
|
||||||
// curveToolStripMenuItem
|
|
||||||
//
|
|
||||||
this.curveToolStripMenuItem.Name = "curveToolStripMenuItem";
|
|
||||||
this.curveToolStripMenuItem.Size = new System.Drawing.Size(146, 22);
|
|
||||||
this.curveToolStripMenuItem.Text = "Curve...";
|
|
||||||
//
|
|
||||||
// WAuthorTools
|
|
||||||
//
|
|
||||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 14F);
|
|
||||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
|
||||||
this.ClientSize = new System.Drawing.Size(243, 130);
|
|
||||||
this.ControlBox = false;
|
|
||||||
this.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
|
||||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
|
||||||
this.MaximizeBox = false;
|
|
||||||
this.MinimizeBox = false;
|
|
||||||
this.Name = "WAuthorTools";
|
|
||||||
this.Text = "WAuthorTools";
|
|
||||||
this.linedefpopup.ResumeLayout(false);
|
|
||||||
this.ResumeLayout(false);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private System.Windows.Forms.ContextMenuStrip linedefpopup;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem propertiesToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem deleteToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem splitToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem flipToolStripMenuItem;
|
|
||||||
private System.Windows.Forms.ToolStripMenuItem curveToolStripMenuItem;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Drawing;
|
|
||||||
using System.Text;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
|
||||||
{
|
|
||||||
public partial class WAuthorTools : Form
|
|
||||||
{
|
|
||||||
// Tools
|
|
||||||
public ContextMenuStrip LinedefPopup { get { return linedefpopup; } }
|
|
||||||
|
|
||||||
// Constructor
|
|
||||||
public WAuthorTools()
|
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,123 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<root>
|
|
||||||
<!--
|
|
||||||
Microsoft ResX Schema
|
|
||||||
|
|
||||||
Version 2.0
|
|
||||||
|
|
||||||
The primary goals of this format is to allow a simple XML format
|
|
||||||
that is mostly human readable. The generation and parsing of the
|
|
||||||
various data types are done through the TypeConverter classes
|
|
||||||
associated with the data types.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
... ado.net/XML headers & schema ...
|
|
||||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
|
||||||
<resheader name="version">2.0</resheader>
|
|
||||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
|
||||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
|
||||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
|
||||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
|
||||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
|
||||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
|
||||||
</data>
|
|
||||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
|
||||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
|
||||||
<comment>This is a comment</comment>
|
|
||||||
</data>
|
|
||||||
|
|
||||||
There are any number of "resheader" rows that contain simple
|
|
||||||
name/value pairs.
|
|
||||||
|
|
||||||
Each data row contains a name, and value. The row also contains a
|
|
||||||
type or mimetype. Type corresponds to a .NET class that support
|
|
||||||
text/value conversion through the TypeConverter architecture.
|
|
||||||
Classes that don't support this are serialized and stored with the
|
|
||||||
mimetype set.
|
|
||||||
|
|
||||||
The mimetype is used for serialized objects, and tells the
|
|
||||||
ResXResourceReader how to depersist the object. This is currently not
|
|
||||||
extensible. For a given mimetype the value must be set accordingly:
|
|
||||||
|
|
||||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
|
||||||
that the ResXResourceWriter will generate, however the reader can
|
|
||||||
read any of the formats listed below.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.binary.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.soap.base64
|
|
||||||
value : The object must be serialized with
|
|
||||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
|
|
||||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
|
||||||
value : The object must be serialized into a byte array
|
|
||||||
: using a System.ComponentModel.TypeConverter
|
|
||||||
: and then encoded with base64 encoding.
|
|
||||||
-->
|
|
||||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:choice maxOccurs="unbounded">
|
|
||||||
<xsd:element name="metadata">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="assembly">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:attribute name="alias" type="xsd:string" />
|
|
||||||
<xsd:attribute name="name" type="xsd:string" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="data">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
|
||||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
|
||||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
|
||||||
<xsd:attribute ref="xml:space" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
<xsd:element name="resheader">
|
|
||||||
<xsd:complexType>
|
|
||||||
<xsd:sequence>
|
|
||||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
|
||||||
</xsd:sequence>
|
|
||||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:choice>
|
|
||||||
</xsd:complexType>
|
|
||||||
</xsd:element>
|
|
||||||
</xsd:schema>
|
|
||||||
<resheader name="resmimetype">
|
|
||||||
<value>text/microsoft-resx</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="version">
|
|
||||||
<value>2.0</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="reader">
|
|
||||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<resheader name="writer">
|
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
|
||||||
</resheader>
|
|
||||||
<metadata name="linedefpopup.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
|
||||||
<value>17, 17</value>
|
|
||||||
</metadata>
|
|
||||||
</root>
|
|
|
@ -58,13 +58,3 @@ wauthormode
|
||||||
allowmouse = true;
|
allowmouse = true;
|
||||||
allowscroll = true;
|
allowscroll = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
triangulatormode
|
|
||||||
{
|
|
||||||
title = "Edit: Triangulator Mode";
|
|
||||||
description = "Switches to Triangulator testing mode.";
|
|
||||||
allowkeys = true;
|
|
||||||
allowmouse = true;
|
|
||||||
allowscroll = true;
|
|
||||||
debugonly = true;
|
|
||||||
}
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 924 B |
|
@ -271,6 +271,19 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
||||||
// Start rendering
|
// Start rendering
|
||||||
if(renderer.Start(true, false))
|
if(renderer.Start(true, false))
|
||||||
{
|
{
|
||||||
|
// Uncomment this to see triangulation
|
||||||
|
/*
|
||||||
|
foreach(Sector s in General.Map.Map.Sectors)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < s.Triangles.Count; i += 3)
|
||||||
|
{
|
||||||
|
renderer.RenderLine(s.Triangles[i + 0], s.Triangles[i + 1], General.Colors.Selection);
|
||||||
|
renderer.RenderLine(s.Triangles[i + 1], s.Triangles[i + 2], General.Colors.Selection);
|
||||||
|
renderer.RenderLine(s.Triangles[i + 2], s.Triangles[i + 0], General.Colors.Selection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Render lines and vertices
|
// Render lines and vertices
|
||||||
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
renderer.RenderLinedefSet(General.Map.Map.Linedefs);
|
||||||
renderer.RenderVerticesSet(unselectedverts);
|
renderer.RenderVerticesSet(unselectedverts);
|
||||||
|
@ -296,6 +309,7 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
||||||
if(MoveGeometryRelative(mousemappos - dragstartmappos, snaptogrid, snaptonearest))
|
if(MoveGeometryRelative(mousemappos - dragstartmappos, snaptogrid, snaptonearest))
|
||||||
{
|
{
|
||||||
// Update cached values
|
// Update cached values
|
||||||
|
//General.Map.Map.Update(true, false);
|
||||||
General.Map.Map.Update();
|
General.Map.Map.Update();
|
||||||
|
|
||||||
// Redraw
|
// Redraw
|
225
Source/BuilderModes/VisualMode/BaseVisualMode.cs
Normal file
225
Source/BuilderModes/VisualMode/BaseVisualMode.cs
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
|
||||||
|
#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.Interface;
|
||||||
|
using CodeImp.DoomBuilder.IO;
|
||||||
|
using CodeImp.DoomBuilder.Map;
|
||||||
|
using CodeImp.DoomBuilder.Rendering;
|
||||||
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
|
using CodeImp.DoomBuilder.Editing;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
||||||
|
{
|
||||||
|
[EditMode(SwitchAction = "visualmode", // Action name used to switch to this mode
|
||||||
|
ButtonDesc = "Visual Mode", // Description on the button in toolbar/menu
|
||||||
|
ButtonImage = "VisualMode.png", // Image resource name for the button
|
||||||
|
ButtonOrder = 0)] // Position of the button (lower is more to the left)
|
||||||
|
|
||||||
|
public class BaseVisualMode : VisualMode
|
||||||
|
{
|
||||||
|
#region ================== Constants
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Variables
|
||||||
|
|
||||||
|
// All constructed visual sectors
|
||||||
|
private Dictionary<Sector, BaseVisualSector> allsectors;
|
||||||
|
|
||||||
|
// List of visible sectors
|
||||||
|
private Dictionary<Sector, BaseVisualSector> visiblesectors;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Properties
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Constructor / Disposer
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public BaseVisualMode()
|
||||||
|
{
|
||||||
|
// Initialize
|
||||||
|
allsectors = new Dictionary<Sector, BaseVisualSector>(General.Map.Map.Sectors.Count);
|
||||||
|
visiblesectors = new Dictionary<Sector, BaseVisualSector>();
|
||||||
|
|
||||||
|
// We have no destructor
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Diposer
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
// Not already disposed?
|
||||||
|
if(!isdisposed)
|
||||||
|
{
|
||||||
|
// Clean up
|
||||||
|
foreach(KeyValuePair<Sector, BaseVisualSector> s in allsectors) s.Value.Dispose();
|
||||||
|
visiblesectors = null;
|
||||||
|
allsectors = null;
|
||||||
|
|
||||||
|
// Done
|
||||||
|
base.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Private Tools
|
||||||
|
|
||||||
|
// This finds the nearest sector to the camera
|
||||||
|
private Sector FindStartSector(Vector2D campos)
|
||||||
|
{
|
||||||
|
float side;
|
||||||
|
Linedef l;
|
||||||
|
|
||||||
|
// Get nearest linedef
|
||||||
|
l = General.Map.Map.NearestLinedef(campos);
|
||||||
|
if(l != null)
|
||||||
|
{
|
||||||
|
// Check if we are on front or back side
|
||||||
|
side = l.SideOfLine(campos);
|
||||||
|
if(side > 0)
|
||||||
|
{
|
||||||
|
// Is there a sidedef here?
|
||||||
|
if(l.Back != null)
|
||||||
|
return l.Back.Sector;
|
||||||
|
else if(l.Front != null)
|
||||||
|
return l.Front.Sector;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Is there a sidedef here?
|
||||||
|
if(l.Front != null)
|
||||||
|
return l.Front.Sector;
|
||||||
|
else if(l.Back != null)
|
||||||
|
return l.Back.Sector;
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This recursively finds and adds visible sectors
|
||||||
|
private void ProcessVisibleSectors(Sector start, Vector2D campos)
|
||||||
|
{
|
||||||
|
BaseVisualSector vs;
|
||||||
|
Sector os;
|
||||||
|
|
||||||
|
// Find the basesector and make it if needed
|
||||||
|
if(allsectors.ContainsKey(start))
|
||||||
|
{
|
||||||
|
// Take existing visualsector
|
||||||
|
vs = allsectors[start];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Make new visualsector
|
||||||
|
vs = new BaseVisualSector(start);
|
||||||
|
allsectors.Add(start, vs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add sector to visibility list
|
||||||
|
visiblesectors.Add(start, vs);
|
||||||
|
|
||||||
|
// Go for all sidedefs in the sector
|
||||||
|
foreach(Sidedef sd in start.Sidedefs)
|
||||||
|
{
|
||||||
|
// Doublesided and not referring to same sector?
|
||||||
|
if((sd.Other != null) && (sd.Other.Sector != sd.Sector))
|
||||||
|
{
|
||||||
|
// Get the other sector
|
||||||
|
os = sd.Other.Sector;
|
||||||
|
|
||||||
|
// Sector not yet added?
|
||||||
|
if(!visiblesectors.ContainsKey(os))
|
||||||
|
{
|
||||||
|
// TODO: Visiblity checking!
|
||||||
|
{
|
||||||
|
// Process this sector as well
|
||||||
|
ProcessVisibleSectors(os, campos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Methods
|
||||||
|
|
||||||
|
// This draws a frame
|
||||||
|
public override void RedrawDisplay()
|
||||||
|
{
|
||||||
|
// Start drawing
|
||||||
|
if(renderer.Start())
|
||||||
|
{
|
||||||
|
// Begin with geometry
|
||||||
|
renderer.StartGeometry();
|
||||||
|
|
||||||
|
// Render all visible sectors
|
||||||
|
foreach(KeyValuePair<Sector, BaseVisualSector> vs in visiblesectors)
|
||||||
|
renderer.RenderGeometry(vs.Value);
|
||||||
|
|
||||||
|
// Done rendering geometry
|
||||||
|
renderer.FinishGeometry();
|
||||||
|
|
||||||
|
// Present!
|
||||||
|
renderer.Finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call base
|
||||||
|
base.RedrawDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This processes a frame
|
||||||
|
public override void Process()
|
||||||
|
{
|
||||||
|
Vector2D campos;
|
||||||
|
|
||||||
|
// Process base class first
|
||||||
|
base.Process();
|
||||||
|
|
||||||
|
// Get the 2D camera position
|
||||||
|
campos = new Vector2D(base.CameraPosition.x, base.CameraPosition.y);
|
||||||
|
|
||||||
|
// Make new visibility list
|
||||||
|
visiblesectors = new Dictionary<Sector, BaseVisualSector>(General.Map.Map.Sectors.Count);
|
||||||
|
|
||||||
|
// Process all visible sectors starting with the nearest
|
||||||
|
ProcessVisibleSectors(FindStartSector(campos), campos);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,12 +35,7 @@ using CodeImp.DoomBuilder.Editing;
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
||||||
{
|
{
|
||||||
[EditMode(SwitchAction = "visualmode", // Action name used to switch to this mode
|
internal class BaseVisualSector : VisualSector
|
||||||
ButtonDesc = "Visual Mode", // Description on the button in toolbar/menu
|
|
||||||
ButtonImage = "VisualMode.png", // Image resource name for the button
|
|
||||||
ButtonOrder = 0)] // Position of the button (lower is more to the left)
|
|
||||||
|
|
||||||
public class BaseVisualMode : VisualMode
|
|
||||||
{
|
{
|
||||||
#region ================== Constants
|
#region ================== Constants
|
||||||
|
|
||||||
|
@ -57,23 +52,24 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
||||||
#region ================== Constructor / Disposer
|
#region ================== Constructor / Disposer
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public BaseVisualMode()
|
public BaseVisualSector(Sector s) : base(s)
|
||||||
{
|
{
|
||||||
// Initialize
|
// Initialize
|
||||||
|
Rebuild();
|
||||||
|
|
||||||
// We have no destructor
|
// We have no destructor
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diposer
|
// Disposer
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
// Not already disposed?
|
// Not already disposed?
|
||||||
if(!isdisposed)
|
if(!IsDisposed)
|
||||||
{
|
{
|
||||||
// Clean up
|
// Clean up
|
||||||
|
|
||||||
// Done
|
// Dispose base
|
||||||
base.Dispose();
|
base.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,30 +78,30 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
||||||
|
|
||||||
#region ================== Methods
|
#region ================== Methods
|
||||||
|
|
||||||
// This draws a frame
|
// This (re)builds the visual sector, calculating all geometry from scratch
|
||||||
public override void RedrawDisplay()
|
public void Rebuild()
|
||||||
{
|
{
|
||||||
VisualSector vs = new VisualSector(General.GetByIndex<Sector>(General.Map.Map.Sectors, 0));
|
// Forget old geometry
|
||||||
VisualObject vo = new VisualObject();
|
base.ClearGeometry();
|
||||||
vo.Texture = General.Map.Data.GetTextureImage("TEKGREN1");
|
|
||||||
vo.Visible = true;
|
|
||||||
vs.AddGeometry(vo);
|
|
||||||
|
|
||||||
// Start drawing
|
// Make the floor and ceiling
|
||||||
if(renderer.Start())
|
base.AddGeometry(new VisualFloor(base.Sector));
|
||||||
|
base.AddGeometry(new VisualCeiling(base.Sector));
|
||||||
|
|
||||||
|
// Go for all sidedefs
|
||||||
|
foreach(Sidedef sd in base.Sector.Sidedefs)
|
||||||
{
|
{
|
||||||
// Begin with geometry
|
// Make middle wall
|
||||||
renderer.StartGeometry();
|
base.AddGeometry(new VisualMiddle(sd));
|
||||||
|
|
||||||
renderer.RenderGeometry(vs);
|
// Check if upper and lower parts are possible at all
|
||||||
|
if(sd.Other != null)
|
||||||
renderer.FinishGeometry();
|
{
|
||||||
|
// Make upper and lower walls
|
||||||
renderer.Finish();
|
base.AddGeometry(new VisualLower(sd));
|
||||||
|
base.AddGeometry(new VisualUpper(sd));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call base
|
|
||||||
base.RedrawDisplay();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
112
Source/BuilderModes/VisualMode/VisualCeiling.cs
Normal file
112
Source/BuilderModes/VisualMode/VisualCeiling.cs
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
|
||||||
|
#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 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.BuilderModes.Editing
|
||||||
|
{
|
||||||
|
internal class VisualCeiling : VisualGeometry
|
||||||
|
{
|
||||||
|
#region ================== Constants
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Variables
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Properties
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Constructor / Disposer
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public VisualCeiling(Sector s)
|
||||||
|
{
|
||||||
|
WorldVertex[] verts;
|
||||||
|
WorldVertex v;
|
||||||
|
PixelColor pc;
|
||||||
|
|
||||||
|
// Load floor texture
|
||||||
|
base.Texture = General.Map.Data.GetFlatImage(s.LongCeilTexture);
|
||||||
|
base.Texture.LoadImage();
|
||||||
|
|
||||||
|
// Make vertices
|
||||||
|
verts = new WorldVertex[s.Triangles.Count];
|
||||||
|
for(int i = 0; i < s.Triangles.Count; i++)
|
||||||
|
{
|
||||||
|
// Use sector brightness for color shading
|
||||||
|
//pc = new PixelColor(255, unchecked((byte)s.Brightness), unchecked((byte)s.Brightness), unchecked((byte)s.Brightness));
|
||||||
|
//verts[i].c = pc.ToInt();
|
||||||
|
verts[i].c = -1;
|
||||||
|
|
||||||
|
// Grid aligned texture coordinates
|
||||||
|
verts[i].u = s.Triangles[i].x / base.Texture.ScaledWidth;
|
||||||
|
verts[i].v = s.Triangles[i].y / base.Texture.ScaledHeight;
|
||||||
|
|
||||||
|
// Vertex coordinates
|
||||||
|
verts[i].x = s.Triangles[i].x;
|
||||||
|
verts[i].y = s.Triangles[i].y;
|
||||||
|
verts[i].z = (float)s.CeilHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The sector triangulation created clockwise triangles that
|
||||||
|
// are right up for the floor. For the ceiling we must flip
|
||||||
|
// the triangles upside down.
|
||||||
|
// Swap some vertices to flip all triangles
|
||||||
|
for(int i = 0; i < verts.Length; i += 3)
|
||||||
|
{
|
||||||
|
// Swap
|
||||||
|
v = verts[i];
|
||||||
|
verts[i] = verts[i + 1];
|
||||||
|
verts[i + 1] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply vertices
|
||||||
|
base.SetVertices(verts);
|
||||||
|
|
||||||
|
// We have no destructor
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Methods
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,7 +38,7 @@ using CodeImp.DoomBuilder.Rendering;
|
||||||
|
|
||||||
namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
||||||
{
|
{
|
||||||
internal class VisualObject : VisualGeometry
|
internal class VisualFloor : VisualGeometry
|
||||||
{
|
{
|
||||||
#region ================== Constants
|
#region ================== Constants
|
||||||
|
|
||||||
|
@ -46,87 +46,50 @@ namespace CodeImp.DoomBuilder.BuilderModes.Editing
|
||||||
|
|
||||||
#region ================== Variables
|
#region ================== Variables
|
||||||
|
|
||||||
// Disposing
|
|
||||||
private bool isdisposed = false;
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Properties
|
#region ================== Properties
|
||||||
|
|
||||||
// Disposing
|
|
||||||
public bool IsDisposed { get { return isdisposed; } }
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Constructor / Disposer
|
#region ================== Constructor / Disposer
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public VisualObject()
|
public VisualFloor(Sector s)
|
||||||
{
|
{
|
||||||
// Initialize
|
WorldVertex[] verts;
|
||||||
WorldVertex[] v = new WorldVertex[6];
|
PixelColor pc;
|
||||||
|
|
||||||
v[0].c = -1;
|
// Load floor texture
|
||||||
v[0].x = 0.0f;
|
base.Texture = General.Map.Data.GetFlatImage(s.LongFloorTexture);
|
||||||
v[0].y = 0.0f;
|
base.Texture.LoadImage();
|
||||||
v[0].z = 0.0f;
|
|
||||||
v[0].u = 0.0f;
|
|
||||||
v[0].v = 1.0f;
|
|
||||||
|
|
||||||
v[1].c = -1;
|
// Make vertices
|
||||||
v[1].x = 0.0f;
|
verts = new WorldVertex[s.Triangles.Count];
|
||||||
v[1].y = 0.0f;
|
for(int i = 0; i < s.Triangles.Count; i++)
|
||||||
v[1].z = 100.0f;
|
{
|
||||||
v[1].u = 0.0f;
|
// Use sector brightness for color shading
|
||||||
v[1].v = 0.0f;
|
//pc = new PixelColor(255, unchecked((byte)s.Brightness), unchecked((byte)s.Brightness), unchecked((byte)s.Brightness));
|
||||||
|
//verts[i].c = pc.ToInt();
|
||||||
|
verts[i].c = -1;
|
||||||
|
|
||||||
v[2].c = -1;
|
// Grid aligned texture coordinates
|
||||||
v[2].x = 100.0f;
|
verts[i].u = s.Triangles[i].x / base.Texture.ScaledWidth;
|
||||||
v[2].y = 0.0f;
|
verts[i].v = s.Triangles[i].y / base.Texture.ScaledHeight;
|
||||||
v[2].z = 100.0f;
|
|
||||||
v[2].u = 1.0f;
|
|
||||||
v[2].v = 0.0f;
|
|
||||||
|
|
||||||
v[3].c = -1;
|
// Vertex coordinates
|
||||||
v[3].x = 0.0f;
|
verts[i].x = s.Triangles[i].x;
|
||||||
v[3].y = 0.0f;
|
verts[i].y = s.Triangles[i].y;
|
||||||
v[3].z = 0.0f;
|
verts[i].z = (float)s.FloorHeight;
|
||||||
v[3].u = 0.0f;
|
}
|
||||||
v[3].v = 1.0f;
|
|
||||||
|
|
||||||
v[4].c = -1;
|
// Apply vertices
|
||||||
v[4].x = 100.0f;
|
base.SetVertices(verts);
|
||||||
v[4].y = 0.0f;
|
|
||||||
v[4].z = 100.0f;
|
|
||||||
v[4].u = 1.0f;
|
|
||||||
v[4].v = 0.0f;
|
|
||||||
|
|
||||||
v[5].c = -1;
|
|
||||||
v[5].x = 100.0f;
|
|
||||||
v[5].y = 0.0f;
|
|
||||||
v[5].z = 0.0f;
|
|
||||||
v[5].u = 1.0f;
|
|
||||||
v[5].v = 1.0f;
|
|
||||||
|
|
||||||
this.SetVertices(v);
|
|
||||||
|
|
||||||
// We have no destructor
|
// We have no destructor
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diposer
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
// Not already disposed?
|
|
||||||
if(!isdisposed)
|
|
||||||
{
|
|
||||||
// Clean up
|
|
||||||
|
|
||||||
// Done
|
|
||||||
isdisposed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Methods
|
#region ================== Methods
|
126
Source/BuilderModes/VisualMode/VisualLower.cs
Normal file
126
Source/BuilderModes/VisualMode/VisualLower.cs
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
|
||||||
|
#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 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.BuilderModes.Editing
|
||||||
|
{
|
||||||
|
internal class VisualLower : VisualGeometry
|
||||||
|
{
|
||||||
|
#region ================== Constants
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Variables
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Properties
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Constructor / Disposer
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public VisualLower(Sidedef s)
|
||||||
|
{
|
||||||
|
WorldVertex[] verts;
|
||||||
|
PixelColor pc;
|
||||||
|
float geotop;
|
||||||
|
float geobottom;
|
||||||
|
float geoheight;
|
||||||
|
Vector2D v1, v2;
|
||||||
|
|
||||||
|
// Calculate size of this wall part
|
||||||
|
geotop = (float)s.Other.Sector.FloorHeight;
|
||||||
|
geobottom = (float)s.Sector.FloorHeight;
|
||||||
|
geoheight = geotop - geobottom;
|
||||||
|
if(geoheight > 0.001f)
|
||||||
|
{
|
||||||
|
// Texture given?
|
||||||
|
if((s.LowTexture.Length > 0) && (s.LowTexture[0] != '-'))
|
||||||
|
{
|
||||||
|
// Load texture
|
||||||
|
base.Texture = General.Map.Data.GetTextureImage(s.LongLowTexture);
|
||||||
|
base.Texture.LoadImage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use missing texture
|
||||||
|
base.Texture = General.Map.Data.MissingTexture3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get coordinates
|
||||||
|
if(s.IsFront)
|
||||||
|
{
|
||||||
|
v1 = s.Line.Start.Position;
|
||||||
|
v2 = s.Line.End.Position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v1 = s.Line.End.Position;
|
||||||
|
v2 = s.Line.Start.Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make vertices
|
||||||
|
verts = new WorldVertex[6];
|
||||||
|
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, -1, 0.0f, 1.0f);
|
||||||
|
verts[1] = new WorldVertex(v1.x, v1.y, geotop, -1, 0.0f, 0.0f);
|
||||||
|
verts[2] = new WorldVertex(v2.x, v2.y, geotop, -1, 1.0f, 0.0f);
|
||||||
|
verts[3] = verts[0];
|
||||||
|
verts[4] = verts[2];
|
||||||
|
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, -1, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No geometry for invisible wall
|
||||||
|
verts = new WorldVertex[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply vertices
|
||||||
|
base.SetVertices(verts);
|
||||||
|
|
||||||
|
// We have no destructor
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Methods
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
141
Source/BuilderModes/VisualMode/VisualMiddle.cs
Normal file
141
Source/BuilderModes/VisualMode/VisualMiddle.cs
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
|
||||||
|
#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 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.BuilderModes.Editing
|
||||||
|
{
|
||||||
|
internal class VisualMiddle : VisualGeometry
|
||||||
|
{
|
||||||
|
#region ================== Constants
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Variables
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Properties
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Constructor / Disposer
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public VisualMiddle(Sidedef s)
|
||||||
|
{
|
||||||
|
WorldVertex[] verts;
|
||||||
|
PixelColor pc;
|
||||||
|
float geotop;
|
||||||
|
float geobottom;
|
||||||
|
float geoheight;
|
||||||
|
bool texturegiven;
|
||||||
|
bool texturerequired;
|
||||||
|
Vector2D v1, v2;
|
||||||
|
|
||||||
|
// Calculate size of this wall part
|
||||||
|
geotop = (float)s.Sector.CeilHeight;
|
||||||
|
geobottom = (float)s.Sector.FloorHeight;
|
||||||
|
geoheight = geotop - geobottom;
|
||||||
|
if(geoheight > 0.001f)
|
||||||
|
{
|
||||||
|
// Check texture status
|
||||||
|
texturegiven = ((s.MiddleTexture.Length > 0) && (s.MiddleTexture[0] != '-'));
|
||||||
|
texturerequired = s.MiddleRequired();
|
||||||
|
|
||||||
|
// Only create wall when middle texture is set or the wall requires a texture
|
||||||
|
if(texturegiven || texturerequired)
|
||||||
|
{
|
||||||
|
// Texture given?
|
||||||
|
if(texturegiven)
|
||||||
|
{
|
||||||
|
// Load texture
|
||||||
|
base.Texture = General.Map.Data.GetTextureImage(s.LongMiddleTexture);
|
||||||
|
base.Texture.LoadImage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use missing texture
|
||||||
|
base.Texture = General.Map.Data.MissingTexture3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get coordinates
|
||||||
|
if(s.IsFront)
|
||||||
|
{
|
||||||
|
v1 = s.Line.Start.Position;
|
||||||
|
v2 = s.Line.End.Position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v1 = s.Line.End.Position;
|
||||||
|
v2 = s.Line.Start.Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make vertices
|
||||||
|
verts = new WorldVertex[6];
|
||||||
|
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, -1, 0.0f, 1.0f);
|
||||||
|
verts[1] = new WorldVertex(v1.x, v1.y, geotop, -1, 0.0f, 0.0f);
|
||||||
|
verts[2] = new WorldVertex(v2.x, v2.y, geotop, -1, 1.0f, 0.0f);
|
||||||
|
verts[3] = verts[0];
|
||||||
|
verts[4] = verts[2];
|
||||||
|
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, -1, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No geometry for invisible wall
|
||||||
|
verts = new WorldVertex[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No geometry for invisible wall
|
||||||
|
verts = new WorldVertex[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply vertices
|
||||||
|
base.SetVertices(verts);
|
||||||
|
|
||||||
|
// We have no destructor
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Methods
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
126
Source/BuilderModes/VisualMode/VisualUpper.cs
Normal file
126
Source/BuilderModes/VisualMode/VisualUpper.cs
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
|
||||||
|
#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 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.BuilderModes.Editing
|
||||||
|
{
|
||||||
|
internal class VisualUpper : VisualGeometry
|
||||||
|
{
|
||||||
|
#region ================== Constants
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Variables
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Properties
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Constructor / Disposer
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public VisualUpper(Sidedef s)
|
||||||
|
{
|
||||||
|
WorldVertex[] verts;
|
||||||
|
PixelColor pc;
|
||||||
|
float geotop;
|
||||||
|
float geobottom;
|
||||||
|
float geoheight;
|
||||||
|
Vector2D v1, v2;
|
||||||
|
|
||||||
|
// Calculate size of this wall part
|
||||||
|
geotop = (float)s.Sector.CeilHeight;
|
||||||
|
geobottom = (float)s.Other.Sector.CeilHeight;
|
||||||
|
geoheight = geotop - geobottom;
|
||||||
|
if(geoheight > 0.001f)
|
||||||
|
{
|
||||||
|
// Texture given?
|
||||||
|
if((s.HighTexture.Length > 0) && (s.HighTexture[0] != '-'))
|
||||||
|
{
|
||||||
|
// Load texture
|
||||||
|
base.Texture = General.Map.Data.GetTextureImage(s.LongHighTexture);
|
||||||
|
base.Texture.LoadImage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use missing texture
|
||||||
|
base.Texture = General.Map.Data.MissingTexture3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get coordinates
|
||||||
|
if(s.IsFront)
|
||||||
|
{
|
||||||
|
v1 = s.Line.Start.Position;
|
||||||
|
v2 = s.Line.End.Position;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v1 = s.Line.End.Position;
|
||||||
|
v2 = s.Line.Start.Position;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make vertices
|
||||||
|
verts = new WorldVertex[6];
|
||||||
|
verts[0] = new WorldVertex(v1.x, v1.y, geobottom, -1, 0.0f, 1.0f);
|
||||||
|
verts[1] = new WorldVertex(v1.x, v1.y, geotop, -1, 0.0f, 0.0f);
|
||||||
|
verts[2] = new WorldVertex(v2.x, v2.y, geotop, -1, 1.0f, 0.0f);
|
||||||
|
verts[3] = verts[0];
|
||||||
|
verts[4] = verts[2];
|
||||||
|
verts[5] = new WorldVertex(v2.x, v2.y, geobottom, -1, 1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No geometry for invisible wall
|
||||||
|
verts = new WorldVertex[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply vertices
|
||||||
|
base.SetVertices(verts);
|
||||||
|
|
||||||
|
// We have no destructor
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Methods
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,6 +33,7 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
|
|
||||||
// Description
|
// Description
|
||||||
private string name;
|
private string name;
|
||||||
|
private string shortname;
|
||||||
private string title;
|
private string title;
|
||||||
private string description;
|
private string description;
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
#region ================== Properties
|
#region ================== Properties
|
||||||
|
|
||||||
public string Name { get { return name; } }
|
public string Name { get { return name; } }
|
||||||
|
public string ShortName { get { return shortname; } }
|
||||||
public string Title { get { return title; } }
|
public string Title { get { return title; } }
|
||||||
public string Description { get { return description; } }
|
public string Description { get { return description; } }
|
||||||
public int ShortcutKey { get { return key; } }
|
public int ShortcutKey { get { return key; } }
|
||||||
|
@ -64,11 +66,12 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
#region ================== Constructor / Disposer
|
#region ================== Constructor / Disposer
|
||||||
|
|
||||||
// Constructor
|
// Constructor
|
||||||
public Action(string name, string title, string description, int key,
|
public Action(string name, string shortname, string title, string description, int key,
|
||||||
bool allowkeys, bool allowmouse, bool allowscroll)
|
bool allowkeys, bool allowmouse, bool allowscroll)
|
||||||
{
|
{
|
||||||
// Initialize
|
// Initialize
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.shortname = shortname;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
this.delegates = new List<ActionDelegate>();
|
this.delegates = new List<ActionDelegate>();
|
||||||
|
@ -166,7 +169,8 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
// No method bound?
|
// No method bound?
|
||||||
if(delegates.Count == 0)
|
if(delegates.Count == 0)
|
||||||
{
|
{
|
||||||
General.WriteLogLine("Called action '" + name + "' has no methods bound");
|
// Ignore this since keys can also be handled through KeyDown and KeyUp in editing modes
|
||||||
|
//General.WriteLogLine("Called action '" + name + "' has no methods bound");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
Stream actionsdata;
|
Stream actionsdata;
|
||||||
StreamReader actionsreader;
|
StreamReader actionsreader;
|
||||||
Configuration cfg;
|
Configuration cfg;
|
||||||
string name, title, desc;
|
string name, title, desc, shortname;
|
||||||
bool amouse, akeys, ascroll, debugonly;
|
bool amouse, akeys, ascroll, debugonly;
|
||||||
string[] resnames;
|
string[] resnames;
|
||||||
AssemblyName asmname = asm.GetName();
|
AssemblyName asmname = asm.GetName();
|
||||||
|
@ -123,7 +123,8 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
foreach(DictionaryEntry a in cfg.Root)
|
foreach(DictionaryEntry a in cfg.Root)
|
||||||
{
|
{
|
||||||
// Get action properties
|
// Get action properties
|
||||||
name = asmname.Name.ToLowerInvariant() + "_" + a.Key.ToString();
|
shortname = a.Key.ToString();
|
||||||
|
name = asmname.Name.ToLowerInvariant() + "_" + shortname;
|
||||||
title = cfg.ReadSetting(a.Key + ".title", "[" + name + "]");
|
title = cfg.ReadSetting(a.Key + ".title", "[" + name + "]");
|
||||||
desc = cfg.ReadSetting(a.Key + ".description", "");
|
desc = cfg.ReadSetting(a.Key + ".description", "");
|
||||||
akeys = cfg.ReadSetting(a.Key + ".allowkeys", false);
|
akeys = cfg.ReadSetting(a.Key + ".allowkeys", false);
|
||||||
|
@ -135,7 +136,7 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
if(General.DebugBuild || !debugonly)
|
if(General.DebugBuild || !debugonly)
|
||||||
{
|
{
|
||||||
// Create an action
|
// Create an action
|
||||||
CreateAction(name, title, desc, akeys, amouse, ascroll);
|
CreateAction(name, shortname, title, desc, akeys, amouse, ascroll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,7 +144,7 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
}
|
}
|
||||||
|
|
||||||
// This manually creates an action
|
// This manually creates an action
|
||||||
private void CreateAction(string name, string title, string desc, bool allowkeys, bool allowmouse, bool allowscroll)
|
private void CreateAction(string name, string shortname, string title, string desc, bool allowkeys, bool allowmouse, bool allowscroll)
|
||||||
{
|
{
|
||||||
// Action does not exist yet?
|
// Action does not exist yet?
|
||||||
if(!actions.ContainsKey(name))
|
if(!actions.ContainsKey(name))
|
||||||
|
@ -152,7 +153,7 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
int key = General.Settings.ReadSetting("shortcuts." + name, 0);
|
int key = General.Settings.ReadSetting("shortcuts." + name, 0);
|
||||||
|
|
||||||
// Create an action
|
// Create an action
|
||||||
actions.Add(name, new Action(name, title, desc, key, allowkeys, allowmouse, allowscroll));
|
actions.Add(name, new Action(name, shortname, title, desc, key, allowkeys, allowmouse, allowscroll));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -198,7 +199,7 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
a.Value.SetShortcutKey(0);
|
a.Value.SetShortcutKey(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will call the associated action for a keypress
|
// This will call the associated actions for a keypress
|
||||||
public void InvokeByKey(int key)
|
public void InvokeByKey(int key)
|
||||||
{
|
{
|
||||||
// Go for all actions
|
// Go for all actions
|
||||||
|
@ -213,6 +214,26 @@ namespace CodeImp.DoomBuilder.Controls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This returns all action names for a given key
|
||||||
|
public string[] GetActionsByKey(int key)
|
||||||
|
{
|
||||||
|
List<string> actionnames = new List<string>();
|
||||||
|
|
||||||
|
// Go for all actions
|
||||||
|
foreach(KeyValuePair<string, Action> a in actions)
|
||||||
|
{
|
||||||
|
// This action is associated with this key?
|
||||||
|
if(a.Value.ShortcutKey == key)
|
||||||
|
{
|
||||||
|
// List short name
|
||||||
|
actionnames.Add(a.Value.ShortName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return result;
|
||||||
|
return actionnames.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,9 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
// Background loading
|
// Background loading
|
||||||
private Thread backgroundloader;
|
private Thread backgroundloader;
|
||||||
|
|
||||||
|
// Special images
|
||||||
|
private ImageData missingtexture3d;
|
||||||
|
|
||||||
// Disposing
|
// Disposing
|
||||||
private bool isdisposed = false;
|
private bool isdisposed = false;
|
||||||
|
|
||||||
|
@ -76,6 +79,7 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
public List<string> FlatNames { get { return flatnames; } }
|
public List<string> FlatNames { get { return flatnames; } }
|
||||||
public bool IsDisposed { get { return isdisposed; } }
|
public bool IsDisposed { get { return isdisposed; } }
|
||||||
public bool IsLoading { get { return (backgroundloader != null) && backgroundloader.IsAlive; } }
|
public bool IsLoading { get { return (backgroundloader != null) && backgroundloader.IsAlive; } }
|
||||||
|
public ImageData MissingTexture3D { get { return missingtexture3d; } }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -86,6 +90,10 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
{
|
{
|
||||||
// We have no destructor
|
// We have no destructor
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
|
|
||||||
|
// Load special images
|
||||||
|
missingtexture3d = new ResourceImage("MissingTexture3D.png");
|
||||||
|
missingtexture3d.LoadImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disposer
|
// Disposer
|
||||||
|
@ -96,6 +104,8 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
{
|
{
|
||||||
// Clean up
|
// Clean up
|
||||||
Unload();
|
Unload();
|
||||||
|
missingtexture3d.Dispose();
|
||||||
|
missingtexture3d = null;
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
isdisposed = true;
|
isdisposed = true;
|
||||||
|
|
|
@ -87,6 +87,8 @@ namespace CodeImp.DoomBuilder.Data
|
||||||
// Get width and height from image
|
// Get width and height from image
|
||||||
width = bitmap.Size.Width;
|
width = bitmap.Size.Width;
|
||||||
height = bitmap.Size.Height;
|
height = bitmap.Size.Height;
|
||||||
|
scaledwidth = (float)width * General.Map.Config.DefaultFlatScale;
|
||||||
|
scaledheight = (float)height * General.Map.Config.DefaultFlatScale;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -203,6 +203,8 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
public void PerformUndo()
|
public void PerformUndo()
|
||||||
{
|
{
|
||||||
UndoSnapshot u, r;
|
UndoSnapshot u, r;
|
||||||
|
Cursor oldcursor = Cursor.Current;
|
||||||
|
Cursor.Current = Cursors.WaitCursor;
|
||||||
|
|
||||||
// Anything to undo?
|
// Anything to undo?
|
||||||
if(undos.Count > 0)
|
if(undos.Count > 0)
|
||||||
|
@ -228,6 +230,8 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
General.MainWindow.RedrawDisplay();
|
General.MainWindow.RedrawDisplay();
|
||||||
General.MainWindow.UpdateInterface();
|
General.MainWindow.UpdateInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cursor.Current = oldcursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This performs a redo
|
// This performs a redo
|
||||||
|
@ -235,6 +239,8 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
public void PerformRedo()
|
public void PerformRedo()
|
||||||
{
|
{
|
||||||
UndoSnapshot u, r;
|
UndoSnapshot u, r;
|
||||||
|
Cursor oldcursor = Cursor.Current;
|
||||||
|
Cursor.Current = Cursors.WaitCursor;
|
||||||
|
|
||||||
// Anything to redo?
|
// Anything to redo?
|
||||||
if(redos.Count > 0)
|
if(redos.Count > 0)
|
||||||
|
@ -260,6 +266,8 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
General.MainWindow.RedrawDisplay();
|
General.MainWindow.RedrawDisplay();
|
||||||
General.MainWindow.UpdateInterface();
|
General.MainWindow.UpdateInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cursor.Current = oldcursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -45,8 +45,9 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
#region ================== Constants
|
#region ================== Constants
|
||||||
|
|
||||||
private const float ANGLE_FROM_MOUSE = 0.0001f;
|
private const float ANGLE_FROM_MOUSE = 0.0001f;
|
||||||
private const float MAX_ANGLEZ_UP = 80f / Angle2D.PIDEG;
|
private const float MAX_ANGLEZ_LOW = 100f / Angle2D.PIDEG;
|
||||||
private const float MAX_ANGLEZ_DOWN = (360f - 80f) / Angle2D.PIDEG;
|
private const float MAX_ANGLEZ_HIGH = (360f - 100f) / Angle2D.PIDEG;
|
||||||
|
private const float CAMERA_SPEED = 6f;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -64,6 +65,12 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
private Vector3D camtarget;
|
private Vector3D camtarget;
|
||||||
private float camanglexy, camanglez;
|
private float camanglexy, camanglez;
|
||||||
|
|
||||||
|
// Input
|
||||||
|
private bool keyforward;
|
||||||
|
private bool keybackward;
|
||||||
|
private bool keyleft;
|
||||||
|
private bool keyright;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Properties
|
#region ================== Properties
|
||||||
|
@ -83,6 +90,8 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
// Initialize
|
// Initialize
|
||||||
this.renderer = General.Map.Renderer3D;
|
this.renderer = General.Map.Renderer3D;
|
||||||
this.renderer3d = (Renderer3D)General.Map.Renderer3D;
|
this.renderer3d = (Renderer3D)General.Map.Renderer3D;
|
||||||
|
this.campos = new Vector3D(0.0f, 0.0f, 96.0f);
|
||||||
|
this.camanglez = Angle2D.PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diposer
|
// Diposer
|
||||||
|
@ -100,7 +109,7 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Methods
|
#region ================== Start / Stop
|
||||||
|
|
||||||
// Mode is engaged
|
// Mode is engaged
|
||||||
public override void Engage()
|
public override void Engage()
|
||||||
|
@ -116,9 +125,9 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
{
|
{
|
||||||
// Position camera here
|
// Position camera here
|
||||||
modething.DetermineSector();
|
modething.DetermineSector();
|
||||||
campos = modething.Position + new Vector3D(0, 0, 20);
|
campos = modething.Position + new Vector3D(0.0f, 0.0f, 96.0f);
|
||||||
camanglexy = modething.Angle;
|
camanglexy = modething.Angle + Angle2D.PI;
|
||||||
camanglez = 0f;
|
camanglez = Angle2D.PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start special input mode
|
// Start special input mode
|
||||||
|
@ -136,7 +145,7 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
{
|
{
|
||||||
// Position the thing to match camera
|
// Position the thing to match camera
|
||||||
modething.Move((int)campos.x, (int)campos.y, 0);
|
modething.Move((int)campos.x, (int)campos.y, 0);
|
||||||
modething.Rotate(camanglexy);
|
modething.Rotate(camanglexy - Angle2D.PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop special input mode
|
// Stop special input mode
|
||||||
|
@ -144,32 +153,98 @@ namespace CodeImp.DoomBuilder.Editing
|
||||||
General.Interface.StopExclusiveMouseInput();
|
General.Interface.StopExclusiveMouseInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Input
|
||||||
|
|
||||||
// Mouse input
|
// Mouse input
|
||||||
public override void MouseInput(Vector2D delta)
|
public override void MouseInput(Vector2D delta)
|
||||||
{
|
{
|
||||||
base.MouseInput(delta);
|
base.MouseInput(delta);
|
||||||
|
|
||||||
// Change camera angles with the mouse changes
|
// Change camera angles with the mouse changes
|
||||||
camanglexy += delta.x * ANGLE_FROM_MOUSE;
|
camanglexy -= delta.x * ANGLE_FROM_MOUSE;
|
||||||
camanglez -= delta.y * ANGLE_FROM_MOUSE;
|
camanglez += delta.y * ANGLE_FROM_MOUSE;
|
||||||
|
|
||||||
|
// Normalize angles
|
||||||
|
camanglexy = Angle2D.Normalized(camanglexy);
|
||||||
|
camanglez = Angle2D.Normalized(camanglez);
|
||||||
|
|
||||||
// Limit vertical angle
|
// Limit vertical angle
|
||||||
if(camanglez < MAX_ANGLEZ_UP) camanglez = MAX_ANGLEZ_UP;
|
if(camanglez < MAX_ANGLEZ_LOW) camanglez = MAX_ANGLEZ_LOW;
|
||||||
if(camanglez > MAX_ANGLEZ_DOWN) camanglez = MAX_ANGLEZ_DOWN;
|
if(camanglez > MAX_ANGLEZ_HIGH) camanglez = MAX_ANGLEZ_HIGH;
|
||||||
|
|
||||||
// Normalize horizontal angle
|
|
||||||
camanglexy = Angle2D.Normalized(camanglexy);
|
|
||||||
|
|
||||||
General.MainWindow.UpdateCoordinates(new Vector2D(camanglexy, camanglez));
|
General.MainWindow.UpdateCoordinates(new Vector2D(camanglexy, camanglez));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Key down
|
||||||
|
public override void KeyDown(KeyEventArgs e)
|
||||||
|
{
|
||||||
|
string[] actions;
|
||||||
|
|
||||||
|
base.KeyDown(e);
|
||||||
|
|
||||||
|
// Get the actions for this key
|
||||||
|
actions = General.Actions.GetActionsByKey((int)e.KeyData);
|
||||||
|
foreach(string a in actions)
|
||||||
|
{
|
||||||
|
// Check what key was pressed down
|
||||||
|
switch(a)
|
||||||
|
{
|
||||||
|
case "moveforward": keyforward = true; break;
|
||||||
|
case "movebackward": keybackward = true; break;
|
||||||
|
case "moveleft": keyleft = true; break;
|
||||||
|
case "moveright": keyright = true; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key up
|
||||||
|
public override void KeyUp(KeyEventArgs e)
|
||||||
|
{
|
||||||
|
string[] actions;
|
||||||
|
|
||||||
|
base.KeyUp(e);
|
||||||
|
|
||||||
|
// Get the actions for this key
|
||||||
|
actions = General.Actions.GetActionsByKey((int)e.KeyData);
|
||||||
|
foreach(string a in actions)
|
||||||
|
{
|
||||||
|
// Check what key was pressed down
|
||||||
|
switch(a)
|
||||||
|
{
|
||||||
|
case "moveforward": keyforward = false; break;
|
||||||
|
case "movebackward": keybackward = false; break;
|
||||||
|
case "moveleft": keyleft = false; break;
|
||||||
|
case "moveright": keyright = false; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ================== Processing
|
||||||
|
|
||||||
// Processing
|
// Processing
|
||||||
public override void Process()
|
public override void Process()
|
||||||
{
|
{
|
||||||
|
Vector3D camvec;
|
||||||
|
Vector3D camvecstrafe;
|
||||||
|
|
||||||
base.Process();
|
base.Process();
|
||||||
|
|
||||||
|
// Calculate camera direction vectors
|
||||||
|
camvec = Vector3D.FromAngleXYZ(camanglexy, camanglez);
|
||||||
|
camvecstrafe = Vector3D.FromAngleXYZ(camanglexy + Angle2D.PIHALF, camanglez);
|
||||||
|
|
||||||
|
// Move the camera
|
||||||
|
if(keyforward) campos += camvec * CAMERA_SPEED;
|
||||||
|
if(keybackward) campos -= camvec * CAMERA_SPEED;
|
||||||
|
if(keyleft) campos -= camvecstrafe * CAMERA_SPEED;
|
||||||
|
if(keyright) campos += camvecstrafe * CAMERA_SPEED;
|
||||||
|
|
||||||
// Target the camera
|
// Target the camera
|
||||||
camtarget = campos + Vector3D.FromAngleXYZ(camanglexy, camanglez);
|
camtarget = campos + camvec;
|
||||||
|
|
||||||
// Apply new camera matrices
|
// Apply new camera matrices
|
||||||
renderer.PositionAndLookAt(campos, camtarget);
|
renderer.PositionAndLookAt(campos, camtarget);
|
||||||
|
|
|
@ -117,6 +117,9 @@ namespace CodeImp.DoomBuilder
|
||||||
// States
|
// States
|
||||||
private static bool debugbuild;
|
private static bool debugbuild;
|
||||||
|
|
||||||
|
// Tools
|
||||||
|
private static EarClipTriangulator earclipper;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Properties
|
#region ================== Properties
|
||||||
|
@ -139,6 +142,7 @@ namespace CodeImp.DoomBuilder
|
||||||
internal static PluginManager Plugins { get { return plugins; } }
|
internal static PluginManager Plugins { get { return plugins; } }
|
||||||
public static Clock Clock { get { return clock; } }
|
public static Clock Clock { get { return clock; } }
|
||||||
public static bool DebugBuild { get { return debugbuild; } }
|
public static bool DebugBuild { get { return debugbuild; } }
|
||||||
|
internal static EarClipTriangulator EarClipper { get { return earclipper; } }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -444,6 +448,9 @@ namespace CodeImp.DoomBuilder
|
||||||
mainwindow.Show();
|
mainwindow.Show();
|
||||||
mainwindow.Update();
|
mainwindow.Update();
|
||||||
|
|
||||||
|
// Create tools
|
||||||
|
earclipper = new EarClipTriangulator();
|
||||||
|
|
||||||
// Start Direct3D
|
// Start Direct3D
|
||||||
General.WriteLogLine("Starting Direct3D graphics driver...");
|
General.WriteLogLine("Starting Direct3D graphics driver...");
|
||||||
Direct3D.Initialize();
|
Direct3D.Initialize();
|
||||||
|
|
|
@ -36,7 +36,9 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
/// Performs triangulation of sectors by using ear clipping.
|
/// Performs triangulation of sectors by using ear clipping.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// See: http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
|
/// See: http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
|
||||||
public sealed class EarClipTriangulator : Triangulator
|
/// NOTE: This is not a derived class from Triangulator because
|
||||||
|
/// caching is not required (sectors cache their own triangles)
|
||||||
|
public sealed class EarClipTriangulator
|
||||||
{
|
{
|
||||||
#region ================== Delegates
|
#region ================== Delegates
|
||||||
|
|
||||||
|
@ -79,25 +81,12 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diposer
|
|
||||||
public override void Dispose()
|
|
||||||
{
|
|
||||||
// Not already disposed?
|
|
||||||
if(!isdisposed)
|
|
||||||
{
|
|
||||||
// Clean up
|
|
||||||
|
|
||||||
// Done
|
|
||||||
base.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Methods
|
#region ================== Methods
|
||||||
|
|
||||||
// This triangulates a sector and stores it
|
// This triangulates a sector and stores it
|
||||||
protected override void PerformTriangulation(Sector sector)
|
public TriangleList PerformTriangulation(Sector sector)
|
||||||
{
|
{
|
||||||
TriangleList triangles = new TriangleList();
|
TriangleList triangles = new TriangleList();
|
||||||
List<Polygon> polys;
|
List<Polygon> polys;
|
||||||
|
@ -125,8 +114,8 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
// EAR-CLIPPING
|
// EAR-CLIPPING
|
||||||
foreach(Polygon p in polys) triangles.AddRange(DoEarClip(p));
|
foreach(Polygon p in polys) triangles.AddRange(DoEarClip(p));
|
||||||
|
|
||||||
// STORE
|
// Return result
|
||||||
base.StoreTriangles(sector, triangles);
|
return triangles;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -618,6 +607,9 @@ namespace CodeImp.DoomBuilder.Geometry
|
||||||
if(!v2.IsReflex && CheckValidEar(t2, reflexes)) v2.AddEarTip(eartips); else v2.RemoveEarTip();
|
if(!v2.IsReflex && CheckValidEar(t2, reflexes)) v2.AddEarTip(eartips); else v2.RemoveEarTip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dispose remaining vertices
|
||||||
|
foreach(EarClipVertex ecv in verts) ecv.Dispose();
|
||||||
|
|
||||||
// Return result
|
// Return result
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,7 +256,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
// Create new item
|
// Create new item
|
||||||
l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
|
l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
|
||||||
l.Update(flags, tag, action, Linedef.EMPTY_ARGS);
|
l.Update(flags, tag, action, Linedef.EMPTY_ARGS);
|
||||||
l.Update();
|
l.UpdateCache();
|
||||||
|
|
||||||
// Line has a front side?
|
// Line has a front side?
|
||||||
if(s1 != ushort.MaxValue)
|
if(s1 != ushort.MaxValue)
|
||||||
|
|
|
@ -270,7 +270,7 @@ namespace CodeImp.DoomBuilder.IO
|
||||||
// Create new item
|
// Create new item
|
||||||
l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
|
l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
|
||||||
l.Update(flags, 0, action, args);
|
l.Update(flags, 0, action, args);
|
||||||
l.Update();
|
l.UpdateCache();
|
||||||
|
|
||||||
// Line has a front side?
|
// Line has a front side?
|
||||||
if(s1 != ushort.MaxValue)
|
if(s1 != ushort.MaxValue)
|
||||||
|
|
|
@ -60,6 +60,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// Cache
|
// Cache
|
||||||
private bool updateneeded;
|
private bool updateneeded;
|
||||||
private float lengthsq;
|
private float lengthsq;
|
||||||
|
private float lengthsqinv;
|
||||||
private float length;
|
private float length;
|
||||||
private float lengthinv;
|
private float lengthinv;
|
||||||
private float angle;
|
private float angle;
|
||||||
|
@ -235,7 +236,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
// This updates the line when changes have been made
|
// This updates the line when changes have been made
|
||||||
public void Update()
|
public void UpdateCache()
|
||||||
{
|
{
|
||||||
Vector2D delta;
|
Vector2D delta;
|
||||||
int l, t, r, b;
|
int l, t, r, b;
|
||||||
|
@ -250,6 +251,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
lengthsq = delta.GetLengthSq();
|
lengthsq = delta.GetLengthSq();
|
||||||
length = (float)Math.Sqrt(lengthsq);
|
length = (float)Math.Sqrt(lengthsq);
|
||||||
if(length > 0f) lengthinv = 1f / length; else lengthinv = 1f / 0.0000000001f;
|
if(length > 0f) lengthinv = 1f / length; else lengthinv = 1f / 0.0000000001f;
|
||||||
|
if(lengthsq > 0f) lengthsqinv = 1f / lengthsq; else lengthsqinv = 1f / 0.0000000001f;
|
||||||
angle = delta.GetAngle();
|
angle = delta.GetAngle();
|
||||||
l = Math.Min(start.X, end.X);
|
l = Math.Min(start.X, end.X);
|
||||||
t = Math.Min(start.Y, end.Y);
|
t = Math.Min(start.Y, end.Y);
|
||||||
|
@ -262,10 +264,15 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This flags the line needs an update
|
// This flags the line needs an update because it moved
|
||||||
public void NeedUpdate()
|
public void NeedUpdate()
|
||||||
{
|
{
|
||||||
|
// Update this line
|
||||||
updateneeded = true;
|
updateneeded = true;
|
||||||
|
|
||||||
|
// Update sectors as well
|
||||||
|
if(front != null) front.Sector.UpdateNeeded = true;
|
||||||
|
if(back != null) back.Sector.UpdateNeeded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -297,7 +304,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
Vector2D v2 = end.Position;
|
Vector2D v2 = end.Position;
|
||||||
|
|
||||||
// Calculate intersection offset
|
// Calculate intersection offset
|
||||||
float u = ((p.x - v1.x) * (v2.x - v1.x) + (p.y - v1.y) * (v2.y - v1.y)) / lengthsq;
|
float u = ((p.x - v1.x) * (v2.x - v1.x) + (p.y - v1.y) * (v2.y - v1.y)) * lengthsqinv;
|
||||||
|
|
||||||
// Limit intersection offset to the line
|
// Limit intersection offset to the line
|
||||||
if(bounded) if(u < lengthinv) u = lengthinv; else if(u > (1f - lengthinv)) u = 1f - lengthinv;
|
if(bounded) if(u < lengthinv) u = lengthinv; else if(u > (1f - lengthinv)) u = 1f - lengthinv;
|
||||||
|
@ -325,7 +332,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
Vector2D v2 = end.Position;
|
Vector2D v2 = end.Position;
|
||||||
|
|
||||||
// Calculate intersection offset
|
// Calculate intersection offset
|
||||||
float u = ((p.x - v1.x) * (v2.x - v1.x) + (p.y - v1.y) * (v2.y - v1.y)) / lengthsq;
|
float u = ((p.x - v1.x) * (v2.x - v1.x) + (p.y - v1.y) * (v2.y - v1.y)) * lengthsqinv;
|
||||||
|
|
||||||
// Limit intersection offset to the line
|
// Limit intersection offset to the line
|
||||||
if(bounded) if(u < 0f) u = 0f; else if(u > 1f) u = 1f;
|
if(bounded) if(u < 0f) u = 0f; else if(u > 1f) u = 1f;
|
||||||
|
|
|
@ -345,9 +345,19 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
|
|
||||||
// This updates all structures if needed
|
// This updates all structures if needed
|
||||||
public void Update()
|
public void Update()
|
||||||
|
{
|
||||||
|
// Update all!
|
||||||
|
Update(true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This updates all structures if needed
|
||||||
|
public void Update(bool dolines, bool dosectors)
|
||||||
{
|
{
|
||||||
// Update all linedefs
|
// Update all linedefs
|
||||||
foreach(Linedef l in linedefs) l.Update();
|
if(dolines) foreach(Linedef l in linedefs) l.UpdateCache();
|
||||||
|
|
||||||
|
// Update all sectors
|
||||||
|
if(dosectors) foreach(Sector s in sectors) s.UpdateCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This updates all structures after a
|
// This updates all structures after a
|
||||||
|
@ -537,9 +547,9 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
// This returns the cohen-sutherland field bits for a vertex in a rectangle area
|
// This returns the cohen-sutherland field bits for a vertex in a rectangle area
|
||||||
private static byte GetCSFieldBits(Vertex v, ref Rectangle area)
|
private static int GetCSFieldBits(Vertex v, ref Rectangle area)
|
||||||
{
|
{
|
||||||
byte bits = 0;
|
int bits = 0;
|
||||||
if(v.Y < area.Top) bits |= 0x01;
|
if(v.Y < area.Top) bits |= 0x01;
|
||||||
if(v.Y > area.Bottom) bits |= 0x02;
|
if(v.Y > area.Bottom) bits |= 0x02;
|
||||||
if(v.X < area.Left) bits |= 0x04;
|
if(v.X < area.Left) bits |= 0x04;
|
||||||
|
@ -603,8 +613,8 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// Join nearby vertices
|
// Join nearby vertices
|
||||||
stitches += MapSet.JoinVertices(fixedverts, movingverts, true, General.Settings.StitchDistance);
|
stitches += MapSet.JoinVertices(fixedverts, movingverts, true, General.Settings.StitchDistance);
|
||||||
|
|
||||||
// Update cached values
|
// Update cached values of lines because we need their length/angle
|
||||||
Update();
|
Update(true, false);
|
||||||
|
|
||||||
// Split moving lines with unselected vertices
|
// Split moving lines with unselected vertices
|
||||||
nearbyfixedverts = MapSet.FilterByArea(fixedverts, ref editarea);
|
nearbyfixedverts = MapSet.FilterByArea(fixedverts, ref editarea);
|
||||||
|
@ -836,8 +846,8 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
|
|
||||||
// Both lines must be updated because their new length
|
// Both lines must be updated because their new length
|
||||||
// is relevant for next iterations!
|
// is relevant for next iterations!
|
||||||
l.Update();
|
l.UpdateCache();
|
||||||
nl.Update();
|
nl.UpdateCache();
|
||||||
|
|
||||||
// Add both lines to changedlines
|
// Add both lines to changedlines
|
||||||
if(changedlines != null) changedlines.Add(l);
|
if(changedlines != null) changedlines.Add(l);
|
||||||
|
@ -852,6 +862,8 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
// Will have to restart when splitted
|
// Will have to restart when splitted
|
||||||
|
// TODO: If we make (linked) lists from the collections first,
|
||||||
|
// we don't have to restart when splitted?
|
||||||
if(splitted) break;
|
if(splitted) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using CodeImp.DoomBuilder.IO;
|
using CodeImp.DoomBuilder.IO;
|
||||||
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -65,6 +66,10 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// Cloning
|
// Cloning
|
||||||
private Sector clone;
|
private Sector clone;
|
||||||
|
|
||||||
|
// Triangulation
|
||||||
|
private bool updateneeded;
|
||||||
|
private TriangleList triangles;
|
||||||
|
|
||||||
// Disposing
|
// Disposing
|
||||||
private bool isdisposed = false;
|
private bool isdisposed = false;
|
||||||
|
|
||||||
|
@ -87,7 +92,9 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
public int Tag { get { return tag; } set { tag = value; if((tag < 0) || (tag > MapSet.HIGHEST_TAG)) throw new ArgumentOutOfRangeException("Tag", "Invalid tag number"); } }
|
public int Tag { get { return tag; } set { tag = value; if((tag < 0) || (tag > MapSet.HIGHEST_TAG)) throw new ArgumentOutOfRangeException("Tag", "Invalid tag number"); } }
|
||||||
public int Brightness { get { return brightness; } }
|
public int Brightness { get { return brightness; } }
|
||||||
public bool Selected { get { return selected; } set { selected = value; } }
|
public bool Selected { get { return selected; } set { selected = value; } }
|
||||||
|
public bool UpdateNeeded { get { return updateneeded; } set { updateneeded |= value; } }
|
||||||
public Sector Clone { get { return clone; } set { clone = value; } }
|
public Sector Clone { get { return clone; } set { clone = value; } }
|
||||||
|
public TriangleList Triangles { get { return triangles; } set { triangles = value; } }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -156,7 +163,11 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
// This attaches a sidedef and returns the listitem
|
// This attaches a sidedef and returns the listitem
|
||||||
public LinkedListNode<Sidedef> AttachSidedef(Sidedef sd) { return sidedefs.AddLast(sd); }
|
public LinkedListNode<Sidedef> AttachSidedef(Sidedef sd)
|
||||||
|
{
|
||||||
|
updateneeded = true;
|
||||||
|
return sidedefs.AddLast(sd);
|
||||||
|
}
|
||||||
|
|
||||||
// This detaches a sidedef
|
// This detaches a sidedef
|
||||||
public void DetachSidedef(LinkedListNode<Sidedef> l)
|
public void DetachSidedef(LinkedListNode<Sidedef> l)
|
||||||
|
@ -165,6 +176,7 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
if(!isdisposed)
|
if(!isdisposed)
|
||||||
{
|
{
|
||||||
// Remove sidedef
|
// Remove sidedef
|
||||||
|
updateneeded = true;
|
||||||
sidedefs.Remove(l);
|
sidedefs.Remove(l);
|
||||||
|
|
||||||
// No more sidedefs left?
|
// No more sidedefs left?
|
||||||
|
@ -182,6 +194,20 @@ namespace CodeImp.DoomBuilder.Map
|
||||||
// This detaches a thing
|
// This detaches a thing
|
||||||
public void DetachThing(LinkedListNode<Thing> l) { if(!isdisposed) things.Remove(l); }
|
public void DetachThing(LinkedListNode<Thing> l) { if(!isdisposed) things.Remove(l); }
|
||||||
|
|
||||||
|
// This updates the sector when changes have been made
|
||||||
|
public void UpdateCache()
|
||||||
|
{
|
||||||
|
// Update if needed
|
||||||
|
if(updateneeded)
|
||||||
|
{
|
||||||
|
// Triangulate sector again
|
||||||
|
triangles = General.EarClipper.PerformTriangulation(this);
|
||||||
|
|
||||||
|
// Updated
|
||||||
|
updateneeded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ================== Changes
|
#region ================== Changes
|
||||||
|
|
|
@ -578,6 +578,8 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
if(count > 0)
|
if(count > 0)
|
||||||
{
|
{
|
||||||
// Set renderstates for things rendering
|
// Set renderstates for things rendering
|
||||||
|
graphics.Device.SetRenderState(RenderState.CullMode, Cull.None);
|
||||||
|
graphics.Device.SetRenderState(RenderState.ZEnable, false);
|
||||||
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
|
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
|
||||||
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, true);
|
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, true);
|
||||||
graphics.Device.SetTexture(0, thingtexture.Texture);
|
graphics.Device.SetTexture(0, thingtexture.Texture);
|
||||||
|
|
|
@ -133,7 +133,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
anglez = delta.GetAngleZ();
|
anglez = delta.GetAngleZ();
|
||||||
|
|
||||||
// Make the view matrix
|
// Make the view matrix
|
||||||
view = Matrix.LookAtRH(D3DDevice.V3(pos), D3DDevice.V3(lookat), new Vector3(0f, 0f, 1f));
|
view = Matrix.LookAtRH(D3DDevice.V3(pos), D3DDevice.V3(lookat), new Vector3(0f, 0f, -1f));
|
||||||
|
|
||||||
// Make the billboard matrix
|
// Make the billboard matrix
|
||||||
billboard = Matrix.RotationYawPitchRoll(0f, anglexy, anglez - Angle2D.PIHALF);
|
billboard = Matrix.RotationYawPitchRoll(0f, anglexy, anglez - Angle2D.PIHALF);
|
||||||
|
@ -182,6 +182,13 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
// This begins rendering world geometry
|
// This begins rendering world geometry
|
||||||
public void StartGeometry()
|
public void StartGeometry()
|
||||||
{
|
{
|
||||||
|
// Renderstates
|
||||||
|
graphics.Device.SetRenderState(RenderState.CullMode, Cull.CounterClockwise);
|
||||||
|
graphics.Device.SetRenderState(RenderState.ZEnable, true);
|
||||||
|
graphics.Device.SetRenderState(RenderState.ZWriteEnable, true);
|
||||||
|
graphics.Device.SetRenderState(RenderState.AlphaBlendEnable, false);
|
||||||
|
graphics.Device.SetRenderState(RenderState.AlphaTestEnable, true);
|
||||||
|
|
||||||
// Setup shader
|
// Setup shader
|
||||||
graphics.Shaders.World3D.Begin();
|
graphics.Shaders.World3D.Begin();
|
||||||
graphics.Shaders.World3D.WorldViewProj = viewproj;
|
graphics.Shaders.World3D.WorldViewProj = viewproj;
|
||||||
|
@ -216,6 +223,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
// Update the sector if needed
|
// Update the sector if needed
|
||||||
if(s.NeedsUpdateGeo) s.Update();
|
if(s.NeedsUpdateGeo) s.Update();
|
||||||
|
|
||||||
|
// Only render when a vertexbuffer exists
|
||||||
|
if(s.GeometryBuffer != null)
|
||||||
|
{
|
||||||
// Set the buffer
|
// Set the buffer
|
||||||
graphics.Device.SetStreamSource(0, s.GeometryBuffer, 0, WorldVertex.Stride);
|
graphics.Device.SetStreamSource(0, s.GeometryBuffer, 0, WorldVertex.Stride);
|
||||||
|
|
||||||
|
@ -247,6 +257,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
// Remove references
|
// Remove references
|
||||||
graphics.Shaders.World3D.Texture1 = null;
|
graphics.Shaders.World3D.Texture1 = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,13 +82,10 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
|
|
||||||
// Register as resource
|
// Register as resource
|
||||||
General.Map.Graphics.RegisterResource(this);
|
General.Map.Graphics.RegisterResource(this);
|
||||||
|
|
||||||
// We have no destructor
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diposer
|
// Diposer
|
||||||
public void Dispose()
|
public virtual void Dispose()
|
||||||
{
|
{
|
||||||
// Not already disposed?
|
// Not already disposed?
|
||||||
if(!isdisposed)
|
if(!isdisposed)
|
||||||
|
@ -112,7 +109,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
|
|
||||||
// This is called before a device is reset
|
// This is called before a device is reset
|
||||||
// (when resized or display adapter was changed)
|
// (when resized or display adapter was changed)
|
||||||
public void UnloadResource()
|
public virtual void UnloadResource()
|
||||||
{
|
{
|
||||||
// Trash geometry buffer
|
// Trash geometry buffer
|
||||||
if(geobuffer != null) geobuffer.Dispose();
|
if(geobuffer != null) geobuffer.Dispose();
|
||||||
|
@ -122,7 +119,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
|
|
||||||
// This is called resets when the device is reset
|
// This is called resets when the device is reset
|
||||||
// (when resized or display adapter was changed)
|
// (when resized or display adapter was changed)
|
||||||
public void ReloadResource()
|
public virtual void ReloadResource()
|
||||||
{
|
{
|
||||||
// Make new geometry
|
// Make new geometry
|
||||||
//Update();
|
//Update();
|
||||||
|
@ -137,6 +134,7 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
|
|
||||||
// Trash geometry buffer
|
// Trash geometry buffer
|
||||||
if(geobuffer != null) geobuffer.Dispose();
|
if(geobuffer != null) geobuffer.Dispose();
|
||||||
|
geobuffer = null;
|
||||||
|
|
||||||
// Sort the geo list by texture
|
// Sort the geo list by texture
|
||||||
geolist.Sort();
|
geolist.Sort();
|
||||||
|
@ -144,6 +142,9 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
// Count the number of vertices there are
|
// Count the number of vertices there are
|
||||||
foreach(VisualGeometry g in geolist) numverts += g.Vertices.Length;
|
foreach(VisualGeometry g in geolist) numverts += g.Vertices.Length;
|
||||||
|
|
||||||
|
// Any vertics?
|
||||||
|
if(numverts > 0)
|
||||||
|
{
|
||||||
// Make a new buffer
|
// Make a new buffer
|
||||||
geobuffer = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * numverts,
|
geobuffer = new VertexBuffer(General.Map.Graphics.Device, WorldVertex.Stride * numverts,
|
||||||
Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default);
|
Usage.WriteOnly | Usage.Dynamic, VertexFormat.None, Pool.Default);
|
||||||
|
@ -152,12 +153,16 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
bufferstream = geobuffer.Lock(0, WorldVertex.Stride * numverts, LockFlags.Discard);
|
bufferstream = geobuffer.Lock(0, WorldVertex.Stride * numverts, LockFlags.Discard);
|
||||||
foreach(VisualGeometry g in geolist)
|
foreach(VisualGeometry g in geolist)
|
||||||
{
|
{
|
||||||
bufferstream.WriteRange<WorldVertex>(g.Vertices, v, g.Vertices.Length);
|
if(g.Vertices.Length > 0)
|
||||||
|
{
|
||||||
|
bufferstream.WriteRange<WorldVertex>(g.Vertices);
|
||||||
g.VertexOffset = v;
|
g.VertexOffset = v;
|
||||||
v += g.Vertices.Length;
|
v += g.Vertices.Length;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
geobuffer.Unlock();
|
geobuffer.Unlock();
|
||||||
bufferstream.Dispose();
|
bufferstream.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
// Done
|
// Done
|
||||||
updategeo = false;
|
updategeo = false;
|
||||||
|
@ -171,6 +176,14 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
updategeo = true;
|
updategeo = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This removes all geometry
|
||||||
|
public void ClearGeometry()
|
||||||
|
{
|
||||||
|
foreach(VisualGeometry g in geolist) g.Sector = null;
|
||||||
|
geolist.Clear();
|
||||||
|
updategeo = true;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,5 +50,49 @@ namespace CodeImp.DoomBuilder.Rendering
|
||||||
public int c;
|
public int c;
|
||||||
public float u;
|
public float u;
|
||||||
public float v;
|
public float v;
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public WorldVertex(float x, float y, float z, int c, float u, float v)
|
||||||
|
{
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.c = c;
|
||||||
|
this.u = u;
|
||||||
|
this.v = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public WorldVertex(float x, float y, float z, float u, float v)
|
||||||
|
{
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.c = -1;
|
||||||
|
this.u = u;
|
||||||
|
this.v = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public WorldVertex(float x, float y, float z, int c)
|
||||||
|
{
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.c = c;
|
||||||
|
this.u = 0.0f;
|
||||||
|
this.v = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public WorldVertex(float x, float y, float z)
|
||||||
|
{
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.c = -1;
|
||||||
|
this.u = 0.0f;
|
||||||
|
this.v = 0.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,7 +134,7 @@ scrolleast
|
||||||
scrollnorth
|
scrollnorth
|
||||||
{
|
{
|
||||||
title = "2D: Scroll North";
|
title = "2D: Scroll North";
|
||||||
description = "Scrolls the 2D map view to the north.";
|
description = "Scrolls the 2D map view to the up.";
|
||||||
allowkeys = true;
|
allowkeys = true;
|
||||||
allowmouse = true;
|
allowmouse = true;
|
||||||
allowscroll = true;
|
allowscroll = true;
|
||||||
|
@ -143,7 +143,7 @@ scrollnorth
|
||||||
scrollsouth
|
scrollsouth
|
||||||
{
|
{
|
||||||
title = "2D: Scroll South";
|
title = "2D: Scroll South";
|
||||||
description = "Scrolls the 2D map view to the south.";
|
description = "Scrolls the 2D map view to the down.";
|
||||||
allowkeys = true;
|
allowkeys = true;
|
||||||
allowmouse = true;
|
allowmouse = true;
|
||||||
allowscroll = true;
|
allowscroll = true;
|
||||||
|
@ -229,3 +229,39 @@ clearselection
|
||||||
allowmouse = true;
|
allowmouse = true;
|
||||||
allowscroll = true;
|
allowscroll = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
moveforward
|
||||||
|
{
|
||||||
|
title = "3D: Move Forward";
|
||||||
|
description = "Moves the camera forward in 3D Visual Mode.";
|
||||||
|
allowkeys = true;
|
||||||
|
allowmouse = true;
|
||||||
|
allowscroll = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
movebackward
|
||||||
|
{
|
||||||
|
title = "3D: Move Backward";
|
||||||
|
description = "Moves the camera backward in 3D Visual Mode.";
|
||||||
|
allowkeys = true;
|
||||||
|
allowmouse = true;
|
||||||
|
allowscroll = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
moveleft
|
||||||
|
{
|
||||||
|
title = "3D: Move Left (strafe)";
|
||||||
|
description = "Strafes the camera left in 3D Visual Mode.";
|
||||||
|
allowkeys = true;
|
||||||
|
allowmouse = true;
|
||||||
|
allowscroll = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
moveright
|
||||||
|
{
|
||||||
|
title = "3D: Move Right (strafe)";
|
||||||
|
description = "Strafes the camera right in 3D Visual Mode.";
|
||||||
|
allowkeys = true;
|
||||||
|
allowmouse = true;
|
||||||
|
allowscroll = true;
|
||||||
|
}
|
||||||
|
|
BIN
Source/Resources/MissingTexture3D.png
Normal file
BIN
Source/Resources/MissingTexture3D.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 695 B |
Loading…
Reference in a new issue