HammeriteNavigationSurface
Navigation. Inherits RefCounted
One convex patch of ground an agent could stand on, and what is measured about it.
The measurements are the point. They are facts about the GEOMETRY - how much headroom there is, how wide the passage is, how steep the ground - and carry no notion of who might walk here. A game turns them into "a guard fits, a rat fits, a brute does not" by comparing them against its own agent profiles, which is what keeps this addon free of any particular game's bestiary. Convex because the world hands it over that way: the compiler already decomposes cell walls into convex pieces with the portal apertures punched out, which is the expensive half of what a navigation mesh baker normally does from scratch. For tools. A game does not see these: a bake keeps the meshes made from them and lets them go, and a bake read from the cache never had them. A tool that wants them runs HammeriteNavigationBuilder.build_surfaces() itself.
Properties
| Type | Name | Default |
|---|---|---|
PackedVector3Array | polygon | PackedVector3Array() |
Vector2i | room_key | Vector2i(0, 0) |
Vector3 | normal | Vector3(0, 1, 0) |
float | clearance | inf |
float | width | 0.0 |
float | slope_degrees | 0.0 |
float | water_depth | 0.0 |
float | travel_cost | 1.0 |
Methods
| Returns | Method |
|---|---|
float | area() |
Vector3 | centroid() |
PackedVector2Array | plan_polygon() |
bool | contains_plan(plan_point: Vector2) |
float | height_at(plan_point: Vector2) |
Property descriptions
polygon
var polygon: PackedVector3Array = PackedVector3Array()
The walkable polygon in the map's space, wound counter-clockwise seen from above.
room_key
var room_key: Vector2i = Vector2i(0, 0)
The room this patch belongs to (HammeriteCell.key()) - a room, not a NavigationRegion3D, of which a room has one per set of agents that use its ground alike. Ground is chunked by room because that is how the world is already divided, and because layers and travel costs are carried per region and can differ from one room to the next - not so that an edit can rebake a single room, which is something the bake does not do.
normal
var normal: Vector3 = Vector3(0, 1, 0)
Upward normal of the ground here. Flat floor is Vector3.UP.
clearance
var clearance: float = inf
Free height above this patch, in world units, before something stops an agent standing up: the ceiling of the room, the underside of a crate, a beam. INF where nothing was found above. This is the measurement that does the most work. An agent walks here if its height fits; a vent with 40 units of headroom is a route for a rat and a wall for a guard, from one number.
width
var width: float = 0.0
How wide a body can stand here, in world units: twice the furthest the patch gets from the edge of the floor it is part of. A corridor a body cannot fit down is narrow whatever its floor area, and a sliver of a wide floor is not.
slope_degrees
var slope_degrees: float = 0.0
Angle of the ground from horizontal, in degrees. Zero is flat.
water_depth
var water_depth: float = 0.0
How deep the water standing over this patch is, in world units: from the ground up to the water line of the water-filled brush it is under (#64). Zero is dry ground. An agent's profile decides whether that is wading, swimming or nowhere it goes.
travel_cost
var travel_cost: float = 1.0
What the author says crossing this room costs, as a multiple of the distance (HammeriteNavigationBrushProperties). The one thing here that is not measured: no amount of geometry says that a floor is slick with mud. An agent's own opinion of the place multiplies this rather than replacing it.
Method descriptions
area()
func area() -> float
Area of the patch, world units².
centroid()
func centroid() -> Vector3
Mean of the patch's vertices - inside it, since it is convex.
plan_polygon()
func plan_polygon() -> PackedVector2Array
This patch's footprint, as a polygon in the x/z plane. Counter-clockwise, like polygon.
contains_plan()
func contains_plan(plan_point: Vector2) -> bool
Is plan_point (an x/z point) over this patch?
height_at()
func height_at(plan_point: Vector2) -> float
The height of the ground at plan_point, following the patch's slope. Extrapolates beyond the patch rather than clamping to it, which is what the callers want: a link probes just outside a ledge to find what is below, and the answer should be the plane the ledge is on, not its nearest vertex.