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 } }