Skip to content
Snippets Groups Projects
Commit 1d86639f authored by Knuiman, Bart's avatar Knuiman, Bart
Browse files

Important bugfix, cache now working without errors.

parent 518f8b1c
No related branches found
No related tags found
No related merge requests found
...@@ -51,7 +51,8 @@ namespace Wander ...@@ -51,7 +51,8 @@ namespace Wander
// float denominator = ((vertex2.y - vertex3.y) * (vertex1.x - vertex3.x) + (vertex3.x - vertex2.x) * (vertex1.y - vertex3.y)); // float denominator = ((vertex2.y - vertex3.y) * (vertex1.x - vertex3.x) + (vertex3.x - vertex2.x) * (vertex1.y - vertex3.y));
float denominator = ((vertices[i+1].y - vertices[i+2].y) * (vertices[i].x - vertices[i+2].x) + (vertices[i+2].x - vertices[i+1].x) * (vertices[i].y - vertices[i+2].y)); float denominator = ((vertices[i+1].y - vertices[i+2].y) * (vertices[i].x - vertices[i+2].x) + (vertices[i+2].x - vertices[i+1].x) * (vertices[i].y - vertices[i+2].y));
denoms.Add( 1.0f / denominator ); denominator = 1.0f / denominator;
denoms.Add( denominator );
} }
} }
} }
...@@ -111,6 +112,12 @@ namespace Wander ...@@ -111,6 +112,12 @@ namespace Wander
return finished; return finished;
} }
static bool IsTriangleCCW( Vector2 vertex1, Vector2 vertex2, Vector2 vertex3 )
{
float signedArea = (vertex2.x - vertex1.x) * (vertex3.y - vertex1.y) - (vertex3.x - vertex1.x) * (vertex2.y - vertex1.y);
return signedArea > 0;
}
// Number of failed polys to triangulate are returned. // Number of failed polys to triangulate are returned.
public int Triangulate() public int Triangulate()
{ {
...@@ -158,6 +165,15 @@ namespace Wander ...@@ -158,6 +165,15 @@ namespace Wander
double y = vertices[indices[k]*2+1]; double y = vertices[indices[k]*2+1];
poly.vertices.Add( new Vector2( (float)x, (float)y ) ); poly.vertices.Add( new Vector2( (float)x, (float)y ) );
} }
//for ( int k = 0; k < indices.Count; k += 3)
//{
// if ( !IsTriangleCCW( poly.vertices[k], poly.vertices[k+1], poly.vertices[k+2] ))
// {
// var t = poly.vertices[k];
// poly.vertices[k] = poly.vertices[k+2];
// poly.vertices[k+2] = t;
// }
//}
polygons[polygons.Count-1] = poly; polygons[polygons.Count-1] = poly;
Debug.Assert( poly.vertices.Count % 3 == 0 ); Debug.Assert( poly.vertices.Count % 3 == 0 );
} }
...@@ -211,7 +227,7 @@ namespace Wander ...@@ -211,7 +227,7 @@ namespace Wander
int resolution, int resolution,
out Dictionary<byte, byte> remappedLayerIndices, out Dictionary<byte, byte> remappedLayerIndices,
out List<Vector3Int> failedPixels, out List<Vector3Int> failedPixels,
bool? cancelToken) bool? cancelToken )
{ {
Debug.Assert( triangulated, "First call Triangulate." ); Debug.Assert( triangulated, "First call Triangulate." );
Debug.Assert( layersIdentified, "Identify layers first." ); Debug.Assert( layersIdentified, "Identify layers first." );
...@@ -220,12 +236,11 @@ namespace Wander ...@@ -220,12 +236,11 @@ namespace Wander
byte [] texture = new byte[resolution*resolution]; byte [] texture = new byte[resolution*resolution];
failedPixels = new List<Vector3Int>(); failedPixels = new List<Vector3Int>();
remappedLayerIndices = new Dictionary<byte, byte>(); remappedLayerIndices = new Dictionary<byte, byte>();
byte cachedPixel = 0;
float oneOverRes = 1.0f / resolution; float oneOverRes = 1.0f / resolution;
TriangulatedPolygon cachedPoly = default; int cachedTriIdx = 0;
int cachedVtxIdx = -1; int cachedLyrIdx = 0;
int cachedTriIdx = -1; int cachedFtrIdx = 0;
// For each pixel. // For each pixel.
for (int y = 0;y < resolution ;y++) for (int y = 0;y < resolution ;y++)
...@@ -237,70 +252,58 @@ namespace Wander ...@@ -237,70 +252,58 @@ namespace Wander
// For each layer, check triangle intersections. // For each layer, check triangle intersections.
for (int l = 0;l < layers.Count && !cancelToken.Value;l++) for (int l = 0;l < layers.Count && !cancelToken.Value;l++)
{ {
var layer = layers[l]; var lIdx = (l+cachedLyrIdx) % layers.Count; // Try last layer/feature/triangle first.
var layer = layers[lIdx];
float fx = layer.Extent * oneOverRes; float fx = layer.Extent * oneOverRes;
Vector2 p = new Vector2(fx*x+0.5f*fx, fx*y+0.5f*fx); Vector2 p = new Vector2(fx*x+0.5f, fx*y+0.5f);
// First try cache, quite often adjacent pixels will hit the same triangle.
if (cachedVtxIdx!=-1)
{
var vertices = cachedPoly.vertices;
var denoms = cachedPoly.denoms;
var mins = cachedPoly.mins;
var maxs = cachedPoly.maxs;
if (!(p.x < mins[cachedTriIdx].x || p.x > maxs[cachedTriIdx].x) &&
!(p.y < mins[cachedTriIdx].y || p.y > maxs[cachedTriIdx].y))
{
hit = GeomUtil.PointIsInsideTriangle2( p, vertices[cachedVtxIdx], vertices[cachedVtxIdx+1], vertices[cachedVtxIdx+2], denoms[cachedTriIdx] );
if (hit)
{
texture[(resolution - y -1)*resolution+x] = cachedPixel;
break; // Pass from cache, continue to next pixel.
}
}
}
// Must check all triangles, no cache or was no hit with cache.
for (int f = 0;f < layer.VectorTileFeatures.Count;f++) for (int f = 0;f < layer.VectorTileFeatures.Count;f++)
{ {
var feature = layer.VectorTileFeatures[f]; var ftrIdx = (f + cachedFtrIdx) % layer.VectorTileFeatures.Count;
var feature = layer.VectorTileFeatures[ftrIdx];
if (feature.GeometryType != Tile.GeomType.Polygon) if (feature.GeometryType != Tile.GeomType.Polygon)
continue; continue;
var polygons = polygonLayers[l][f]; var polygons = polygonLayers[lIdx][ftrIdx];
if (polygons.vertices.Count == 0) if (polygons.vertices.Count == 0)
continue; continue;
cachedVtxIdx = -1; var poly = polygonLayers[lIdx][ftrIdx];
cachedPoly = polygonLayers[l][f]; var mins = poly.mins;
var mins = cachedPoly.mins; var maxs = poly.maxs;
var maxs = cachedPoly.maxs; var denoms = poly.denoms;
var denoms = cachedPoly.denoms; var vertices = poly.vertices;
var vertices = cachedPoly.vertices; var triCount = vertices.Count/3;
for (int vIdx = 0, triIdx = 0;vIdx < vertices.Count;vIdx += 3, triIdx++) for (int t = 0; t < triCount;t++)
{ {
int triIdx = (t+cachedTriIdx) % triCount;
if (p.x < mins[triIdx].x || p.x > maxs[triIdx].x) continue; if (p.x < mins[triIdx].x || p.x > maxs[triIdx].x) continue;
if (p.y < mins[triIdx].y || p.y > maxs[triIdx].y) continue; if (p.y < mins[triIdx].y || p.y > maxs[triIdx].y) continue;
hit = GeomUtil.PointIsInsideTriangle2( p, vertices[vIdx], vertices[vIdx+1], vertices[vIdx+2], denoms[triIdx] ); hit = GeomUtil.PointIsInsideTriangle2( p, vertices[triIdx*3], vertices[triIdx*3+1], vertices[triIdx*3+2], denoms[triIdx] );
if (hit) if (hit)
{ {
cachedTriIdx = triIdx; cachedTriIdx = triIdx;
cachedVtxIdx = vIdx; cachedLyrIdx = lIdx;
cachedPixel = (byte)feature.SelectedLayerIdx; cachedFtrIdx = ftrIdx;
texture[(resolution - y -1)*resolution+x] = cachedPixel; texture[(resolution - y -1)*resolution+x] = (byte)feature.SelectedLayerIdx;
break; break;
} }
} }
if (hit) break; if (hit) break;
cachedTriIdx = 0;
} }
if (hit) break; if (hit) break;
cachedFtrIdx = 0;
} }
if (!hit) if (!hit)
{ {
cachedLyrIdx = 0;
texture[(resolution - y -1)*resolution+x] = 255; texture[(resolution - y -1)*resolution+x] = 255;
failedPixels.Add( new Vector3Int( x, y, 255 ) ); failedPixels.Add( new Vector3Int( x, y, 255 ) );
} }
...@@ -309,7 +312,7 @@ namespace Wander ...@@ -309,7 +312,7 @@ namespace Wander
// Determine number of different layers. For instance, if only layer 3, 8, 14 and 15 are used, we select // Determine number of different layers. For instance, if only layer 3, 8, 14 and 15 are used, we select
// a material that only uses 4 textures and put 3 -> Albedo_0 -> 8 to Albedo_1, etc. in the shader. // a material that only uses 4 textures and put 3 -> Albedo_0 -> 8 to Albedo_1, etc. in the shader.
cachedPixel = 255; byte cachedPixel = 255;
int remappedIndexCounter = -1; int remappedIndexCounter = -1;
byte remappedPixel = 255; byte remappedPixel = 255;
int addr = 0; int addr = 0;
...@@ -318,21 +321,24 @@ namespace Wander ...@@ -318,21 +321,24 @@ namespace Wander
for (int x = 0;x < resolution;x++) for (int x = 0;x < resolution;x++)
{ {
byte pixel = texture[addr]; byte pixel = texture[addr];
if ( pixel != cachedPixel && pixel < 254 /*used for not matched layer*/ ) if (pixel < 254)
{ {
if (!remappedLayerIndices.TryGetValue( pixel, out remappedPixel )) if (pixel != cachedPixel)
{ {
if (remappedIndexCounter < 253) // 254 is reserved for no layer match, 255 is ray hit with triangle. if (!remappedLayerIndices.TryGetValue( pixel, out remappedPixel ))
{ {
remappedIndexCounter++; if (remappedIndexCounter < 253) // 254 is reserved for no layer match, 255 is ray hit with triangle.
remappedPixel = (byte)remappedIndexCounter; {
remappedLayerIndices.Add( pixel, remappedPixel ); remappedIndexCounter++;
remappedPixel = (byte)remappedIndexCounter;
remappedLayerIndices.Add( pixel, remappedPixel );
}
else remappedPixel = 0;
} }
else remappedPixel = 0; cachedPixel = pixel;
} }
cachedPixel = pixel; texture[addr] = remappedPixel;
} } // leave unfound or unhit pixels on their original value.
texture[addr] = remappedPixel;
addr++; addr++;
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment