using System;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Rendering;
namespace CodeImp.DoomBuilder.VisualModes
{
public enum VisualSlopeType
{
Line,
Vertex
}
public abstract class VisualSlope : IVisualPickable
{
#region ================== Variables
// Disposing
private bool isdisposed;
// Selected?
protected bool selected;
// Pivot?
protected bool pivot;
// Smart Pivot?
protected bool smartpivot;
// Was changed?
private bool changed;
protected VisualSlopeType type;
protected double length;
private Matrix position;
#endregion
#region ================== Properties
///
/// Selected or not? This is only used by the core to determine what color to draw it with.
///
public bool Selected { get { return selected; } set { selected = value; } }
///
/// Pivot or not? This is only used by the core to determine what color to draw it with.
///
public bool Pivot { get { return pivot; } set { pivot = value; } }
///
/// Disposed or not?
///
public bool IsDisposed { get { return isdisposed; } }
public bool SmartPivot { get { return smartpivot; } set { smartpivot = value; } }
public bool Changed { get { return changed; } set { changed = value; } }
public VisualSlopeType Type { get { return type; } }
public double Length { get { return length; } }
public Matrix Position { get { return position; } }
#endregion
#region ================== Constructor / Destructor
public VisualSlope()
{
pivot = false;
smartpivot = false;
}
#endregion
#region ================== Methods
// This is called before a device is reset (when resized or display adapter was changed)
public void UnloadResource()
{
}
// This is called resets when the device is reset
// (when resized or display adapter was changed)
public void ReloadResource()
{
}
///
/// This is called when the thing must be tested for line intersection. This should reject
/// as fast as possible to rule out all geometry that certainly does not touch the line.
///
public virtual bool PickFastReject(Vector3D from, Vector3D to, Vector3D dir)
{
return true;
}
///
/// This is called when the thing must be tested for line intersection. This should perform
/// accurate hit detection and set u_ray to the position on the ray where this hits the geometry.
///
public virtual bool PickAccurate(Vector3D from, Vector3D to, Vector3D dir, ref double u_ray)
{
return true;
}
public virtual void Update() {}
public virtual Vector3D GetPivotPoint() { return new Vector3D(); }
public virtual VisualSlope GetSmartPivotHandle() { return null; }
public void SetPosition(Line2D line, Plane plane)
{
Line3D line3d = new Line3D(new Vector3D(line.v1, plane.GetZ(line.v1)), new Vector3D(line.v2, plane.GetZ(line.v2)));
// This vector is perpendicular to the line, with a 90° angle between it and the plane normal
Vector3D perpendicularvector = Vector3D.CrossProduct(line3d.GetDelta().GetNormal(), plane.Normal) * (-1);
// This vector is on the plane, with a 90° angle to the perpendicular vector (so effectively
// it's on the line, but in 3D
Vector3D linevector = Vector3D.CrossProduct(plane.Normal, perpendicularvector) * (-1);
Matrix m = Matrix.Null;
m.M11 = (float)linevector.x;
m.M12 = (float)linevector.y;
m.M13 = (float)linevector.z;
m.M21 = (float)perpendicularvector.x;
m.M22 = (float)perpendicularvector.y;
m.M23 = (float)perpendicularvector.z;
m.M31 = (float)plane.Normal.x;
m.M32 = (float)plane.Normal.y;
m.M33 = (float)plane.Normal.z;
m.M44 = 1.0f;
// The matrix is at the 0,0 origin, so move it to the start vertex of the line
Vector3D tp = new Vector3D(line.v1, plane.GetZ(line.v1));
position = Matrix.Multiply(m, Matrix.Translation(RenderDevice.V3(tp)));
}
#endregion
}
}