Files
WickedEngine/WickedEngine/wiPathQuery.h
2024-04-11 10:07:05 +02:00

98 lines
3.1 KiB
C++

#pragma once
#include "CommonInclude.h"
#include "wiUnorderedMap.h"
#include "wiVector.h"
#include "wiVoxelGrid.h"
#include "wiGraphicsDevice.h"
#include "wiPrimitive.h"
#include <queue>
namespace wi
{
struct PathQuery
{
struct Node
{
uint16_t x = 0;
uint16_t y = 0;
uint16_t z = 0;
uint16_t cost = 0;
constexpr XMUINT3 coord() const
{
return XMUINT3(x, y, z);
}
static constexpr Node create(XMUINT3 coord)
{
Node node = {};
node.x = coord.x;
node.y = coord.y;
node.z = coord.z;
return node;
}
static constexpr Node invalid()
{
return {};
}
constexpr bool operator>(const Node& other) const { return cost > other.cost; } // for priority_queue
constexpr bool operator<(const Node& other) const { return cost < other.cost; } // for priority_queue
constexpr operator uint64_t() const { return uint64_t(uint64_t(x) | (uint64_t(y) << 16ull) | (uint64_t(z) << 32ull)); } // for unordered_map
};
std::priority_queue<Node, wi::vector<Node>, std::greater<Node>> frontier;
wi::unordered_map<uint64_t, Node> came_from;
wi::unordered_map<uint64_t, uint16_t> cost_so_far;
wi::vector<XMFLOAT3> result_path_goal_to_start;
wi::vector<XMFLOAT3> result_path_goal_to_start_simplified;
XMFLOAT3 process_startpos = XMFLOAT3(0, 0, 0);
bool flying = false; // if set to true, it will switch to navigating on empty voxels
int agent_height = 1; // keep away from vertical obstacles by this many voxels
int agent_width = 0; // keep away from horizontal obstacles by this many voxels
// Find the path between startpos and goalpos in the voxel grid:
void process(
const XMFLOAT3& startpos,
const XMFLOAT3& goalpos,
const wi::VoxelGrid& voxelgrid
);
bool is_succesful() const;
// Search for a cover location that can hide the subject from observer.
// observer: location to hide from
// subject: location of who wants to hide
// direction: subject's search direction
// max_distance: maximum search distance
// voxelgrid: voxel grid to perform the search in
// returns whether a suitable cover was found or not
bool search_cover(
const XMFLOAT3& observer,
const XMFLOAT3& subject,
const XMFLOAT3& direction,
float max_distance,
const wi::VoxelGrid& voxelgrid
);
// Gets the next upcoming waypoint between start and goal that was used in process():
XMFLOAT3 get_next_waypoint() const;
// Gets the number of resulting waypoints
size_t get_waypoint_count() const;
// Gets the result waypoint at specified index (direction: start -> goal)
XMFLOAT3 get_waypoint(size_t index) const;
XMFLOAT3 get_goal() const;
bool is_voxel_valid(const VoxelGrid& voxelgrid, XMUINT3 coord) const;
bool debug_voxels = true;
mutable float debugtimer = 0;
XMFLOAT3 debugvoxelsize = XMFLOAT3(0, 0, 0);
XMFLOAT3 debugstartnode = XMFLOAT3(0, 0, 0);
XMFLOAT3 debuggoalnode = XMFLOAT3(0, 0, 0);
bool debug_waypoints = false; // if true, waypoint voxels will be drawn. Blue = waypoint, Pink = simplified waypoint
void debugdraw(const XMFLOAT4X4& ViewProjection, wi::graphics::CommandList cmd) const;
};
}