Update
This commit is contained in:
256
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/BinarySearch.cs
vendored
Normal file
256
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/BinarySearch.cs
vendored
Normal file
@@ -0,0 +1,256 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2015 Mikola Lysenko
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
using System;
|
||||
|
||||
namespace DA_Assets.SVGMeshUnity.Internals.Cdt2d
|
||||
{
|
||||
public static class BinarySearch
|
||||
{
|
||||
// https://github.com/mikolalysenko/binary-search-bounds
|
||||
|
||||
public interface IComparer<G, E>
|
||||
{
|
||||
int Compare(G x, E y);
|
||||
}
|
||||
|
||||
public static int GE<G, E>(G[] a, E y, IComparer<G, E> c, int l, int h)
|
||||
{
|
||||
var i = h + 1;
|
||||
while (l <= h)
|
||||
{
|
||||
var m = (int) (uint) (l + h) >> 1;
|
||||
var x = a[m];
|
||||
if (c.Compare(x, y) >= 0)
|
||||
{
|
||||
i = m;
|
||||
h = m - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = m + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int GE<G>(G[] a, G y, int l, int h) where G : IComparable<G>
|
||||
{
|
||||
var i = h + 1;
|
||||
while (l <= h)
|
||||
{
|
||||
var m = (int) (uint) (l + h) >> 1;
|
||||
var x = a[m];
|
||||
if (x.CompareTo(y) >= 0)
|
||||
{
|
||||
i = m;
|
||||
h = m - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = m + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int GT<G, E>(G[] a, E y, IComparer<G, E> c, int l, int h)
|
||||
{
|
||||
var i = h + 1;
|
||||
while (l <= h)
|
||||
{
|
||||
var m = (int) (uint) (l + h) >> 1;
|
||||
var x = a[m];
|
||||
if (c.Compare(x, y) > 0)
|
||||
{
|
||||
i = m;
|
||||
h = m - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = m + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int GT<G>(G[] a, G y, int l, int h) where G : IComparable<G>
|
||||
{
|
||||
var i = h + 1;
|
||||
while (l <= h)
|
||||
{
|
||||
var m = (int) (uint) (l + h) >> 1;
|
||||
var x = a[m];
|
||||
if (x.CompareTo(y) > 0)
|
||||
{
|
||||
i = m;
|
||||
h = m - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = m + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int LT<G, E>(G[] a, E y, IComparer<G, E> c, int l, int h)
|
||||
{
|
||||
var i = l - 1;
|
||||
while (l <= h)
|
||||
{
|
||||
var m = (int) (uint) (l + h) >> 1;
|
||||
var x = a[m];
|
||||
if (c.Compare(x, y) < 0)
|
||||
{
|
||||
i = m;
|
||||
l = m + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = m - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int LT<G>(G[] a, G y, int l, int h) where G : IComparable<G>
|
||||
{
|
||||
var i = l - 1;
|
||||
while (l <= h)
|
||||
{
|
||||
var m = (int) (uint) (l + h) >> 1;
|
||||
var x = a[m];
|
||||
if (x.CompareTo(y) < 0)
|
||||
{
|
||||
i = m;
|
||||
l = m + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = m - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int LE<G, E>(G[] a, E y, IComparer<G, E> c, int l, int h)
|
||||
{
|
||||
var i = l - 1;
|
||||
while (l <= h)
|
||||
{
|
||||
var m = (int) (uint) (l + h) >> 1;
|
||||
var x = a[m];
|
||||
if (c.Compare(x, y) <= 0)
|
||||
{
|
||||
i = m;
|
||||
l = m + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = m - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int LE<G>(G[] a, G y, int l, int h) where G : IComparable<G>
|
||||
{
|
||||
var i = l - 1;
|
||||
while (l <= h)
|
||||
{
|
||||
var m = (int) (uint) (l + h) >> 1;
|
||||
var x = a[m];
|
||||
if (x.CompareTo(y) <= 0)
|
||||
{
|
||||
i = m;
|
||||
l = m + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = m - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int EQ<G, E>(G[] a, E y, IComparer<G, E> c, int l, int h)
|
||||
{
|
||||
while (l <= h)
|
||||
{
|
||||
var m = (int) (uint) (l + h) >> 1;
|
||||
var x = a[m];
|
||||
var p = c.Compare(x, y);
|
||||
if (p == 0)
|
||||
{
|
||||
return m;
|
||||
}
|
||||
|
||||
if (p <= 0)
|
||||
{
|
||||
l = m + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = m - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static int EQ<G>(G[] a, G y, int l, int h) where G : IComparable<G>
|
||||
{
|
||||
while (l <= h)
|
||||
{
|
||||
var m = (int) (uint) (l + h) >> 1;
|
||||
var x = a[m];
|
||||
var p = x.CompareTo(y);
|
||||
if (p == 0)
|
||||
{
|
||||
return m;
|
||||
}
|
||||
|
||||
if (p <= 0)
|
||||
{
|
||||
l = m + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
h = m - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/BinarySearch.cs.meta
vendored
Normal file
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/BinarySearch.cs.meta
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ebc1111a29cd4d6c89f5458aa07da178
|
||||
timeCreated: 1519710584
|
||||
179
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/DelaunayRefine.cs
vendored
Normal file
179
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/DelaunayRefine.cs
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Yoshihiro Shindo
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DA_Assets.SVGMeshUnity.Internals.Cdt2d
|
||||
{
|
||||
public class DelaunayRefine
|
||||
{
|
||||
public WorkBufferPool WorkBufferPool;
|
||||
|
||||
//Assume edges are sorted lexicographically
|
||||
public void RefineTriangles(Triangles triangles)
|
||||
{
|
||||
var stack = WorkBufferPool.Get<Int2>();
|
||||
|
||||
var points = triangles.Vertices;
|
||||
var numPoints = points.Count;
|
||||
var stars = triangles.Stars;
|
||||
for (var a = 0; a < numPoints; ++a)
|
||||
{
|
||||
var star = stars[a];
|
||||
var starData = star.Data;
|
||||
var sl = star.UsedSize;
|
||||
for (var j = 0; j < sl; ++j)
|
||||
{
|
||||
var s = starData[j];
|
||||
var b = s.y;
|
||||
|
||||
//If order is not consistent, then skip edge
|
||||
if (b < a)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Check if edge is constrained
|
||||
if (triangles.IsConstraint(a, b))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Find opposite edge
|
||||
var x = s.x;
|
||||
var y = -1;
|
||||
for (var k = 0; k < sl; ++k)
|
||||
{
|
||||
if (starData[k].x == b)
|
||||
{
|
||||
y = starData[k].y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//If this is a boundary edge, don't flip it
|
||||
if (y < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//If edge is in circle, flip it
|
||||
if (Robust.InSphere(points[a], points[b], points[x], points[y]) < 0f)
|
||||
{
|
||||
var v = new Int2(a, b);
|
||||
stack.Push(ref v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (stack.UsedSize > 0)
|
||||
{
|
||||
var v = stack.Pop();
|
||||
var a = v.x;
|
||||
var b = v.y;
|
||||
|
||||
//Find opposite pairs
|
||||
var x = -1;
|
||||
var y = -1;
|
||||
var star = stars[a];
|
||||
var starData = star.Data;
|
||||
var sl = star.UsedSize;
|
||||
for (var i = 0; i < sl; ++i)
|
||||
{
|
||||
var s = starData[i].x;
|
||||
var t = starData[i].y;
|
||||
if (s == b)
|
||||
{
|
||||
y = t;
|
||||
}
|
||||
else if (t == b)
|
||||
{
|
||||
x = s;
|
||||
}
|
||||
}
|
||||
|
||||
//If x/y are both valid then skip edge
|
||||
if (x < 0 || y < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//If edge is now delaunay, then don't flip it
|
||||
if (Robust.InSphere(points[a], points[b], points[x], points[y]) >= 0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Flip the edge
|
||||
triangles.Flip(a, b);
|
||||
|
||||
//Test flipping neighboring edges
|
||||
TestFlip(points, triangles, stack, x, a, y);
|
||||
TestFlip(points, triangles, stack, a, y, x);
|
||||
TestFlip(points, triangles, stack, y, b, x);
|
||||
TestFlip(points, triangles, stack, b, x, y);
|
||||
}
|
||||
|
||||
WorkBufferPool.Release(ref stack);
|
||||
}
|
||||
|
||||
private void TestFlip(List<Vector3> points, Triangles triangles, WorkBuffer<Int2> stack, int a, int b, int x)
|
||||
{
|
||||
var y = triangles.Opposite(a, b);
|
||||
|
||||
//Test boundary edge
|
||||
if (y < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Swap edge if order flipped
|
||||
if (b < a)
|
||||
{
|
||||
var tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
//Test if edge is constrained
|
||||
if (triangles.IsConstraint(a, b))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Test if edge is delaunay
|
||||
if (Robust.InSphere(points[a], points[b], points[x], points[y]) < 0f)
|
||||
{
|
||||
var v = new Int2(a, b);
|
||||
stack.Push(ref v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/DelaunayRefine.cs.meta
vendored
Normal file
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/DelaunayRefine.cs.meta
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: daf4535a11864f7e9737bf2657ad86e1
|
||||
timeCreated: 1519795855
|
||||
362
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Filter.cs
vendored
Normal file
362
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Filter.cs
vendored
Normal file
@@ -0,0 +1,362 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Yoshihiro Shindo
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DA_Assets.SVGMeshUnity.Internals.Cdt2d
|
||||
{
|
||||
public class Filter
|
||||
{
|
||||
public int Target;
|
||||
public bool Infinity;
|
||||
|
||||
public WorkBufferPool WorkBufferPool;
|
||||
|
||||
public void Do(Triangles triangles, List<int> result)
|
||||
{
|
||||
using (var index = IndexCells(triangles))
|
||||
{
|
||||
var cellN = index.Cells.UsedSize;
|
||||
|
||||
if (result.Capacity < cellN * 3)
|
||||
{
|
||||
result.Capacity = cellN * 3;
|
||||
}
|
||||
|
||||
result.Clear();
|
||||
|
||||
if (Target == 0)
|
||||
{
|
||||
if (Infinity)
|
||||
{
|
||||
FillTriangles(index.Cells, result);
|
||||
FillTriangles(index.Boundary, result);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
FillTriangles(index.Cells, result);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var side = 1;
|
||||
var active = index.Active;
|
||||
var next = index.Next;
|
||||
var flags = index.Flags;
|
||||
var flagsData = flags.Data;
|
||||
var cells = index.Cells;
|
||||
var constraint = index.Constraint;
|
||||
var constraintData = constraint.Data;
|
||||
var neighbor = index.Neighbor;
|
||||
var neighborData = neighbor.Data;
|
||||
|
||||
while (active.UsedSize > 0 || next.UsedSize > 0)
|
||||
{
|
||||
while (active.UsedSize > 0)
|
||||
{
|
||||
var t = active.Pop();
|
||||
if (flagsData[t] == -side)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
flagsData[t] = side;
|
||||
for (var j = 0; j < 3; ++j)
|
||||
{
|
||||
var f = neighborData[3 * t + j];
|
||||
if (f >= 0 && flagsData[f] == 0)
|
||||
{
|
||||
if (constraintData[3 * t + j])
|
||||
{
|
||||
next.Push(ref f);
|
||||
}
|
||||
else
|
||||
{
|
||||
active.Push(ref f);
|
||||
flagsData[f] = side;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Swap arrays and loop
|
||||
var tmp = next;
|
||||
next = active;
|
||||
active = tmp;
|
||||
next.Clear();
|
||||
side = -side;
|
||||
}
|
||||
|
||||
FilterCells(cells, flags);
|
||||
FillTriangles(cells, result);
|
||||
|
||||
if (Infinity)
|
||||
{
|
||||
FillTriangles(index.Boundary, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FaceIndex : IDisposable
|
||||
{
|
||||
public FaceIndex(WorkBufferPool pool)
|
||||
{
|
||||
WorkBufferPool = pool;
|
||||
pool.Get(ref Cells);
|
||||
pool.Get(ref Neighbor);
|
||||
pool.Get(ref Constraint);
|
||||
pool.Get(ref Flags);
|
||||
pool.Get(ref Active);
|
||||
pool.Get(ref Next);
|
||||
pool.Get(ref Boundary);
|
||||
}
|
||||
|
||||
public WorkBuffer<Int3> Cells;
|
||||
public WorkBuffer<int> Neighbor;
|
||||
public WorkBuffer<bool> Constraint;
|
||||
public WorkBuffer<int> Flags;
|
||||
public WorkBuffer<int> Active;
|
||||
public WorkBuffer<int> Next;
|
||||
public WorkBuffer<Int3> Boundary;
|
||||
|
||||
private WorkBufferPool WorkBufferPool;
|
||||
private bool Disposed = false;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
private void Dispose(bool disposing)
|
||||
{
|
||||
if (Disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
WorkBufferPool.Release(ref Boundary);
|
||||
WorkBufferPool.Release(ref Next);
|
||||
WorkBufferPool.Release(ref Active);
|
||||
WorkBufferPool.Release(ref Flags);
|
||||
WorkBufferPool.Release(ref Constraint);
|
||||
WorkBufferPool.Release(ref Neighbor);
|
||||
WorkBufferPool.Release(ref Cells);
|
||||
}
|
||||
|
||||
Disposed = true;
|
||||
}
|
||||
|
||||
public void Dump()
|
||||
{
|
||||
Debug.LogFormat("Cells:\n{0}\n", Dump(Cells));
|
||||
Debug.LogFormat("Neighbor:\n{0}\n", Dump(Neighbor));
|
||||
Debug.LogFormat("Flags:\n{0}\n", Dump(Flags));
|
||||
Debug.LogFormat("Constraint:\n{0}\n", Dump(Constraint));
|
||||
Debug.LogFormat("Active:\n{0}\n", Dump(Active));
|
||||
Debug.LogFormat("Next:\n{0}\n", Dump(Next));
|
||||
Debug.LogFormat("Boundary:\n{0}\n", Dump(Boundary));
|
||||
}
|
||||
|
||||
private string Dump<T>(WorkBuffer<T> buf)
|
||||
{
|
||||
return buf.Data.Take(buf.UsedSize).Aggregate("", (_, s) => _ + " " + s.ToString() + ",\n");
|
||||
}
|
||||
}
|
||||
|
||||
private FaceIndex IndexCells(Triangles triangles)
|
||||
{
|
||||
var zero = 0;
|
||||
var fals = false;
|
||||
|
||||
var index = new FaceIndex(WorkBufferPool);
|
||||
|
||||
triangles.Fill(index.Cells);
|
||||
|
||||
//First get cells and canonicalize
|
||||
var cells = index.Cells;
|
||||
var nc = cells.UsedSize;
|
||||
var cellsData = cells.Data;
|
||||
for (var i = 0; i < nc; ++i)
|
||||
{
|
||||
var c = cellsData[i];
|
||||
var x = c.x;
|
||||
var y = c.y;
|
||||
var z = c.z;
|
||||
if (y < z)
|
||||
{
|
||||
if (y < x)
|
||||
{
|
||||
c.x = y;
|
||||
c.y = z;
|
||||
c.z = x;
|
||||
cellsData[i] = c;
|
||||
}
|
||||
}
|
||||
else if (z < x)
|
||||
{
|
||||
c.x = z;
|
||||
c.y = x;
|
||||
c.z = y;
|
||||
cellsData[i] = c;
|
||||
}
|
||||
}
|
||||
|
||||
WorkBuffer<Int3>.Sort(cells);
|
||||
|
||||
//Initialize flag array
|
||||
var flags = index.Flags;
|
||||
flags.Fill(ref zero, nc);
|
||||
|
||||
//Build neighbor index, initialize queues
|
||||
var active = index.Active;
|
||||
var next = index.Next;
|
||||
var neighbor = index.Neighbor;
|
||||
var constraint = index.Constraint;
|
||||
var boundary = index.Boundary;
|
||||
neighbor.Fill(ref zero, nc * 3);
|
||||
constraint.Fill(ref fals, nc * 3);
|
||||
var flagsData = flags.Data;
|
||||
var neighborData = neighbor.Data;
|
||||
var constraintData = constraint.Data;
|
||||
for (var i = 0; i < nc; ++i)
|
||||
{
|
||||
var c = cellsData[i];
|
||||
for (var j = 0; j < 3; ++j)
|
||||
{
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
|
||||
switch (j)
|
||||
{
|
||||
case 0:
|
||||
x = c.x;
|
||||
y = c.y;
|
||||
break;
|
||||
case 1:
|
||||
x = c.y;
|
||||
y = c.z;
|
||||
break;
|
||||
case 2:
|
||||
x = c.z;
|
||||
y = c.x;
|
||||
break;
|
||||
}
|
||||
|
||||
var a = neighborData[3 * i + j] = Locate(cells, y, x, triangles.Opposite(y, x));
|
||||
var b = constraintData[3 * i + j] = triangles.IsConstraint(x, y);
|
||||
if (a < 0)
|
||||
{
|
||||
if (b)
|
||||
{
|
||||
next.Push(ref i);
|
||||
}
|
||||
else
|
||||
{
|
||||
active.Push(ref i);
|
||||
flagsData[i] = 1;
|
||||
}
|
||||
|
||||
if (Infinity)
|
||||
{
|
||||
var v = new Int3(y, x, -1);
|
||||
boundary.Push(ref v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
private int Locate(WorkBuffer<Int3> cells, int a, int b, int c)
|
||||
{
|
||||
var x = a;
|
||||
var y = b;
|
||||
var z = c;
|
||||
if (b < c)
|
||||
{
|
||||
if (b < a)
|
||||
{
|
||||
x = b;
|
||||
y = c;
|
||||
z = a;
|
||||
}
|
||||
}
|
||||
else if (c < a)
|
||||
{
|
||||
x = c;
|
||||
y = a;
|
||||
z = b;
|
||||
}
|
||||
|
||||
if (x < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return BinarySearch.EQ(cells.Data, new Int3(x, y, z), 0, cells.UsedSize - 1);
|
||||
}
|
||||
|
||||
private void FilterCells(WorkBuffer<Int3> cells, WorkBuffer<int> flags)
|
||||
{
|
||||
var ptr = 0;
|
||||
var n = cells.UsedSize;
|
||||
var cellsData = cells.Data;
|
||||
var flagsData = flags.Data;
|
||||
for (var i = 0; i < n; ++i) {
|
||||
if(flagsData[i] == Target)
|
||||
{
|
||||
cellsData[ptr++] = cellsData[i];
|
||||
}
|
||||
}
|
||||
cells.RemoveLast(n - ptr);
|
||||
}
|
||||
|
||||
private void FillTriangles(WorkBuffer<Int3> from, List<int> to)
|
||||
{
|
||||
var n = from.UsedSize;
|
||||
|
||||
if (to.Capacity < n * 3)
|
||||
{
|
||||
to.Capacity = n * 3;
|
||||
}
|
||||
|
||||
var data = from.Data;
|
||||
for (var i = 0; i < n; ++i)
|
||||
{
|
||||
var v = data[i];
|
||||
to.Add(v.x);
|
||||
to.Add(v.y);
|
||||
to.Add(v.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Filter.cs.meta
vendored
Normal file
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Filter.cs.meta
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1384c72d4a744c9db5fbd24870a9c0e5
|
||||
timeCreated: 1519830352
|
||||
405
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/MonotoneTriangulation.cs
vendored
Normal file
405
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/MonotoneTriangulation.cs
vendored
Normal file
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Yoshihiro Shindo
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DA_Assets.SVGMeshUnity.Internals.Cdt2d
|
||||
{
|
||||
public class MonotoneTriangulation
|
||||
{
|
||||
private static readonly bool Verbose = false;
|
||||
|
||||
public WorkBufferPool WorkBufferPool;
|
||||
|
||||
private enum EventType
|
||||
{
|
||||
Point = 0,
|
||||
End = 1,
|
||||
Start = 2,
|
||||
}
|
||||
|
||||
//An event in the sweep line procedure
|
||||
private class Event : IComparable<Event>
|
||||
{
|
||||
public Vector2 A;
|
||||
public Vector2 B;
|
||||
public EventType Type;
|
||||
public int Index;
|
||||
|
||||
//This is used to compare events for the sweep line procedure
|
||||
// Points are:
|
||||
// 1. sorted lexicographically
|
||||
// 2. sorted by type (point < end < start)
|
||||
// 3. segments sorted by winding order
|
||||
// 4. sorted by index
|
||||
public int CompareTo(Event b)
|
||||
{
|
||||
var d = 0;
|
||||
|
||||
d = Sign(A.x - b.A.x);
|
||||
if (d != 0) return d;
|
||||
|
||||
d = Sign(A.y - b.A.y);
|
||||
if (d != 0) return d;
|
||||
|
||||
d = Type - b.Type;
|
||||
if (d != 0) return d;
|
||||
|
||||
if (Type != EventType.Point)
|
||||
{
|
||||
d = Sign(Robust.Orientation(A, B, b.B));
|
||||
if (d != 0) return d;
|
||||
}
|
||||
|
||||
return Index - b.Index;
|
||||
}
|
||||
}
|
||||
|
||||
//A partial convex hull fragment, made of two unimonotone polygons
|
||||
private class PartialHull
|
||||
{
|
||||
public Vector2 A;
|
||||
public Vector2 B;
|
||||
public int Index;
|
||||
public WorkBuffer<int> LowerIds = new WorkBuffer<int>(8);
|
||||
public WorkBuffer<int> UpperIds = new WorkBuffer<int>(8);
|
||||
}
|
||||
|
||||
public void BuildTriangles(MeshData data)
|
||||
{
|
||||
var numPoints = data.Vertices.Count;
|
||||
var numEdges = data.Edges.Count;
|
||||
|
||||
data.Triangles.Capacity = numPoints * 3;
|
||||
|
||||
var events = WorkBufferPool.Get<Event>();
|
||||
if (events.NewForClass == null)
|
||||
{
|
||||
events.NewForClass = () => new Event();
|
||||
}
|
||||
|
||||
//Create point events
|
||||
for (var i = 0; i < numPoints; ++i)
|
||||
{
|
||||
var e = events.Push();
|
||||
e.A = data.Vertices[i];
|
||||
e.B = Vector2.zero;
|
||||
e.Type = EventType.Point;
|
||||
e.Index = i;
|
||||
}
|
||||
|
||||
//Create edge events
|
||||
for(var i=0; i<numEdges; ++i)
|
||||
{
|
||||
var edge = data.Edges[i];
|
||||
var a = data.Vertices[edge.x];
|
||||
var b = data.Vertices[edge.y];
|
||||
if(a.x < b.x)
|
||||
{
|
||||
{
|
||||
var e = events.Push();
|
||||
e.A = a;
|
||||
e.B = b;
|
||||
e.Type = EventType.Start;
|
||||
e.Index = i;
|
||||
}
|
||||
{
|
||||
var e = events.Push();
|
||||
e.A = b;
|
||||
e.B = a;
|
||||
e.Type = EventType.End;
|
||||
e.Index = i;
|
||||
}
|
||||
}
|
||||
else if(a.x > b.x)
|
||||
{
|
||||
{
|
||||
var e = events.Push();
|
||||
e.A = b;
|
||||
e.B = a;
|
||||
e.Type = EventType.Start;
|
||||
e.Index = i;
|
||||
}
|
||||
{
|
||||
var e = events.Push();
|
||||
e.A = a;
|
||||
e.B = b;
|
||||
e.Type = EventType.End;
|
||||
e.Index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Sort events
|
||||
WorkBuffer<Event>.Sort(events);
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
DumpEvents(events);
|
||||
}
|
||||
|
||||
//Initialize hull
|
||||
var minX = events.Data[0].A.x - 1f;
|
||||
var hulls = WorkBufferPool.Get<PartialHull>();
|
||||
if (hulls.NewForClass == null)
|
||||
{
|
||||
hulls.NewForClass = () => new PartialHull();
|
||||
}
|
||||
var h = hulls.Push();
|
||||
h.A = new Vector2(minX, 1f);
|
||||
h.B = new Vector2(minX, 0f);
|
||||
h.Index = -1;
|
||||
h.LowerIds.Clear();
|
||||
h.UpperIds.Clear();
|
||||
|
||||
//Process events in order
|
||||
var numEvents = events.UsedSize;
|
||||
for (var i = 0; i < numEvents; ++i)
|
||||
{
|
||||
var e = events.Data[i];
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
Debug.Log("");
|
||||
Debug.Log(i);
|
||||
DumpEvent(e);
|
||||
}
|
||||
|
||||
switch (e.Type)
|
||||
{
|
||||
case EventType.Point:
|
||||
AddPoint(data.Triangles, hulls, data.Vertices, e.A, e.Index);
|
||||
break;
|
||||
case EventType.Start:
|
||||
SplitHulls(hulls, e);
|
||||
break;
|
||||
case EventType.End:
|
||||
MergeHulls(hulls, e);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
Debug.Log("");
|
||||
}
|
||||
}
|
||||
|
||||
WorkBufferPool.Release(ref hulls);
|
||||
WorkBufferPool.Release(ref events);
|
||||
}
|
||||
|
||||
private static int Sign(float n)
|
||||
{
|
||||
if (n < 0f)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n > 0f)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void AddPoint(List<int> cells, WorkBuffer<PartialHull> hulls, List<Vector3> points, Vector2 p, int idx)
|
||||
{
|
||||
var lo = BinarySearch.LT(hulls.Data, p, TestPoint.Default, 0, hulls.UsedSize - 1);
|
||||
var hi = BinarySearch.GT(hulls.Data, p, TestPoint.Default, 0, hulls.UsedSize - 1);
|
||||
for (var i = lo; i < hi; ++i)
|
||||
{
|
||||
var hull = hulls.Data[i];
|
||||
|
||||
//Insert p into lower hull
|
||||
{
|
||||
var lowerIds = hull.LowerIds;
|
||||
var m = lowerIds.UsedSize;
|
||||
var lowerIdsData = lowerIds.Data;
|
||||
while (m > 1 && Robust.Orientation(points[lowerIdsData[m - 2]], points[lowerIdsData[m - 1]], p) > 0f)
|
||||
{
|
||||
cells.Add(lowerIdsData[m - 1]);
|
||||
cells.Add(lowerIdsData[m - 2]);
|
||||
cells.Add(idx);
|
||||
m -= 1;
|
||||
}
|
||||
|
||||
if (m < lowerIds.UsedSize)
|
||||
{
|
||||
lowerIds.RemoveLast(lowerIds.UsedSize - m);
|
||||
}
|
||||
|
||||
lowerIds.Push(ref idx);
|
||||
}
|
||||
|
||||
//Insert p into upper hull
|
||||
{
|
||||
var upperIds = hull.UpperIds;
|
||||
var m = upperIds.UsedSize;
|
||||
var upperIdsData = upperIds.Data;
|
||||
while (m > 1 && Robust.Orientation(points[upperIdsData[m - 2]], points[upperIdsData[m - 1]], p) < 0f)
|
||||
{
|
||||
cells.Add(upperIdsData[m - 2]);
|
||||
cells.Add(upperIdsData[m - 1]);
|
||||
cells.Add(idx);
|
||||
m -= 1;
|
||||
}
|
||||
|
||||
if (m < upperIds.UsedSize)
|
||||
{
|
||||
upperIds.RemoveLast(upperIds.UsedSize - m);
|
||||
}
|
||||
|
||||
upperIds.Push(ref idx);
|
||||
}
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
Debug.Log("Add");
|
||||
DumpHulls(hulls);
|
||||
hulls.Dump();
|
||||
}
|
||||
}
|
||||
|
||||
private void SplitHulls(WorkBuffer<PartialHull> hulls, Event e)
|
||||
{
|
||||
var splitIdx = BinarySearch.LE(hulls.Data, e, FindSplit.Default, 0, hulls.UsedSize - 1);
|
||||
var hull = hulls.Data[splitIdx];
|
||||
var upperIds = hull.UpperIds;
|
||||
var x = upperIds.Data[upperIds.UsedSize - 1];
|
||||
hull.UpperIds = new WorkBuffer<int>(8);
|
||||
hull.UpperIds.Push(ref x);
|
||||
var h = hulls.Insert(splitIdx + 1);
|
||||
h.A = e.A;
|
||||
h.B = e.B;
|
||||
h.Index = e.Index;
|
||||
h.LowerIds.Clear();
|
||||
h.LowerIds.Push(ref x);
|
||||
h.UpperIds = upperIds;
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
Debug.Log("Split: " + splitIdx);
|
||||
DumpHulls(hulls);
|
||||
hulls.Dump();
|
||||
}
|
||||
}
|
||||
|
||||
private void MergeHulls(WorkBuffer<PartialHull> hulls, Event e)
|
||||
{
|
||||
//Swap pointers for merge search
|
||||
var tmp = e.A;
|
||||
e.A = e.B;
|
||||
e.B = tmp;
|
||||
var mergeIdx = BinarySearch.EQ(hulls.Data, e, FindSplit.Default, 0, hulls.UsedSize - 1);
|
||||
var upper = hulls.Data[mergeIdx];
|
||||
var lower = hulls.Data[mergeIdx - 1];
|
||||
lower.UpperIds = upper.UpperIds;
|
||||
hulls.RemoveAt(mergeIdx);
|
||||
|
||||
if (Verbose)
|
||||
{
|
||||
Debug.Log("Merge: " + mergeIdx);
|
||||
DumpHulls(hulls);
|
||||
hulls.Dump();
|
||||
}
|
||||
}
|
||||
|
||||
private class TestPoint : BinarySearch.IComparer<PartialHull, Vector2>
|
||||
{
|
||||
public static readonly TestPoint Default = new TestPoint();
|
||||
|
||||
public int Compare(PartialHull hull, Vector2 p)
|
||||
{
|
||||
return Sign(Robust.Orientation(hull.A, hull.B, p));
|
||||
}
|
||||
}
|
||||
|
||||
private class FindSplit : BinarySearch.IComparer<PartialHull, Event>
|
||||
{
|
||||
public static readonly FindSplit Default = new FindSplit();
|
||||
|
||||
public int Compare(PartialHull hull, Event edge)
|
||||
{
|
||||
var d = 0;
|
||||
|
||||
if (hull.A.x < edge.A.x)
|
||||
{
|
||||
d = Sign(Robust.Orientation(hull.A, hull.B, edge.A));
|
||||
} else
|
||||
{
|
||||
d = Sign(Robust.Orientation(edge.B, edge.A, hull.A));
|
||||
}
|
||||
|
||||
if (d != 0) return d;
|
||||
|
||||
if (edge.B.x < hull.B.x)
|
||||
{
|
||||
d = Sign(Robust.Orientation(hull.A, hull.B, edge.B));
|
||||
} else
|
||||
{
|
||||
d = Sign(Robust.Orientation(edge.B, edge.A, hull.B));
|
||||
}
|
||||
|
||||
if (d != 0) return d;
|
||||
|
||||
return hull.Index - edge.Index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Debug
|
||||
|
||||
private void DumpEvent(Event _)
|
||||
{
|
||||
Debug.Log(string.Format("{{ a: {0}, b: {1}, type: {2}, idx: {3} }}", _.A, _.B, _.Type, _.Index));
|
||||
}
|
||||
|
||||
private void DumpEvents(WorkBuffer<Event> events)
|
||||
{
|
||||
Debug.Log(events.Data.Take(events.UsedSize)
|
||||
.Select(_ => string.Format("{{ a: {0}, b: {1}, type: {2}, idx: {3} }}", _.A, _.B, _.Type, _.Index))
|
||||
.Aggregate("", (_, s) => _ + s + "\n"));
|
||||
}
|
||||
|
||||
private void DumpHulls(WorkBuffer<PartialHull> hulls)
|
||||
{
|
||||
Debug.Log(hulls.Data.Take(hulls.UsedSize)
|
||||
.Select(_ => string.Format("{{ a: {0}, b: {1}, idx: {2}, lowerIds: [ {3} ], upperIds: [ {4} ] }}", _.A, _.B, _.Index, ToString(_.LowerIds), ToString(_.UpperIds)))
|
||||
.Aggregate("", (_, s) => _ + s + "\n"));
|
||||
}
|
||||
|
||||
private string ToString(WorkBuffer<int> list)
|
||||
{
|
||||
return string.Join(", ", list.Data.Take(list.UsedSize).Select(_ => _.ToString()).ToArray());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3f866907d0c43a086ba61429b3d2b8a
|
||||
timeCreated: 1519699803
|
||||
930
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Robust.cs
vendored
Normal file
930
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Robust.cs
vendored
Normal file
@@ -0,0 +1,930 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Mikola Lysenko
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Mikola Lysenko
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace DA_Assets.SVGMeshUnity.Internals.Cdt2d
|
||||
{
|
||||
public static class Robust
|
||||
{
|
||||
// https://github.com/mikolalysenko/robust-orientation
|
||||
// https://github.com/mikolalysenko/robust-in-sphere
|
||||
// https://github.com/mikolalysenko/robust-sum
|
||||
// https://github.com/mikolalysenko/robust-subtract
|
||||
// https://github.com/mikolalysenko/robust-scale
|
||||
// https://github.com/mikolalysenko/two-product
|
||||
// https://github.com/mikolalysenko/two-sum
|
||||
|
||||
private static readonly float Epsilon = 1.1102230246251565e-16f;
|
||||
private static readonly float Errbound3 = (3.0f + 16.0f * Epsilon) * Epsilon;
|
||||
|
||||
private static readonly float Splitter = +(Mathf.Pow(2f, 27f) + 1.0f);
|
||||
|
||||
private static float[][] BufferPool = new float[32][];
|
||||
private static int BufferPoolSize = 0;
|
||||
|
||||
private static float[] GetTemporaryBuffer()
|
||||
{
|
||||
if (BufferPoolSize > 0)
|
||||
{
|
||||
return BufferPool[--BufferPoolSize];
|
||||
}
|
||||
return new float[16];
|
||||
}
|
||||
|
||||
private static void ReleaseTemporaryBuffer(ref float[] buf)
|
||||
{
|
||||
if (BufferPool.Length == BufferPoolSize)
|
||||
{
|
||||
var newBufferPool = new float[BufferPool.Length + 32][];
|
||||
BufferPool.CopyTo(newBufferPool, 0);
|
||||
BufferPool = newBufferPool;
|
||||
}
|
||||
|
||||
BufferPool[BufferPoolSize++] = buf;
|
||||
buf = null;
|
||||
}
|
||||
|
||||
public static float Orientation(Vector2 a, Vector2 b, Vector2 c)
|
||||
{
|
||||
var l = (a.y - c.y) * (b.x - c.x);
|
||||
var r = (a.x - c.x) * (b.y - c.y);
|
||||
var det = l - r;
|
||||
var s = 0f;
|
||||
if (l > 0)
|
||||
{
|
||||
if (r <= 0)
|
||||
{
|
||||
return det;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = l + r;
|
||||
}
|
||||
}
|
||||
else if (l < 0)
|
||||
{
|
||||
if (r >= 0)
|
||||
{
|
||||
return det;
|
||||
}
|
||||
else
|
||||
{
|
||||
s = -(l + r);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return det;
|
||||
}
|
||||
|
||||
var tol = Errbound3 * s;
|
||||
if (det >= tol || det <= -tol)
|
||||
{
|
||||
return det;
|
||||
}
|
||||
|
||||
var m0 = a;
|
||||
var m1 = b;
|
||||
var m2 = c;
|
||||
|
||||
var sL = GetTemporaryBuffer();
|
||||
var sR = GetTemporaryBuffer();
|
||||
|
||||
var p = GetTemporaryBuffer();
|
||||
var n = GetTemporaryBuffer();
|
||||
var d = GetTemporaryBuffer();
|
||||
|
||||
var pN = 0;
|
||||
var nN = 0;
|
||||
var dN = 0;
|
||||
|
||||
var pL = GetTemporaryBuffer();
|
||||
var pR = GetTemporaryBuffer();
|
||||
|
||||
var pLN = 0;
|
||||
var pRN = 0;
|
||||
|
||||
TwoProd( m1.y, m2.x, sL);
|
||||
TwoProd(-m2.y, m1.x, sR);
|
||||
Sum(sL, 2, sR, 2, pL, out pLN);
|
||||
|
||||
TwoProd( m0.y, m1.x, sL);
|
||||
TwoProd(-m1.y, m0.x, sR);
|
||||
Sum(sL, 2, sR, 2, pR, out pRN);
|
||||
|
||||
Sum(pL, pLN, pR, pRN, p, out pN);
|
||||
|
||||
ReleaseTemporaryBuffer(ref pL);
|
||||
ReleaseTemporaryBuffer(ref pR);
|
||||
|
||||
TwoProd( m0.y, m2.x, sL);
|
||||
TwoProd(-m2.y, m0.x, sR);
|
||||
Sum(sL, 2, sR, 2, n, out nN);
|
||||
|
||||
ReleaseTemporaryBuffer(ref sL);
|
||||
ReleaseTemporaryBuffer(ref sR);
|
||||
|
||||
Sub(p, pN, n, nN, d, out dN);
|
||||
|
||||
var result = d[dN - 1];
|
||||
|
||||
ReleaseTemporaryBuffer(ref p);
|
||||
ReleaseTemporaryBuffer(ref n);
|
||||
ReleaseTemporaryBuffer(ref d);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static float InSphere(Vector2 m0, Vector2 m1, Vector2 m2, Vector2 m3)
|
||||
{
|
||||
var w = GetTemporaryBuffer();
|
||||
var wL = GetTemporaryBuffer();
|
||||
var wR = GetTemporaryBuffer();
|
||||
|
||||
var wN = 0;
|
||||
|
||||
var w0m1 = GetTemporaryBuffer();
|
||||
var w0m2 = GetTemporaryBuffer();
|
||||
var w0m3 = GetTemporaryBuffer();
|
||||
var w1m0 = GetTemporaryBuffer();
|
||||
var w1m2 = GetTemporaryBuffer();
|
||||
var w1m3 = GetTemporaryBuffer();
|
||||
var w2m0 = GetTemporaryBuffer();
|
||||
var w2m1 = GetTemporaryBuffer();
|
||||
var w2m3 = GetTemporaryBuffer();
|
||||
var w3m0 = GetTemporaryBuffer();
|
||||
var w3m1 = GetTemporaryBuffer();
|
||||
var w3m2 = GetTemporaryBuffer();
|
||||
|
||||
var w0m1N = 0;
|
||||
var w0m2N = 0;
|
||||
var w0m3N = 0;
|
||||
var w1m0N = 0;
|
||||
var w1m2N = 0;
|
||||
var w1m3N = 0;
|
||||
var w2m0N = 0;
|
||||
var w2m1N = 0;
|
||||
var w2m3N = 0;
|
||||
var w3m0N = 0;
|
||||
var w3m1N = 0;
|
||||
var w3m2N = 0;
|
||||
|
||||
TwoProd(m0[0], m0[0], wL);
|
||||
TwoProd(m0[1], m0[1], wR);
|
||||
Sum(wL, 2, wR, 2, w, out wN);
|
||||
Scale(w, wN, m1[0], w0m1, out w0m1N);
|
||||
Scale(w, wN, m2[0], w0m2, out w0m2N);
|
||||
Scale(w, wN, m3[0], w0m3, out w0m3N);
|
||||
|
||||
TwoProd(m1[0], m1[0], wL);
|
||||
TwoProd(m1[1], m1[1], wR);
|
||||
Sum(wL, 2, wR, 2, w, out wN);
|
||||
Scale(w, wN, m0[0], w1m0, out w1m0N);
|
||||
Scale(w, wN, m2[0], w1m2, out w1m2N);
|
||||
Scale(w, wN, m3[0], w1m3, out w1m3N);
|
||||
|
||||
TwoProd(m2[0], m2[0], wL);
|
||||
TwoProd(m2[1], m2[1], wR);
|
||||
Sum(wL, 2, wR, 2, w, out wN);
|
||||
Scale(w, wN, m0[0], w2m0, out w2m0N);
|
||||
Scale(w, wN, m1[0], w2m1, out w2m1N);
|
||||
Scale(w, wN, m3[0], w2m3, out w2m3N);
|
||||
|
||||
TwoProd(m3[0], m3[0], wL);
|
||||
TwoProd(m3[1], m3[1], wR);
|
||||
Sum(wL, 2, wR, 2, w, out wN);
|
||||
Scale(w, wN, m0[0], w3m0, out w3m0N);
|
||||
Scale(w, wN, m1[0], w3m1, out w3m1N);
|
||||
Scale(w, wN, m2[0], w3m2, out w3m2N);
|
||||
|
||||
ReleaseTemporaryBuffer(ref wL);
|
||||
ReleaseTemporaryBuffer(ref wR);
|
||||
ReleaseTemporaryBuffer(ref w);
|
||||
|
||||
var p = GetTemporaryBuffer();
|
||||
var n = GetTemporaryBuffer();
|
||||
var d = GetTemporaryBuffer();
|
||||
|
||||
var pN = 0;
|
||||
var nN = 0;
|
||||
var dN = 0;
|
||||
|
||||
var pL = GetTemporaryBuffer();
|
||||
var pR = GetTemporaryBuffer();
|
||||
|
||||
var pLN = 0;
|
||||
var pRN = 0;
|
||||
|
||||
var pLLL = GetTemporaryBuffer();
|
||||
var pLL = GetTemporaryBuffer();
|
||||
var pLRLL = GetTemporaryBuffer();
|
||||
var pLRL = GetTemporaryBuffer();
|
||||
var pLRRL = GetTemporaryBuffer();
|
||||
var pLRR = GetTemporaryBuffer();
|
||||
var pLR = GetTemporaryBuffer();
|
||||
|
||||
var pLLLN = 0;
|
||||
var pLLN = 0;
|
||||
var pLRLLN = 0;
|
||||
var pLRLN = 0;
|
||||
var pLRRLN = 0;
|
||||
var pLRRN = 0;
|
||||
var pLRN = 0;
|
||||
|
||||
Sub(w3m2, w3m2N, w2m3, w2m3N, pLLL, out pLLLN);
|
||||
Scale(pLLL, pLLLN, m1[1], pLL, out pLLN);
|
||||
Sub(w3m1, w3m1N, w1m3, w1m3N, pLRLL, out pLRLLN);
|
||||
Scale(pLRLL, pLRLLN, -m2[1], pLRL, out pLRLN);
|
||||
Sub(w2m1, w2m1N, w1m2, w1m2N, pLRRL, out pLRRLN);
|
||||
Scale(pLRRL, pLRRLN, m3[1], pLRR, out pLRRN);
|
||||
Sum(pLRL, pLRLN, pLRR, pLRRN, pLR, out pLRN);
|
||||
Sum(pLL, pLLN, pLR, pLRN, pL, out pLN);
|
||||
|
||||
ReleaseTemporaryBuffer(ref pLLL);
|
||||
ReleaseTemporaryBuffer(ref pLL);
|
||||
ReleaseTemporaryBuffer(ref pLRLL);
|
||||
ReleaseTemporaryBuffer(ref pLRL);
|
||||
ReleaseTemporaryBuffer(ref pLRRL);
|
||||
ReleaseTemporaryBuffer(ref pLRR);
|
||||
ReleaseTemporaryBuffer(ref pLR);
|
||||
|
||||
var pRLL = GetTemporaryBuffer();
|
||||
var pRL = GetTemporaryBuffer();
|
||||
var pRRLL = GetTemporaryBuffer();
|
||||
var pRRL = GetTemporaryBuffer();
|
||||
var pRRRL = GetTemporaryBuffer();
|
||||
var pRRR = GetTemporaryBuffer();
|
||||
var pRR = GetTemporaryBuffer();
|
||||
|
||||
var pRLLN = 0;
|
||||
var pRLN = 0;
|
||||
var pRRLLN = 0;
|
||||
var pRRLN = 0;
|
||||
var pRRRLN = 0;
|
||||
var pRRRN = 0;
|
||||
var pRRN = 0;
|
||||
|
||||
Sub(w3m1, w3m1N, w1m3, w1m3N, pRLL, out pRLLN);
|
||||
Scale(pRLL, pRLLN, m0[1], pRL, out pRLN);
|
||||
Sub(w3m0, w3m0N, w0m3, w0m3N, pRRLL, out pRRLLN);
|
||||
Scale(pRRLL, pRRLLN, -m1[1], pRRL, out pRRLN);
|
||||
Sub(w1m0, w1m0N, w0m1, w0m1N, pRRRL, out pRRRLN);
|
||||
Scale(pRRRL, pRRRLN, m3[1], pRRR, out pRRRN);
|
||||
Sum(pRRL, pRRLN, pRRR, pRRRN, pRR, out pRRN);
|
||||
Sum(pRL, pRLN, pRR, pRRN, pR, out pRN);
|
||||
|
||||
ReleaseTemporaryBuffer(ref pRLL);
|
||||
ReleaseTemporaryBuffer(ref pRL);
|
||||
ReleaseTemporaryBuffer(ref pRRLL);
|
||||
ReleaseTemporaryBuffer(ref pRRL);
|
||||
ReleaseTemporaryBuffer(ref pRRRL);
|
||||
ReleaseTemporaryBuffer(ref pRRR);
|
||||
ReleaseTemporaryBuffer(ref pRR);
|
||||
|
||||
Sum(pL, pLN, pR, pRN, p, out pN);
|
||||
|
||||
ReleaseTemporaryBuffer(ref pL);
|
||||
ReleaseTemporaryBuffer(ref pR);
|
||||
|
||||
var nL = GetTemporaryBuffer();
|
||||
var nR = GetTemporaryBuffer();
|
||||
|
||||
var nLN = 0;
|
||||
var nRN = 0;
|
||||
|
||||
var nLLL = GetTemporaryBuffer();
|
||||
var nLL = GetTemporaryBuffer();
|
||||
var nLRLL = GetTemporaryBuffer();
|
||||
var nLRL = GetTemporaryBuffer();
|
||||
var nLRRL = GetTemporaryBuffer();
|
||||
var nLRR = GetTemporaryBuffer();
|
||||
var nLR = GetTemporaryBuffer();
|
||||
|
||||
var nLLLN = 0;
|
||||
var nLLN = 0;
|
||||
var nLRLLN = 0;
|
||||
var nLRLN = 0;
|
||||
var nLRRLN = 0;
|
||||
var nLRRN = 0;
|
||||
var nLRN = 0;
|
||||
|
||||
Sub(w3m2, w3m2N, w2m3, w2m3N, nLLL, out nLLLN);
|
||||
Scale(nLLL, nLLLN, m0[1], nLL, out nLLN);
|
||||
Sub(w3m0, w3m0N, w0m3, w0m3N, nLRLL, out nLRLLN);
|
||||
Scale(nLRLL, nLRLLN, -m2[1], nLRL, out nLRLN);
|
||||
Sub(w2m0, w2m0N, w0m2, w0m2N, nLRRL, out nLRRLN);
|
||||
Scale(nLRRL, nLRRLN, m3[1], nLRR, out nLRRN);
|
||||
Sum(nLRL, nLRLN, nLRR, nLRRN, nLR, out nLRN);
|
||||
Sum(nLL, nLLN, nLR, nLRN, nL, out nLN);
|
||||
|
||||
ReleaseTemporaryBuffer(ref nLLL);
|
||||
ReleaseTemporaryBuffer(ref nLL);
|
||||
ReleaseTemporaryBuffer(ref nLRLL);
|
||||
ReleaseTemporaryBuffer(ref nLRL);
|
||||
ReleaseTemporaryBuffer(ref nLRRL);
|
||||
ReleaseTemporaryBuffer(ref nLRR);
|
||||
ReleaseTemporaryBuffer(ref nLR);
|
||||
|
||||
var nRLL = GetTemporaryBuffer();
|
||||
var nRL = GetTemporaryBuffer();
|
||||
var nRRLL = GetTemporaryBuffer();
|
||||
var nRRL = GetTemporaryBuffer();
|
||||
var nRRRL = GetTemporaryBuffer();
|
||||
var nRRR = GetTemporaryBuffer();
|
||||
var nRR = GetTemporaryBuffer();
|
||||
|
||||
var nRLLN = 0;
|
||||
var nRLN = 0;
|
||||
var nRRLLN = 0;
|
||||
var nRRLN = 0;
|
||||
var nRRRLN = 0;
|
||||
var nRRRN = 0;
|
||||
var nRRN = 0;
|
||||
|
||||
Sub(w2m1, w2m1N, w1m2, w1m2N, nRLL, out nRLLN);
|
||||
Scale(nRLL, nRLLN, m0[1], nRL, out nRLN);
|
||||
Sub(w2m0, w2m0N, w0m2, w0m2N, nRRLL, out nRRLLN);
|
||||
Scale(nRRLL, nRRLLN, -m1[1], nRRL, out nRRLN);
|
||||
Sub(w1m0, w1m0N, w0m1, w0m1N, nRRRL, out nRRRLN);
|
||||
Scale(nRRRL, nRRRLN, m2[1], nRRR, out nRRRN);
|
||||
Sum(nRRL, nRRLN, nRRR, nRRRN, nRR, out nRRN);
|
||||
Sum(nRL, nRLN, nRR, nRRN, nR, out nRN);
|
||||
|
||||
ReleaseTemporaryBuffer(ref nRLL);
|
||||
ReleaseTemporaryBuffer(ref nRL);
|
||||
ReleaseTemporaryBuffer(ref nRRLL);
|
||||
ReleaseTemporaryBuffer(ref nRRL);
|
||||
ReleaseTemporaryBuffer(ref nRRRL);
|
||||
ReleaseTemporaryBuffer(ref nRRR);
|
||||
ReleaseTemporaryBuffer(ref nRR);
|
||||
|
||||
Sum(nL, nLN, nR, nRN, n, out nN);
|
||||
|
||||
ReleaseTemporaryBuffer(ref nL);
|
||||
ReleaseTemporaryBuffer(ref nR);
|
||||
|
||||
ReleaseTemporaryBuffer(ref w0m1);
|
||||
ReleaseTemporaryBuffer(ref w0m2);
|
||||
ReleaseTemporaryBuffer(ref w0m3);
|
||||
ReleaseTemporaryBuffer(ref w1m0);
|
||||
ReleaseTemporaryBuffer(ref w1m2);
|
||||
ReleaseTemporaryBuffer(ref w1m3);
|
||||
ReleaseTemporaryBuffer(ref w2m0);
|
||||
ReleaseTemporaryBuffer(ref w2m1);
|
||||
ReleaseTemporaryBuffer(ref w2m3);
|
||||
ReleaseTemporaryBuffer(ref w3m0);
|
||||
ReleaseTemporaryBuffer(ref w3m1);
|
||||
ReleaseTemporaryBuffer(ref w3m2);
|
||||
|
||||
Sub(p, pN, n, nN, d, out dN);
|
||||
|
||||
var result = d[dN - 1];
|
||||
|
||||
ReleaseTemporaryBuffer(ref p);
|
||||
ReleaseTemporaryBuffer(ref n);
|
||||
ReleaseTemporaryBuffer(ref d);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void TwoProd(float a, float b, float[] result)
|
||||
{
|
||||
var x = a * b;
|
||||
|
||||
var c = Splitter * a;
|
||||
var abig = c - a;
|
||||
var ahi = c - abig;
|
||||
var alo = a - ahi;
|
||||
|
||||
var d = Splitter * b;
|
||||
var bbig = d - b;
|
||||
var bhi = d - bbig;
|
||||
var blo = b - bhi;
|
||||
|
||||
var err1 = x - (ahi * bhi);
|
||||
var err2 = err1 - (alo * bhi);
|
||||
var err3 = err2 - (ahi * blo);
|
||||
|
||||
var y = alo * blo - err3;
|
||||
|
||||
result[0] = y;
|
||||
result[1] = x;
|
||||
}
|
||||
|
||||
private static void TwoSum(float a, float b, float[] result)
|
||||
{
|
||||
var x = a + b;
|
||||
var bv = x - a;
|
||||
var av = x - bv;
|
||||
var br = b - bv;
|
||||
var ar = a - av;
|
||||
|
||||
result[0] = ar + br;
|
||||
result[1] = x;
|
||||
}
|
||||
|
||||
private static void Sum(float[] e, int eN, float[] f, int fN, float[] result, out int resultN)
|
||||
{
|
||||
if(eN == 1 && fN == 1)
|
||||
{
|
||||
ScalarScalar(e[0], f[0], result, out resultN);
|
||||
return;
|
||||
}
|
||||
|
||||
resultN = 0;
|
||||
|
||||
var eptr = 0;
|
||||
var fptr = 0;
|
||||
var ei = e[eptr];
|
||||
var ea = Mathf.Abs(ei);
|
||||
var fi = f[fptr];
|
||||
var fa = Mathf.Abs(fi);
|
||||
var a = 0f;
|
||||
var b = 0f;
|
||||
if (ea < fa)
|
||||
{
|
||||
b = ei;
|
||||
eptr += 1;
|
||||
if (eptr < eN)
|
||||
{
|
||||
ei = e[eptr];
|
||||
ea = Mathf.Abs(ei);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b = fi;
|
||||
fptr += 1;
|
||||
if (fptr < fN)
|
||||
{
|
||||
fi = f[fptr];
|
||||
fa = Mathf.Abs(fi);
|
||||
}
|
||||
}
|
||||
|
||||
if ((eptr < eN && ea < fa) || (fptr >= fN))
|
||||
{
|
||||
a = ei;
|
||||
eptr += 1;
|
||||
if (eptr < eN)
|
||||
{
|
||||
ei = e[eptr];
|
||||
ea = Mathf.Abs(ei);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a = fi;
|
||||
fptr += 1;
|
||||
if (fptr < fN)
|
||||
{
|
||||
fi = f[fptr];
|
||||
fa = Mathf.Abs(fi);
|
||||
}
|
||||
}
|
||||
|
||||
var x = a + b;
|
||||
var bv = x - a;
|
||||
var y = b - bv;
|
||||
var q0 = y;
|
||||
var q1 = x;
|
||||
var _x = 0f;
|
||||
var _bv = 0f;
|
||||
var _av = 0f;
|
||||
var _br = 0f;
|
||||
var _ar = 0f;
|
||||
while (eptr < eN && fptr < fN)
|
||||
{
|
||||
if (ea < fa)
|
||||
{
|
||||
a = ei;
|
||||
eptr += 1;
|
||||
if (eptr < eN)
|
||||
{
|
||||
ei = e[eptr];
|
||||
ea = Mathf.Abs(ei);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a = fi;
|
||||
fptr += 1;
|
||||
if (fptr < fN)
|
||||
{
|
||||
fi = f[fptr];
|
||||
fa = Mathf.Abs(fi);
|
||||
}
|
||||
}
|
||||
|
||||
b = q0;
|
||||
x = a + b;
|
||||
bv = x - a;
|
||||
y = b - bv;
|
||||
if (y != 0f)
|
||||
{
|
||||
result[resultN++] = y;
|
||||
}
|
||||
|
||||
_x = q1 + x;
|
||||
_bv = _x - q1;
|
||||
_av = _x - _bv;
|
||||
_br = x - _bv;
|
||||
_ar = q1 - _av;
|
||||
q0 = _ar + _br;
|
||||
q1 = _x;
|
||||
}
|
||||
|
||||
while (eptr < eN)
|
||||
{
|
||||
a = ei;
|
||||
b = q0;
|
||||
x = a + b;
|
||||
bv = x - a;
|
||||
y = b - bv;
|
||||
if (y != 0f)
|
||||
{
|
||||
result[resultN++] = y;
|
||||
}
|
||||
|
||||
_x = q1 + x;
|
||||
_bv = _x - q1;
|
||||
_av = _x - _bv;
|
||||
_br = x - _bv;
|
||||
_ar = q1 - _av;
|
||||
q0 = _ar + _br;
|
||||
q1 = _x;
|
||||
eptr += 1;
|
||||
if (eptr < eN)
|
||||
{
|
||||
ei = e[eptr];
|
||||
}
|
||||
}
|
||||
|
||||
while (fptr < fN)
|
||||
{
|
||||
a = fi;
|
||||
b = q0;
|
||||
x = a + b;
|
||||
bv = x - a;
|
||||
y = b - bv;
|
||||
if (y != 0f)
|
||||
{
|
||||
result[resultN++] = y;
|
||||
}
|
||||
|
||||
_x = q1 + x;
|
||||
_bv = _x - q1;
|
||||
_av = _x - _bv;
|
||||
_br = x - _bv;
|
||||
_ar = q1 - _av;
|
||||
q0 = _ar + _br;
|
||||
q1 = _x;
|
||||
fptr += 1;
|
||||
if (fptr < fN)
|
||||
{
|
||||
fi = f[fptr];
|
||||
}
|
||||
}
|
||||
|
||||
if (q0 != 0f)
|
||||
{
|
||||
result[resultN++] = q0;
|
||||
}
|
||||
|
||||
if (q1 != 0f)
|
||||
{
|
||||
result[resultN++] = q1;
|
||||
}
|
||||
|
||||
if (resultN == 0)
|
||||
{
|
||||
result[resultN++] = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
private static void Sub(float[] e, int eN, float[] f, int fN, float[] result, out int resultN)
|
||||
{
|
||||
if (eN == 1 && fN == 1)
|
||||
{
|
||||
ScalarScalar(e[0], -f[0], result, out resultN);
|
||||
return;
|
||||
}
|
||||
|
||||
resultN = 0;
|
||||
|
||||
var eptr = 0;
|
||||
var fptr = 0;
|
||||
var ei = e[eptr];
|
||||
var ea = Mathf.Abs(ei);
|
||||
var fi = -f[fptr];
|
||||
var fa = Mathf.Abs(fi);
|
||||
var a = 0f;
|
||||
var b = 0f;
|
||||
if (ea < fa)
|
||||
{
|
||||
b = ei;
|
||||
eptr += 1;
|
||||
if (eptr < eN)
|
||||
{
|
||||
ei = e[eptr];
|
||||
ea = Mathf.Abs(ei);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
b = fi;
|
||||
fptr += 1;
|
||||
if (fptr < fN)
|
||||
{
|
||||
fi = -f[fptr];
|
||||
fa = Mathf.Abs(fi);
|
||||
}
|
||||
}
|
||||
|
||||
if ((eptr < eN && ea < fa) || (fptr >= fN))
|
||||
{
|
||||
a = ei;
|
||||
eptr += 1;
|
||||
if (eptr < eN)
|
||||
{
|
||||
ei = e[eptr];
|
||||
ea = Mathf.Abs(ei);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a = fi;
|
||||
fptr += 1;
|
||||
if (fptr < fN)
|
||||
{
|
||||
fi = -f[fptr];
|
||||
fa = Mathf.Abs(fi);
|
||||
}
|
||||
}
|
||||
|
||||
var x = a + b;
|
||||
var bv = x - a;
|
||||
var y = b - bv;
|
||||
var q0 = y;
|
||||
var q1 = x;
|
||||
var _x = 0f;
|
||||
var _bv = 0f;
|
||||
var _av = 0f;
|
||||
var _br = 0f;
|
||||
var _ar = 0f;
|
||||
while (eptr < eN && fptr < fN)
|
||||
{
|
||||
if (ea < fa)
|
||||
{
|
||||
a = ei;
|
||||
eptr += 1;
|
||||
if (eptr < eN)
|
||||
{
|
||||
ei = e[eptr];
|
||||
ea = Mathf.Abs(ei);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a = fi;
|
||||
fptr += 1;
|
||||
if (fptr < fN)
|
||||
{
|
||||
fi = -f[fptr];
|
||||
fa = Mathf.Abs(fi);
|
||||
}
|
||||
}
|
||||
|
||||
b = q0;
|
||||
x = a + b;
|
||||
bv = x - a;
|
||||
y = b - bv;
|
||||
if (y != 0f)
|
||||
{
|
||||
result[resultN++] = y;
|
||||
}
|
||||
|
||||
_x = q1 + x;
|
||||
_bv = _x - q1;
|
||||
_av = _x - _bv;
|
||||
_br = x - _bv;
|
||||
_ar = q1 - _av;
|
||||
q0 = _ar + _br;
|
||||
q1 = _x;
|
||||
}
|
||||
|
||||
while (eptr < eN)
|
||||
{
|
||||
a = ei;
|
||||
b = q0;
|
||||
x = a + b;
|
||||
bv = x - a;
|
||||
y = b - bv;
|
||||
if (y != 0f)
|
||||
{
|
||||
result[resultN++] = y;
|
||||
}
|
||||
|
||||
_x = q1 + x;
|
||||
_bv = _x - q1;
|
||||
_av = _x - _bv;
|
||||
_br = x - _bv;
|
||||
_ar = q1 - _av;
|
||||
q0 = _ar + _br;
|
||||
q1 = _x;
|
||||
eptr += 1;
|
||||
if (eptr < eN)
|
||||
{
|
||||
ei = e[eptr];
|
||||
}
|
||||
}
|
||||
|
||||
while (fptr < fN)
|
||||
{
|
||||
a = fi;
|
||||
b = q0;
|
||||
x = a + b;
|
||||
bv = x - a;
|
||||
y = b - bv;
|
||||
if (y != 0f)
|
||||
{
|
||||
result[resultN++] = y;
|
||||
}
|
||||
|
||||
_x = q1 + x;
|
||||
_bv = _x - q1;
|
||||
_av = _x - _bv;
|
||||
_br = x - _bv;
|
||||
_ar = q1 - _av;
|
||||
q0 = _ar + _br;
|
||||
q1 = _x;
|
||||
fptr += 1;
|
||||
if (fptr < fN)
|
||||
{
|
||||
fi = -f[fptr];
|
||||
}
|
||||
}
|
||||
|
||||
if (q0 != 0f)
|
||||
{
|
||||
result[resultN++] = q0;
|
||||
}
|
||||
|
||||
if (q1 != 0f)
|
||||
{
|
||||
result[resultN++] = q1;
|
||||
}
|
||||
|
||||
if (resultN == 0)
|
||||
{
|
||||
result[resultN++] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
private static void Scale(float[] e, int eN, float scale, float[] result, out int resultN)
|
||||
{
|
||||
if (eN == 1)
|
||||
{
|
||||
var ts = GetTemporaryBuffer();
|
||||
|
||||
TwoProd(e[0], scale, ts);
|
||||
|
||||
if (ts[0] != 0f)
|
||||
{
|
||||
result[0] = ts[0];
|
||||
result[1] = ts[1];
|
||||
resultN = 2;
|
||||
ReleaseTemporaryBuffer(ref ts);
|
||||
return;
|
||||
}
|
||||
|
||||
result[0] = ts[1];
|
||||
resultN = 1;
|
||||
ReleaseTemporaryBuffer(ref ts);
|
||||
return;
|
||||
}
|
||||
|
||||
var q = GetTemporaryBuffer();
|
||||
var t = GetTemporaryBuffer();
|
||||
|
||||
q[0] = 0.1f;
|
||||
q[1] = 0.1f;
|
||||
t[0] = 0.1f;
|
||||
t[1] = 0.1f;
|
||||
|
||||
resultN = 0;
|
||||
|
||||
TwoProd(e[0], scale, q);
|
||||
|
||||
if (q[0] != 0f)
|
||||
{
|
||||
result[resultN++] = q[0];
|
||||
}
|
||||
|
||||
for (var i = 1; i < eN; ++i)
|
||||
{
|
||||
TwoProd(e[i], scale, t);
|
||||
|
||||
var pq = q[1];
|
||||
|
||||
TwoSum(pq, t[0], q);
|
||||
|
||||
if (q[0] != 0f)
|
||||
{
|
||||
result[resultN++] = q[0];
|
||||
}
|
||||
|
||||
var a = t[1];
|
||||
var b = q[1];
|
||||
var x = a + b;
|
||||
var bv = x - a;
|
||||
var y = b - bv;
|
||||
q[1] = x;
|
||||
|
||||
if (y != 0f)
|
||||
{
|
||||
result[resultN++] = y;
|
||||
}
|
||||
}
|
||||
|
||||
if (q[1] != 0f)
|
||||
{
|
||||
result[resultN++] = q[1];
|
||||
}
|
||||
|
||||
ReleaseTemporaryBuffer(ref q);
|
||||
ReleaseTemporaryBuffer(ref t);
|
||||
|
||||
if (resultN == 0)
|
||||
{
|
||||
result[resultN++] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
//Easy case: Add two scalars
|
||||
private static void ScalarScalar(float a, float b, float[] result, out int resultN)
|
||||
{
|
||||
var x = a + b;
|
||||
var bv = x - a;
|
||||
var av = x - bv;
|
||||
var br = b - bv;
|
||||
var ar = a - av;
|
||||
var y = ar + br;
|
||||
if (y != 0f)
|
||||
{
|
||||
result[0] = y;
|
||||
result[1] = x;
|
||||
resultN = 2;
|
||||
return;
|
||||
}
|
||||
result[0] = x;
|
||||
resultN = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Robust.cs.meta
vendored
Normal file
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Robust.cs.meta
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76852b2115774598947fe907402ed9fd
|
||||
timeCreated: 1519703003
|
||||
210
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Triangles.cs
vendored
Normal file
210
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Triangles.cs
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2018 Yoshihiro Shindo
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DA_Assets.SVGMeshUnity.Internals.Cdt2d
|
||||
{
|
||||
public class Triangles
|
||||
{
|
||||
public Triangles(MeshData data)
|
||||
{
|
||||
PrivateVertices = data.Vertices;
|
||||
CreateStars(data.Vertices.Count);
|
||||
CreateEdges(data.Edges);
|
||||
CreateTriangles(data.Triangles);
|
||||
}
|
||||
|
||||
public List<Vector3> Vertices
|
||||
{
|
||||
get { return PrivateVertices; }
|
||||
}
|
||||
|
||||
public WorkBuffer<Int2>[] Stars
|
||||
{
|
||||
get { return PrivateStars; }
|
||||
}
|
||||
|
||||
private List<Vector3> PrivateVertices;
|
||||
private WorkBuffer<Int2>[] PrivateStars;
|
||||
private Int2[] Edges;
|
||||
|
||||
private void CreateStars(int n)
|
||||
{
|
||||
var stars = new WorkBuffer<Int2>[n];
|
||||
for (var i = 0; i < n; ++i)
|
||||
{
|
||||
stars[i] = new WorkBuffer<Int2>(16);
|
||||
}
|
||||
PrivateStars = stars;
|
||||
}
|
||||
|
||||
private void CreateEdges(List<Int2> source)
|
||||
{
|
||||
var l = source.Count;
|
||||
var edges = new Int2[l];
|
||||
for (var i = 0; i < l; ++i)
|
||||
{
|
||||
var edge = source[i];
|
||||
if (edge.y < edge.x)
|
||||
{
|
||||
var x = edge.x;
|
||||
edge.x = edge.y;
|
||||
edge.y = x;
|
||||
}
|
||||
edges[i] = edge;
|
||||
}
|
||||
Sort<Int2>.QuickSort(edges, 0, edges.Length - 1);
|
||||
Edges = edges;
|
||||
}
|
||||
|
||||
private void CreateTriangles(List<int> source)
|
||||
{
|
||||
var l = source.Count;
|
||||
for (var i = 0; i < l; i += 3)
|
||||
{
|
||||
AddTriangle(source[i + 0], source[i + 1], source[i + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddTriangle(int i, int j, int k)
|
||||
{
|
||||
var jk = new Int2(j, k);
|
||||
var ki = new Int2(k, i);
|
||||
var ij = new Int2(i, j);
|
||||
PrivateStars[i].Push(ref jk);
|
||||
PrivateStars[j].Push(ref ki);
|
||||
PrivateStars[k].Push(ref ij);
|
||||
}
|
||||
|
||||
public void RemoveTriangle(int i, int j, int k)
|
||||
{
|
||||
RemovePair(PrivateStars[i], j, k);
|
||||
RemovePair(PrivateStars[j], k, i);
|
||||
RemovePair(PrivateStars[k], i, j);
|
||||
}
|
||||
|
||||
private void RemovePair(WorkBuffer<Int2> list, int j, int k)
|
||||
{
|
||||
var n = list.UsedSize;
|
||||
var data = list.Data;
|
||||
for (var i = 0; i < n; ++i)
|
||||
{
|
||||
var s = data[i];
|
||||
if (s.x == j && s.y == k)
|
||||
{
|
||||
data[i] = data[n - 1];
|
||||
list.RemoveLast(1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Opposite(int j, int i)
|
||||
{
|
||||
var list = PrivateStars[i];
|
||||
var n = list.UsedSize;
|
||||
var data = list.Data;
|
||||
for (var k = 0; k < n; ++k)
|
||||
{
|
||||
if (data[k].y == j)
|
||||
{
|
||||
return data[k].x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Flip(int i, int j)
|
||||
{
|
||||
var a = Opposite(i, j);
|
||||
var b = Opposite(j, i);
|
||||
RemoveTriangle(i, j, a);
|
||||
RemoveTriangle(j, i, b);
|
||||
AddTriangle(i, b, a);
|
||||
AddTriangle(j, a, b);
|
||||
}
|
||||
|
||||
public bool IsConstraint(int i, int j)
|
||||
{
|
||||
var e = new Int2(Mathf.Min(i, j), Mathf.Max(i, j));
|
||||
return BinarySearch.EQ(Edges, e, 0, Edges.Length) >= 0;
|
||||
}
|
||||
|
||||
public void Fill(List<int> triangles)
|
||||
{
|
||||
var n = PrivateStars.Length;
|
||||
|
||||
if (triangles.Capacity < n)
|
||||
{
|
||||
triangles.Capacity = n;
|
||||
}
|
||||
triangles.Clear();
|
||||
|
||||
for(var i = 0; i < n; ++i)
|
||||
{
|
||||
var list = PrivateStars[i];
|
||||
var data = list.Data;
|
||||
var m = list.UsedSize;
|
||||
for(var j = 0; j < m; ++j)
|
||||
{
|
||||
var s = data[j];
|
||||
if(i < Mathf.Min(s.x, s.y))
|
||||
{
|
||||
triangles.Add(i);
|
||||
triangles.Add(s.x);
|
||||
triangles.Add(s.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Fill(WorkBuffer<Int3> triangles)
|
||||
{
|
||||
var n = PrivateStars.Length;
|
||||
|
||||
triangles.Extend(n);
|
||||
triangles.Clear();
|
||||
|
||||
for(var i = 0; i < n; ++i)
|
||||
{
|
||||
var list = PrivateStars[i];
|
||||
var data = list.Data;
|
||||
var m = list.UsedSize;
|
||||
for(var j = 0; j < m; ++j)
|
||||
{
|
||||
var s = data[j];
|
||||
if(i < Mathf.Min(s.x, s.y))
|
||||
{
|
||||
var v = new Int3(i, s.x, s.y);
|
||||
triangles.Push(ref v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Triangles.cs.meta
vendored
Normal file
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Triangles.cs.meta
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ae927e5d9354637b7361e1a99ac6aa9
|
||||
timeCreated: 1519790845
|
||||
96
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Triangulation.cs
vendored
Normal file
96
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Triangulation.cs
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Mikola Lysenko
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
namespace DA_Assets.SVGMeshUnity.Internals.Cdt2d
|
||||
{
|
||||
public class Triangulation
|
||||
{
|
||||
// https://github.com/mikolalysenko/cdt2d
|
||||
|
||||
public bool Delaunay = true;
|
||||
public bool Interior = true;
|
||||
public bool Exterior = true;
|
||||
public bool Infinity = false;
|
||||
|
||||
public WorkBufferPool WorkBufferPool;
|
||||
|
||||
private MonotoneTriangulation MonotoneTriangulation = new MonotoneTriangulation();
|
||||
private DelaunayRefine DelaunayRefine = new DelaunayRefine();
|
||||
private Filter Filter = new Filter();
|
||||
|
||||
public void BuildTriangles(MeshData data)
|
||||
{
|
||||
//Handle trivial case
|
||||
if ((!Interior && !Exterior) || data.Vertices.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Construct initial triangulation
|
||||
MonotoneTriangulation.WorkBufferPool = WorkBufferPool;
|
||||
MonotoneTriangulation.BuildTriangles(data);
|
||||
|
||||
//If delaunay refinement needed, then improve quality by edge flipping
|
||||
if (Delaunay || Interior != Exterior || Infinity)
|
||||
{
|
||||
//Index all of the cells to support fast neighborhood queries
|
||||
var triangles = new Triangles(data);
|
||||
|
||||
//Run edge flipping
|
||||
if (Delaunay)
|
||||
{
|
||||
DelaunayRefine.WorkBufferPool = WorkBufferPool;
|
||||
DelaunayRefine.RefineTriangles(triangles);
|
||||
}
|
||||
|
||||
Filter.WorkBufferPool = WorkBufferPool;
|
||||
Filter.Infinity = Infinity;
|
||||
|
||||
//Filter points
|
||||
if (!Exterior)
|
||||
{
|
||||
Filter.Target = -1;
|
||||
Filter.Do(triangles, data.Triangles);
|
||||
return;
|
||||
}
|
||||
if (!Interior)
|
||||
{
|
||||
Filter.Target = 1;
|
||||
Filter.Do(triangles, data.Triangles);
|
||||
return;
|
||||
}
|
||||
if (Infinity)
|
||||
{
|
||||
Filter.Target = 0;
|
||||
Filter.Do(triangles, data.Triangles);
|
||||
return;
|
||||
}
|
||||
|
||||
triangles.Fill(data.Triangles);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Triangulation.cs.meta
vendored
Normal file
3
Assets/D.A. Assets/DA-Shared/ThirdParty/SVGMeshUnity/Internals/Cdt2d/Triangulation.cs.meta
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 781d3a8656524a829b4205bab46ef8de
|
||||
timeCreated: 1519698011
|
||||
Reference in New Issue
Block a user