#region ================== Copyright (c) 2022 Boris Iwanski /* * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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. * * You should have received a copy of the GNU General Public License * along with this program.If not, see. */ #endregion #region ================== Namespaces using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using CodeImp.DoomBuilder.Geometry; #endregion namespace CodeImp.DoomBuilder.UDBScript.Wrapper { class PlaneWrapper { #region ================== Variables private Plane plane; #endregion #region ================== Properties /// /// The plane's normal vector. /// [UDBScriptSettings(MinVersion = 5)] public Vector3D normal { get { return plane.Normal; } } /// /// The distance of the plane along the normal vector. /// [UDBScriptSettings(MinVersion = 5)] public double offset { get { return plane.Offset; } set { plane.Offset = value; } } /// /// The `a` value of the plane equation. This is the `x` value of the normal vector. /// [UDBScriptSettings(MinVersion = 5)] public double a { get { return plane.Normal.x; } } /// /// The `b` value of the plane equation. This is the `y` value of the normal vector. /// [UDBScriptSettings(MinVersion = 5)] public double b { get { return plane.Normal.y; } } /// /// The `c` value of the plane equation. This is the `z` value of the normal vector. /// [UDBScriptSettings(MinVersion = 5)] public double c { get { return plane.Normal.z; } } /// /// The `d` value of the plane equation. This is the same as the `offset` value. /// [UDBScriptSettings(MinVersion = 5)] public double d { get { return plane.Offset; } set { plane.Offset = value; } } #endregion #region ================== Constructors /// /// Creates a new `Plane` from a normal and an offset. The normal vector has to be `Vector3D`, `Array`s of 3 numbers, or an object with x, y, and z properties. /// ``` /// let plane1 = new UDB.Plane(new Vector3D(0.0, -0.707, 0.707), 32); /// let plane2 = new UDB.Plane([ 0.0, -0.707, 0.707 ], 32); /// ``` /// /// Normal vector of the plane /// Distance of the plane from the origin [UDBScriptSettings(MinVersion = 5)] public PlaneWrapper(object normal, double offset) { plane = new Plane(BuilderPlug.Me.GetVector3DFromObject(normal), offset); } private object bla() { return new Vector2D(1, 2); } /// /// Creates a new `Plane` from 3 points. The points have to be `Vector3D`, `Array`s of 3 numbers, or an object with x, y, and z properties. /// ``` /// let plane1 = new UDB.Plane(new Vector3D(0, 0, 0), new Vector3D(64, 0, 0), new Vector3D(64, 64, 32), true); /// let plane2 = new UDB.Plane([ 0, 0, 0 ], [ 64, 0, 0 ], [ 64, 64, 32 ], true); /// ``` /// /// First point /// Second point /// Thrid point /// `true` if plane is pointing up, `false` if pointing down [UDBScriptSettings(MinVersion = 5)] public PlaneWrapper(object p1, object p2, object p3, bool up) { //Vector2D a2 = new Vector2D(1, 2); Vector3D a3 = (Vector2D)bla(); try { Vector3D v1 = BuilderPlug.Me.GetVector3DFromObject(p1); Vector3D v2 = BuilderPlug.Me.GetVector3DFromObject(p2); Vector3D v3 = BuilderPlug.Me.GetVector3DFromObject(p3); plane = new Plane(v1, v2, v3, up); } catch (CantConvertToVectorException e) { throw BuilderPlug.Me.ScriptRunner.CreateRuntimeException(e.Message); } } #endregion #region ================== Methods /// /// Checks if the line between `from` and `to` intersects the plane. /// /// It returns an `Array`, where the first element is a `bool` vaue indicating if there is an intersector, and the second element is the position of the intersection on the line between the two points. /// /// ``` /// const plane = new UDB.Plane([ 0, 0, 1 ], 0); /// const [intersecting, u] = plane.getIntersection([0, 0, 32], [0, 0, -32]); /// UDB.log(`${intersecting} / ${u}`); // Prints "true / 0.5" /// ``` /// /// `Vector3D` of the start of the line /// `Vector3D` of the end of the line /// [UDBScriptSettings(MinVersion = 5)] public object[] getIntersection(object from, object to) { Vector3D f = BuilderPlug.Me.GetVector3DFromObject(from); Vector3D t = BuilderPlug.Me.GetVector3DFromObject(to); double u_ray = double.NaN; bool r = plane.GetIntersection(f, t, ref u_ray); return new object[] { r, u_ray }; } /// /// Computes the distance between the `Plane` and a point. The given point can be a `Vector3D` or an `Array` of three numbers. A result greater than 0 means the point is on the front of the plane, less than 0 means the point is behind the plane. /// ``` /// const plane = new UDB.Plane([ 0, 0, 0 ], [ 32, 0, 0 ], [ 32, 32, 16 ], true); /// UDB.log(plane.distance([ 16, 16, 32 ])); // Prints '21.466252583998' /// ``` /// /// Point to compute the distnace to /// Distance between the `Plane` and the point as `number` [UDBScriptSettings(MinVersion = 5)] public double distance(object p) { Vector3D v = BuilderPlug.Me.GetVector3DFromObject(p); return plane.Distance(v); } /// /// Returns the point that's closest to the given point on the `Plane`. The given point can be a `Vector3D` or an `Array` of three numbers. /// ``` /// const plane = new UDB.Plane([ 0, 0, 0 ], [ 32, 0, 0 ], [ 32, 32, 16 ], true); /// UDB.log(plane.closestOnPlane([ 16, 16, 32 ])); // Prints '16, 25.6, 12.8' /// ``` /// /// Point to get the closest position from /// Point as `Vector3D` on the plane closest to the given point [UDBScriptSettings(MinVersion = 5)] public Vector3DWrapper closestOnPlane(object p) { Vector3D v = BuilderPlug.Me.GetVector3DFromObject(p); return new Vector3DWrapper(plane.ClosestOnPlane(v)); } /// /// Returns the position on the z axis of the plane for the given point. The given point can be a `Vector2D` or an `Array` of two numbers. /// ``` /// const plane = new UDB.Plane([ 0, 0, 0 ], [ 32, 0, 0 ], [ 32, 32, 16 ], true); /// UDB.log(plane.getZ([ 16, 16 ])); // Prints '8' /// ``` /// /// Point to get the z position from /// [UDBScriptSettings(MinVersion = 5)] public double getZ(object p) { Vector2D v = BuilderPlug.Me.GetVector3DFromObject(p); return plane.GetZ(v); } public override bool Equals(object obj) { if (!(obj is PlaneWrapper other)) return false; return plane.Equals(other.plane); } public override int GetHashCode() { return plane.GetHashCode(); } #endregion #region ================== Statics public static bool operator ==(PlaneWrapper a, PlaneWrapper b) => a.plane == b.plane; public static bool operator !=(PlaneWrapper a, PlaneWrapper b) => a.plane != b.plane; #endregion } }