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

wip wap

parent 26192e5c
No related branches found
No related tags found
No related merge requests found
......@@ -67,6 +67,7 @@ namespace Wander
private bool valid;
private bool finished;
private bool triangulated;
private bool layersIdentified;
private Task parseTileTask;
private List<VectorTileLayer> layers;
private List<List<TriangulatedPolygon>> polygonLayers;
......@@ -178,94 +179,68 @@ namespace Wander
polygonLayers[i][j].OptimizeForIsPointInTriangle();
}
// Calls callback(x, y, channel) for each raster position (256 channels) where each value represents a single channel.
// If no polygon was hit, 255 is called.
// If polygon was hit, but no feature was matched, 254 is called.
// Returns a list of failed to match pixels. This can be due to geometry not exactly matching or a layer not being found.
public List<Vector3Int> RenderToTextureSingle(
int width, int height,
List<string> matchingAttribKeys,
List<List<string>> layerNamesList,
Func<int, int, byte, bool> callback )
// Identify feature by specifying a (unique) index based on some criteria. This can very per
// vector tile provider.
public void IdentifyLayers( Func<VectorTileLayer, List<KeyValuePair<string, object>>, int> selectionCallback )
{
Debug.Assert( triangulated, "First call Triangulate." );
Debug.Assert( layerNamesList.Count < 254, "254 and 255 are reserved for no hit or no match." );
// First match layers to layer names.
bool cancel = false;
List<Vector3Int> failedPixels = new List<Vector3Int>();
for (int l = 0;l < layers.Count && !cancel;l++)
for (int l = 0;l < layers.Count;l++)
{
var layer = layers[l];
for (int f = 0;f < layer.VectorTileFeatures.Count && !cancel;f++)
for (int f = 0;f < layer.VectorTileFeatures.Count;f++)
{
var feature = layer.VectorTileFeatures[f];
feature.SelectedLayerIdx = 254;
if (feature.GeometryType != Tile.GeomType.Polygon)
continue;
if (feature.Attributes == null)
continue;
// Find matching layer.
bool matchingLayerFound = false;
for (int a = 0;a < feature.Attributes.Count && !matchingLayerFound;a++)
int uniqueId = selectionCallback( layer, feature.Attributes );
if (uniqueId > -1)
{
for (int m = 0;m < matchingAttribKeys.Count && !matchingLayerFound;m++)
if ( uniqueId == 8 )
{
if (feature.Attributes[a].Key != matchingAttribKeys[m])
continue;
string function = feature.Attributes[a].Value as string;
for (int layerIdx = 0;layerIdx < layerNamesList.Count && !matchingLayerFound;layerIdx++)
{
for (int layerNameIdx = 0;layerNameIdx < layerNamesList[layerIdx].Count;layerNameIdx++)
{
if (function.Contains( layerNamesList[layerIdx][layerNameIdx] ))
{
feature.SelectedLayerIdx = layerIdx;
matchingLayerFound = true;
break;
}
}
}
}
}
// try Layer.name
if (!matchingLayerFound)
{
for (int layerIdx = 0;layerIdx < layerNamesList.Count && !matchingLayerFound;layerIdx++)
{
for (int layerNameIdx = 0;layerNameIdx < layerNamesList[layerIdx].Count;layerNameIdx++)
{
if (layer.Name.Contains( layerNamesList[layerIdx][layerNameIdx] ))
{
feature.SelectedLayerIdx = layerIdx;
matchingLayerFound = true;
break;
}
}
int jt = 0;
}
feature.SelectedLayerIdx = uniqueId;
break; // Done with this feature.
}
}
}
Debug.Assert( width == height, "Must be square images." );
layersIdentified = true;
}
// For each layer, for each pixel, now check triangle intersections.
for (int l = 0;l < layers.Count && !cancel;l++)
// Calls callback(x, y, channel) for each raster position (256 channels) where each value represents a single channel.
// If no polygon was hit, 255 is called.
// If polygon was hit, but no feature was matched, 254 is called.
// Returns a list of failed to match pixels. This can be due to geometry not exactly matching or a layer not being found.
// Also out puts a remap of layer indices. For instance for a specific tile, only layerIdx 1, 6 and 3 are used.
// Then this a remapping of 1->0, 6->1, 3->2. So that in the shader only 3 textures are needed starting from 0, 1.. etc.
public byte[] RenderToTextureSingle(
int resolution,
out Dictionary<byte, byte> remappedLayerIndices,
out List<Vector3Int> failedPixels,
bool? cancelToken)
{
Debug.Assert( triangulated, "First call Triangulate." );
Debug.Assert( layersIdentified, "Identify layers first." );
Debug.Assert( resolution > 1, "Must be at least 2." );
byte [] texture = new byte[resolution*resolution];
failedPixels = new List<Vector3Int>();
remappedLayerIndices = new Dictionary<byte, byte>();
byte cachedPixel = 0;
// For each layer, for each pixel, check triangle intersections.
for (int l = 0;l < layers.Count && !cancelToken.Value;l++)
{
var layer = layers[l];
float fx = (float)layer.Extent / width;
float fx = (float)layer.Extent / resolution;
TriangulatedPolygon cachedPoly = default;
int cachedVtxIdx = -1;
int cachedTriIdx = -1;
byte cachedPixel = 0;
for (int y = 0;y < height && !cancel;y++)
for (int y = 0;y < resolution && !cancelToken.Value;y++)
{
for (int x = 0;x < width && !cancel;x++)
for (int x = 0; x < resolution; x++)
{
Vector2 p = new Vector2(fx*x+0.5f*fx, fx*y+0.5f*fx);
bool hit = false;
......@@ -283,7 +258,7 @@ namespace Wander
hit = GeomUtil.PointIsInsideTriangle2( p, vertices[cachedVtxIdx], vertices[cachedVtxIdx+1], vertices[cachedVtxIdx+2], denoms[cachedTriIdx] );
if (hit)
{
cancel = callback( x, y, cachedPixel ); // If SelectedLayerIdx did not match, it was set to 254.
texture[(resolution - y -1)*resolution+x] = cachedPixel;
continue; // Pass from cache, continue to next pixel.
}
}
......@@ -317,7 +292,11 @@ namespace Wander
cachedTriIdx = triIdx;
cachedVtxIdx = vIdx;
cachedPixel = (byte)feature.SelectedLayerIdx;
cancel = callback( x, y, cachedPixel );
if ( cachedPixel == 8 )
{
int jt = 0;
}
texture[(resolution - y -1)*resolution+x] = cachedPixel;
break;
}
}
......@@ -327,13 +306,49 @@ namespace Wander
if ( !hit )
{
// texture[(resolution - y -1)*resolution+x] = 255;
failedPixels.Add( new Vector3Int( x, y, 255 ) );
}
}
}
}
return failedPixels;
// 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.
cachedPixel = 255;
int remappedIndexCounter = -1;
byte remappedPixel = 255;
int addr = 0;
for (int y = 0;y < resolution && !cancelToken.Value;y++)
{
for (int x = 0;x < resolution;x++)
{
byte pixel = texture[addr];
if (pixel == 8 )
{
int jt = 0;
}
if ( pixel != cachedPixel && pixel != 254 /*used for not matched layer*/ )
{
if (!remappedLayerIndices.TryGetValue( pixel, out remappedPixel ))
{
if (remappedIndexCounter < 253) // 254 is reserved for no layer match, 255 is ray hit with triangle.
{
remappedIndexCounter++;
remappedPixel = (byte)remappedIndexCounter;
remappedLayerIndices.Add( pixel, remappedPixel );
}
else remappedPixel = 0;
}
cachedPixel = pixel;
}
texture[addr] = remappedPixel;
addr++;
}
}
Debug.Assert(remappedIndexCounter <= 254, "Exceeded layer count." );
return texture;
}
}
......
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