feat: use Vector2Int instead of IsoVector

master
uc-hoba 10 months ago
parent 35e7d5478b
commit b1cc1528cf
  1. 142
      Assets/Scripts/Editor/GeodesicMesh.cs
  2. 44
      Assets/Scripts/Extensions.cs
  3. 2
      Assets/Scripts/Extensions.cs.meta

@ -7,26 +7,26 @@ namespace Metamesh
{ {
public class PrimaryIsoTriangle public class PrimaryIsoTriangle
{ {
public int m; private int m;
public int n; private int n;
public List<Vector3> cartesian = new List<Vector3>(); private List<Vector3> cartesian = new List<Vector3>();
public List<IsoVector> vertices = new List<IsoVector>(); private List<Vector2Int> vertices = new List<Vector2Int>();
public List<int> max = new List<int>(); private List<int> max = new List<int>();
public List<int> min = new List<int>(); private List<int> min = new List<int>();
public Dictionary<string, int> vecToidx = new Dictionary<string, int>(); public Dictionary<string, int> vecToidx = new Dictionary<string, int>();
public Dictionary<string, List<int>> vertByDist = new Dictionary<string, List<int>>(); private Dictionary<string, List<int>> vertByDist = new Dictionary<string, List<int>>();
public Dictionary<int, List<int>> closestTo = new Dictionary<int, List<int>>(); public Dictionary<int, List<int>> closestTo = new Dictionary<int, List<int>>();
public List<List<string>> innerFacets = new List<List<string>>(); public List<List<string>> innerFacets = new List<List<string>>();
public List<List<IsoVector>> isoVecsABOB = new List<List<IsoVector>>(); public List<List<Vector2Int>> isoVecsABOB = new List<List<Vector2Int>>();
public List<List<IsoVector>> isoVecsOBOA = new List<List<IsoVector>>(); public List<List<Vector2Int>> isoVecsOBOA = new List<List<Vector2Int>>();
public List<List<IsoVector>> isoVecsBAOA = new List<List<IsoVector>>(); public List<List<Vector2Int>> isoVecsBAOA = new List<List<Vector2Int>>();
public List<List<int>> vertexTypes = new List<List<int>>(); public List<List<int>> vertexTypes = new List<List<int>>();
public float coau; private float coau;
public float cobu; private float cobu;
public float coav; private float coav;
public float cobv; private float cobv;
//float PHI = (1 + Mathf.Sqrt(5f)) / 2; //float PHI = (1 + Mathf.Sqrt(5f)) / 2;
const float PHI = 1.618034f; const float PHI = 1.618034f;
@ -133,7 +133,7 @@ namespace Metamesh
var closestTo = new Dictionary<int, List<int>>(); var closestTo = new Dictionary<int, List<int>>();
var vDist = this.vertByDist; var vDist = this.vertByDist;
System.Action<int, int, string, string> matchIdx = (f, fr, isoId, isoIdR) => void MatchIdx(int f, int fr, string isoId, string isoIdR)
{ {
idx = f + "|" + isoId; idx = f + "|" + isoId;
idxR = fr + "|" + isoIdR; idxR = fr + "|" + isoIdR;
@ -143,11 +143,11 @@ namespace Metamesh
vecToidx[idxR] = indexCount; vecToidx[idxR] = indexCount;
indexCount++; indexCount++;
} }
else if (vecToidx.ContainsKey(idx) && !(vecToidx.ContainsKey(idxR))) else if (vecToidx.ContainsKey(idx) && !vecToidx.ContainsKey(idxR))
{ {
vecToidx[idxR] = vecToidx[idx]; vecToidx[idxR] = vecToidx[idx];
} }
else if (vecToidx.ContainsKey(idxR) && !(vecToidx.ContainsKey(idx))) else if (vecToidx.ContainsKey(idxR) && !vecToidx.ContainsKey(idx))
{ {
vecToidx[idx] = vecToidx[idxR]; vecToidx[idx] = vecToidx[idxR];
} }
@ -160,7 +160,7 @@ namespace Metamesh
{ {
closestTo[vecToidx[idx]] = new List<int> { verts[vDist[isoId][0]], vDist[isoId][1], vecToidx[idx] }; closestTo[vecToidx[idx]] = new List<int> { verts[vDist[isoId][0]], vDist[isoId][1], vecToidx[idx] };
} }
}; }
this.IDATA.edgematch = new List<(int, string, int, string)> this.IDATA.edgematch = new List<(int, string, int, string)>
@ -234,7 +234,7 @@ namespace Metamesh
obVec.y = i * (m1 + n1); obVec.y = i * (m1 + n1);
isoId = abVec.x + "|" + abVec.y; isoId = abVec.x + "|" + abVec.y;
isoIdR = obVec.x + "|" + obVec.y; isoIdR = obVec.x + "|" + obVec.y;
matchIdx(f, fr, isoId, isoIdR); MatchIdx(f, fr, isoId, isoIdR);
} }
} }
@ -248,7 +248,7 @@ namespace Metamesh
oaVec.y = i * n1; oaVec.y = i * n1;
isoId = obVec.x + "|" + obVec.y; isoId = obVec.x + "|" + obVec.y;
isoIdR = oaVec.x + "|" + oaVec.y; isoIdR = oaVec.x + "|" + oaVec.y;
matchIdx(f, fr, isoId, isoIdR); MatchIdx(f, fr, isoId, isoIdR);
} }
} }
@ -264,7 +264,7 @@ namespace Metamesh
abVec.y = n + (g - i) * m1; //reversed for BA abVec.y = n + (g - i) * m1; //reversed for BA
isoId = oaVec.x + "|" + oaVec.y; isoId = oaVec.x + "|" + oaVec.y;
isoIdR = abVec.x + "|" + abVec.y; isoIdR = abVec.x + "|" + abVec.y;
matchIdx(f, fr, isoId, isoIdR); MatchIdx(f, fr, isoId, isoIdR);
} }
} }
@ -335,24 +335,24 @@ namespace Metamesh
var m = this.m; var m = this.m;
var n = this.n; var n = this.n;
var B = new IsoVector(-n, m + n); var B = new Vector2Int(-n, m + n);
for (var y = 1; y < m + n; y++) for (var y = 1; y < m + n; y++)
{ {
var point = new IsoVector(this.min[y], y); var point = new Vector2Int(this.min[y], y);
var prev = new IsoVector(this.min[y - 1], y - 1); var prev = new Vector2Int(this.min[y - 1], y - 1);
var next = new IsoVector(this.min[y + 1], y + 1); var next = new Vector2Int(this.min[y + 1], y + 1);
var pointR = point.Clone(); var pointR = point;
var prevR = prev.Clone(); var prevR = prev;
var nextR = next.Clone(); var nextR = next;
pointR.Rotate60About(B); pointR = pointR.Rotate60About(B);
prevR.Rotate60About(B); prevR = prevR.Rotate60About(B);
nextR.Rotate60About(B); nextR = nextR.Rotate60About(B);
var maxPoint = new IsoVector(this.max[pointR.y], pointR.y); var maxPoint = new Vector2Int(this.max[pointR.y], pointR.y);
var maxPrev = new IsoVector(this.max[pointR.y - 1], pointR.y - 1); var maxPrev = new Vector2Int(this.max[pointR.y - 1], pointR.y - 1);
var maxLeftPrev = new IsoVector(this.max[pointR.y - 1] - 1, pointR.y - 1); var maxLeftPrev = new Vector2Int(this.max[pointR.y - 1] - 1, pointR.y - 1);
if (pointR.x != maxPoint.x || pointR.y != maxPoint.y) if (pointR.x != maxPoint.x || pointR.y != maxPoint.y)
{ {
@ -361,30 +361,30 @@ namespace Metamesh
// type2 // type2
//up //up
this.vertexTypes.Add(new List<int> { 1, 0, 0 }); this.vertexTypes.Add(new List<int> { 1, 0, 0 });
this.isoVecsABOB.Add(new List<IsoVector> { point, maxPrev, maxLeftPrev }); this.isoVecsABOB.Add(new List<Vector2Int> { point, maxPrev, maxLeftPrev });
//down //down
this.vertexTypes.Add(new List<int> { 1, 0, 0 }); this.vertexTypes.Add(new List<int> { 1, 0, 0 });
this.isoVecsABOB.Add(new List<IsoVector> { point, maxLeftPrev, maxPoint }); this.isoVecsABOB.Add(new List<Vector2Int> { point, maxLeftPrev, maxPoint });
} }
else if (pointR.y == nextR.y) else if (pointR.y == nextR.y)
{ {
// type1 // type1
//up //up
this.vertexTypes.Add(new List<int> { 1, 1, 0 }); this.vertexTypes.Add(new List<int> { 1, 1, 0 });
this.isoVecsABOB.Add(new List<IsoVector> { point, prev, maxPrev }); this.isoVecsABOB.Add(new List<Vector2Int> { point, prev, maxPrev });
//down //down
this.vertexTypes.Add(new List<int> { 1, 0, 1 }); this.vertexTypes.Add(new List<int> { 1, 0, 1 });
this.isoVecsABOB.Add(new List<IsoVector> { point, maxPrev, next }); this.isoVecsABOB.Add(new List<Vector2Int> { point, maxPrev, next });
} }
else else
{ {
// type 0 // type 0
//up //up
this.vertexTypes.Add(new List<int> { 1, 1, 0 }); this.vertexTypes.Add(new List<int> { 1, 1, 0 });
this.isoVecsABOB.Add(new List<IsoVector> { point, prev, maxPrev }); this.isoVecsABOB.Add(new List<Vector2Int> { point, prev, maxPrev });
//down //down
this.vertexTypes.Add(new List<int> { 1, 0, 0 }); this.vertexTypes.Add(new List<int> { 1, 0, 0 });
this.isoVecsABOB.Add(new List<IsoVector> { point, maxPrev, maxPoint }); this.isoVecsABOB.Add(new List<Vector2Int> { point, maxPrev, maxPoint });
} }
} }
} }
@ -392,20 +392,20 @@ namespace Metamesh
public void MapABOBtoOBOA() public void MapABOBtoOBOA()
{ {
var point = new IsoVector(0, 0); var point = new Vector2Int(0, 0);
for (var i = 0; i < this.isoVecsABOB.Count; i++) for (var i = 0; i < this.isoVecsABOB.Count; i++)
{ {
var temp = new List<IsoVector>(); var temp = new List<Vector2Int>();
for (var j = 0; j < 3; j++) for (var j = 0; j < 3; j++)
{ {
point.x = this.isoVecsABOB[i][j].x; point.x = this.isoVecsABOB[i][j].x;
point.y = this.isoVecsABOB[i][j].y; point.y = this.isoVecsABOB[i][j].y;
if (this.vertexTypes[i][j] == 0) if (this.vertexTypes[i][j] == 0)
{ {
point.RotateNeg120(this.m, this.n); point = point.RotateNeg120(this.m, this.n);
} }
temp.Add(point.Clone()); temp.Add(point);
} }
this.isoVecsOBOA.Add(temp); this.isoVecsOBOA.Add(temp);
@ -414,20 +414,20 @@ namespace Metamesh
public void MapABOBtoBAOA() public void MapABOBtoBAOA()
{ {
var point = new IsoVector(0, 0); var point = new Vector2Int(0, 0);
for (var i = 0; i < this.isoVecsABOB.Count; i++) for (var i = 0; i < this.isoVecsABOB.Count; i++)
{ {
var temp = new List<IsoVector>(); var temp = new List<Vector2Int>();
for (var j = 0; j < 3; j++) for (var j = 0; j < 3; j++)
{ {
point.x = this.isoVecsABOB[i][j].x; point.x = this.isoVecsABOB[i][j].x;
point.y = this.isoVecsABOB[i][j].y; point.y = this.isoVecsABOB[i][j].y;
if (this.vertexTypes[i][j] == 1) if (this.vertexTypes[i][j] == 1)
{ {
point.Rotate120(this.m, this.n); point = point.Rotate120(this.m, this.n);
} }
temp.Add(point.Clone()); temp.Add(point);
} }
this.isoVecsBAOA.Add(temp); this.isoVecsBAOA.Add(temp);
@ -454,13 +454,13 @@ namespace Metamesh
var x = OA * this.coau + OB * this.cobu; var x = OA * this.coau + OB * this.cobu;
var y = OA * this.coav + OB * this.cobv; var y = OA * this.coav + OB * this.cobv;
var mapped = new Dictionary<int, List<float>>(); //var mapped = new Dictionary<int, Vector3>();
string idx; string idx;
for (var i = 0; i < this.cartesian.Count; i++) for (var i = 0; i < this.cartesian.Count; i++)
{ {
var tempVec = x * this.cartesian[i].x + y * this.cartesian[i].y + O; var tempVec = x * this.cartesian[i].x + y * this.cartesian[i].y + O;
mapped[i] = new List<float> { tempVec.x, tempVec.y, tempVec.z }; //mapped[i] = tempVec;
idx = faceNb + "|" + this.vertices[i].x + "|" + this.vertices[i].y; idx = faceNb + "|" + this.vertices[i].x + "|" + this.vertices[i].y;
while (this.vecToidx[idx] >= geodesicData.vertex.Count) while (this.vecToidx[idx] >= geodesicData.vertex.Count)
geodesicData.vertex.Add(Vector3.zero); geodesicData.vertex.Add(Vector3.zero);
@ -470,19 +470,19 @@ namespace Metamesh
public PrimaryIsoTriangle Build(int m, int n) public PrimaryIsoTriangle Build(int m, int n)
{ {
var vertices = new List<IsoVector>(); var vertices = new List<Vector2Int>();
var O = IsoVector.Zero(); var O = Vector2Int.zero;
var A = new IsoVector(m, n); var A = new Vector2Int(m, n);
var B = new IsoVector(-n, m + n); var B = new Vector2Int(-n, m + n);
vertices.AddRange(new IsoVector[] { O, A, B }); vertices.AddRange(new Vector2Int[] { O, A, B });
//max internal isoceles triangle vertices //max internal isoceles triangle vertices
for (var iy = n; iy < m + 1; iy++) for (var iy = n; iy < m + 1; iy++)
{ {
for (var ix = 0; ix < m + 1 - iy; ix++) for (var ix = 0; ix < m + 1 - iy; ix++)
{ {
vertices.Add(new IsoVector(ix, iy)); vertices.Add(new Vector2Int(ix, iy));
} }
} }
@ -495,9 +495,9 @@ namespace Metamesh
for (var i = 1; i < g; i++) for (var i = 1; i < g; i++)
{ {
vertices.Add(new IsoVector(i * m1, i * n1)); //OA vertices.Add(new Vector2Int(i * m1, i * n1)); //OA
vertices.Add(new IsoVector(-i * n1, i * (m1 + n1))); //OB vertices.Add(new Vector2Int(-i * n1, i * (m1 + n1))); //OB
vertices.Add(new IsoVector(m - i * (m1 + n1), n + i * m1)); // AB vertices.Add(new Vector2Int(m - i * (m1 + n1), n + i * m1)); // AB
} }
//lower rows vertices and their rotations //lower rows vertices and their rotations
@ -506,9 +506,9 @@ namespace Metamesh
{ {
for (var ix = 0; ix < iy * ratio; ix++) for (var ix = 0; ix < iy * ratio; ix++)
{ {
vertices.Add(new IsoVector(ix, iy)); vertices.Add(new Vector2Int(ix, iy));
vertices.Add(new IsoVector(ix, iy).Rotate120(m, n)); vertices.Add(new Vector2Int(ix, iy).Rotate120(m, n));
vertices.Add(new IsoVector(ix, iy).RotateNeg120(m, n)); vertices.Add(new Vector2Int(ix, iy).RotateNeg120(m, n));
} }
} }
} }
@ -534,17 +534,17 @@ namespace Metamesh
} }
//calculates the distance of a vertex from a given primary vertex //calculates the distance of a vertex from a given primary vertex
Func<IsoVector, string, int> distFrom = (IsoVector vert, string primVert) => int DistFrom(Vector2Int vert, string primVert)
{ {
var v = vert.Clone(); var v = vert;
if (primVert == "A") if (primVert == "A")
{ {
v.RotateNeg120(m, n); v = v.RotateNeg120(m, n);
} }
if (primVert == "B") if (primVert == "B")
{ {
v.Rotate120(m, n); v = v.Rotate120(m, n);
} }
if (v.x < 0) if (v.x < 0)
@ -553,7 +553,7 @@ namespace Metamesh
} }
return v.x + v.y; return v.x + v.y;
}; }
var cartesian = Enumerable.Repeat(Vector3.zero, len).ToList(); var cartesian = Enumerable.Repeat(Vector3.zero, len).ToList();
var distFromO = Enumerable.Repeat(0, len).ToArray(); var distFromO = Enumerable.Repeat(0, len).ToArray();
@ -566,10 +566,10 @@ namespace Metamesh
var dist = -1; var dist = -1;
for (var i = 0; i < len; i++) for (var i = 0; i < len; i++)
{ {
cartesian[i] = vertices[i].ToCartesianOrigin(new IsoVector(0, 0), 0.5f); cartesian[i] = vertices[i].ToCartesianOrigin(new Vector2Int(0, 0), 0.5f);
distFromO[i] = distFrom(vertices[i], "O"); distFromO[i] = DistFrom(vertices[i], "O");
distFromA[i] = distFrom(vertices[i], "A"); distFromA[i] = DistFrom(vertices[i], "A");
distFromB[i] = distFrom(vertices[i], "B"); distFromB[i] = DistFrom(vertices[i], "B");
if (distFromO[i] == distFromA[i] && distFromA[i] == distFromB[i]) if (distFromO[i] == distFromA[i] && distFromA[i] == distFromB[i])
{ {

@ -0,0 +1,44 @@
using UnityEngine;
public static class Vector2IntExtensions
{
public static Vector2Int Rotate60About(this Vector2Int vector, Vector2Int other)
{
var x = other.x + other.y - vector.y;
var y = vector.x + vector.y - other.x;
return new Vector2Int(x, y);
}
public static Vector2Int RotateNeg60About(this Vector2Int vector, Vector2Int other)
{
var x = vector.x + vector.y - other.x;
var y = other.x + other.y - vector.y;
return new Vector2Int(x, y);
}
public static Vector2Int Rotate120(this Vector2Int vector, int m, int n)
{
var x = m - vector.x - vector.y;
var y = n + vector.x;
return new Vector2Int(x, y);
}
public static Vector2Int RotateNeg120(this Vector2Int vector, int m, int n)
{
var x = vector.y - n;
var y = m + n - vector.x - vector.y;
return new Vector2Int(x, y);
}
public static Vector3 ToCartesianOrigin(this Vector2Int vector, Vector2Int origin, float isoGridSize)
{
Vector3 point = Vector3.zero;
point.x = origin.x + 2 * vector.x * isoGridSize + vector.y * isoGridSize;
point.y = origin.y + Mathf.Sqrt(3) * vector.y * isoGridSize;
return point;
}
}

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 06cb1f7cb5c9b794497584417b3aa86e