21#ifndef NAVMAP_CORE__NAVMAP_HPP
22#define NAVMAP_CORE__NAVMAP_HPP
43#include <unordered_map>
87 inline size_t size()
const {
return x.size();}
97 return {
x[id],
y[id],
z[id]};
108 std::vector<uint8_t>
r;
109 std::vector<uint8_t>
g;
110 std::vector<uint8_t>
b;
111 std::vector<uint8_t>
a;
138 virtual const std::string &
name()
const = 0;
141 virtual size_t size()
const = 0;
177 const std::string &
name()
const override {
return name_;}
225 const std::string & name,
229 auto it = layers_.find(name);
230 if (it != layers_.end()) {
231 return std::dynamic_pointer_cast<LayerView<T>>(it->second);
233 auto view = std::make_shared<LayerView<T>>(name, nitems, type);
234 layers_[name] = view;
243 std::shared_ptr<LayerViewBase>
get(
const std::string & name)
const
245 auto it = layers_.find(name);
246 return it == layers_.end() ? nullptr : it->second;
253 std::vector<std::string>
list()
const
255 std::vector<std::string> out;
256 out.reserve(layers_.size());
257 for (
const auto & kv : layers_) {
258 out.push_back(kv.first);
269 return layers_.erase(name) > 0;
281 for (
auto & kv : layers_) {
283 v->data_.resize(nitems);
284 kv.second->mark_dirty();
288 v->data_.resize(nitems);
289 kv.second->mark_dirty();
293 v->data_.resize(nitems);
294 kv.second->mark_dirty();
301 std::unordered_map<std::string, std::shared_ptr<LayerViewBase>> layers_;
332 Eigen::Vector3f
normal{0.0f, 0.0f, 1.0f};
335 std::numeric_limits<uint32_t>::max(),
336 std::numeric_limits<uint32_t>::max(),
337 std::numeric_limits<uint32_t>::max()
497 return {
navcels[cid].neighbor[0],
512 const Eigen::Vector3f & o,
513 const Eigen::Vector3f & d,
516 Eigen::Vector3f & hit_pt)
const;
525 const std::vector<Ray> & rays,
526 std::vector<RayHit> & out,
527 bool first_hit_only =
true)
const;
575 const Eigen::Vector3f & p_world,
576 size_t & surface_idx,
578 Eigen::Vector3f & bary,
579 Eigen::Vector3f * hit_pt)
const;
598 const Eigen::Vector3f & p_world,
599 size_t & surface_idx,
601 Eigen::Vector3f & bary,
602 Eigen::Vector3f * hit_pt,
620 const Eigen::Vector3f & p_world,
621 size_t & surface_idx,
623 Eigen::Vector3f & closest_point,
625 int restrict_surface = -1)
const;
651 uint32_t
add_vertex(
const Eigen::Vector3f & p);
686 const std::string & name,
687 const std::string & description = {},
688 const std::string & unit = {},
689 T default_value = T{})
692 if (v->data().size() !=
navcels.size()) {
693 v->data().assign(
navcels.size(), default_value);
695 layer_meta[name] = LayerMeta{description, unit,
true};
700 bool has_layer(
const std::string & name)
const;
703 std::size_t
layer_size(
const std::string & name)
const;
719 if (
static_cast<size_t>(cid) < view->data().size()) {
720 view->data()[cid] = value;
744 if (
auto view = std::dynamic_pointer_cast<
LayerView<T>>(base)) {
745 const auto & buf = view->data();
746 if (
static_cast<size_t>(cid) < buf.size()) {
754 if (
auto base =
layers.get(name)) {
755 if (
auto v8 = std::dynamic_pointer_cast<LayerView<uint8_t>>(base)) {
756 const auto & buf = v8->data();
757 if (
static_cast<size_t>(cid) >= buf.size()) {
return def;}
758 v =
static_cast<double>(buf[cid]);
759 }
else if (
auto vf = std::dynamic_pointer_cast<LayerView<float>>(base)) {
760 const auto & buf = vf->data();
761 if (
static_cast<size_t>(cid) >= buf.size()) {
return def;}
762 v =
static_cast<double>(buf[cid]);
763 }
else if (
auto vd = std::dynamic_pointer_cast<LayerView<double>>(base)) {
764 const auto & buf = vd->data();
765 if (
static_cast<size_t>(cid) >= buf.size()) {
return def;}
774 if constexpr (std::is_floating_point_v<T>) {
775 return static_cast<T
>(v);
776 }
else if constexpr (std::is_integral_v<T>) {
778 double hi =
static_cast<double>(std::numeric_limits<T>::max());
779 double vv = v < lo ? lo : (v > hi ? hi : v);
780 return static_cast<T
>(std::llround(vv));
782 static_assert(
sizeof(T) == 0,
"Unsupported layer type");
791 std::optional<LayerMeta>
get_layer_meta(
const std::string & name)
const;
809 const std::string & name,
810 const Eigen::Vector3f & p_world,
811 double def = std::numeric_limits<double>::quiet_NaN())
const;
824 std::fill(view->data().begin(), view->data().end(), value);
839 bool layer_copy(
const std::string & src,
const std::string & dst)
847 auto src_base =
layers.get(src);
848 auto src_view = std::dynamic_pointer_cast<LayerView<T>>(src_base);
861 if (src_view->data().size() != dst_view->data().size()) {
866 if (!src_view->data().empty() &&
867 src_view->data().data() == dst_view->data().data())
873 const bool same_hash = (src_view->content_hash() == dst_view->content_hash());
879 dst_view->set_data(src_view->data());
901 const std::string & name,
902 const std::string & description,
903 const std::string & unit,
904 const std::string & src_layer)
907 if (dst->data().size() !=
navcels.size()) {
908 dst->data().assign(
navcels.size(), T{});
920 const std::size_t n = dst->size();
921 for (
NavCelId cid = 0; cid < n; ++cid) {
922 double v =
layer_get<double>(src_layer, cid, std::numeric_limits<double>::quiet_NaN());
923 if (std::isnan(v)) {v = 0.0;}
925 if constexpr (std::is_floating_point_v<T>) {
926 dst->data()[cid] =
static_cast<T
>(v);
927 }
else if constexpr (std::is_integral_v<T>) {
929 double hi =
static_cast<double>(std::numeric_limits<T>::max());
930 if (v < lo) {v = lo;}
931 if (v > hi) {v = hi;}
932 dst->data()[cid] =
static_cast<T
>(std::llround(v));
934 static_assert(
sizeof(T) == 0,
"Unsupported layer type");
948 const Eigen::Vector3f & p_world,
949 std::size_t & surface_idx,
951 Eigen::Vector3f & bary,
952 Eigen::Vector3f * hit_pt,
953 const LocateOpts & opts)
const;
974 const Eigen::Vector3f & p_world,
976 const std::string & layer_name,
984 std::size_t surface_idx = 0;
986 Eigen::Vector3f bary{};
987 Eigen::Vector3f hit_pt{};
988 if (!
locate_navcel(p_world, surface_idx, start_cid, bary, &hit_pt)) {
992 const float cx = hit_pt.x();
993 const float cy = hit_pt.y();
996 auto existing =
layers.get(layer_name);
1005 if (layer->data().size() !=
navcels.size()) {
1006 const_cast<std::vector<T> &
>(layer->data()).resize(
navcels.size(), T{});
1010 const float minx = cx - half, maxx = cx + half;
1011 const float miny = cy - half, maxy = cy + half;
1014 auto tri_aabb_intersects_box = [&](
NavCelId cid) ->
bool {
1015 const auto & tri =
navcels[
static_cast<std::size_t
>(cid)];
1022 const float tminx = std::min({p0.x(), p1.x(), p2.x()});
1023 const float tmaxx = std::max({p0.x(), p1.x(), p2.x()});
1024 const float tminy = std::min({p0.y(), p1.y(), p2.y()});
1025 const float tmaxy = std::max({p0.y(), p1.y(), p2.y()});
1026 if (tmaxx < minx || tminx > maxx || tmaxy < miny || tminy > maxy) {
1032 auto inside_area = [&](
const Eigen::Vector3f & c) ->
bool {
1033 const float dx = c.x() - cx;
1034 const float dy = c.y() - cy;
1036 return (dx * dx + dy * dy) <= r2;
1038 return (std::abs(dx) <= half) && (std::abs(dy) <= half);
1042 std::vector<char> visited(
navcels.size(), 0);
1043 std::deque<NavCelId> q;
1044 q.push_back(start_cid);
1045 visited[
static_cast<std::size_t
>(start_cid)] = 1;
1047 auto & data = layer->mutable_data();
1049 while (!q.empty()) {
1050 const NavCelId cid = q.front(); q.pop_front();
1052 if (!tri_aabb_intersects_box(cid)) {
1057 if (inside_area(c)) {
1058 data[
static_cast<std::size_t
>(cid)] = value;
1062 const std::size_t nidx =
static_cast<std::size_t
>(ncid);
1063 if (nidx <
navcels.size() && !visited[nidx] && tri_aabb_intersects_box(ncid)) {
1075 void ensure_geometry_fingerprint_()
const;
1076 static std::uint64_t hash_geometry_bytes_(
1077 const float *x, std::size_t nx,
1078 const float *y, std::size_t ny,
1079 const float *z, std::size_t nz,
1080 const std::uint32_t *v0, std::size_t nv0,
1081 const std::uint32_t *v1, std::size_t nv1,
1082 const std::uint32_t *v2, std::size_t nv2);
1084 mutable bool geometry_dirty_{
true};
1085 mutable std::uint64_t geometry_fp_{0};
1093 void build_surface_bvh(Surface & s);
1105 bool surface_raycast(
1107 const Eigen::Vector3f & o,
1108 const Eigen::Vector3f & d,
1111 Eigen::Vector3f & hit_pt)
const;
1123 bool locate_by_walking(
1125 const Eigen::Vector3f & p,
1127 Eigen::Vector3f & bary,
1128 Eigen::Vector3f * hit_pt,
1129 float planar_eps)
const;
1141 bool surface_closest_triangle(
1143 const Eigen::Vector3f & p,
1145 Eigen::Vector3f & q,
1146 float & best_sq)
const;
1151 const Eigen::Vector3f & p_world,
1152 size_t & surface_idx,
1154 Eigen::Vector3f & bary,
1155 Eigen::Vector3f * hit_pt)
const
Low-level geometry utilities for NavMap cells (triangles), AABB and basic queries such as ray-triangl...
NavMap()
Copy constructor: deep copy of geometry, surfaces, layers and metadata.
Definition NavMap.cpp:79
Registry of named layers (per-NavCel).
Definition NavMap.hpp:209
bool remove(const std::string &name)
Remove a layer by name.
Definition NavMap.hpp:267
void resize_all(size_t nitems)
Resize all known typed layers to nitems.
Definition NavMap.hpp:279
std::shared_ptr< LayerViewBase > get(const std::string &name) const
Get an existing layer by name (untyped view).
Definition NavMap.hpp:243
std::vector< std::string > list() const
List layer names currently in the registry.
Definition NavMap.hpp:253
std::shared_ptr< LayerView< T > > add_or_get(const std::string &name, size_t nitems, LayerType type)
Add a new typed layer or return an existing one with the same name.
Definition NavMap.hpp:224
std::array< NavCelId, 3 > get_neighbors(NavCelId cid) const
Return the three neighbor NavCel ids of triangle cid.
Definition NavMap.hpp:495
Surface create_surface_obj(const std::string &frame_id) const
Create a standalone Surface object (not yet added to the map).
Definition NavMap.cpp:830
void raycast_many(const std::vector< Ray > &rays, std::vector< RayHit > &out, bool first_hit_only=true) const
Batched raycast.
Definition NavMap.cpp:500
void add_navcel_to_surface(std::size_t surface_index, NavCelId cid)
Add an existing nav cell id to a surface.
Definition NavMap.cpp:871
Eigen::Vector3f navcel_centroid(NavCelId cid) const
Triangle centroid (computed on the fly).
Definition NavMap.cpp:878
bool layer_copy(const std::string &src, const std::string &dst)
Copy values from one layer into another.
Definition NavMap.hpp:839
LayerRegistry layers
Per-NavCel layers (runtime registry)
Definition NavMap.hpp:440
std::vector< NavCel > navcels
All triangles (global indexing)
Definition NavMap.hpp:438
NavCelId add_navcel(uint32_t v0, uint32_t v1, uint32_t v2)
Append a triangle (NavCel) and return its id.
Definition NavMap.cpp:864
bool remove_surface(std::size_t surface_index)
Remove a Surface by index.
Definition NavMap.cpp:849
bool locate_navcel_core(const Eigen::Vector3f &p_world, std::size_t &surface_idx, NavCelId &cid, Eigen::Vector3f &bary, Eigen::Vector3f *hit_pt, const LocateOpts &opts) const
Forward to the existing low-level locator (implemented in .cpp).
Definition NavMap.cpp:627
std::optional< Colors > colors
Optional per-vertex colors.
Definition NavMap.hpp:437
std::shared_ptr< LayerView< T > > add_layer(const std::string &name, const std::string &description, const std::string &unit, const std::string &src_layer)
Create (or get) a typed per-NavCel layer, initialized from another layer.
Definition NavMap.hpp:900
bool locate_navcel(const Eigen::Vector3f &p_world, size_t &surface_idx, NavCelId &cid, Eigen::Vector3f &bary, Eigen::Vector3f *hit_pt) const
Locate the triangle under / near a world point (convenience).
Definition NavMap.hpp:1150
std::string layer_type_name(const std::string &name) const
Human-readable type name for a layer ("float", "double", "uint8", ...).
Definition NavMap.cpp:1011
std::size_t add_surface(const Surface &s)
Append an existing Surface (by value).
Definition NavMap.cpp:837
bool has_same_geometry(const NavMap &other) const
Fast check for identical geometry (vertices and NavCel indices).
Definition NavMap.cpp:137
double sample_layer_at(const std::string &name, const Eigen::Vector3f &p_world, double def=std::numeric_limits< double >::quiet_NaN()) const
Sample a per-NavCel layer at a world position.
Definition NavMap.cpp:1036
void layer_clear(const std::string &name, T value=T{})
Reset all values in a layer to a given value.
Definition NavMap.hpp:821
std::vector< NavCelId > navcel_neighbors(NavCelId cid) const
Return up to 3 neighbor cell ids (skips invalid entries).
Definition NavMap.cpp:887
bool set_area(const Eigen::Vector3f &p_world, T value, const std::string &layer_name, AreaShape shape, float size)
Set a per-NavCel layer to a constant value over a 2D area.
Definition NavMap.hpp:973
uint32_t add_vertex(const Eigen::Vector3f &p)
Append a vertex and return its index.
Definition NavMap.cpp:856
std::vector< Surface > surfaces
Surfaces (partitions of navcels)
Definition NavMap.hpp:439
std::shared_ptr< LayerView< T > > add_layer(const std::string &name, const std::string &description={}, const std::string &unit={}, T default_value=T{})
Create (or get) a typed per-NavCel layer with a default value.
Definition NavMap.hpp:685
void mark_vertex_updated(PointId)
Mark a vertex as updated (reserved for future cache invalidation).
Definition NavMap.hpp:488
T navcel_value(NavCelId cid, const LayerView< T > &layer) const
Read the value of a typed per-NavCel layer at triangle cid.
Definition NavMap.hpp:539
std::vector< std::string > list_layers() const
List all layer names currently stored.
Definition NavMap.cpp:1031
std::optional< LayerMeta > get_layer_meta(const std::string &name) const
Return metadata for a layer if present (implementation-defined).
Definition NavMap.cpp:1024
NavMap & operator=(const NavMap &other)
Copy assignment optimized to avoid geometry duplication.
Definition NavMap.cpp:153
bool locate_navcel(const Eigen::Vector3f &p_world, size_t &surface_idx, NavCelId &cid, Eigen::Vector3f &bary, Eigen::Vector3f *hit_pt, const LocateOpts &opts) const
Locate the triangle under / near a world point.
Positions positions
Vertex positions (SoA)
Definition NavMap.hpp:436
void layer_set(const std::string &name, NavCelId cid, T value)
Set a per-cell value (creates/retypes the layer if needed).
Definition NavMap.hpp:716
std::size_t create_surface(std::string frame_id)
Create a new empty Surface and append it to the map.
Definition NavMap.cpp:823
void build_adjacency()
Build topological adjacency between neighboring NavCels.
Definition NavMap.cpp:259
bool has_layer(const std::string &name) const
Check whether a layer named name exists.
Definition NavMap.cpp:1000
NavMap()
Copy constructor: deep copy of geometry, surfaces, layers and metadata.
Definition NavMap.cpp:79
std::size_t layer_size(const std::string &name) const
Number of entries in a layer (should equal navcels.size()).
Definition NavMap.cpp:1005
bool raycast(const Eigen::Vector3f &o, const Eigen::Vector3f &d, NavCelId &hit_cid, float &t, Eigen::Vector3f &hit_pt) const
Raycast against all surfaces to find the closest hit.
Definition NavMap.cpp:466
void rebuild_geometry_accels()
Recompute derived geometry and acceleration structures.
Definition NavMap.cpp:386
T layer_get(const std::string &name, NavCelId cid, T def=T{}) const
Get a per-cell value as the requested type.
Definition NavMap.hpp:741
bool closest_triangle(const Eigen::Vector3f &p_world, size_t &surface_idx, NavCelId &cid, Eigen::Vector3f &closest_point, float &sqdist, int restrict_surface=-1) const
Find the closest triangle to a point.
Definition NavMap.cpp:764
std::unordered_map< std::string, LayerMeta > layer_meta
Optional metadata per layer.
Definition NavMap.hpp:441
Definition Geometry.hpp:40
constexpr LayerType layer_type_tag< double >()
Definition NavMap.hpp:409
constexpr LayerType layer_type_tag< uint8_t >()
Definition NavMap.hpp:407
LayerType
Runtime type tag for a layer's scalar storage.
Definition NavMap.hpp:123
@ F64
Definition NavMap.hpp:123
@ F32
Definition NavMap.hpp:123
@ U8
Definition NavMap.hpp:123
AreaShape
Shape selector for area-writing APIs.
Definition NavMap.hpp:414
@ RECTANGULAR
Definition NavMap.hpp:414
@ CIRCULAR
Definition NavMap.hpp:414
constexpr LayerType layer_type_tag()
Helper to map C++ scalar type to navmap::LayerType tag.
uint32_t NavCelId
Index of a triangle (NavCel) within the global mesh.
Definition NavMap.hpp:65
uint32_t PointId
Index into the per-vertex position arrays (SoA).
Definition NavMap.hpp:63
constexpr LayerType layer_type_tag< float >()
Definition NavMap.hpp:408
LayerView(std::string name, size_t nitems, LayerType t)
Construct a typed view.
Definition NavMap.hpp:173
Options for the locate functions.
Definition NavMap.hpp:554
Axis-aligned bounding box.
Definition Geometry.hpp:152
Node in a per-surface bounding volume hierarchy (BVH).
Definition NavMap.hpp:348
int right
Right child index (or -1 for leaf)
Definition NavMap.hpp:351
int start
Start index in primitive array (leaf only)
Definition NavMap.hpp:352
bool is_leaf() const
Definition NavMap.hpp:354
int count
Number of primitives in leaf (0 for inner nodes)
Definition NavMap.hpp:353
int left
Left child index (or -1 for leaf)
Definition NavMap.hpp:350
AABB box
Bounding box of this node (world coordinates)
Definition NavMap.hpp:349
Optional per-vertex colors (RGBA, 8-bit per channel).
Definition NavMap.hpp:107
std::vector< uint8_t > r
Red channel.
Definition NavMap.hpp:108
std::vector< uint8_t > a
Alpha channel.
Definition NavMap.hpp:111
std::vector< uint8_t > g
Green channel.
Definition NavMap.hpp:109
std::vector< uint8_t > b
Blue channel.
Definition NavMap.hpp:110
Non-templated base for runtime layer handling.
Definition NavMap.hpp:131
virtual LayerType type() const =0
virtual const std::string & name() const =0
virtual std::uint64_t content_hash() const =0
Return 64-bit content hash (cached; recomputed lazily).
std::uint64_t hash_cache_
Definition NavMap.hpp:151
void mark_dirty() const noexcept
Mark content dirty (forces hash recompute on next query).
Definition NavMap.hpp:147
virtual size_t size() const =0
virtual ~LayerViewBase()=default
bool hash_dirty_
Definition NavMap.hpp:150
Typed layer view storing one T value per NavCel.
Definition NavMap.hpp:162
std::uint64_t content_hash() const override
Return 64-bit content hash (cached; recomputed lazily).
Definition NavMap.cpp:47
const std::vector< T > & data() const
Definition NavMap.hpp:189
void set_data(const std::vector< T > &v)
Definition NavMap.hpp:197
std::string name_
Layer name (key in the registry)
Definition NavMap.hpp:163
std::vector< T > data_
Values, one per NavCel.
Definition NavMap.hpp:164
LayerType type_
Runtime type tag (must match T)
Definition NavMap.hpp:165
LayerType type() const override
Definition NavMap.hpp:176
const std::string & name() const override
Definition NavMap.hpp:177
const T & operator[](NavCelId cid) const
Definition NavMap.hpp:183
std::vector< T > & mutable_data() const
Definition NavMap.hpp:193
T & operator[](NavCelId cid)
Definition NavMap.hpp:182
size_t size() const override
Definition NavMap.hpp:178
LayerView(std::string name, size_t nitems, LayerType t)
Construct a typed view.
Definition NavMap.hpp:173
std::vector< T > & data()
Definition NavMap.hpp:187
Navigation cell (triangle) with geometry and adjacency.
Definition NavMap.hpp:330
uint32_t layer_dirty_mask
Reserved for future per-layer flags.
Definition NavMap.hpp:339
Eigen::Vector3f normal
Unit normal of the triangle.
Definition NavMap.hpp:332
NavCelId neighbor[3]
Neighbor cids across edges 0,1,2.
Definition NavMap.hpp:334
float area
Triangle area (m²)
Definition NavMap.hpp:333
PointId v[3]
Indices into navmap::Positions.
Definition NavMap.hpp:331
Options for the locate functions.
Definition NavMap.hpp:554
std::optional< NavCelId > hint_cid
Optional triangle hint for walking.
Definition NavMap.hpp:555
std::optional< size_t > hint_surface
Optional surface hint.
Definition NavMap.hpp:556
bool use_downward_ray
Downward ray on fallback (else upward)
Definition NavMap.hpp:559
float height_eps
Z tolerance for vertical fallback (meters)
Definition NavMap.hpp:558
float planar_eps
In-plane barycentric tolerance.
Definition NavMap.hpp:557
Structure-of-arrays for storing 3D vertex positions.
Definition NavMap.hpp:81
Eigen::Vector3f at(PointId id) const
Returns vertex id as a 3D vector.
Definition NavMap.hpp:95
size_t size() const
Definition NavMap.hpp:87
std::vector< float > x
X coordinates (meters)
Definition NavMap.hpp:82
std::vector< float > z
Z coordinates (meters)
Definition NavMap.hpp:84
std::vector< float > y
Y coordinates (meters)
Definition NavMap.hpp:83
Result of a raycast against the NavMap.
Definition NavMap.hpp:393
Eigen::Vector3f p
World coordinates of intersection.
Definition NavMap.hpp:398
bool hit
True if the ray hit any triangle.
Definition NavMap.hpp:394
size_t surface
Index of surface hit.
Definition NavMap.hpp:395
NavCelId cid
Id of the NavCel hit.
Definition NavMap.hpp:396
float t
Distance along the ray (units of d)
Definition NavMap.hpp:397
Simple ray (origin + direction).
Definition NavMap.hpp:382
Eigen::Vector3f o
Origin of the ray (world)
Definition NavMap.hpp:383
Eigen::Vector3f d
Direction of the ray (unit length recommended)
Definition NavMap.hpp:384
A connected set of NavCels in a common reference frame.
Definition NavMap.hpp:364
std::vector< BVHNode > bvh
BVH nodes for this surface.
Definition NavMap.hpp:369
AABB aabb
Bounds of the surface geometry.
Definition NavMap.hpp:367
std::vector< NavCelId > navcels
NavCels belonging to this surface (global ids)
Definition NavMap.hpp:366
std::string frame_id
Frame id of this surface.
Definition NavMap.hpp:365
std::vector< int > prim_indices
Compact list of cids used by BVH leaves.
Definition NavMap.hpp:368