You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: contour.rs
    path of file: ./repos/oxidized_navigation/src
    
    the code of the file until where you have to start completion: use std::cmp::Ordering;

use bevy::{prelude::{IVec2, UVec2, UVec4}, log::warn};

use crate::{
    get_neighbour_index,
    heightfields::{OpenSpan, OpenTile}, Area,
};

use super::{in_cone, intersect, NavMeshSettings, FLAG_BORDER_VERTEX, MASK_CONTOUR_REGION};

#[derive(Default, Clone, Debug)]
pub struct Contour {
    pub vertices: Vec<UVec4>,
    pub region: u16,
    /// Unlike [OpenSpan] this can't be ``None`` as ``None`` spans are ignored when generating contours.  
    pub area: Area,
}

#[derive(Default)]
pub struct ContourSet {
    pub contours: Vec<Contour>,
}

#[derive(Default, Clone)]
struct ContourHole {
    contour: Contour,
    min_x: u32,
    min_z: u32,
    left_most_vertex: u32,
}

#[derive(Default, Clone)]
struct ContourRegion {
    outline: Option<Contour>,
    holes: Vec<ContourHole>,
}

pub fn build_contours(open_tile: OpenTile, nav_mesh_settings: &NavMeshSettings) -> ContourSet {
    let max_contours = open_tile.max_regions.max(8);
    let mut contour_set = ContourSet {
        contours: Vec::with_capacity(max_contours.into()),
    };
    let tile_side = nav_mesh_settings.get_tile_side_with_border();

    // Mark boundaries.
    let mut boundry_flags = vec![0u8; open_tile.span_count];
    for (cell_index, cell) in open_tile.cells.iter().enumerate() {
        for span in cell.spans.iter() {
            let mut res = 0;

            for dir in 0..4 {
                let mut other_region = 0;
                if let Some(span_index) = span.neighbours[dir] {
                    let other_span = &open_tile.cells
  
    
pub fn build_contours(open_tile: OpenTile, nav_mesh_settings: &NavMeshSettings) -> ContourSet {
    let max_contours = open_tile.max_regions.max(8);
    let mut contour_set = ContourSet {
        contours: Vec::with_capacity(max_contours.into()),
    };
    let tile_side = nav_mesh_settings.get_tile_side_with_border();

    // Mark boundaries.
    let mut boundry_flags = vec![0u8; open_tile.span_count];
    for (cell_index, cell) in open_tile.cells.iter().enumerate() {
        for span in cell.spans.iter() {
            let mut res = 0;

            for dir in 0..4 {
                let mut other_region = 0;
                if let Some(span_index) = span.neighbours[dir] {
                    let other_span = &open_tile.cells
                        [get_neighbour_index(tile_side, cell_index, dir)]
                    .spans[span_index as usize];
                    other_region = other_span.region;
                }

                if span.region == other_region {
                    res |= 1 << dir;
                }
            }

            boundry_flags[span.tile_index] = res ^ 0b1111; // Flip so we mark unconnected sides.
        }
    }

    let mut vertices = Vec::with_capacity(256);
    let mut simplified_vertices = Vec::with_capacity(64);

    for (cell_index, cell) in open_tile.cells.iter().enumerate() {
        for (span_index, span) in cell.spans.iter().enumerate() {
            if boundry_flags[span.tile_index] == 0 || boundry_flags[span.tile_index] == 0b1111 {
                boundry_flags[span.tile_index] = 0;
                continue;
            }
            if span.region == 0 {
                continue;
            }
            let Some(area) = open_tile.areas[span.tile_index] else {
                continue;
            };

            vertices.clear();
            simplified_vertices.clear();

            // Walk contour
            walk_contour(
                cell_index,
                span_index,
                &open_tile,
                nav_mesh_settings,
                &mut boundry_flags,
                &mut vertices,
            );

            // Simplify contour
            simplify_contour(
                &vertices,
                &mut simplified_vertices,
                nav_mesh_settings.max_contour_simplification_error,
                nav_mesh_settings.max_edge_length,
            );

            // Remove degenerate segments.
            remove_degenerate_segments(&mut simplified_vertices);

            if simplified_vertices.len() >= 3 {
                let new_contour = Contour {
                    vertices: simplified_vertices.clone(),
                    region: span.region,
                    area,
                };

                contour_set.contours.push(new_contour);
            }
        }
    }

    // handle holes.
    if !contour_set.contours.is_empty() {
        #[derive(Clone, Copy)]
        enum Winding {
            Outline,
            Hole,
        }

        let mut winding = vec![Winding::Hole; contour_set.contours.len()];
        let mut num_holes = 0;
        for (i, contour) in contour_set.contours.iter().enumerate() {
            let contour_winding = calc_area_of_polygon_2d(&contour.vertices);

            if contour_winding < 0 {
                num_holes += 1;
                winding[i] = Winding::Hole;
            } else {
                winding[i] = Winding::Outline;
            }
        }

        if num_holes > 0 {
            let num_regions = open_tile.max_regions + 1;
            let mut regions = vec![ContourRegion::default(); num_regions.into()];

            for (contour, winding) in contour_set.contours.iter().zip(winding) {
                match winding {
                    Winding::Outline => {
                        regions[contour.region as usize].outline = Some(contour.clone());
                    }
                    Winding::Hole => {
                        regions[contour.region as usize].holes.push(ContourHole {
                            contour: contour.clone(),
                            min_x: contour.vertices[0].x,
                            min_z: contour.vertices[0].z,
                            left_most_vertex: 0,
                        });
                    }
                }
            }

            for region in regions
                .iter_mut()
                .filter(|region| !region.holes.is_empty() && region.outline.is_some())
            {
                merge_region_holes(region);
            }
        }
    }

    contour_set
}