From dfa993e0d4b1871ad5157a280b1b165b379f2cae Mon Sep 17 00:00:00 2001 From: Anonymous Date: Tue, 14 Jan 2014 12:04:45 -0700 Subject: [PATCH] Added sharedPathfinding library --- engine/shared/library/CMakeLists.txt | 1 + .../library/sharedGame/src/CMakeLists.txt | 1 + .../sharedNetworkMessages/src/CMakeLists.txt | 2 + .../clientGameServer/SceneChannelMessages.cpp | 2 + .../library/sharedObject/src/CMakeLists.txt | 2 + .../src/shared/portal/PortalProperty.cpp | 1 + .../library/sharedPathfinding/CMakeLists.txt | 11 + .../ConfigSharedPathfinding.h | 1 + .../sharedPathfinding/DynamicPathGraph.h | 1 + .../sharedPathfinding/DynamicPathNode.h | 1 + .../FirstSharedPathfinding.h | 1 + .../public/sharedPathfinding/PathEdge.h | 1 + .../public/sharedPathfinding/PathGraph.h | 1 + .../sharedPathfinding/PathGraphIterator.h | 1 + .../public/sharedPathfinding/PathNode.h | 1 + .../public/sharedPathfinding/PathSearch.h | 1 + .../public/sharedPathfinding/Pathfinding.h | 1 + .../sharedPathfinding/PathfindingEnums.h | 1 + .../SetupSharedPathfinding.h | 1 + .../sharedPathfinding/SimplePathGraph.h | 1 + .../sharedPathfinding/src/CMakeLists.txt | 55 ++ .../src/shared/ConfigSharedPathfinding.cpp | 37 + .../src/shared/ConfigSharedPathfinding.h | 64 ++ .../src/shared/DynamicPathGraph.cpp | 344 +++++++++ .../src/shared/DynamicPathGraph.h | 82 +++ .../src/shared/DynamicPathNode.cpp | 267 +++++++ .../src/shared/DynamicPathNode.h | 67 ++ .../src/shared/FirstSharedPathfinding.h | 17 + .../sharedPathfinding/src/shared/PathEdge.cpp | 55 ++ .../sharedPathfinding/src/shared/PathEdge.h | 149 ++++ .../src/shared/PathGraph.cpp | 301 ++++++++ .../sharedPathfinding/src/shared/PathGraph.h | 101 +++ .../src/shared/PathGraphIterator.cpp | 68 ++ .../src/shared/PathGraphIterator.h | 50 ++ .../sharedPathfinding/src/shared/PathNode.cpp | 107 +++ .../sharedPathfinding/src/shared/PathNode.h | 238 +++++++ .../src/shared/PathSearch.cpp | 652 ++++++++++++++++++ .../sharedPathfinding/src/shared/PathSearch.h | 83 +++ .../src/shared/Pathfinding.cpp | 94 +++ .../src/shared/Pathfinding.h | 36 + .../src/shared/PathfindingEnums.h | 69 ++ .../src/shared/SetupSharedPathfinding.cpp | 172 +++++ .../src/shared/SetupSharedPathfinding.h | 25 + .../src/shared/SimplePathGraph.cpp | 579 ++++++++++++++++ .../src/shared/SimplePathGraph.h | 108 +++ .../src/win32/FirstSharedPathfinding.cpp | 8 + .../library/sharedTerrain/src/CMakeLists.txt | 1 + .../library/sharedUtility/src/CMakeLists.txt | 10 + .../src/shared/CachedFileManager.cpp | 2 +- .../src/shared/InteriorLayoutReaderWriter.cpp | 2 +- 50 files changed, 3874 insertions(+), 2 deletions(-) create mode 100644 engine/shared/library/sharedPathfinding/CMakeLists.txt create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/ConfigSharedPathfinding.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/DynamicPathGraph.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/DynamicPathNode.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/FirstSharedPathfinding.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathEdge.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathGraph.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathGraphIterator.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathNode.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathSearch.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/Pathfinding.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathfindingEnums.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/SetupSharedPathfinding.h create mode 100644 engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/SimplePathGraph.h create mode 100644 engine/shared/library/sharedPathfinding/src/CMakeLists.txt create mode 100644 engine/shared/library/sharedPathfinding/src/shared/ConfigSharedPathfinding.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/ConfigSharedPathfinding.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/DynamicPathGraph.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/DynamicPathGraph.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/DynamicPathNode.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/DynamicPathNode.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/FirstSharedPathfinding.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathEdge.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathEdge.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathGraph.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathGraph.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathGraphIterator.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathGraphIterator.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathNode.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathNode.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathSearch.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/Pathfinding.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/Pathfinding.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/PathfindingEnums.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/SetupSharedPathfinding.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/SetupSharedPathfinding.h create mode 100644 engine/shared/library/sharedPathfinding/src/shared/SimplePathGraph.cpp create mode 100644 engine/shared/library/sharedPathfinding/src/shared/SimplePathGraph.h create mode 100644 engine/shared/library/sharedPathfinding/src/win32/FirstSharedPathfinding.cpp diff --git a/engine/shared/library/CMakeLists.txt b/engine/shared/library/CMakeLists.txt index 92f6867f..dee89db3 100644 --- a/engine/shared/library/CMakeLists.txt +++ b/engine/shared/library/CMakeLists.txt @@ -16,6 +16,7 @@ add_subdirectory(sharedMessageDispatch) add_subdirectory(sharedNetwork) add_subdirectory(sharedNetworkMessages) add_subdirectory(sharedObject) +add_subdirectory(sharedPathfinding) add_subdirectory(sharedRandom) add_subdirectory(sharedSkillSystem) add_subdirectory(sharedSynchronization) diff --git a/engine/shared/library/sharedGame/src/CMakeLists.txt b/engine/shared/library/sharedGame/src/CMakeLists.txt index 3efa73a7..2052f32a 100644 --- a/engine/shared/library/sharedGame/src/CMakeLists.txt +++ b/engine/shared/library/sharedGame/src/CMakeLists.txt @@ -323,6 +323,7 @@ include_directories( ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSkillSystem/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedTerrain/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public + ${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/fileInterface/include/public ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include diff --git a/engine/shared/library/sharedNetworkMessages/src/CMakeLists.txt b/engine/shared/library/sharedNetworkMessages/src/CMakeLists.txt index aa78114a..10b248a5 100644 --- a/engine/shared/library/sharedNetworkMessages/src/CMakeLists.txt +++ b/engine/shared/library/sharedNetworkMessages/src/CMakeLists.txt @@ -716,9 +716,11 @@ include_directories( ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public + ${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localizationArchive/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/singleton/include ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public ) diff --git a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/SceneChannelMessages.cpp b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/SceneChannelMessages.cpp index 9ed2e939..ce12270c 100644 --- a/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/SceneChannelMessages.cpp +++ b/engine/shared/library/sharedNetworkMessages/src/shared/clientGameServer/SceneChannelMessages.cpp @@ -11,6 +11,8 @@ #include "sharedMathArchive/TransformArchive.h" #include "sharedFoundation/MemoryBlockManager.h" +#include + //----------------------------------------------------------------------- namespace SceneChannelMessagesNamespace diff --git a/engine/shared/library/sharedObject/src/CMakeLists.txt b/engine/shared/library/sharedObject/src/CMakeLists.txt index 6dd18070..e9cb7767 100644 --- a/engine/shared/library/sharedObject/src/CMakeLists.txt +++ b/engine/shared/library/sharedObject/src/CMakeLists.txt @@ -180,10 +180,12 @@ include_directories( ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetworkMessages/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedPathfinding/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSynchronization/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedTerrain/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public + ${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/fileInterface/include/public ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include diff --git a/engine/shared/library/sharedObject/src/shared/portal/PortalProperty.cpp b/engine/shared/library/sharedObject/src/shared/portal/PortalProperty.cpp index 6605cebf..aa3f3164 100644 --- a/engine/shared/library/sharedObject/src/shared/portal/PortalProperty.cpp +++ b/engine/shared/library/sharedObject/src/shared/portal/PortalProperty.cpp @@ -24,6 +24,7 @@ #include "sharedObject/PortalPropertyTemplate.h" #include "sharedObject/PortalPropertyTemplateList.h" +#include #include // ====================================================================== diff --git a/engine/shared/library/sharedPathfinding/CMakeLists.txt b/engine/shared/library/sharedPathfinding/CMakeLists.txt new file mode 100644 index 00000000..3a498561 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 2.8) + +project(sharedPathfinding) + +if(WIN32) + add_definitions(/D_CRT_SECURE_NO_WARNINGS) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public) + +add_subdirectory(src) diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/ConfigSharedPathfinding.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/ConfigSharedPathfinding.h new file mode 100644 index 00000000..7d0f5904 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/ConfigSharedPathfinding.h @@ -0,0 +1 @@ +#include "../../src/shared/ConfigSharedPathfinding.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/DynamicPathGraph.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/DynamicPathGraph.h new file mode 100644 index 00000000..a4003145 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/DynamicPathGraph.h @@ -0,0 +1 @@ +#include "../../src/shared/DynamicPathGraph.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/DynamicPathNode.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/DynamicPathNode.h new file mode 100644 index 00000000..03d66e3f --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/DynamicPathNode.h @@ -0,0 +1 @@ +#include "../../src/shared/DynamicPathNode.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/FirstSharedPathfinding.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/FirstSharedPathfinding.h new file mode 100644 index 00000000..292db6e4 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/FirstSharedPathfinding.h @@ -0,0 +1 @@ +#include "../../src/shared/FirstSharedPathfinding.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathEdge.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathEdge.h new file mode 100644 index 00000000..d9029615 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathEdge.h @@ -0,0 +1 @@ +#include "../../src/shared/PathEdge.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathGraph.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathGraph.h new file mode 100644 index 00000000..5195b75e --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathGraph.h @@ -0,0 +1 @@ +#include "../../src/shared/PathGraph.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathGraphIterator.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathGraphIterator.h new file mode 100644 index 00000000..53cf8119 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathGraphIterator.h @@ -0,0 +1 @@ +#include "../../src/shared/PathGraphIterator.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathNode.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathNode.h new file mode 100644 index 00000000..c10a0d54 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathNode.h @@ -0,0 +1 @@ +#include "../../src/shared/PathNode.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathSearch.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathSearch.h new file mode 100644 index 00000000..b40a8090 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathSearch.h @@ -0,0 +1 @@ +#include "../../src/shared/PathSearch.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/Pathfinding.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/Pathfinding.h new file mode 100644 index 00000000..89158dbf --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/Pathfinding.h @@ -0,0 +1 @@ +#include "../../src/shared/Pathfinding.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathfindingEnums.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathfindingEnums.h new file mode 100644 index 00000000..ae50bd53 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/PathfindingEnums.h @@ -0,0 +1 @@ +#include "../../src/shared/PathfindingEnums.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/SetupSharedPathfinding.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/SetupSharedPathfinding.h new file mode 100644 index 00000000..79b25fe4 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/SetupSharedPathfinding.h @@ -0,0 +1 @@ +#include "../../src/shared/SetupSharedPathfinding.h" diff --git a/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/SimplePathGraph.h b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/SimplePathGraph.h new file mode 100644 index 00000000..0496b073 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/include/public/sharedPathfinding/SimplePathGraph.h @@ -0,0 +1 @@ +#include "../../src/shared/SimplePathGraph.h" diff --git a/engine/shared/library/sharedPathfinding/src/CMakeLists.txt b/engine/shared/library/sharedPathfinding/src/CMakeLists.txt new file mode 100644 index 00000000..42accf79 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/CMakeLists.txt @@ -0,0 +1,55 @@ + +set(SHARED_SOURCES + shared/ConfigSharedPathfinding.cpp + shared/ConfigSharedPathfinding.h + shared/DynamicPathGraph.cpp + shared/DynamicPathGraph.h + shared/DynamicPathNode.cpp + shared/DynamicPathNode.h + shared/FirstSharedPathfinding.h + shared/PathEdge.cpp + shared/PathEdge.h + shared/Pathfinding.cpp + shared/PathfindingEnums.h + shared/Pathfinding.h + shared/PathGraph.cpp + shared/PathGraph.h + shared/PathGraphIterator.cpp + shared/PathGraphIterator.h + shared/PathNode.cpp + shared/PathNode.h + shared/PathSearch.cpp + shared/PathSearch.h + shared/SetupSharedPathfinding.cpp + shared/SetupSharedPathfinding.h + shared/SimplePathGraph.cpp + shared/SimplePathGraph.h +) + +if(WIN32) + set(PLATFORM_SOURCES + win32/FirstSharedPathfinding.cpp + ) + + include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32) +else() + set(PLATFORM_SOURCES "") +endif() + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/shared + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCollision/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedObject/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include +) + +add_library(sharedPathfinding STATIC + ${SHARED_SOURCES} + ${PLATFORM_SOURCES} +) diff --git a/engine/shared/library/sharedPathfinding/src/shared/ConfigSharedPathfinding.cpp b/engine/shared/library/sharedPathfinding/src/shared/ConfigSharedPathfinding.cpp new file mode 100644 index 00000000..e6729bc2 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/ConfigSharedPathfinding.cpp @@ -0,0 +1,37 @@ +// ====================================================================== +// +// ConfigSharedPathfinding.cpp +// copyright 1998 Bootprint Entertainment +// copyright 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "ConfigSharedPathfinding.h" + +#include "sharedDebug/DebugFlags.h" +#include "sharedFoundation/ConfigFile.h" + +#define KEY_INT(a,b) (ms_ ## a = ConfigFile::getKeyInt("SharedPathfinding", #a, b)) +#define KEY_BOOL(a,b) {ms_ ## a = ConfigFile::getKeyBool("SharedPathfinding", #a, b); DebugFlags::registerFlag(ms_ ## a, "SharedPathfinding", #a);} +#define KEY_FLOAT(a,b) (ms_ ## a = ConfigFile::getKeyFloat("SharedPathfinding", #a, b)) +#define KEY_STRING(a,b) (ms_ ## a = ConfigFile::getKeyString("SharedPathfinding", #a, b)) + +bool ConfigSharedPathfinding::ms_autoCreateBuildingPathNodes = false; +bool ConfigSharedPathfinding::ms_useCityRegions = true; +bool ConfigSharedPathfinding::ms_jitterCityWaypoints = false; +bool ConfigSharedPathfinding::ms_enableDirtyBoxes = false; +bool ConfigSharedPathfinding::ms_enablePathScrubber = false; + +// ---------------------------------------------------------------------- + +void ConfigSharedPathfinding::install () +{ + KEY_BOOL(autoCreateBuildingPathNodes,false); + KEY_BOOL(useCityRegions,true); + KEY_BOOL(jitterCityWaypoints,false); + KEY_BOOL(enableDirtyBoxes,false); + KEY_BOOL(enablePathScrubber,false); +} + +// ====================================================================== diff --git a/engine/shared/library/sharedPathfinding/src/shared/ConfigSharedPathfinding.h b/engine/shared/library/sharedPathfinding/src/shared/ConfigSharedPathfinding.h new file mode 100644 index 00000000..4acc95ef --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/ConfigSharedPathfinding.h @@ -0,0 +1,64 @@ +// ====================================================================== +// +// ConfigSharedPathfinding.h +// copyright 1998 Bootprint Entertainment +// copyright 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_ConfigSharedPathfinding_H +#define INCLUDED_ConfigSharedPathfinding_H + +// ====================================================================== + +class ConfigSharedPathfinding +{ +public: + + static void install(); + + static bool getAutoCreateBuildingPathNodes(); + static bool getUseCityRegions(); + static bool getJitterCityWaypoints(); + static bool getEnableDirtyBoxes(); + static bool getEnablePathScrubber(); + +private: + + static bool ms_autoCreateBuildingPathNodes; + static bool ms_useCityRegions; + static bool ms_jitterCityWaypoints; + static bool ms_enableDirtyBoxes; + static bool ms_enablePathScrubber; +}; + +//-------------------------------------------------------------------- + +inline bool ConfigSharedPathfinding::getAutoCreateBuildingPathNodes() +{ + return ms_autoCreateBuildingPathNodes; +} + +inline bool ConfigSharedPathfinding::getUseCityRegions() +{ + return ms_useCityRegions; +} + +inline bool ConfigSharedPathfinding::getJitterCityWaypoints() +{ + return ms_jitterCityWaypoints; +} + +inline bool ConfigSharedPathfinding::getEnableDirtyBoxes() +{ + return ms_enableDirtyBoxes; +} + +inline bool ConfigSharedPathfinding::getEnablePathScrubber() +{ + return ms_enablePathScrubber; +} + +// ====================================================================== + +#endif diff --git a/engine/shared/library/sharedPathfinding/src/shared/DynamicPathGraph.cpp b/engine/shared/library/sharedPathfinding/src/shared/DynamicPathGraph.cpp new file mode 100644 index 00000000..532ade02 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/DynamicPathGraph.cpp @@ -0,0 +1,344 @@ +// ====================================================================== +// +// DynamicPathGraph.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "sharedPathfinding/DynamicPathGraph.h" + +#include "sharedCollision/CollisionWorld.h" +#include "sharedObject/CellProperty.h" +#include "sharedPathfinding/DynamicPathNode.h" + +DynamicPathGraph::DynamicPathGraph ( PathGraphType type ) +: PathGraph(type), + m_nodeList( new NodeList() ), + m_dirtyNodes( new IndexList() ), + m_liveNodeCount(0) +{ +} + +DynamicPathGraph::~DynamicPathGraph() +{ + clear(); + + delete m_nodeList; + m_nodeList = NULL; + + delete m_dirtyNodes; + m_dirtyNodes = NULL; +} + +// ---------- + +void DynamicPathGraph::clear ( void ) +{ + int nodeCount = getNodeCount(); + + for(int i = 0; i < nodeCount; i++) + { + delete m_nodeList->at(i); + } + + m_nodeList->clear(); +} + +// ---------- +// PathGraph interface + +int DynamicPathGraph::getNodeCount ( void ) const +{ + return m_nodeList->size(); +} + +int DynamicPathGraph::getLiveNodeCount ( void ) const +{ + return m_liveNodeCount; +} + +PathNode * DynamicPathGraph::getNode ( int nodeIndex ) +{ + return _getNode(nodeIndex); +} + +PathNode const * DynamicPathGraph::getNode ( int nodeIndex ) const +{ + return _getNode(nodeIndex); +} + +int DynamicPathGraph::getEdgeCount ( int nodeIndex ) const +{ + DynamicPathNode const * node = _getNode(nodeIndex); + + if(node == NULL) + { + return 0; + } + else + { + return node->getEdgeCount(); + } +} + +PathEdge * DynamicPathGraph::getEdge ( int nodeIndex, int edgeIndex ) +{ + DynamicPathNode * node = _getNode(nodeIndex); + + if(node != NULL) + { + return node->getEdge(edgeIndex); + } + else + { + return NULL; + } +} + +PathEdge const * DynamicPathGraph::getEdge ( int nodeIndex, int edgeIndex ) const +{ + DynamicPathNode const * node = _getNode(nodeIndex); + + if(node != NULL) + { + return node->getEdge(edgeIndex); + } + else + { + return NULL; + } +} + +// ---------------------------------------------------------------------- + +int DynamicPathGraph::addNode ( DynamicPathNode * newNode ) +{ + if(newNode == NULL) return -1; + + int listSize = m_nodeList->size(); + + int nodeIndex = -1; + + if(m_liveNodeCount < listSize) + { + for(int i = 0; i < listSize; i++) + { + if(m_nodeList->at(i) == NULL) + { + nodeIndex = i; + break; + } + } + } + else + { + m_nodeList->resize(listSize + 1); + nodeIndex = listSize; + } + + FATAL(nodeIndex == -1,("DynamicPathGraph::addNode - Couldn't add the new node to the node list\n")); + + m_nodeList->at(nodeIndex) = newNode; + + newNode->setIndex(nodeIndex); + newNode->setGraph(this); + + m_liveNodeCount++; + + return nodeIndex; +} + +void DynamicPathGraph::removeNode ( int nodeIndex ) +{ + if(nodeIndex == -1) return; + + DynamicPathNode * node = _getNode(nodeIndex); + + if(node != NULL) + { + unlinkNode(nodeIndex); + + m_nodeList->at(nodeIndex) = NULL; + + delete node; + + m_liveNodeCount--; + } +} + +void DynamicPathGraph::moveNode ( int nodeIndex, Vector const & newPosition ) +{ + DynamicPathNode * node = _getNode(nodeIndex); + + if(node != NULL) + { + node->setPosition_p(newPosition); + + m_dirtyNodes->push_back(nodeIndex); + + //@todo - HACK - force cleaning after move + + clean(); + } +} + +// ---------------------------------------------------------------------- + +void DynamicPathGraph::update ( void ) +{ + if(isDirty()) + { + clean(); + } +} + +// ---------------------------------------------------------------------- + +bool DynamicPathGraph::isDirty ( void ) const +{ + return !m_dirtyNodes->empty(); +} + +// ---------- + +void DynamicPathGraph::clean ( void ) +{ + // Clean all dirty nodes + + /* nothing to do here yet */ + + // All dirty nodes are now clean but unlinked. Relink them. + + int dirtyCount = m_dirtyNodes->size(); + + for(int i = 0; i < dirtyCount; i++) + { + int dirtyIndex = m_dirtyNodes->at(i); + + relinkNode(dirtyIndex); + } + + // Done. + + m_dirtyNodes->clear(); +} + +// ---------------------------------------------------------------------- + +void DynamicPathGraph::unlinkNode ( int nodeIndex ) +{ + DynamicPathNode * node = _getNode(nodeIndex); + + if(node == NULL) return; + + // ---------- + + int edgeCount = node->getEdgeCount(); + + for(int i = 0; i < edgeCount; i++) + { + int neighborIndex = node->getNeighbor(i); + + DynamicPathNode * neighborNode = _getNode(neighborIndex); + + if(neighborNode) neighborNode->_removeEdge(nodeIndex); + } + + node->clearEdges(); +} + +// ---------------------------------------------------------------------- + +void DynamicPathGraph::relinkNode ( int nodeIndex ) +{ + DynamicPathNode * nodeA = _getNode(nodeIndex); + + if(nodeA == NULL) return; + + // ---------- + + unlinkNode(nodeIndex); + + int listSize = m_nodeList->size(); + + int i; + + for(i = 0; i < listSize; i++) + { + DynamicPathNode * nodeB = _getNode(i); + + if(nodeB == NULL) continue; + if(nodeA == nodeB) continue; + + Vector const & posA = nodeA->getPosition_p(); + Vector const & posB = nodeB->getPosition_p(); + + // Only try and link nodes that are within 40 meters of each other + + if(posA.magnitudeBetweenSquared(posB) < (40.0f * 40.0f)) + { + if(CollisionWorld::canMove( CellProperty::getWorldCellProperty(), posA, posB, 0.5f, true, true, false) == CMR_MoveOK) + { + nodeA->addEdge( nodeB->getIndex() ); + nodeB->addEdge( nodeA->getIndex() ); + } + else + { + // nodes can't be connected + + continue; + } + } + } + + // ---------- + // Linking done, prune redundant edges + + nodeA->markRedundantEdges(); + nodeA->removeMarkedEdges(); + + // this has to be done in two passes, otherwise node A's neighbor list could be changing + // as we prune edges. + + std::vector neighborList; + + int edgeCount = nodeA->getEdgeCount(); + + for(i = 0; i < edgeCount; i++) + { + neighborList.push_back( nodeA->getNeighbor(i) ); + } + + for(i = 0; i < edgeCount; i++) + { + DynamicPathNode * neighborNode = _getNode(neighborList[i]); + + if(neighborNode != NULL) + { + neighborNode->markRedundantEdges(); + neighborNode->removeMarkedEdges(); + } + } +} + +// ---------------------------------------------------------------------- + +DynamicPathNode * DynamicPathGraph::_getNode ( int nodeIndex ) +{ + if(nodeIndex == -1) return NULL; + + return m_nodeList->at(nodeIndex); +} + +// ---------- + +DynamicPathNode const * DynamicPathGraph::_getNode ( int nodeIndex ) const +{ + if(nodeIndex == -1) return NULL; + + return m_nodeList->at(nodeIndex); +} + +// ====================================================================== + diff --git a/engine/shared/library/sharedPathfinding/src/shared/DynamicPathGraph.h b/engine/shared/library/sharedPathfinding/src/shared/DynamicPathGraph.h new file mode 100644 index 00000000..e2baf1f3 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/DynamicPathGraph.h @@ -0,0 +1,82 @@ +// ====================================================================== +// +// DynamicPathGraph.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_DynamicPathGraph_H +#define INCLUDED_DynamicPathGraph_H + +#include "sharedPathfinding/PathGraph.h" + +#include "sharedMath/Vector.h" + +class DynamicPathNode; + +// ====================================================================== +// Dynamic path graph, used for graphs where we need to be able to add +// and remove nodes on the fly (such as city graphs) + +// DynamicPathGraph uses a sparse array to store its nodes. Calling +// getNode with a nodeIndex in [0,nodeCount) may return NULL. If you +// want to know the number of live nodes in the graph, call getLiveNodeCount. + +class DynamicPathGraph : public PathGraph +{ +public: + + DynamicPathGraph ( PathGraphType type = PGT_None ); + + virtual ~DynamicPathGraph(); + + // ---------- + // PathGraph interface + + virtual int getNodeCount ( void ) const; + virtual PathNode * getNode ( int nodeIndex ); + virtual PathNode const * getNode ( int nodeIndex ) const; + + virtual int getEdgeCount ( int nodeIndex ) const; + virtual PathEdge * getEdge ( int nodeIndex, int edgeIndex ); + virtual PathEdge const * getEdge ( int nodeIndex, int edgeIndex ) const; + + // ---------- + + virtual int addNode ( DynamicPathNode * newNode ); + virtual void removeNode ( int nodeIndex ); + + virtual void moveNode ( int nodeIndex, Vector const & newPosition ); + + virtual void update ( void ); + + virtual bool isDirty ( void ) const; + virtual void clean ( void ); + + virtual void clear ( void ); + + virtual void unlinkNode ( int nodeIndex ); + virtual void relinkNode ( int nodeIndex ); + + virtual int getLiveNodeCount( void ) const; + +protected: + + friend class DynamicPathNode; + + DynamicPathNode * _getNode ( int nodeIndex ); + DynamicPathNode const * _getNode ( int nodeIndex ) const; + + typedef stdvector::fwd NodeList; + typedef stdvector::fwd IndexList; + + NodeList * m_nodeList; + IndexList * m_dirtyNodes; + int m_liveNodeCount; +}; + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/shared/DynamicPathNode.cpp b/engine/shared/library/sharedPathfinding/src/shared/DynamicPathNode.cpp new file mode 100644 index 00000000..8f3798bf --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/DynamicPathNode.cpp @@ -0,0 +1,267 @@ +// ====================================================================== +// +// DynamicPathNode.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "sharedPathfinding/DynamicPathNode.h" + +#include "sharedPathfinding/PathEdge.h" +#include "sharedPathfinding/DynamicPathGraph.h" + +static float angleBetween ( Vector const & A, Vector const & B, Vector const & C ) +{ + Vector dA = (B-A); + Vector dB = (C-A); + + IGNORE_RETURN(dA.normalize()); + IGNORE_RETURN(dB.normalize()); + + float dot = dA.dot(dB); + + return acos(dot); +} + +// ====================================================================== + +DynamicPathNode::DynamicPathNode ( void ) +: PathNode(), + m_edges() +{ +} + +DynamicPathNode::DynamicPathNode ( Vector const & position_p ) +: PathNode( position_p ), + m_edges() +{ +} + +DynamicPathNode::~DynamicPathNode() +{ +} + +// ---------------------------------------------------------------------- + +int DynamicPathNode::getEdgeCount ( void ) const +{ + return m_edges.size(); +} + +// ---------- + +PathEdge * DynamicPathNode::getEdge ( int whichEdge ) +{ + return &m_edges[whichEdge]; +} + +// ---------- + +PathEdge const * DynamicPathNode::getEdge ( int whichEdge ) const +{ + return &m_edges[whichEdge]; +} + +// ---------- + +int DynamicPathNode::getNeighbor ( int whichEdge ) const +{ + return m_edges[whichEdge].getIndexB(); +} + +// ---------------------------------------------------------------------- + +bool DynamicPathNode::hasEdge ( int nodeIndex ) const +{ + int edgeCount = m_edges.size(); + + for(int i = 0; i < edgeCount; i++) + { + if(m_edges[i].getIndexB() == nodeIndex) + { + return true; + } + } + + return false; +} + +// ---------- + +bool DynamicPathNode::addEdge ( int nodeIndex ) +{ + if(!hasEdge(nodeIndex)) + { + m_edges.push_back( PathEdge( m_index, nodeIndex ) ); + } + + return true; +} + +// ---------- + +bool DynamicPathNode::removeEdge ( int nodeIndex ) +{ + DynamicPathNode * neighbor = _getGraph()->_getNode(nodeIndex); + + if(neighbor == NULL) return false; + + if(!_removeEdge(nodeIndex)) return false; + + return neighbor->_removeEdge( getIndex() ); +} + +bool DynamicPathNode::_removeEdge ( int nodeIndex ) +{ + int edgeIndex = -1; + + int edgeCount = m_edges.size(); + + for(int i = 0; i < edgeCount; i++) + { + if(m_edges[i].getIndexB() == nodeIndex) + { + edgeIndex = i; + break; + } + } + + if(edgeIndex != -1) + { + m_edges.erase( m_edges.begin() + edgeIndex ); + return true; + } + else + { + return false; + } +} + +// ---------- + +void DynamicPathNode::clearEdges ( void ) +{ + m_edges.clear(); +} + +// ---------------------------------------------------------------------- + +void DynamicPathNode::clearEdgeMarks ( void ) const +{ + int edgeCount = getEdgeCount(); + + for(int i = 0; i < edgeCount; i++) + { + getEdge(i)->clearMarks(); + } +} + +// ---------------------------------------------------------------------- + +int DynamicPathNode::markRedundantEdges ( void ) const +{ + clearEdgeMarks(); + + float angleTolerance = (20.0f / 360.0f) * (2.0f * PI); + + int edgeCount = getEdgeCount(); + int markCount = 0; + + for(int i = 0; i < edgeCount - 1; i++) + { + for(int j = i+1; j < edgeCount; j++) + { + PathEdge const * edgeA = getEdge(i); + PathEdge const * edgeB = getEdge(j); + + if(edgeA == NULL) continue; + if(edgeB == NULL) continue; + + int iA = edgeA->getIndexA(); + int iB = edgeA->getIndexB(); + int iC = edgeB->getIndexB(); + + if(getGraph()->getNode(iA)->getType() == PNT_CityBuilding) continue; + if(getGraph()->getNode(iB)->getType() == PNT_CityBuilding) continue; + if(getGraph()->getNode(iC)->getType() == PNT_CityBuilding) continue; + + Vector A = getGraph()->getNode(iA)->getPosition_p(); + Vector B = getGraph()->getNode(iB)->getPosition_p(); + Vector C = getGraph()->getNode(iC)->getPosition_p(); + + if(angleBetween(A,B,C) < angleTolerance) + { + float magAB = (B-A).magnitudeSquared(); + float magAC = (C-A).magnitudeSquared(); + + if(magAB > magAC) + { + // The A-B edge is longer, so mark edgeA as redundant. + + if(edgeA->getMark(0) != 1) + { + edgeA->setMark(0,1); + markCount++; + } + } + else + { + // The A-C edge is longer, so mark edgeB as redundant. + + if(edgeB->getMark(0) != 1) + { + edgeB->setMark(0,1); + markCount++; + } + } + } + } + } + + return markCount; +} + +// ---------------------------------------------------------------------- +// not the most efficient way to do this, but it should be OK. + +int DynamicPathNode::removeMarkedEdges ( void ) +{ + int removeCount = 0; + + bool removed = true; + + while(removed) + { + removed = false; + + int edgeCount = getEdgeCount(); + + for(int i = 0; i < edgeCount; i++) + { + PathEdge * edge = getEdge(i); + + if(edge && (edge->getMark(0) != -1)) + { + if(removeEdge(edge->getIndexB())) + { + removeCount++; + removed = true; + break; + } + } + } + } + + return removeCount; +} + +// ---------------------------------------------------------------------- + +DynamicPathGraph * DynamicPathNode::_getGraph ( void ) +{ + return safe_cast< DynamicPathGraph * >( getGraph() ); +} + +// ---------------------------------------------------------------------- + diff --git a/engine/shared/library/sharedPathfinding/src/shared/DynamicPathNode.h b/engine/shared/library/sharedPathfinding/src/shared/DynamicPathNode.h new file mode 100644 index 00000000..d1934019 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/DynamicPathNode.h @@ -0,0 +1,67 @@ +// ====================================================================== +// +// DynamicPathNode.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_DynamicPathNode_H +#define INCLUDED_DynamicPathNode_H + +#include "sharedMath/Vector.h" +#include "sharedPathfinding/PathNode.h" + +#include + +class PathEdge; +class DynamicPathGraph; + +// ====================================================================== + +class DynamicPathNode : public PathNode +{ +public: + + DynamicPathNode ( void ); + + DynamicPathNode ( Vector const & position_p ); + + virtual ~DynamicPathNode(); + + // ---------- + + int getEdgeCount ( void ) const; + PathEdge * getEdge ( int whichEdge ); + PathEdge const * getEdge ( int whichEdge ) const; + + int getNeighbor ( int whichEdge ) const; + + bool hasEdge ( int nodeIndex ) const; + bool addEdge ( int nodeIndex ); + bool removeEdge ( int nodeIndex ); + void clearEdges ( void ); + +protected: + + friend class DynamicPathGraph; + + virtual void clearEdgeMarks ( void ) const; + virtual int markRedundantEdges ( void ) const; + virtual int removeMarkedEdges ( void ); + + bool _removeEdge ( int nodeIndex ); + + DynamicPathGraph * _getGraph ( void ); + + // ---------- + + typedef std::vector EdgeList; + + EdgeList m_edges; +}; + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/shared/FirstSharedPathfinding.h b/engine/shared/library/sharedPathfinding/src/shared/FirstSharedPathfinding.h new file mode 100644 index 00000000..a98bcae5 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/FirstSharedPathfinding.h @@ -0,0 +1,17 @@ +// ====================================================================== +// +// FirstSharedPathfinding.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_FirstSharedPathfinding_H +#define INCLUDED_FirstSharedPathfinding_H + +// ====================================================================== + +#include "sharedFoundation/FirstSharedFoundation.h" + +// ====================================================================== + +#endif diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathEdge.cpp b/engine/shared/library/sharedPathfinding/src/shared/PathEdge.cpp new file mode 100644 index 00000000..eaedcc69 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathEdge.cpp @@ -0,0 +1,55 @@ +// ====================================================================== +// +// PathEdge.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "sharedPathfinding/PathEdge.h" + +#include "sharedFile/Iff.h" + +// ====================================================================== + +PathEdge::PathEdge() +: m_indexA(-1), + m_indexB(-1), + m_laneWidthRight(0.0f), + m_laneWidthLeft(0.0f) +{ +} + +PathEdge::PathEdge ( int indexA, int indexB ) +: m_indexA(indexA), + m_indexB(indexB), + m_laneWidthRight(0.0f), + m_laneWidthLeft(0.0f) +{ +} + +PathEdge::~PathEdge() +{ +} + +// ---------------------------------------------------------------------- + +void PathEdge::read_0000 ( Iff & iff ) +{ + m_indexA = iff.read_int32(); + m_indexB = iff.read_int32(); + m_laneWidthRight = iff.read_float(); + m_laneWidthLeft = iff.read_float(); +} + +// ---------------------------------------------------------------------- + +void PathEdge::write ( Iff & iff ) const +{ + iff.insertChunkData( m_indexA ); + iff.insertChunkData( m_indexB ); + iff.insertChunkData( m_laneWidthRight ); + iff.insertChunkData( m_laneWidthLeft ); +} + +// ====================================================================== diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathEdge.h b/engine/shared/library/sharedPathfinding/src/shared/PathEdge.h new file mode 100644 index 00000000..6add1a3b --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathEdge.h @@ -0,0 +1,149 @@ +// ====================================================================== +// +// PathEdge.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_PathEdge_H +#define INCLUDED_PathEdge_H + +class PathEdge; + +class Iff; + +// ====================================================================== + +class PathEdge +{ +public: + + PathEdge ( void ); + + PathEdge ( int indexA, int indexB ); + + virtual ~PathEdge(); + + // ---------- + + bool operator < ( PathEdge const & edge ) const; + bool operator == ( PathEdge const & edge ) const; + + int getIndexA ( void ) const; + int getIndexB ( void ) const; + + void setIndexA ( int newIndex ); + void setIndexB ( int newIndex ); + + void read_old ( Iff & iff ); + void read_0000 ( Iff & iff ); + + void write ( Iff & iff ) const; + + // ---------- + + int getUserId ( void ) const; + void setUserId ( int newId ) const; + + int getMark ( int whichMark ) const; + void setMark ( int whichMark, int newValue ) const; + void clearMarks ( void ) const; + +protected: + + int m_indexA; + int m_indexB; + + float m_laneWidthRight; // [1] + float m_laneWidthLeft; + + // These are used to speed up some algorithms. They're not persisted. + + mutable int m_userId; + mutable int m_marks[4]; +}; + +// [1] - The lane widths indicate how far to the left or the right of +// the edge a creature moving along the edge can stray without hitting +// anything. + +// ---------------------------------------------------------------------- + +inline bool PathEdge::operator < ( PathEdge const & edge ) const +{ + if( m_indexA == edge.m_indexA ) + { + return m_indexB < edge.m_indexB; + } + else + { + return m_indexA < edge.m_indexA; + } +} + +inline bool PathEdge::operator == ( PathEdge const & edge ) const +{ + return (m_indexA == edge.m_indexA) && (m_indexB == edge.m_indexB); +} + +// ---------- + +inline int PathEdge::getIndexA ( void ) const +{ + return m_indexA; +} + +inline int PathEdge::getIndexB ( void ) const +{ + return m_indexB; +} + +// ---------- + +inline void PathEdge::setIndexA ( int newIndex ) +{ + m_indexA = newIndex; +} + +inline void PathEdge::setIndexB( int newIndex ) +{ + m_indexB = newIndex; +} + +// ---------- + +inline int PathEdge::getUserId ( void ) const +{ + return m_userId; +} + +inline void PathEdge::setUserId ( int newId ) const +{ + m_userId = newId; +} + +// ---------- + +inline int PathEdge::getMark ( int whichMark ) const +{ + return m_marks[whichMark]; +} + +inline void PathEdge::setMark ( int whichMark, int newMark ) const +{ + m_marks[whichMark] = newMark; +} + +inline void PathEdge::clearMarks ( void ) const +{ + m_marks[0] = -1; + m_marks[1] = -1; + m_marks[2] = -1; + m_marks[3] = -1; +} + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathGraph.cpp b/engine/shared/library/sharedPathfinding/src/shared/PathGraph.cpp new file mode 100644 index 00000000..a72faa92 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathGraph.cpp @@ -0,0 +1,301 @@ +// ====================================================================== +// +// PathGraph.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "sharedPathfinding/PathGraph.h" + +#include "sharedPathfinding/PathNode.h" +#include "sharedPathfinding/PathEdge.h" + +#include +#include + +typedef std::stack > PathNodeStack; + +// ====================================================================== + +PathGraph::PathGraph ( PathGraphType type ) +: m_type(type), + m_partCount(-1), + m_searchLock(false) +{ +} + +PathGraph::~PathGraph() +{ +} + +// ---------------------------------------------------------------------- + +PathNode * PathGraph::getNeighbor ( int nodeIndex, int edgeIndex ) +{ + PathEdge * edge = getEdge(nodeIndex,edgeIndex); + + int neighborIndex = edge->getIndexB(); + + return getNode(neighborIndex); +} + +// ---------- + +PathNode const * PathGraph::getNeighbor ( int nodeIndex, int edgeIndex ) const +{ + PathEdge const * edge = getEdge(nodeIndex,edgeIndex); + + int neighborIndex = edge->getIndexB(); + + return getNode(neighborIndex); +} + +// ---------------------------------------------------------------------- + +void PathGraph::drawDebugShapes ( DebugShapeRenderer * ) const +{ +} + +// ---------------------------------------------------------------------- + +int PathGraph::findNode ( PathNodeType type, int key ) const +{ + int nodeCount = getNodeCount(); + + for(int i = 0; i < nodeCount; i++) + { + PathNode const * node = getNode(i); + + if(getEdgeCount(i) == 0) continue; + + if((node != NULL) && (node->getType() == type) && (node->getKey() == key)) + { + return i; + } + } + + return -1; +} + +// ---------------------------------------------------------------------- + +int PathGraph::findEntrance ( int key ) const +{ + int nodeCount = getNodeCount(); + + for(int i = 0; i < nodeCount; i++) + { + PathNode const * node = getNode(i); + + if(node == NULL) continue; + + if(getEdgeCount(i) == 0) continue; + + PathNodeType type = node->getType(); + + if((type == PNT_CellPortal) || (type == PNT_BuildingEntrance) || (type == PNT_CityEntrance)) + { + if(node->getKey() == key) + { + return i; + } + } + } + + return -1; +} + +// ---------------------------------------------------------------------- + +int PathGraph::findNearestNode ( Vector const & position_p ) const +{ + int minNode = -1; + float minDist2 = REAL_MAX; + + int nodeCount = getNodeCount(); + + for(int i = 0; i < nodeCount; i++) + { + PathNode const * node = getNode(i); + + if(node == NULL) continue; + + if(getEdgeCount(i) == 0) continue; + + float dist2 = position_p.magnitudeBetweenSquared(node->getPosition_p()); + + if(dist2 < minDist2) + { + minNode = i; + minDist2 = dist2; + } + } + + return minNode; +} + +// ---------------------------------------------------------------------- + +int PathGraph::findNearestNode ( PathNodeType searchType, Vector const & position_p ) const +{ + int minNode = -1; + float minDist2 = REAL_MAX; + + int nodeCount = getNodeCount(); + + for(int i = 0; i < nodeCount; i++) + { + PathNode const * node = getNode(i); + + if(node == NULL) continue; + + if(getEdgeCount(i) == 0) continue; + + PathNodeType type = node->getType(); + + if(type != searchType) continue; + + float dist2 = position_p.magnitudeBetweenSquared(node->getPosition_p()); + + if(dist2 < minDist2) + { + minNode = i; + minDist2 = dist2; + } + } + + return minNode; +} + +// ---------------------------------------------------------------------- + +void PathGraph::findNodesInRange ( Vector const & position_p, float range, PathNodeList & results ) const +{ + float range2 = range * range; + + int nodeCount = getNodeCount(); + + for(int i = 0; i < nodeCount; i++) + { + PathNode const * node = getNode(i); + + if(node == NULL) continue; + + if(getEdgeCount(i) == 0) continue; + + float dist2 = position_p.magnitudeBetweenSquared(node->getPosition_p()); + + if(dist2 < range2) + { + results.push_back( const_cast(node) ); + } + } +} + +// ---------------------------------------------------------------------- + +int PathGraph::getNodeKey ( int nodeIndex ) const +{ + PathNode const * node = getNode(nodeIndex); + + return node ? node->getKey() : -1; +} + +// ---------------------------------------------------------------------- + +void PathGraph::searchLock ( void ) const +{ + DEBUG_FATAL(m_searchLock,("PathGraph::searchLock - Tried to lock a path graph that was already locked\n")); + + m_searchLock = true; +} + +void PathGraph::searchUnlock ( void ) const +{ + DEBUG_WARNING(!m_searchLock,("PathGraph::searchUnlock - Graph was already unlocked\n")); + + m_searchLock = false; +} + +// ---------------------------------------------------------------------- + +void PathGraph::setPartTags ( void ) +{ + static PathNodeStack unprocessed; + + int nodeCount = getNodeCount(); + + for(int i = 0; i < nodeCount; i++) + { + PathNode * node = getNode(i); + + node->setPartId(-1); + + // ignore nodes without edges unless they're the only node in the cell + + int edgeCount = getEdgeCount(node->getIndex()); + + if(edgeCount > 0) + { + unprocessed.push(node); + } + else + { + PathNodeType type = node->getType(); + + if((nodeCount == 1) && (type == PNT_CellPortal)) + { + unprocessed.push(node); + } + } + } + + static PathNodeStack processing; + + int currentTag = 0; + + while(!unprocessed.empty()) + { + PathNode * currentNode = unprocessed.top(); + unprocessed.pop(); + + if(currentNode->getPartId() != -1) continue; + + processing.push(currentNode); + + while(!processing.empty()) + { + PathNode * node = processing.top(); + processing.pop(); + + if(node->getPartId() != -1) continue; + + node->setPartId(currentTag); + + int edgeCount = getEdgeCount(node->getIndex()); + + for(int i = 0; i < edgeCount; i++) + { + int neighborIndex = getEdge(node->getIndex(),i)->getIndexB(); + + PathNode * neighborNode = getNode(neighborIndex); + + processing.push(neighborNode); + } + } + + currentTag++; + } + + m_partCount = currentTag; +} + +// ---------- + +int PathGraph::getPartCount ( void ) const +{ + return m_partCount; +} + +// ====================================================================== diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathGraph.h b/engine/shared/library/sharedPathfinding/src/shared/PathGraph.h new file mode 100644 index 00000000..e2fbc773 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathGraph.h @@ -0,0 +1,101 @@ +// ====================================================================== +// +// PathGraph.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_PathGraph_H +#define INCLUDED_PathGraph_H + +#include "sharedCollision/BaseClass.h" // this really needs to be in a different library +#include "sharedPathfinding/PathfindingEnums.h" + +class PathGraph; +class PathEdge; +class PathNode; +class Iff; +class DebugShapeRenderer; +class Vector; + +typedef stdvector::fwd IndexList; +typedef stdvector::fwd PathNodeList; + +// ====================================================================== + +class PathGraph : public BaseClass +{ +public: + + PathGraph ( PathGraphType type = PGT_None ); + + virtual ~PathGraph(); + + // ---------- + + virtual PathGraphType getType ( void ) const; + virtual void setType ( PathGraphType newType ); + + virtual int getNodeCount ( void ) const = 0; + virtual PathNode * getNode ( int nodeIndex ) = 0; + virtual PathNode const * getNode ( int nodeIndex ) const = 0; + + virtual int getEdgeCount ( int nodeIndex ) const = 0; + virtual PathEdge * getEdge ( int nodeIndex, int edgeIndex ) = 0; + virtual PathEdge const * getEdge ( int nodeIndex, int edgeIndex ) const = 0; + + virtual PathNode * getNeighbor ( int nodeIndex, int edgeIndex ); + virtual PathNode const * getNeighbor ( int nodeIndex, int edgeIndex ) const; + + virtual void drawDebugShapes ( DebugShapeRenderer * renderer ) const; + + // ---------- + + virtual int findNode ( PathNodeType type, int key ) const; + virtual int findEntrance ( int entranceKey ) const; + virtual int findNearestNode ( Vector const & position_p ) const; + virtual int findNearestNode ( PathNodeType type, Vector const & position_p ) const; + virtual void findNodesInRange( Vector const & position_p, float range, PathNodeList & results) const; + + virtual int getNodeKey ( int nodeIndex ) const; + + // If the A* search is using node marks to associate search nodes with path nodes, + // then we can only have 1 search going at a time. Locking and unlocking the path + // graph helps to catch if we try to do more than one search at a time. + + virtual void searchLock ( void ) const; + virtual void searchUnlock ( void ) const; + + virtual void setPartTags ( void ); + virtual int getPartCount ( void ) const; + +protected: + + PathGraphType m_type; + + int m_partCount; + + mutable bool m_searchLock; +}; + +// [1] - The first set of functions allows access to the full set of +// edges in the graph, the second set allows access to the outgoing +// edges for a particular node in the graph. + +// ---------- + +inline PathGraphType PathGraph::getType ( void ) const +{ + return m_type; +} + +inline void PathGraph::setType ( PathGraphType newType ) +{ + m_type = newType; +} + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathGraphIterator.cpp b/engine/shared/library/sharedPathfinding/src/shared/PathGraphIterator.cpp new file mode 100644 index 00000000..92a4dc10 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathGraphIterator.cpp @@ -0,0 +1,68 @@ +// ====================================================================== +// +// PathGraph.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "sharedPathfinding/PathGraphIterator.h" + +#include "sharedPathfinding/PathGraph.h" +#include "sharedPathfinding/PathEdge.h" + +// ====================================================================== + +PathGraphIterator::PathGraphIterator () +: m_graph(NULL), + m_nodeIndex(-1) +{ +} + +PathGraphIterator::PathGraphIterator ( PathGraph const * graph, int nodeIndex ) +: m_graph(graph), + m_nodeIndex(nodeIndex) +{ +} + +// ---------- + +bool PathGraphIterator::isValid ( void ) const +{ + return (m_graph != NULL) && (m_nodeIndex != -1) && (m_graph->getNode(m_nodeIndex) != NULL); +} + +PathNode const * PathGraphIterator::getNode ( void ) const +{ + if( (m_graph != NULL) && (m_nodeIndex != -1) ) + { + return m_graph->getNode( m_nodeIndex ); + } + else + { + return NULL; + } +} + +int PathGraphIterator::getNeighborCount ( void ) const +{ + if(!isValid()) return 0; + + return m_graph->getEdgeCount( m_nodeIndex ); +} + +PathNode const * PathGraphIterator::getNeighbor ( int whichNeighbor ) const +{ + if(!isValid()) return NULL; + + return m_graph->getNode( m_graph->getEdge( m_nodeIndex, whichNeighbor )->getIndexB() ); +} + +void PathGraphIterator::stepTo ( int whichNeighbor ) +{ + if(!isValid()) return; + + m_nodeIndex = m_graph->getEdge( m_nodeIndex, whichNeighbor )->getIndexB(); +} + +// ====================================================================== diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathGraphIterator.h b/engine/shared/library/sharedPathfinding/src/shared/PathGraphIterator.h new file mode 100644 index 00000000..9aabb368 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathGraphIterator.h @@ -0,0 +1,50 @@ +// ====================================================================== +// +// PathGraphIterator.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_PathGraphIterator_H +#define INCLUDED_PathGraphIterator_H + +class PathGraph; +class PathNode; + +// ====================================================================== +// This is an accessory class to make code that traverses path graphs +// easier. It's not an iterator in the strict STL sense, but it is quite +// helpful. + +class PathGraphIterator +{ +public: + + PathGraphIterator (); + + PathGraphIterator ( PathGraph const * graph, int nodeIndex ); + + // ---------- + + bool isValid ( void ) const; + + PathNode const * getNode ( void ) const; + + int getNeighborCount ( void ) const; + PathNode const * getNeighbor ( int whichNeighbor ) const; + + void stepTo ( int whichNeighbor ); + + // ---------- + +protected: + + PathGraph const * m_graph; + int m_nodeIndex; +}; + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathNode.cpp b/engine/shared/library/sharedPathfinding/src/shared/PathNode.cpp new file mode 100644 index 00000000..6ff18223 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathNode.cpp @@ -0,0 +1,107 @@ +// ====================================================================== +// +// PathNode.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "sharedPathfinding/PathNode.h" + +#include "sharedFile/Iff.h" + +// ====================================================================== + +PathNode::PathNode() +: m_graph(NULL), + m_index(-1), + m_id(-1), + m_key(-1), + m_type(PNT_Invalid), + m_partId(-1), + m_position( Vector::zero ), + m_radius(0.0f), + m_userId(-1) +{ + clearMarks(); +} + +PathNode::PathNode ( Vector const & position ) +: m_graph(NULL), + m_index(-1), + m_id(-1), + m_key(-1), + m_type(PNT_Invalid), + m_partId(-1), + m_position( position ), + m_radius(0.0f), + m_userId(-1) +{ + clearMarks(); +} + +PathNode::~PathNode() +{ +} + +void PathNode::copy ( PathNode const & P ) +{ + m_id = P.m_id; + m_key = P.m_key; + m_type = P.m_type; + m_partId = P.m_partId; + m_position = P.m_position; + m_radius = P.m_radius; + m_userId = P.m_userId; +} + +// ---------------------------------------------------------------------- + +void PathNode::read_0000 ( Iff & iff ) +{ + m_index = iff.read_int32(); + m_id = iff.read_int32(); + m_key = iff.read_int32(); + m_type = static_cast(iff.read_int32()); + m_position = iff.read_floatVector(); + m_radius = iff.read_float(); +} + +// ---------------------------------------------------------------------- + +void PathNode::write ( Iff & iff ) const +{ + iff.insertChunkData( m_index ); + iff.insertChunkData( m_id ); + iff.insertChunkData( m_key ); + iff.insertChunkData( m_type ); + iff.insertChunkData( m_position ); + iff.insertChunkData( m_radius ); +} + +// ---------------------------------------------------------------------- + +bool PathNode::hasSubgraph ( void ) const +{ + if(m_type == PNT_BuildingCell) return true; + if(m_type == PNT_BuildingCellPart) return true; + if(m_type == PNT_CityBuilding) return true; + + return false; +} + +// ---------------------------------------------------------------------- + +bool PathNode::isConcrete ( void ) const +{ + if(m_type == PNT_BuildingEntrance) return false; + if(m_type == PNT_BuildingCell) return false; + if(m_type == PNT_BuildingPortal) return false; + if(m_type == PNT_CityBuildingEntrance) return false; + if(m_type == PNT_CityBuilding) return false; + if(m_type == PNT_Invalid) return false; + + return true; +} + +// ====================================================================== diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathNode.h b/engine/shared/library/sharedPathfinding/src/shared/PathNode.h new file mode 100644 index 00000000..fd62f52c --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathNode.h @@ -0,0 +1,238 @@ +// ====================================================================== +// +// PathNode.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_PathNode_H +#define INCLUDED_PathNode_H + +#include "sharedMath/Vector.h" +#include "sharedPathfinding/PathfindingEnums.h" + +class Iff; +class PathGraph; + +// ====================================================================== + +class PathNode +{ +public: + + // ---------- + + PathNode ( void ); + + PathNode ( Vector const & position_p ); + + virtual ~PathNode(); + + virtual void copy ( PathNode const & P ); + + // ---------- + + PathGraph * getGraph ( void ); + PathGraph const * getGraph ( void ) const; + void setGraph ( PathGraph * graph ); + + bool hasSubgraph ( void ) const; + + int getIndex ( void ) const; + void setIndex ( int newIndex ); + + int getId ( void ) const; + void setId ( int newId ); + + int getKey ( void ) const; + void setKey ( int newKey ); + + PathNodeType getType ( void ) const; + void setType ( PathNodeType newType ); + + int getPartId ( void ) const; + void setPartId ( int newPart ); + + // ---------- + + Vector const & getPosition_p ( void ) const; + virtual void setPosition_p ( Vector const & newPosition ); + + float getRadius ( void ) const; + void setRadius ( float newRadius ); + + // ---------- + + int getUserId ( void ) const; + void setUserId ( int newId ) const; + + int getMark ( int whichMark ) const; + void setMark ( int whichMark, int newValue ) const; + void clearMarks ( void ) const; + + // ---------- + + void read_0000 ( Iff & iff ); + + void write ( Iff & iff ) const; + + bool isConcrete ( void ) const; + +protected: + + PathGraph * m_graph; + + int m_index; + int m_id; + int m_key; + PathNodeType m_type; + int m_partId; + + Vector m_position; + float m_radius; + + // These are used to speed up some algorithms. They're not persisted. + // Code that uses the marks MUST clear them after use. + + mutable int m_userId; + mutable int m_marks[4]; +}; + +// ---------------------------------------------------------------------- + +inline PathGraph * PathNode::getGraph ( void ) +{ + return m_graph; +} + +inline PathGraph const * PathNode::getGraph ( void ) const +{ + return m_graph; +} + +inline void PathNode::setGraph ( PathGraph * graph ) +{ + m_graph = graph; +} + +// ---------- + +inline int PathNode::getIndex ( void ) const +{ + return m_index; +} + +inline void PathNode::setIndex ( int newIndex ) +{ + m_index = newIndex; +} + +// ---------- + +inline int PathNode::getId ( void ) const +{ + return m_id; +} + +inline void PathNode::setId ( int newId ) +{ + m_id = newId; +} + +// ---------- + +inline int PathNode::getKey ( void ) const +{ + return m_key; +} + +inline void PathNode::setKey ( int newKey ) +{ + m_key = newKey; +} + +// ---------- + +inline PathNodeType PathNode::getType ( void ) const +{ + return m_type; +} + +inline void PathNode::setType ( PathNodeType newType ) +{ + m_type = newType; +} + +// ---------- + +inline int PathNode::getPartId ( void ) const +{ + return m_partId; +} + +inline void PathNode::setPartId ( int newId ) +{ + m_partId = newId; +} + +// ---------------------------------------------------------------------- + +inline Vector const & PathNode::getPosition_p ( void ) const +{ + return m_position; +} + +inline void PathNode::setPosition_p ( Vector const & newPosition ) +{ + m_position = newPosition; +} + +// ---------- + +inline float PathNode::getRadius ( void ) const +{ + return m_radius; +} + +inline void PathNode::setRadius ( float newRadius ) +{ + m_radius = newRadius; +} + +// ---------------------------------------------------------------------- + +inline int PathNode::getUserId ( void ) const +{ + return m_userId; +} + +inline void PathNode::setUserId ( int newId ) const +{ + m_userId = newId; +} + +// ---------- + +inline int PathNode::getMark ( int whichMark ) const +{ + return m_marks[whichMark]; +} + +inline void PathNode::setMark ( int whichMark, int newMark ) const +{ + m_marks[whichMark] = newMark; +} + +inline void PathNode::clearMarks ( void ) const +{ + m_marks[0] = -1; + m_marks[1] = -1; + m_marks[2] = -1; + m_marks[3] = -1; +} + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp b/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp new file mode 100644 index 00000000..42abd9d7 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathSearch.cpp @@ -0,0 +1,652 @@ +// ====================================================================== +// +// PathSearch.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "sharedPathfinding/PathSearch.h" + +#include "sharedFoundation/ExitChain.h" +#include "sharedFoundation/MemoryBlockManager.h" +#include "sharedFoundation/MemoryBlockManagerMacros.h" + +#include "sharedDebug/PerformanceTimer.h" + +#include "sharedPathfinding/PathGraph.h" +#include "sharedPathfinding/PathNode.h" +#include "sharedPathfinding/PathEdge.h" + +#include +#include + +const float BIG_HEURISTIC = 1000000000.0f; + +// ====================================================================== + +size_t PathNodeHasher::operator() ( PathNode const * node ) const +{ + return reinterpret_cast(node); +} + +// ---------------------------------------------------------------------- + +class PathSearchNode +{ + MEMORY_BLOCK_MANAGER_INTERFACE_WITH_INSTALL; + +public: + + PathSearchNode( PathSearch * search, PathGraph const * graph, PathNode const * node ); + + int getNeighborCount ( void ); + + PathNode const * getPathNode ( void ) const + { + return m_node; + } + + int getPathNodeIndex ( void ) const + { + return m_node->getIndex(); + } + + PathSearchNode * getNeighbor ( int whichNeighbor ); + + // ---------- + + PathSearchNode * getParent ( void ) const + { + return m_parent; + } + + void setParent ( PathSearchNode * newParent ) + { + m_parent = newParent; + } + + // ---------- + + float getCost ( void ) const + { + return m_cost; + } + + void setCost ( float newCost ) + { + m_cost = newCost; + m_total = m_cost + m_heuristic; + } + + float getTotal ( void ) const + { + return m_total; + } + + // ---------- + + bool isQueued ( void ) + { + return m_queued; + } + + void setQueued ( bool queued ) + { + m_queued = queued; + } + + // ---------- + + void setPathIndex ( int index ) + { + m_pathIndex = index; + } + + int getPathIndex ( void ) const + { + return m_pathIndex; + } + + // ---------- + + PathSearchNode * getSearchNode ( PathNode const * node ); + PathSearchNode * createSearchNode ( PathNode const * node ); + + // ---------- + +protected: + + PathSearch * m_search; + PathSearchNode * m_parent; + PathGraph const * m_graph; + PathNode const * m_node; + + bool m_queued; + + float m_cost; + float m_heuristic; + float m_total; + + int m_pathIndex; +}; + +MEMORY_BLOCK_MANAGER_IMPLEMENTATION_WITH_INSTALL(PathSearchNode, true, 0, 0, 0); + +// ---------- + +PathSearchNode::PathSearchNode ( PathSearch * search, PathGraph const * graph, PathNode const * node ) +: m_search(search), + m_parent(NULL), + m_graph(graph), + m_node(node), + m_queued(false), + m_cost(REAL_MAX), + m_heuristic(0.0f), + m_total(REAL_MAX), + m_pathIndex(-1) +{ + m_heuristic = m_search->calcHeuristic(m_node); +} + +// ---------------------------------------------------------------------- + +int PathSearchNode::getNeighborCount ( void ) +{ + return m_graph->getEdgeCount( m_node->getIndex() ); +} + +// ---------- + +PathSearchNode * PathSearchNode::getNeighbor ( int whichNeighbor ) +{ + int neighborIndex = m_graph->getEdge( m_node->getIndex(), whichNeighbor )->getIndexB(); + + PathNode const * neighborNode = m_graph->getNode(neighborIndex); + + if(neighborNode != NULL) + { + return getSearchNode(neighborNode); + } + else + { + return NULL; + } +} + +// ---------------------------------------------------------------------- + +PathSearchNode * PathSearchNode::createSearchNode( PathNode const * node ) +{ + // doing bad voodoo with the node marks + + PathSearchNode * oldNode = NULL; + + int mark = node->getMark(3); + + if(mark != -1) + { + oldNode = (PathSearchNode*)((void*)mark); + } + + delete oldNode; + + PathSearchNode * searchNode = new PathSearchNode(m_search,m_graph,node); + + node->setMark( 3, (int)((void*)searchNode) ); + + m_search->m_visitedNodes->push_back(node); + + return searchNode; +} + +// ---------- + +PathSearchNode * PathSearchNode::getSearchNode( PathNode const * node ) +{ + // doing bad voodoo with the node marks + + PathSearchNode * searchNode = NULL; + + int mark = node->getMark(3); + + if(mark != -1) + { + searchNode = (PathSearchNode*)((void*)mark); + } + + if(searchNode == NULL) + { + return createSearchNode(node); + } + else + { + return searchNode; + } +} + +// ====================================================================== + +bool PathSearchGreater( PathSearchNode const * A, PathSearchNode const * B ) +{ + return A->getTotal() > B->getTotal(); +} + +// ====================================================================== + +class PathSearchQueue +{ +public: + + void push ( PathSearchNode * node ) + { + m_nodes.push_back(node); + + std::push_heap(m_nodes.begin(),m_nodes.end(),PathSearchGreater); + + node->setQueued(true); + } + + PathSearchNode * pop ( void ) + { + PathSearchNode * node = m_nodes.front(); + + std::pop_heap(m_nodes.begin(),m_nodes.end(),PathSearchGreater); + m_nodes.pop_back(); + + node->setQueued(false); + + return node; + } + + void update ( PathSearchNode * node ) + { + if(node->isQueued()) + { + for(uint i = 0; i < m_nodes.size(); i++) + { + if(m_nodes[i] == node) + { + std::push_heap( m_nodes.begin(), m_nodes.begin() + i + 1, PathSearchGreater ); + return; + } + } + } + else + { + push(node); + } + } + + void clear ( void ) + { + m_nodes.clear(); + } + + bool empty ( void ) + { + return m_nodes.empty(); + } + + // ---------- + +protected: + + std::vector m_nodes; +}; + +// ====================================================================== + +void PathSearch::install() +{ + PathSearchNode::install(); +} + +// ---------------------------------------------------------------------- + +PathSearch::PathSearch ( void ) +: m_graph(NULL), + m_start(NULL), + m_goal(NULL), + m_multiGoal(false), + m_goals(new NodeList()), + m_queue(new PathSearchQueue()), + m_path(new IndexList()), + m_visitedNodes(new NodeList()) +{ + m_path->reserve(20); + m_visitedNodes->reserve(20); +} + +PathSearch::~PathSearch() +{ + delete m_goals; + m_goals = NULL; + + delete m_queue; + m_queue = NULL; + + delete m_path; + m_path = NULL; + + delete m_visitedNodes; + m_visitedNodes = NULL; +} + +// ---------------------------------------------------------------------- + +PathSearchNode * PathSearch::search ( void ) +{ + PathSearchNode * startNode = new PathSearchNode(this,m_graph,m_start); + + startNode->setCost(0.0f); + startNode->setPathIndex(0); + + m_queue->push(startNode); + + while(!m_queue->empty()) + { + PathSearchNode * node = m_queue->pop(); + + if(atGoal(node)) + { + return node; + } + + // ---------- + + int neighborCount = node->getNeighborCount(); + + for(int i = 0; i < neighborCount; i++) + { + PathSearchNode * neighbor = node->getNeighbor(i); + + if(neighbor != NULL) + { + float newCost = node->getCost() + costBetween(node->getPathNode(),neighbor->getPathNode()); + + if( newCost < neighbor->getCost() ) + { + neighbor->setParent(node); + neighbor->setCost(newCost); + neighbor->setPathIndex( node->getPathIndex() + 1); + + m_queue->update(neighbor); + } + } + } + } + + return NULL; +} + +// ---------------------------------------------------------------------- + +extern float pathSearchTime; + +bool PathSearch::search ( PathGraph const * graph, int startIndex, int goalIndex ) +{ + PerformanceTimer timer; + + timer.start(); + + m_graph = graph; + m_start = graph->getNode(startIndex); + m_goal = graph->getNode(goalIndex); + m_multiGoal = false; + + if(m_start == NULL) return false; + if(m_goal == NULL) return false; + + m_path->clear(); + + PathSearchNode * endNode = search(); + + bool buildOk = buildPath(endNode); + + cleanup(); + + timer.stop(); + + pathSearchTime += timer.getElapsedTime(); + + return buildOk; +} + +// ---------------------------------------------------------------------- + +bool PathSearch::search ( PathGraph const * graph, int startIndex, IndexList const & goalIndices ) +{ + PerformanceTimer timer; + + timer.start(); + + m_graph = graph; + m_start = graph->getNode(startIndex); + + m_multiGoal = true; + + int goalCount = goalIndices.size(); + + if(goalCount == 0) return false; + if(m_start == NULL) return false; + + m_goals->resize(goalCount); + + for(int i = 0; i < goalCount; i++) + { + m_goals->at(i) = graph->getNode(goalIndices[i]); + } + + PathSearchNode * endNode = search(); + + bool buildOk = buildPath(endNode); + + cleanup(); + + timer.stop(); + + pathSearchTime += timer.getElapsedTime(); + + return buildOk; +} + +// ---------------------------------------------------------------------- + +bool PathSearch::buildPath ( PathSearchNode * endNode ) +{ + if( endNode == NULL ) + { + m_path->clear(); + return false; + } + + // ---------- + + int pathLength = endNode->getPathIndex() + 1; + + m_path->resize(pathLength); + + PathSearchNode * cursor = endNode; + + while(cursor) + { + int pathIndex = cursor->getPathIndex(); + int nodeIndex = cursor->getPathNodeIndex(); + + m_path->at(pathIndex) = nodeIndex; + + cursor = cursor->getParent(); + } + + return true; +} + + +// ---------------------------------------------------------------------- + +void PathSearch::cleanup ( void ) +{ + int visitedCount = m_visitedNodes->size(); + + for(int i = 0; i < visitedCount; i++) + { + PathNode const * visitedNode = m_visitedNodes->at(i); + + int mark = visitedNode->getMark(3); + + if(mark != -1) + { + PathSearchNode * searchNode = (PathSearchNode*)((void*)mark); + + delete searchNode; + } + + visitedNode->clearMarks(); + } + + m_queue->clear(); + m_goals->clear(); + m_visitedNodes->clear(); + + m_multiGoal = false; +} + +// ---------------------------------------------------------------------- + +float PathSearch::costBetween ( PathNode const * A, PathNode const * B ) const +{ + if(m_graph->getType() == PGT_Building) + { + if(A->getType() == PNT_BuildingCell) + { + return BIG_HEURISTIC; + } + + if(B->getType() == PNT_BuildingCell) + { + return BIG_HEURISTIC; + } + + return 1.0f; + } + else + { + Vector posA = A->getPosition_p(); + Vector posB = B->getPosition_p(); + + posA.y = 0; + posB.y = 0; + + float dist = posA.magnitudeBetween(posB); + + return dist; + } +} + +// ---------------------------------------------------------------------- + +float PathSearch::calcHeuristic ( PathNode const * A ) const +{ + if(!m_graph) return BIG_HEURISTIC; + + if(m_multiGoal) + { + int minGoal = -1; + float minHeuristic = REAL_MAX; + + int goalCount = m_goals->size(); + + for(int i = 0; i < goalCount; i++) + { + PathNode const * goal = m_goals->at(i); + + float heuristic = calcHeuristic(A,goal); + + if(heuristic < minHeuristic) + { + minHeuristic = heuristic; + minGoal = i; + } + } + + if(minGoal != -1) + { + return minHeuristic; + } + else + { + return BIG_HEURISTIC; + } + } + else + { + return calcHeuristic(A,m_goal); + } +} + +// ---------------------------------------------------------------------- + +float PathSearch::calcHeuristic ( PathNode const * A, PathNode const * goal ) const +{ + if(m_graph->getType() == PGT_Building) + { + // HACK - Exporter versions 2.136 and earlier created building graph + // edges connected to cell 0, which is incorrect since cell 0 represents + // the outside of the building. + + // Get around this by making any edge connected to the graph node + // for cell 0 have a huge heuristic. + + if(m_goal->getType() == PNT_BuildingCell) + { + if(m_goal->getKey() == 0) + { + return BIG_HEURISTIC; + } + } + + if(A->getType() == PNT_BuildingCell) + { + if(A->getKey() == 0) + { + return BIG_HEURISTIC; + } + } + + return 0; + } + else + { + return costBetween(A,goal) * 3.0f; + } +} + +// ---------------------------------------------------------------------- + +IndexList const & PathSearch::getPath ( void ) const +{ + return *m_path; +} + +// ---------------------------------------------------------------------- + +bool PathSearch::atGoal ( PathSearchNode * searchNode ) const +{ + if(searchNode == NULL) return false; + + if(m_multiGoal) + { + PathNode const * pathNode = searchNode->getPathNode(); + + if(pathNode == NULL) return false; + + return std::find( m_goals->begin(), m_goals->end(), pathNode ) != m_goals->end(); + } + else + { + return m_goal && (m_goal == searchNode->getPathNode()); + } +} + +// ---------------------------------------------------------------------- diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathSearch.h b/engine/shared/library/sharedPathfinding/src/shared/PathSearch.h new file mode 100644 index 00000000..6f0b4767 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathSearch.h @@ -0,0 +1,83 @@ +// ====================================================================== +// +// PathSearch.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_PathSearch_H +#define INCLUDED_PathSearch_H + +class PathGraph; +class PathNode; +class PathSearch; +class PathSearchNode; +class PathSearchQueue; + + +struct PathNodeHasher +{ + size_t operator() ( PathNode const * node ) const; +}; + +typedef stdvector::fwd IndexList; +typedef stdvector::fwd NodeList; + +// ====================================================================== + +class PathSearch +{ +public: + + PathSearch(); + ~PathSearch(); + + static void install ( void ); + + // ---------- + + bool search ( PathGraph const * graph, int startIndex, int goalIndex ); + + bool search ( PathGraph const * graph, int startIndex, IndexList const & goalIndices ); + + IndexList const & getPath ( void ) const; + +protected: + + PathSearchNode * search ( void ); + + float costBetween ( PathNode const * A, PathNode const * B ) const; + + float calcHeuristic ( PathNode const * A ) const; + float calcHeuristic ( PathNode const * A, PathNode const * goal ) const; + + void cleanup ( void ); + + bool buildPath ( PathSearchNode * endNode ); + + bool atGoal ( PathSearchNode * endNode ) const; + + // ---------- + + friend class PathSearchNode; + + PathGraph const * m_graph; + PathNode const * m_start; + + PathNode const * m_goal; + + bool m_multiGoal; + NodeList * m_goals; + + PathSearchQueue * m_queue; + + IndexList * m_path; + + NodeList * m_visitedNodes; +}; + +// ====================================================================== + +#endif // INCLUDED_PathSearch_H + diff --git a/engine/shared/library/sharedPathfinding/src/shared/Pathfinding.cpp b/engine/shared/library/sharedPathfinding/src/shared/Pathfinding.cpp new file mode 100644 index 00000000..dc532a9a --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/Pathfinding.cpp @@ -0,0 +1,94 @@ +// ====================================================================== +// +// Pathfinding.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "sharedPathfinding/Pathfinding.h" + +#include "sharedCollision/Floor.h" +#include "sharedCollision/FloorMesh.h" +#include "sharedCollision/FloorManager.h" + +#include "sharedFile/Iff.h" + +#include "sharedObject/CellProperty.h" + +#include "sharedPathfinding/PathSearch.h" +#include "sharedPathfinding/SimplePathGraph.h" + +const Tag TAG_PGRF = TAG(P,G,R,F); +const Tag TAG_PNOD = TAG(P,N,O,D); + +// ====================================================================== + +void Pathfinding::install ( void ) +{ + FloorManager::setPathGraphFactory( &Pathfinding::graphFactory ); + FloorManager::setPathGraphWriter( &Pathfinding::graphWriter ); + FloorManager::setPathGraphRenderer( &Pathfinding::graphRenderer ); + + PathSearch::install(); +} + +// ---------- + +void Pathfinding::remove ( void ) +{ +} + +// ---------- + +BaseClass * Pathfinding::graphFactory ( Iff & iff ) +{ + if(iff.getCurrentName() == TAG_PGRF) + { + SimplePathGraph * graph = new SimplePathGraph(); + + graph->read(iff); + + graph->setPartTags(); + + return graph; + } + else if(iff.getCurrentName() == TAG_PNOD) + { + // This is an old IFF, the path information isn't in a PGRF form. + + SimplePathGraph * graph = new SimplePathGraph(); + + graph->read_old(iff); + + graph->setPartTags(); + + return graph; + } + else + { + DEBUG_WARNING(true,("Pathfinding::graphFactory - Don't know how to construct a path graph from the IFF in %s\n",iff.getFileName())); + + return NULL; + } +} + +// ---------- + +void Pathfinding::graphWriter ( BaseClass const * baseGraph, Iff & iff ) +{ + SimplePathGraph const * graph = safe_cast(baseGraph); + + graph->write(iff); +} + +// ---------- + +void Pathfinding::graphRenderer ( BaseClass const * baseGraph, DebugShapeRenderer * renderer ) +{ + PathGraph const * graph = safe_cast(baseGraph); + + graph->drawDebugShapes(renderer); +} + +// ====================================================================== diff --git a/engine/shared/library/sharedPathfinding/src/shared/Pathfinding.h b/engine/shared/library/sharedPathfinding/src/shared/Pathfinding.h new file mode 100644 index 00000000..3cc84542 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/Pathfinding.h @@ -0,0 +1,36 @@ +// ====================================================================== +// +// Pathfinding.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_Pathfinding_H +#define INCLUDED_Pathfinding_H + +class CellProperty; +class BaseClass; +class Iff; +class DebugShapeRenderer; + +// ====================================================================== + +class Pathfinding +{ +public: + + static void install ( void ); + static void remove ( void ); + + static void setupCell ( CellProperty const * newCell ); + + static BaseClass * graphFactory ( Iff & iff ); + static void graphWriter ( BaseClass const * baseGraph, Iff & iff ); + static void graphRenderer ( BaseClass const * baseGraph, DebugShapeRenderer * renderer ); +}; + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/shared/PathfindingEnums.h b/engine/shared/library/sharedPathfinding/src/shared/PathfindingEnums.h new file mode 100644 index 00000000..3e864f49 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/PathfindingEnums.h @@ -0,0 +1,69 @@ +// ====================================================================== +// +// PathfindingEnums.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_PathfindingEnums_H +#define INCLUDED_PathfindingEnums_H + +// ====================================================================== + +enum PathGraphType +{ + PGT_Cell, + PGT_Building, + PGT_City, + + PGT_None, +}; + +// ---------- + +enum PathNodeType +{ + // node types for cell graphs + + PNT_CellPortal = 0, + PNT_CellWaypoint = 1, + PNT_CellPOI = 2, + + // node types for building graphs + + PNT_BuildingEntrance = 3, + PNT_BuildingCell = 4, + PNT_BuildingPortal = 5, + + // node types for city graphs + + PNT_CityBuildingEntrance = 6, + PNT_CityWaypoint = 7, + PNT_CityPOI = 8, + PNT_CityBuilding = 9, + PNT_CityEntrance = 10, // the city gates, in a sense + + // new node type to represent one contiguous piece of a cell + + PNT_BuildingCellPart = 11, + + PNT_Invalid = 12, +}; + +// ---------- + +enum PathBuildResult +{ + PBR_OK, + PBR_Unreachable, + PBR_Incomplete, +}; + + + + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/shared/SetupSharedPathfinding.cpp b/engine/shared/library/sharedPathfinding/src/shared/SetupSharedPathfinding.cpp new file mode 100644 index 00000000..304f3504 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/SetupSharedPathfinding.cpp @@ -0,0 +1,172 @@ +// ====================================================================== +// +// SetupSharedPathfinding.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "sharedPathfinding/SetupSharedPathfinding.h" + +#include "sharedDebug/InstallTimer.h" +#include "sharedCollision/FloorMesh.h" +#include "sharedObject/PortalPropertyTemplate.h" +#include "sharedPathfinding/ConfigSharedPathfinding.h" +#include "sharedPathfinding/PathEdge.h" +#include "sharedPathfinding/Pathfinding.h" +#include "sharedPathfinding/PathNode.h" +#include "sharedPathfinding/SimplePathGraph.h" + +#include +#include + +typedef BaseClass * (*ExpandBuildingGraphHook)( PortalPropertyTemplate * portalTemplate, BaseClass * baseBuildingGraph ); + +BaseClass * expandBuildingGraph ( PortalPropertyTemplate * portalTemplate, BaseClass * baseBuildingGraph ); + +void SetupSharedPathfinding::install ( void ) +{ + InstallTimer const installTimer("SetupSharedPathfinding::install"); + + ConfigSharedPathfinding::install(); + Pathfinding::install(); + + PortalPropertyTemplate::setExpandBuildingGraphHook(expandBuildingGraph); +} + +void SetupSharedPathfinding::remove ( void ) +{ +} + +// ---------------------------------------------------------------------- + +int findNeighbor ( PathNode * node, PathNodeType neighborType, int neighborKey ) +{ + int nodeIndex = node->getIndex(); + + PathGraph * graph = node->getGraph(); + + int neighborCount = graph->getEdgeCount(nodeIndex); + + for(int i = 0; i < neighborCount; i++) + { + PathNode * neighbor = graph->getNeighbor(nodeIndex,i); + + if((neighbor->getType() == neighborType) && (neighbor->getKey() == neighborKey)) + { + return neighbor->getIndex(); + } + } + + return -1; +} + +// ---------------------------------------------------------------------- +// Expand the building graph by creating BuildingCellPart nodes for all +// parts of the cell graph in each cell + +BaseClass * expandBuildingGraph ( PortalPropertyTemplate * portalTemplate, BaseClass * baseBuildingGraph ) +{ + if(baseBuildingGraph == NULL) return NULL; + + SimplePathGraph * buildingGraph = safe_cast(baseBuildingGraph); + + SimplePathGraph::NodeList * newBuildingNodes = new SimplePathGraph::NodeList( buildingGraph->getNodes() ); + SimplePathGraph::EdgeList * newBuildingEdges = new SimplePathGraph::EdgeList( buildingGraph->getEdges() ); + + // ---------- + + int buildingNodeCount = buildingGraph->getNodeCount(); + + for(int iBuildingNode = 0; iBuildingNode < buildingNodeCount; iBuildingNode++) + { + PathNode * buildingCellNode = buildingGraph->getNode(iBuildingNode); + + if(buildingCellNode->getType() != PNT_BuildingCell) continue; + + // ---------- + + int cellIndex = buildingCellNode->getKey(); + + PortalPropertyTemplateCell const * cell = &portalTemplate->getCell(cellIndex); + + FloorMesh const * floorMesh = cell->getFloorMesh(); + + if(floorMesh == NULL) continue; + + PathGraph const * cellGraph = safe_cast(floorMesh->getPathGraph()); + + if(cellGraph == NULL) continue; + + // ---------- + + int cellPartCount = cellGraph->getPartCount(); + + for(int i = 0; i < cellPartCount; i++) + { + int partNodeIndex = newBuildingNodes->size(); + + newBuildingNodes->resize(newBuildingNodes->size() + 1); + + PathNode & partNode = newBuildingNodes->back(); + + partNode.setType(PNT_BuildingCellPart); + partNode.setPosition_p(buildingCellNode->getPosition_p()); + partNode.setKey(buildingCellNode->getKey()); + partNode.setId(i); + + // ---------- + // search through the nodes in the cell graph, add the indices of all + // portals that have a portal node in this part of the graph to our + // portal id set + + typedef std::set IntSet; + + IntSet portalIds; + + for(int j = 0; j < cellGraph->getNodeCount(); j++) + { + PathNode const * cellNode = cellGraph->getNode(j); + + NOT_NULL(cellNode); + + if((cellNode->getPartId() == i) && (cellNode->getType() == PNT_CellPortal)) + { + portalIds.insert(cellNode->getKey()); + } + } + + // ---------- + // for each portal ID in the set, find the neighboring BuildingPortal node + // of the BuildingCell node that corresponds with that ID, and add path + // edges for it + + for(IntSet::iterator it = portalIds.begin(); it != portalIds.end(); ++it) + { + int portalId = *it; + + int portalNodeIndex = findNeighbor(buildingCellNode,PNT_BuildingPortal,portalId); + + if(portalNodeIndex == -1) portalNodeIndex = findNeighbor(buildingCellNode,PNT_BuildingEntrance,portalId); + + if(portalNodeIndex != -1) + { + newBuildingEdges->push_back( PathEdge(partNodeIndex,portalNodeIndex) ); + newBuildingEdges->push_back( PathEdge(portalNodeIndex,partNodeIndex) ); + } + } + + // and add a link from the building cell node to the building cell part node + + newBuildingEdges->push_back( PathEdge(iBuildingNode,partNodeIndex) ); + } + } + + // ---------- + + SimplePathGraph * newBuildingGraph = new SimplePathGraph ( newBuildingNodes, newBuildingEdges ); + + newBuildingGraph->setType(PGT_Building); + + return newBuildingGraph; +} diff --git a/engine/shared/library/sharedPathfinding/src/shared/SetupSharedPathfinding.h b/engine/shared/library/sharedPathfinding/src/shared/SetupSharedPathfinding.h new file mode 100644 index 00000000..ca9d9364 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/SetupSharedPathfinding.h @@ -0,0 +1,25 @@ +// ====================================================================== +// +// SetupSharedPathfinding.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_SetupSharedPathfinding_H +#define INCLUDED_SetupSharedPathfinding_H + +// ====================================================================== + +class SetupSharedPathfinding +{ +public: + + static void install ( void ); + static void remove ( void ); +}; + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/shared/SimplePathGraph.cpp b/engine/shared/library/sharedPathfinding/src/shared/SimplePathGraph.cpp new file mode 100644 index 00000000..d408d035 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/SimplePathGraph.cpp @@ -0,0 +1,579 @@ +// ====================================================================== +// +// PathGraph.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" +#include "sharedPathfinding/SimplePathGraph.h" + +#include "sharedCollision/ConfigSharedCollision.h" +#include "sharedCollision/FloorMesh.h" +#include "sharedCollision/FloorLocator.h" + +#include "sharedFile/Iff.h" + +#include "sharedMath/DebugShapeRenderer.h" +#include "sharedMath/Sphere.h" + +#include "sharedPathfinding/PathNode.h" +#include "sharedPathfinding/PathEdge.h" + +#include +#include + +const Tag TAG_PGRF = TAG(P,G,R,F); +const Tag TAG_PNOD = TAG(P,N,O,D); +const Tag TAG_PEDG = TAG(P,E,D,G); +const Tag TAG_ECNT = TAG(E,C,N,T); +const Tag TAG_ESTR = TAG(E,S,T,R); +const Tag TAG_META = TAG(M,E,T,A); + +// ---------------------------------------------------------------------- + +template +void readArray_Class ( Iff & iff, T * & array, Tag tag ) +{ + iff.enterChunk(tag); + { + int count = iff.read_int32(); + + if(array == NULL) array = new T(); + + array->resize(count); + + for(int i = 0; i < count; i++) + { + array->at(i).read(iff); + } + } + iff.exitChunk(tag); +} + +template +void readArray_Class ( Iff & iff, T * & array, Tag tag, Reader R ) +{ + iff.enterChunk(tag); + { + int count = iff.read_int32(); + + if(array == NULL) array = new T(); + + array->resize(count); + + for(int i = 0; i < count; i++) + { + (array->at(i).*R)(iff); + } + } + iff.exitChunk(tag); +} + +template +void readArray_Struct ( Iff & iff, T * & array, Tag tag ) +{ + iff.enterChunk(tag); + { + int count = iff.read_int32(); + + if(array == NULL) array = new T(); + + array->resize(count); + + for(int i = 0; i < count; i++) + { + // bleh. hacky. + + uint8 * bytes = reinterpret_cast(&array->at(i)); + + iff.read_uint8( sizeof(typename T::value_type), bytes ); + } + } + iff.exitChunk(tag); +} + +// ---------------------------------------------------------------------- + +template +void writeArray_Class ( Iff & iff, T * array, Tag tag ) +{ + iff.insertChunk(tag); + { + int count = array->size(); + + iff.insertChunkData(count); + + for(int i = 0; i < count; i++) + { + array->at(i).write(iff); + } + } + iff.exitChunk(tag); +} + +template +void writeArray_Class ( Iff & iff, T * array, Tag tag, Writer W ) +{ + iff.insertChunk(tag); + { + int count = array->size(); + + iff.insertChunkData(count); + + for(int i = 0; i < count; i++) + { + (array->at(i).*W)(iff); + } + } + iff.exitChunk(tag); +} + +template +void writeArray_Struct ( Iff & iff, T * array, Tag tag ) +{ + iff.insertChunk(tag); + { + int count = array->size(); + + iff.insertChunkData(count); + + for(int i = 0; i < count; i++) + { + iff.insertChunkData( array->at(i) ); + } + } + iff.exitChunk(tag); +} + +// ====================================================================== + +SimplePathGraph::SimplePathGraph ( PathGraphType type ) +: PathGraph( type ), + m_nodes( new SimplePathGraph::NodeList() ), + m_edges( new SimplePathGraph::EdgeList() ), + m_edgeCounts( new IndexList() ), + m_edgeStarts( new IndexList() ) +{ +#ifdef _DEBUG + + m_debugLines = NULL; + +#endif +} + +SimplePathGraph::SimplePathGraph( SimplePathGraph::NodeList * nodes, SimplePathGraph::EdgeList * edges, PathGraphType type ) +: PathGraph( type ), + m_nodes( nodes ), + m_edges( edges ), + m_edgeCounts( new IndexList() ), + m_edgeStarts( new IndexList() ) +{ + int nodeCount = nodes->size(); + + for(int i = 0; i < nodeCount; i++) + { + nodes->at(i).setGraph(this); + nodes->at(i).setIndex(i); + } + + buildIndexTables(); + +#ifdef _DEBUG + + m_debugLines = NULL; + +#endif +} + +SimplePathGraph::~SimplePathGraph() +{ + delete m_nodes; + m_nodes = NULL; + + delete m_edges; + m_edges = NULL; + + delete m_edgeCounts; + m_edgeCounts = NULL; + + delete m_edgeStarts; + m_edgeStarts = NULL; + +#ifdef _DEBUG + + delete m_debugLines; + m_debugLines = NULL; + +#endif +} + +// ---------- + +void SimplePathGraph::clear ( void ) +{ + m_nodes->clear(); + m_edges->clear(); + m_edgeCounts->clear(); + m_edgeStarts->clear(); + +#ifdef _DEBUG + + if(m_debugLines) m_debugLines->clear(); + +#endif +} + +// ---------------------------------------------------------------------- + +void SimplePathGraph::buildIndexTables ( void ) +{ + std::sort( m_edges->begin(), m_edges->end() ); + + m_edgeCounts->clear(); + m_edgeStarts->clear(); + + m_edgeCounts->resize(m_nodes->size(),0); + m_edgeStarts->resize(m_nodes->size(),-1); + + int edgeCount = m_edges->size(); + + int i; + + for(i = 0; i < edgeCount; i++) + { + int node = m_edges->at(i).getIndexA(); + + m_edgeCounts->at(node)++; + + if(m_edgeStarts->at(node) == -1) + { + m_edgeStarts->at(node) = i; + } + } +} + +// ---------------------------------------------------------------------- + +int SimplePathGraph::getNodeCount ( void ) const +{ + return m_nodes->size(); +} + +PathNode * SimplePathGraph::getNode ( int nodeIndex ) +{ + if (static_cast(nodeIndex) < m_nodes->size()) + return &m_nodes->at(nodeIndex); + + return NULL; +} + +PathNode const * SimplePathGraph::getNode ( int nodeIndex ) const +{ + if (static_cast(nodeIndex) < m_nodes->size()) + return &m_nodes->at(nodeIndex); + + return NULL; +} + +// ---------------------------------------------------------------------- + +int SimplePathGraph::getEdgeCount ( int nodeIndex ) const +{ + return m_edgeCounts->at(nodeIndex); +} + +PathEdge * SimplePathGraph::getEdge ( int nodeIndex, int edgeIndex ) +{ + return &m_edges->at( m_edgeStarts->at(nodeIndex) + edgeIndex ); +} + +PathEdge const * SimplePathGraph::getEdge ( int nodeIndex, int edgeIndex ) const +{ + return &m_edges->at( m_edgeStarts->at(nodeIndex) + edgeIndex ); +} + +// ---------------------------------------------------------------------- + +void SimplePathGraph::read ( Iff & iff ) +{ + clear(); + + // ---------- + + iff.enterForm(TAG_PGRF); + + switch (iff.getCurrentName()) + { + case TAG_0000: + m_version = 0; + read_0000(iff); + break; + + case TAG_0001: + m_version = 1; + read_0001(iff); + break; + + default: + FATAL(true,("SimplePathGraph::read - Invalid version")); + break; + } + + iff.exitForm(TAG_PGRF); + + // ---------- + // Looks like the graph type isn't getting saved out. Patch it up at runtime + + if(getNodeCount() > 0) + { + PathNode const * node = getNode(0); + + PathNodeType type = node->getType(); + + if(type == PNT_CellPortal || type == PNT_CellWaypoint || type == PNT_CellPOI) + { + setType(PGT_Cell); + } + else if(type == PNT_BuildingEntrance || type == PNT_BuildingCell || type == PNT_BuildingPortal || type == PNT_BuildingCellPart) + { + setType(PGT_Building); + } + else if(type == PNT_CityBuildingEntrance || type == PNT_CityWaypoint || type == PNT_CityPOI || type == PNT_CityBuilding || type == PNT_CityEntrance) + { + setType(PGT_City); + } + else + { + setType(PGT_None); + } + } + + // ---------- + + int nodeCount = m_nodes->size(); + + for(int i = 0; i < nodeCount; i++) + { + m_nodes->at(i).setGraph(this); + } + + // ---------- + +#ifdef _DEBUG + + if(ConfigSharedCollision::getBuildDebugData()) + { + buildDebugData(); + } + +#endif +} + +// ---------------------------------------------------------------------- +// Version 4 floor meshes stored path information in an array of floor +// locators and an array of int pairs. + +void SimplePathGraph::read_old ( Iff & iff ) +{ + clear(); + + // ---------- + + iff.enterChunk(TAG_PNOD); + { + FloorLocator loc; + + while(iff.getChunkLengthLeft()) + { + loc.read_0000(iff); + + m_nodes->push_back( PathNode(loc.getPosition_p()) ); + } + } + iff.exitChunk(TAG_PNOD); + + iff.enterChunk(TAG_PEDG); + { + while(iff.getChunkLengthLeft()) + { + int a = iff.read_int32(); + int b = iff.read_int32(); + + m_edges->push_back( PathEdge(a,b) ); + m_edges->push_back( PathEdge(b,a) ); + } + } + iff.exitChunk(TAG_PEDG); + + // ---------- + + buildIndexTables(); + +#ifdef _DEBUG + + if(ConfigSharedCollision::getBuildDebugData()) + { + buildDebugData(); + } + +#endif +} + +// ---------------------------------------------------------------------- + +void SimplePathGraph::read_0000 ( Iff & iff ) +{ + iff.enterForm(TAG_0000); + + // ---------- + + readArray_Class( iff, m_nodes, TAG_PNOD, &PathNode::read_0000 ); + + readArray_Class( iff, m_edges, TAG_PEDG, &PathEdge::read_0000 ); + + readArray_Struct( iff, m_edgeCounts, TAG_ECNT ); + + readArray_Struct( iff, m_edgeStarts, TAG_ESTR ); + + // ---------- + + iff.exitForm(TAG_0000); +} + +// ---------- + +void SimplePathGraph::read_0001 ( Iff & iff ) +{ + iff.enterForm(TAG_0001); + + // ---------- + + iff.enterChunk(TAG_META); + { + setType( static_cast(iff.read_int32()) ); + } + iff.exitChunk(TAG_META); + + readArray_Class( iff, m_nodes, TAG_PNOD, &PathNode::read_0000 ); + + readArray_Class( iff, m_edges, TAG_PEDG, &PathEdge::read_0000 ); + + readArray_Struct( iff, m_edgeCounts, TAG_ECNT ); + + readArray_Struct( iff, m_edgeStarts, TAG_ESTR ); + + // ---------- + + iff.exitForm(TAG_0001); +} + +// ---------- + +void SimplePathGraph::write ( Iff & iff ) const +{ + iff.insertForm(TAG_PGRF); + + iff.insertForm(TAG_0001); + + // ---------- + + iff.insertChunk(TAG_META); + { + iff.insertChunkData( static_cast(getType()) ); + } + iff.exitChunk(TAG_META); + + writeArray_Class( iff, m_nodes, TAG_PNOD ); + + writeArray_Class( iff, m_edges, TAG_PEDG ); + + writeArray_Struct( iff, m_edgeCounts, TAG_ECNT ); + + writeArray_Struct( iff, m_edgeStarts, TAG_ESTR ); + + // ---------- + + iff.exitForm(TAG_0001); + + iff.exitForm(TAG_PGRF); +} + +// ---------------------------------------------------------------------- + +void SimplePathGraph::drawDebugShapes ( DebugShapeRenderer * renderer ) const +{ + UNREF(renderer); + +#ifdef _DEBUG + + if(renderer == NULL) return; + + if( m_debugLines ) renderer->drawLineList( *m_debugLines, VectorArgb::solidYellow ); + + int nodeCount = getNodeCount(); + + for(int i = 0; i < nodeCount; i++) + { + PathNode const * node = getNode(i); + +// if(node->isPortalAdjacent()) +// { +// renderer->setColor( VectorArgb::solidMagenta ); +// } +// else + { + renderer->setColor( VectorArgb::solidCyan ); + } + + Vector center = node->getPosition_p() + Vector(0.0f,0.5f,0.0f); + + renderer->drawSphere( Sphere(center,0.2f) ); + } + +#endif +} + +// ---------------------------------------------------------------------- + +SimplePathGraph::NodeList const & SimplePathGraph::getNodes ( void ) const +{ + return *m_nodes; +} + +// ---------- + +SimplePathGraph::EdgeList const & SimplePathGraph::getEdges ( void ) const +{ + return *m_edges; +} + +// ---------------------------------------------------------------------- + +#ifdef _DEBUG + +void SimplePathGraph::buildDebugData ( void ) +{ + m_debugLines = new VectorList(); + + int edgeCount = m_edges->size(); + + m_debugLines->reserve(edgeCount*2); + + for(int i = 0; i < edgeCount; i++) + { + PathEdge const & edge = m_edges->at(i); + + int A = edge.getIndexA(); + int B = edge.getIndexB(); + + Vector a = getNode(A)->getPosition_p(); + Vector b = getNode(B)->getPosition_p(); + + m_debugLines->push_back( a + Vector(0.0f,0.7f,0.0f) ); + m_debugLines->push_back( b + Vector(0.0f,0.3f,0.0f) ); + } +} + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/shared/SimplePathGraph.h b/engine/shared/library/sharedPathfinding/src/shared/SimplePathGraph.h new file mode 100644 index 00000000..7772efaa --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/shared/SimplePathGraph.h @@ -0,0 +1,108 @@ +// ====================================================================== +// +// SimplePathGraph.h +// Copyright 2001 Sony Online Entertainment Inc. +// All Rights Reserved. +// +// ====================================================================== + +#ifndef INCLUDED_SimplePathGraph_H +#define INCLUDED_SimplePathGraph_H + +#include "sharedPathfinding/PathGraph.h" + +#include "sharedMath/Vector.h" + +class FloorLocator; + +typedef std::pair IndexPair; +typedef stdvector::fwd IntList; +typedef stdvector::fwd VectorList; +typedef stdvector::fwd IndexPairList; +typedef stdvector::fwd FloorLocatorList; + +// ====================================================================== +// Very simple concrete path graph class, uses base PathEdge and PathNode +// classes and stores them in a vector. + +class SimplePathGraph : public PathGraph +{ +public: + + typedef stdvector::fwd EdgeList; + typedef stdvector::fwd NodeList; + + SimplePathGraph ( PathGraphType type = PGT_None ); + + SimplePathGraph ( NodeList * nodes, EdgeList * edges, PathGraphType type = PGT_None ); + + virtual ~SimplePathGraph(); + + // ---------- + + void clear ( void ); + + // ---------- + // PathGraph interface + + virtual int getNodeCount ( void ) const; + virtual PathNode * getNode ( int nodeIndex ); + virtual PathNode const * getNode ( int nodeIndex ) const; + + virtual int getEdgeCount ( int nodeIndex ) const; + virtual PathEdge * getEdge ( int nodeIndex, int edgeIndex ); + virtual PathEdge const * getEdge ( int nodeIndex, int edgeIndex ) const; + + virtual void read ( Iff & iff ); + virtual void write ( Iff & iff ) const; + + virtual void drawDebugShapes ( DebugShapeRenderer * renderer ) const; + + // ---------- + // SimplePathGraph interface + + virtual NodeList const & getNodes ( void ) const; + virtual EdgeList const & getEdges ( void ) const; + + // ---------- + + int getVersion ( void ) const; + + void read_old ( Iff & iff ); + +protected: + + void buildIndexTables ( void ); + + void read_0000 ( Iff & iff ); + void read_0001 ( Iff & iff ); + + // ---------- + + int m_version; + + NodeList * m_nodes; + EdgeList * m_edges; + IndexList * m_edgeCounts; + IndexList * m_edgeStarts; + +#ifdef _DEBUG + + void buildDebugData ( void ); + + VectorList * m_debugLines; + +#endif +}; + +// ---------- + +inline int SimplePathGraph::getVersion ( void ) const +{ + return m_version; +} + +// ====================================================================== + +#endif + diff --git a/engine/shared/library/sharedPathfinding/src/win32/FirstSharedPathfinding.cpp b/engine/shared/library/sharedPathfinding/src/win32/FirstSharedPathfinding.cpp new file mode 100644 index 00000000..9792c261 --- /dev/null +++ b/engine/shared/library/sharedPathfinding/src/win32/FirstSharedPathfinding.cpp @@ -0,0 +1,8 @@ +// ====================================================================== +// +// FirstSharedPathfinding.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "sharedPathfinding/FirstSharedPathfinding.h" diff --git a/engine/shared/library/sharedTerrain/src/CMakeLists.txt b/engine/shared/library/sharedTerrain/src/CMakeLists.txt index 589f5d5c..b89b33ff 100644 --- a/engine/shared/library/sharedTerrain/src/CMakeLists.txt +++ b/engine/shared/library/sharedTerrain/src/CMakeLists.txt @@ -130,6 +130,7 @@ include_directories( ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedObject/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSynchronization/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/fileInterface/include/public ) diff --git a/engine/shared/library/sharedUtility/src/CMakeLists.txt b/engine/shared/library/sharedUtility/src/CMakeLists.txt index 4e8a58f0..acc44231 100644 --- a/engine/shared/library/sharedUtility/src/CMakeLists.txt +++ b/engine/shared/library/sharedUtility/src/CMakeLists.txt @@ -111,9 +111,19 @@ endif() include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/shared ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMathArchive/include/public ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedXml/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/fileInterface/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public ) add_library(sharedUtility STATIC diff --git a/engine/shared/library/sharedUtility/src/shared/CachedFileManager.cpp b/engine/shared/library/sharedUtility/src/shared/CachedFileManager.cpp index 255bef4b..30bf9486 100644 --- a/engine/shared/library/sharedUtility/src/shared/CachedFileManager.cpp +++ b/engine/shared/library/sharedUtility/src/shared/CachedFileManager.cpp @@ -205,7 +205,7 @@ void CachedFileManager::preloadSomeAssets () if (possibleExtension) { ConstCharCrcString const extension (possibleExtension + 1); - ExtensionMap::iterator iter = ms_extensionMap.find (&extension); + ExtensionMap::iterator iter = ms_extensionMap.find ((const CrcString*)&extension); if (iter == ms_extensionMap.end ()) { CachedFileInfo * const info = new CachedFileInfo (extension.getString ()); diff --git a/engine/shared/library/sharedUtility/src/shared/InteriorLayoutReaderWriter.cpp b/engine/shared/library/sharedUtility/src/shared/InteriorLayoutReaderWriter.cpp index 7aa78f09..e192e095 100644 --- a/engine/shared/library/sharedUtility/src/shared/InteriorLayoutReaderWriter.cpp +++ b/engine/shared/library/sharedUtility/src/shared/InteriorLayoutReaderWriter.cpp @@ -281,7 +281,7 @@ void InteriorLayoutReaderWriter::addObject(char const * const cellName, char con { Node * node = 0; TemporaryCrcString const cellNameCrcString(cellName, true); - NodeMap::iterator iter = m_nodeMap->find(&cellNameCrcString); + NodeMap::iterator iter = m_nodeMap->find((const CrcString*)&cellNameCrcString); if (iter != m_nodeMap->end()) node = iter->second; else