Skip to content

Instantly share code, notes, and snippets.

@andybak
Created April 6, 2024 09:12
Show Gist options
  • Save andybak/a54028cfd44222a5c43a6bab02aad770 to your computer and use it in GitHub Desktop.
Save andybak/a54028cfd44222a5c43a6bab02aad770 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
using Polyhydra.Core;
using Sylves;
using UnityEngine;
using UnityEngine.UIElements;
using MeshTopology = Sylves.MeshTopology;
[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class SylvesTest : TestBase
{
public enum SylvesGridTypes
{
HexGrid,
SquareGrid,
TriangleGrid,
RhombilleGrid,
CairoGrid,
TriHexGrid,
JitteredSquareGrid,
TownscaperGrid,
ChairGrid,
MetaHexagonGrid,
SquareSnubGrid,
TetrakisSquareGrid,
DominoGrid,
PenroseRhombGrid,
OffGrid,
}
[Header("Base Shape Parameters")]
public SylvesGridTypes type;
[Range(1, 64)] public int Size = 3;
public override void Go()
{
poly = BuildSylves(type);
Build();
}
private PolyMesh BuildSylves(SylvesGridTypes sylvesGridTypes)
{
IGrid grid;
IBound bound = null;
switch (type)
{
case SylvesGridTypes.HexGrid:
grid = new HexGrid(1f);
bound = HexBound.Hexagon(Size);
break;
case SylvesGridTypes.SquareGrid:
grid = new SquareGrid(1f);
bound = new SquareBound(-Vector2Int.one * Size, Vector2Int.one * Size);
break;
case SylvesGridTypes.TriangleGrid:
grid = new TriangleGrid(1f);
bound = TriangleBound.Hexagon(Size);
break;
case SylvesGridTypes.RhombilleGrid:
grid = new RhombilleGrid();
bound = new SquareBound(-Vector2Int.one * Size, Vector2Int.one * Size);
break;
case SylvesGridTypes.CairoGrid:
grid = new CairoGrid();
bound = new SquareBound(-Vector2Int.one * Size, Vector2Int.one * Size);
break;
case SylvesGridTypes.TriHexGrid:
grid = new TriHexGrid();
bound = new SquareBound(-Vector2Int.one * Size, Vector2Int.one * Size);
break;
case SylvesGridTypes.JitteredSquareGrid:
grid = new JitteredSquareGrid();
bound = new SquareBound(-Vector2Int.one * Size, Vector2Int.one * Size);
break;
case SylvesGridTypes.TownscaperGrid:
grid = new TownscaperGrid(1);
bound = new SquareBound(-Vector2Int.one * Size, Vector2Int.one * Size);
break;
case SylvesGridTypes.ChairGrid:
grid = new ChairGrid();
bound = new SubstitutionTilingBound();
break;
case SylvesGridTypes.MetaHexagonGrid:
grid = new MetaHexagonGrid();
bound = new SquareBound(-Vector2Int.one * Size, Vector2Int.one * Size);
break;
case SylvesGridTypes.SquareSnubGrid:
grid = new SquareSnubGrid();
bound = new SquareBound(-Vector2Int.one * Size, Vector2Int.one * Size);
break;
case SylvesGridTypes.TetrakisSquareGrid:
grid = new TetrakisSquareGrid();
bound = new SquareBound(-Vector2Int.one * Size, Vector2Int.one * Size);
break;
case SylvesGridTypes.DominoGrid:
grid = new DominoGrid();
bound = new SubstitutionTilingBound();
break;
case SylvesGridTypes.PenroseRhombGrid:
grid = new PenroseRhombGrid();
bound = new SubstitutionTilingBound();
break;
case SylvesGridTypes.OffGrid:
grid = new OffGrid();
bound = new SquareBound(-Vector2Int.one * Size, Vector2Int.one * Size);
break;
default:
throw new ArgumentOutOfRangeException();
}
var meshData = grid.BoundBy(bound).ToMeshData();
var indices = new List<List<int>>();
Func<int[], int, List<List<int>>> splitInto = (list, chunkSize) =>
Enumerable.Range(0, (list.Length + chunkSize - 1) / chunkSize)
.Select(i => list.Skip(i * chunkSize).Take(chunkSize).ToList())
.ToList();
if (meshData.indices.Length == 0 || meshData.indices[0].Length == 0)
{
Debug.Log($"No indices found for {type}");
return new PolyMesh();
}
var rawIndices = meshData.indices[0];
switch (meshData.topologies[0])
{
case MeshTopology.Triangles:
indices = splitInto(rawIndices, 3);
break;
case MeshTopology.Quads:
indices = splitInto(rawIndices, 4);
break;
case MeshTopology.NGon:
List<int> currentChunk = new List<int>();
for (var i = 0; i < rawIndices.Length; i++)
{
var item = rawIndices[i];
if (item < 0)
{
currentChunk.Add(-item);
indices.Add(new List<int>(currentChunk));
currentChunk.Clear();
}
else currentChunk.Add(item);
}
if (currentChunk.Count > 0) indices.Add(currentChunk);
break;
}
return new PolyMesh(
meshData.vertices,
indices
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment