Skip to content

Commit

Permalink
[Pathfinding] Add config file for force including or removing sectors.
Browse files Browse the repository at this point in the history
  • Loading branch information
num0005 committed Oct 15, 2018
1 parent e58ac77 commit 16d809e
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 35 deletions.
110 changes: 105 additions & 5 deletions H2Codez/Common/Pathfinding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <map>
#include <unordered_set>
#include <functional>
#include "../util/string_util.h"

using namespace pathfinding;

Expand All @@ -27,8 +28,100 @@ inline t_data get_idx(const std::map<t_index, t_data, Compare, Allocator> &map,
return NONE;
}

bool pathfinding::generate(scenario_structure_bsp_block *sbsp)
class pathfinding_settings_parser
{
public:
bool parse_file(std::ifstream &file)
{
const static std::string remove_header = "[remove]";
const static std::string keep_header = "[keep]";
enum mode
{
undefined,
keep,
remove
};
mode current_mode = undefined;
while (file)
{
std::string line;
std::getline(file, line);
str_trim(line);
line = tolower(line);

if (line == keep_header)
{
current_mode = keep;
continue;
}
if (line == remove_header)
{
current_mode = remove;
continue;
}

unsigned short surface_idx = NONE;
try {
surface_idx = static_cast<unsigned short>(std::stoul(line));
} catch(...) {
continue;
}
if (LOG_CHECK(current_mode != undefined))
{
switch (current_mode)
{
case remove:
surfaces_to_remove.insert(surface_idx);
case keep:
surfaces_to_keep.insert(surface_idx);
}
} else {
return false;
}
}
return !file.bad();
}

bool parse_file(const std::string &file_name)
{
std::ifstream file(file_name);
if (file)
{
return parse_file(file);
}
return false;
}

pathfinding_settings_parser(const std::string &file_name)
{
parse_file(file_name);
}
pathfinding_settings_parser() {};

bool force_keep_surface(unsigned short surface)
{
return keep_surface(surface) && surfaces_to_keep.count(surface) > 0;
}

bool keep_surface(unsigned short surface)
{
return !remove_surface(surface);
}

bool remove_surface(unsigned short surface)
{
return surfaces_to_remove.count(surface) > 0;
}

private:

std::unordered_set<unsigned short> surfaces_to_remove;
std::unordered_set<unsigned short> surfaces_to_keep;
};

bool pathfinding::generate(datum sbsp_tag)
{
auto *sbsp = tags::get_tag<scenario_structure_bsp_block>('sbsp', sbsp_tag);
if (LOG_CHECK(sbsp->pathfindingData.size == 0)) // check the map has no pathfinding
{
tags::resize_block(&sbsp->pathfindingData, 1);
Expand All @@ -39,6 +132,12 @@ bool pathfinding::generate(scenario_structure_bsp_block *sbsp)
if (!LOG_CHECK(pathfinding && collision_bsp))
return false;

std::string import_settings_file = "tags\\" + tags::get_name(sbsp_tag) + "_import_setting.txt";
pathfinding_settings_parser importer;
std::cout << "Import settings file: \"" + import_settings_file << "\"" << std::endl;
if (!importer.parse_file(import_settings_file))
std::cout << "Import settings file not found or unreadable" << std::endl;

std::cout << "Converting surfaces to sectors" << std::endl;

// calculate surfaces to use
Expand All @@ -53,7 +152,8 @@ bool pathfinding::generate(scenario_structure_bsp_block *sbsp)
return false;
auto plane = collision_bsp->get_plane_by_ref(surface->plane);
auto normal_angle = plane.normal.get_angle();
if (!is_between(normal_angle.roll.as_degree(), 45.0, 135.0))
if (importer.force_keep_surface(surface_idx)
|| !is_between(normal_angle.roll.as_degree(), 45.0, 135.0) && !importer.remove_surface(surface_idx))
{
surface_sector_mapping[surface_idx] = sector_index;
ref_index = sector_index;
Expand All @@ -66,7 +166,7 @@ bool pathfinding::generate(scenario_structure_bsp_block *sbsp)
std::cout << "Culling edges and vertices" << std::endl;

// Ilterating over edges and calculating edges + points used
std::unordered_set<size_t> vertices_used;
std::unordered_set<unsigned short> vertices_used;
std::map<unsigned short, unsigned short> edge_link_mapping;
unsigned short link_idx = 0;
std::unordered_set<unsigned short> edges_used; // make a copy for ilterating
Expand Down Expand Up @@ -113,8 +213,8 @@ bool pathfinding::generate(scenario_structure_bsp_block *sbsp)
// copy over vertices
std::map<unsigned short, unsigned short> coll_to_path_vertex;
tags::resize_block(&pathfinding->vertices, vertices_used.size());
size_t p_vertex_idx = 0;
for (size_t c_vertex_idx: vertices_used)
unsigned short p_vertex_idx = 0;
for (auto c_vertex_idx: vertices_used)
{
auto *p_vertex = pathfinding->vertices[p_vertex_idx];
auto *c_vertex = collision_bsp->vertices[c_vertex_idx];
Expand Down
2 changes: 1 addition & 1 deletion H2Codez/Common/Pathfinding.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ namespace pathfinding
};
std::map<size_t, line_set> sector_lines;
};
bool generate(scenario_structure_bsp_block *sbsp);
bool generate(datum sbsp_tag);
render_info get_render_info(scenario_structure_bsp_block *sbsp);
}
2 changes: 1 addition & 1 deletion H2Codez/Common/TagInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace tags
return (tag_block_ref *)(get_object_at_data_array_index(get_tag_instance_ptr(), tag.index) + 8);
}

