public List<Vertices> detectVertices()
{
#region Check TextureConverter setup.
if( _data == null )
throw new Exception( "'_data' can't be null. You have to use SetTextureData(uint[] data, int width) before calling this method." );
if( _data.Length < 4 )
throw new Exception( "'_data' length can't be less then 4. Your texture must be at least 2 x 2 pixels in size. " +
"You have to use SetTextureData(uint[] data, int width) before calling this method." );
if( _width < 2 )
throw new Exception( "'_width' can't be less then 2. Your texture must be at least 2 x 2 pixels in size. " +
"You have to use SetTextureData(uint[] data, int width) before calling this method." );
if( _data.Length % _width != 0 )
throw new Exception( "'_width' has an invalid value. You have to use SetTextureData(uint[] data, int width) before calling this method." );
#endregion
var detectedPolygons = new List<Vertices>();
Vector2? holeEntrance = null;
Vector2? polygonEntrance = null;
List<Vector2> blackList = new List<Vector2>();
bool searchOn;
do
{
Vertices polygon;
if( detectedPolygons.Count == 0 )
{
// First pass / single polygon
polygon = new Vertices( createSimplePolygon( Vector2.Zero, Vector2.Zero ) );
if( polygon.Count > 2 )
polygonEntrance = getTopMostVertex( polygon );
}
else if( polygonEntrance.HasValue )
{
// Multi pass / multiple polygons
polygon = new Vertices( createSimplePolygon( polygonEntrance.Value, new Vector2( polygonEntrance.Value.X - 1f, polygonEntrance.Value.Y ) ) );
}
else
break;
searchOn = false;
if( polygon.Count > 2 )
{
if( _holeDetection )
{
do
{
holeEntrance = searchHoleEntrance( polygon, holeEntrance );
if( holeEntrance.HasValue )
{
if( !blackList.Contains( holeEntrance.Value ) )
{
blackList.Add( holeEntrance.Value );
Vertices holePolygon = createSimplePolygon( holeEntrance.Value,
new Vector2( holeEntrance.Value.X + 1, holeEntrance.Value.Y ) );
if( holePolygon != null && holePolygon.Count > 2 )
{
switch( _polygonDetectionType )
{
case VerticesDetectionType.Integrated:
// Add first hole polygon vertex to close the hole polygon.
holePolygon.Add( holePolygon[0] );
int vertex1Index, vertex2Index;
if( splitPolygonEdge( polygon, holeEntrance.Value, out vertex1Index, out vertex2Index ) )
polygon.InsertRange( vertex2Index, holePolygon );
break;
case VerticesDetectionType.Separated:
if( polygon.holes == null )
polygon.holes = new List<Vertices>();
polygon.holes.Add( holePolygon );
break;
}
}
}
else
break;
}
else
break;
}
while( true );
}
detectedPolygons.Add( polygon );
}
if( _multipartDetection || polygon.Count <= 2 )
{
if( searchNextHullEntrance( detectedPolygons, polygonEntrance.Value, out polygonEntrance ) )
searchOn = true;
}
}
while( searchOn );
if( detectedPolygons == null || ( detectedPolygons != null && detectedPolygons.Count == 0 ) )
throw new Exception( "Couldn't detect any vertices." );
// Post processing.
if( polygonDetectionType == VerticesDetectionType.Separated ) // Only when VerticesDetectionType.Separated? -> Recheck.
applyTriangulationCompatibleWinding( ref detectedPolygons );
if( _transform != Matrix.Identity )
applyTransform( ref detectedPolygons );
return detectedPolygons;
}