mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-12-12 21:21:48 +00:00
286 lines
7.9 KiB
C#
286 lines
7.9 KiB
C#
|
#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<http://www.gnu.org/licenses/>.
|
|||
|
*/
|
|||
|
|
|||
|
#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
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The plane's normal vector.
|
|||
|
/// </summary>
|
|||
|
[UDBScriptSettings(MinVersion = 5)]
|
|||
|
public Vector3D normal
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return plane.Normal;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The distance of the plane along the normal vector.
|
|||
|
/// </summary>
|
|||
|
[UDBScriptSettings(MinVersion = 5)]
|
|||
|
public double offset
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return plane.Offset;
|
|||
|
}
|
|||
|
set
|
|||
|
{
|
|||
|
plane.Offset = value;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The `a` value of the plane equation. This is the `x` value of the normal vector.
|
|||
|
/// </summary>
|
|||
|
[UDBScriptSettings(MinVersion = 5)]
|
|||
|
public double a
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return plane.Normal.x;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The `b` value of the plane equation. This is the `y` value of the normal vector.
|
|||
|
/// </summary>
|
|||
|
[UDBScriptSettings(MinVersion = 5)]
|
|||
|
public double b
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return plane.Normal.y;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The `c` value of the plane equation. This is the `z` value of the normal vector.
|
|||
|
/// </summary>
|
|||
|
[UDBScriptSettings(MinVersion = 5)]
|
|||
|
public double c
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return plane.Normal.z;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// The `d` value of the plane equation. This is the same as the `offset` value.
|
|||
|
/// </summary>
|
|||
|
[UDBScriptSettings(MinVersion = 5)]
|
|||
|
public double d
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return plane.Offset;
|
|||
|
}
|
|||
|
set
|
|||
|
{
|
|||
|
plane.Offset = value;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region ================== Constructors
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 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);
|
|||
|
/// ```
|
|||
|
/// </summary>
|
|||
|
/// <param name="normal">Normal vector of the plane</param>
|
|||
|
/// <param name="offset">Distance of the plane from the origin</param>
|
|||
|
[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);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 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);
|
|||
|
/// ```
|
|||
|
/// </summary>
|
|||
|
/// <param name="p1">First point</param>
|
|||
|
/// <param name="p2">Second point</param>
|
|||
|
/// <param name="p3">Thrid point</param>
|
|||
|
/// <param name="up">`true` if plane is pointing up, `false` if pointing down</param>
|
|||
|
[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
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 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"
|
|||
|
/// ```
|
|||
|
/// </summary>
|
|||
|
/// <param name="from">`Vector3D` of the start of the line</param>
|
|||
|
/// <param name="to">`Vector3D` of the end of the line</param>
|
|||
|
/// <returns></returns>
|
|||
|
[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 };
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 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'
|
|||
|
/// ```
|
|||
|
/// </summary>
|
|||
|
/// <param name="p">Point to compute the distnace to</param>
|
|||
|
/// <returns>Distance between the `Plane` and the point as `number`</returns>
|
|||
|
[UDBScriptSettings(MinVersion = 5)]
|
|||
|
public double distance(object p)
|
|||
|
{
|
|||
|
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(p);
|
|||
|
|
|||
|
return plane.Distance(v);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 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'
|
|||
|
/// ```
|
|||
|
/// </summary>
|
|||
|
/// <param name="p">Point to get the closest position from</param>
|
|||
|
/// <returns>Point as `Vector3D` on the plane closest to the given point</returns>
|
|||
|
[UDBScriptSettings(MinVersion = 5)]
|
|||
|
public Vector3DWrapper closestOnPlane(object p)
|
|||
|
{
|
|||
|
Vector3D v = BuilderPlug.Me.GetVector3DFromObject(p);
|
|||
|
|
|||
|
return new Vector3DWrapper(plane.ClosestOnPlane(v));
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 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'
|
|||
|
/// ```
|
|||
|
/// </summary>
|
|||
|
/// <param name="p">Point to get the z position from</param>
|
|||
|
/// <returns></returns>
|
|||
|
[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
|
|||
|
}
|
|||
|
}
|