update
This commit is contained in:
283
Packages/com.arongranberg.astar/Core/Geometry/Int3.cs
Normal file
283
Packages/com.arongranberg.astar/Core/Geometry/Int3.cs
Normal file
@@ -0,0 +1,283 @@
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>
|
||||
/// Holds a coordinate in (integer) millimeters.
|
||||
///
|
||||
/// This is used for node coordinates and other things, primarily to avoid floating point calculations in the core pathfinding routines (as they can be slow and non-deterministic if you are not careful).
|
||||
///
|
||||
/// You can cast back and forth between Vector3s and Int3s like:
|
||||
/// <code>
|
||||
/// Int3 intPoint = (Int3)transform.position;
|
||||
/// transform.position = (Vector3)intPoint;
|
||||
/// </code>
|
||||
///
|
||||
/// During the cast, the coordinates will be rounded to the nearest millimeter.
|
||||
/// </summary>
|
||||
public struct Int3 : System.IEquatable<Int3> {
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
|
||||
//These should be set to the same value (only PrecisionFactor should be 1 divided by Precision)
|
||||
|
||||
/// <summary>
|
||||
/// Precision for the integer coordinates.
|
||||
/// One world unit is divided into [value] pieces. A value of 1000 would mean millimeter precision, a value of 1 would mean meter precision (assuming 1 world unit = 1 meter).
|
||||
/// This value affects the maximum coordinates for nodes as well as how large the cost values are for moving between two nodes.
|
||||
/// A higher value means that you also have to set all penalty values to a higher value to compensate since the normal cost of moving will be higher.
|
||||
/// </summary>
|
||||
public const int Precision = 1000;
|
||||
|
||||
/// <summary><see cref="Precision"/> as a float</summary>
|
||||
public const float FloatPrecision = 1000F;
|
||||
|
||||
/// <summary>1 divided by <see cref="Precision"/></summary>
|
||||
public const float PrecisionFactor = 0.001F;
|
||||
|
||||
public static Int3 zero => new Int3();
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public Int3 (Vector3 position) {
|
||||
x = (int)System.Math.Round(position.x*FloatPrecision);
|
||||
y = (int)System.Math.Round(position.y*FloatPrecision);
|
||||
z = (int)System.Math.Round(position.z*FloatPrecision);
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public Int3 (int _x, int _y, int _z) {
|
||||
x = _x;
|
||||
y = _y;
|
||||
z = _z;
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator == (Int3 lhs, Int3 rhs) {
|
||||
return lhs.x == rhs.x &&
|
||||
lhs.y == rhs.y &&
|
||||
lhs.z == rhs.z;
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator != (Int3 lhs, Int3 rhs) {
|
||||
return lhs.x != rhs.x ||
|
||||
lhs.y != rhs.y ||
|
||||
lhs.z != rhs.z;
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator Int3 (Vector3 ob) {
|
||||
return new Int3(
|
||||
(int)System.Math.Round(ob.x*FloatPrecision),
|
||||
(int)System.Math.Round(ob.y*FloatPrecision),
|
||||
(int)System.Math.Round(ob.z*FloatPrecision)
|
||||
);
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator Vector3 (Int3 ob) {
|
||||
return new Vector3(ob.x*PrecisionFactor, ob.y*PrecisionFactor, ob.z*PrecisionFactor);
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator float3 (Int3 ob) {
|
||||
return (float3)(int3)ob*PrecisionFactor;
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator int3 (Int3 ob) {
|
||||
return new int3(ob.x, ob.y, ob.z);
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static Int3 operator - (Int3 lhs, Int3 rhs) {
|
||||
lhs.x -= rhs.x;
|
||||
lhs.y -= rhs.y;
|
||||
lhs.z -= rhs.z;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static Int3 operator - (Int3 lhs) {
|
||||
lhs.x = -lhs.x;
|
||||
lhs.y = -lhs.y;
|
||||
lhs.z = -lhs.z;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static Int3 operator + (Int3 lhs, Int3 rhs) {
|
||||
lhs.x += rhs.x;
|
||||
lhs.y += rhs.y;
|
||||
lhs.z += rhs.z;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static Int3 operator * (Int3 lhs, int rhs) {
|
||||
lhs.x *= rhs;
|
||||
lhs.y *= rhs;
|
||||
lhs.z *= rhs;
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public static Int3 operator * (Int3 lhs, float rhs) {
|
||||
lhs.x = (int)System.Math.Round(lhs.x * rhs);
|
||||
lhs.y = (int)System.Math.Round(lhs.y * rhs);
|
||||
lhs.z = (int)System.Math.Round(lhs.z * rhs);
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public static Int3 operator * (Int3 lhs, double rhs) {
|
||||
lhs.x = (int)System.Math.Round(lhs.x * rhs);
|
||||
lhs.y = (int)System.Math.Round(lhs.y * rhs);
|
||||
lhs.z = (int)System.Math.Round(lhs.z * rhs);
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public static Int3 operator / (Int3 lhs, float rhs) {
|
||||
lhs.x = (int)System.Math.Round(lhs.x / rhs);
|
||||
lhs.y = (int)System.Math.Round(lhs.y / rhs);
|
||||
lhs.z = (int)System.Math.Round(lhs.z / rhs);
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public int this[int i] {
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
get {
|
||||
return i == 0 ? x : (i == 1 ? y : z);
|
||||
}
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
set {
|
||||
if (i == 0) x = value;
|
||||
else if (i == 1) y = value;
|
||||
else z = value;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static Int3 Max (Int3 lhs, Int3 rhs) {
|
||||
return new Int3(System.Math.Max(lhs.x, rhs.x), System.Math.Max(lhs.y, rhs.y), System.Math.Max(lhs.z, rhs.z));
|
||||
}
|
||||
|
||||
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
|
||||
public static Int3 Min (Int3 lhs, Int3 rhs) {
|
||||
return new Int3(System.Math.Min(lhs.x, rhs.x), System.Math.Min(lhs.y, rhs.y), System.Math.Min(lhs.z, rhs.z));
|
||||
}
|
||||
|
||||
/// <summary>Angle between the vectors in radians</summary>
|
||||
public static float Angle (Int3 lhs, Int3 rhs) {
|
||||
double cos = Dot(lhs, rhs)/ ((double)lhs.magnitude*(double)rhs.magnitude);
|
||||
|
||||
cos = cos < -1 ? -1 : (cos > 1 ? 1 : cos);
|
||||
return (float)System.Math.Acos(cos);
|
||||
}
|
||||
|
||||
public static int Dot (Int3 lhs, Int3 rhs) {
|
||||
return
|
||||
lhs.x * rhs.x +
|
||||
lhs.y * rhs.y +
|
||||
lhs.z * rhs.z;
|
||||
}
|
||||
|
||||
public static long DotLong (Int3 lhs, Int3 rhs) {
|
||||
return
|
||||
(long)lhs.x * (long)rhs.x +
|
||||
(long)lhs.y * (long)rhs.y +
|
||||
(long)lhs.z * (long)rhs.z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Normal in 2D space (XZ).
|
||||
/// Equivalent to Cross(this, Int3(0,1,0) )
|
||||
/// except that the Y coordinate is left unchanged with this operation.
|
||||
/// </summary>
|
||||
public Int3 Normal2D () {
|
||||
return new Int3(z, y, -x);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the magnitude of the vector. The magnitude is the 'length' of the vector from 0,0,0 to this point. Can be used for distance calculations:
|
||||
/// <code> Debug.Log ("Distance between 3,4,5 and 6,7,8 is: "+(new Int3(3,4,5) - new Int3(6,7,8)).magnitude); </code>
|
||||
/// </summary>
|
||||
public float magnitude {
|
||||
get {
|
||||
//It turns out that using doubles is just as fast as using ints with Mathf.Sqrt. And this can also handle larger numbers (possibly with small errors when using huge numbers)!
|
||||
|
||||
double _x = x;
|
||||
double _y = y;
|
||||
double _z = z;
|
||||
|
||||
return (float)System.Math.Sqrt(_x*_x+_y*_y+_z*_z);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Magnitude used for the cost between two nodes. The default cost between two nodes can be calculated like this:
|
||||
/// <code> int cost = (node1.position-node2.position).costMagnitude; </code>
|
||||
///
|
||||
/// This is simply the magnitude, rounded to the nearest integer
|
||||
/// </summary>
|
||||
public int costMagnitude {
|
||||
get {
|
||||
return (int)System.Math.Round(magnitude);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The squared magnitude of the vector</summary>
|
||||
public float sqrMagnitude {
|
||||
get {
|
||||
double _x = x;
|
||||
double _y = y;
|
||||
double _z = z;
|
||||
return (float)(_x*_x+_y*_y+_z*_z);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The squared magnitude of the vector</summary>
|
||||
public long sqrMagnitudeLong {
|
||||
get {
|
||||
long _x = x;
|
||||
long _y = y;
|
||||
long _z = z;
|
||||
return (_x*_x+_y*_y+_z*_z);
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator string (Int3 obj) {
|
||||
return obj.ToString();
|
||||
}
|
||||
|
||||
/// <summary>Returns a nicely formatted string representing the vector</summary>
|
||||
public override string ToString () {
|
||||
return "( "+x+", "+y+", "+z+")";
|
||||
}
|
||||
|
||||
public override bool Equals (System.Object obj) {
|
||||
if (!(obj is Int3)) return false;
|
||||
|
||||
var rhs = (Int3)obj;
|
||||
|
||||
return x == rhs.x &&
|
||||
y == rhs.y &&
|
||||
z == rhs.z;
|
||||
}
|
||||
|
||||
#region IEquatable implementation
|
||||
|
||||
public bool Equals (Int3 other) {
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public override int GetHashCode () {
|
||||
return x*73856093 ^ y*19349669 ^ z*83492791;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5826dd4a1809b448291582cd06deadc1
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
68
Packages/com.arongranberg.astar/Core/Geometry/IntBounds.cs
Normal file
68
Packages/com.arongranberg.astar/Core/Geometry/IntBounds.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace Pathfinding {
|
||||
/// <summary>
|
||||
/// Integer bounding box.
|
||||
/// Works almost like UnityEngine.BoundsInt but with a slightly nicer and more efficient api.
|
||||
///
|
||||
/// Uses an exclusive upper bound (max field).
|
||||
/// </summary>
|
||||
public struct IntBounds {
|
||||
public int3 min, max;
|
||||
|
||||
public IntBounds (int xmin, int ymin, int zmin, int xmax, int ymax, int zmax) {
|
||||
min = new int3(xmin, ymin, zmin);
|
||||
max = new int3(xmax, ymax, zmax);
|
||||
}
|
||||
|
||||
public IntBounds(int3 min, int3 max) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public int3 size => max - min;
|
||||
public int volume {
|
||||
get {
|
||||
var s = size;
|
||||
return s.x * s.y * s.z;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the intersection bounding box between the two bounds.
|
||||
/// The intersection bounds is the volume which is inside both bounds.
|
||||
/// If the rects do not have an intersection, an invalid rect is returned.
|
||||
/// See: IsValid
|
||||
/// </summary>
|
||||
public static IntBounds Intersection (IntBounds a, IntBounds b) {
|
||||
return new IntBounds(
|
||||
math.max(a.min, b.min),
|
||||
math.min(a.max, b.max)
|
||||
);
|
||||
}
|
||||
|
||||
public static bool Intersects (IntBounds a, IntBounds b) {
|
||||
return math.all(a.min< b.max & a.max > b.min);
|
||||
}
|
||||
|
||||
public IntBounds Offset (int3 offset) {
|
||||
return new IntBounds(min + offset, max + offset);
|
||||
}
|
||||
|
||||
public bool Contains (IntBounds other) {
|
||||
return math.all(other.min >= min & other.max <= max);
|
||||
}
|
||||
|
||||
public override string ToString() => "(" + min.ToString() + " <= x < " + max.ToString() + ")";
|
||||
public override bool Equals (object _b) {
|
||||
var b = (IntBounds)_b;
|
||||
return this == b;
|
||||
}
|
||||
|
||||
public override int GetHashCode() => min.GetHashCode() ^ (max.GetHashCode() << 2);
|
||||
|
||||
public static bool operator ==(IntBounds a, IntBounds b) => math.all(a.min == b.min & a.max == b.max);
|
||||
|
||||
public static bool operator !=(IntBounds a, IntBounds b) => !(a == b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd3215aff835b0e49925b61562b0a83e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aa02e060392acd24a985d56e2dfc2b52
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Andrzej Więckowski, Ph.D.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4777e4e500a981c4eac1a2b308e16b73
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,121 @@
|
||||
using Unity.Collections;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace andywiecko.BurstTriangulator {
|
||||
public struct Status {
|
||||
// Allow unused fields outside the editor
|
||||
#pragma warning disable 0414
|
||||
int value1, value2, value3, value4;
|
||||
#pragma warning restore 0414
|
||||
public TriangulatorErrorType type;
|
||||
|
||||
/// <summary>
|
||||
/// If true, then something went wrong during triangulation.
|
||||
/// Check <see cref="type"/> or <see cref="ToString"/> for more information.
|
||||
/// </summary>
|
||||
public bool IsError => type != TriangulatorErrorType.Ok;
|
||||
|
||||
public static Status Ok => new Status { type = TriangulatorErrorType.Ok };
|
||||
public static Status PositionsLengthLessThan3 (int length) => new Status { value1 = length, type = TriangulatorErrorType.PositionsLengthLessThan3 };
|
||||
public static Status PositionsMustBeFinite (int index) => new Status { value1 = index, type = TriangulatorErrorType.PositionsMustBeFinite };
|
||||
public static Status ConstraintsLengthNotDivisibleBy2 (int length) => new Status { value1 = length, type = TriangulatorErrorType.ConstraintsLengthNotDivisibleBy2 };
|
||||
public static Status DuplicatePosition (int index) => new Status { value1 = index, type = TriangulatorErrorType.DuplicatePosition };
|
||||
public static Status DuplicateConstraint (int index1, int index2) => new Status { value1 = index1, value2 = index2, type = TriangulatorErrorType.DuplicateConstraint };
|
||||
public static Status ConstraintOutOfBounds (int index, int2 constraint, int positionLength) => new Status { value1 = index, value2 = constraint.x, value3 = constraint.y, value4 = positionLength, type = TriangulatorErrorType.ConstraintOutOfBounds };
|
||||
public static Status ConstraintSelfLoop (int index, int2 constraint) => new Status { value1 = index, value2 = constraint.x, value3 = constraint.y, type = TriangulatorErrorType.ConstraintSelfLoop };
|
||||
public static Status ConstraintIntersection (int index1, int index2) => new Status { value1 = index1, value2 = index2, type = TriangulatorErrorType.ConstraintIntersection };
|
||||
public static Status DegenerateInput => new Status { type = TriangulatorErrorType.DegenerateInput };
|
||||
public static Status SloanMaxItersExceeded => new Status { type = TriangulatorErrorType.SloanMaxItersExceeded };
|
||||
public static Status IntegersDoNotSupportMeshRefinement => new Status { type = TriangulatorErrorType.IntegersDoNotSupportMeshRefinement };
|
||||
public static Status ConstraintArrayLengthMismatch (int constraintLength, int constraintTypeLength) => new Status { value1 = constraintLength, value2 = constraintTypeLength, type = TriangulatorErrorType.ConstraintArrayLengthMismatch };
|
||||
public static Status HoleMustBeFinite (int index) => new Status { value1 = index, type = TriangulatorErrorType.HoleMustBeFinite };
|
||||
public static Status RedudantHolesArray => new Status { type = TriangulatorErrorType.RedudantHolesArray };
|
||||
public static Status ConstraintEdgesMissingForAutoHolesAndBoundary => new Status { type = TriangulatorErrorType.ConstraintEdgesMissingForAutoHolesAndBoundary };
|
||||
public static Status ConstraintEdgesMissingForRestoreBoundary => new Status { type = TriangulatorErrorType.ConstraintEdgesMissingForRestoreBoundary };
|
||||
public static Status RefinementNotSupportedForCoordinateType => new Status { type = TriangulatorErrorType.RefinementNotSupportedForCoordinateType };
|
||||
public static Status SloanMaxItersMustBePositive (int sloanMaxIters) => new Status { type = TriangulatorErrorType.SloanMaxItersMustBePositive, value1 = sloanMaxIters };
|
||||
public static Status RefinementThresholdAreaMustBePositive => new Status { type = TriangulatorErrorType.RefinementThresholdAreaMustBePositive };
|
||||
public static Status RefinementThresholdAngleOutOfRange => new Status { type = TriangulatorErrorType.RefinementThresholdAngleOutOfRange };
|
||||
|
||||
#if UNITY_EDITOR
|
||||
internal FixedString512Bytes ToFixedString () {
|
||||
switch (type) {
|
||||
case TriangulatorErrorType.Ok:
|
||||
return "Ok";
|
||||
case TriangulatorErrorType.PositionsLengthLessThan3:
|
||||
return $"Position array's length must be greater than 3, but was {value1}.";
|
||||
case TriangulatorErrorType.PositionsMustBeFinite:
|
||||
return $"Positions must be finite, but position at index {value1} is not finite.";
|
||||
case TriangulatorErrorType.HoleMustBeFinite:
|
||||
return $"Hole must be finite, but hole at index {value1} is not finite.";
|
||||
case TriangulatorErrorType.ConstraintsLengthNotDivisibleBy2:
|
||||
return $"Input constraint array's length must be divisible by 2, but was {value1}.";
|
||||
case TriangulatorErrorType.DuplicatePosition:
|
||||
return $"Duplicate position at index {value1}.";
|
||||
case TriangulatorErrorType.DuplicateConstraint:
|
||||
return $"Constraints at indices {value1} and {value2} are equivalent.";
|
||||
case TriangulatorErrorType.ConstraintOutOfBounds:
|
||||
return $"Constraint[{value1}] = ({value2}, {value3}) is out of bounds of the positions array (length={value4}).";
|
||||
case TriangulatorErrorType.ConstraintSelfLoop:
|
||||
return $"Constraint[{value1}] = ({value2}, {value3}) is a self-loop.";
|
||||
case TriangulatorErrorType.ConstraintIntersection:
|
||||
return $"Constraints at indices {value1} and {value2} intersect.";
|
||||
case TriangulatorErrorType.DegenerateInput:
|
||||
return "Input is degenerate. It seems to consist only of duplicate or collinear points.";
|
||||
case TriangulatorErrorType.SloanMaxItersExceeded:
|
||||
return $"Sloan max iterations exceeded! This usually happens when the scale of the input positions is not uniform. Try to pre-process the input data or increase {nameof(TriangulationSettings.SloanMaxIters)}.";
|
||||
case TriangulatorErrorType.IntegersDoNotSupportMeshRefinement:
|
||||
return "Integer coordinates do not support mesh refinement. Please use float or double coordinates.";
|
||||
case TriangulatorErrorType.ConstraintArrayLengthMismatch:
|
||||
return $"Constraint type array's length ({value2}) must be exactly half of the constraint array's length ({value1}).";
|
||||
case TriangulatorErrorType.RedudantHolesArray:
|
||||
return "HoleSeeds buffer is provided, but ConstraintEdges is missing. Using holes requires constrained edges.";
|
||||
case TriangulatorErrorType.ConstraintEdgesMissingForAutoHolesAndBoundary:
|
||||
return "ConstraintEdges buffer is missing. This is required when using the AutoHolesAndBoundary settings.";
|
||||
case TriangulatorErrorType.ConstraintEdgesMissingForRestoreBoundary:
|
||||
return "ConstraintEdges buffer is missing. This is required when using the RestoreBoundary settings.";
|
||||
case TriangulatorErrorType.RefinementNotSupportedForCoordinateType:
|
||||
return "Mesh refinement is not supported for the coordinate type T.";
|
||||
case TriangulatorErrorType.SloanMaxItersMustBePositive:
|
||||
return $"Sloan max iterations must be positive. But found {value1}.";
|
||||
case TriangulatorErrorType.RefinementThresholdAreaMustBePositive:
|
||||
return "Refinement threshold area must be positive.";
|
||||
case TriangulatorErrorType.RefinementThresholdAngleOutOfRange:
|
||||
return "RefinementThresholdAngle must be in the range [0, π / 4]. Note that in the literature, the upper boundary for convergence is approximately π / 6.";
|
||||
default:
|
||||
return "Unknown error.";
|
||||
}
|
||||
}
|
||||
#else
|
||||
internal FixedString64Bytes ToFixedString() => "Triangulation error. Run in editor for more info.";
|
||||
#endif
|
||||
|
||||
public override string ToString () {
|
||||
return ToFixedString().ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public enum TriangulatorErrorType : byte {
|
||||
Ok,
|
||||
PositionsLengthLessThan3,
|
||||
PositionsMustBeFinite,
|
||||
ConstraintsLengthNotDivisibleBy2,
|
||||
DuplicatePosition,
|
||||
DuplicateConstraint,
|
||||
ConstraintOutOfBounds,
|
||||
ConstraintSelfLoop,
|
||||
ConstraintIntersection,
|
||||
DegenerateInput,
|
||||
SloanMaxItersExceeded,
|
||||
IntegersDoNotSupportMeshRefinement,
|
||||
ConstraintArrayLengthMismatch,
|
||||
HoleMustBeFinite,
|
||||
RedudantHolesArray,
|
||||
ConstraintEdgesMissingForAutoHolesAndBoundary,
|
||||
ConstraintEdgesMissingForRestoreBoundary,
|
||||
RefinementNotSupportedForCoordinateType,
|
||||
SloanMaxItersMustBePositive,
|
||||
RefinementThresholdAreaMustBePositive,
|
||||
RefinementThresholdAngleOutOfRange,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 44a41ae21b8b5a549a97fd31a287e96a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 134af43887144874baba950fcbbd99c1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,52 @@
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace andywiecko.BurstTriangulator {
|
||||
/// <summary>
|
||||
/// A signed 128-bit integer.
|
||||
/// </summary>
|
||||
struct I128 {
|
||||
ulong hi;
|
||||
ulong lo;
|
||||
|
||||
public bool IsNegative => (hi & 0x8000000000000000UL) != 0;
|
||||
|
||||
public I128(ulong hi, ulong lo) => (this.hi, this.lo) = (hi, lo);
|
||||
public static I128 operator + (I128 a, I128 b) {
|
||||
var lo = a.lo + b.lo;
|
||||
var hi = a.hi + b.hi + (lo < a.lo ? 1UL : 0);
|
||||
return new(hi, lo);
|
||||
}
|
||||
|
||||
public static I128 operator - (I128 a, I128 b) {
|
||||
var lo = a.lo - b.lo;
|
||||
var hi = a.hi - b.hi - (lo > a.lo ? 1UL : 0);
|
||||
return new(hi, lo);
|
||||
}
|
||||
|
||||
public static I128 operator -(I128 a) => new I128(~a.hi, ~a.lo) + new I128(0, 1);
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies two 64-bit signed integers, without any possibility of overflow.
|
||||
/// </summary>
|
||||
public static I128 Multiply (long slhs, long srhs) {
|
||||
// From https://stackoverflow.com/a/58381061
|
||||
var negative = (slhs < 0) ^ (srhs < 0);
|
||||
ulong lhs = (ulong)math.abs(slhs);
|
||||
ulong rhs = (ulong)math.abs(srhs);
|
||||
|
||||
// First calculate all of the cross products.
|
||||
ulong lo_lo = (lhs & 0xFFFFFFFFUL) * (rhs & 0xFFFFFFFFUL);
|
||||
ulong hi_lo = (lhs >> 32) * (rhs & 0xFFFFFFFFUL);
|
||||
ulong lo_hi = (lhs & 0xFFFFFFFFUL) * (rhs >> 32);
|
||||
ulong hi_hi = (lhs >> 32) * (rhs >> 32);
|
||||
|
||||
// Now add the products together. These will never overflow.
|
||||
ulong cross = (lo_lo >> 32) + (hi_lo & 0xFFFFFFFFUL) + lo_hi;
|
||||
ulong upper = (hi_lo >> 32) + (cross >> 32) + hi_hi;
|
||||
|
||||
var res = new I128(upper, (cross << 32) | (lo_lo & 0xFFFFFFFFUL));
|
||||
res = negative ? -res : res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 612e57e0b7ab4d2469aaa505f5124c1b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "andywiecko.BurstTriangulator",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"Unity.Burst",
|
||||
"Unity.Mathematics",
|
||||
"Unity.Collections",
|
||||
"Unity.Mathematics.FixedPoint"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": true,
|
||||
"overrideReferences": true,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": ["UNITY_2022_3_OR_NEWER", "MODULE_COLLECTIONS_2_2_0_OR_NEWER"],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.danielmansson.mathematics.fixedpoint",
|
||||
"expression": "0.1.0",
|
||||
"define": "UNITY_MATHEMATICS_FIXEDPOINT"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.collections",
|
||||
"expression": "2.2.0",
|
||||
"define": "MODULE_COLLECTIONS_2_2_0_OR_NEWER"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db11b4b5d7520bc479416b48c98206cb
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,11 @@
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
|
||||
namespace Pathfinding {
|
||||
public static class Vector2IntExtensions {
|
||||
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
|
||||
public static int2 ToInt2 (this Vector2Int v) {
|
||||
return new int2(v.x, v.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9425a80c48577a29197319636963481e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user