Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Boost with Pybind11 + Add checking if BVH/maps built + Add C API docs #55

Merged
merged 3 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 3 additions & 11 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ jobs:
- name: Checkout submodules
run: git submodule update --init --recursive

- name: Install python and boost
- name: Install python
run: |
sudo apt-get -y update
sudo apt-get install python3 python3-dev libboost-python-dev
sudo apt-get install python3 python3-dev

- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
Expand Down Expand Up @@ -59,16 +59,8 @@ jobs:
python-version: '3.9'
architecture: 'x64'

- name: Build Boost
run: |
Invoke-WebRequest https://boostorg.jfrog.io/artifactory/main/release/1.78.0/source/boost_1_78_0.zip -OutFile boost.zip
Expand-Archive -Path boost.zip -DestinationPath .
cd boost_1_78_0
.\bootstrap
.\b2 --with-python link=static threading=multi runtime-link=shared architecture=x86 address-model=64 stage

- name: Configure CMake
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DBOOST_ROOT=${{github.workspace}}/boost_1_78_0 -DBOOST_LIBRARYDIR=${{github.workspace}}/boost_1_78_0/stage/lib
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}

- name: Build
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "stormlib"]
path = stormlib
url = https://github.com/ladislav-zezula/StormLib.git
[submodule "pybind11"]
path = pybind11
url = https://github.com/pybind/pybind11
80 changes: 3 additions & 77 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,87 +21,13 @@ if (CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-multichar")
endif()

unset(Python3_FOUND CACHE)
unset(PYTHON_COMPONENT CACHE)

# github python setup action will set this environment variable
if(DEFINED ENV{pythonLocation})
set(Python3_ROOT_DIR $ENV{pythonLocation})
set(Python3_FIND_REGISTRY NEVER)
endif()

option(NAMIGATOR_BUILD_PYTHON "Build Python bindings if Python2/3 is present." TRUE)
option(NAMIGATOR_INSTALL_TESTS "Install tests." TRUE)

if(NAMIGATOR_BUILD_PYTHON)
# First try finding python 3 development files
find_package(Python3 COMPONENTS Development)

if (Python3_FOUND)
set(PYTHON_COMPONENT "python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}")
set(PYTHON_LIBRARIES "${Python3_LIBRARIES}")
set(PYTHON_INCLUDE_DIRS "${Python3_INCLUDE_DIRS}")
else()
message(STATUS "Could not find python3. Attemping to find python2.")
find_package(Python2 COMPONENTS Development)
if (Python2_FOUND)
set(PYTHON_COMPONENT "python${Python2_VERSION_MAJOR}${Python2_VERSION_MINOR}")
set(PYTHON_LIBRARIES "${Python2_LIBRARIES}")
set(PYTHON_INCLUDE_DIRS "${Python2_INCLUDE_DIRS}")
else()
message(STATUS "Could not find python2 either.")
endif()
endif()
endif() # NAMIGATOR_BUILD_PYTHON

# Enable debug output from FindBoost
#set(Boost_DEBUG ON)
#set(Boost_DETAILED_FAILURE_MSG ON)

if (PYTHON_COMPONENT)
# There currently seems to be a bug with the Linux distro of boost binaries
# where some symbols are not built with position independent code (-fPIC).
# So rather than requiring our users to build boost themselves, we can just
# disable static linking of Boost libraries for now.
if (MSVC)
set(Boost_USE_STATIC_LIBS ON)
else()
set(Boost_USE_STATIC_LIBS OFF)
endif()

set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
set(Boost_FIND_QUIETLY ON)

find_package(Boost COMPONENTS "${PYTHON_COMPONENT}")

# If we found python 3 and boost rejected it, try again with python 2
if (NOT Boost_FOUND AND Python3_FOUND)
message(STATUS "Boost rejected ${PYTHON_COMPONENT}. Trying with python2.")
find_package(Python2 COMPONENTS Development)

if (Python2_FOUND)
message(STATUS "Python2 found. Checking for support from boost.")
set(PYTHON_COMPONENT "python${Python2_VERSION_MAJOR}${Python2_VERSION_MINOR}")
set(PYTHON_LIBRARIES "${Python2_LIBRARIES}")
set(PYTHON_INCLUDE_DIRS "${Python2_INCLUDE_DIRS}")
find_package(Boost COMPONENTS "${PYTHON_COMPONENT}")
else()
message(STATUS "Could not find python2 either.")
endif()

# Failed? Give up
if (NOT Boost_FOUND)
message(STATUS "Giving up on finding boost and python match")
unset(PYTHON_COMPONENT)
unset(PYTHON_LIBRARIES)
unset(PYTHON_INCLUDE_DIRS)
endif()
endif()
endif()

if (NAMIGATOR_BUILD_PYTHON AND NOT PYTHON_COMPONENT)
message(WARNING "No boost-compatible python was found. Python bindings for ${CMAKE_PROJECT_NAME} will not be compiled")
add_subdirectory(pybind11)
else()
message(WARNING "Python bindings for ${CMAKE_PROJECT_NAME} will not be compiled")
endif()

# GCC 7 requires an extra lib for this, but MSVC does not
Expand Down
18 changes: 5 additions & 13 deletions MapBuilder/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ set(EXECUTABLE_NAME MapBuilder)
set(LIBRARY_NAME libmapbuild)
set(PYTHON_NAME mapbuild)

set(SRC BVHConstructor.cpp GameObjectBVHBuilder.cpp MeshBuilder.cpp RecastContext.cpp Worker.cpp MapBuilder_c_bindings.cpp)
set(SRC BVHConstructor.cpp GameObjectBVHBuilder.cpp MeshBuilder.cpp RecastContext.cpp Worker.cpp MapBuilder_c_bindings.cpp FileExist.cpp)

add_library(${LIBRARY_NAME} ${SRC})
target_include_directories(${LIBRARY_NAME} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../")
Expand All @@ -15,18 +15,10 @@ target_link_libraries(${EXECUTABLE_NAME} ${LIBRARY_NAME})

install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin)

if (PYTHON_COMPONENT)
if (Python3_FOUND)
Python3_add_library(${PYTHON_NAME} ${SRC} python.cpp)
elseif (Python2_FOUND)
Python2_add_library(${PYTHON_NAME} ${SRC} python.cpp)
else()
message(FATAL_ERROR "Python component defined but neither python2 nor python3 were found")
endif()

target_compile_definitions(${PYTHON_NAME} PUBLIC PYTHON BOOST_PYTHON_STATIC_LIB)
target_include_directories(${PYTHON_NAME} PUBLIC ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
target_link_libraries(${PYTHON_NAME} PRIVATE parser utility RecastNavigation::Recast RecastNavigation::Detour storm ${Boost_LIBRARIES})
if (NAMIGATOR_BUILD_PYTHON)
pybind11_add_module(${PYTHON_NAME} ${SRC} python.cpp)

target_link_libraries(${PYTHON_NAME} PRIVATE parser utility RecastNavigation::Recast RecastNavigation::Detour storm)

install(TARGETS ${PYTHON_NAME} DESTINATION lib)
endif()
17 changes: 17 additions & 0 deletions MapBuilder/FileExist.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "FileExist.hpp"

#include <filesystem>

namespace file_exist {

bool bvh_files_exist(const std::string& outputPath) {
// bvh.idx is created at the very end of building game objects
return std::filesystem::exists(outputPath + "/BVH/bvh.idx");
}

bool map_files_exist(const std::string& outputPath, const std::string& mapName) {
// mapName.map is created in MeshBuilder::SaveMap which should be after successful creation
return std::filesystem::exists(outputPath + "/" + mapName + ".map");
}

} // namespace file_exist
9 changes: 9 additions & 0 deletions MapBuilder/FileExist.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <string>

namespace file_exist {

bool bvh_files_exist(const std::string& outputPath);

bool map_files_exist(const std::string& outputPath, const std::string& mapName);

} // namespace file_exist
39 changes: 39 additions & 0 deletions MapBuilder/MapBuilder_c_bindings.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "mapbuilder_c_bindings.h"

#include "FileExist.hpp"
#include "GameObjectBVHBuilder.hpp"
#include "MeshBuilder.hpp"
#include "Worker.hpp"
Expand Down Expand Up @@ -134,5 +135,43 @@ MapBuildResultType mapbuild_build_map(const char* const data_path,
return static_cast<MapBuildResultType>(Result::SUCCESS);
}

MapBuildResultType mapbuild_bvh_files_exist(const char* const output_path,
uint8_t* const exists) {
std::string outputPath = output_path;

try {
if (file_exist::bvh_files_exist(outputPath)) {
*exists = 1;
} else {
*exists = 0;
}
}
catch (...) {
return static_cast<MapBuildResultType>(Result::UNKNOWN_EXCEPTION);
}

return static_cast<MapBuildResultType>(Result::SUCCESS);
}

MapBuildResultType mapbuild_map_files_exist(const char* const output_path,
const char* const map_name,
uint8_t* const exists) {

std::string outputPath = output_path;
std::string mapName = map_name;

try {
if (file_exist::map_files_exist(outputPath, mapName)) {
*exists = 1;
} else {
*exists = 0;
}
}
catch (...) {
return static_cast<MapBuildResultType>(Result::UNKNOWN_EXCEPTION);
}

return static_cast<MapBuildResultType>(Result::SUCCESS);
}

}
46 changes: 45 additions & 1 deletion MapBuilder/mapbuilder_c_bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,59 @@ extern "C" {

typedef uint8_t MapBuildResultType;

/*
Build gameobjects as bounded volume hierachy (BVH).

`data_path` is the `Data` directory containing `MPQ` files of a client.

`output_path` is the location where generated data will be placed.

`threads` is the amount of concurrent jobs that will be used to build the data.

`amount_of_bvhs_built` returns the amount of gameobjects built.

This MUST be done before building the maps with `mapbuild_build_map`.
*/
MapBuildResultType mapbuild_build_bvh(const char* const data_path,
const char* const output_path,
uint32_t threads,
uint32_t* const amount_of_bvhs_built);

/*
Builds a single map.

`data_path` is the `Data` directory containing `MPQ` files of a client.

`output_path` is the location where generated data will be placed.

`threads` is the amount of concurrent jobs that will be used to build the data.

`map_name` is the name of the map folder inside the MPQ. For example `Azeroth` for Eastern Kingdoms.

`gameobject_csv` is the path to a CSV file containing a list of dynamically loaded objects.
This feature is unlikely to work.
*/
MapBuildResultType mapbuild_build_map(const char* const data_path,
const char* const output_path,
const char* const map_name,
const char* const gameobject_csv,
uint32_t threads);

}
/*
Tests if gameobjects have been built in `output_path`.

`exists` will be `0` if the gameobject files haven't been built, and `1` if they have.
*/
MapBuildResultType mapbuild_bvh_files_exist(const char* const output_path,
uint8_t* const exists);

/*
Tests if the map with `map_name` has already been built in `output_path`.

`exists` will be `0` if the map hasn't been built, and `1` if it has.
*/
MapBuildResultType mapbuild_map_files_exist(const char* const output_path,
const char* const map_name,
uint8_t* const exists);

}
21 changes: 16 additions & 5 deletions MapBuilder/python.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
#include "MeshBuilder.hpp"
#include "Worker.hpp"
#include "parser/MpqManager.hpp"
#include "FileExist.hpp"

