Added Recast&Detour to Carla project
This commit is contained in:
parent
46ca67bc23
commit
8b92cc95b5
|
@ -6,6 +6,10 @@ install(DIRECTORY "${RPCLIB_INCLUDE_PATH}/rpc" DESTINATION include/system)
|
|||
file(GLOB libcarla_carla_rpclib "${RPCLIB_LIB_PATH}/*.*")
|
||||
install(FILES ${libcarla_carla_rpclib} DESTINATION lib)
|
||||
|
||||
# Install Recast&Detour libraries
|
||||
file(GLOB libcarla_carla_recastlib "${RECAST_LIB_PATH}/*.*")
|
||||
install(FILES ${libcarla_carla_recastlib} DESTINATION lib)
|
||||
|
||||
# Install boost headers (install in system folder to avoid extra warnings).
|
||||
# @todo Remove boost from public interface of LibCarla.client.
|
||||
install(DIRECTORY "${BOOST_INCLUDE_PATH}/boost" DESTINATION include/system)
|
||||
|
@ -60,6 +64,17 @@ file(GLOB libcarla_carla_image_sources
|
|||
set(libcarla_sources "${libcarla_sources};${libcarla_carla_image_sources}")
|
||||
install(FILES ${libcarla_carla_image_sources} DESTINATION include/carla/image)
|
||||
|
||||
file(GLOB libcarla_carla_nav_sources
|
||||
"${libcarla_source_path}/carla/nav/*.cpp"
|
||||
"${libcarla_source_path}/carla/nav/*.h")
|
||||
set(libcarla_sources "${libcarla_sources};${libcarla_carla_nav_sources}")
|
||||
install(FILES ${libcarla_carla_nav_sources} DESTINATION include/carla/nav)
|
||||
|
||||
file(GLOB libcarla_carla_nav_recast_sources
|
||||
"${libcarla_source_path}/carla/nav/recast/*.h")
|
||||
set(libcarla_sources "${libcarla_sources};${libcarla_carla_nav_recast_sources}")
|
||||
install(FILES ${libcarla_carla_nav_recast_sources} DESTINATION include/carla/nav/recast)
|
||||
|
||||
file(GLOB libcarla_carla_opendrive_sources
|
||||
"${libcarla_source_path}/carla/opendrive/*.cpp"
|
||||
"${libcarla_source_path}/carla/opendrive/*.h")
|
||||
|
@ -179,7 +194,6 @@ install(FILES ${libcarla_moodycamel_sources} DESTINATION include/moodycamel)
|
|||
# ==============================================================================
|
||||
# Create targets for debug and release in the same build type.
|
||||
# ==============================================================================
|
||||
|
||||
if (LIBCARLA_BUILD_RELEASE)
|
||||
|
||||
add_library(carla_client STATIC ${libcarla_sources})
|
||||
|
@ -197,6 +211,10 @@ if (LIBCARLA_BUILD_RELEASE)
|
|||
set(CMAKE_CXX_FLAGS_RELEASE_CLIENT ${CMAKE_CXX_FLAGS_RELEASE})
|
||||
endif()
|
||||
set_target_properties(carla_client PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS_RELEASE_CLIENT}")
|
||||
|
||||
target_link_libraries(carla_client "${RECAST_LIB_PATH}/libRecast.a")
|
||||
target_link_libraries(carla_client "${RECAST_LIB_PATH}/libDetour.a")
|
||||
|
||||
endif (WIN32)
|
||||
|
||||
endif()
|
||||
|
@ -214,4 +232,7 @@ if (LIBCARLA_BUILD_DEBUG)
|
|||
set_target_properties(carla_client_debug PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
target_compile_definitions(carla_client_debug PUBLIC -DBOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
|
||||
target_link_libraries(carla_client "${RECAST_LIB_PATH}/libRecast.a")
|
||||
target_link_libraries(carla_client "${RECAST_LIB_PATH}/libDetour.a")
|
||||
|
||||
endif()
|
||||
|
|
|
@ -100,6 +100,12 @@ namespace client {
|
|||
return _simulator->ApplyBatchSync(std::move(commands), do_tick_cue);
|
||||
}
|
||||
|
||||
std::vector<carla::geom::Location> CreateWalker(
|
||||
carla::geom::Location From,
|
||||
carla::geom::Location To) const {
|
||||
return _simulator->CreateWalker(From, To);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<detail::Simulator> _simulator;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "carla/Exception.h"
|
||||
#include "carla/Version.h"
|
||||
#include "carla/client/TimeoutException.h"
|
||||
#include "carla/nav/NavMesh.h"
|
||||
#include "carla/rpc/ActorDescription.h"
|
||||
#include "carla/rpc/BoneTransformData.h"
|
||||
#include "carla/rpc/Client.h"
|
||||
|
@ -136,6 +137,10 @@ namespace detail {
|
|||
return _pimpl->CallAndWait<rpc::MapInfo>("get_map_info");
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Client::GetNavigationMesh() const {
|
||||
return _pimpl->CallAndWait<std::vector<uint8_t>>("get_navigation_mesh");
|
||||
}
|
||||
|
||||
std::vector<std::string> Client::GetAvailableMaps() {
|
||||
return _pimpl->CallAndWait<std::vector<std::string>>("get_available_maps");
|
||||
}
|
||||
|
|
|
@ -77,6 +77,8 @@ namespace detail {
|
|||
|
||||
rpc::MapInfo GetMapInfo();
|
||||
|
||||
std::vector<uint8_t> GetNavigationMesh() const;
|
||||
|
||||
std::vector<std::string> GetAvailableMaps();
|
||||
|
||||
std::vector<rpc::ActorDefinition> GetActorDefinitions();
|
||||
|
|
|
@ -342,6 +342,18 @@ namespace detail {
|
|||
_client.SetReplayerTimeFactor(time_factor);
|
||||
}
|
||||
|
||||
std::vector<carla::geom::Location> CreateWalker(
|
||||
carla::geom::Location From,
|
||||
carla::geom::Location To) const {
|
||||
return _client.CreateWalker(From, To);
|
||||
};
|
||||
|
||||
/// @}
|
||||
// =========================================================================
|
||||
/// @name Operations with walkers
|
||||
// =========================================================================
|
||||
/// @{
|
||||
|
||||
/// @}
|
||||
// =========================================================================
|
||||
/// @name Operations with sensors
|
||||
|
|
|
@ -0,0 +1,216 @@
|
|||
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#include "carla/Logging.h"
|
||||
#include "carla/nav/NavMesh.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <fstream>
|
||||
|
||||
namespace carla {
|
||||
namespace nav {
|
||||
|
||||
static const int MAX_POLYS = 256;
|
||||
|
||||
NavMesh::NavMesh() {
|
||||
// const FString FilePath = FPaths::ProjectContentDir() + TEXT("Carla/Maps/Nav/") + MapName + TEXT(".bin");
|
||||
// Load(FilePath);
|
||||
// carla::geom::Location a, b;
|
||||
|
||||
// a.x = -141.788834;
|
||||
// a.y = 0.139954;
|
||||
// a.z = -153.839020;
|
||||
// b.x = -29.750393;
|
||||
// b.y = 0.270432;
|
||||
// b.z = -26.876369;
|
||||
// if (GetPath(a, b, nullptr, Path)) {
|
||||
// logging::log("NAV: Path %d (%f,%f,%f)", Path.size, Path[0].x, Path[0].y, Path[0].z);
|
||||
// }
|
||||
// allocate object
|
||||
|
||||
// dtNavMesh *mesh = dtAllocNavMesh();
|
||||
// DEBUG_ASSERT(mesh != nullptr);
|
||||
// // DEBUG_ASSERT(false);
|
||||
// int i = mesh->getMaxTiles();
|
||||
// logging::log("NAV: %d", i);
|
||||
// i += 1;
|
||||
// logging::log("NAV: %d", i);
|
||||
// dtFreeNavMesh(mesh);
|
||||
}
|
||||
|
||||
// load navigation data
|
||||
bool NavMesh::Load(const std::string filename) {
|
||||
std::ifstream f;
|
||||
std::istream_iterator<uint8_t> start(f), end;
|
||||
|
||||
// read the whole file
|
||||
f.open(filename, std::ios::binary);
|
||||
if (!f.is_open())
|
||||
return false;
|
||||
std::vector<uint8_t> Content(start, end);
|
||||
f.close();
|
||||
|
||||
// parse the content
|
||||
return Load(Content);
|
||||
}
|
||||
|
||||
// load navigation data from memory
|
||||
bool NavMesh::Load(const std::vector<uint8_t> Content) {
|
||||
const int NAVMESHSET_MAGIC = 'M'<<24 | 'S'<<16 | 'E'<<8 | 'T'; //'MSET';
|
||||
const int NAVMESHSET_VERSION = 1;
|
||||
#pragma pack(push, 1)
|
||||
struct NavMeshSetHeader {
|
||||
int magic;
|
||||
int version;
|
||||
int numTiles;
|
||||
dtNavMeshParams params;
|
||||
} header;
|
||||
struct NavMeshTileHeader {
|
||||
dtTileRef tileRef;
|
||||
int dataSize;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
// read the file header
|
||||
// f.read(reinterpret_cast<char *>(&header), sizeof(header));
|
||||
unsigned long Pos = 0;
|
||||
memcpy(&header, &Content[Pos], sizeof(header));
|
||||
Pos += sizeof(header);
|
||||
|
||||
// check file magic and version
|
||||
if (header.magic != NAVMESHSET_MAGIC || header.version != NAVMESHSET_VERSION) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// allocate object
|
||||
dtNavMesh* mesh = dtAllocNavMesh();
|
||||
// set number of tiles and origin
|
||||
dtStatus status = mesh->init(&header.params);
|
||||
if (dtStatusFailed(status)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the tiles data
|
||||
for (int i = 0; i < header.numTiles; ++i) {
|
||||
NavMeshTileHeader tileHeader;
|
||||
|
||||
// read the tile header
|
||||
// f.read(reinterpret_cast<char *>(&tileHeader), sizeof(tileHeader));
|
||||
memcpy(&tileHeader, &Content[Pos], sizeof(tileHeader));
|
||||
Pos += sizeof(tileHeader);
|
||||
if (Pos >= Content.size()) {
|
||||
dtFreeNavMesh(mesh);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for valid tile
|
||||
if (!tileHeader.tileRef || !tileHeader.dataSize)
|
||||
break;
|
||||
|
||||
// allocate the buffer
|
||||
char* data = static_cast<char*>(dtAlloc(static_cast<size_t>(tileHeader.dataSize), DT_ALLOC_PERM));
|
||||
if (!data) break;
|
||||
|
||||
// read the tile
|
||||
memset(data, 0, static_cast<size_t>(tileHeader.dataSize));
|
||||
// f.read(data, tileHeader.dataSize);
|
||||
memcpy(data, &Content[Pos], static_cast<size_t>(tileHeader.dataSize));
|
||||
Pos += static_cast<unsigned long>(tileHeader.dataSize);
|
||||
if (Pos >= Content.size()) {
|
||||
dtFree(data);
|
||||
dtFreeNavMesh(mesh);
|
||||
return false;
|
||||
}
|
||||
|
||||
// add the tile data
|
||||
mesh->addTile(reinterpret_cast<unsigned char*>(data), tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0);
|
||||
}
|
||||
|
||||
// exchange
|
||||
dtFreeNavMesh(m_navMesh);
|
||||
m_navMesh = mesh;
|
||||
|
||||
// prepare the query object
|
||||
dtFreeNavMeshQuery(m_navQuery);
|
||||
m_navQuery = dtAllocNavMeshQuery();
|
||||
m_navQuery->init(m_navMesh, 2048);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// return the path points to go from one position to another
|
||||
bool NavMesh::GetPath(const carla::geom::Location from, const carla::geom::Location to, dtQueryFilter* filter, std::vector<carla::geom::Location> path) {
|
||||
// path found
|
||||
float m_straightPath[MAX_POLYS*3];
|
||||
unsigned char m_straightPathFlags[MAX_POLYS];
|
||||
dtPolyRef m_straightPathPolys[MAX_POLYS];
|
||||
int m_nstraightPath;
|
||||
int m_straightPathOptions = 0;
|
||||
// polys in path
|
||||
dtPolyRef m_polys[MAX_POLYS];
|
||||
int m_npolys;
|
||||
|
||||
// point extension
|
||||
float m_polyPickExt[3];
|
||||
m_polyPickExt[0] = 2;
|
||||
m_polyPickExt[1] = 4;
|
||||
m_polyPickExt[2] = 2;
|
||||
|
||||
// filter
|
||||
dtQueryFilter m_filter;
|
||||
if (filter == nullptr) {
|
||||
m_filter.setIncludeFlags(SAMPLE_POLYFLAGS_ALL ^ SAMPLE_POLYFLAGS_DISABLED);
|
||||
m_filter.setExcludeFlags(0);
|
||||
filter = &m_filter;
|
||||
}
|
||||
|
||||
// set the points
|
||||
dtPolyRef m_startRef = 0;
|
||||
dtPolyRef m_endRef = 0;
|
||||
float m_spos[3] = { from.x, from.z, from.y };
|
||||
float m_epos[3] = { to.x, to.z, to.y };
|
||||
m_navQuery->findNearestPoly(m_spos, m_polyPickExt, filter, &m_startRef, 0);
|
||||
m_navQuery->findNearestPoly(m_epos, m_polyPickExt, filter, &m_endRef, 0);
|
||||
if (!m_startRef || !m_endRef) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the path of nodes
|
||||
m_navQuery->findPath(m_startRef, m_endRef, m_spos, m_epos, filter, m_polys, &m_npolys, MAX_POLYS);
|
||||
|
||||
// get the path of points
|
||||
m_nstraightPath = 0;
|
||||
if (m_npolys == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// in case of partial path, make sure the end point is clamped to the last polygon
|
||||
float epos[3];
|
||||
dtVcopy(epos, m_epos);
|
||||
if (m_polys[m_npolys-1] != m_endRef)
|
||||
m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos, 0);
|
||||
|
||||
// get the points
|
||||
m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys,
|
||||
m_straightPath, m_straightPathFlags,
|
||||
m_straightPathPolys, &m_nstraightPath, MAX_POLYS, m_straightPathOptions);
|
||||
|
||||
// copy the path to the output buffer
|
||||
path.clear();
|
||||
path.reserve(static_cast<unsigned long>(m_nstraightPath));
|
||||
for (int i=0; i<m_nstraightPath*3; i+=3) {
|
||||
// export for Unreal axis (x, z, y)
|
||||
// path.push_back(carla::geom::Location(m_straightPath[i], m_straightPath[i+2], m_straightPath[i+1]));
|
||||
path.emplace_back(m_straightPath[i], m_straightPath[i+2], m_straightPath[i+1]);
|
||||
// std::cout << "(" << m_straightPath[i] << ", " << m_straightPath[i+2] << ", " << m_straightPath[i+1] << "), " << std::endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace nav
|
||||
} // namespace carla
|
|
@ -0,0 +1,61 @@
|
|||
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "carla/geom/Location.h"
|
||||
#include "recast/Recast.h"
|
||||
#include "recast/DetourNavMesh.h"
|
||||
#include "recast/DetourNavMeshBuilder.h"
|
||||
#include "recast/DetourNavMeshQuery.h"
|
||||
#include "recast/DetourCommon.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
|
||||
namespace carla {
|
||||
namespace nav {
|
||||
|
||||
enum SamplePolyAreas {
|
||||
SAMPLE_POLYAREA_GROUND,
|
||||
SAMPLE_POLYAREA_WATER,
|
||||
SAMPLE_POLYAREA_ROAD,
|
||||
SAMPLE_POLYAREA_DOOR,
|
||||
SAMPLE_POLYAREA_GRASS,
|
||||
SAMPLE_POLYAREA_JUMP,
|
||||
};
|
||||
|
||||
enum SamplePolyFlags {
|
||||
SAMPLE_POLYFLAGS_WALK = 0x01, // Ability to walk (ground, grass, road)
|
||||
SAMPLE_POLYFLAGS_SWIM = 0x02, // Ability to swim (water).
|
||||
SAMPLE_POLYFLAGS_DOOR = 0x04, // Ability to move through doors.
|
||||
SAMPLE_POLYFLAGS_JUMP = 0x08, // Ability to jump.
|
||||
SAMPLE_POLYFLAGS_DISABLED = 0x10, // Disabled polygon
|
||||
SAMPLE_POLYFLAGS_ALL = 0xffff // All abilities.
|
||||
};
|
||||
|
||||
|
||||
class NavMesh {
|
||||
|
||||
public:
|
||||
NavMesh();
|
||||
// load navigation data
|
||||
bool Load(const std::string filename);
|
||||
// load navigation data from memory
|
||||
bool Load(const std::vector<uint8_t> Content);
|
||||
// return the path points to go from one position to another
|
||||
bool GetPath(const carla::geom::Location from, const carla::geom::Location to, dtQueryFilter* filter, std::vector<carla::geom::Location> path);
|
||||
|
||||
private:
|
||||
// meshes loaded
|
||||
dtNavMesh* m_navMesh { nullptr };
|
||||
dtNavMeshQuery* m_navQuery { nullptr };
|
||||
};
|
||||
|
||||
// NavMesh *navMesh2 = new NavMesh();
|
||||
|
||||
} // namespace nav
|
||||
} // namespace carla
|
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURALLOCATOR_H
|
||||
#define DETOURALLOCATOR_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/// Provides hint values to the memory allocator on how long the
|
||||
/// memory is expected to be used.
|
||||
enum dtAllocHint
|
||||
{
|
||||
DT_ALLOC_PERM, ///< Memory persist after a function call.
|
||||
DT_ALLOC_TEMP ///< Memory used temporarily within a function.
|
||||
};
|
||||
|
||||
/// A memory allocation function.
|
||||
// @param[in] size The size, in bytes of memory, to allocate.
|
||||
// @param[in] rcAllocHint A hint to the allocator on how long the memory is expected to be in use.
|
||||
// @return A pointer to the beginning of the allocated memory block, or null if the allocation failed.
|
||||
/// @see dtAllocSetCustom
|
||||
typedef void* (dtAllocFunc)(size_t size, dtAllocHint hint);
|
||||
|
||||
/// A memory deallocation function.
|
||||
/// @param[in] ptr A pointer to a memory block previously allocated using #dtAllocFunc.
|
||||
/// @see dtAllocSetCustom
|
||||
typedef void (dtFreeFunc)(void* ptr);
|
||||
|
||||
/// Sets the base custom allocation functions to be used by Detour.
|
||||
/// @param[in] allocFunc The memory allocation function to be used by #dtAlloc
|
||||
/// @param[in] freeFunc The memory de-allocation function to be used by #dtFree
|
||||
void dtAllocSetCustom(dtAllocFunc *allocFunc, dtFreeFunc *freeFunc);
|
||||
|
||||
/// Allocates a memory block.
|
||||
/// @param[in] size The size, in bytes of memory, to allocate.
|
||||
/// @param[in] hint A hint to the allocator on how long the memory is expected to be in use.
|
||||
/// @return A pointer to the beginning of the allocated memory block, or null if the allocation failed.
|
||||
/// @see dtFree
|
||||
void* dtAlloc(size_t size, dtAllocHint hint);
|
||||
|
||||
/// Deallocates a memory block.
|
||||
/// @param[in] ptr A pointer to a memory block previously allocated using #dtAlloc.
|
||||
/// @see dtAlloc
|
||||
void dtFree(void* ptr);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURASSERT_H
|
||||
#define DETOURASSERT_H
|
||||
|
||||
// Note: This header file's only purpose is to include define assert.
|
||||
// Feel free to change the file and include your own implementation instead.
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
||||
// From http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/
|
||||
# define dtAssert(x) do { (void)sizeof(x); } while((void)(__LINE__==-1),false)
|
||||
|
||||
#else
|
||||
|
||||
/// An assertion failure function.
|
||||
// @param[in] expression asserted expression.
|
||||
// @param[in] file Filename of the failed assertion.
|
||||
// @param[in] line Line number of the failed assertion.
|
||||
/// @see dtAssertFailSetCustom
|
||||
typedef void (dtAssertFailFunc)(const char* expression, const char* file, int line);
|
||||
|
||||
/// Sets the base custom assertion failure function to be used by Detour.
|
||||
/// @param[in] assertFailFunc The function to be invoked in case of failure of #dtAssert
|
||||
void dtAssertFailSetCustom(dtAssertFailFunc *assertFailFunc);
|
||||
|
||||
/// Gets the base custom assertion failure function to be used by Detour.
|
||||
dtAssertFailFunc* dtAssertFailGetCustom();
|
||||
|
||||
# include <assert.h>
|
||||
# define dtAssert(expression) \
|
||||
{ \
|
||||
dtAssertFailFunc* failFunc = dtAssertFailGetCustom(); \
|
||||
if(failFunc == NULL) { assert(expression); } \
|
||||
else if(!(expression)) { (*failFunc)(#expression, __FILE__, __LINE__); } \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // DETOURASSERT_H
|
|
@ -0,0 +1,572 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURCOMMON_H
|
||||
#define DETOURCOMMON_H
|
||||
|
||||
#include "DetourMath.h"
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
@defgroup detour Detour
|
||||
|
||||
Members in this module are used to create, manipulate, and query navigation
|
||||
meshes.
|
||||
|
||||
@note This is a summary list of members. Use the index or search
|
||||
feature to find minor members.
|
||||
*/
|
||||
|
||||
/// @name General helper functions
|
||||
/// @{
|
||||
|
||||
/// Used to ignore a function parameter. VS complains about unused parameters
|
||||
/// and this silences the warning.
|
||||
/// @param [in] _ Unused parameter
|
||||
template<class T> void dtIgnoreUnused(const T&) { }
|
||||
|
||||
/// Swaps the values of the two parameters.
|
||||
/// @param[in,out] a Value A
|
||||
/// @param[in,out] b Value B
|
||||
template<class T> inline void dtSwap(T& a, T& b) { T t = a; a = b; b = t; }
|
||||
|
||||
/// Returns the minimum of two values.
|
||||
/// @param[in] a Value A
|
||||
/// @param[in] b Value B
|
||||
/// @return The minimum of the two values.
|
||||
template<class T> inline T dtMin(T a, T b) { return a < b ? a : b; }
|
||||
|
||||
/// Returns the maximum of two values.
|
||||
/// @param[in] a Value A
|
||||
/// @param[in] b Value B
|
||||
/// @return The maximum of the two values.
|
||||
template<class T> inline T dtMax(T a, T b) { return a > b ? a : b; }
|
||||
|
||||
/// Returns the absolute value.
|
||||
/// @param[in] a The value.
|
||||
/// @return The absolute value of the specified value.
|
||||
template<class T> inline T dtAbs(T a) { return a < 0 ? -a : a; }
|
||||
|
||||
/// Returns the square of the value.
|
||||
/// @param[in] a The value.
|
||||
/// @return The square of the value.
|
||||
template<class T> inline T dtSqr(T a) { return a*a; }
|
||||
|
||||
/// Clamps the value to the specified range.
|
||||
/// @param[in] v The value to clamp.
|
||||
/// @param[in] mn The minimum permitted return value.
|
||||
/// @param[in] mx The maximum permitted return value.
|
||||
/// @return The value, clamped to the specified range.
|
||||
template<class T> inline T dtClamp(T v, T mn, T mx) { return v < mn ? mn : (v > mx ? mx : v); }
|
||||
|
||||
/// @}
|
||||
/// @name Vector helper functions.
|
||||
/// @{
|
||||
|
||||
/// Derives the cross product of two vectors. (@p v1 x @p v2)
|
||||
/// @param[out] dest The cross product. [(x, y, z)]
|
||||
/// @param[in] v1 A Vector [(x, y, z)]
|
||||
/// @param[in] v2 A vector [(x, y, z)]
|
||||
inline void dtVcross(float* dest, const float* v1, const float* v2)
|
||||
{
|
||||
dest[0] = v1[1]*v2[2] - v1[2]*v2[1];
|
||||
dest[1] = v1[2]*v2[0] - v1[0]*v2[2];
|
||||
dest[2] = v1[0]*v2[1] - v1[1]*v2[0];
|
||||
}
|
||||
|
||||
/// Derives the dot product of two vectors. (@p v1 . @p v2)
|
||||
/// @param[in] v1 A Vector [(x, y, z)]
|
||||
/// @param[in] v2 A vector [(x, y, z)]
|
||||
/// @return The dot product.
|
||||
inline float dtVdot(const float* v1, const float* v2)
|
||||
{
|
||||
return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
|
||||
}
|
||||
|
||||
/// Performs a scaled vector addition. (@p v1 + (@p v2 * @p s))
|
||||
/// @param[out] dest The result vector. [(x, y, z)]
|
||||
/// @param[in] v1 The base vector. [(x, y, z)]
|
||||
/// @param[in] v2 The vector to scale and add to @p v1. [(x, y, z)]
|
||||
/// @param[in] s The amount to scale @p v2 by before adding to @p v1.
|
||||
inline void dtVmad(float* dest, const float* v1, const float* v2, const float s)
|
||||
{
|
||||
dest[0] = v1[0]+v2[0]*s;
|
||||
dest[1] = v1[1]+v2[1]*s;
|
||||
dest[2] = v1[2]+v2[2]*s;
|
||||
}
|
||||
|
||||
/// Performs a linear interpolation between two vectors. (@p v1 toward @p v2)
|
||||
/// @param[out] dest The result vector. [(x, y, x)]
|
||||
/// @param[in] v1 The starting vector.
|
||||
/// @param[in] v2 The destination vector.
|
||||
/// @param[in] t The interpolation factor. [Limits: 0 <= value <= 1.0]
|
||||
inline void dtVlerp(float* dest, const float* v1, const float* v2, const float t)
|
||||
{
|
||||
dest[0] = v1[0]+(v2[0]-v1[0])*t;
|
||||
dest[1] = v1[1]+(v2[1]-v1[1])*t;
|
||||
dest[2] = v1[2]+(v2[2]-v1[2])*t;
|
||||
}
|
||||
|
||||
/// Performs a vector addition. (@p v1 + @p v2)
|
||||
/// @param[out] dest The result vector. [(x, y, z)]
|
||||
/// @param[in] v1 The base vector. [(x, y, z)]
|
||||
/// @param[in] v2 The vector to add to @p v1. [(x, y, z)]
|
||||
inline void dtVadd(float* dest, const float* v1, const float* v2)
|
||||
{
|
||||
dest[0] = v1[0]+v2[0];
|
||||
dest[1] = v1[1]+v2[1];
|
||||
dest[2] = v1[2]+v2[2];
|
||||
}
|
||||
|
||||
/// Performs a vector subtraction. (@p v1 - @p v2)
|
||||
/// @param[out] dest The result vector. [(x, y, z)]
|
||||
/// @param[in] v1 The base vector. [(x, y, z)]
|
||||
/// @param[in] v2 The vector to subtract from @p v1. [(x, y, z)]
|
||||
inline void dtVsub(float* dest, const float* v1, const float* v2)
|
||||
{
|
||||
dest[0] = v1[0]-v2[0];
|
||||
dest[1] = v1[1]-v2[1];
|
||||
dest[2] = v1[2]-v2[2];
|
||||
}
|
||||
|
||||
/// Scales the vector by the specified value. (@p v * @p t)
|
||||
/// @param[out] dest The result vector. [(x, y, z)]
|
||||
/// @param[in] v The vector to scale. [(x, y, z)]
|
||||
/// @param[in] t The scaling factor.
|
||||
inline void dtVscale(float* dest, const float* v, const float t)
|
||||
{
|
||||
dest[0] = v[0]*t;
|
||||
dest[1] = v[1]*t;
|
||||
dest[2] = v[2]*t;
|
||||
}
|
||||
|
||||
/// Selects the minimum value of each element from the specified vectors.
|
||||
/// @param[in,out] mn A vector. (Will be updated with the result.) [(x, y, z)]
|
||||
/// @param[in] v A vector. [(x, y, z)]
|
||||
inline void dtVmin(float* mn, const float* v)
|
||||
{
|
||||
mn[0] = dtMin(mn[0], v[0]);
|
||||
mn[1] = dtMin(mn[1], v[1]);
|
||||
mn[2] = dtMin(mn[2], v[2]);
|
||||
}
|
||||
|
||||
/// Selects the maximum value of each element from the specified vectors.
|
||||
/// @param[in,out] mx A vector. (Will be updated with the result.) [(x, y, z)]
|
||||
/// @param[in] v A vector. [(x, y, z)]
|
||||
inline void dtVmax(float* mx, const float* v)
|
||||
{
|
||||
mx[0] = dtMax(mx[0], v[0]);
|
||||
mx[1] = dtMax(mx[1], v[1]);
|
||||
mx[2] = dtMax(mx[2], v[2]);
|
||||
}
|
||||
|
||||
/// Sets the vector elements to the specified values.
|
||||
/// @param[out] dest The result vector. [(x, y, z)]
|
||||
/// @param[in] x The x-value of the vector.
|
||||
/// @param[in] y The y-value of the vector.
|
||||
/// @param[in] z The z-value of the vector.
|
||||
inline void dtVset(float* dest, const float x, const float y, const float z)
|
||||
{
|
||||
dest[0] = x; dest[1] = y; dest[2] = z;
|
||||
}
|
||||
|
||||
/// Performs a vector copy.
|
||||
/// @param[out] dest The result. [(x, y, z)]
|
||||
/// @param[in] a The vector to copy. [(x, y, z)]
|
||||
inline void dtVcopy(float* dest, const float* a)
|
||||
{
|
||||
dest[0] = a[0];
|
||||
dest[1] = a[1];
|
||||
dest[2] = a[2];
|
||||
}
|
||||
|
||||
/// Derives the scalar length of the vector.
|
||||
/// @param[in] v The vector. [(x, y, z)]
|
||||
/// @return The scalar length of the vector.
|
||||
inline float dtVlen(const float* v)
|
||||
{
|
||||
return dtMathSqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
}
|
||||
|
||||
/// Derives the square of the scalar length of the vector. (len * len)
|
||||
/// @param[in] v The vector. [(x, y, z)]
|
||||
/// @return The square of the scalar length of the vector.
|
||||
inline float dtVlenSqr(const float* v)
|
||||
{
|
||||
return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
|
||||
}
|
||||
|
||||
/// Returns the distance between two points.
|
||||
/// @param[in] v1 A point. [(x, y, z)]
|
||||
/// @param[in] v2 A point. [(x, y, z)]
|
||||
/// @return The distance between the two points.
|
||||
inline float dtVdist(const float* v1, const float* v2)
|
||||
{
|
||||
const float dx = v2[0] - v1[0];
|
||||
const float dy = v2[1] - v1[1];
|
||||
const float dz = v2[2] - v1[2];
|
||||
return dtMathSqrtf(dx*dx + dy*dy + dz*dz);
|
||||
}
|
||||
|
||||
/// Returns the square of the distance between two points.
|
||||
/// @param[in] v1 A point. [(x, y, z)]
|
||||
/// @param[in] v2 A point. [(x, y, z)]
|
||||
/// @return The square of the distance between the two points.
|
||||
inline float dtVdistSqr(const float* v1, const float* v2)
|
||||
{
|
||||
const float dx = v2[0] - v1[0];
|
||||
const float dy = v2[1] - v1[1];
|
||||
const float dz = v2[2] - v1[2];
|
||||
return dx*dx + dy*dy + dz*dz;
|
||||
}
|
||||
|
||||
/// Derives the distance between the specified points on the xz-plane.
|
||||
/// @param[in] v1 A point. [(x, y, z)]
|
||||
/// @param[in] v2 A point. [(x, y, z)]
|
||||
/// @return The distance between the point on the xz-plane.
|
||||
///
|
||||
/// The vectors are projected onto the xz-plane, so the y-values are ignored.
|
||||
inline float dtVdist2D(const float* v1, const float* v2)
|
||||
{
|
||||
const float dx = v2[0] - v1[0];
|
||||
const float dz = v2[2] - v1[2];
|
||||
return dtMathSqrtf(dx*dx + dz*dz);
|
||||
}
|
||||
|
||||
/// Derives the square of the distance between the specified points on the xz-plane.
|
||||
/// @param[in] v1 A point. [(x, y, z)]
|
||||
/// @param[in] v2 A point. [(x, y, z)]
|
||||
/// @return The square of the distance between the point on the xz-plane.
|
||||
inline float dtVdist2DSqr(const float* v1, const float* v2)
|
||||
{
|
||||
const float dx = v2[0] - v1[0];
|
||||
const float dz = v2[2] - v1[2];
|
||||
return dx*dx + dz*dz;
|
||||
}
|
||||
|
||||
/// Normalizes the vector.
|
||||
/// @param[in,out] v The vector to normalize. [(x, y, z)]
|
||||
inline void dtVnormalize(float* v)
|
||||
{
|
||||
float d = 1.0f / dtMathSqrtf(dtSqr(v[0]) + dtSqr(v[1]) + dtSqr(v[2]));
|
||||
v[0] *= d;
|
||||
v[1] *= d;
|
||||
v[2] *= d;
|
||||
}
|
||||
|
||||
/// Performs a 'sloppy' colocation check of the specified points.
|
||||
/// @param[in] p0 A point. [(x, y, z)]
|
||||
/// @param[in] p1 A point. [(x, y, z)]
|
||||
/// @return True if the points are considered to be at the same location.
|
||||
///
|
||||
/// Basically, this function will return true if the specified points are
|
||||
/// close enough to eachother to be considered colocated.
|
||||
inline bool dtVequal(const float* p0, const float* p1)
|
||||
{
|
||||
static const float thr = dtSqr(1.0f/16384.0f);
|
||||
const float d = dtVdistSqr(p0, p1);
|
||||
return d < thr;
|
||||
}
|
||||
|
||||
/// Checks that the specified vector's components are all finite.
|
||||
/// @param[in] v A point. [(x, y, z)]
|
||||
/// @return True if all of the point's components are finite, i.e. not NaN
|
||||
/// or any of the infinities.
|
||||
inline bool dtVisfinite(const float* v)
|
||||
{
|
||||
bool result =
|
||||
dtMathIsfinite(v[0]) &&
|
||||
dtMathIsfinite(v[1]) &&
|
||||
dtMathIsfinite(v[2]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Checks that the specified vector's 2D components are finite.
|
||||
/// @param[in] v A point. [(x, y, z)]
|
||||
inline bool dtVisfinite2D(const float* v)
|
||||
{
|
||||
bool result = dtMathIsfinite(v[0]) && dtMathIsfinite(v[2]);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Derives the dot product of two vectors on the xz-plane. (@p u . @p v)
|
||||
/// @param[in] u A vector [(x, y, z)]
|
||||
/// @param[in] v A vector [(x, y, z)]
|
||||
/// @return The dot product on the xz-plane.
|
||||
///
|
||||
/// The vectors are projected onto the xz-plane, so the y-values are ignored.
|
||||
inline float dtVdot2D(const float* u, const float* v)
|
||||
{
|
||||
return u[0]*v[0] + u[2]*v[2];
|
||||
}
|
||||
|
||||
/// Derives the xz-plane 2D perp product of the two vectors. (uz*vx - ux*vz)
|
||||
/// @param[in] u The LHV vector [(x, y, z)]
|
||||
/// @param[in] v The RHV vector [(x, y, z)]
|
||||
/// @return The dot product on the xz-plane.
|
||||
///
|
||||
/// The vectors are projected onto the xz-plane, so the y-values are ignored.
|
||||
inline float dtVperp2D(const float* u, const float* v)
|
||||
{
|
||||
return u[2]*v[0] - u[0]*v[2];
|
||||
}
|
||||
|
||||
/// @}
|
||||
/// @name Computational geometry helper functions.
|
||||
/// @{
|
||||
|
||||
/// Derives the signed xz-plane area of the triangle ABC, or the relationship of line AB to point C.
|
||||
/// @param[in] a Vertex A. [(x, y, z)]
|
||||
/// @param[in] b Vertex B. [(x, y, z)]
|
||||
/// @param[in] c Vertex C. [(x, y, z)]
|
||||
/// @return The signed xz-plane area of the triangle.
|
||||
inline float dtTriArea2D(const float* a, const float* b, const float* c)
|
||||
{
|
||||
const float abx = b[0] - a[0];
|
||||
const float abz = b[2] - a[2];
|
||||
const float acx = c[0] - a[0];
|
||||
const float acz = c[2] - a[2];
|
||||
return acx*abz - abx*acz;
|
||||
}
|
||||
|
||||
/// Determines if two axis-aligned bounding boxes overlap.
|
||||
/// @param[in] amin Minimum bounds of box A. [(x, y, z)]
|
||||
/// @param[in] amax Maximum bounds of box A. [(x, y, z)]
|
||||
/// @param[in] bmin Minimum bounds of box B. [(x, y, z)]
|
||||
/// @param[in] bmax Maximum bounds of box B. [(x, y, z)]
|
||||
/// @return True if the two AABB's overlap.
|
||||
/// @see dtOverlapBounds
|
||||
inline bool dtOverlapQuantBounds(const unsigned short amin[3], const unsigned short amax[3],
|
||||
const unsigned short bmin[3], const unsigned short bmax[3])
|
||||
{
|
||||
bool overlap = true;
|
||||
overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap;
|
||||
overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap;
|
||||
overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap;
|
||||
return overlap;
|
||||
}
|
||||
|
||||
/// Determines if two axis-aligned bounding boxes overlap.
|
||||
/// @param[in] amin Minimum bounds of box A. [(x, y, z)]
|
||||
/// @param[in] amax Maximum bounds of box A. [(x, y, z)]
|
||||
/// @param[in] bmin Minimum bounds of box B. [(x, y, z)]
|
||||
/// @param[in] bmax Maximum bounds of box B. [(x, y, z)]
|
||||
/// @return True if the two AABB's overlap.
|
||||
/// @see dtOverlapQuantBounds
|
||||
inline bool dtOverlapBounds(const float* amin, const float* amax,
|
||||
const float* bmin, const float* bmax)
|
||||
{
|
||||
bool overlap = true;
|
||||
overlap = (amin[0] > bmax[0] || amax[0] < bmin[0]) ? false : overlap;
|
||||
overlap = (amin[1] > bmax[1] || amax[1] < bmin[1]) ? false : overlap;
|
||||
overlap = (amin[2] > bmax[2] || amax[2] < bmin[2]) ? false : overlap;
|
||||
return overlap;
|
||||
}
|
||||
|
||||
/// Derives the closest point on a triangle from the specified reference point.
|
||||
/// @param[out] closest The closest point on the triangle.
|
||||
/// @param[in] p The reference point from which to test. [(x, y, z)]
|
||||
/// @param[in] a Vertex A of triangle ABC. [(x, y, z)]
|
||||
/// @param[in] b Vertex B of triangle ABC. [(x, y, z)]
|
||||
/// @param[in] c Vertex C of triangle ABC. [(x, y, z)]
|
||||
void dtClosestPtPointTriangle(float* closest, const float* p,
|
||||
const float* a, const float* b, const float* c);
|
||||
|
||||
/// Derives the y-axis height of the closest point on the triangle from the specified reference point.
|
||||
/// @param[in] p The reference point from which to test. [(x, y, z)]
|
||||
/// @param[in] a Vertex A of triangle ABC. [(x, y, z)]
|
||||
/// @param[in] b Vertex B of triangle ABC. [(x, y, z)]
|
||||
/// @param[in] c Vertex C of triangle ABC. [(x, y, z)]
|
||||
/// @param[out] h The resulting height.
|
||||
bool dtClosestHeightPointTriangle(const float* p, const float* a, const float* b, const float* c, float& h);
|
||||
|
||||
bool dtIntersectSegmentPoly2D(const float* p0, const float* p1,
|
||||
const float* verts, int nverts,
|
||||
float& tmin, float& tmax,
|
||||
int& segMin, int& segMax);
|
||||
|
||||
bool dtIntersectSegSeg2D(const float* ap, const float* aq,
|
||||
const float* bp, const float* bq,
|
||||
float& s, float& t);
|
||||
|
||||
/// Determines if the specified point is inside the convex polygon on the xz-plane.
|
||||
/// @param[in] pt The point to check. [(x, y, z)]
|
||||
/// @param[in] verts The polygon vertices. [(x, y, z) * @p nverts]
|
||||
/// @param[in] nverts The number of vertices. [Limit: >= 3]
|
||||
/// @return True if the point is inside the polygon.
|
||||
bool dtPointInPolygon(const float* pt, const float* verts, const int nverts);
|
||||
|
||||
bool dtDistancePtPolyEdgesSqr(const float* pt, const float* verts, const int nverts,
|
||||
float* ed, float* et);
|
||||
|
||||
float dtDistancePtSegSqr2D(const float* pt, const float* p, const float* q, float& t);
|
||||
|
||||
/// Derives the centroid of a convex polygon.
|
||||
/// @param[out] tc The centroid of the polgyon. [(x, y, z)]
|
||||
/// @param[in] idx The polygon indices. [(vertIndex) * @p nidx]
|
||||
/// @param[in] nidx The number of indices in the polygon. [Limit: >= 3]
|
||||
/// @param[in] verts The polygon vertices. [(x, y, z) * vertCount]
|
||||
void dtCalcPolyCenter(float* tc, const unsigned short* idx, int nidx, const float* verts);
|
||||
|
||||
/// Determines if the two convex polygons overlap on the xz-plane.
|
||||
/// @param[in] polya Polygon A vertices. [(x, y, z) * @p npolya]
|
||||
/// @param[in] npolya The number of vertices in polygon A.
|
||||
/// @param[in] polyb Polygon B vertices. [(x, y, z) * @p npolyb]
|
||||
/// @param[in] npolyb The number of vertices in polygon B.
|
||||
/// @return True if the two polygons overlap.
|
||||
bool dtOverlapPolyPoly2D(const float* polya, const int npolya,
|
||||
const float* polyb, const int npolyb);
|
||||
|
||||
/// @}
|
||||
/// @name Miscellanious functions.
|
||||
/// @{
|
||||
|
||||
inline unsigned int dtNextPow2(unsigned int v)
|
||||
{
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline unsigned int dtIlog2(unsigned int v)
|
||||
{
|
||||
unsigned int r;
|
||||
unsigned int shift;
|
||||
r = static_cast<unsigned int>(v > 0xffff) << 4; v >>= r;
|
||||
shift = static_cast<unsigned int>(v > 0xff) << 3; v >>= shift; r |= shift;
|
||||
shift = static_cast<unsigned int>(v > 0xf) << 2; v >>= shift; r |= shift;
|
||||
shift = static_cast<unsigned int>(v > 0x3) << 1; v >>= shift; r |= shift;
|
||||
r |= (v >> 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
inline int dtAlign4(int x) { return (x+3) & ~3; }
|
||||
|
||||
inline int dtOppositeTile(int side) { return (side+4) & 0x7; }
|
||||
|
||||
inline void dtSwapByte(unsigned char* a, unsigned char* b)
|
||||
{
|
||||
unsigned char tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
inline void dtSwapEndian(unsigned short* v)
|
||||
{
|
||||
unsigned char* x = reinterpret_cast<unsigned char*>(v);
|
||||
dtSwapByte(x+0, x+1);
|
||||
}
|
||||
|
||||
inline void dtSwapEndian(short* v)
|
||||
{
|
||||
unsigned char* x = reinterpret_cast<unsigned char*>(v);
|
||||
dtSwapByte(x+0, x+1);
|
||||
}
|
||||
|
||||
inline void dtSwapEndian(unsigned int* v)
|
||||
{
|
||||
unsigned char* x = reinterpret_cast<unsigned char*>(v);
|
||||
dtSwapByte(x+0, x+3); dtSwapByte(x+1, x+2);
|
||||
}
|
||||
|
||||
inline void dtSwapEndian(int* v)
|
||||
{
|
||||
unsigned char* x = reinterpret_cast<unsigned char*>(v);
|
||||
dtSwapByte(x+0, x+3); dtSwapByte(x+1, x+2);
|
||||
}
|
||||
|
||||
inline void dtSwapEndian(float* v)
|
||||
{
|
||||
unsigned char* x = reinterpret_cast<unsigned char*>(v);
|
||||
dtSwapByte(x+0, x+3); dtSwapByte(x+1, x+2);
|
||||
}
|
||||
|
||||
void dtRandomPointInConvexPoly(const float* pts, const int npts, float* areas,
|
||||
const float s, const float t, float* out);
|
||||
|
||||
template<typename TypeToRetrieveAs>
|
||||
TypeToRetrieveAs* dtGetThenAdvanceBufferPointer(const unsigned char*& buffer, const size_t distanceToAdvance)
|
||||
{
|
||||
TypeToRetrieveAs* returnPointer = reinterpret_cast<TypeToRetrieveAs*>(buffer);
|
||||
buffer += distanceToAdvance;
|
||||
return returnPointer;
|
||||
}
|
||||
|
||||
template<typename TypeToRetrieveAs>
|
||||
TypeToRetrieveAs* dtGetThenAdvanceBufferPointer(unsigned char*& buffer, const size_t distanceToAdvance)
|
||||
{
|
||||
TypeToRetrieveAs* returnPointer = reinterpret_cast<TypeToRetrieveAs*>(buffer);
|
||||
buffer += distanceToAdvance;
|
||||
return returnPointer;
|
||||
}
|
||||
|
||||
|
||||
/// @}
|
||||
|
||||
#endif // DETOURCOMMON_H
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This section contains detailed documentation for members that don't have
|
||||
// a source file. It reduces clutter in the main section of the header.
|
||||
|
||||
/**
|
||||
|
||||
@fn float dtTriArea2D(const float* a, const float* b, const float* c)
|
||||
@par
|
||||
|
||||
The vertices are projected onto the xz-plane, so the y-values are ignored.
|
||||
|
||||
This is a low cost function than can be used for various purposes. Its main purpose
|
||||
is for point/line relationship testing.
|
||||
|
||||
In all cases: A value of zero indicates that all vertices are collinear or represent the same point.
|
||||
(On the xz-plane.)
|
||||
|
||||
When used for point/line relationship tests, AB usually represents a line against which
|
||||
the C point is to be tested. In this case:
|
||||
|
||||
A positive value indicates that point C is to the left of line AB, looking from A toward B.<br/>
|
||||
A negative value indicates that point C is to the right of lineAB, looking from A toward B.
|
||||
|
||||
When used for evaluating a triangle:
|
||||
|
||||
The absolute value of the return value is two times the area of the triangle when it is
|
||||
projected onto the xz-plane.
|
||||
|
||||
A positive return value indicates:
|
||||
|
||||
<ul>
|
||||
<li>The vertices are wrapped in the normal Detour wrap direction.</li>
|
||||
<li>The triangle's 3D face normal is in the general up direction.</li>
|
||||
</ul>
|
||||
|
||||
A negative return value indicates:
|
||||
|
||||
<ul>
|
||||
<li>The vertices are reverse wrapped. (Wrapped opposite the normal Detour wrap direction.)</li>
|
||||
<li>The triangle's 3D face normal is in the general down direction.</li>
|
||||
</ul>
|
||||
|
||||
*/
|
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
@defgroup detour Detour
|
||||
|
||||
Members in this module are wrappers around the standard math library
|
||||
*/
|
||||
|
||||
#ifndef DETOURMATH_H
|
||||
#define DETOURMATH_H
|
||||
|
||||
#include <math.h>
|
||||
// This include is required because libstdc++ has problems with isfinite
|
||||
// if cmath is included before math.h.
|
||||
#include <cmath>
|
||||
|
||||
inline float dtMathFabsf(float x) { return fabsf(x); }
|
||||
inline float dtMathSqrtf(float x) { return sqrtf(x); }
|
||||
inline float dtMathFloorf(float x) { return floorf(x); }
|
||||
inline float dtMathCeilf(float x) { return ceilf(x); }
|
||||
inline float dtMathCosf(float x) { return cosf(x); }
|
||||
inline float dtMathSinf(float x) { return sinf(x); }
|
||||
inline float dtMathAtan2f(float y, float x) { return atan2f(y, x); }
|
||||
inline bool dtMathIsfinite(float x) { return std::isfinite(x); }
|
||||
|
||||
#endif
|
|
@ -0,0 +1,784 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURNAVMESH_H
|
||||
#define DETOURNAVMESH_H
|
||||
|
||||
#include "DetourAlloc.h"
|
||||
#include "DetourStatus.h"
|
||||
|
||||
// Undefine (or define in a build cofnig) the following line to use 64bit polyref.
|
||||
// Generally not needed, useful for very large worlds.
|
||||
// Note: tiles build using 32bit refs are not compatible with 64bit refs!
|
||||
//#define DT_POLYREF64 1
|
||||
|
||||
#ifdef DT_POLYREF64
|
||||
// TODO: figure out a multiplatform version of uint64_t
|
||||
// - maybe: https://code.google.com/p/msinttypes/
|
||||
// - or: http://www.azillionmonkeys.com/qed/pstdint.h
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
// Note: If you want to use 64-bit refs, change the types of both dtPolyRef & dtTileRef.
|
||||
// It is also recommended that you change dtHashRef() to a proper 64-bit hash.
|
||||
|
||||
/// A handle to a polygon within a navigation mesh tile.
|
||||
/// @ingroup detour
|
||||
#ifdef DT_POLYREF64
|
||||
static const unsigned int DT_SALT_BITS = 16;
|
||||
static const unsigned int DT_TILE_BITS = 28;
|
||||
static const unsigned int DT_POLY_BITS = 20;
|
||||
typedef uint64_t dtPolyRef;
|
||||
#else
|
||||
typedef unsigned int dtPolyRef;
|
||||
#endif
|
||||
|
||||
/// A handle to a tile within a navigation mesh.
|
||||
/// @ingroup detour
|
||||
#ifdef DT_POLYREF64
|
||||
typedef uint64_t dtTileRef;
|
||||
#else
|
||||
typedef unsigned int dtTileRef;
|
||||
#endif
|
||||
|
||||
/// The maximum number of vertices per navigation polygon.
|
||||
/// @ingroup detour
|
||||
static const int DT_VERTS_PER_POLYGON = 6;
|
||||
|
||||
/// @{
|
||||
/// @name Tile Serialization Constants
|
||||
/// These constants are used to detect whether a navigation tile's data
|
||||
/// and state format is compatible with the current build.
|
||||
///
|
||||
|
||||
/// A magic number used to detect compatibility of navigation tile data.
|
||||
static const int DT_NAVMESH_MAGIC = 'D'<<24 | 'N'<<16 | 'A'<<8 | 'V';
|
||||
|
||||
/// A version number used to detect compatibility of navigation tile data.
|
||||
static const int DT_NAVMESH_VERSION = 7;
|
||||
|
||||
/// A magic number used to detect the compatibility of navigation tile states.
|
||||
static const int DT_NAVMESH_STATE_MAGIC = 'D'<<24 | 'N'<<16 | 'M'<<8 | 'S';
|
||||
|
||||
/// A version number used to detect compatibility of navigation tile states.
|
||||
static const int DT_NAVMESH_STATE_VERSION = 1;
|
||||
|
||||
/// @}
|
||||
|
||||
/// A flag that indicates that an entity links to an external entity.
|
||||
/// (E.g. A polygon edge is a portal that links to another polygon.)
|
||||
static const unsigned short DT_EXT_LINK = 0x8000;
|
||||
|
||||
/// A value that indicates the entity does not link to anything.
|
||||
static const unsigned int DT_NULL_LINK = 0xffffffff;
|
||||
|
||||
/// A flag that indicates that an off-mesh connection can be traversed in both directions. (Is bidirectional.)
|
||||
static const unsigned int DT_OFFMESH_CON_BIDIR = 1;
|
||||
|
||||
/// The maximum number of user defined area ids.
|
||||
/// @ingroup detour
|
||||
static const int DT_MAX_AREAS = 64;
|
||||
|
||||
/// Tile flags used for various functions and fields.
|
||||
/// For an example, see dtNavMesh::addTile().
|
||||
enum dtTileFlags
|
||||
{
|
||||
/// The navigation mesh owns the tile memory and is responsible for freeing it.
|
||||
DT_TILE_FREE_DATA = 0x01,
|
||||
};
|
||||
|
||||
/// Vertex flags returned by dtNavMeshQuery::findStraightPath.
|
||||
enum dtStraightPathFlags
|
||||
{
|
||||
DT_STRAIGHTPATH_START = 0x01, ///< The vertex is the start position in the path.
|
||||
DT_STRAIGHTPATH_END = 0x02, ///< The vertex is the end position in the path.
|
||||
DT_STRAIGHTPATH_OFFMESH_CONNECTION = 0x04, ///< The vertex is the start of an off-mesh connection.
|
||||
};
|
||||
|
||||
/// Options for dtNavMeshQuery::findStraightPath.
|
||||
enum dtStraightPathOptions
|
||||
{
|
||||
DT_STRAIGHTPATH_AREA_CROSSINGS = 0x01, ///< Add a vertex at every polygon edge crossing where area changes.
|
||||
DT_STRAIGHTPATH_ALL_CROSSINGS = 0x02, ///< Add a vertex at every polygon edge crossing.
|
||||
};
|
||||
|
||||
|
||||
/// Options for dtNavMeshQuery::initSlicedFindPath and updateSlicedFindPath
|
||||
enum dtFindPathOptions
|
||||
{
|
||||
DT_FINDPATH_ANY_ANGLE = 0x02, ///< use raycasts during pathfind to "shortcut" (raycast still consider costs)
|
||||
};
|
||||
|
||||
/// Options for dtNavMeshQuery::raycast
|
||||
enum dtRaycastOptions
|
||||
{
|
||||
DT_RAYCAST_USE_COSTS = 0x01, ///< Raycast should calculate movement cost along the ray and fill RaycastHit::cost
|
||||
};
|
||||
|
||||
enum dtDetailTriEdgeFlags
|
||||
{
|
||||
DT_DETAIL_EDGE_BOUNDARY = 0x01, ///< Detail triangle edge is part of the poly boundary
|
||||
};
|
||||
|
||||
|
||||
/// Limit raycasting during any angle pahfinding
|
||||
/// The limit is given as a multiple of the character radius
|
||||
static const float DT_RAY_CAST_LIMIT_PROPORTIONS = 50.0f;
|
||||
|
||||
/// Flags representing the type of a navigation mesh polygon.
|
||||
enum dtPolyTypes
|
||||
{
|
||||
/// The polygon is a standard convex polygon that is part of the surface of the mesh.
|
||||
DT_POLYTYPE_GROUND = 0,
|
||||
/// The polygon is an off-mesh connection consisting of two vertices.
|
||||
DT_POLYTYPE_OFFMESH_CONNECTION = 1,
|
||||
};
|
||||
|
||||
|
||||
/// Defines a polygon within a dtMeshTile object.
|
||||
/// @ingroup detour
|
||||
struct dtPoly
|
||||
{
|
||||
/// Index to first link in linked list. (Or #DT_NULL_LINK if there is no link.)
|
||||
unsigned int firstLink;
|
||||
|
||||
/// The indices of the polygon's vertices.
|
||||
/// The actual vertices are located in dtMeshTile::verts.
|
||||
unsigned short verts[DT_VERTS_PER_POLYGON];
|
||||
|
||||
/// Packed data representing neighbor polygons references and flags for each edge.
|
||||
unsigned short neis[DT_VERTS_PER_POLYGON];
|
||||
|
||||
/// The user defined polygon flags.
|
||||
unsigned short flags;
|
||||
|
||||
/// The number of vertices in the polygon.
|
||||
unsigned char vertCount;
|
||||
|
||||
/// The bit packed area id and polygon type.
|
||||
/// @note Use the structure's set and get methods to acess this value.
|
||||
unsigned char areaAndtype;
|
||||
|
||||
/// Sets the user defined area id. [Limit: < #DT_MAX_AREAS]
|
||||
inline void setArea(unsigned char a) { areaAndtype = (areaAndtype & 0xc0) | (a & 0x3f); }
|
||||
|
||||
/// Sets the polygon type. (See: #dtPolyTypes.)
|
||||
inline void setType(unsigned char t) { areaAndtype = static_cast<unsigned char>(areaAndtype & 0x3f) | static_cast<unsigned char>(t << 6); }
|
||||
|
||||
/// Gets the user defined area id.
|
||||
inline unsigned char getArea() const { return areaAndtype & 0x3f; }
|
||||
|
||||
/// Gets the polygon type. (See: #dtPolyTypes)
|
||||
inline unsigned char getType() const { return areaAndtype >> 6; }
|
||||
};
|
||||
|
||||
/// Defines the location of detail sub-mesh data within a dtMeshTile.
|
||||
struct dtPolyDetail
|
||||
{
|
||||
unsigned int vertBase; ///< The offset of the vertices in the dtMeshTile::detailVerts array.
|
||||
unsigned int triBase; ///< The offset of the triangles in the dtMeshTile::detailTris array.
|
||||
unsigned char vertCount; ///< The number of vertices in the sub-mesh.
|
||||
unsigned char triCount; ///< The number of triangles in the sub-mesh.
|
||||
};
|
||||
|
||||
/// Defines a link between polygons.
|
||||
/// @note This structure is rarely if ever used by the end user.
|
||||
/// @see dtMeshTile
|
||||
struct dtLink
|
||||
{
|
||||
dtPolyRef ref; ///< Neighbour reference. (The neighbor that is linked to.)
|
||||
unsigned int next; ///< Index of the next link.
|
||||
unsigned char edge; ///< Index of the polygon edge that owns this link.
|
||||
unsigned char side; ///< If a boundary link, defines on which side the link is.
|
||||
unsigned char bmin; ///< If a boundary link, defines the minimum sub-edge area.
|
||||
unsigned char bmax; ///< If a boundary link, defines the maximum sub-edge area.
|
||||
};
|
||||
|
||||
/// Bounding volume node.
|
||||
/// @note This structure is rarely if ever used by the end user.
|
||||
/// @see dtMeshTile
|
||||
struct dtBVNode
|
||||
{
|
||||
unsigned short bmin[3]; ///< Minimum bounds of the node's AABB. [(x, y, z)]
|
||||
unsigned short bmax[3]; ///< Maximum bounds of the node's AABB. [(x, y, z)]
|
||||
int i; ///< The node's index. (Negative for escape sequence.)
|
||||
};
|
||||
|
||||
/// Defines an navigation mesh off-mesh connection within a dtMeshTile object.
|
||||
/// An off-mesh connection is a user defined traversable connection made up to two vertices.
|
||||
struct dtOffMeshConnection
|
||||
{
|
||||
/// The endpoints of the connection. [(ax, ay, az, bx, by, bz)]
|
||||
float pos[6];
|
||||
|
||||
/// The radius of the endpoints. [Limit: >= 0]
|
||||
float rad;
|
||||
|
||||
/// The polygon reference of the connection within the tile.
|
||||
unsigned short poly;
|
||||
|
||||
/// Link flags.
|
||||
/// @note These are not the connection's user defined flags. Those are assigned via the
|
||||
/// connection's dtPoly definition. These are link flags used for internal purposes.
|
||||
unsigned char flags;
|
||||
|
||||
/// End point side.
|
||||
unsigned char side;
|
||||
|
||||
/// The id of the offmesh connection. (User assigned when the navigation mesh is built.)
|
||||
unsigned int userId;
|
||||
};
|
||||
|
||||
/// Provides high level information related to a dtMeshTile object.
|
||||
/// @ingroup detour
|
||||
struct dtMeshHeader
|
||||
{
|
||||
int magic; ///< Tile magic number. (Used to identify the data format.)
|
||||
int version; ///< Tile data format version number.
|
||||
int x; ///< The x-position of the tile within the dtNavMesh tile grid. (x, y, layer)
|
||||
int y; ///< The y-position of the tile within the dtNavMesh tile grid. (x, y, layer)
|
||||
int layer; ///< The layer of the tile within the dtNavMesh tile grid. (x, y, layer)
|
||||
unsigned int userId; ///< The user defined id of the tile.
|
||||
int polyCount; ///< The number of polygons in the tile.
|
||||
int vertCount; ///< The number of vertices in the tile.
|
||||
int maxLinkCount; ///< The number of allocated links.
|
||||
int detailMeshCount; ///< The number of sub-meshes in the detail mesh.
|
||||
|
||||
/// The number of unique vertices in the detail mesh. (In addition to the polygon vertices.)
|
||||
int detailVertCount;
|
||||
|
||||
int detailTriCount; ///< The number of triangles in the detail mesh.
|
||||
int bvNodeCount; ///< The number of bounding volume nodes. (Zero if bounding volumes are disabled.)
|
||||
int offMeshConCount; ///< The number of off-mesh connections.
|
||||
int offMeshBase; ///< The index of the first polygon which is an off-mesh connection.
|
||||
float walkableHeight; ///< The height of the agents using the tile.
|
||||
float walkableRadius; ///< The radius of the agents using the tile.
|
||||
float walkableClimb; ///< The maximum climb height of the agents using the tile.
|
||||
float bmin[3]; ///< The minimum bounds of the tile's AABB. [(x, y, z)]
|
||||
float bmax[3]; ///< The maximum bounds of the tile's AABB. [(x, y, z)]
|
||||
|
||||
/// The bounding volume quantization factor.
|
||||
float bvQuantFactor;
|
||||
};
|
||||
|
||||
/// Defines a navigation mesh tile.
|
||||
/// @ingroup detour
|
||||
struct dtMeshTile
|
||||
{
|
||||
unsigned int salt; ///< Counter describing modifications to the tile.
|
||||
|
||||
unsigned int linksFreeList; ///< Index to the next free link.
|
||||
dtMeshHeader* header; ///< The tile header.
|
||||
dtPoly* polys; ///< The tile polygons. [Size: dtMeshHeader::polyCount]
|
||||
float* verts; ///< The tile vertices. [Size: dtMeshHeader::vertCount]
|
||||
dtLink* links; ///< The tile links. [Size: dtMeshHeader::maxLinkCount]
|
||||
dtPolyDetail* detailMeshes; ///< The tile's detail sub-meshes. [Size: dtMeshHeader::detailMeshCount]
|
||||
|
||||
/// The detail mesh's unique vertices. [(x, y, z) * dtMeshHeader::detailVertCount]
|
||||
float* detailVerts;
|
||||
|
||||
/// The detail mesh's triangles. [(vertA, vertB, vertC, triFlags) * dtMeshHeader::detailTriCount].
|
||||
/// See dtDetailTriEdgeFlags and dtGetDetailTriEdgeFlags.
|
||||
unsigned char* detailTris;
|
||||
|
||||
/// The tile bounding volume nodes. [Size: dtMeshHeader::bvNodeCount]
|
||||
/// (Will be null if bounding volumes are disabled.)
|
||||
dtBVNode* bvTree;
|
||||
|
||||
dtOffMeshConnection* offMeshCons; ///< The tile off-mesh connections. [Size: dtMeshHeader::offMeshConCount]
|
||||
|
||||
unsigned char* data; ///< The tile data. (Not directly accessed under normal situations.)
|
||||
int dataSize; ///< Size of the tile data.
|
||||
int flags; ///< Tile flags. (See: #dtTileFlags)
|
||||
dtMeshTile* next; ///< The next free tile, or the next tile in the spatial grid.
|
||||
private:
|
||||
dtMeshTile(const dtMeshTile&);
|
||||
dtMeshTile& operator=(const dtMeshTile&);
|
||||
};
|
||||
|
||||
/// Get flags for edge in detail triangle.
|
||||
/// @param triFlags[in] The flags for the triangle (last component of detail vertices above).
|
||||
/// @param edgeIndex[in] The index of the first vertex of the edge. For instance, if 0,
|
||||
/// returns flags for edge AB.
|
||||
inline int dtGetDetailTriEdgeFlags(unsigned char triFlags, int edgeIndex)
|
||||
{
|
||||
return (triFlags >> (edgeIndex * 2)) & 0x3;
|
||||
}
|
||||
|
||||
/// Configuration parameters used to define multi-tile navigation meshes.
|
||||
/// The values are used to allocate space during the initialization of a navigation mesh.
|
||||
/// @see dtNavMesh::init()
|
||||
/// @ingroup detour
|
||||
struct dtNavMeshParams
|
||||
{
|
||||
float orig[3]; ///< The world space origin of the navigation mesh's tile space. [(x, y, z)]
|
||||
float tileWidth; ///< The width of each tile. (Along the x-axis.)
|
||||
float tileHeight; ///< The height of each tile. (Along the z-axis.)
|
||||
int maxTiles; ///< The maximum number of tiles the navigation mesh can contain.
|
||||
int maxPolys; ///< The maximum number of polygons each tile can contain.
|
||||
};
|
||||
|
||||
/// A navigation mesh based on tiles of convex polygons.
|
||||
/// @ingroup detour
|
||||
class dtNavMesh
|
||||
{
|
||||
public:
|
||||
dtNavMesh();
|
||||
~dtNavMesh();
|
||||
|
||||
/// @{
|
||||
/// @name Initialization and Tile Management
|
||||
|
||||
/// Initializes the navigation mesh for tiled use.
|
||||
/// @param[in] params Initialization parameters.
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus init(const dtNavMeshParams* params);
|
||||
|
||||
/// Initializes the navigation mesh for single tile use.
|
||||
/// @param[in] data Data of the new tile. (See: #dtCreateNavMeshData)
|
||||
/// @param[in] dataSize The data size of the new tile.
|
||||
/// @param[in] flags The tile flags. (See: #dtTileFlags)
|
||||
/// @return The status flags for the operation.
|
||||
/// @see dtCreateNavMeshData
|
||||
dtStatus init(unsigned char* data, const int dataSize, const int flags);
|
||||
|
||||
/// The navigation mesh initialization params.
|
||||
const dtNavMeshParams* getParams() const;
|
||||
|
||||
/// Adds a tile to the navigation mesh.
|
||||
/// @param[in] data Data for the new tile mesh. (See: #dtCreateNavMeshData)
|
||||
/// @param[in] dataSize Data size of the new tile mesh.
|
||||
/// @param[in] flags Tile flags. (See: #dtTileFlags)
|
||||
/// @param[in] lastRef The desired reference for the tile. (When reloading a tile.) [opt] [Default: 0]
|
||||
/// @param[out] result The tile reference. (If the tile was succesfully added.) [opt]
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus addTile(unsigned char* data, int dataSize, int flags, dtTileRef lastRef, dtTileRef* result);
|
||||
|
||||
/// Removes the specified tile from the navigation mesh.
|
||||
/// @param[in] ref The reference of the tile to remove.
|
||||
/// @param[out] data Data associated with deleted tile.
|
||||
/// @param[out] dataSize Size of the data associated with deleted tile.
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus removeTile(dtTileRef ref, unsigned char** data, int* dataSize);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @{
|
||||
/// @name Query Functions
|
||||
|
||||
/// Calculates the tile grid location for the specified world position.
|
||||
/// @param[in] pos The world position for the query. [(x, y, z)]
|
||||
/// @param[out] tx The tile's x-location. (x, y)
|
||||
/// @param[out] ty The tile's y-location. (x, y)
|
||||
void calcTileLoc(const float* pos, int* tx, int* ty) const;
|
||||
|
||||
/// Gets the tile at the specified grid location.
|
||||
/// @param[in] x The tile's x-location. (x, y, layer)
|
||||
/// @param[in] y The tile's y-location. (x, y, layer)
|
||||
/// @param[in] layer The tile's layer. (x, y, layer)
|
||||
/// @return The tile, or null if the tile does not exist.
|
||||
const dtMeshTile* getTileAt(const int x, const int y, const int layer) const;
|
||||
|
||||
/// Gets all tiles at the specified grid location. (All layers.)
|
||||
/// @param[in] x The tile's x-location. (x, y)
|
||||
/// @param[in] y The tile's y-location. (x, y)
|
||||
/// @param[out] tiles A pointer to an array of tiles that will hold the result.
|
||||
/// @param[in] maxTiles The maximum tiles the tiles parameter can hold.
|
||||
/// @return The number of tiles returned in the tiles array.
|
||||
int getTilesAt(const int x, const int y,
|
||||
dtMeshTile const** tiles, const int maxTiles) const;
|
||||
|
||||
/// Gets the tile reference for the tile at specified grid location.
|
||||
/// @param[in] x The tile's x-location. (x, y, layer)
|
||||
/// @param[in] y The tile's y-location. (x, y, layer)
|
||||
/// @param[in] layer The tile's layer. (x, y, layer)
|
||||
/// @return The tile reference of the tile, or 0 if there is none.
|
||||
dtTileRef getTileRefAt(int x, int y, int layer) const;
|
||||
|
||||
/// Gets the tile reference for the specified tile.
|
||||
/// @param[in] tile The tile.
|
||||
/// @return The tile reference of the tile.
|
||||
dtTileRef getTileRef(const dtMeshTile* tile) const;
|
||||
|
||||
/// Gets the tile for the specified tile reference.
|
||||
/// @param[in] ref The tile reference of the tile to retrieve.
|
||||
/// @return The tile for the specified reference, or null if the
|
||||
/// reference is invalid.
|
||||
const dtMeshTile* getTileByRef(dtTileRef ref) const;
|
||||
|
||||
/// The maximum number of tiles supported by the navigation mesh.
|
||||
/// @return The maximum number of tiles supported by the navigation mesh.
|
||||
int getMaxTiles() const;
|
||||
|
||||
/// Gets the tile at the specified index.
|
||||
/// @param[in] i The tile index. [Limit: 0 >= index < #getMaxTiles()]
|
||||
/// @return The tile at the specified index.
|
||||
const dtMeshTile* getTile(int i) const;
|
||||
|
||||
/// Gets the tile and polygon for the specified polygon reference.
|
||||
/// @param[in] ref The reference for the a polygon.
|
||||
/// @param[out] tile The tile containing the polygon.
|
||||
/// @param[out] poly The polygon.
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus getTileAndPolyByRef(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const;
|
||||
|
||||
/// Returns the tile and polygon for the specified polygon reference.
|
||||
/// @param[in] ref A known valid reference for a polygon.
|
||||
/// @param[out] tile The tile containing the polygon.
|
||||
/// @param[out] poly The polygon.
|
||||
void getTileAndPolyByRefUnsafe(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const;
|
||||
|
||||
/// Checks the validity of a polygon reference.
|
||||
/// @param[in] ref The polygon reference to check.
|
||||
/// @return True if polygon reference is valid for the navigation mesh.
|
||||
bool isValidPolyRef(dtPolyRef ref) const;
|
||||
|
||||
/// Gets the polygon reference for the tile's base polygon.
|
||||
/// @param[in] tile The tile.
|
||||
/// @return The polygon reference for the base polygon in the specified tile.
|
||||
dtPolyRef getPolyRefBase(const dtMeshTile* tile) const;
|
||||
|
||||
/// Gets the endpoints for an off-mesh connection, ordered by "direction of travel".
|
||||
/// @param[in] prevRef The reference of the polygon before the connection.
|
||||
/// @param[in] polyRef The reference of the off-mesh connection polygon.
|
||||
/// @param[out] startPos The start position of the off-mesh connection. [(x, y, z)]
|
||||
/// @param[out] endPos The end position of the off-mesh connection. [(x, y, z)]
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const;
|
||||
|
||||
/// Gets the specified off-mesh connection.
|
||||
/// @param[in] ref The polygon reference of the off-mesh connection.
|
||||
/// @return The specified off-mesh connection, or null if the polygon reference is not valid.
|
||||
const dtOffMeshConnection* getOffMeshConnectionByRef(dtPolyRef ref) const;
|
||||
|
||||
/// @}
|
||||
|
||||
/// @{
|
||||
/// @name State Management
|
||||
/// These functions do not effect #dtTileRef or #dtPolyRef's.
|
||||
|
||||
/// Sets the user defined flags for the specified polygon.
|
||||
/// @param[in] ref The polygon reference.
|
||||
/// @param[in] flags The new flags for the polygon.
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus setPolyFlags(dtPolyRef ref, unsigned short flags);
|
||||
|
||||
/// Gets the user defined flags for the specified polygon.
|
||||
/// @param[in] ref The polygon reference.
|
||||
/// @param[out] resultFlags The polygon flags.
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus getPolyFlags(dtPolyRef ref, unsigned short* resultFlags) const;
|
||||
|
||||
/// Sets the user defined area for the specified polygon.
|
||||
/// @param[in] ref The polygon reference.
|
||||
/// @param[in] area The new area id for the polygon. [Limit: < #DT_MAX_AREAS]
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus setPolyArea(dtPolyRef ref, unsigned char area);
|
||||
|
||||
/// Gets the user defined area for the specified polygon.
|
||||
/// @param[in] ref The polygon reference.
|
||||
/// @param[out] resultArea The area id for the polygon.
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus getPolyArea(dtPolyRef ref, unsigned char* resultArea) const;
|
||||
|
||||
/// Gets the size of the buffer required by #storeTileState to store the specified tile's state.
|
||||
/// @param[in] tile The tile.
|
||||
/// @return The size of the buffer required to store the state.
|
||||
int getTileStateSize(const dtMeshTile* tile) const;
|
||||
|
||||
/// Stores the non-structural state of the tile in the specified buffer. (Flags, area ids, etc.)
|
||||
/// @param[in] tile The tile.
|
||||
/// @param[out] data The buffer to store the tile's state in.
|
||||
/// @param[in] maxDataSize The size of the data buffer. [Limit: >= #getTileStateSize]
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus storeTileState(const dtMeshTile* tile, unsigned char* data, const int maxDataSize) const;
|
||||
|
||||
/// Restores the state of the tile.
|
||||
/// @param[in] tile The tile.
|
||||
/// @param[in] data The new state. (Obtained from #storeTileState.)
|
||||
/// @param[in] maxDataSize The size of the state within the data buffer.
|
||||
/// @return The status flags for the operation.
|
||||
dtStatus restoreTileState(dtMeshTile* tile, const unsigned char* data, const int maxDataSize);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @{
|
||||
/// @name Encoding and Decoding
|
||||
/// These functions are generally meant for internal use only.
|
||||
|
||||
/// Derives a standard polygon reference.
|
||||
/// @note This function is generally meant for internal use only.
|
||||
/// @param[in] salt The tile's salt value.
|
||||
/// @param[in] it The index of the tile.
|
||||
/// @param[in] ip The index of the polygon within the tile.
|
||||
inline dtPolyRef encodePolyId(unsigned int salt, unsigned int it, unsigned int ip) const
|
||||
{
|
||||
#ifdef DT_POLYREF64
|
||||
return (static_cast<dtPolyRef>(salt) << (DT_POLY_BITS+DT_TILE_BITS)) | (static_cast<dtPolyRef>(it) << DT_POLY_BITS) | static_cast<dtPolyRef>(ip);
|
||||
#else
|
||||
return (static_cast<dtPolyRef>(salt) << (m_polyBits+m_tileBits)) | (static_cast<dtPolyRef>(it) << m_polyBits) | static_cast<dtPolyRef>(ip);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Decodes a standard polygon reference.
|
||||
/// @note This function is generally meant for internal use only.
|
||||
/// @param[in] ref The polygon reference to decode.
|
||||
/// @param[out] salt The tile's salt value.
|
||||
/// @param[out] it The index of the tile.
|
||||
/// @param[out] ip The index of the polygon within the tile.
|
||||
/// @see #encodePolyId
|
||||
inline void decodePolyId(dtPolyRef ref, unsigned int& salt, unsigned int& it, unsigned int& ip) const
|
||||
{
|
||||
#ifdef DT_POLYREF64
|
||||
const dtPolyRef saltMask = ((dtPolyRef)1<<DT_SALT_BITS)-1;
|
||||
const dtPolyRef tileMask = ((dtPolyRef)1<<DT_TILE_BITS)-1;
|
||||
const dtPolyRef polyMask = ((dtPolyRef)1<<DT_POLY_BITS)-1;
|
||||
salt = (unsigned int)((ref >> (DT_POLY_BITS+DT_TILE_BITS)) & saltMask);
|
||||
it = (unsigned int)((ref >> DT_POLY_BITS) & tileMask);
|
||||
ip = (unsigned int)(ref & polyMask);
|
||||
#else
|
||||
const dtPolyRef saltMask = (static_cast<dtPolyRef>(1) << m_saltBits)-1;
|
||||
const dtPolyRef tileMask = (static_cast<dtPolyRef>(1) << m_tileBits)-1;
|
||||
const dtPolyRef polyMask = (static_cast<dtPolyRef>(1) << m_polyBits)-1;
|
||||
salt = static_cast<unsigned int>((ref >> (m_polyBits+m_tileBits)) & saltMask);
|
||||
it = static_cast<unsigned int>((ref >> m_polyBits) & tileMask);
|
||||
ip = static_cast<unsigned int>(ref & polyMask);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Extracts a tile's salt value from the specified polygon reference.
|
||||
/// @note This function is generally meant for internal use only.
|
||||
/// @param[in] ref The polygon reference.
|
||||
/// @see #encodePolyId
|
||||
inline unsigned int decodePolyIdSalt(dtPolyRef ref) const
|
||||
{
|
||||
#ifdef DT_POLYREF64
|
||||
const dtPolyRef saltMask = (static_cast<dtPolyRef>(1)<<DT_SALT_BITS)-1;
|
||||
return static_cast<unsigned int>((ref >> (DT_POLY_BITS+DT_TILE_BITS)) & saltMask);
|
||||
#else
|
||||
const dtPolyRef saltMask = (static_cast<dtPolyRef>(1) << m_saltBits)-1;
|
||||
return static_cast<unsigned int>((ref >> (m_polyBits+m_tileBits)) & saltMask);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Extracts the tile's index from the specified polygon reference.
|
||||
/// @note This function is generally meant for internal use only.
|
||||
/// @param[in] ref The polygon reference.
|
||||
/// @see #encodePolyId
|
||||
inline unsigned int decodePolyIdTile(dtPolyRef ref) const
|
||||
{
|
||||
#ifdef DT_POLYREF64
|
||||
const dtPolyRef tileMask = (static_cast<dtPolyRef>(1)<<DT_TILE_BITS)-1;
|
||||
return static_cast<unsigned int>((ref >> DT_POLY_BITS) & tileMask);
|
||||
#else
|
||||
const dtPolyRef tileMask = (static_cast<dtPolyRef>(1)<<m_tileBits)-1;
|
||||
return static_cast<unsigned int>((ref >> m_polyBits) & tileMask);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Extracts the polygon's index (within its tile) from the specified polygon reference.
|
||||
/// @note This function is generally meant for internal use only.
|
||||
/// @param[in] ref The polygon reference.
|
||||
/// @see #encodePolyId
|
||||
inline unsigned int decodePolyIdPoly(dtPolyRef ref) const
|
||||
{
|
||||
#ifdef DT_POLYREF64
|
||||
const dtPolyRef polyMask = (static_cast<dtPolyRef>(1)<<DT_POLY_BITS)-1;
|
||||
return static_cast<unsigned int>(ref & polyMask);
|
||||
#else
|
||||
const dtPolyRef polyMask = (static_cast<dtPolyRef>(1)<<m_polyBits)-1;
|
||||
return static_cast<unsigned int>(ref & polyMask);
|
||||
#endif
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator.
|
||||
dtNavMesh(const dtNavMesh&);
|
||||
dtNavMesh& operator=(const dtNavMesh&);
|
||||
|
||||
/// Returns pointer to tile in the tile array.
|
||||
dtMeshTile* getTile(int i);
|
||||
|
||||
/// Returns neighbour tile based on side.
|
||||
int getTilesAt(const int x, const int y,
|
||||
dtMeshTile** tiles, const int maxTiles) const;
|
||||
|
||||
/// Returns neighbour tile based on side.
|
||||
int getNeighbourTilesAt(const int x, const int y, const int side,
|
||||
dtMeshTile** tiles, const int maxTiles) const;
|
||||
|
||||
/// Returns all polygons in neighbour tile based on portal defined by the segment.
|
||||
int findConnectingPolys(const float* va, const float* vb,
|
||||
const dtMeshTile* tile, int side,
|
||||
dtPolyRef* con, float* conarea, int maxcon) const;
|
||||
|
||||
/// Builds internal polygons links for a tile.
|
||||
void connectIntLinks(dtMeshTile* tile);
|
||||
/// Builds internal polygons links for a tile.
|
||||
void baseOffMeshLinks(dtMeshTile* tile);
|
||||
|
||||
/// Builds external polygon links for a tile.
|
||||
void connectExtLinks(dtMeshTile* tile, dtMeshTile* target, int side);
|
||||
/// Builds external polygon links for a tile.
|
||||
void connectExtOffMeshLinks(dtMeshTile* tile, dtMeshTile* target, int side);
|
||||
|
||||
/// Removes external links at specified side.
|
||||
void unconnectLinks(dtMeshTile* tile, dtMeshTile* target);
|
||||
|
||||
|
||||
// TODO: These methods are duplicates from dtNavMeshQuery, but are needed for off-mesh connection finding.
|
||||
|
||||
/// Queries polygons within a tile.
|
||||
int queryPolygonsInTile(const dtMeshTile* tile, const float* qmin, const float* qmax,
|
||||
dtPolyRef* polys, const int maxPolys) const;
|
||||
/// Find nearest polygon within a tile.
|
||||
dtPolyRef findNearestPolyInTile(const dtMeshTile* tile, const float* center,
|
||||
const float* halfExtents, float* nearestPt) const;
|
||||
/// Returns whether position is over the poly and the height at the position if so.
|
||||
bool getPolyHeight(const dtMeshTile* tile, const dtPoly* poly, const float* pos, float* height) const;
|
||||
/// Returns closest point on polygon.
|
||||
void closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest, bool* posOverPoly) const;
|
||||
|
||||
dtNavMeshParams m_params; ///< Current initialization params. TODO: do not store this info twice.
|
||||
float m_orig[3]; ///< Origin of the tile (0,0)
|
||||
float m_tileWidth, m_tileHeight; ///< Dimensions of each tile.
|
||||
int m_maxTiles; ///< Max number of tiles.
|
||||
int m_tileLutSize; ///< Tile hash lookup size (must be pot).
|
||||
int m_tileLutMask; ///< Tile hash lookup mask.
|
||||
|
||||
dtMeshTile** m_posLookup; ///< Tile hash lookup.
|
||||
dtMeshTile* m_nextFree; ///< Freelist of tiles.
|
||||
dtMeshTile* m_tiles; ///< List of tiles.
|
||||
|
||||
#ifndef DT_POLYREF64
|
||||
unsigned int m_saltBits; ///< Number of salt bits in the tile ID.
|
||||
unsigned int m_tileBits; ///< Number of tile bits in the tile ID.
|
||||
unsigned int m_polyBits; ///< Number of poly bits in the tile ID.
|
||||
#endif
|
||||
|
||||
friend class dtNavMeshQuery;
|
||||
};
|
||||
|
||||
/// Allocates a navigation mesh object using the Detour allocator.
|
||||
/// @return A navigation mesh that is ready for initialization, or null on failure.
|
||||
/// @ingroup detour
|
||||
dtNavMesh* dtAllocNavMesh();
|
||||
|
||||
/// Frees the specified navigation mesh object using the Detour allocator.
|
||||
/// @param[in] navmesh A navigation mesh allocated using #dtAllocNavMesh
|
||||
/// @ingroup detour
|
||||
void dtFreeNavMesh(dtNavMesh* navmesh);
|
||||
|
||||
#endif // DETOURNAVMESH_H
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This section contains detailed documentation for members that don't have
|
||||
// a source file. It reduces clutter in the main section of the header.
|
||||
|
||||
/**
|
||||
|
||||
@typedef dtPolyRef
|
||||
@par
|
||||
|
||||
Polygon references are subject to the same invalidate/preserve/restore
|
||||
rules that apply to #dtTileRef's. If the #dtTileRef for the polygon's
|
||||
tile changes, the polygon reference becomes invalid.
|
||||
|
||||
Changing a polygon's flags, area id, etc. does not impact its polygon
|
||||
reference.
|
||||
|
||||
@typedef dtTileRef
|
||||
@par
|
||||
|
||||
The following changes will invalidate a tile reference:
|
||||
|
||||
- The referenced tile has been removed from the navigation mesh.
|
||||
- The navigation mesh has been initialized using a different set
|
||||
of #dtNavMeshParams.
|
||||
|
||||
A tile reference is preserved/restored if the tile is added to a navigation
|
||||
mesh initialized with the original #dtNavMeshParams and is added at the
|
||||
original reference location. (E.g. The lastRef parameter is used with
|
||||
dtNavMesh::addTile.)
|
||||
|
||||
Basically, if the storage structure of a tile changes, its associated
|
||||
tile reference changes.
|
||||
|
||||
|
||||
@var unsigned short dtPoly::neis[DT_VERTS_PER_POLYGON]
|
||||
@par
|
||||
|
||||
Each entry represents data for the edge starting at the vertex of the same index.
|
||||
E.g. The entry at index n represents the edge data for vertex[n] to vertex[n+1].
|
||||
|
||||
A value of zero indicates the edge has no polygon connection. (It makes up the
|
||||
border of the navigation mesh.)
|
||||
|
||||
The information can be extracted as follows:
|
||||
@code
|
||||
neighborRef = neis[n] & 0xff; // Get the neighbor polygon reference.
|
||||
|
||||
if (neis[n] & #DT_EX_LINK)
|
||||
{
|
||||
// The edge is an external (portal) edge.
|
||||
}
|
||||
@endcode
|
||||
|
||||
@var float dtMeshHeader::bvQuantFactor
|
||||
@par
|
||||
|
||||
This value is used for converting between world and bounding volume coordinates.
|
||||
For example:
|
||||
@code
|
||||
const float cs = 1.0f / tile->header->bvQuantFactor;
|
||||
const dtBVNode* n = &tile->bvTree[i];
|
||||
if (n->i >= 0)
|
||||
{
|
||||
// This is a leaf node.
|
||||
float worldMinX = tile->header->bmin[0] + n->bmin[0]*cs;
|
||||
float worldMinY = tile->header->bmin[0] + n->bmin[1]*cs;
|
||||
// Etc...
|
||||
}
|
||||
@endcode
|
||||
|
||||
@struct dtMeshTile
|
||||
@par
|
||||
|
||||
Tiles generally only exist within the context of a dtNavMesh object.
|
||||
|
||||
Some tile content is optional. For example, a tile may not contain any
|
||||
off-mesh connections. In this case the associated pointer will be null.
|
||||
|
||||
If a detail mesh exists it will share vertices with the base polygon mesh.
|
||||
Only the vertices unique to the detail mesh will be stored in #detailVerts.
|
||||
|
||||
@warning Tiles returned by a dtNavMesh object are not guarenteed to be populated.
|
||||
For example: The tile at a location might not have been loaded yet, or may have been removed.
|
||||
In this case, pointers will be null. So if in doubt, check the polygon count in the
|
||||
tile's header to determine if a tile has polygons defined.
|
||||
|
||||
@var float dtOffMeshConnection::pos[6]
|
||||
@par
|
||||
|
||||
For a properly built navigation mesh, vertex A will always be within the bounds of the mesh.
|
||||
Vertex B is not required to be within the bounds of the mesh.
|
||||
|
||||
*/
|
|
@ -0,0 +1,149 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURNAVMESHBUILDER_H
|
||||
#define DETOURNAVMESHBUILDER_H
|
||||
|
||||
#include "DetourAlloc.h"
|
||||
|
||||
/// Represents the source data used to build an navigation mesh tile.
|
||||
/// @ingroup detour
|
||||
struct dtNavMeshCreateParams
|
||||
{
|
||||
|
||||
/// @name Polygon Mesh Attributes
|
||||
/// Used to create the base navigation graph.
|
||||
/// See #rcPolyMesh for details related to these attributes.
|
||||
/// @{
|
||||
|
||||
const unsigned short* verts; ///< The polygon mesh vertices. [(x, y, z) * #vertCount] [Unit: vx]
|
||||
int vertCount; ///< The number vertices in the polygon mesh. [Limit: >= 3]
|
||||
const unsigned short* polys; ///< The polygon data. [Size: #polyCount * 2 * #nvp]
|
||||
const unsigned short* polyFlags; ///< The user defined flags assigned to each polygon. [Size: #polyCount]
|
||||
const unsigned char* polyAreas; ///< The user defined area ids assigned to each polygon. [Size: #polyCount]
|
||||
int polyCount; ///< Number of polygons in the mesh. [Limit: >= 1]
|
||||
int nvp; ///< Number maximum number of vertices per polygon. [Limit: >= 3]
|
||||
|
||||
/// @}
|
||||
/// @name Height Detail Attributes (Optional)
|
||||
/// See #rcPolyMeshDetail for details related to these attributes.
|
||||
/// @{
|
||||
|
||||
const unsigned int* detailMeshes; ///< The height detail sub-mesh data. [Size: 4 * #polyCount]
|
||||
const float* detailVerts; ///< The detail mesh vertices. [Size: 3 * #detailVertsCount] [Unit: wu]
|
||||
int detailVertsCount; ///< The number of vertices in the detail mesh.
|
||||
const unsigned char* detailTris; ///< The detail mesh triangles. [Size: 4 * #detailTriCount]
|
||||
int detailTriCount; ///< The number of triangles in the detail mesh.
|
||||
|
||||
/// @}
|
||||
/// @name Off-Mesh Connections Attributes (Optional)
|
||||
/// Used to define a custom point-to-point edge within the navigation graph, an
|
||||
/// off-mesh connection is a user defined traversable connection made up to two vertices,
|
||||
/// at least one of which resides within a navigation mesh polygon.
|
||||
/// @{
|
||||
|
||||
/// Off-mesh connection vertices. [(ax, ay, az, bx, by, bz) * #offMeshConCount] [Unit: wu]
|
||||
const float* offMeshConVerts;
|
||||
/// Off-mesh connection radii. [Size: #offMeshConCount] [Unit: wu]
|
||||
const float* offMeshConRad;
|
||||
/// User defined flags assigned to the off-mesh connections. [Size: #offMeshConCount]
|
||||
const unsigned short* offMeshConFlags;
|
||||
/// User defined area ids assigned to the off-mesh connections. [Size: #offMeshConCount]
|
||||
const unsigned char* offMeshConAreas;
|
||||
/// The permitted travel direction of the off-mesh connections. [Size: #offMeshConCount]
|
||||
///
|
||||
/// 0 = Travel only from endpoint A to endpoint B.<br/>
|
||||
/// #DT_OFFMESH_CON_BIDIR = Bidirectional travel.
|
||||
const unsigned char* offMeshConDir;
|
||||
/// The user defined ids of the off-mesh connection. [Size: #offMeshConCount]
|
||||
const unsigned int* offMeshConUserID;
|
||||
/// The number of off-mesh connections. [Limit: >= 0]
|
||||
int offMeshConCount;
|
||||
|
||||
/// @}
|
||||
/// @name Tile Attributes
|
||||
/// @note The tile grid/layer data can be left at zero if the destination is a single tile mesh.
|
||||
/// @{
|
||||
|
||||
unsigned int userId; ///< The user defined id of the tile.
|
||||
int tileX; ///< The tile's x-grid location within the multi-tile destination mesh. (Along the x-axis.)
|
||||
int tileY; ///< The tile's y-grid location within the multi-tile desitation mesh. (Along the z-axis.)
|
||||
int tileLayer; ///< The tile's layer within the layered destination mesh. [Limit: >= 0] (Along the y-axis.)
|
||||
float bmin[3]; ///< The minimum bounds of the tile. [(x, y, z)] [Unit: wu]
|
||||
float bmax[3]; ///< The maximum bounds of the tile. [(x, y, z)] [Unit: wu]
|
||||
|
||||
/// @}
|
||||
/// @name General Configuration Attributes
|
||||
/// @{
|
||||
|
||||
float walkableHeight; ///< The agent height. [Unit: wu]
|
||||
float walkableRadius; ///< The agent radius. [Unit: wu]
|
||||
float walkableClimb; ///< The agent maximum traversable ledge. (Up/Down) [Unit: wu]
|
||||
float cs; ///< The xz-plane cell size of the polygon mesh. [Limit: > 0] [Unit: wu]
|
||||
float ch; ///< The y-axis cell height of the polygon mesh. [Limit: > 0] [Unit: wu]
|
||||
|
||||
/// True if a bounding volume tree should be built for the tile.
|
||||
/// @note The BVTree is not normally needed for layered navigation meshes.
|
||||
bool buildBvTree;
|
||||
|
||||
/// @}
|
||||
};
|
||||
|
||||
/// Builds navigation mesh tile data from the provided tile creation data.
|
||||
/// @ingroup detour
|
||||
/// @param[in] params Tile creation data.
|
||||
/// @param[out] outData The resulting tile data.
|
||||
/// @param[out] outDataSize The size of the tile data array.
|
||||
/// @return True if the tile data was successfully created.
|
||||
bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, int* outDataSize);
|
||||
|
||||
/// Swaps the endianess of the tile data's header (#dtMeshHeader).
|
||||
/// @param[in,out] data The tile data array.
|
||||
/// @param[in] dataSize The size of the data array.
|
||||
bool dtNavMeshHeaderSwapEndian(unsigned char* data, const int dataSize);
|
||||
|
||||
/// Swaps endianess of the tile data.
|
||||
/// @param[in,out] data The tile data array.
|
||||
/// @param[in] dataSize The size of the data array.
|
||||
bool dtNavMeshDataSwapEndian(unsigned char* data, const int dataSize);
|
||||
|
||||
#endif // DETOURNAVMESHBUILDER_H
|
||||
|
||||
// This section contains detailed documentation for members that don't have
|
||||
// a source file. It reduces clutter in the main section of the header.
|
||||
|
||||
/**
|
||||
|
||||
@struct dtNavMeshCreateParams
|
||||
@par
|
||||
|
||||
This structure is used to marshal data between the Recast mesh generation pipeline and Detour navigation components.
|
||||
|
||||
See the rcPolyMesh and rcPolyMeshDetail documentation for detailed information related to mesh structure.
|
||||
|
||||
Units are usually in voxels (vx) or world units (wu). The units for voxels, grid size, and cell size
|
||||
are all based on the values of #cs and #ch.
|
||||
|
||||
The standard navigation mesh build process is to create tile data using dtCreateNavMeshData, then add the tile
|
||||
to a navigation mesh using either the dtNavMesh single tile <tt>init()</tt> function or the dtNavMesh::addTile()
|
||||
function.
|
||||
|
||||
@see dtCreateNavMeshData
|
||||
|
||||
*/
|
||||
|
|
@ -0,0 +1,573 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURNAVMESHQUERY_H
|
||||
#define DETOURNAVMESHQUERY_H
|
||||
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourStatus.h"
|
||||
|
||||
|
||||
// Define DT_VIRTUAL_QUERYFILTER if you wish to derive a custom filter from dtQueryFilter.
|
||||
// On certain platforms indirect or virtual function call is expensive. The default
|
||||
// setting is to use non-virtual functions, the actual implementations of the functions
|
||||
// are declared as inline for maximum speed.
|
||||
|
||||
//#define DT_VIRTUAL_QUERYFILTER 1
|
||||
|
||||
/// Defines polygon filtering and traversal costs for navigation mesh query operations.
|
||||
/// @ingroup detour
|
||||
class dtQueryFilter
|
||||
{
|
||||
float m_areaCost[DT_MAX_AREAS]; ///< Cost per area type. (Used by default implementation.)
|
||||
unsigned short m_includeFlags; ///< Flags for polygons that can be visited. (Used by default implementation.)
|
||||
unsigned short m_excludeFlags; ///< Flags for polygons that should not be visted. (Used by default implementation.)
|
||||
|
||||
public:
|
||||
dtQueryFilter();
|
||||
|
||||
#ifdef DT_VIRTUAL_QUERYFILTER
|
||||
virtual ~dtQueryFilter() { }
|
||||
#endif
|
||||
|
||||
/// Returns true if the polygon can be visited. (I.e. Is traversable.)
|
||||
/// @param[in] ref The reference id of the polygon test.
|
||||
/// @param[in] tile The tile containing the polygon.
|
||||
/// @param[in] poly The polygon to test.
|
||||
#ifdef DT_VIRTUAL_QUERYFILTER
|
||||
virtual bool passFilter(const dtPolyRef ref,
|
||||
const dtMeshTile* tile,
|
||||
const dtPoly* poly) const;
|
||||
#else
|
||||
bool passFilter(const dtPolyRef ref,
|
||||
const dtMeshTile* tile,
|
||||
const dtPoly* poly) const;
|
||||
#endif
|
||||
|
||||
/// Returns cost to move from the beginning to the end of a line segment
|
||||
/// that is fully contained within a polygon.
|
||||
/// @param[in] pa The start position on the edge of the previous and current polygon. [(x, y, z)]
|
||||
/// @param[in] pb The end position on the edge of the current and next polygon. [(x, y, z)]
|
||||
/// @param[in] prevRef The reference id of the previous polygon. [opt]
|
||||
/// @param[in] prevTile The tile containing the previous polygon. [opt]
|
||||
/// @param[in] prevPoly The previous polygon. [opt]
|
||||
/// @param[in] curRef The reference id of the current polygon.
|
||||
/// @param[in] curTile The tile containing the current polygon.
|
||||
/// @param[in] curPoly The current polygon.
|
||||
/// @param[in] nextRef The refernece id of the next polygon. [opt]
|
||||
/// @param[in] nextTile The tile containing the next polygon. [opt]
|
||||
/// @param[in] nextPoly The next polygon. [opt]
|
||||
#ifdef DT_VIRTUAL_QUERYFILTER
|
||||
virtual float getCost(const float* pa, const float* pb,
|
||||
const dtPolyRef prevRef, const dtMeshTile* prevTile, const dtPoly* prevPoly,
|
||||
const dtPolyRef curRef, const dtMeshTile* curTile, const dtPoly* curPoly,
|
||||
const dtPolyRef nextRef, const dtMeshTile* nextTile, const dtPoly* nextPoly) const;
|
||||
#else
|
||||
float getCost(const float* pa, const float* pb,
|
||||
const dtPolyRef prevRef, const dtMeshTile* prevTile, const dtPoly* prevPoly,
|
||||
const dtPolyRef curRef, const dtMeshTile* curTile, const dtPoly* curPoly,
|
||||
const dtPolyRef nextRef, const dtMeshTile* nextTile, const dtPoly* nextPoly) const;
|
||||
#endif
|
||||
|
||||
/// @name Getters and setters for the default implementation data.
|
||||
///@{
|
||||
|
||||
/// Returns the traversal cost of the area.
|
||||
/// @param[in] i The id of the area.
|
||||
/// @returns The traversal cost of the area.
|
||||
inline float getAreaCost(const int i) const { return m_areaCost[i]; }
|
||||
|
||||
/// Sets the traversal cost of the area.
|
||||
/// @param[in] i The id of the area.
|
||||
/// @param[in] cost The new cost of traversing the area.
|
||||
inline void setAreaCost(const int i, const float cost) { m_areaCost[i] = cost; }
|
||||
|
||||
/// Returns the include flags for the filter.
|
||||
/// Any polygons that include one or more of these flags will be
|
||||
/// included in the operation.
|
||||
inline unsigned short getIncludeFlags() const { return m_includeFlags; }
|
||||
|
||||
/// Sets the include flags for the filter.
|
||||
/// @param[in] flags The new flags.
|
||||
inline void setIncludeFlags(const unsigned short flags) { m_includeFlags = flags; }
|
||||
|
||||
/// Returns the exclude flags for the filter.
|
||||
/// Any polygons that include one ore more of these flags will be
|
||||
/// excluded from the operation.
|
||||
inline unsigned short getExcludeFlags() const { return m_excludeFlags; }
|
||||
|
||||
/// Sets the exclude flags for the filter.
|
||||
/// @param[in] flags The new flags.
|
||||
inline void setExcludeFlags(const unsigned short flags) { m_excludeFlags = flags; }
|
||||
|
||||
///@}
|
||||
|
||||
};
|
||||
|
||||
/// Provides information about raycast hit
|
||||
/// filled by dtNavMeshQuery::raycast
|
||||
/// @ingroup detour
|
||||
struct dtRaycastHit
|
||||
{
|
||||
/// The hit parameter. (FLT_MAX if no wall hit.)
|
||||
float t;
|
||||
|
||||
/// hitNormal The normal of the nearest wall hit. [(x, y, z)]
|
||||
float hitNormal[3];
|
||||
|
||||
/// The index of the edge on the final polygon where the wall was hit.
|
||||
int hitEdgeIndex;
|
||||
|
||||
/// Pointer to an array of reference ids of the visited polygons. [opt]
|
||||
dtPolyRef* path;
|
||||
|
||||
/// The number of visited polygons. [opt]
|
||||
int pathCount;
|
||||
|
||||
/// The maximum number of polygons the @p path array can hold.
|
||||
int maxPath;
|
||||
|
||||
/// The cost of the path until hit.
|
||||
float pathCost;
|
||||
};
|
||||
|
||||
/// Provides custom polygon query behavior.
|
||||
/// Used by dtNavMeshQuery::queryPolygons.
|
||||
/// @ingroup detour
|
||||
class dtPolyQuery
|
||||
{
|
||||
public:
|
||||
virtual ~dtPolyQuery() { }
|
||||
|
||||
/// Called for each batch of unique polygons touched by the search area in dtNavMeshQuery::queryPolygons.
|
||||
/// This can be called multiple times for a single query.
|
||||
virtual void process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count) = 0;
|
||||
};
|
||||
|
||||
/// Provides the ability to perform pathfinding related queries against
|
||||
/// a navigation mesh.
|
||||
/// @ingroup detour
|
||||
class dtNavMeshQuery
|
||||
{
|
||||
public:
|
||||
dtNavMeshQuery();
|
||||
~dtNavMeshQuery();
|
||||
|
||||
/// Initializes the query object.
|
||||
/// @param[in] nav Pointer to the dtNavMesh object to use for all queries.
|
||||
/// @param[in] maxNodes Maximum number of search nodes. [Limits: 0 < value <= 65535]
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus init(const dtNavMesh* nav, const int maxNodes);
|
||||
|
||||
/// @name Standard Pathfinding Functions
|
||||
// /@{
|
||||
|
||||
/// Finds a path from the start polygon to the end polygon.
|
||||
/// @param[in] startRef The refrence id of the start polygon.
|
||||
/// @param[in] endRef The reference id of the end polygon.
|
||||
/// @param[in] startPos A position within the start polygon. [(x, y, z)]
|
||||
/// @param[in] endPos A position within the end polygon. [(x, y, z)]
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[out] path An ordered list of polygon references representing the path. (Start to end.)
|
||||
/// [(polyRef) * @p pathCount]
|
||||
/// @param[out] pathCount The number of polygons returned in the @p path array.
|
||||
/// @param[in] maxPath The maximum number of polygons the @p path array can hold. [Limit: >= 1]
|
||||
dtStatus findPath(dtPolyRef startRef, dtPolyRef endRef,
|
||||
const float* startPos, const float* endPos,
|
||||
const dtQueryFilter* filter,
|
||||
dtPolyRef* path, int* pathCount, const int maxPath) const;
|
||||
|
||||
/// Finds the straight path from the start to the end position within the polygon corridor.
|
||||
/// @param[in] startPos Path start position. [(x, y, z)]
|
||||
/// @param[in] endPos Path end position. [(x, y, z)]
|
||||
/// @param[in] path An array of polygon references that represent the path corridor.
|
||||
/// @param[in] pathSize The number of polygons in the @p path array.
|
||||
/// @param[out] straightPath Points describing the straight path. [(x, y, z) * @p straightPathCount].
|
||||
/// @param[out] straightPathFlags Flags describing each point. (See: #dtStraightPathFlags) [opt]
|
||||
/// @param[out] straightPathRefs The reference id of the polygon that is being entered at each point. [opt]
|
||||
/// @param[out] straightPathCount The number of points in the straight path.
|
||||
/// @param[in] maxStraightPath The maximum number of points the straight path arrays can hold. [Limit: > 0]
|
||||
/// @param[in] options Query options. (see: #dtStraightPathOptions)
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus findStraightPath(const float* startPos, const float* endPos,
|
||||
const dtPolyRef* path, const int pathSize,
|
||||
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
||||
int* straightPathCount, const int maxStraightPath, const int options = 0) const;
|
||||
|
||||
///@}
|
||||
/// @name Sliced Pathfinding Functions
|
||||
/// Common use case:
|
||||
/// -# Call initSlicedFindPath() to initialize the sliced path query.
|
||||
/// -# Call updateSlicedFindPath() until it returns complete.
|
||||
/// -# Call finalizeSlicedFindPath() to get the path.
|
||||
///@{
|
||||
|
||||
/// Intializes a sliced path query.
|
||||
/// @param[in] startRef The refrence id of the start polygon.
|
||||
/// @param[in] endRef The reference id of the end polygon.
|
||||
/// @param[in] startPos A position within the start polygon. [(x, y, z)]
|
||||
/// @param[in] endPos A position within the end polygon. [(x, y, z)]
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[in] options query options (see: #dtFindPathOptions)
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef,
|
||||
const float* startPos, const float* endPos,
|
||||
const dtQueryFilter* filter, const unsigned int options = 0);
|
||||
|
||||
/// Updates an in-progress sliced path query.
|
||||
/// @param[in] maxIter The maximum number of iterations to perform.
|
||||
/// @param[out] doneIters The actual number of iterations completed. [opt]
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus updateSlicedFindPath(const int maxIter, int* doneIters);
|
||||
|
||||
/// Finalizes and returns the results of a sliced path query.
|
||||
/// @param[out] path An ordered list of polygon references representing the path. (Start to end.)
|
||||
/// [(polyRef) * @p pathCount]
|
||||
/// @param[out] pathCount The number of polygons returned in the @p path array.
|
||||
/// @param[in] maxPath The max number of polygons the path array can hold. [Limit: >= 1]
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath);
|
||||
|
||||
/// Finalizes and returns the results of an incomplete sliced path query, returning the path to the furthest
|
||||
/// polygon on the existing path that was visited during the search.
|
||||
/// @param[in] existing An array of polygon references for the existing path.
|
||||
/// @param[in] existingSize The number of polygon in the @p existing array.
|
||||
/// @param[out] path An ordered list of polygon references representing the path. (Start to end.)
|
||||
/// [(polyRef) * @p pathCount]
|
||||
/// @param[out] pathCount The number of polygons returned in the @p path array.
|
||||
/// @param[in] maxPath The max number of polygons the @p path array can hold. [Limit: >= 1]
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus finalizeSlicedFindPathPartial(const dtPolyRef* existing, const int existingSize,
|
||||
dtPolyRef* path, int* pathCount, const int maxPath);
|
||||
|
||||
///@}
|
||||
/// @name Dijkstra Search Functions
|
||||
/// @{
|
||||
|
||||
/// Finds the polygons along the navigation graph that touch the specified circle.
|
||||
/// @param[in] startRef The reference id of the polygon where the search starts.
|
||||
/// @param[in] centerPos The center of the search circle. [(x, y, z)]
|
||||
/// @param[in] radius The radius of the search circle.
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[out] resultRef The reference ids of the polygons touched by the circle. [opt]
|
||||
/// @param[out] resultParent The reference ids of the parent polygons for each result.
|
||||
/// Zero if a result polygon has no parent. [opt]
|
||||
/// @param[out] resultCost The search cost from @p centerPos to the polygon. [opt]
|
||||
/// @param[out] resultCount The number of polygons found. [opt]
|
||||
/// @param[in] maxResult The maximum number of polygons the result arrays can hold.
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus findPolysAroundCircle(dtPolyRef startRef, const float* centerPos, const float radius,
|
||||
const dtQueryFilter* filter,
|
||||
dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost,
|
||||
int* resultCount, const int maxResult) const;
|
||||
|
||||
/// Finds the polygons along the naviation graph that touch the specified convex polygon.
|
||||
/// @param[in] startRef The reference id of the polygon where the search starts.
|
||||
/// @param[in] verts The vertices describing the convex polygon. (CCW)
|
||||
/// [(x, y, z) * @p nverts]
|
||||
/// @param[in] nverts The number of vertices in the polygon.
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[out] resultRef The reference ids of the polygons touched by the search polygon. [opt]
|
||||
/// @param[out] resultParent The reference ids of the parent polygons for each result. Zero if a
|
||||
/// result polygon has no parent. [opt]
|
||||
/// @param[out] resultCost The search cost from the centroid point to the polygon. [opt]
|
||||
/// @param[out] resultCount The number of polygons found.
|
||||
/// @param[in] maxResult The maximum number of polygons the result arrays can hold.
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus findPolysAroundShape(dtPolyRef startRef, const float* verts, const int nverts,
|
||||
const dtQueryFilter* filter,
|
||||
dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost,
|
||||
int* resultCount, const int maxResult) const;
|
||||
|
||||
/// Gets a path from the explored nodes in the previous search.
|
||||
/// @param[in] endRef The reference id of the end polygon.
|
||||
/// @param[out] path An ordered list of polygon references representing the path. (Start to end.)
|
||||
/// [(polyRef) * @p pathCount]
|
||||
/// @param[out] pathCount The number of polygons returned in the @p path array.
|
||||
/// @param[in] maxPath The maximum number of polygons the @p path array can hold. [Limit: >= 0]
|
||||
/// @returns The status flags. Returns DT_FAILURE | DT_INVALID_PARAM if any parameter is wrong, or if
|
||||
/// @p endRef was not explored in the previous search. Returns DT_SUCCESS | DT_BUFFER_TOO_SMALL
|
||||
/// if @p path cannot contain the entire path. In this case it is filled to capacity with a partial path.
|
||||
/// Otherwise returns DT_SUCCESS.
|
||||
/// @remarks The result of this function depends on the state of the query object. For that reason it should only
|
||||
/// be used immediately after one of the two Dijkstra searches, findPolysAroundCircle or findPolysAroundShape.
|
||||
dtStatus getPathFromDijkstraSearch(dtPolyRef endRef, dtPolyRef* path, int* pathCount, int maxPath) const;
|
||||
|
||||
/// @}
|
||||
/// @name Local Query Functions
|
||||
///@{
|
||||
|
||||
/// Finds the polygon nearest to the specified center point.
|
||||
/// @param[in] center The center of the search box. [(x, y, z)]
|
||||
/// @param[in] halfExtents The search distance along each axis. [(x, y, z)]
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[out] nearestRef The reference id of the nearest polygon.
|
||||
/// @param[out] nearestPt The nearest point on the polygon. [opt] [(x, y, z)]
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus findNearestPoly(const float* center, const float* halfExtents,
|
||||
const dtQueryFilter* filter,
|
||||
dtPolyRef* nearestRef, float* nearestPt) const;
|
||||
|
||||
/// Finds polygons that overlap the search box.
|
||||
/// @param[in] center The center of the search box. [(x, y, z)]
|
||||
/// @param[in] halfExtents The search distance along each axis. [(x, y, z)]
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[out] polys The reference ids of the polygons that overlap the query box.
|
||||
/// @param[out] polyCount The number of polygons in the search result.
|
||||
/// @param[in] maxPolys The maximum number of polygons the search result can hold.
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus queryPolygons(const float* center, const float* halfExtents,
|
||||
const dtQueryFilter* filter,
|
||||
dtPolyRef* polys, int* polyCount, const int maxPolys) const;
|
||||
|
||||
/// Finds polygons that overlap the search box.
|
||||
/// @param[in] center The center of the search box. [(x, y, z)]
|
||||
/// @param[in] halfExtents The search distance along each axis. [(x, y, z)]
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[in] query The query. Polygons found will be batched together and passed to this query.
|
||||
dtStatus queryPolygons(const float* center, const float* halfExtents,
|
||||
const dtQueryFilter* filter, dtPolyQuery* query) const;
|
||||
|
||||
/// Finds the non-overlapping navigation polygons in the local neighbourhood around the center position.
|
||||
/// @param[in] startRef The reference id of the polygon where the search starts.
|
||||
/// @param[in] centerPos The center of the query circle. [(x, y, z)]
|
||||
/// @param[in] radius The radius of the query circle.
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[out] resultRef The reference ids of the polygons touched by the circle.
|
||||
/// @param[out] resultParent The reference ids of the parent polygons for each result.
|
||||
/// Zero if a result polygon has no parent. [opt]
|
||||
/// @param[out] resultCount The number of polygons found.
|
||||
/// @param[in] maxResult The maximum number of polygons the result arrays can hold.
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus findLocalNeighbourhood(dtPolyRef startRef, const float* centerPos, const float radius,
|
||||
const dtQueryFilter* filter,
|
||||
dtPolyRef* resultRef, dtPolyRef* resultParent,
|
||||
int* resultCount, const int maxResult) const;
|
||||
|
||||
/// Moves from the start to the end position constrained to the navigation mesh.
|
||||
/// @param[in] startRef The reference id of the start polygon.
|
||||
/// @param[in] startPos A position of the mover within the start polygon. [(x, y, x)]
|
||||
/// @param[in] endPos The desired end position of the mover. [(x, y, z)]
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[out] resultPos The result position of the mover. [(x, y, z)]
|
||||
/// @param[out] visited The reference ids of the polygons visited during the move.
|
||||
/// @param[out] visitedCount The number of polygons visited during the move.
|
||||
/// @param[in] maxVisitedSize The maximum number of polygons the @p visited array can hold.
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus moveAlongSurface(dtPolyRef startRef, const float* startPos, const float* endPos,
|
||||
const dtQueryFilter* filter,
|
||||
float* resultPos, dtPolyRef* visited, int* visitedCount, const int maxVisitedSize) const;
|
||||
|
||||
/// Casts a 'walkability' ray along the surface of the navigation mesh from
|
||||
/// the start position toward the end position.
|
||||
/// @note A wrapper around raycast(..., RaycastHit*). Retained for backward compatibility.
|
||||
/// @param[in] startRef The reference id of the start polygon.
|
||||
/// @param[in] startPos A position within the start polygon representing
|
||||
/// the start of the ray. [(x, y, z)]
|
||||
/// @param[in] endPos The position to cast the ray toward. [(x, y, z)]
|
||||
/// @param[out] t The hit parameter. (FLT_MAX if no wall hit.)
|
||||
/// @param[out] hitNormal The normal of the nearest wall hit. [(x, y, z)]
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[out] path The reference ids of the visited polygons. [opt]
|
||||
/// @param[out] pathCount The number of visited polygons. [opt]
|
||||
/// @param[in] maxPath The maximum number of polygons the @p path array can hold.
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus raycast(dtPolyRef startRef, const float* startPos, const float* endPos,
|
||||
const dtQueryFilter* filter,
|
||||
float* t, float* hitNormal, dtPolyRef* path, int* pathCount, const int maxPath) const;
|
||||
|
||||
/// Casts a 'walkability' ray along the surface of the navigation mesh from
|
||||
/// the start position toward the end position.
|
||||
/// @param[in] startRef The reference id of the start polygon.
|
||||
/// @param[in] startPos A position within the start polygon representing
|
||||
/// the start of the ray. [(x, y, z)]
|
||||
/// @param[in] endPos The position to cast the ray toward. [(x, y, z)]
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[in] flags govern how the raycast behaves. See dtRaycastOptions
|
||||
/// @param[out] hit Pointer to a raycast hit structure which will be filled by the results.
|
||||
/// @param[in] prevRef parent of start ref. Used during for cost calculation [opt]
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus raycast(dtPolyRef startRef, const float* startPos, const float* endPos,
|
||||
const dtQueryFilter* filter, const unsigned int options,
|
||||
dtRaycastHit* hit, dtPolyRef prevRef = 0) const;
|
||||
|
||||
|
||||
/// Finds the distance from the specified position to the nearest polygon wall.
|
||||
/// @param[in] startRef The reference id of the polygon containing @p centerPos.
|
||||
/// @param[in] centerPos The center of the search circle. [(x, y, z)]
|
||||
/// @param[in] maxRadius The radius of the search circle.
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[out] hitDist The distance to the nearest wall from @p centerPos.
|
||||
/// @param[out] hitPos The nearest position on the wall that was hit. [(x, y, z)]
|
||||
/// @param[out] hitNormal The normalized ray formed from the wall point to the
|
||||
/// source point. [(x, y, z)]
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus findDistanceToWall(dtPolyRef startRef, const float* centerPos, const float maxRadius,
|
||||
const dtQueryFilter* filter,
|
||||
float* hitDist, float* hitPos, float* hitNormal) const;
|
||||
|
||||
/// Returns the segments for the specified polygon, optionally including portals.
|
||||
/// @param[in] ref The reference id of the polygon.
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[out] segmentVerts The segments. [(ax, ay, az, bx, by, bz) * segmentCount]
|
||||
/// @param[out] segmentRefs The reference ids of each segment's neighbor polygon.
|
||||
/// Or zero if the segment is a wall. [opt] [(parentRef) * @p segmentCount]
|
||||
/// @param[out] segmentCount The number of segments returned.
|
||||
/// @param[in] maxSegments The maximum number of segments the result arrays can hold.
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter,
|
||||
float* segmentVerts, dtPolyRef* segmentRefs, int* segmentCount,
|
||||
const int maxSegments) const;
|
||||
|
||||
/// Returns random location on navmesh.
|
||||
/// Polygons are chosen weighted by area. The search runs in linear related to number of polygon.
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[in] frand Function returning a random number [0..1).
|
||||
/// @param[out] randomRef The reference id of the random location.
|
||||
/// @param[out] randomPt The random location.
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus findRandomPoint(const dtQueryFilter* filter, float (*frand)(),
|
||||
dtPolyRef* randomRef, float* randomPt) const;
|
||||
|
||||
/// Returns random location on navmesh within the reach of specified location.
|
||||
/// Polygons are chosen weighted by area. The search runs in linear related to number of polygon.
|
||||
/// The location is not exactly constrained by the circle, but it limits the visited polygons.
|
||||
/// @param[in] startRef The reference id of the polygon where the search starts.
|
||||
/// @param[in] centerPos The center of the search circle. [(x, y, z)]
|
||||
/// @param[in] filter The polygon filter to apply to the query.
|
||||
/// @param[in] frand Function returning a random number [0..1).
|
||||
/// @param[out] randomRef The reference id of the random location.
|
||||
/// @param[out] randomPt The random location. [(x, y, z)]
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus findRandomPointAroundCircle(dtPolyRef startRef, const float* centerPos, const float maxRadius,
|
||||
const dtQueryFilter* filter, float (*frand)(),
|
||||
dtPolyRef* randomRef, float* randomPt) const;
|
||||
|
||||
/// Finds the closest point on the specified polygon.
|
||||
/// @param[in] ref The reference id of the polygon.
|
||||
/// @param[in] pos The position to check. [(x, y, z)]
|
||||
/// @param[out] closest The closest point on the polygon. [(x, y, z)]
|
||||
/// @param[out] posOverPoly True of the position is over the polygon.
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest, bool* posOverPoly) const;
|
||||
|
||||
/// Returns a point on the boundary closest to the source point if the source point is outside the
|
||||
/// polygon's xz-bounds.
|
||||
/// @param[in] ref The reference id to the polygon.
|
||||
/// @param[in] pos The position to check. [(x, y, z)]
|
||||
/// @param[out] closest The closest point. [(x, y, z)]
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, float* closest) const;
|
||||
|
||||
/// Gets the height of the polygon at the provided position using the height detail. (Most accurate.)
|
||||
/// @param[in] ref The reference id of the polygon.
|
||||
/// @param[in] pos A position within the xz-bounds of the polygon. [(x, y, z)]
|
||||
/// @param[out] height The height at the surface of the polygon.
|
||||
/// @returns The status flags for the query.
|
||||
dtStatus getPolyHeight(dtPolyRef ref, const float* pos, float* height) const;
|
||||
|
||||
/// @}
|
||||
/// @name Miscellaneous Functions
|
||||
/// @{
|
||||
|
||||
/// Returns true if the polygon reference is valid and passes the filter restrictions.
|
||||
/// @param[in] ref The polygon reference to check.
|
||||
/// @param[in] filter The filter to apply.
|
||||
bool isValidPolyRef(dtPolyRef ref, const dtQueryFilter* filter) const;
|
||||
|
||||
/// Returns true if the polygon reference is in the closed list.
|
||||
/// @param[in] ref The reference id of the polygon to check.
|
||||
/// @returns True if the polygon is in closed list.
|
||||
bool isInClosedList(dtPolyRef ref) const;
|
||||
|
||||
/// Gets the node pool.
|
||||
/// @returns The node pool.
|
||||
class dtNodePool* getNodePool() const { return m_nodePool; }
|
||||
|
||||
/// Gets the navigation mesh the query object is using.
|
||||
/// @return The navigation mesh the query object is using.
|
||||
const dtNavMesh* getAttachedNavMesh() const { return m_nav; }
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator
|
||||
dtNavMeshQuery(const dtNavMeshQuery&);
|
||||
dtNavMeshQuery& operator=(const dtNavMeshQuery&);
|
||||
|
||||
/// Queries polygons within a tile.
|
||||
void queryPolygonsInTile(const dtMeshTile* tile, const float* qmin, const float* qmax,
|
||||
const dtQueryFilter* filter, dtPolyQuery* query) const;
|
||||
|
||||
/// Returns portal points between two polygons.
|
||||
dtStatus getPortalPoints(dtPolyRef from, dtPolyRef to, float* left, float* right,
|
||||
unsigned char& fromType, unsigned char& toType) const;
|
||||
dtStatus getPortalPoints(dtPolyRef from, const dtPoly* fromPoly, const dtMeshTile* fromTile,
|
||||
dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile,
|
||||
float* left, float* right) const;
|
||||
|
||||
/// Returns edge mid point between two polygons.
|
||||
dtStatus getEdgeMidPoint(dtPolyRef from, dtPolyRef to, float* mid) const;
|
||||
dtStatus getEdgeMidPoint(dtPolyRef from, const dtPoly* fromPoly, const dtMeshTile* fromTile,
|
||||
dtPolyRef to, const dtPoly* toPoly, const dtMeshTile* toTile,
|
||||
float* mid) const;
|
||||
|
||||
// Appends vertex to a straight path
|
||||
dtStatus appendVertex(const float* pos, const unsigned char flags, const dtPolyRef ref,
|
||||
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
||||
int* straightPathCount, const int maxStraightPath) const;
|
||||
|
||||
// Appends intermediate portal points to a straight path.
|
||||
dtStatus appendPortals(const int startIdx, const int endIdx, const float* endPos, const dtPolyRef* path,
|
||||
float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs,
|
||||
int* straightPathCount, const int maxStraightPath, const int options) const;
|
||||
|
||||
// Gets the path leading to the specified end node.
|
||||
dtStatus getPathToNode(struct dtNode* endNode, dtPolyRef* path, int* pathCount, int maxPath) const;
|
||||
|
||||
const dtNavMesh* m_nav; ///< Pointer to navmesh data.
|
||||
|
||||
struct dtQueryData
|
||||
{
|
||||
dtStatus status;
|
||||
struct dtNode* lastBestNode;
|
||||
float lastBestNodeCost;
|
||||
dtPolyRef startRef, endRef;
|
||||
float startPos[3], endPos[3];
|
||||
const dtQueryFilter* filter;
|
||||
unsigned int options;
|
||||
float raycastLimitSqr;
|
||||
};
|
||||
dtQueryData m_query; ///< Sliced query state.
|
||||
|
||||
class dtNodePool* m_tinyNodePool; ///< Pointer to small node pool.
|
||||
class dtNodePool* m_nodePool; ///< Pointer to node pool.
|
||||
class dtNodeQueue* m_openList; ///< Pointer to open list queue.
|
||||
};
|
||||
|
||||
/// Allocates a query object using the Detour allocator.
|
||||
/// @return An allocated query object, or null on failure.
|
||||
/// @ingroup detour
|
||||
dtNavMeshQuery* dtAllocNavMeshQuery();
|
||||
|
||||
/// Frees the specified query object using the Detour allocator.
|
||||
/// @param[in] query A query object allocated using #dtAllocNavMeshQuery
|
||||
/// @ingroup detour
|
||||
void dtFreeNavMeshQuery(dtNavMeshQuery* query);
|
||||
|
||||
#endif // DETOURNAVMESHQUERY_H
|
|
@ -0,0 +1,168 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURNODE_H
|
||||
#define DETOURNODE_H
|
||||
|
||||
#include "DetourNavMesh.h"
|
||||
|
||||
enum dtNodeFlags
|
||||
{
|
||||
DT_NODE_OPEN = 0x01,
|
||||
DT_NODE_CLOSED = 0x02,
|
||||
DT_NODE_PARENT_DETACHED = 0x04, // parent of the node is not adjacent. Found using raycast.
|
||||
};
|
||||
|
||||
typedef unsigned short dtNodeIndex;
|
||||
static const dtNodeIndex DT_NULL_IDX = (dtNodeIndex)~0;
|
||||
|
||||
static const int DT_NODE_PARENT_BITS = 24;
|
||||
static const int DT_NODE_STATE_BITS = 2;
|
||||
struct dtNode
|
||||
{
|
||||
float pos[3]; ///< Position of the node.
|
||||
float cost; ///< Cost from previous node to current node.
|
||||
float total; ///< Cost up to the node.
|
||||
unsigned int pidx : DT_NODE_PARENT_BITS; ///< Index to parent node.
|
||||
unsigned int state : DT_NODE_STATE_BITS; ///< extra state information. A polyRef can have multiple nodes with different extra info. see DT_MAX_STATES_PER_NODE
|
||||
unsigned int flags : 3; ///< Node flags. A combination of dtNodeFlags.
|
||||
dtPolyRef id; ///< Polygon ref the node corresponds to.
|
||||
};
|
||||
|
||||
static const int DT_MAX_STATES_PER_NODE = 1 << DT_NODE_STATE_BITS; // number of extra states per node. See dtNode::state
|
||||
|
||||
class dtNodePool
|
||||
{
|
||||
public:
|
||||
dtNodePool(int maxNodes, int hashSize);
|
||||
~dtNodePool();
|
||||
void clear();
|
||||
|
||||
// Get a dtNode by ref and extra state information. If there is none then - allocate
|
||||
// There can be more than one node for the same polyRef but with different extra state information
|
||||
dtNode* getNode(dtPolyRef id, unsigned char state=0);
|
||||
dtNode* findNode(dtPolyRef id, unsigned char state);
|
||||
unsigned int findNodes(dtPolyRef id, dtNode** nodes, const int maxNodes);
|
||||
|
||||
inline unsigned int getNodeIdx(const dtNode* node) const
|
||||
{
|
||||
if (!node) return 0;
|
||||
return (unsigned int)(node - m_nodes) + 1;
|
||||
}
|
||||
|
||||
inline dtNode* getNodeAtIdx(unsigned int idx)
|
||||
{
|
||||
if (!idx) return 0;
|
||||
return &m_nodes[idx - 1];
|
||||
}
|
||||
|
||||
inline const dtNode* getNodeAtIdx(unsigned int idx) const
|
||||
{
|
||||
if (!idx) return 0;
|
||||
return &m_nodes[idx - 1];
|
||||
}
|
||||
|
||||
inline int getMemUsed() const
|
||||
{
|
||||
return sizeof(*this) +
|
||||
sizeof(dtNode)*m_maxNodes +
|
||||
sizeof(dtNodeIndex)*m_maxNodes +
|
||||
sizeof(dtNodeIndex)*m_hashSize;
|
||||
}
|
||||
|
||||
inline int getMaxNodes() const { return m_maxNodes; }
|
||||
|
||||
inline int getHashSize() const { return m_hashSize; }
|
||||
inline dtNodeIndex getFirst(int bucket) const { return m_first[bucket]; }
|
||||
inline dtNodeIndex getNext(int i) const { return m_next[i]; }
|
||||
inline int getNodeCount() const { return m_nodeCount; }
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator.
|
||||
dtNodePool(const dtNodePool&);
|
||||
dtNodePool& operator=(const dtNodePool&);
|
||||
|
||||
dtNode* m_nodes;
|
||||
dtNodeIndex* m_first;
|
||||
dtNodeIndex* m_next;
|
||||
const int m_maxNodes;
|
||||
const int m_hashSize;
|
||||
int m_nodeCount;
|
||||
};
|
||||
|
||||
class dtNodeQueue
|
||||
{
|
||||
public:
|
||||
dtNodeQueue(int n);
|
||||
~dtNodeQueue();
|
||||
|
||||
inline void clear() { m_size = 0; }
|
||||
|
||||
inline dtNode* top() { return m_heap[0]; }
|
||||
|
||||
inline dtNode* pop()
|
||||
{
|
||||
dtNode* result = m_heap[0];
|
||||
m_size--;
|
||||
trickleDown(0, m_heap[m_size]);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void push(dtNode* node)
|
||||
{
|
||||
m_size++;
|
||||
bubbleUp(m_size-1, node);
|
||||
}
|
||||
|
||||
inline void modify(dtNode* node)
|
||||
{
|
||||
for (int i = 0; i < m_size; ++i)
|
||||
{
|
||||
if (m_heap[i] == node)
|
||||
{
|
||||
bubbleUp(i, node);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline bool empty() const { return m_size == 0; }
|
||||
|
||||
inline int getMemUsed() const
|
||||
{
|
||||
return sizeof(*this) +
|
||||
sizeof(dtNode*) * (m_capacity + 1);
|
||||
}
|
||||
|
||||
inline int getCapacity() const { return m_capacity; }
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator.
|
||||
dtNodeQueue(const dtNodeQueue&);
|
||||
dtNodeQueue& operator=(const dtNodeQueue&);
|
||||
|
||||
void bubbleUp(int i, dtNode* node);
|
||||
void trickleDown(int i, dtNode* node);
|
||||
|
||||
dtNode** m_heap;
|
||||
const int m_capacity;
|
||||
int m_size;
|
||||
};
|
||||
|
||||
|
||||
#endif // DETOURNODE_H
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURSTATUS_H
|
||||
#define DETOURSTATUS_H
|
||||
|
||||
typedef unsigned int dtStatus;
|
||||
|
||||
// High level status.
|
||||
static const unsigned int DT_FAILURE = 1u << 31; // Operation failed.
|
||||
static const unsigned int DT_SUCCESS = 1u << 30; // Operation succeed.
|
||||
static const unsigned int DT_IN_PROGRESS = 1u << 29; // Operation still in progress.
|
||||
|
||||
// Detail information for status.
|
||||
static const unsigned int DT_STATUS_DETAIL_MASK = 0x0ffffff;
|
||||
static const unsigned int DT_WRONG_MAGIC = 1 << 0; // Input data is not recognized.
|
||||
static const unsigned int DT_WRONG_VERSION = 1 << 1; // Input data is in wrong version.
|
||||
static const unsigned int DT_OUT_OF_MEMORY = 1 << 2; // Operation ran out of memory.
|
||||
static const unsigned int DT_INVALID_PARAM = 1 << 3; // An input parameter was invalid.
|
||||
static const unsigned int DT_BUFFER_TOO_SMALL = 1 << 4; // Result buffer for the query was too small to store all results.
|
||||
static const unsigned int DT_OUT_OF_NODES = 1 << 5; // Query ran out of nodes during search.
|
||||
static const unsigned int DT_PARTIAL_RESULT = 1 << 6; // Query did not reach the end location, returning best guess.
|
||||
static const unsigned int DT_ALREADY_OCCUPIED = 1 << 7; // A tile has already been assigned to the given x,y coordinate
|
||||
|
||||
|
||||
// Returns true of status is success.
|
||||
inline bool dtStatusSucceed(dtStatus status)
|
||||
{
|
||||
return (status & DT_SUCCESS) != 0;
|
||||
}
|
||||
|
||||
// Returns true of status is failure.
|
||||
inline bool dtStatusFailed(dtStatus status)
|
||||
{
|
||||
return (status & DT_FAILURE) != 0;
|
||||
}
|
||||
|
||||
// Returns true of status is in progress.
|
||||
inline bool dtStatusInProgress(dtStatus status)
|
||||
{
|
||||
return (status & DT_IN_PROGRESS) != 0;
|
||||
}
|
||||
|
||||
// Returns true if specific detail is set.
|
||||
inline bool dtStatusDetail(dtStatus status, unsigned int detail)
|
||||
{
|
||||
return (status & detail) != 0;
|
||||
}
|
||||
|
||||
#endif // DETOURSTATUS_H
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,342 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef RECASTALLOC_H
|
||||
#define RECASTALLOC_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <RecastAssert.h>
|
||||
|
||||
/// Provides hint values to the memory allocator on how long the
|
||||
/// memory is expected to be used.
|
||||
enum rcAllocHint
|
||||
{
|
||||
RC_ALLOC_PERM, ///< Memory will persist after a function call.
|
||||
RC_ALLOC_TEMP ///< Memory used temporarily within a function.
|
||||
};
|
||||
|
||||
/// A memory allocation function.
|
||||
// @param[in] size The size, in bytes of memory, to allocate.
|
||||
// @param[in] rcAllocHint A hint to the allocator on how long the memory is expected to be in use.
|
||||
// @return A pointer to the beginning of the allocated memory block, or null if the allocation failed.
|
||||
/// @see rcAllocSetCustom
|
||||
typedef void* (rcAllocFunc)(size_t size, rcAllocHint hint);
|
||||
|
||||
/// A memory deallocation function.
|
||||
/// @param[in] ptr A pointer to a memory block previously allocated using #rcAllocFunc.
|
||||
/// @see rcAllocSetCustom
|
||||
typedef void (rcFreeFunc)(void* ptr);
|
||||
|
||||
/// Sets the base custom allocation functions to be used by Recast.
|
||||
/// @param[in] allocFunc The memory allocation function to be used by #rcAlloc
|
||||
/// @param[in] freeFunc The memory de-allocation function to be used by #rcFree
|
||||
void rcAllocSetCustom(rcAllocFunc *allocFunc, rcFreeFunc *freeFunc);
|
||||
|
||||
/// Allocates a memory block.
|
||||
/// @param[in] size The size, in bytes of memory, to allocate.
|
||||
/// @param[in] hint A hint to the allocator on how long the memory is expected to be in use.
|
||||
/// @return A pointer to the beginning of the allocated memory block, or null if the allocation failed.
|
||||
/// @see rcFree
|
||||
void* rcAlloc(size_t size, rcAllocHint hint);
|
||||
|
||||
/// Deallocates a memory block.
|
||||
/// @param[in] ptr A pointer to a memory block previously allocated using #rcAlloc.
|
||||
/// @see rcAlloc
|
||||
void rcFree(void* ptr);
|
||||
|
||||
/// An implementation of operator new usable for placement new. The default one is part of STL (which we don't use).
|
||||
/// rcNewTag is a dummy type used to differentiate our operator from the STL one, in case users import both Recast
|
||||
/// and STL.
|
||||
struct rcNewTag {};
|
||||
inline void* operator new(size_t, const rcNewTag&, void* p) { return p; }
|
||||
inline void operator delete(void*, const rcNewTag&, void*) {}
|
||||
|
||||
/// Signed to avoid warnnings when comparing to int loop indexes, and common error with comparing to zero.
|
||||
/// MSVC2010 has a bug where ssize_t is unsigned (!!!).
|
||||
typedef intptr_t rcSizeType;
|
||||
#define RC_SIZE_MAX INTPTR_MAX
|
||||
|
||||
/// Macros to hint to the compiler about the likeliest branch. Please add a benchmark that demonstrates a performance
|
||||
/// improvement before introducing use cases.
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define rcLikely(x) __builtin_expect((x), true)
|
||||
#define rcUnlikely(x) __builtin_expect((x), false)
|
||||
#else
|
||||
#define rcLikely(x) (x)
|
||||
#define rcUnlikely(x) (x)
|
||||
#endif
|
||||
|
||||
/// Variable-sized storage type. Mimics the interface of std::vector<T> with some notable differences:
|
||||
/// * Uses rcAlloc()/rcFree() to handle storage.
|
||||
/// * No support for a custom allocator.
|
||||
/// * Uses signed size instead of size_t to avoid warnings in for loops: "for (int i = 0; i < foo.size(); i++)"
|
||||
/// * Omits methods of limited utility: insert/erase, (bad performance), at (we don't use exceptions), operator=.
|
||||
/// * assign() and the pre-sizing constructor follow C++11 semantics -- they don't construct a temporary if no value is provided.
|
||||
/// * push_back() and resize() support adding values from the current vector. Range-based constructors and assign(begin, end) do not.
|
||||
/// * No specialization for bool.
|
||||
template <typename T, rcAllocHint H>
|
||||
class rcVectorBase {
|
||||
rcSizeType m_size;
|
||||
rcSizeType m_cap;
|
||||
T* m_data;
|
||||
// Constructs a T at the give address with either the copy constructor or the default.
|
||||
static void construct(T* p, const T& v) { ::new(rcNewTag(), (void*)p) T(v); }
|
||||
static void construct(T* p) { ::new(rcNewTag(), (void*)p) T; }
|
||||
static void construct_range(T* begin, T* end);
|
||||
static void construct_range(T* begin, T* end, const T& value);
|
||||
static void copy_range(T* dst, const T* begin, const T* end);
|
||||
void destroy_range(rcSizeType begin, rcSizeType end);
|
||||
// Creates an array of the given size, copies all of this vector's data into it, and returns it.
|
||||
T* allocate_and_copy(rcSizeType size);
|
||||
void resize_impl(rcSizeType size, const T* value);
|
||||
public:
|
||||
typedef rcSizeType size_type;
|
||||
typedef T value_type;
|
||||
|
||||
rcVectorBase() : m_size(0), m_cap(0), m_data(0) {};
|
||||
rcVectorBase(const rcVectorBase<T, H>& other) : m_size(0), m_cap(0), m_data(0) { assign(other.begin(), other.end()); }
|
||||
explicit rcVectorBase(rcSizeType count) : m_size(0), m_cap(0), m_data(0) { resize(count); }
|
||||
rcVectorBase(rcSizeType count, const T& value) : m_size(0), m_cap(0), m_data(0) { resize(count, value); }
|
||||
rcVectorBase(const T* begin, const T* end) : m_size(0), m_cap(0), m_data(0) { assign(begin, end); }
|
||||
~rcVectorBase() { destroy_range(0, m_size); rcFree(m_data); }
|
||||
|
||||
// Unlike in std::vector, we return a bool to indicate whether the alloc was successful.
|
||||
bool reserve(rcSizeType size);
|
||||
|
||||
void assign(rcSizeType count, const T& value) { clear(); resize(count, value); }
|
||||
void assign(const T* begin, const T* end);
|
||||
|
||||
void resize(rcSizeType size) { resize_impl(size, NULL); }
|
||||
void resize(rcSizeType size, const T& value) { resize_impl(size, &value); }
|
||||
// Not implemented as resize(0) because resize requires T to be default-constructible.
|
||||
void clear() { destroy_range(0, m_size); m_size = 0; }
|
||||
|
||||
void push_back(const T& value);
|
||||
void pop_back() { rcAssert(m_size > 0); back().~T(); m_size--; }
|
||||
|
||||
rcSizeType size() const { return m_size; }
|
||||
rcSizeType capacity() const { return m_cap; }
|
||||
bool empty() const { return size() == 0; }
|
||||
|
||||
const T& operator[](rcSizeType i) const { rcAssert(i >= 0 && i < m_size); return m_data[i]; }
|
||||
T& operator[](rcSizeType i) { rcAssert(i >= 0 && i < m_size); return m_data[i]; }
|
||||
|
||||
const T& front() const { rcAssert(m_size); return m_data[0]; }
|
||||
T& front() { rcAssert(m_size); return m_data[0]; }
|
||||
const T& back() const { rcAssert(m_size); return m_data[m_size - 1]; };
|
||||
T& back() { rcAssert(m_size); return m_data[m_size - 1]; };
|
||||
const T* data() const { return m_data; }
|
||||
T* data() { return m_data; }
|
||||
|
||||
T* begin() { return m_data; }
|
||||
T* end() { return m_data + m_size; }
|
||||
const T* begin() const { return m_data; }
|
||||
const T* end() const { return m_data + m_size; }
|
||||
|
||||
void swap(rcVectorBase<T, H>& other);
|
||||
|
||||
// Explicitly deleted.
|
||||
rcVectorBase& operator=(const rcVectorBase<T, H>& other);
|
||||
};
|
||||
|
||||
template<typename T, rcAllocHint H>
|
||||
bool rcVectorBase<T, H>::reserve(rcSizeType count) {
|
||||
if (count <= m_cap) {
|
||||
return true;
|
||||
}
|
||||
T* new_data = allocate_and_copy(count);
|
||||
if (!new_data) {
|
||||
return false;
|
||||
}
|
||||
destroy_range(0, m_size);
|
||||
rcFree(m_data);
|
||||
m_data = new_data;
|
||||
m_cap = count;
|
||||
return true;
|
||||
}
|
||||
template <typename T, rcAllocHint H>
|
||||
T* rcVectorBase<T, H>::allocate_and_copy(rcSizeType size) {
|
||||
rcAssert(RC_SIZE_MAX / static_cast<rcSizeType>(sizeof(T)) >= size);
|
||||
T* new_data = static_cast<T*>(rcAlloc(sizeof(T) * size, H));
|
||||
if (new_data) {
|
||||
copy_range(new_data, m_data, m_data + m_size);
|
||||
}
|
||||
return new_data;
|
||||
}
|
||||
template <typename T, rcAllocHint H>
|
||||
void rcVectorBase<T, H>::assign(const T* begin, const T* end) {
|
||||
clear();
|
||||
reserve(end - begin);
|
||||
m_size = end - begin;
|
||||
copy_range(m_data, begin, end);
|
||||
}
|
||||
template <typename T, rcAllocHint H>
|
||||
void rcVectorBase<T, H>::push_back(const T& value) {
|
||||
// rcLikely increases performance by ~50% on BM_rcVector_PushPreallocated,
|
||||
// and by ~2-5% on BM_rcVector_Push.
|
||||
if (rcLikely(m_size < m_cap)) {
|
||||
construct(m_data + m_size++, value);
|
||||
return;
|
||||
}
|
||||
|
||||
rcAssert(RC_SIZE_MAX / 2 >= m_size);
|
||||
rcSizeType new_cap = m_size ? 2*m_size : 1;
|
||||
T* data = allocate_and_copy(new_cap);
|
||||
// construct between allocate and destroy+free in case value is
|
||||
// in this vector.
|
||||
construct(data + m_size, value);
|
||||
destroy_range(0, m_size);
|
||||
m_size++;
|
||||
m_cap = new_cap;
|
||||
rcFree(m_data);
|
||||
m_data = data;
|
||||
}
|
||||
template <typename T, rcAllocHint H>
|
||||
void rcVectorBase<T, H>::resize_impl(rcSizeType size, const T* value) {
|
||||
if (size < m_size) {
|
||||
destroy_range(size, m_size);
|
||||
m_size = size;
|
||||
} else if (size > m_size) {
|
||||
T* new_data = allocate_and_copy(size);
|
||||
// We defer deconstructing/freeing old data until after constructing
|
||||
// new elements in case "value" is there.
|
||||
if (value) {
|
||||
construct_range(new_data + m_size, new_data + size, *value);
|
||||
} else {
|
||||
construct_range(new_data + m_size, new_data + size);
|
||||
}
|
||||
destroy_range(0, m_size);
|
||||
rcFree(m_data);
|
||||
m_data = new_data;
|
||||
m_cap = size;
|
||||
m_size = size;
|
||||
}
|
||||
}
|
||||
template <typename T, rcAllocHint H>
|
||||
void rcVectorBase<T, H>::swap(rcVectorBase<T, H>& other) {
|
||||
// TODO: Reorganize headers so we can use rcSwap here.
|
||||
rcSizeType tmp_cap = other.m_cap;
|
||||
rcSizeType tmp_size = other.m_size;
|
||||
T* tmp_data = other.m_data;
|
||||
|
||||
other.m_cap = m_cap;
|
||||
other.m_size = m_size;
|
||||
other.m_data = m_data;
|
||||
|
||||
m_cap = tmp_cap;
|
||||
m_size = tmp_size;
|
||||
m_data = tmp_data;
|
||||
}
|
||||
// static
|
||||
template <typename T, rcAllocHint H>
|
||||
void rcVectorBase<T, H>::construct_range(T* begin, T* end) {
|
||||
for (T* p = begin; p < end; p++) {
|
||||
construct(p);
|
||||
}
|
||||
}
|
||||
// static
|
||||
template <typename T, rcAllocHint H>
|
||||
void rcVectorBase<T, H>::construct_range(T* begin, T* end, const T& value) {
|
||||
for (T* p = begin; p < end; p++) {
|
||||
construct(p, value);
|
||||
}
|
||||
}
|
||||
// static
|
||||
template <typename T, rcAllocHint H>
|
||||
void rcVectorBase<T, H>::copy_range(T* dst, const T* begin, const T* end) {
|
||||
for (rcSizeType i = 0 ; i < end - begin; i++) {
|
||||
construct(dst + i, begin[i]);
|
||||
}
|
||||
}
|
||||
template <typename T, rcAllocHint H>
|
||||
void rcVectorBase<T, H>::destroy_range(rcSizeType begin, rcSizeType end) {
|
||||
for (rcSizeType i = begin; i < end; i++) {
|
||||
m_data[i].~T();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class rcTempVector : public rcVectorBase<T, RC_ALLOC_TEMP> {
|
||||
typedef rcVectorBase<T, RC_ALLOC_TEMP> Base;
|
||||
public:
|
||||
rcTempVector() : Base() {}
|
||||
explicit rcTempVector(rcSizeType size) : Base(size) {}
|
||||
rcTempVector(rcSizeType size, const T& value) : Base(size, value) {}
|
||||
rcTempVector(const rcTempVector<T>& other) : Base(other) {}
|
||||
rcTempVector(const T* begin, const T* end) : Base(begin, end) {}
|
||||
};
|
||||
template <typename T>
|
||||
class rcPermVector : public rcVectorBase<T, RC_ALLOC_PERM> {
|
||||
typedef rcVectorBase<T, RC_ALLOC_PERM> Base;
|
||||
public:
|
||||
rcPermVector() : Base() {}
|
||||
explicit rcPermVector(rcSizeType size) : Base(size) {}
|
||||
rcPermVector(rcSizeType size, const T& value) : Base(size, value) {}
|
||||
rcPermVector(const rcPermVector<T>& other) : Base(other) {}
|
||||
rcPermVector(const T* begin, const T* end) : Base(begin, end) {}
|
||||
};
|
||||
|
||||
|
||||
/// Legacy class. Prefer rcVector<int>.
|
||||
class rcIntArray
|
||||
{
|
||||
rcTempVector<int> m_impl;
|
||||
public:
|
||||
rcIntArray() {}
|
||||
rcIntArray(int n) : m_impl(n, 0) {}
|
||||
void push(int item) { m_impl.push_back(item); }
|
||||
void resize(int size) { m_impl.resize(size); }
|
||||
int pop()
|
||||
{
|
||||
int v = m_impl.back();
|
||||
m_impl.pop_back();
|
||||
return v;
|
||||
}
|
||||
int size() const { return static_cast<int>(m_impl.size()); }
|
||||
int& operator[](int index) { return m_impl[index]; }
|
||||
int operator[](int index) const { return m_impl[index]; }
|
||||
};
|
||||
|
||||
/// A simple helper class used to delete an array when it goes out of scope.
|
||||
/// @note This class is rarely if ever used by the end user.
|
||||
template<class T> class rcScopedDelete
|
||||
{
|
||||
T* ptr;
|
||||
public:
|
||||
|
||||
/// Constructs an instance with a null pointer.
|
||||
inline rcScopedDelete() : ptr(0) {}
|
||||
|
||||
/// Constructs an instance with the specified pointer.
|
||||
/// @param[in] p An pointer to an allocated array.
|
||||
inline rcScopedDelete(T* p) : ptr(p) {}
|
||||
inline ~rcScopedDelete() { rcFree(ptr); }
|
||||
|
||||
/// The root array pointer.
|
||||
/// @return The root array pointer.
|
||||
inline operator T*() { return ptr; }
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator.
|
||||
rcScopedDelete(const rcScopedDelete&);
|
||||
rcScopedDelete& operator=(const rcScopedDelete&);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef RECASTASSERT_H
|
||||
#define RECASTASSERT_H
|
||||
|
||||
// Note: This header file's only purpose is to include define assert.
|
||||
// Feel free to change the file and include your own implementation instead.
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
||||
// From http://cnicholson.net/2009/02/stupid-c-tricks-adventures-in-assert/
|
||||
# define rcAssert(x) do { (void)sizeof(x); } while((void)(__LINE__==-1),false)
|
||||
|
||||
#else
|
||||
|
||||
/// An assertion failure function.
|
||||
// @param[in] expression asserted expression.
|
||||
// @param[in] file Filename of the failed assertion.
|
||||
// @param[in] line Line number of the failed assertion.
|
||||
/// @see rcAssertFailSetCustom
|
||||
typedef void (rcAssertFailFunc)(const char* expression, const char* file, int line);
|
||||
|
||||
/// Sets the base custom assertion failure function to be used by Recast.
|
||||
/// @param[in] assertFailFunc The function to be used in case of failure of #dtAssert
|
||||
void rcAssertFailSetCustom(rcAssertFailFunc *assertFailFunc);
|
||||
|
||||
/// Gets the base custom assertion failure function to be used by Recast.
|
||||
rcAssertFailFunc* rcAssertFailGetCustom();
|
||||
|
||||
# include <assert.h>
|
||||
# define rcAssert(expression) \
|
||||
{ \
|
||||
rcAssertFailFunc* failFunc = rcAssertFailGetCustom(); \
|
||||
if(failFunc == NULL) { assert(expression); } \
|
||||
else if(!(expression)) { (*failFunc)(#expression, __FILE__, __LINE__); } \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // RECASTASSERT_H
|
|
@ -37,6 +37,8 @@ def get_libcarla_extensions():
|
|||
os.path.join(pwd, 'dependencies/lib/libcarla_client.a'),
|
||||
os.path.join(pwd, 'dependencies/lib/librpc.a'),
|
||||
os.path.join(pwd, 'dependencies/lib/libboost_filesystem.a'),
|
||||
os.path.join(pwd, 'dependencies/lib/libRecast.a'),
|
||||
os.path.join(pwd, 'dependencies/lib/libDetour.a'),
|
||||
os.path.join(pwd, 'dependencies/lib', pylib)]
|
||||
extra_compile_args = [
|
||||
'-isystem', 'dependencies/include/system', '-fPIC', '-std=c++14',
|
||||
|
|
|
@ -71,5 +71,6 @@ void export_client() {
|
|||
.def("set_replayer_time_factor", &cc::Client::SetReplayerTimeFactor, (arg("time_factor")))
|
||||
.def("apply_batch", &ApplyBatchCommands, (arg("commands"), arg("do_tick")=false))
|
||||
.def("apply_batch_sync", &ApplyBatchCommandsSync, (arg("commands"), arg("do_tick")=false))
|
||||
.def("create_walker", CALL_RETURNING_LIST_2(cc::Client, CreateWalker, carla::geom::Location, carla::geom::Location), (arg("location"), arg("location")))
|
||||
;
|
||||
}
|
||||
|
|
|
@ -78,6 +78,14 @@
|
|||
return result; \
|
||||
}
|
||||
|
||||
#define CALL_RETURNING_LIST_2(cls, fn, T1_, T2_) +[](const cls &self, T1_ t1, T2_ t2) { \
|
||||
boost::python::list result; \
|
||||
for (auto &&item : self.fn(std::forward<T1_>(t1), std::forward<T2_>(t2))) { \
|
||||
result.append(item); \
|
||||
} \
|
||||
return result; \
|
||||
}
|
||||
|
||||
#define CALL_RETURNING_OPTIONAL(cls, fn) +[](const cls &self) { \
|
||||
auto optional = self.fn(); \
|
||||
return optional.has_value() ? boost::python::object(*optional) : boost::python::object(); \
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma de
|
||||
# Barcelona (UAB).
|
||||
#
|
||||
# This work is licensed under the terms of the MIT license.
|
||||
# For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
sys.path.append(glob.glob('../carla/dist/carla-*%d.%d-%s.egg' % (
|
||||
sys.version_info.major,
|
||||
sys.version_info.minor,
|
||||
'win-amd64' if os.name == 'nt' else 'linux-x86_64'))[0])
|
||||
except IndexError:
|
||||
pass
|
||||
|
||||
import carla
|
||||
|
||||
import argparse
|
||||
import math
|
||||
import random
|
||||
import time
|
||||
|
||||
red = carla.Color(255, 0, 0)
|
||||
green = carla.Color(0, 255, 0)
|
||||
blue = carla.Color(47, 210, 231)
|
||||
cyan = carla.Color(0, 255, 255)
|
||||
yellow = carla.Color(255, 255, 0)
|
||||
orange = carla.Color(255, 162, 0)
|
||||
white = carla.Color(255, 255, 255)
|
||||
|
||||
def main():
|
||||
argparser = argparse.ArgumentParser()
|
||||
argparser.add_argument(
|
||||
'--host',
|
||||
metavar='H',
|
||||
default='127.0.0.1',
|
||||
help='IP of the host server (default: 127.0.0.1)')
|
||||
argparser.add_argument(
|
||||
'-p', '--port',
|
||||
metavar='P',
|
||||
default=2000,
|
||||
type=int,
|
||||
help='TCP port to listen to (default: 2000)')
|
||||
args = argparser.parse_args()
|
||||
|
||||
try:
|
||||
client = carla.Client(args.host, args.port)
|
||||
client.set_timeout(2.0)
|
||||
|
||||
world = client.get_world()
|
||||
m = world.get_map()
|
||||
debug = world.debug
|
||||
a = carla.Location(-141.789, -153.839, 0.139954)
|
||||
b = carla.Location(-29.7504, -26.8764, 0.270432)
|
||||
points = []
|
||||
points = client.create_walker(a, b)
|
||||
# points = [
|
||||
# (-141.789, -153.839, 0.139954),
|
||||
# (-119.9, -134.6, 0.178125),
|
||||
# (-112.1, -109.7, 0.178125),
|
||||
# (-71.6, -67.4, 0.178125),
|
||||
# (-40.1, -55.4, 0.178125),
|
||||
# (-39.8, -54.8, 0.178125),
|
||||
# (-29.7504, -26.8764, 0.270432)
|
||||
# ]
|
||||
for i in range(len(points)-1):
|
||||
a1 = carla.Location(points[i][0], points[i][1], points[i][2])
|
||||
b1 = carla.Location(points[i+1][0], points[i+1][1], points[i+1][2])
|
||||
# print(a.x, a.y, a.z)
|
||||
debug.draw_line(a1, b1, color=orange, thickness=0.5, life_time=12)
|
||||
# debug.draw_line(a, a+carla.Location(z=1000), color=orange, thickness=0.2, life_time=12)
|
||||
debug.draw_point(a1, 1, red, 12)
|
||||
|
||||
time.sleep(5)
|
||||
|
||||
finally:
|
||||
# print("Total: ", total)
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
finally:
|
||||
pass
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include "Carla/OpenDrive/OpenDrive.h"
|
||||
#include "Carla/Util/DebugShapeDrawer.h"
|
||||
#include "Carla/Util/OpenDrive.h"
|
||||
#include "Carla/Util/NavigationMesh.h"
|
||||
#include "Carla/Vehicle/CarlaWheeledVehicle.h"
|
||||
#include "Carla/Walker/WalkerController.h"
|
||||
|
||||
|
@ -208,6 +210,17 @@ void FCarlaServer::FPimpl::BindActions()
|
|||
MakeVectorFromTArray<cg::Transform>(SpawnPoints)};
|
||||
};
|
||||
|
||||
BIND_SYNC(get_navigation_mesh) << [this]() -> R<std::vector<uint8_t>>
|
||||
{
|
||||
REQUIRE_CARLA_EPISODE();
|
||||
auto FileContents = FNavigationMesh::Load(Episode->GetMapName());
|
||||
// make a mem copy (from TArray to std::vector)
|
||||
std::vector<uint8_t> Result(FileContents.Num());
|
||||
memcpy(&Result[0], FileContents.GetData(), FileContents.Num());
|
||||
return Result;
|
||||
};
|
||||
|
||||
|
||||
BIND_SYNC(get_episode_settings) << [this]() -> R<cr::EpisodeSettings>
|
||||
{
|
||||
REQUIRE_CARLA_EPISODE();
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#include "Carla.h"
|
||||
#include "Carla/Util/NavigationMesh.h"
|
||||
|
||||
TArray<uint8> FNavigationMesh::Load(FString MapName)
|
||||
{
|
||||
#if WITH_EDITOR
|
||||
{
|
||||
// When playing in editor the map name gets an extra prefix, here we
|
||||
// remove it.
|
||||
FString CorrectedMapName = MapName;
|
||||
constexpr auto PIEPrefix = TEXT("UEDPIE_0_");
|
||||
CorrectedMapName.RemoveFromStart(PIEPrefix);
|
||||
UE_LOG(LogCarla, Log, TEXT("FNavigationMesh: Corrected map name from %s to %s"), *MapName, *CorrectedMapName);
|
||||
MapName = CorrectedMapName;
|
||||
}
|
||||
#endif // WITH_EDITOR
|
||||
|
||||
const FString FilePath =
|
||||
FPaths::ProjectContentDir() +
|
||||
TEXT("Carla/Maps/Nav/") +
|
||||
MapName +
|
||||
TEXT(".bin");
|
||||
|
||||
TArray<uint8> Content;
|
||||
UE_LOG(LogCarla, Log, TEXT("Loading Navigation Mesh file '%s'"), *FilePath);
|
||||
|
||||
if (!FFileHelper::LoadFileToArray(Content, *FilePath, 0))
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Failed to load Navigation Mesh file '%s'"), *FilePath);
|
||||
}
|
||||
|
||||
return Content;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) 2019 Computer Vision Center (CVC) at the Universitat Autonoma
|
||||
// de Barcelona (UAB).
|
||||
//
|
||||
// This work is licensed under the terms of the MIT license.
|
||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||
|
||||
#pragma once
|
||||
|
||||
class FNavigationMesh
|
||||
{
|
||||
public:
|
||||
|
||||
/// Return the Navigation Mesh Binary associated to @a MapName, or empty if the such
|
||||
/// file wasn't serialized.
|
||||
static TArray<uint8> Load(FString MapName);
|
||||
};
|
|
@ -285,6 +285,57 @@ fi
|
|||
|
||||
unset GTEST_BASENAME
|
||||
|
||||
# ==============================================================================
|
||||
# -- Get Recast&Detour and compile it with libc++ ------------------------------
|
||||
# ==============================================================================
|
||||
|
||||
RECAST_COMMIT="c40188c796f089f89a42e0b939d934178dbcfc5c"
|
||||
RECAST_BASENAME=recast-${CXX_TAG}
|
||||
|
||||
RECAST_INCLUDE=${PWD}/${RECAST_BASENAME}-install/include
|
||||
RECAST_LIBPATH=${PWD}/${RECAST_BASENAME}-install/lib
|
||||
|
||||
if [[ -d "${RECAST_BASENAME}-install" ]] ; then
|
||||
log "${RECAST_BASENAME} already installed."
|
||||
else
|
||||
rm -Rf \
|
||||
${RECAST_BASENAME}-source \
|
||||
${RECAST_BASENAME}-build \
|
||||
${RECAST_BASENAME}-install
|
||||
|
||||
log "Retrieving Recast & Detour"
|
||||
|
||||
git clone https://github.com/recastnavigation/recastnavigation.git ${RECAST_BASENAME}-source
|
||||
|
||||
pushd ${RECAST_BASENAME}-source >/dev/null
|
||||
|
||||
git reset --hard ${RECAST_COMMIT}
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
log "Building Recast & Detour with libc++."
|
||||
|
||||
mkdir -p ${RECAST_BASENAME}-build
|
||||
|
||||
pushd ${RECAST_BASENAME}-build >/dev/null
|
||||
|
||||
cmake -G "Ninja" \
|
||||
-DCMAKE_CXX_FLAGS="-std=c++14 -fPIC" \
|
||||
-DCMAKE_INSTALL_PREFIX="../${RECAST_BASENAME}-install" \
|
||||
../${RECAST_BASENAME}-source
|
||||
|
||||
ninja
|
||||
|
||||
ninja install
|
||||
|
||||
popd >/dev/null
|
||||
|
||||
rm -Rf ${RECAST_BASENAME}-source ${RECAST_BASENAME}-build
|
||||
|
||||
fi
|
||||
|
||||
unset RECAST_BASENAME
|
||||
|
||||
# ==============================================================================
|
||||
# -- Generate Version.h --------------------------------------------------------
|
||||
# ==============================================================================
|
||||
|
@ -378,6 +429,8 @@ elseif (CMAKE_BUILD_TYPE STREQUAL "Client")
|
|||
set(GTEST_INCLUDE_PATH "${GTEST_LIBSTDCXX_INCLUDE}")
|
||||
set(GTEST_LIB_PATH "${GTEST_LIBSTDCXX_LIBPATH}")
|
||||
set(BOOST_LIB_PATH "${BOOST_LIBPATH}")
|
||||
set(RECAST_INCLUDE_PATH "${RECAST_INCLUDE}")
|
||||
set(RECAST_LIB_PATH "${RECAST_LIBPATH}")
|
||||
endif ()
|
||||
|
||||
EOL
|
||||
|
|
Loading…
Reference in New Issue