const char *get_name(datum tag)
std::string get_name(datum tag)
{
return (const char *)get_object_at_data_array_index(get_tag_instance_ptr(), tag.index)[1];
}
Expand Down
2 changes: 1 addition & 1 deletion H2Codez/Common/TagInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace tags
{
int get_group_tag(datum tag);
tag_block_ref *get_root_block(datum tag);
const char *get_name(datum tag);
std::string get_name(datum tag);
bool tag_exists(int group, std::string path);
bool is_read_only(datum tag);

Expand Down
10 changes: 6 additions & 4 deletions H2Codez/H2Sapien/HaloScript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "../Common/H2EKCommon.h"
#include "../HaloScript/hs_interface.h"
#include <Shellapi.h>
#include "../Common/TagInterface.h"

void status_dump()
{
Expand All @@ -22,9 +23,9 @@ void status_dump()
ShellExecuteA(NULL, NULL, temp_file_name.c_str(), NULL, NULL, SW_SHOW);
}

static inline scenario_structure_bsp_block *get_sbsp()
static inline datum get_sbsp_index()
{
return *reinterpret_cast<scenario_structure_bsp_block **>(0xA9CA74);
return *reinterpret_cast<datum *>(0x9A14B8);
}

void H2SapienPatches::haloscript_init()
Expand All @@ -43,8 +44,9 @@ void H2SapienPatches::haloscript_init()
"generate_pathfinding",
"Generate pathfinding from collision for current bsp",
HS_FUNC(
auto bsp = get_sbsp();
if (bsp->pathfindingData.size == 0)
auto bsp = get_sbsp_index();
auto bsp_data = tags::get_tag<scenario_structure_bsp_block>('sbsp', bsp);
if (bsp_data->pathfindingData.size == 0)
pathfinding::generate(bsp);
return 0;
)
Expand Down
24 changes: 1 addition & 23 deletions H2Codez/H2Tool/H2Tool_extra_commands.inl
Original file line number Diff line number Diff line change
Expand Up @@ -559,32 +559,10 @@ void _cdecl pathfinding_from_coll_proc(const wchar_t *argv[])
if (sbsp.index == NONE)
return;
scenario_structure_bsp_block *sbsp_data = tags::get_tag<scenario_structure_bsp_block>('sbsp', sbsp);
auto collisionBSP = sbsp_data->collisionBSP[0];
if (collisionBSP)
{
size_t i = 0;
for (auto &coll_plane : collisionBSP->planes)
{
continue;
auto normal = coll_plane.plane.normal.get_angle();
std::cout << "plane: " << std::setw(3) << i;
std::cout << " (" << std::setw(6) << "yaw: " << std::setw(3) << normal.yaw.as_degree()
<< std::setw(6) << " pitch: " << std::setw(3) << normal.pitch.as_degree()
<< std::setw(6) << " roll: " << std::setw(3) << normal.roll.as_degree() << " )" << std::endl;
i++;
continue;
auto to_degree = [](double rad) -> double { return rad * (180.0 / 3.14159265358979323846); };
auto convert = [to_degree](double vector_v) -> double { return to_degree(std::acos(vector_v)); };
//auto convert = [to_degree](double vector_v) -> double { return vector_v; };
printf_s("i: %f\n", convert(coll_plane.plane.normal.i));
printf_s("j: %f\n", convert(coll_plane.plane.normal.j));
printf_s("k: %f\n\n", convert(coll_plane.plane.normal.k));
}
}
if (!check_pathfinding_clear(sbsp_data))
return;

pathfinding::generate(sbsp_data);
pathfinding::generate(sbsp);

if (!tags::save_tag(sbsp))
printf_s("Failed to save tag!\n");
Expand Down

0 comments on commit 16d809e

Please sign in to comment.