private void PerformMarchingSquares()
{
// Clear internal members
WorkingShape.Triangles.Clear();
allEdges.Clear();
fullCells.Clear();
// Iterate over all bitmap pixels
for (int y = 1; y < height; ++y)
{
fullCells.Add(new List<IntVector2>(width));
for (int x = 1; x < width; ++x)
{
/*
* 0 -- 3
* | |
* 1 -- 2
*
*/
// TODO: upper-left row/column
float w0 = terrainSmoothmap[x - 1, y - 1];
float w1 = terrainSmoothmap[x - 1, y];
float w2 = terrainSmoothmap[x, y];
float w3 = terrainSmoothmap[x, y - 1];
bool _0 = w0 > 0.5f;
bool _1 = w1 > 0.5f;
bool _2 = w2 > 0.5f;
bool _3 = w3 > 0.5f;
int mscase = (_0 ? 1 : 0) + (_1 ? 2 : 0) + (_2 ? 4 : 0) + (_3 ? 8 : 0);
// Early-out?
if (mscase == 0)
continue;
// Early-in?
if (mscase == 15)
{
fullCells[fullCells.Count - 1].Add(new IntVector2(x, y));
}
else
{
Vector2 v0 = new Vector2(x - 1, y - 1);
Vector2 v1 = new Vector2(x - 1, y);
Vector2 v2 = new Vector2(x, y);
Vector2 v3 = new Vector2(x, y - 1);
switch (mscase)
{
case 0:
// No triangles at all
break;
case 1:
WorkingShape.Triangles.Add(new Triangle(v0, Mix(v0, v1, w0, w1), Mix(v0, v3, w0, w3)));
//allEdges.Add(new Edge(2*x-1, 2*(y-1), 2*(x-1), 2*y-1));
allEdges.Add(new Edge(2 * x - 1, 2 * (y - 1), 2 * (x - 1), 2 * y - 1, Mix(v0, v1, w0, w1), Mix(v0, v3, w0, w3)));
break;
case 2:
WorkingShape.Triangles.Add(new Triangle(v1, Mix(v1, v2, w1, w2), Mix(v0, v1, w0, w1)));
allEdges.Add(new Edge(2 * (x - 1), 2 * y - 1, 2 * x - 1, 2 * y, Mix(v1, v2, w1, w2), Mix(v0, v1, w0, w1)));
break;
case 3:
WorkingShape.Triangles.Add(new Triangle(v0, v1, Mix(v1, v2, w1, w2)));
WorkingShape.Triangles.Add(new Triangle(Mix(v1, v2, w1, w2), Mix(v0, v3, w0, w3), v0));
allEdges.Add(new Edge(2 * x - 1, 2 * (y - 1), 2 * x - 1, 2 * y, Mix(v1, v2, w1, w2), Mix(v0, v3, w0, w3)));
break;
case 4:
WorkingShape.Triangles.Add(new Triangle(v2, Mix(v2, v3, w2, w3), Mix(v1, v2, w1, w2)));
allEdges.Add(new Edge(2 * x - 1, 2 * y, 2 * x, 2 * y - 1, Mix(v2, v3, w2, w3), Mix(v1, v2, w1, w2)));
break;
case 5:
WorkingShape.Triangles.Add(new Triangle(v0, Mix(v0, v1, w0, w1), Mix(v0, v3, w0, w3)));
WorkingShape.Triangles.Add(new Triangle(v2, Mix(v2, v3, w2, w3), Mix(v1, v2, w1, w2)));
allEdges.Add(new Edge(2 * x - 1, 2 * (y - 1), 2 * (x - 1), 2 * y - 1, Mix(v0, v1, w0, w1), Mix(v0, v3, w0, w3)));
allEdges.Add(new Edge(2 * x - 1, 2 * y, 2 * x, 2 * y - 1, Mix(v2, v3, w2, w3), Mix(v1, v2, w1, w2)));
break;
case 6:
WorkingShape.Triangles.Add(new Triangle(v2, Mix(v0, v1, w0, w1), v1));
WorkingShape.Triangles.Add(new Triangle(v2, Mix(v2, v3, w2, w3), Mix(v0, v1, w0, w1)));
allEdges.Add(new Edge(2 * (x - 1), 2 * y - 1, 2 * x, 2 * y - 1, Mix(v2, v3, w2, w3), Mix(v0, v1, w0, w1)));
break;
case 7:
WorkingShape.Triangles.Add(new Triangle(v1, Mix(v0, v3, w0, w3), v0));
WorkingShape.Triangles.Add(new Triangle(v1, Mix(v2, v3, w2, w3), Mix(v0, v3, w0, w3)));
WorkingShape.Triangles.Add(new Triangle(v1, v2, Mix(v2, v3, w2, w3)));
allEdges.Add(new Edge(2 * x - 1, 2 * (y - 1), 2 * x, 2 * y - 1, Mix(v2, v3, w2, w3), Mix(v0, v3, w0, w3)));
break;
case 8:
WorkingShape.Triangles.Add(new Triangle(v3, Mix(v0, v3, w0, w3), Mix(v2, v3, w2, w3)));
allEdges.Add(new Edge(2 * x - 1, 2 * (y - 1), 2 * x, 2 * y - 1, Mix(v0, v3, w0, w3), Mix(v2, v3, w2, w3)));
break;
case 9:
WorkingShape.Triangles.Add(new Triangle(v0, Mix(v2, v3, w2, w3), v3));
WorkingShape.Triangles.Add(new Triangle(v0, Mix(v0, v1, w0, w1), Mix(v2, v3, w2, w3)));
allEdges.Add(new Edge(2 * (x - 1), 2 * y - 1, 2 * x, 2 * y - 1, Mix(v0, v1, w0, w1), Mix(v2, v3, w2, w3)));
break;
case 10:
WorkingShape.Triangles.Add(new Triangle(v1, Mix(v1, v2, w1, w2), Mix(v0, v1, w0, w1)));
WorkingShape.Triangles.Add(new Triangle(v3, Mix(v0, v3, w0, w3), Mix(v2, v3, w2, w3)));
allEdges.Add(new Edge(2 * (x - 1), 2 * y - 1, 2 * x - 1, 2 * y, Mix(v1, v2, w1, w2), Mix(v0, v1, w0, w1)));
allEdges.Add(new Edge(2 * x - 1, 2 * (y - 1), 2 * x, 2 * y - 1, Mix(v0, v3, w0, w3), Mix(v2, v3, w2, w3)));
break;
case 11:
WorkingShape.Triangles.Add(new Triangle(v0, v1, Mix(v1, v2, w1, w2)));
WorkingShape.Triangles.Add(new Triangle(v0, Mix(v1, v2, w1, w2), Mix(v2, v3, w2, w3)));
WorkingShape.Triangles.Add(new Triangle(v0, Mix(v2, v3, w2, w3), v3));
allEdges.Add(new Edge(2 * x - 1, 2 * y, 2 * x, 2 * y - 1, Mix(v1, v2, w1, w2), Mix(v2, v3, w2, w3)));
break;
case 12:
WorkingShape.Triangles.Add(new Triangle(v3, Mix(v0, v3, w0, w3), Mix(v1, v2, w1, w2)));
WorkingShape.Triangles.Add(new Triangle(v3, Mix(v1, v2, w1, w2), v2));
allEdges.Add(new Edge(2 * x - 1, 2 * (y - 1), 2 * x - 1, 2 * y, Mix(v0, v3, w0, w3), Mix(v1, v2, w1, w2)));
break;
case 13:
WorkingShape.Triangles.Add(new Triangle(v3, v0, Mix(v0, v1, w0, w1)));
WorkingShape.Triangles.Add(new Triangle(v3, Mix(v0, v1, w0, w1), Mix(v1, v2, w1, w2)));
WorkingShape.Triangles.Add(new Triangle(v3, Mix(v1, v2, w1, w2), v2));
allEdges.Add(new Edge(2 * (x - 1), 2 * y - 1, 2 * x - 1, 2 * y, Mix(v0, v1, w0, w1), Mix(v1, v2, w1, w2)));
break;
case 14:
WorkingShape.Triangles.Add(new Triangle(v2, Mix(v0, v1, w0, w1), v1));
WorkingShape.Triangles.Add(new Triangle(v2, Mix(v0, v3, w0, w3), Mix(v0, v1, w0, w1)));
WorkingShape.Triangles.Add(new Triangle(v2, v3, Mix(v0, v3, w0, w3)));
allEdges.Add(new Edge(2 * x - 1, 2 * (y - 1), 2 * (x - 1), 2 * y - 1, Mix(v0, v3, w0, w3), Mix(v0, v1, w0, w1)));
break;
case 15:
fullCells[fullCells.Count - 1].Add(new IntVector2(x, y));
break;
default:
break;
}
}
}
}
}