UltimateZoneBuilder/Source/Plugins/UDBScript/API/PlaneWrapper.cs
biwa 5b2b149b40
UDBScript version 5 (#819)
Improved UDBScript to version 5:

- Added Plane class
- Added BlockMap, BlockEntry, and BlackMapQueryResult classes
- Sector class
  - Added getLabelPositions method to get the position of sector labels (where tags, effects etc. are displayed)
- Added support for JavaScript BigInt for UDMF fields. This means it's not necessary anymore to use UniValue to assign integers to new UDMF fields. Instead it can be done like this: sector.fields.my_int_field = 1n;
- Added type information file (udbscript.d.ts)
2022-11-13 01:15:17 +01:00

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