simvx.core.navigation3d.mesh

NavigationMesh3D — triangle-based navmesh with A* pathfinding.

Module Contents

Classes

NavigationMesh3D

3D navigation mesh with triangle-based A* pathfinding.

Data

log

API

simvx.core.navigation3d.mesh.log[source]

‘getLogger(…)’

class simvx.core.navigation3d.mesh.NavigationMesh3D[source]

3D navigation mesh with triangle-based A* pathfinding.

Stores walkable geometry as triangles and builds an adjacency graph for pathfinding. Supports manual polygon insertion and automated bake from level geometry.

Initialization

property vertices: numpy.ndarray

(N, 3) float32 array of mesh vertices.

property triangles: numpy.ndarray

(M, 3) int32 array of triangle vertex indices.

property triangle_count: int
add_polygon(vertices: list[simvx.core.math.types.Vec3], cell_size: float = 0.0) None[source]

Add a walkable polygon.

Without cell_size the polygon is fan-triangulated from the first vertex (fast, 2 triangles for a quad). When cell_size is positive the polygon’s axis-aligned bounding box is subdivided into a regular grid of right-triangles, keeping only cells whose centres fall inside the polygon. The finer mesh is required for obstacle carving to work at useful resolution.

Args: vertices: 3+ coplanar points defining the polygon boundary. cell_size: When > 0, grid cell size for subdivision. Typical values: 0.5 – 2.0 depending on obstacle density.

add_triangle(v0: simvx.core.math.types.Vec3, v1: simvx.core.math.types.Vec3, v2: simvx.core.math.types.Vec3) None[source]

Add a single walkable triangle.

add_obstacle(vertices: list[simvx.core.math.types.Vec3]) None[source]

Subtract an obstacle region from the walkable area.

The polygon is projected onto the XZ plane. Any navmesh triangle whose centroid falls inside the obstacle polygon (or whose area overlaps it significantly) is marked as blocked and excluded from pathfinding.

Args: vertices: 3+ points defining the obstacle boundary (Y is ignored).

clear() None[source]

Remove all polygons, obstacles, and cached data.

bake_from_geometry(mesh_vertices: numpy.ndarray, mesh_indices: numpy.ndarray, agent_radius: float = 0.5, agent_height: float = 2.0, max_slope: float = 45.0, cell_size: float = 0.3, cell_height: float = 0.2) None[source]

Generate navmesh from level geometry using simplified Recast-style algorithm.

Steps: 1. Voxelize geometry into a height field 2. Mark walkable voxels (slope < max_slope, clearance > agent_height) 3. Build regions from connected walkable areas 4. Extract contours and triangulate

Args: mesh_vertices: (N, 3) float32 array of source mesh vertices. mesh_indices: (M, 3) int32 array of triangle indices. agent_radius: Agent capsule radius for erosion. agent_height: Minimum clearance height. max_slope: Maximum walkable slope in degrees. cell_size: Horizontal voxel size. cell_height: Vertical voxel size.

find_path(start: simvx.core.math.types.Vec3, end: simvx.core.math.types.Vec3) list[simvx.core.math.types.Vec3][source]

A* pathfinding on the navmesh triangle graph.

Finds the shortest path from start to end by searching through connected triangles. Returns a list of waypoints (triangle centroids + start/end) forming the path, or an empty list if no path exists.

Args: start: Start position in world space. end: End position in world space.

Returns: List of Vec3 waypoints, or empty list if unreachable.

get_closest_point(point: simvx.core.math.types.Vec3) simvx.core.math.types.Vec3[source]

Snap a point to the nearest navmesh surface.

Args: point: Query point in world space.

Returns: Closest point on the navmesh surface.

is_point_on_mesh(point: simvx.core.math.types.Vec3, tolerance: float = 0.5) bool[source]

Test if a point is on the walkable area.

Args: point: Query point in world space. tolerance: Maximum distance from navmesh surface to still count.

Returns: True if point is within tolerance of the navmesh.

sample_position(center: simvx.core.math.types.Vec3, radius: float, max_attempts: int = 30) simvx.core.math.types.Vec3 | None[source]

Sample a random point near center that lies on the navmesh.

Args: center: Center of the sampling sphere. radius: Maximum distance from center. max_attempts: Number of random samples to try.

Returns: A random point on the navmesh within radius, or None if not found.