#include <boost/python.hpp>
#include <pybind11/pybind11.h>
#include <filesystem>
#include <memory>
#include <string>
Expand Down Expand Up @@ -142,9 +143,19 @@ bool BuildADT(const std::string& dataPath, const std::string& outputPath,
return true;
}

BOOST_PYTHON_MODULE(mapbuild)
bool BVHFilesExist(const std::string& outputPath) {
return file_exist::bvh_files_exist(outputPath);
}

bool MapFilesExist(const std::string& outputPath, const std::string& mapName) {
return file_exist::map_files_exist(outputPath, mapName);
}

PYBIND11_MODULE(mapbuild, m)
{
boost::python::def("build_bvh", BuildBVH);
boost::python::def("build_map", BuildMap);
boost::python::def("build_adt", BuildADT);
m.def("build_bvh", &BuildBVH);
m.def("build_map", &BuildMap);
m.def("build_adt", &BuildADT);
m.def("map_files_exist", &MapFilesExist);
m.def("bvh_files_exist", &BVHFilesExist);
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ server.
* **stormlib** -- Used for extracting source data from its containers.
* **recastnavigation** -- Underlying computational geometry library. Used for
mesh generation, pathfinding, and more.
* **boost** -- Optional. Used in creating python modules.
* **pybind11** -- Optional. Used in creating python modules.
* **python** -- Optional. Used in creating python modules.

## Future Plans
Expand Down
14 changes: 3 additions & 11 deletions pathfind/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,10 @@ target_link_libraries(${LIBRARY_NAME} PRIVATE ${FILESYSTEM_LIBRARY} utility Reca

install(TARGETS ${LIBRARY_NAME} ARCHIVE DESTINATION lib)

if (PYTHON_COMPONENT)
if (Python3_FOUND)
Python3_add_library(${PYTHON_NAME} ${SRC} python.cpp)
elseif (Python2_FOUND)
Python2_add_library(${PYTHON_NAME} ${SRC} python.cpp)
else()
message(FATAL_ERROR "Python component defined but neither python2 nor python3 were found")
endif()
if (NAMIGATOR_BUILD_PYTHON)
pybind11_add_module(${PYTHON_NAME} ${SRC} python.cpp)

target_compile_definitions(${PYTHON_NAME} PUBLIC PYTHON BOOST_PYTHON_STATIC_LIB)
target_include_directories(${PYTHON_NAME} PRIVATE ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS})
target_link_libraries(${PYTHON_NAME} PRIVATE ${FILESYSTEM_LIBRARY} utility RecastNavigation::Recast RecastNavigation::Detour storm ${Boost_LIBRARIES})
target_link_libraries(${PYTHON_NAME} PRIVATE ${FILESYSTEM_LIBRARY} utility RecastNavigation::Recast RecastNavigation::Detour storm)

install(TARGETS ${PYTHON_NAME} DESTINATION lib)
endif()
Loading