Fixed, .obj Terrain Importer mode: the mode was not canceled properly after failing to import a model.

Fixed, .obj Terrain Importer mode: the mode was unable to parse .obj vertex/face definitions generated by some (Cinema4D) modeling programs.
Changed, .obj Terrain Importer mode: vertical (e.g. perpendicular to up axis) polygons are now skipped during model importing.
Changed, Ceiling Align mode, Floor Align mode: changed rotation steps form 45 to 15 deg.
This commit is contained in:
MaxED 2015-04-28 14:22:03 +00:00
parent c2b3e92673
commit 60c4ad7b4b
4 changed files with 80 additions and 142 deletions

View file

@ -106,6 +106,7 @@ namespace CodeImp.DoomBuilder.BuilderEffects
// Return to base mode // Return to base mode
General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name); General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name);
return;
} }
// Update caches // Update caches
@ -139,6 +140,13 @@ namespace CodeImp.DoomBuilder.BuilderEffects
private bool CreateGeometry(List<Vector3D> verts, List<Face> faces, int maxZ) private bool CreateGeometry(List<Vector3D> verts, List<Face> faces, int maxZ)
{ {
if(verts.Count < 3 || faces.Count == 0)
{
MessageBox.Show("Cannot import the model: failed to find any suitable polygons!",
"Terrain Importer", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
MapSet map = General.Map.Map; MapSet map = General.Map.Map;
// Capacity checks // Capacity checks
@ -305,6 +313,7 @@ namespace CodeImp.DoomBuilder.BuilderEffects
float x, y, z; float x, y, z;
int px, py, pz; int px, py, pz;
int counter = 0; int counter = 0;
float picoarse = (float)Math.Round(Angle2D.PI, 3);
while((line = reader.ReadLine()) != null) while((line = reader.ReadLine()) != null)
{ {
@ -312,7 +321,7 @@ namespace CodeImp.DoomBuilder.BuilderEffects
if(line.StartsWith("v ")) if(line.StartsWith("v "))
{ {
string[] parts = line.Split(space); string[] parts = line.Split(space, StringSplitOptions.RemoveEmptyEntries);
if(parts.Length != 4 || !float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out x) || if(parts.Length != 4 || !float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out x) ||
!float.TryParse(parts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out y) || !float.TryParse(parts[2], NumberStyles.Float, CultureInfo.InvariantCulture, out y) ||
@ -357,11 +366,11 @@ namespace CodeImp.DoomBuilder.BuilderEffects
} }
else if(line.StartsWith("f ")) else if(line.StartsWith("f "))
{ {
string[] parts = line.Split(space); string[] parts = line.Split(space, StringSplitOptions.RemoveEmptyEntries);
if(parts.Length != 4) if(parts.Length != 4)
{ {
MessageBox.Show("Failed to parse face definition at line " + counter + ": only triangle faces are supported!", "Terrain Importer", MessageBoxButtons.OK, MessageBoxIcon.Error); MessageBox.Show("Failed to parse face definition at line " + counter + ": only triangular faces are supported!", "Terrain Importer", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false; return false;
} }
@ -370,7 +379,13 @@ namespace CodeImp.DoomBuilder.BuilderEffects
int v2 = ReadVertexIndex(parts[2]) - 1; int v2 = ReadVertexIndex(parts[2]) - 1;
int v3 = ReadVertexIndex(parts[3]) - 1; int v3 = ReadVertexIndex(parts[3]) - 1;
// Skip face if vertex indexes match
if(verts[v1] == verts[v2] || verts[v1] == verts[v3] || verts[v2] == verts[v3]) continue; if(verts[v1] == verts[v2] || verts[v1] == verts[v3] || verts[v2] == verts[v3]) continue;
// Skip face if it's vertical
Plane p = new Plane(verts[v1], verts[v2], verts[v3], true);
if((float)Math.Round(p.Normal.GetAngleZ(), 3) == picoarse) continue;
faces.Add(new Face(verts[v3], verts[v2], verts[v1])); faces.Add(new Face(verts[v3], verts[v2], verts[v1]));
} }
} }

View file

@ -36,33 +36,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
public class CeilingAlignMode : FlatAlignMode public class CeilingAlignMode : FlatAlignMode
{ {
#region ================== Constants
#endregion
#region ================== Variables
private ViewMode prevviewmode;
#endregion
#region ================== Properties #region ================== Properties
public override string XScaleName { get { return "xscaleceiling"; } } protected override string XScaleName { get { return "xscaleceiling"; } }
public override string YScaleName { get { return "yscaleceiling"; } } protected override string YScaleName { get { return "yscaleceiling"; } }
public override string XOffsetName { get { return "xpanningceiling"; } } protected override string XOffsetName { get { return "xpanningceiling"; } }
public override string YOffsetName { get { return "ypanningceiling"; } } protected override string YOffsetName { get { return "ypanningceiling"; } }
public override string RotationName { get { return "rotationceiling"; } } protected override string RotationName { get { return "rotationceiling"; } }
public override string UndoDescription { get { return "Ceiling Alignment"; } } protected override string UndoDescription { get { return "Ceiling Alignment"; } }
#endregion
#region ================== Constructor / Disposer
// Constructor
public CeilingAlignMode()
{
}
#endregion #endregion
@ -81,27 +62,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Mode engages // Mode engages
public override void OnEngage() public override void OnEngage()
{ {
prevviewmode = General.Map.Renderer2D.ViewMode;
base.OnEngage(); base.OnEngage();
General.Actions.InvokeAction("builder_viewmodeceilings"); General.Actions.InvokeAction("builder_viewmodeceilings");
} }
// Mode disengages
public override void OnDisengage()
{
switch(prevviewmode)
{
case ViewMode.Normal: General.Actions.InvokeAction("builder_viewmodenormal"); break;
case ViewMode.FloorTextures: General.Actions.InvokeAction("builder_viewmodefloors"); break;
case ViewMode.CeilingTextures: General.Actions.InvokeAction("builder_viewmodeceilings"); break;
case ViewMode.Brightness: General.Actions.InvokeAction("builder_viewmodebrightness"); break;
}
base.OnDisengage();
}
#endregion #endregion
} }
} }

View file

@ -18,15 +18,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using CodeImp.DoomBuilder.Actions;
using CodeImp.DoomBuilder.Data; using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Types; using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Windows;
using CodeImp.DoomBuilder.Map; using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Rendering; using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Geometry; using CodeImp.DoomBuilder.Types;
using System.Drawing; using CodeImp.DoomBuilder.Windows;
using CodeImp.DoomBuilder.Actions;
#endregion #endregion
@ -34,9 +34,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
{ {
public abstract class FlatAlignMode : BaseClassicMode public abstract class FlatAlignMode : BaseClassicMode
{ {
#region ================== Constants #region ================== Enums and Structs
private enum ModifyMode : int private enum ModifyMode
{ {
None, None,
Dragging, Dragging,
@ -44,7 +44,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
Rotating Rotating
} }
private enum Grip : int private enum Grip
{ {
None, None,
Main, Main,
@ -61,6 +61,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
public Vector2D offset; public Vector2D offset;
} }
#endregion
#region ================== Constants
private const float GRIP_SIZE = 9.0f; private const float GRIP_SIZE = 9.0f;
private readonly Cursor[] RESIZE_CURSORS = { Cursors.SizeNS, Cursors.SizeNWSE, Cursors.SizeWE, Cursors.SizeNESW }; private readonly Cursor[] RESIZE_CURSORS = { Cursors.SizeNS, Cursors.SizeNWSE, Cursors.SizeWE, Cursors.SizeNESW };
private const byte RECTANGLE_ALPHA = 60; private const byte RECTANGLE_ALPHA = 60;
@ -71,7 +75,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Variables #region ================== Variables
private ICollection<Sector> selection; private ICollection<Sector> selection;
protected Sector editsector; private Sector editsector;
protected IList<SectorInfo> sectorinfo; protected IList<SectorInfo> sectorinfo;
private ImageData texture; private ImageData texture;
//private Vector2D selectionoffset; //private Vector2D selectionoffset;
@ -88,11 +92,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
private Vector2D offset; private Vector2D offset;
// Rectangle components // Rectangle components
private Vector2D[] corners = new Vector2D[4]; // lefttop, righttop, rightbottom, leftbottom private readonly Vector2D[] corners = new Vector2D[4]; // lefttop, righttop, rightbottom, leftbottom
private FlatVertex[] cornerverts = new FlatVertex[6]; private FlatVertex[] cornerverts = new FlatVertex[6];
private Vector2D[] extends = new Vector2D[2]; // right, bottom private readonly Vector2D[] extends = new Vector2D[2]; // right, bottom
private RectangleF[] resizegrips = new RectangleF[2]; // right, bottom private readonly RectangleF[] resizegrips = new RectangleF[2]; // right, bottom
private RectangleF[] rotategrips = new RectangleF[2]; // righttop, leftbottom private readonly RectangleF[] rotategrips = new RectangleF[2]; // righttop, leftbottom
private Line2D extensionline; private Line2D extensionline;
// Aligning // Aligning
@ -106,6 +110,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
private float rotationoffset; private float rotationoffset;
private Vector2D rotationcenter; private Vector2D rotationcenter;
//mxd. View mode
private ViewMode prevviewmode;
// Options // Options
private bool snaptogrid; // SHIFT to toggle private bool snaptogrid; // SHIFT to toggle
private bool snaptonearest; // CTRL to enable private bool snaptonearest; // CTRL to enable
@ -114,21 +121,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
#region ================== Properties #region ================== Properties
public abstract string XScaleName { get; } protected abstract string XScaleName { get; }
public abstract string YScaleName { get; } protected abstract string YScaleName { get; }
public abstract string XOffsetName { get; } protected abstract string XOffsetName { get; }
public abstract string YOffsetName { get; } protected abstract string YOffsetName { get; }
public abstract string RotationName { get; } protected abstract string RotationName { get; }
public abstract string UndoDescription { get; } protected abstract string UndoDescription { get; }
#endregion
#region ================== Constructor / Disposer
// Constructor
protected FlatAlignMode()
{
}
#endregion #endregion
@ -143,7 +141,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
// Transforms p from Texture space into World space // Transforms p from Texture space into World space
protected Vector2D TexToWorld(Vector2D p) private Vector2D TexToWorld(Vector2D p)
{ {
return TexToWorld(p, sectorinfo[0]); return TexToWorld(p, sectorinfo[0]);
} }
@ -160,7 +158,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
} }
// Transforms p from World space into Texture space // Transforms p from World space into Texture space
protected Vector2D WorldToTex(Vector2D p) private Vector2D WorldToTex(Vector2D p)
{ {
return WorldToTex(p, sectorinfo[0]); return WorldToTex(p, sectorinfo[0]);
} }
@ -441,15 +439,16 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Snap to grid? // Snap to grid?
if(dosnaptogrid) if(dosnaptogrid)
{ {
// We make 8 vectors that the rotation can snap to // We make 24 vectors that the rotation can snap to
float founddistance = float.MaxValue; float founddistance = float.MaxValue;
float foundrotation = rotation; float foundrotation = rotation;
for(int i = 0; i < 8; i++) Vector3D rotvec = Vector2D.FromAngle(deltaangle + rotationoffset);
for(int i = 0; i < 24; i++)
{ {
// Make the vectors // Make the vectors
float angle = i * Angle2D.PI * 0.25f; float angle = i * Angle2D.PI * 0.08333333333f; //mxd. 15-degree increments
Vector2D gridvec = Vector2D.FromAngle(angle); Vector2D gridvec = Vector2D.FromAngle(angle);
Vector3D rotvec = Vector2D.FromAngle(deltaangle + rotationoffset);
// Check distance // Check distance
float dist = 2.0f - Vector2D.DotProduct(gridvec, rotvec); float dist = 2.0f - Vector2D.DotProduct(gridvec, rotvec);
@ -544,18 +543,12 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This checks and returns the grip the mouse pointer is in // This checks and returns the grip the mouse pointer is in
private Grip CheckMouseGrip() private Grip CheckMouseGrip()
{ {
if(PointInRectF(resizegrips[0], mousemappos)) if(PointInRectF(resizegrips[0], mousemappos)) return Grip.SizeH;
return Grip.SizeH; if(PointInRectF(resizegrips[1], mousemappos)) return Grip.SizeV;
else if(PointInRectF(resizegrips[1], mousemappos)) if(PointInRectF(rotategrips[0], mousemappos)) return Grip.RotateRT;
return Grip.SizeV; if(PointInRectF(rotategrips[1], mousemappos)) return Grip.RotateLB;
else if(PointInRectF(rotategrips[0], mousemappos)) if(Tools.PointInPolygon(corners, mousemappos)) return Grip.Main;
return Grip.RotateRT; return Grip.None;
else if(PointInRectF(rotategrips[1], mousemappos))
return Grip.RotateLB;
else if(Tools.PointInPolygon(corners, mousemappos))
return Grip.Main;
else
return Grip.None;
} }
#endregion #endregion
@ -565,6 +558,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Mode engages // Mode engages
public override void OnEngage() public override void OnEngage()
{ {
prevviewmode = General.Map.Renderer2D.ViewMode; //mxd
base.OnEngage(); base.OnEngage();
// We don't want to record this for undoing while we move the geometry around. // We don't want to record this for undoing while we move the geometry around.
@ -662,6 +656,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Mode disengages // Mode disengages
public override void OnDisengage() public override void OnDisengage()
{ {
switch(prevviewmode)
{
case ViewMode.Normal: General.Actions.InvokeAction("builder_viewmodenormal"); break;
case ViewMode.FloorTextures: General.Actions.InvokeAction("builder_viewmodefloors"); break;
case ViewMode.CeilingTextures: General.Actions.InvokeAction("builder_viewmodeceilings"); break;
case ViewMode.Brightness: General.Actions.InvokeAction("builder_viewmodebrightness"); break;
}
base.OnDisengage(); base.OnDisengage();
// When not cancelled manually, we assume it is accepted // When not cancelled manually, we assume it is accepted
@ -735,7 +737,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public override void OnMouseMove(MouseEventArgs e) public override void OnMouseMove(MouseEventArgs e)
{ {
base.OnMouseMove(e); base.OnMouseMove(e);
if(panning) return; //mxd. Skip all this jass while panning if(panning) return; //mxd. Skip all this jazz while panning
Update(); Update();
} }
@ -767,12 +769,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
protected override void OnSelectBegin() protected override void OnSelectBegin()
{ {
base.OnSelectBegin(); base.OnSelectBegin();
if(mode != ModifyMode.None) return; if(mode != ModifyMode.None) return;
// Used in many cases
//Vector2D delta;
// Check what grip the mouse is over // Check what grip the mouse is over
switch(CheckMouseGrip()) switch(CheckMouseGrip())
{ {
@ -786,7 +784,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Scale // Scale
case Grip.SizeH: case Grip.SizeH:
// The resize vector is a unit vector in the direction of the resize. // The resize vector is a unit vector in the direction of the resize.
// We multiply this with the sign of the current size, because the // We multiply this with the sign of the current size, because the
// corners may be reversed when the selection is flipped. // corners may be reversed when the selection is flipped.
@ -864,9 +861,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
// This redraws the display // This redraws the display
public override void OnRedrawDisplay() public override void OnRedrawDisplay()
{ {
if(sectorinfo != null) if(sectorinfo != null) UpdateRectangleComponents();
UpdateRectangleComponents();
renderer.RedrawSurface(); renderer.RedrawSurface();
// Render lines // Render lines

View file

@ -36,33 +36,14 @@ namespace CodeImp.DoomBuilder.BuilderModes
public class FloorAlignMode : FlatAlignMode public class FloorAlignMode : FlatAlignMode
{ {
#region ================== Constants
#endregion
#region ================== Variables
private ViewMode prevviewmode;
#endregion
#region ================== Properties #region ================== Properties
public override string XScaleName { get { return "xscalefloor"; } } protected override string XScaleName { get { return "xscalefloor"; } }
public override string YScaleName { get { return "yscalefloor"; } } protected override string YScaleName { get { return "yscalefloor"; } }
public override string XOffsetName { get { return "xpanningfloor"; } } protected override string XOffsetName { get { return "xpanningfloor"; } }
public override string YOffsetName { get { return "ypanningfloor"; } } protected override string YOffsetName { get { return "ypanningfloor"; } }
public override string RotationName { get { return "rotationfloor"; } } protected override string RotationName { get { return "rotationfloor"; } }
public override string UndoDescription { get { return "Floor Alignment"; } } protected override string UndoDescription { get { return "Floor Alignment"; } }
#endregion
#region ================== Constructor / Disposer
// Constructor
public FloorAlignMode()
{
}
#endregion #endregion
@ -81,27 +62,10 @@ namespace CodeImp.DoomBuilder.BuilderModes
// Mode engages // Mode engages
public override void OnEngage() public override void OnEngage()
{ {
prevviewmode = General.Map.Renderer2D.ViewMode;
base.OnEngage(); base.OnEngage();
General.Actions.InvokeAction("builder_viewmodefloors"); General.Actions.InvokeAction("builder_viewmodefloors");
} }
// Mode disengages
public override void OnDisengage()
{
switch(prevviewmode)
{
case ViewMode.Normal: General.Actions.InvokeAction("builder_viewmodenormal"); break;
case ViewMode.FloorTextures: General.Actions.InvokeAction("builder_viewmodefloors"); break;
case ViewMode.CeilingTextures: General.Actions.InvokeAction("builder_viewmodeceilings"); break;
case ViewMode.Brightness: General.Actions.InvokeAction("builder_viewmodebrightness"); break;
}
base.OnDisengage();
}
#endregion #endregion
} }
} }