VIPRA Documentation
Loading...
Searching...
No Matches
target_nearest.hpp
1#pragma once
2
3#include <limits>
4#include <optional>
5#include <utility>
6
7#include "vipra/geometry/f3d.hpp"
8
9#include "vipra/vipra_behaviors/definitions/pedestrian_types.hpp"
10#include "vipra/vipra_behaviors/definitions/sim_pack.hpp"
11#include "vipra/vipra_behaviors/targets/target.hpp"
12#include "vipra/vipra_behaviors/targets/target_modifier.hpp"
13
14namespace VIPRA::Behaviors {
19struct TargetNearest {
20 NON_DEFAULT_CONSTRUCTIBLE(TargetNearest)
21 COPYABLE(TargetNearest)
22 MOVEABLE(TargetNearest)
23
24 Ptype type;
25 bool allPeds;
26 std::optional<TargetModifier> modifier;
27
28 explicit TargetNearest(Ptype type, bool allPeds = false,
29 std::optional<TargetModifier> modifier = std::nullopt)
30 : type(type), allPeds(allPeds), modifier(std::move(modifier))
31 {
32 }
33
41 inline auto operator()(Simpack pack, Self self) const -> Target
42 {
43 if ( allPeds ) {
44 auto curr = nearest_in_group(pack, self.target.targetIdx, pack.groups.get_group(0));
45 if ( curr.second == VIPRA::INVALID_IDX ) return Target{TargetType::INVALID, 0};
46 return {TargetType::PEDESTRIAN, curr.second};
47 }
48
49 VIPRA::f_pnt shortest = std::numeric_limits<VIPRA::f_pnt>::max();
50 VIPRA::idx nearest = VIPRA::INVALID_IDX;
51
52 type.for_each_type([&](typeUID type) {
53 VIPRA::idx groupIdx = GroupsContainer::index(type);
54 auto curr =
55 nearest_in_group(pack, self.target.targetIdx, pack.groups.get_group(groupIdx));
56 if ( curr.first < shortest ) {
57 shortest = curr.first;
58 nearest = curr.second;
59 }
60 });
61
62 if ( nearest == VIPRA::INVALID_IDX ) {
63 return Target{TargetType::INVALID, 0};
64 }
65
66 return Target{TargetType::PEDESTRIAN, nearest};
67 }
68
69 private:
78 [[nodiscard]] inline auto nearest_in_group(Simpack pack, VIPRA::idx self,
79 VIPRA::idxVec const& idxs) const
80 -> std::pair<VIPRA::f_pnt, VIPRA::idx>
81 {
82 VIPRA::f_pnt shortest = std::numeric_limits<VIPRA::f_pnt>::max();
83 VIPRA::idx nearest = VIPRA::INVALID_IDX;
84
85 auto const& coords = pack.pedset.all_coords();
86 const VIPRA::f3d currCoords = coords[self];
87
88 nearest = pack.pedset.conditional_closest_ped(self, [&](VIPRA::idx other) {
89 if ( std::find(idxs.begin(), idxs.end(), other) == idxs.end() ) return false;
90
91 if ( modifier ) {
92 if ( ! modifier->check(pack, self, other) ) return false;
93 }
94
95 if ( pack.map.ray_hit(currCoords, coords[other]) != -1 ) return false;
96
97 return true;
98 });
99
100 return {currCoords.distance_to(coords[nearest]), nearest};
101 }
102};
103} // namespace VIPRA::Behaviors
static constexpr auto index(typeUID type) -> VIPRA::idx
Gets the index into the container for a given type.
Definition pedestrian_groups.hpp:28
Pedestrian Type, used as a composite of typeUIDs.
Definition pedestrian_types.hpp:23
Struct for explicitly targeting the self.
Definition target.hpp:27
Holds references to commonly used parameters for simpler passing.
Definition sim_pack.hpp:23
auto operator()(Simpack pack, Self self) const -> Target
Returns the nearest pedestrian that has any of the target types.
Definition target_nearest.hpp:41
Holds information about what to target.
Definition target.hpp:18
Definition f3d.hpp:27