mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
Some missing from merge.
Signed-off-by: Salja <salja2012@hotmail.de>
This commit is contained in:
parent
ec939a5bce
commit
f4be15a7af
1895 changed files with 160408 additions and 53601 deletions
43
dep/recastnavigation/.gitignore
vendored
Normal file
43
dep/recastnavigation/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
## Compiled source #
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.ilk
|
||||
*.o
|
||||
*.pdb
|
||||
*.so
|
||||
|
||||
## Linux exes have no extension
|
||||
RecastDemo/Bin/RecastDemo
|
||||
|
||||
# Build directory
|
||||
RecastDemo/Build
|
||||
|
||||
# Ignore some meshes based on name
|
||||
RecastDemo/Bin/Meshes/_*
|
||||
|
||||
## Logs and databases #
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
## OS generated files #
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
## xcode specific
|
||||
*xcuserdata*
|
||||
|
||||
## SDL contrib
|
||||
RecastDemo/Contrib/SDL/*
|
||||
|
||||
## Generated doc files
|
||||
Docs/html
|
||||
46
dep/recastnavigation/DebugUtils/CMakeLists.txt
Normal file
46
dep/recastnavigation/DebugUtils/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# MaNGOS is a full featured server for World of Warcraft, supporting
|
||||
# the following clients: 1.12.x, 2.4.3, 3.2.5a, 4.2.3 and 5.4.8
|
||||
#
|
||||
# Copyright (C) 2005-2019 MaNGOS project <http://getmangos.eu>
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
# and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
|
||||
include(MacroMangosSourceGroup)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define the DebugUtils library
|
||||
file(GLOB sources Source/*.cpp)
|
||||
file(GLOB headers Include/*.h)
|
||||
|
||||
set(DebugUtils_LIB_SRCS ${sources} ${headers})
|
||||
|
||||
mangos_source_group(${DebugUtils_LIB_SRCS})
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../Detour/Include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../Recast/Include/
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build the DebugUtils library
|
||||
add_library(DebugUtils STATIC ${DebugUtils_LIB_SRCS})
|
||||
|
|
@ -1,24 +1,21 @@
|
|||
#ifndef DETOURMATH_H
|
||||
#define DETOURMATH_H
|
||||
|
||||
/**
|
||||
@defgroup detour Detour
|
||||
|
||||
Members in this module are wrappers around the standard math library
|
||||
|
||||
*/
|
||||
|
||||
#ifndef DETOURMATH_H
|
||||
#define DETOURMATH_H
|
||||
|
||||
#include <math.h>
|
||||
// This include is required because libstdc++ has problems with isfinite
|
||||
// if cmath is included before math.h.
|
||||
#include <cmath>
|
||||
|
||||
inline float dtMathFabsf(float x) { return fabsf(x); }
|
||||
inline float dtMathSqrtf(float x) { return sqrtf(x); }
|
||||
inline float dtMathFloorf(float x) { return floorf(x); }
|
||||
inline float dtMathCeilf(float x) { return ceilf(x); }
|
||||
inline float dtMathCosf(float x) { return cosf(x); }
|
||||
inline float dtMathSinf(float x) { return sinf(x); }
|
||||
inline float dtMathAtan2f(float y, float x) { return atan2f(y, x); }
|
||||
inline bool dtMathIsfinite(float x) { return std::isfinite(x); }
|
||||
#define dtMathFabs(x) fabs(x)
|
||||
#define dtMathSqrtf(x) sqrtf(x)
|
||||
#define dtMathFloorf(x) floorf(x)
|
||||
#define dtMathCeilf(x) ceilf(x)
|
||||
#define dtMathCosf(x) cosf(x)
|
||||
#define dtMathSinf(x) sinf(x)
|
||||
#define dtMathAtan2f(y, x) atan2f(y, x)
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,44 +22,43 @@
|
|||
typedef unsigned int dtStatus;
|
||||
|
||||
// High level status.
|
||||
static const unsigned int DT_FAILURE = 1u << 31; // Operation failed.
|
||||
static const unsigned int DT_SUCCESS = 1u << 30; // Operation succeed.
|
||||
static const unsigned int DT_IN_PROGRESS = 1u << 29; // Operation still in progress.
|
||||
static const unsigned int DT_FAILURE = 1u << 31; // Operation failed.
|
||||
static const unsigned int DT_SUCCESS = 1u << 30; // Operation succeed.
|
||||
static const unsigned int DT_IN_PROGRESS = 1u << 29; // Operation still in progress.
|
||||
|
||||
// Detail information for status.
|
||||
static const unsigned int DT_STATUS_DETAIL_MASK = 0x0ffffff;
|
||||
static const unsigned int DT_WRONG_MAGIC = 1 << 0; // Input data is not recognized.
|
||||
static const unsigned int DT_WRONG_VERSION = 1 << 1; // Input data is in wrong version.
|
||||
static const unsigned int DT_OUT_OF_MEMORY = 1 << 2; // Operation ran out of memory.
|
||||
static const unsigned int DT_INVALID_PARAM = 1 << 3; // An input parameter was invalid.
|
||||
static const unsigned int DT_BUFFER_TOO_SMALL = 1 << 4; // Result buffer for the query was too small to store all results.
|
||||
static const unsigned int DT_OUT_OF_NODES = 1 << 5; // Query ran out of nodes during search.
|
||||
static const unsigned int DT_PARTIAL_RESULT = 1 << 6; // Query did not reach the end location, returning best guess.
|
||||
static const unsigned int DT_ALREADY_OCCUPIED = 1 << 7; // A tile has already been assigned to the given x,y coordinate
|
||||
static const unsigned int DT_WRONG_MAGIC = 1 << 0; // Input data is not recognized.
|
||||
static const unsigned int DT_WRONG_VERSION = 1 << 1; // Input data is in wrong version.
|
||||
static const unsigned int DT_OUT_OF_MEMORY = 1 << 2; // Operation ran out of memory.
|
||||
static const unsigned int DT_INVALID_PARAM = 1 << 3; // An input parameter was invalid.
|
||||
static const unsigned int DT_BUFFER_TOO_SMALL = 1 << 4; // Result buffer for the query was too small to store all results.
|
||||
static const unsigned int DT_OUT_OF_NODES = 1 << 5; // Query ran out of nodes during search.
|
||||
static const unsigned int DT_PARTIAL_RESULT = 1 << 6; // Query did not reach the end location, returning best guess.
|
||||
|
||||
|
||||
// Returns true of status is success.
|
||||
inline bool dtStatusSucceed(dtStatus status)
|
||||
{
|
||||
return (status & DT_SUCCESS) != 0;
|
||||
return (status & DT_SUCCESS) != 0;
|
||||
}
|
||||
|
||||
// Returns true of status is failure.
|
||||
inline bool dtStatusFailed(dtStatus status)
|
||||
{
|
||||
return (status & DT_FAILURE) != 0;
|
||||
return (status & DT_FAILURE) != 0;
|
||||
}
|
||||
|
||||
// Returns true of status is in progress.
|
||||
inline bool dtStatusInProgress(dtStatus status)
|
||||
{
|
||||
return (status & DT_IN_PROGRESS) != 0;
|
||||
return (status & DT_IN_PROGRESS) != 0;
|
||||
}
|
||||
|
||||
// Returns true if specific detail is set.
|
||||
inline bool dtStatusDetail(dtStatus status, unsigned int detail)
|
||||
{
|
||||
return (status & detail) != 0;
|
||||
return (status & detail) != 0;
|
||||
}
|
||||
|
||||
#endif // DETOURSTATUS_H
|
||||
|
|
|
|||
26
dep/recastnavigation/Detour/win/Detour_VC110.sln
Normal file
26
dep/recastnavigation/Detour/win/Detour_VC110.sln
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Detour", "VC110\Detour.vcxproj", "{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|x64.Build.0 = Debug|x64
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|Win32.Build.0 = Release|Win32
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|x64.ActiveCfg = Release|x64
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
28
dep/recastnavigation/Detour/win/Detour_VC120.sln
Normal file
28
dep/recastnavigation/Detour/win/Detour_VC120.sln
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Detour", "VC120\Detour.vcxproj", "{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Debug|x64.Build.0 = Debug|x64
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|Win32.Build.0 = Release|Win32
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|x64.ActiveCfg = Release|x64
|
||||
{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
6
dep/recastnavigation/Detour/win/VC110/.gitignore
vendored
Normal file
6
dep/recastnavigation/Detour/win/VC110/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
*__Win32_Release
|
||||
*__Win32_Debug
|
||||
*__x64_Release
|
||||
*__x64_Debug
|
||||
*.user
|
||||
170
dep/recastnavigation/Detour/win/VC110/Detour.vcxproj
Normal file
170
dep/recastnavigation/Detour/win/VC110/Detour.vcxproj
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}</ProjectGuid>
|
||||
<RootNamespace>Detour</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;DEBUG;_MBCS;DT_POLYREF64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;DEBUG;_MBCS;DT_POLYREF64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_MBCS;DT_POLYREF64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_MBCS;DT_POLYREF64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\Include\DetourAlloc.h" />
|
||||
<ClInclude Include="..\..\Include\DetourAssert.h" />
|
||||
<ClInclude Include="..\..\Include\DetourCommon.h" />
|
||||
<ClInclude Include="..\..\Include\DetourMath.h" />
|
||||
<ClInclude Include="..\..\Include\DetourNavMesh.h" />
|
||||
<ClInclude Include="..\..\Include\DetourNavMeshBuilder.h" />
|
||||
<ClInclude Include="..\..\Include\DetourNavMeshQuery.h" />
|
||||
<ClInclude Include="..\..\Include\DetourNode.h" />
|
||||
<ClInclude Include="..\..\Include\DetourStatus.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\Source\DetourAlloc.cpp" />
|
||||
<ClCompile Include="..\..\Source\DetourCommon.cpp" />
|
||||
<ClCompile Include="..\..\Source\DetourNavMesh.cpp" />
|
||||
<ClCompile Include="..\..\Source\DetourNavMeshBuilder.cpp" />
|
||||
<ClCompile Include="..\..\Source\DetourNavMeshQuery.cpp" />
|
||||
<ClCompile Include="..\..\Source\DetourNode.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
60
dep/recastnavigation/Detour/win/VC110/Detour.vcxproj.filters
Normal file
60
dep/recastnavigation/Detour/win/VC110/Detour.vcxproj.filters
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
<UniqueIdentifier>{93bb99d1-034f-421d-abf2-856b22079565}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="include">
|
||||
<UniqueIdentifier>{661147bd-4839-4f24-8697-6ce5cb9b61a2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\Include\DetourAlloc.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourCommon.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourNavMesh.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourNavMeshBuilder.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourNode.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourAssert.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourNavMeshQuery.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourMath.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourStatus.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\Source\DetourAlloc.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\DetourCommon.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\DetourNavMesh.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\DetourNavMeshBuilder.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\DetourNode.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\DetourNavMeshQuery.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
dep/recastnavigation/Detour/win/VC120/.gitignore
vendored
Normal file
6
dep/recastnavigation/Detour/win/VC120/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
*__Win32_Release
|
||||
*__Win32_Debug
|
||||
*__x64_Release
|
||||
*__x64_Debug
|
||||
*.user
|
||||
170
dep/recastnavigation/Detour/win/VC120/Detour.vcxproj
Normal file
170
dep/recastnavigation/Detour/win/VC120/Detour.vcxproj
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{72BDF975-4D4A-42C7-B2C4-F9ED90A2ABB6}</ProjectGuid>
|
||||
<RootNamespace>Detour</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;DEBUG;_MBCS;DT_POLYREF64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;DEBUG;_MBCS;DT_POLYREF64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_MBCS;DT_POLYREF64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_MBCS;DT_POLYREF64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\Include\DetourAlloc.h" />
|
||||
<ClInclude Include="..\..\Include\DetourAssert.h" />
|
||||
<ClInclude Include="..\..\Include\DetourCommon.h" />
|
||||
<ClInclude Include="..\..\Include\DetourMath.h" />
|
||||
<ClInclude Include="..\..\Include\DetourNavMesh.h" />
|
||||
<ClInclude Include="..\..\Include\DetourNavMeshBuilder.h" />
|
||||
<ClInclude Include="..\..\Include\DetourNavMeshQuery.h" />
|
||||
<ClInclude Include="..\..\Include\DetourNode.h" />
|
||||
<ClInclude Include="..\..\Include\DetourStatus.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\Source\DetourAlloc.cpp" />
|
||||
<ClCompile Include="..\..\Source\DetourCommon.cpp" />
|
||||
<ClCompile Include="..\..\Source\DetourNavMesh.cpp" />
|
||||
<ClCompile Include="..\..\Source\DetourNavMeshBuilder.cpp" />
|
||||
<ClCompile Include="..\..\Source\DetourNavMeshQuery.cpp" />
|
||||
<ClCompile Include="..\..\Source\DetourNode.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
60
dep/recastnavigation/Detour/win/VC120/Detour.vcxproj.filters
Normal file
60
dep/recastnavigation/Detour/win/VC120/Detour.vcxproj.filters
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
<UniqueIdentifier>{93bb99d1-034f-421d-abf2-856b22079565}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="include">
|
||||
<UniqueIdentifier>{661147bd-4839-4f24-8697-6ce5cb9b61a2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\Include\DetourAlloc.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourCommon.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourNavMesh.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourNavMeshBuilder.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourNode.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourAssert.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourNavMeshQuery.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourMath.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\DetourStatus.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\Source\DetourAlloc.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\DetourCommon.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\DetourNavMesh.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\DetourNavMeshBuilder.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\DetourNode.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\DetourNavMeshQuery.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
450
dep/recastnavigation/DetourCrowd/Include/DetourCrowd.h
Normal file
450
dep/recastnavigation/DetourCrowd/Include/DetourCrowd.h
Normal file
|
|
@ -0,0 +1,450 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURCROWD_H
|
||||
#define DETOURCROWD_H
|
||||
|
||||
#include "DetourNavMeshQuery.h"
|
||||
#include "DetourObstacleAvoidance.h"
|
||||
#include "DetourLocalBoundary.h"
|
||||
#include "DetourPathCorridor.h"
|
||||
#include "DetourProximityGrid.h"
|
||||
#include "DetourPathQueue.h"
|
||||
|
||||
/// The maximum number of neighbors that a crowd agent can take into account
|
||||
/// for steering decisions.
|
||||
/// @ingroup crowd
|
||||
static const int DT_CROWDAGENT_MAX_NEIGHBOURS = 6;
|
||||
|
||||
/// The maximum number of corners a crowd agent will look ahead in the path.
|
||||
/// This value is used for sizing the crowd agent corner buffers.
|
||||
/// Due to the behavior of the crowd manager, the actual number of useful
|
||||
/// corners will be one less than this number.
|
||||
/// @ingroup crowd
|
||||
static const int DT_CROWDAGENT_MAX_CORNERS = 4;
|
||||
|
||||
/// The maximum number of crowd avoidance configurations supported by the
|
||||
/// crowd manager.
|
||||
/// @ingroup crowd
|
||||
/// @see dtObstacleAvoidanceParams, dtCrowd::setObstacleAvoidanceParams(), dtCrowd::getObstacleAvoidanceParams(),
|
||||
/// dtCrowdAgentParams::obstacleAvoidanceType
|
||||
static const int DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS = 8;
|
||||
|
||||
/// The maximum number of query filter types supported by the crowd manager.
|
||||
/// @ingroup crowd
|
||||
/// @see dtQueryFilter, dtCrowd::getFilter() dtCrowd::getEditableFilter(),
|
||||
/// dtCrowdAgentParams::queryFilterType
|
||||
static const int DT_CROWD_MAX_QUERY_FILTER_TYPE = 16;
|
||||
|
||||
/// Provides neighbor data for agents managed by the crowd.
|
||||
/// @ingroup crowd
|
||||
/// @see dtCrowdAgent::neis, dtCrowd
|
||||
struct dtCrowdNeighbour
|
||||
{
|
||||
int idx; ///< The index of the neighbor in the crowd.
|
||||
float dist; ///< The distance between the current agent and the neighbor.
|
||||
};
|
||||
|
||||
/// The type of navigation mesh polygon the agent is currently traversing.
|
||||
/// @ingroup crowd
|
||||
enum CrowdAgentState
|
||||
{
|
||||
DT_CROWDAGENT_STATE_INVALID, ///< The agent is not in a valid state.
|
||||
DT_CROWDAGENT_STATE_WALKING, ///< The agent is traversing a normal navigation mesh polygon.
|
||||
DT_CROWDAGENT_STATE_OFFMESH, ///< The agent is traversing an off-mesh connection.
|
||||
};
|
||||
|
||||
/// Configuration parameters for a crowd agent.
|
||||
/// @ingroup crowd
|
||||
struct dtCrowdAgentParams
|
||||
{
|
||||
float radius; ///< Agent radius. [Limit: >= 0]
|
||||
float height; ///< Agent height. [Limit: > 0]
|
||||
float maxAcceleration; ///< Maximum allowed acceleration. [Limit: >= 0]
|
||||
float maxSpeed; ///< Maximum allowed speed. [Limit: >= 0]
|
||||
|
||||
/// Defines how close a collision element must be before it is considered for steering behaviors. [Limits: > 0]
|
||||
float collisionQueryRange;
|
||||
|
||||
float pathOptimizationRange; ///< The path visibility optimization range. [Limit: > 0]
|
||||
|
||||
/// How aggresive the agent manager should be at avoiding collisions with this agent. [Limit: >= 0]
|
||||
float separationWeight;
|
||||
|
||||
/// Flags that impact steering behavior. (See: #UpdateFlags)
|
||||
unsigned char updateFlags;
|
||||
|
||||
/// The index of the avoidance configuration to use for the agent.
|
||||
/// [Limits: 0 <= value <= #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
|
||||
unsigned char obstacleAvoidanceType;
|
||||
|
||||
/// The index of the query filter used by this agent.
|
||||
unsigned char queryFilterType;
|
||||
|
||||
/// User defined data attached to the agent.
|
||||
void* userData;
|
||||
};
|
||||
|
||||
enum MoveRequestState
|
||||
{
|
||||
DT_CROWDAGENT_TARGET_NONE = 0,
|
||||
DT_CROWDAGENT_TARGET_FAILED,
|
||||
DT_CROWDAGENT_TARGET_VALID,
|
||||
DT_CROWDAGENT_TARGET_REQUESTING,
|
||||
DT_CROWDAGENT_TARGET_WAITING_FOR_QUEUE,
|
||||
DT_CROWDAGENT_TARGET_WAITING_FOR_PATH,
|
||||
DT_CROWDAGENT_TARGET_VELOCITY,
|
||||
};
|
||||
|
||||
/// Represents an agent managed by a #dtCrowd object.
|
||||
/// @ingroup crowd
|
||||
struct dtCrowdAgent
|
||||
{
|
||||
/// True if the agent is active, false if the agent is in an unused slot in the agent pool.
|
||||
bool active;
|
||||
|
||||
/// The type of mesh polygon the agent is traversing. (See: #CrowdAgentState)
|
||||
unsigned char state;
|
||||
|
||||
/// True if the agent has valid path (targetState == DT_CROWDAGENT_TARGET_VALID) and the path does not lead to the requested position, else false.
|
||||
bool partial;
|
||||
|
||||
/// The path corridor the agent is using.
|
||||
dtPathCorridor corridor;
|
||||
|
||||
/// The local boundary data for the agent.
|
||||
dtLocalBoundary boundary;
|
||||
|
||||
/// Time since the agent's path corridor was optimized.
|
||||
float topologyOptTime;
|
||||
|
||||
/// The known neighbors of the agent.
|
||||
dtCrowdNeighbour neis[DT_CROWDAGENT_MAX_NEIGHBOURS];
|
||||
|
||||
/// The number of neighbors.
|
||||
int nneis;
|
||||
|
||||
/// The desired speed.
|
||||
float desiredSpeed;
|
||||
|
||||
float npos[3]; ///< The current agent position. [(x, y, z)]
|
||||
float disp[3];
|
||||
float dvel[3]; ///< The desired velocity of the agent. [(x, y, z)]
|
||||
float nvel[3];
|
||||
float vel[3]; ///< The actual velocity of the agent. [(x, y, z)]
|
||||
|
||||
/// The agent's configuration parameters.
|
||||
dtCrowdAgentParams params;
|
||||
|
||||
/// The local path corridor corners for the agent. (Staight path.) [(x, y, z) * #ncorners]
|
||||
float cornerVerts[DT_CROWDAGENT_MAX_CORNERS*3];
|
||||
|
||||
/// The local path corridor corner flags. (See: #dtStraightPathFlags) [(flags) * #ncorners]
|
||||
unsigned char cornerFlags[DT_CROWDAGENT_MAX_CORNERS];
|
||||
|
||||
/// The reference id of the polygon being entered at the corner. [(polyRef) * #ncorners]
|
||||
dtPolyRef cornerPolys[DT_CROWDAGENT_MAX_CORNERS];
|
||||
|
||||
/// The number of corners.
|
||||
int ncorners;
|
||||
|
||||
unsigned char targetState; ///< State of the movement request.
|
||||
dtPolyRef targetRef; ///< Target polyref of the movement request.
|
||||
float targetPos[3]; ///< Target position of the movement request (or velocity in case of DT_CROWDAGENT_TARGET_VELOCITY).
|
||||
dtPathQueueRef targetPathqRef; ///< Path finder ref.
|
||||
bool targetReplan; ///< Flag indicating that the current path is being replanned.
|
||||
float targetReplanTime; /// <Time since the agent's target was replanned.
|
||||
};
|
||||
|
||||
struct dtCrowdAgentAnimation
|
||||
{
|
||||
bool active;
|
||||
float initPos[3], startPos[3], endPos[3];
|
||||
dtPolyRef polyRef;
|
||||
float t, tmax;
|
||||
};
|
||||
|
||||
/// Crowd agent update flags.
|
||||
/// @ingroup crowd
|
||||
/// @see dtCrowdAgentParams::updateFlags
|
||||
enum UpdateFlags
|
||||
{
|
||||
DT_CROWD_ANTICIPATE_TURNS = 1,
|
||||
DT_CROWD_OBSTACLE_AVOIDANCE = 2,
|
||||
DT_CROWD_SEPARATION = 4,
|
||||
DT_CROWD_OPTIMIZE_VIS = 8, ///< Use #dtPathCorridor::optimizePathVisibility() to optimize the agent path.
|
||||
DT_CROWD_OPTIMIZE_TOPO = 16, ///< Use dtPathCorridor::optimizePathTopology() to optimize the agent path.
|
||||
};
|
||||
|
||||
struct dtCrowdAgentDebugInfo
|
||||
{
|
||||
int idx;
|
||||
float optStart[3], optEnd[3];
|
||||
dtObstacleAvoidanceDebugData* vod;
|
||||
};
|
||||
|
||||
/// Provides local steering behaviors for a group of agents.
|
||||
/// @ingroup crowd
|
||||
class dtCrowd
|
||||
{
|
||||
int m_maxAgents;
|
||||
dtCrowdAgent* m_agents;
|
||||
dtCrowdAgent** m_activeAgents;
|
||||
dtCrowdAgentAnimation* m_agentAnims;
|
||||
|
||||
dtPathQueue m_pathq;
|
||||
|
||||
dtObstacleAvoidanceParams m_obstacleQueryParams[DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS];
|
||||
dtObstacleAvoidanceQuery* m_obstacleQuery;
|
||||
|
||||
dtProximityGrid* m_grid;
|
||||
|
||||
dtPolyRef* m_pathResult;
|
||||
int m_maxPathResult;
|
||||
|
||||
float m_ext[3];
|
||||
|
||||
dtQueryFilter m_filters[DT_CROWD_MAX_QUERY_FILTER_TYPE];
|
||||
|
||||
float m_maxAgentRadius;
|
||||
|
||||
int m_velocitySampleCount;
|
||||
|
||||
dtNavMeshQuery* m_navquery;
|
||||
|
||||
void updateTopologyOptimization(dtCrowdAgent** agents, const int nagents, const float dt);
|
||||
void updateMoveRequest(const float dt);
|
||||
void checkPathValidity(dtCrowdAgent** agents, const int nagents, const float dt);
|
||||
|
||||
inline int getAgentIndex(const dtCrowdAgent* agent) const { return (int)(agent - m_agents); }
|
||||
|
||||
bool requestMoveTargetReplan(const int idx, dtPolyRef ref, const float* pos);
|
||||
|
||||
void purge();
|
||||
|
||||
public:
|
||||
dtCrowd();
|
||||
~dtCrowd();
|
||||
|
||||
/// Initializes the crowd.
|
||||
/// @param[in] maxAgents The maximum number of agents the crowd can manage. [Limit: >= 1]
|
||||
/// @param[in] maxAgentRadius The maximum radius of any agent that will be added to the crowd. [Limit: > 0]
|
||||
/// @param[in] nav The navigation mesh to use for planning.
|
||||
/// @return True if the initialization succeeded.
|
||||
bool init(const int maxAgents, const float maxAgentRadius, dtNavMesh* nav);
|
||||
|
||||
/// Sets the shared avoidance configuration for the specified index.
|
||||
/// @param[in] idx The index. [Limits: 0 <= value < #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
|
||||
/// @param[in] params The new configuration.
|
||||
void setObstacleAvoidanceParams(const int idx, const dtObstacleAvoidanceParams* params);
|
||||
|
||||
/// Gets the shared avoidance configuration for the specified index.
|
||||
/// @param[in] idx The index of the configuration to retreive.
|
||||
/// [Limits: 0 <= value < #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
|
||||
/// @return The requested configuration.
|
||||
const dtObstacleAvoidanceParams* getObstacleAvoidanceParams(const int idx) const;
|
||||
|
||||
/// Gets the specified agent from the pool.
|
||||
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
||||
/// @return The requested agent.
|
||||
const dtCrowdAgent* getAgent(const int idx);
|
||||
|
||||
/// Gets the specified agent from the pool.
|
||||
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
||||
/// @return The requested agent.
|
||||
dtCrowdAgent* getEditableAgent(const int idx);
|
||||
|
||||
/// The maximum number of agents that can be managed by the object.
|
||||
/// @return The maximum number of agents.
|
||||
int getAgentCount() const;
|
||||
|
||||
/// Adds a new agent to the crowd.
|
||||
/// @param[in] pos The requested position of the agent. [(x, y, z)]
|
||||
/// @param[in] params The configutation of the agent.
|
||||
/// @return The index of the agent in the agent pool. Or -1 if the agent could not be added.
|
||||
int addAgent(const float* pos, const dtCrowdAgentParams* params);
|
||||
|
||||
/// Updates the specified agent's configuration.
|
||||
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
||||
/// @param[in] params The new agent configuration.
|
||||
void updateAgentParameters(const int idx, const dtCrowdAgentParams* params);
|
||||
|
||||
/// Removes the agent from the crowd.
|
||||
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
||||
void removeAgent(const int idx);
|
||||
|
||||
/// Submits a new move request for the specified agent.
|
||||
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
||||
/// @param[in] ref The position's polygon reference.
|
||||
/// @param[in] pos The position within the polygon. [(x, y, z)]
|
||||
/// @return True if the request was successfully submitted.
|
||||
bool requestMoveTarget(const int idx, dtPolyRef ref, const float* pos);
|
||||
|
||||
/// Submits a new move request for the specified agent.
|
||||
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
||||
/// @param[in] vel The movement velocity. [(x, y, z)]
|
||||
/// @return True if the request was successfully submitted.
|
||||
bool requestMoveVelocity(const int idx, const float* vel);
|
||||
|
||||
/// Resets any request for the specified agent.
|
||||
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
||||
/// @return True if the request was successfully reseted.
|
||||
bool resetMoveTarget(const int idx);
|
||||
|
||||
/// Gets the active agents int the agent pool.
|
||||
/// @param[out] agents An array of agent pointers. [(#dtCrowdAgent *) * maxAgents]
|
||||
/// @param[in] maxAgents The size of the crowd agent array.
|
||||
/// @return The number of agents returned in @p agents.
|
||||
int getActiveAgents(dtCrowdAgent** agents, const int maxAgents);
|
||||
|
||||
/// Updates the steering and positions of all agents.
|
||||
/// @param[in] dt The time, in seconds, to update the simulation. [Limit: > 0]
|
||||
/// @param[out] debug A debug object to load with debug information. [Opt]
|
||||
void update(const float dt, dtCrowdAgentDebugInfo* debug);
|
||||
|
||||
/// Gets the filter used by the crowd.
|
||||
/// @return The filter used by the crowd.
|
||||
inline const dtQueryFilter* getFilter(const int i) const { return (i >= 0 && i < DT_CROWD_MAX_QUERY_FILTER_TYPE) ? &m_filters[i] : 0; }
|
||||
|
||||
/// Gets the filter used by the crowd.
|
||||
/// @return The filter used by the crowd.
|
||||
inline dtQueryFilter* getEditableFilter(const int i) { return (i >= 0 && i < DT_CROWD_MAX_QUERY_FILTER_TYPE) ? &m_filters[i] : 0; }
|
||||
|
||||
/// Gets the search extents [(x, y, z)] used by the crowd for query operations.
|
||||
/// @return The search extents used by the crowd. [(x, y, z)]
|
||||
const float* getQueryExtents() const { return m_ext; }
|
||||
|
||||
/// Gets the velocity sample count.
|
||||
/// @return The velocity sample count.
|
||||
inline int getVelocitySampleCount() const { return m_velocitySampleCount; }
|
||||
|
||||
/// Gets the crowd's proximity grid.
|
||||
/// @return The crowd's proximity grid.
|
||||
const dtProximityGrid* getGrid() const { return m_grid; }
|
||||
|
||||
/// Gets the crowd's path request queue.
|
||||
/// @return The crowd's path request queue.
|
||||
const dtPathQueue* getPathQueue() const { return &m_pathq; }
|
||||
|
||||
/// Gets the query object used by the crowd.
|
||||
const dtNavMeshQuery* getNavMeshQuery() const { return m_navquery; }
|
||||
};
|
||||
|
||||
/// Allocates a crowd object using the Detour allocator.
|
||||
/// @return A crowd object that is ready for initialization, or null on failure.
|
||||
/// @ingroup crowd
|
||||
dtCrowd* dtAllocCrowd();
|
||||
|
||||
/// Frees the specified crowd object using the Detour allocator.
|
||||
/// @param[in] ptr A crowd object allocated using #dtAllocCrowd
|
||||
/// @ingroup crowd
|
||||
void dtFreeCrowd(dtCrowd* ptr);
|
||||
|
||||
|
||||
#endif // DETOURCROWD_H
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This section contains detailed documentation for members that don't have
|
||||
// a source file. It reduces clutter in the main section of the header.
|
||||
|
||||
/**
|
||||
|
||||
@defgroup crowd Crowd
|
||||
|
||||
Members in this module implement local steering and dynamic avoidance features.
|
||||
|
||||
The crowd is the big beast of the navigation features. It not only handles a
|
||||
lot of the path management for you, but also local steering and dynamic
|
||||
avoidance between members of the crowd. I.e. It can keep your agents from
|
||||
running into each other.
|
||||
|
||||
Main class: #dtCrowd
|
||||
|
||||
The #dtNavMeshQuery and #dtPathCorridor classes provide perfectly good, easy
|
||||
to use path planning features. But in the end they only give you points that
|
||||
your navigation client should be moving toward. When it comes to deciding things
|
||||
like agent velocity and steering to avoid other agents, that is up to you to
|
||||
implement. Unless, of course, you decide to use #dtCrowd.
|
||||
|
||||
Basically, you add an agent to the crowd, providing various configuration
|
||||
settings such as maximum speed and acceleration. You also provide a local
|
||||
target to more toward. The crowd manager then provides, with every update, the
|
||||
new agent position and velocity for the frame. The movement will be
|
||||
constrained to the navigation mesh, and steering will be applied to ensure
|
||||
agents managed by the crowd do not collide with each other.
|
||||
|
||||
This is very powerful feature set. But it comes with limitations.
|
||||
|
||||
The biggest limitation is that you must give control of the agent's position
|
||||
completely over to the crowd manager. You can update things like maximum speed
|
||||
and acceleration. But in order for the crowd manager to do its thing, it can't
|
||||
allow you to constantly be giving it overrides to position and velocity. So
|
||||
you give up direct control of the agent's movement. It belongs to the crowd.
|
||||
|
||||
The second biggest limitation revolves around the fact that the crowd manager
|
||||
deals with local planning. So the agent's target should never be more than
|
||||
256 polygons aways from its current position. If it is, you risk
|
||||
your agent failing to reach its target. So you may still need to do long
|
||||
distance planning and provide the crowd manager with intermediate targets.
|
||||
|
||||
Other significant limitations:
|
||||
|
||||
- All agents using the crowd manager will use the same #dtQueryFilter.
|
||||
- Crowd management is relatively expensive. The maximum agents under crowd
|
||||
management at any one time is between 20 and 30. A good place to start
|
||||
is a maximum of 25 agents for 0.5ms per frame.
|
||||
|
||||
@note This is a summary list of members. Use the index or search
|
||||
feature to find minor members.
|
||||
|
||||
@struct dtCrowdAgentParams
|
||||
@see dtCrowdAgent, dtCrowd::addAgent(), dtCrowd::updateAgentParameters()
|
||||
|
||||
@var dtCrowdAgentParams::obstacleAvoidanceType
|
||||
@par
|
||||
|
||||
#dtCrowd permits agents to use different avoidance configurations. This value
|
||||
is the index of the #dtObstacleAvoidanceParams within the crowd.
|
||||
|
||||
@see dtObstacleAvoidanceParams, dtCrowd::setObstacleAvoidanceParams(),
|
||||
dtCrowd::getObstacleAvoidanceParams()
|
||||
|
||||
@var dtCrowdAgentParams::collisionQueryRange
|
||||
@par
|
||||
|
||||
Collision elements include other agents and navigation mesh boundaries.
|
||||
|
||||
This value is often based on the agent radius and/or maximum speed. E.g. radius * 8
|
||||
|
||||
@var dtCrowdAgentParams::pathOptimizationRange
|
||||
@par
|
||||
|
||||
Only applicalbe if #updateFlags includes the #DT_CROWD_OPTIMIZE_VIS flag.
|
||||
|
||||
This value is often based on the agent radius. E.g. radius * 30
|
||||
|
||||
@see dtPathCorridor::optimizePathVisibility()
|
||||
|
||||
@var dtCrowdAgentParams::separationWeight
|
||||
@par
|
||||
|
||||
A higher value will result in agents trying to stay farther away from each other at
|
||||
the cost of more difficult steering in tight spaces.
|
||||
|
||||
*/
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURLOCALBOUNDARY_H
|
||||
#define DETOURLOCALBOUNDARY_H
|
||||
|
||||
#include "DetourNavMeshQuery.h"
|
||||
|
||||
|
||||
class dtLocalBoundary
|
||||
{
|
||||
static const int MAX_LOCAL_SEGS = 8;
|
||||
static const int MAX_LOCAL_POLYS = 16;
|
||||
|
||||
struct Segment
|
||||
{
|
||||
float s[6]; ///< Segment start/end
|
||||
float d; ///< Distance for pruning.
|
||||
};
|
||||
|
||||
float m_center[3];
|
||||
Segment m_segs[MAX_LOCAL_SEGS];
|
||||
int m_nsegs;
|
||||
|
||||
dtPolyRef m_polys[MAX_LOCAL_POLYS];
|
||||
int m_npolys;
|
||||
|
||||
void addSegment(const float dist, const float* seg);
|
||||
|
||||
public:
|
||||
dtLocalBoundary();
|
||||
~dtLocalBoundary();
|
||||
|
||||
void reset();
|
||||
|
||||
void update(dtPolyRef ref, const float* pos, const float collisionQueryRange,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
bool isValid(dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
inline const float* getCenter() const { return m_center; }
|
||||
inline int getSegmentCount() const { return m_nsegs; }
|
||||
inline const float* getSegment(int i) const { return m_segs[i].s; }
|
||||
};
|
||||
|
||||
#endif // DETOURLOCALBOUNDARY_H
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOUROBSTACLEAVOIDANCE_H
|
||||
#define DETOUROBSTACLEAVOIDANCE_H
|
||||
|
||||
struct dtObstacleCircle
|
||||
{
|
||||
float p[3]; ///< Position of the obstacle
|
||||
float vel[3]; ///< Velocity of the obstacle
|
||||
float dvel[3]; ///< Velocity of the obstacle
|
||||
float rad; ///< Radius of the obstacle
|
||||
float dp[3], np[3]; ///< Use for side selection during sampling.
|
||||
};
|
||||
|
||||
struct dtObstacleSegment
|
||||
{
|
||||
float p[3], q[3]; ///< End points of the obstacle segment
|
||||
bool touch;
|
||||
};
|
||||
|
||||
|
||||
class dtObstacleAvoidanceDebugData
|
||||
{
|
||||
public:
|
||||
dtObstacleAvoidanceDebugData();
|
||||
~dtObstacleAvoidanceDebugData();
|
||||
|
||||
bool init(const int maxSamples);
|
||||
void reset();
|
||||
void addSample(const float* vel, const float ssize, const float pen,
|
||||
const float vpen, const float vcpen, const float spen, const float tpen);
|
||||
|
||||
void normalizeSamples();
|
||||
|
||||
inline int getSampleCount() const { return m_nsamples; }
|
||||
inline const float* getSampleVelocity(const int i) const { return &m_vel[i*3]; }
|
||||
inline float getSampleSize(const int i) const { return m_ssize[i]; }
|
||||
inline float getSamplePenalty(const int i) const { return m_pen[i]; }
|
||||
inline float getSampleDesiredVelocityPenalty(const int i) const { return m_vpen[i]; }
|
||||
inline float getSampleCurrentVelocityPenalty(const int i) const { return m_vcpen[i]; }
|
||||
inline float getSamplePreferredSidePenalty(const int i) const { return m_spen[i]; }
|
||||
inline float getSampleCollisionTimePenalty(const int i) const { return m_tpen[i]; }
|
||||
|
||||
private:
|
||||
int m_nsamples;
|
||||
int m_maxSamples;
|
||||
float* m_vel;
|
||||
float* m_ssize;
|
||||
float* m_pen;
|
||||
float* m_vpen;
|
||||
float* m_vcpen;
|
||||
float* m_spen;
|
||||
float* m_tpen;
|
||||
};
|
||||
|
||||
dtObstacleAvoidanceDebugData* dtAllocObstacleAvoidanceDebugData();
|
||||
void dtFreeObstacleAvoidanceDebugData(dtObstacleAvoidanceDebugData* ptr);
|
||||
|
||||
|
||||
static const int DT_MAX_PATTERN_DIVS = 32; ///< Max numver of adaptive divs.
|
||||
static const int DT_MAX_PATTERN_RINGS = 4; ///< Max number of adaptive rings.
|
||||
|
||||
struct dtObstacleAvoidanceParams
|
||||
{
|
||||
float velBias;
|
||||
float weightDesVel;
|
||||
float weightCurVel;
|
||||
float weightSide;
|
||||
float weightToi;
|
||||
float horizTime;
|
||||
unsigned char gridSize; ///< grid
|
||||
unsigned char adaptiveDivs; ///< adaptive
|
||||
unsigned char adaptiveRings; ///< adaptive
|
||||
unsigned char adaptiveDepth; ///< adaptive
|
||||
};
|
||||
|
||||
class dtObstacleAvoidanceQuery
|
||||
{
|
||||
public:
|
||||
dtObstacleAvoidanceQuery();
|
||||
~dtObstacleAvoidanceQuery();
|
||||
|
||||
bool init(const int maxCircles, const int maxSegments);
|
||||
|
||||
void reset();
|
||||
|
||||
void addCircle(const float* pos, const float rad,
|
||||
const float* vel, const float* dvel);
|
||||
|
||||
void addSegment(const float* p, const float* q);
|
||||
|
||||
int sampleVelocityGrid(const float* pos, const float rad, const float vmax,
|
||||
const float* vel, const float* dvel, float* nvel,
|
||||
const dtObstacleAvoidanceParams* params,
|
||||
dtObstacleAvoidanceDebugData* debug = 0);
|
||||
|
||||
int sampleVelocityAdaptive(const float* pos, const float rad, const float vmax,
|
||||
const float* vel, const float* dvel, float* nvel,
|
||||
const dtObstacleAvoidanceParams* params,
|
||||
dtObstacleAvoidanceDebugData* debug = 0);
|
||||
|
||||
inline int getObstacleCircleCount() const { return m_ncircles; }
|
||||
const dtObstacleCircle* getObstacleCircle(const int i) { return &m_circles[i]; }
|
||||
|
||||
inline int getObstacleSegmentCount() const { return m_nsegments; }
|
||||
const dtObstacleSegment* getObstacleSegment(const int i) { return &m_segments[i]; }
|
||||
|
||||
private:
|
||||
|
||||
void prepare(const float* pos, const float* dvel);
|
||||
|
||||
float processSample(const float* vcand, const float cs,
|
||||
const float* pos, const float rad,
|
||||
const float* vel, const float* dvel,
|
||||
dtObstacleAvoidanceDebugData* debug);
|
||||
|
||||
dtObstacleCircle* insertCircle(const float dist);
|
||||
dtObstacleSegment* insertSegment(const float dist);
|
||||
|
||||
dtObstacleAvoidanceParams m_params;
|
||||
float m_invHorizTime;
|
||||
float m_vmax;
|
||||
float m_invVmax;
|
||||
|
||||
int m_maxCircles;
|
||||
dtObstacleCircle* m_circles;
|
||||
int m_ncircles;
|
||||
|
||||
int m_maxSegments;
|
||||
dtObstacleSegment* m_segments;
|
||||
int m_nsegments;
|
||||
};
|
||||
|
||||
dtObstacleAvoidanceQuery* dtAllocObstacleAvoidanceQuery();
|
||||
void dtFreeObstacleAvoidanceQuery(dtObstacleAvoidanceQuery* ptr);
|
||||
|
||||
|
||||
#endif // DETOUROBSTACLEAVOIDANCE_H
|
||||
146
dep/recastnavigation/DetourCrowd/Include/DetourPathCorridor.h
Normal file
146
dep/recastnavigation/DetourCrowd/Include/DetourPathCorridor.h
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOUTPATHCORRIDOR_H
|
||||
#define DETOUTPATHCORRIDOR_H
|
||||
|
||||
#include "DetourNavMeshQuery.h"
|
||||
|
||||
/// Represents a dynamic polygon corridor used to plan agent movement.
|
||||
/// @ingroup crowd, detour
|
||||
class dtPathCorridor
|
||||
{
|
||||
float m_pos[3];
|
||||
float m_target[3];
|
||||
|
||||
dtPolyRef* m_path;
|
||||
int m_npath;
|
||||
int m_maxPath;
|
||||
|
||||
public:
|
||||
dtPathCorridor();
|
||||
~dtPathCorridor();
|
||||
|
||||
/// Allocates the corridor's path buffer.
|
||||
/// @param[in] maxPath The maximum path size the corridor can handle.
|
||||
/// @return True if the initialization succeeded.
|
||||
bool init(const int maxPath);
|
||||
|
||||
/// Resets the path corridor to the specified position.
|
||||
/// @param[in] ref The polygon reference containing the position.
|
||||
/// @param[in] pos The new position in the corridor. [(x, y, z)]
|
||||
void reset(dtPolyRef ref, const float* pos);
|
||||
|
||||
/// Finds the corners in the corridor from the position toward the target. (The straightened path.)
|
||||
/// @param[out] cornerVerts The corner vertices. [(x, y, z) * cornerCount] [Size: <= maxCorners]
|
||||
/// @param[out] cornerFlags The flag for each corner. [(flag) * cornerCount] [Size: <= maxCorners]
|
||||
/// @param[out] cornerPolys The polygon reference for each corner. [(polyRef) * cornerCount]
|
||||
/// [Size: <= @p maxCorners]
|
||||
/// @param[in] maxCorners The maximum number of corners the buffers can hold.
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
/// @return The number of corners returned in the corner buffers. [0 <= value <= @p maxCorners]
|
||||
int findCorners(float* cornerVerts, unsigned char* cornerFlags,
|
||||
dtPolyRef* cornerPolys, const int maxCorners,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Attempts to optimize the path if the specified point is visible from the current position.
|
||||
/// @param[in] next The point to search toward. [(x, y, z])
|
||||
/// @param[in] pathOptimizationRange The maximum range to search. [Limit: > 0]
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
void optimizePathVisibility(const float* next, const float pathOptimizationRange,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Attempts to optimize the path using a local area search. (Partial replanning.)
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
bool optimizePathTopology(dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
bool moveOverOffmeshConnection(dtPolyRef offMeshConRef, dtPolyRef* refs,
|
||||
float* startPos, float* endPos,
|
||||
dtNavMeshQuery* navquery);
|
||||
|
||||
bool fixPathStart(dtPolyRef safeRef, const float* safePos);
|
||||
|
||||
bool trimInvalidPath(dtPolyRef safeRef, const float* safePos,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Checks the current corridor path to see if its polygon references remain valid.
|
||||
/// @param[in] maxLookAhead The number of polygons from the beginning of the corridor to search.
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
bool isValid(const int maxLookAhead, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Moves the position from the current location to the desired location, adjusting the corridor
|
||||
/// as needed to reflect the change.
|
||||
/// @param[in] npos The desired new position. [(x, y, z)]
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
/// @return Returns true if move succeeded.
|
||||
bool movePosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Moves the target from the curent location to the desired location, adjusting the corridor
|
||||
/// as needed to reflect the change.
|
||||
/// @param[in] npos The desired new target position. [(x, y, z)]
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
/// @return Returns true if move succeeded.
|
||||
bool moveTargetPosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Loads a new path and target into the corridor.
|
||||
/// @param[in] target The target location within the last polygon of the path. [(x, y, z)]
|
||||
/// @param[in] path The path corridor. [(polyRef) * @p npolys]
|
||||
/// @param[in] npath The number of polygons in the path.
|
||||
void setCorridor(const float* target, const dtPolyRef* polys, const int npath);
|
||||
|
||||
/// Gets the current position within the corridor. (In the first polygon.)
|
||||
/// @return The current position within the corridor.
|
||||
inline const float* getPos() const { return m_pos; }
|
||||
|
||||
/// Gets the current target within the corridor. (In the last polygon.)
|
||||
/// @return The current target within the corridor.
|
||||
inline const float* getTarget() const { return m_target; }
|
||||
|
||||
/// The polygon reference id of the first polygon in the corridor, the polygon containing the position.
|
||||
/// @return The polygon reference id of the first polygon in the corridor. (Or zero if there is no path.)
|
||||
inline dtPolyRef getFirstPoly() const { return m_npath ? m_path[0] : 0; }
|
||||
|
||||
/// The polygon reference id of the last polygon in the corridor, the polygon containing the target.
|
||||
/// @return The polygon reference id of the last polygon in the corridor. (Or zero if there is no path.)
|
||||
inline dtPolyRef getLastPoly() const { return m_npath ? m_path[m_npath-1] : 0; }
|
||||
|
||||
/// The corridor's path.
|
||||
/// @return The corridor's path. [(polyRef) * #getPathCount()]
|
||||
inline const dtPolyRef* getPath() const { return m_path; }
|
||||
|
||||
/// The number of polygons in the current corridor path.
|
||||
/// @return The number of polygons in the current corridor path.
|
||||
inline int getPathCount() const { return m_npath; }
|
||||
};
|
||||
|
||||
int dtMergeCorridorStartMoved(dtPolyRef* path, const int npath, const int maxPath,
|
||||
const dtPolyRef* visited, const int nvisited);
|
||||
|
||||
int dtMergeCorridorEndMoved(dtPolyRef* path, const int npath, const int maxPath,
|
||||
const dtPolyRef* visited, const int nvisited);
|
||||
|
||||
int dtMergeCorridorStartShortcut(dtPolyRef* path, const int npath, const int maxPath,
|
||||
const dtPolyRef* visited, const int nvisited);
|
||||
|
||||
#endif // DETOUTPATHCORRIDOR_H
|
||||
75
dep/recastnavigation/DetourCrowd/Include/DetourPathQueue.h
Normal file
75
dep/recastnavigation/DetourCrowd/Include/DetourPathQueue.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURPATHQUEUE_H
|
||||
#define DETOURPATHQUEUE_H
|
||||
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourNavMeshQuery.h"
|
||||
|
||||
static const unsigned int DT_PATHQ_INVALID = 0;
|
||||
|
||||
typedef unsigned int dtPathQueueRef;
|
||||
|
||||
class dtPathQueue
|
||||
{
|
||||
struct PathQuery
|
||||
{
|
||||
dtPathQueueRef ref;
|
||||
/// Path find start and end location.
|
||||
float startPos[3], endPos[3];
|
||||
dtPolyRef startRef, endRef;
|
||||
/// Result.
|
||||
dtPolyRef* path;
|
||||
int npath;
|
||||
/// State.
|
||||
dtStatus status;
|
||||
int keepAlive;
|
||||
const dtQueryFilter* filter; ///< TODO: This is potentially dangerous!
|
||||
};
|
||||
|
||||
static const int MAX_QUEUE = 8;
|
||||
PathQuery m_queue[MAX_QUEUE];
|
||||
dtPathQueueRef m_nextHandle;
|
||||
int m_maxPathSize;
|
||||
int m_queueHead;
|
||||
dtNavMeshQuery* m_navquery;
|
||||
|
||||
void purge();
|
||||
|
||||
public:
|
||||
dtPathQueue();
|
||||
~dtPathQueue();
|
||||
|
||||
bool init(const int maxPathSize, const int maxSearchNodeCount, dtNavMesh* nav);
|
||||
|
||||
void update(const int maxIters);
|
||||
|
||||
dtPathQueueRef request(dtPolyRef startRef, dtPolyRef endRef,
|
||||
const float* startPos, const float* endPos,
|
||||
const dtQueryFilter* filter);
|
||||
|
||||
dtStatus getRequestStatus(dtPathQueueRef ref) const;
|
||||
|
||||
dtStatus getPathResult(dtPathQueueRef ref, dtPolyRef* path, int* pathSize, const int maxPath);
|
||||
|
||||
inline const dtNavMeshQuery* getNavQuery() const { return m_navquery; }
|
||||
|
||||
};
|
||||
|
||||
#endif // DETOURPATHQUEUE_H
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURPROXIMITYGRID_H
|
||||
#define DETOURPROXIMITYGRID_H
|
||||
|
||||
class dtProximityGrid
|
||||
{
|
||||
int m_maxItems;
|
||||
float m_cellSize;
|
||||
float m_invCellSize;
|
||||
|
||||
struct Item
|
||||
{
|
||||
unsigned short id;
|
||||
short x,y;
|
||||
unsigned short next;
|
||||
};
|
||||
Item* m_pool;
|
||||
int m_poolHead;
|
||||
int m_poolSize;
|
||||
|
||||
unsigned short* m_buckets;
|
||||
int m_bucketsSize;
|
||||
|
||||
int m_bounds[4];
|
||||
|
||||
public:
|
||||
dtProximityGrid();
|
||||
~dtProximityGrid();
|
||||
|
||||
bool init(const int maxItems, const float cellSize);
|
||||
|
||||
void clear();
|
||||
|
||||
void addItem(const unsigned short id,
|
||||
const float minx, const float miny,
|
||||
const float maxx, const float maxy);
|
||||
|
||||
int queryItems(const float minx, const float miny,
|
||||
const float maxx, const float maxy,
|
||||
unsigned short* ids, const int maxIds) const;
|
||||
|
||||
int getItemCountAt(const int x, const int y) const;
|
||||
|
||||
inline const int* getBounds() const { return m_bounds; }
|
||||
inline float getCellSize() const { return m_cellSize; }
|
||||
};
|
||||
|
||||
dtProximityGrid* dtAllocProximityGrid();
|
||||
void dtFreeProximityGrid(dtProximityGrid* ptr);
|
||||
|
||||
|
||||
#endif // DETOURPROXIMITYGRID_H
|
||||
|
||||
1446
dep/recastnavigation/DetourCrowd/Source/DetourCrowd.cpp
Normal file
1446
dep/recastnavigation/DetourCrowd/Source/DetourCrowd.cpp
Normal file
File diff suppressed because it is too large
Load diff
137
dep/recastnavigation/DetourCrowd/Source/DetourLocalBoundary.cpp
Normal file
137
dep/recastnavigation/DetourCrowd/Source/DetourLocalBoundary.cpp
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include "DetourLocalBoundary.h"
|
||||
#include "DetourNavMeshQuery.h"
|
||||
#include "DetourCommon.h"
|
||||
#include "DetourAssert.h"
|
||||
|
||||
|
||||
dtLocalBoundary::dtLocalBoundary() :
|
||||
m_nsegs(0),
|
||||
m_npolys(0)
|
||||
{
|
||||
dtVset(m_center, FLT_MAX,FLT_MAX,FLT_MAX);
|
||||
}
|
||||
|
||||
dtLocalBoundary::~dtLocalBoundary()
|
||||
{
|
||||
}
|
||||
|
||||
void dtLocalBoundary::reset()
|
||||
{
|
||||
dtVset(m_center, FLT_MAX,FLT_MAX,FLT_MAX);
|
||||
m_npolys = 0;
|
||||
m_nsegs = 0;
|
||||
}
|
||||
|
||||
void dtLocalBoundary::addSegment(const float dist, const float* s)
|
||||
{
|
||||
// Insert neighbour based on the distance.
|
||||
Segment* seg = 0;
|
||||
if (!m_nsegs)
|
||||
{
|
||||
// First, trivial accept.
|
||||
seg = &m_segs[0];
|
||||
}
|
||||
else if (dist >= m_segs[m_nsegs-1].d)
|
||||
{
|
||||
// Further than the last segment, skip.
|
||||
if (m_nsegs >= MAX_LOCAL_SEGS)
|
||||
return;
|
||||
// Last, trivial accept.
|
||||
seg = &m_segs[m_nsegs];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Insert inbetween.
|
||||
int i;
|
||||
for (i = 0; i < m_nsegs; ++i)
|
||||
if (dist <= m_segs[i].d)
|
||||
break;
|
||||
const int tgt = i+1;
|
||||
const int n = dtMin(m_nsegs-i, MAX_LOCAL_SEGS-tgt);
|
||||
dtAssert(tgt+n <= MAX_LOCAL_SEGS);
|
||||
if (n > 0)
|
||||
memmove(&m_segs[tgt], &m_segs[i], sizeof(Segment)*n);
|
||||
seg = &m_segs[i];
|
||||
}
|
||||
|
||||
seg->d = dist;
|
||||
memcpy(seg->s, s, sizeof(float)*6);
|
||||
|
||||
if (m_nsegs < MAX_LOCAL_SEGS)
|
||||
m_nsegs++;
|
||||
}
|
||||
|
||||
void dtLocalBoundary::update(dtPolyRef ref, const float* pos, const float collisionQueryRange,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||
{
|
||||
static const int MAX_SEGS_PER_POLY = DT_VERTS_PER_POLYGON*3;
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
dtVset(m_center, FLT_MAX,FLT_MAX,FLT_MAX);
|
||||
m_nsegs = 0;
|
||||
m_npolys = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
dtVcopy(m_center, pos);
|
||||
|
||||
// First query non-overlapping polygons.
|
||||
navquery->findLocalNeighbourhood(ref, pos, collisionQueryRange,
|
||||
filter, m_polys, 0, &m_npolys, MAX_LOCAL_POLYS);
|
||||
|
||||
// Secondly, store all polygon edges.
|
||||
m_nsegs = 0;
|
||||
float segs[MAX_SEGS_PER_POLY*6];
|
||||
int nsegs = 0;
|
||||
for (int j = 0; j < m_npolys; ++j)
|
||||
{
|
||||
navquery->getPolyWallSegments(m_polys[j], filter, segs, 0, &nsegs, MAX_SEGS_PER_POLY);
|
||||
for (int k = 0; k < nsegs; ++k)
|
||||
{
|
||||
const float* s = &segs[k*6];
|
||||
// Skip too distant segments.
|
||||
float tseg;
|
||||
const float distSqr = dtDistancePtSegSqr2D(pos, s, s+3, tseg);
|
||||
if (distSqr > dtSqr(collisionQueryRange))
|
||||
continue;
|
||||
addSegment(distSqr, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool dtLocalBoundary::isValid(dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||
{
|
||||
if (!m_npolys)
|
||||
return false;
|
||||
|
||||
// Check that all polygons still pass query filter.
|
||||
for (int i = 0; i < m_npolys; ++i)
|
||||
{
|
||||
if (!navquery->isValidPolyRef(m_polys[i], filter))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,544 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#include "DetourObstacleAvoidance.h"
|
||||
#include "DetourCommon.h"
|
||||
#include "DetourMath.h"
|
||||
#include "DetourAlloc.h"
|
||||
#include "DetourAssert.h"
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
#include <new>
|
||||
|
||||
static const float DT_PI = 3.14159265f;
|
||||
|
||||
static int sweepCircleCircle(const float* c0, const float r0, const float* v,
|
||||
const float* c1, const float r1,
|
||||
float& tmin, float& tmax)
|
||||
{
|
||||
static const float EPS = 0.0001f;
|
||||
float s[3];
|
||||
dtVsub(s,c1,c0);
|
||||
float r = r0+r1;
|
||||
float c = dtVdot2D(s,s) - r*r;
|
||||
float a = dtVdot2D(v,v);
|
||||
if (a < EPS) return 0; // not moving
|
||||
|
||||
// Overlap, calc time to exit.
|
||||
float b = dtVdot2D(v,s);
|
||||
float d = b*b - a*c;
|
||||
if (d < 0.0f) return 0; // no intersection.
|
||||
a = 1.0f / a;
|
||||
const float rd = dtSqrt(d);
|
||||
tmin = (b - rd) * a;
|
||||
tmax = (b + rd) * a;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int isectRaySeg(const float* ap, const float* u,
|
||||
const float* bp, const float* bq,
|
||||
float& t)
|
||||
{
|
||||
float v[3], w[3];
|
||||
dtVsub(v,bq,bp);
|
||||
dtVsub(w,ap,bp);
|
||||
float d = dtVperp2D(u,v);
|
||||
if (dtMathFabs(d) < 1e-6f) return 0;
|
||||
d = 1.0f/d;
|
||||
t = dtVperp2D(v,w) * d;
|
||||
if (t < 0 || t > 1) return 0;
|
||||
float s = dtVperp2D(u,w) * d;
|
||||
if (s < 0 || s > 1) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
dtObstacleAvoidanceDebugData* dtAllocObstacleAvoidanceDebugData()
|
||||
{
|
||||
void* mem = dtAlloc(sizeof(dtObstacleAvoidanceDebugData), DT_ALLOC_PERM);
|
||||
if (!mem) return 0;
|
||||
return new(mem) dtObstacleAvoidanceDebugData;
|
||||
}
|
||||
|
||||
void dtFreeObstacleAvoidanceDebugData(dtObstacleAvoidanceDebugData* ptr)
|
||||
{
|
||||
if (!ptr) return;
|
||||
ptr->~dtObstacleAvoidanceDebugData();
|
||||
dtFree(ptr);
|
||||
}
|
||||
|
||||
|
||||
dtObstacleAvoidanceDebugData::dtObstacleAvoidanceDebugData() :
|
||||
m_nsamples(0),
|
||||
m_maxSamples(0),
|
||||
m_vel(0),
|
||||
m_ssize(0),
|
||||
m_pen(0),
|
||||
m_vpen(0),
|
||||
m_vcpen(0),
|
||||
m_spen(0),
|
||||
m_tpen(0)
|
||||
{
|
||||
}
|
||||
|
||||
dtObstacleAvoidanceDebugData::~dtObstacleAvoidanceDebugData()
|
||||
{
|
||||
dtFree(m_vel);
|
||||
dtFree(m_ssize);
|
||||
dtFree(m_pen);
|
||||
dtFree(m_vpen);
|
||||
dtFree(m_vcpen);
|
||||
dtFree(m_spen);
|
||||
dtFree(m_tpen);
|
||||
}
|
||||
|
||||
bool dtObstacleAvoidanceDebugData::init(const int maxSamples)
|
||||
{
|
||||
dtAssert(maxSamples);
|
||||
m_maxSamples = maxSamples;
|
||||
|
||||
m_vel = (float*)dtAlloc(sizeof(float)*3*m_maxSamples, DT_ALLOC_PERM);
|
||||
if (!m_vel)
|
||||
return false;
|
||||
m_pen = (float*)dtAlloc(sizeof(float)*m_maxSamples, DT_ALLOC_PERM);
|
||||
if (!m_pen)
|
||||
return false;
|
||||
m_ssize = (float*)dtAlloc(sizeof(float)*m_maxSamples, DT_ALLOC_PERM);
|
||||
if (!m_ssize)
|
||||
return false;
|
||||
m_vpen = (float*)dtAlloc(sizeof(float)*m_maxSamples, DT_ALLOC_PERM);
|
||||
if (!m_vpen)
|
||||
return false;
|
||||
m_vcpen = (float*)dtAlloc(sizeof(float)*m_maxSamples, DT_ALLOC_PERM);
|
||||
if (!m_vcpen)
|
||||
return false;
|
||||
m_spen = (float*)dtAlloc(sizeof(float)*m_maxSamples, DT_ALLOC_PERM);
|
||||
if (!m_spen)
|
||||
return false;
|
||||
m_tpen = (float*)dtAlloc(sizeof(float)*m_maxSamples, DT_ALLOC_PERM);
|
||||
if (!m_tpen)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dtObstacleAvoidanceDebugData::reset()
|
||||
{
|
||||
m_nsamples = 0;
|
||||
}
|
||||
|
||||
void dtObstacleAvoidanceDebugData::addSample(const float* vel, const float ssize, const float pen,
|
||||
const float vpen, const float vcpen, const float spen, const float tpen)
|
||||
{
|
||||
if (m_nsamples >= m_maxSamples)
|
||||
return;
|
||||
dtAssert(m_vel);
|
||||
dtAssert(m_ssize);
|
||||
dtAssert(m_pen);
|
||||
dtAssert(m_vpen);
|
||||
dtAssert(m_vcpen);
|
||||
dtAssert(m_spen);
|
||||
dtAssert(m_tpen);
|
||||
dtVcopy(&m_vel[m_nsamples*3], vel);
|
||||
m_ssize[m_nsamples] = ssize;
|
||||
m_pen[m_nsamples] = pen;
|
||||
m_vpen[m_nsamples] = vpen;
|
||||
m_vcpen[m_nsamples] = vcpen;
|
||||
m_spen[m_nsamples] = spen;
|
||||
m_tpen[m_nsamples] = tpen;
|
||||
m_nsamples++;
|
||||
}
|
||||
|
||||
static void normalizeArray(float* arr, const int n)
|
||||
{
|
||||
// Normalize penaly range.
|
||||
float minPen = FLT_MAX;
|
||||
float maxPen = -FLT_MAX;
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
minPen = dtMin(minPen, arr[i]);
|
||||
maxPen = dtMax(maxPen, arr[i]);
|
||||
}
|
||||
const float penRange = maxPen-minPen;
|
||||
const float s = penRange > 0.001f ? (1.0f / penRange) : 1;
|
||||
for (int i = 0; i < n; ++i)
|
||||
arr[i] = dtClamp((arr[i]-minPen)*s, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void dtObstacleAvoidanceDebugData::normalizeSamples()
|
||||
{
|
||||
normalizeArray(m_pen, m_nsamples);
|
||||
normalizeArray(m_vpen, m_nsamples);
|
||||
normalizeArray(m_vcpen, m_nsamples);
|
||||
normalizeArray(m_spen, m_nsamples);
|
||||
normalizeArray(m_tpen, m_nsamples);
|
||||
}
|
||||
|
||||
|
||||
dtObstacleAvoidanceQuery* dtAllocObstacleAvoidanceQuery()
|
||||
{
|
||||
void* mem = dtAlloc(sizeof(dtObstacleAvoidanceQuery), DT_ALLOC_PERM);
|
||||
if (!mem) return 0;
|
||||
return new(mem) dtObstacleAvoidanceQuery;
|
||||
}
|
||||
|
||||
void dtFreeObstacleAvoidanceQuery(dtObstacleAvoidanceQuery* ptr)
|
||||
{
|
||||
if (!ptr) return;
|
||||
ptr->~dtObstacleAvoidanceQuery();
|
||||
dtFree(ptr);
|
||||
}
|
||||
|
||||
|
||||
dtObstacleAvoidanceQuery::dtObstacleAvoidanceQuery() :
|
||||
m_maxCircles(0),
|
||||
m_circles(0),
|
||||
m_ncircles(0),
|
||||
m_maxSegments(0),
|
||||
m_segments(0),
|
||||
m_nsegments(0)
|
||||
{
|
||||
}
|
||||
|
||||
dtObstacleAvoidanceQuery::~dtObstacleAvoidanceQuery()
|
||||
{
|
||||
dtFree(m_circles);
|
||||
dtFree(m_segments);
|
||||
}
|
||||
|
||||
bool dtObstacleAvoidanceQuery::init(const int maxCircles, const int maxSegments)
|
||||
{
|
||||
m_maxCircles = maxCircles;
|
||||
m_ncircles = 0;
|
||||
m_circles = (dtObstacleCircle*)dtAlloc(sizeof(dtObstacleCircle)*m_maxCircles, DT_ALLOC_PERM);
|
||||
if (!m_circles)
|
||||
return false;
|
||||
memset(m_circles, 0, sizeof(dtObstacleCircle)*m_maxCircles);
|
||||
|
||||
m_maxSegments = maxSegments;
|
||||
m_nsegments = 0;
|
||||
m_segments = (dtObstacleSegment*)dtAlloc(sizeof(dtObstacleSegment)*m_maxSegments, DT_ALLOC_PERM);
|
||||
if (!m_segments)
|
||||
return false;
|
||||
memset(m_segments, 0, sizeof(dtObstacleSegment)*m_maxSegments);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dtObstacleAvoidanceQuery::reset()
|
||||
{
|
||||
m_ncircles = 0;
|
||||
m_nsegments = 0;
|
||||
}
|
||||
|
||||
void dtObstacleAvoidanceQuery::addCircle(const float* pos, const float rad,
|
||||
const float* vel, const float* dvel)
|
||||
{
|
||||
if (m_ncircles >= m_maxCircles)
|
||||
return;
|
||||
|
||||
dtObstacleCircle* cir = &m_circles[m_ncircles++];
|
||||
dtVcopy(cir->p, pos);
|
||||
cir->rad = rad;
|
||||
dtVcopy(cir->vel, vel);
|
||||
dtVcopy(cir->dvel, dvel);
|
||||
}
|
||||
|
||||
void dtObstacleAvoidanceQuery::addSegment(const float* p, const float* q)
|
||||
{
|
||||
if (m_nsegments > m_maxSegments)
|
||||
return;
|
||||
|
||||
dtObstacleSegment* seg = &m_segments[m_nsegments++];
|
||||
dtVcopy(seg->p, p);
|
||||
dtVcopy(seg->q, q);
|
||||
}
|
||||
|
||||
void dtObstacleAvoidanceQuery::prepare(const float* pos, const float* dvel)
|
||||
{
|
||||
// Prepare obstacles
|
||||
for (int i = 0; i < m_ncircles; ++i)
|
||||
{
|
||||
dtObstacleCircle* cir = &m_circles[i];
|
||||
|
||||
// Side
|
||||
const float* pa = pos;
|
||||
const float* pb = cir->p;
|
||||
|
||||
const float orig[3] = {0,0};
|
||||
float dv[3];
|
||||
dtVsub(cir->dp,pb,pa);
|
||||
dtVnormalize(cir->dp);
|
||||
dtVsub(dv, cir->dvel, dvel);
|
||||
|
||||
const float a = dtTriArea2D(orig, cir->dp,dv);
|
||||
if (a < 0.01f)
|
||||
{
|
||||
cir->np[0] = -cir->dp[2];
|
||||
cir->np[2] = cir->dp[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
cir->np[0] = cir->dp[2];
|
||||
cir->np[2] = -cir->dp[0];
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_nsegments; ++i)
|
||||
{
|
||||
dtObstacleSegment* seg = &m_segments[i];
|
||||
|
||||
// Precalc if the agent is really close to the segment.
|
||||
const float r = 0.01f;
|
||||
float t;
|
||||
seg->touch = dtDistancePtSegSqr2D(pos, seg->p, seg->q, t) < dtSqr(r);
|
||||
}
|
||||
}
|
||||
|
||||
float dtObstacleAvoidanceQuery::processSample(const float* vcand, const float cs,
|
||||
const float* pos, const float rad,
|
||||
const float* vel, const float* dvel,
|
||||
dtObstacleAvoidanceDebugData* debug)
|
||||
{
|
||||
// Find min time of impact and exit amongst all obstacles.
|
||||
float tmin = m_params.horizTime;
|
||||
float side = 0;
|
||||
int nside = 0;
|
||||
|
||||
for (int i = 0; i < m_ncircles; ++i)
|
||||
{
|
||||
const dtObstacleCircle* cir = &m_circles[i];
|
||||
|
||||
// RVO
|
||||
float vab[3];
|
||||
dtVscale(vab, vcand, 2);
|
||||
dtVsub(vab, vab, vel);
|
||||
dtVsub(vab, vab, cir->vel);
|
||||
|
||||
// Side
|
||||
side += dtClamp(dtMin(dtVdot2D(cir->dp,vab)*0.5f+0.5f, dtVdot2D(cir->np,vab)*2), 0.0f, 1.0f);
|
||||
nside++;
|
||||
|
||||
float htmin = 0, htmax = 0;
|
||||
if (!sweepCircleCircle(pos,rad, vab, cir->p,cir->rad, htmin, htmax))
|
||||
continue;
|
||||
|
||||
// Handle overlapping obstacles.
|
||||
if (htmin < 0.0f && htmax > 0.0f)
|
||||
{
|
||||
// Avoid more when overlapped.
|
||||
htmin = -htmin * 0.5f;
|
||||
}
|
||||
|
||||
if (htmin >= 0.0f)
|
||||
{
|
||||
// The closest obstacle is somewhere ahead of us, keep track of nearest obstacle.
|
||||
if (htmin < tmin)
|
||||
tmin = htmin;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_nsegments; ++i)
|
||||
{
|
||||
const dtObstacleSegment* seg = &m_segments[i];
|
||||
float htmin = 0;
|
||||
|
||||
if (seg->touch)
|
||||
{
|
||||
// Special case when the agent is very close to the segment.
|
||||
float sdir[3], snorm[3];
|
||||
dtVsub(sdir, seg->q, seg->p);
|
||||
snorm[0] = -sdir[2];
|
||||
snorm[2] = sdir[0];
|
||||
// If the velocity is pointing towards the segment, no collision.
|
||||
if (dtVdot2D(snorm, vcand) < 0.0f)
|
||||
continue;
|
||||
// Else immediate collision.
|
||||
htmin = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isectRaySeg(pos, vcand, seg->p, seg->q, htmin))
|
||||
continue;
|
||||
}
|
||||
|
||||
// Avoid less when facing walls.
|
||||
htmin *= 2.0f;
|
||||
|
||||
// The closest obstacle is somewhere ahead of us, keep track of nearest obstacle.
|
||||
if (htmin < tmin)
|
||||
tmin = htmin;
|
||||
}
|
||||
|
||||
// Normalize side bias, to prevent it dominating too much.
|
||||
if (nside)
|
||||
side /= nside;
|
||||
|
||||
const float vpen = m_params.weightDesVel * (dtVdist2D(vcand, dvel) * m_invVmax);
|
||||
const float vcpen = m_params.weightCurVel * (dtVdist2D(vcand, vel) * m_invVmax);
|
||||
const float spen = m_params.weightSide * side;
|
||||
const float tpen = m_params.weightToi * (1.0f/(0.1f+tmin*m_invHorizTime));
|
||||
|
||||
const float penalty = vpen + vcpen + spen + tpen;
|
||||
|
||||
// Store different penalties for debug viewing
|
||||
if (debug)
|
||||
debug->addSample(vcand, cs, penalty, vpen, vcpen, spen, tpen);
|
||||
|
||||
return penalty;
|
||||
}
|
||||
|
||||
int dtObstacleAvoidanceQuery::sampleVelocityGrid(const float* pos, const float rad, const float vmax,
|
||||
const float* vel, const float* dvel, float* nvel,
|
||||
const dtObstacleAvoidanceParams* params,
|
||||
dtObstacleAvoidanceDebugData* debug)
|
||||
{
|
||||
prepare(pos, dvel);
|
||||
|
||||
memcpy(&m_params, params, sizeof(dtObstacleAvoidanceParams));
|
||||
m_invHorizTime = 1.0f / m_params.horizTime;
|
||||
m_vmax = vmax;
|
||||
m_invVmax = 1.0f / vmax;
|
||||
|
||||
dtVset(nvel, 0,0,0);
|
||||
|
||||
if (debug)
|
||||
debug->reset();
|
||||
|
||||
const float cvx = dvel[0] * m_params.velBias;
|
||||
const float cvz = dvel[2] * m_params.velBias;
|
||||
const float cs = vmax * 2 * (1 - m_params.velBias) / (float)(m_params.gridSize-1);
|
||||
const float half = (m_params.gridSize-1)*cs*0.5f;
|
||||
|
||||
float minPenalty = FLT_MAX;
|
||||
int ns = 0;
|
||||
|
||||
for (int y = 0; y < m_params.gridSize; ++y)
|
||||
{
|
||||
for (int x = 0; x < m_params.gridSize; ++x)
|
||||
{
|
||||
float vcand[3];
|
||||
vcand[0] = cvx + x*cs - half;
|
||||
vcand[1] = 0;
|
||||
vcand[2] = cvz + y*cs - half;
|
||||
|
||||
if (dtSqr(vcand[0])+dtSqr(vcand[2]) > dtSqr(vmax+cs/2)) continue;
|
||||
|
||||
const float penalty = processSample(vcand, cs, pos,rad,vel,dvel, debug);
|
||||
ns++;
|
||||
if (penalty < minPenalty)
|
||||
{
|
||||
minPenalty = penalty;
|
||||
dtVcopy(nvel, vcand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ns;
|
||||
}
|
||||
|
||||
|
||||
int dtObstacleAvoidanceQuery::sampleVelocityAdaptive(const float* pos, const float rad, const float vmax,
|
||||
const float* vel, const float* dvel, float* nvel,
|
||||
const dtObstacleAvoidanceParams* params,
|
||||
dtObstacleAvoidanceDebugData* debug)
|
||||
{
|
||||
prepare(pos, dvel);
|
||||
|
||||
memcpy(&m_params, params, sizeof(dtObstacleAvoidanceParams));
|
||||
m_invHorizTime = 1.0f / m_params.horizTime;
|
||||
m_vmax = vmax;
|
||||
m_invVmax = 1.0f / vmax;
|
||||
|
||||
dtVset(nvel, 0,0,0);
|
||||
|
||||
if (debug)
|
||||
debug->reset();
|
||||
|
||||
// Build sampling pattern aligned to desired velocity.
|
||||
float pat[(DT_MAX_PATTERN_DIVS*DT_MAX_PATTERN_RINGS+1)*2];
|
||||
int npat = 0;
|
||||
|
||||
const int ndivs = (int)m_params.adaptiveDivs;
|
||||
const int nrings= (int)m_params.adaptiveRings;
|
||||
const int depth = (int)m_params.adaptiveDepth;
|
||||
|
||||
const int nd = dtClamp(ndivs, 1, DT_MAX_PATTERN_DIVS);
|
||||
const int nr = dtClamp(nrings, 1, DT_MAX_PATTERN_RINGS);
|
||||
const float da = (1.0f/nd) * DT_PI*2;
|
||||
const float dang = dtMathAtan2f(dvel[2], dvel[0]);
|
||||
|
||||
// Always add sample at zero
|
||||
pat[npat*2+0] = 0;
|
||||
pat[npat*2+1] = 0;
|
||||
npat++;
|
||||
|
||||
for (int j = 0; j < nr; ++j)
|
||||
{
|
||||
const float r = (float)(nr-j)/(float)nr;
|
||||
float a = dang + (j&1)*0.5f*da;
|
||||
for (int i = 0; i < nd; ++i)
|
||||
{
|
||||
pat[npat*2+0] = cosf(a)*r;
|
||||
pat[npat*2+1] = sinf(a)*r;
|
||||
npat++;
|
||||
a += da;
|
||||
}
|
||||
}
|
||||
|
||||
// Start sampling.
|
||||
float cr = vmax * (1.0f - m_params.velBias);
|
||||
float res[3];
|
||||
dtVset(res, dvel[0] * m_params.velBias, 0, dvel[2] * m_params.velBias);
|
||||
int ns = 0;
|
||||
|
||||
for (int k = 0; k < depth; ++k)
|
||||
{
|
||||
float minPenalty = FLT_MAX;
|
||||
float bvel[3];
|
||||
dtVset(bvel, 0,0,0);
|
||||
|
||||
for (int i = 0; i < npat; ++i)
|
||||
{
|
||||
float vcand[3];
|
||||
vcand[0] = res[0] + pat[i*2+0]*cr;
|
||||
vcand[1] = 0;
|
||||
vcand[2] = res[2] + pat[i*2+1]*cr;
|
||||
|
||||
if (dtSqr(vcand[0])+dtSqr(vcand[2]) > dtSqr(vmax+0.001f)) continue;
|
||||
|
||||
const float penalty = processSample(vcand,cr/10, pos,rad,vel,dvel, debug);
|
||||
ns++;
|
||||
if (penalty < minPenalty)
|
||||
{
|
||||
minPenalty = penalty;
|
||||
dtVcopy(bvel, vcand);
|
||||
}
|
||||
}
|
||||
|
||||
dtVcopy(res, bvel);
|
||||
|
||||
cr *= 0.5f;
|
||||
}
|
||||
|
||||
dtVcopy(nvel, res);
|
||||
|
||||
return ns;
|
||||
}
|
||||
|
||||
597
dep/recastnavigation/DetourCrowd/Source/DetourPathCorridor.cpp
Normal file
597
dep/recastnavigation/DetourCrowd/Source/DetourPathCorridor.cpp
Normal file
|
|
@ -0,0 +1,597 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include "DetourPathCorridor.h"
|
||||
#include "DetourNavMeshQuery.h"
|
||||
#include "DetourCommon.h"
|
||||
#include "DetourAssert.h"
|
||||
#include "DetourAlloc.h"
|
||||
|
||||
|
||||
int dtMergeCorridorStartMoved(dtPolyRef* path, const int npath, const int maxPath,
|
||||
const dtPolyRef* visited, const int nvisited)
|
||||
{
|
||||
int furthestPath = -1;
|
||||
int furthestVisited = -1;
|
||||
|
||||
// Find furthest common polygon.
|
||||
for (int i = npath-1; i >= 0; --i)
|
||||
{
|
||||
bool found = false;
|
||||
for (int j = nvisited-1; j >= 0; --j)
|
||||
{
|
||||
if (path[i] == visited[j])
|
||||
{
|
||||
furthestPath = i;
|
||||
furthestVisited = j;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
// If no intersection found just return current path.
|
||||
if (furthestPath == -1 || furthestVisited == -1)
|
||||
return npath;
|
||||
|
||||
// Concatenate paths.
|
||||
|
||||
// Adjust beginning of the buffer to include the visited.
|
||||
const int req = nvisited - furthestVisited;
|
||||
const int orig = dtMin(furthestPath+1, npath);
|
||||
int size = dtMax(0, npath-orig);
|
||||
if (req+size > maxPath)
|
||||
size = maxPath-req;
|
||||
if (size)
|
||||
memmove(path+req, path+orig, size*sizeof(dtPolyRef));
|
||||
|
||||
// Store visited
|
||||
for (int i = 0; i < req; ++i)
|
||||
path[i] = visited[(nvisited-1)-i];
|
||||
|
||||
return req+size;
|
||||
}
|
||||
|
||||
int dtMergeCorridorEndMoved(dtPolyRef* path, const int npath, const int maxPath,
|
||||
const dtPolyRef* visited, const int nvisited)
|
||||
{
|
||||
int furthestPath = -1;
|
||||
int furthestVisited = -1;
|
||||
|
||||
// Find furthest common polygon.
|
||||
for (int i = 0; i < npath; ++i)
|
||||
{
|
||||
bool found = false;
|
||||
for (int j = nvisited-1; j >= 0; --j)
|
||||
{
|
||||
if (path[i] == visited[j])
|
||||
{
|
||||
furthestPath = i;
|
||||
furthestVisited = j;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
// If no intersection found just return current path.
|
||||
if (furthestPath == -1 || furthestVisited == -1)
|
||||
return npath;
|
||||
|
||||
// Concatenate paths.
|
||||
const int ppos = furthestPath+1;
|
||||
const int vpos = furthestVisited+1;
|
||||
const int count = dtMin(nvisited-vpos, maxPath-ppos);
|
||||
dtAssert(ppos+count <= maxPath);
|
||||
if (count)
|
||||
memcpy(path+ppos, visited+vpos, sizeof(dtPolyRef)*count);
|
||||
|
||||
return ppos+count;
|
||||
}
|
||||
|
||||
int dtMergeCorridorStartShortcut(dtPolyRef* path, const int npath, const int maxPath,
|
||||
const dtPolyRef* visited, const int nvisited)
|
||||
{
|
||||
int furthestPath = -1;
|
||||
int furthestVisited = -1;
|
||||
|
||||
// Find furthest common polygon.
|
||||
for (int i = npath-1; i >= 0; --i)
|
||||
{
|
||||
bool found = false;
|
||||
for (int j = nvisited-1; j >= 0; --j)
|
||||
{
|
||||
if (path[i] == visited[j])
|
||||
{
|
||||
furthestPath = i;
|
||||
furthestVisited = j;
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
break;
|
||||
}
|
||||
|
||||
// If no intersection found just return current path.
|
||||
if (furthestPath == -1 || furthestVisited == -1)
|
||||
return npath;
|
||||
|
||||
// Concatenate paths.
|
||||
|
||||
// Adjust beginning of the buffer to include the visited.
|
||||
const int req = furthestVisited;
|
||||
if (req <= 0)
|
||||
return npath;
|
||||
|
||||
const int orig = furthestPath;
|
||||
int size = dtMax(0, npath-orig);
|
||||
if (req+size > maxPath)
|
||||
size = maxPath-req;
|
||||
if (size)
|
||||
memmove(path+req, path+orig, size*sizeof(dtPolyRef));
|
||||
|
||||
// Store visited
|
||||
for (int i = 0; i < req; ++i)
|
||||
path[i] = visited[i];
|
||||
|
||||
return req+size;
|
||||
}
|
||||
|
||||
/**
|
||||
@class dtPathCorridor
|
||||
@par
|
||||
|
||||
The corridor is loaded with a path, usually obtained from a #dtNavMeshQuery::findPath() query. The corridor
|
||||
is then used to plan local movement, with the corridor automatically updating as needed to deal with inaccurate
|
||||
agent locomotion.
|
||||
|
||||
Example of a common use case:
|
||||
|
||||
-# Construct the corridor object and call #init() to allocate its path buffer.
|
||||
-# Obtain a path from a #dtNavMeshQuery object.
|
||||
-# Use #reset() to set the agent's current position. (At the beginning of the path.)
|
||||
-# Use #setCorridor() to load the path and target.
|
||||
-# Use #findCorners() to plan movement. (This handles dynamic path straightening.)
|
||||
-# Use #movePosition() to feed agent movement back into the corridor. (The corridor will automatically adjust as needed.)
|
||||
-# If the target is moving, use #moveTargetPosition() to update the end of the corridor.
|
||||
(The corridor will automatically adjust as needed.)
|
||||
-# Repeat the previous 3 steps to continue to move the agent.
|
||||
|
||||
The corridor position and target are always constrained to the navigation mesh.
|
||||
|
||||
One of the difficulties in maintaining a path is that floating point errors, locomotion inaccuracies, and/or local
|
||||
steering can result in the agent crossing the boundary of the path corridor, temporarily invalidating the path.
|
||||
This class uses local mesh queries to detect and update the corridor as needed to handle these types of issues.
|
||||
|
||||
The fact that local mesh queries are used to move the position and target locations results in two beahviors that
|
||||
need to be considered:
|
||||
|
||||
Every time a move function is used there is a chance that the path will become non-optimial. Basically, the further
|
||||
the target is moved from its original location, and the further the position is moved outside the original corridor,
|
||||
the more likely the path will become non-optimal. This issue can be addressed by periodically running the
|
||||
#optimizePathTopology() and #optimizePathVisibility() methods.
|
||||
|
||||
All local mesh queries have distance limitations. (Review the #dtNavMeshQuery methods for details.) So the most accurate
|
||||
use case is to move the position and target in small increments. If a large increment is used, then the corridor
|
||||
may not be able to accurately find the new location. Because of this limiation, if a position is moved in a large
|
||||
increment, then compare the desired and resulting polygon references. If the two do not match, then path replanning
|
||||
may be needed. E.g. If you move the target, check #getLastPoly() to see if it is the expected polygon.
|
||||
|
||||
*/
|
||||
|
||||
dtPathCorridor::dtPathCorridor() :
|
||||
m_path(0),
|
||||
m_npath(0),
|
||||
m_maxPath(0)
|
||||
{
|
||||
}
|
||||
|
||||
dtPathCorridor::~dtPathCorridor()
|
||||
{
|
||||
dtFree(m_path);
|
||||
}
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// @warning Cannot be called more than once.
|
||||
bool dtPathCorridor::init(const int maxPath)
|
||||
{
|
||||
dtAssert(!m_path);
|
||||
m_path = (dtPolyRef*)dtAlloc(sizeof(dtPolyRef)*maxPath, DT_ALLOC_PERM);
|
||||
if (!m_path)
|
||||
return false;
|
||||
m_npath = 0;
|
||||
m_maxPath = maxPath;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// Essentially, the corridor is set of one polygon in size with the target
|
||||
/// equal to the position.
|
||||
void dtPathCorridor::reset(dtPolyRef ref, const float* pos)
|
||||
{
|
||||
dtAssert(m_path);
|
||||
dtVcopy(m_pos, pos);
|
||||
dtVcopy(m_target, pos);
|
||||
m_path[0] = ref;
|
||||
m_npath = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@par
|
||||
|
||||
This is the function used to plan local movement within the corridor. One or more corners can be
|
||||
detected in order to plan movement. It performs essentially the same function as #dtNavMeshQuery::findStraightPath.
|
||||
|
||||
Due to internal optimizations, the maximum number of corners returned will be (@p maxCorners - 1)
|
||||
For example: If the buffers are sized to hold 10 corners, the function will never return more than 9 corners.
|
||||
So if 10 corners are needed, the buffers should be sized for 11 corners.
|
||||
|
||||
If the target is within range, it will be the last corner and have a polygon reference id of zero.
|
||||
*/
|
||||
int dtPathCorridor::findCorners(float* cornerVerts, unsigned char* cornerFlags,
|
||||
dtPolyRef* cornerPolys, const int maxCorners,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* /*filter*/)
|
||||
{
|
||||
dtAssert(m_path);
|
||||
dtAssert(m_npath);
|
||||
|
||||
static const float MIN_TARGET_DIST = 0.01f;
|
||||
|
||||
int ncorners = 0;
|
||||
navquery->findStraightPath(m_pos, m_target, m_path, m_npath,
|
||||
cornerVerts, cornerFlags, cornerPolys, &ncorners, maxCorners);
|
||||
|
||||
// Prune points in the beginning of the path which are too close.
|
||||
while (ncorners)
|
||||
{
|
||||
if ((cornerFlags[0] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ||
|
||||
dtVdist2DSqr(&cornerVerts[0], m_pos) > dtSqr(MIN_TARGET_DIST))
|
||||
break;
|
||||
ncorners--;
|
||||
if (ncorners)
|
||||
{
|
||||
memmove(cornerFlags, cornerFlags+1, sizeof(unsigned char)*ncorners);
|
||||
memmove(cornerPolys, cornerPolys+1, sizeof(dtPolyRef)*ncorners);
|
||||
memmove(cornerVerts, cornerVerts+3, sizeof(float)*3*ncorners);
|
||||
}
|
||||
}
|
||||
|
||||
// Prune points after an off-mesh connection.
|
||||
for (int i = 0; i < ncorners; ++i)
|
||||
{
|
||||
if (cornerFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION)
|
||||
{
|
||||
ncorners = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ncorners;
|
||||
}
|
||||
|
||||
/**
|
||||
@par
|
||||
|
||||
Inaccurate locomotion or dynamic obstacle avoidance can force the argent position significantly outside the
|
||||
original corridor. Over time this can result in the formation of a non-optimal corridor. Non-optimal paths can
|
||||
also form near the corners of tiles.
|
||||
|
||||
This function uses an efficient local visibility search to try to optimize the corridor
|
||||
between the current position and @p next.
|
||||
|
||||
The corridor will change only if @p next is visible from the current position and moving directly toward the point
|
||||
is better than following the existing path.
|
||||
|
||||
The more inaccurate the agent movement, the more beneficial this function becomes. Simply adjust the frequency
|
||||
of the call to match the needs to the agent.
|
||||
|
||||
This function is not suitable for long distance searches.
|
||||
*/
|
||||
void dtPathCorridor::optimizePathVisibility(const float* next, const float pathOptimizationRange,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||
{
|
||||
dtAssert(m_path);
|
||||
|
||||
// Clamp the ray to max distance.
|
||||
float goal[3];
|
||||
dtVcopy(goal, next);
|
||||
float dist = dtVdist2D(m_pos, goal);
|
||||
|
||||
// If too close to the goal, do not try to optimize.
|
||||
if (dist < 0.01f)
|
||||
return;
|
||||
|
||||
// Overshoot a little. This helps to optimize open fields in tiled meshes.
|
||||
dist = dtMin(dist+0.01f, pathOptimizationRange);
|
||||
|
||||
// Adjust ray length.
|
||||
float delta[3];
|
||||
dtVsub(delta, goal, m_pos);
|
||||
dtVmad(goal, m_pos, delta, pathOptimizationRange/dist);
|
||||
|
||||
static const int MAX_RES = 32;
|
||||
dtPolyRef res[MAX_RES];
|
||||
float t, norm[3];
|
||||
int nres = 0;
|
||||
navquery->raycast(m_path[0], m_pos, goal, filter, &t, norm, res, &nres, MAX_RES);
|
||||
if (nres > 1 && t > 0.99f)
|
||||
{
|
||||
m_npath = dtMergeCorridorStartShortcut(m_path, m_npath, m_maxPath, res, nres);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@par
|
||||
|
||||
Inaccurate locomotion or dynamic obstacle avoidance can force the agent position significantly outside the
|
||||
original corridor. Over time this can result in the formation of a non-optimal corridor. This function will use a
|
||||
local area path search to try to re-optimize the corridor.
|
||||
|
||||
The more inaccurate the agent movement, the more beneficial this function becomes. Simply adjust the frequency of
|
||||
the call to match the needs to the agent.
|
||||
*/
|
||||
bool dtPathCorridor::optimizePathTopology(dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||
{
|
||||
dtAssert(navquery);
|
||||
dtAssert(filter);
|
||||
dtAssert(m_path);
|
||||
|
||||
if (m_npath < 3)
|
||||
return false;
|
||||
|
||||
static const int MAX_ITER = 32;
|
||||
static const int MAX_RES = 32;
|
||||
|
||||
dtPolyRef res[MAX_RES];
|
||||
int nres = 0;
|
||||
navquery->initSlicedFindPath(m_path[0], m_path[m_npath-1], m_pos, m_target, filter);
|
||||
navquery->updateSlicedFindPath(MAX_ITER, 0);
|
||||
dtStatus status = navquery->finalizeSlicedFindPathPartial(m_path, m_npath, res, &nres, MAX_RES);
|
||||
|
||||
if (dtStatusSucceed(status) && nres > 0)
|
||||
{
|
||||
m_npath = dtMergeCorridorStartShortcut(m_path, m_npath, m_maxPath, res, nres);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool dtPathCorridor::moveOverOffmeshConnection(dtPolyRef offMeshConRef, dtPolyRef* refs,
|
||||
float* startPos, float* endPos,
|
||||
dtNavMeshQuery* navquery)
|
||||
{
|
||||
dtAssert(navquery);
|
||||
dtAssert(m_path);
|
||||
dtAssert(m_npath);
|
||||
|
||||
// Advance the path up to and over the off-mesh connection.
|
||||
dtPolyRef prevRef = 0, polyRef = m_path[0];
|
||||
int npos = 0;
|
||||
while (npos < m_npath && polyRef != offMeshConRef)
|
||||
{
|
||||
prevRef = polyRef;
|
||||
polyRef = m_path[npos];
|
||||
npos++;
|
||||
}
|
||||
if (npos == m_npath)
|
||||
{
|
||||
// Could not find offMeshConRef
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prune path
|
||||
for (int i = npos; i < m_npath; ++i)
|
||||
m_path[i-npos] = m_path[i];
|
||||
m_npath -= npos;
|
||||
|
||||
refs[0] = prevRef;
|
||||
refs[1] = polyRef;
|
||||
|
||||
const dtNavMesh* nav = navquery->getAttachedNavMesh();
|
||||
dtAssert(nav);
|
||||
|
||||
dtStatus status = nav->getOffMeshConnectionPolyEndPoints(refs[0], refs[1], startPos, endPos);
|
||||
if (dtStatusSucceed(status))
|
||||
{
|
||||
dtVcopy(m_pos, endPos);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@par
|
||||
|
||||
Behavior:
|
||||
|
||||
- The movement is constrained to the surface of the navigation mesh.
|
||||
- The corridor is automatically adjusted (shorted or lengthened) in order to remain valid.
|
||||
- The new position will be located in the adjusted corridor's first polygon.
|
||||
|
||||
The expected use case is that the desired position will be 'near' the current corridor. What is considered 'near'
|
||||
depends on local polygon density, query search extents, etc.
|
||||
|
||||
The resulting position will differ from the desired position if the desired position is not on the navigation mesh,
|
||||
or it can't be reached using a local search.
|
||||
*/
|
||||
bool dtPathCorridor::movePosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||
{
|
||||
dtAssert(m_path);
|
||||
dtAssert(m_npath);
|
||||
|
||||
// Move along navmesh and update new position.
|
||||
float result[3];
|
||||
static const int MAX_VISITED = 16;
|
||||
dtPolyRef visited[MAX_VISITED];
|
||||
int nvisited = 0;
|
||||
dtStatus status = navquery->moveAlongSurface(m_path[0], m_pos, npos, filter,
|
||||
result, visited, &nvisited, MAX_VISITED);
|
||||
if (dtStatusSucceed(status)) {
|
||||
m_npath = dtMergeCorridorStartMoved(m_path, m_npath, m_maxPath, visited, nvisited);
|
||||
|
||||
// Adjust the position to stay on top of the navmesh.
|
||||
float h = m_pos[1];
|
||||
navquery->getPolyHeight(m_path[0], result, &h);
|
||||
result[1] = h;
|
||||
dtVcopy(m_pos, result);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@par
|
||||
|
||||
Behavior:
|
||||
|
||||
- The movement is constrained to the surface of the navigation mesh.
|
||||
- The corridor is automatically adjusted (shorted or lengthened) in order to remain valid.
|
||||
- The new target will be located in the adjusted corridor's last polygon.
|
||||
|
||||
The expected use case is that the desired target will be 'near' the current corridor. What is considered 'near' depends on local polygon density, query search extents, etc.
|
||||
|
||||
The resulting target will differ from the desired target if the desired target is not on the navigation mesh, or it can't be reached using a local search.
|
||||
*/
|
||||
bool dtPathCorridor::moveTargetPosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||
{
|
||||
dtAssert(m_path);
|
||||
dtAssert(m_npath);
|
||||
|
||||
// Move along navmesh and update new position.
|
||||
float result[3];
|
||||
static const int MAX_VISITED = 16;
|
||||
dtPolyRef visited[MAX_VISITED];
|
||||
int nvisited = 0;
|
||||
dtStatus status = navquery->moveAlongSurface(m_path[m_npath-1], m_target, npos, filter,
|
||||
result, visited, &nvisited, MAX_VISITED);
|
||||
if (dtStatusSucceed(status))
|
||||
{
|
||||
m_npath = dtMergeCorridorEndMoved(m_path, m_npath, m_maxPath, visited, nvisited);
|
||||
// TODO: should we do that?
|
||||
// Adjust the position to stay on top of the navmesh.
|
||||
/* float h = m_target[1];
|
||||
navquery->getPolyHeight(m_path[m_npath-1], result, &h);
|
||||
result[1] = h;*/
|
||||
|
||||
dtVcopy(m_target, result);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// The current corridor position is expected to be within the first polygon in the path. The target
|
||||
/// is expected to be in the last polygon.
|
||||
///
|
||||
/// @warning The size of the path must not exceed the size of corridor's path buffer set during #init().
|
||||
void dtPathCorridor::setCorridor(const float* target, const dtPolyRef* path, const int npath)
|
||||
{
|
||||
dtAssert(m_path);
|
||||
dtAssert(npath > 0);
|
||||
dtAssert(npath < m_maxPath);
|
||||
|
||||
dtVcopy(m_target, target);
|
||||
memcpy(m_path, path, sizeof(dtPolyRef)*npath);
|
||||
m_npath = npath;
|
||||
}
|
||||
|
||||
bool dtPathCorridor::fixPathStart(dtPolyRef safeRef, const float* safePos)
|
||||
{
|
||||
dtAssert(m_path);
|
||||
|
||||
dtVcopy(m_pos, safePos);
|
||||
if (m_npath < 3 && m_npath > 0)
|
||||
{
|
||||
m_path[2] = m_path[m_npath-1];
|
||||
m_path[0] = safeRef;
|
||||
m_path[1] = 0;
|
||||
m_npath = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_path[0] = safeRef;
|
||||
m_path[1] = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dtPathCorridor::trimInvalidPath(dtPolyRef safeRef, const float* safePos,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||
{
|
||||
dtAssert(navquery);
|
||||
dtAssert(filter);
|
||||
dtAssert(m_path);
|
||||
|
||||
// Keep valid path as far as possible.
|
||||
int n = 0;
|
||||
while (n < m_npath && navquery->isValidPolyRef(m_path[n], filter)) {
|
||||
n++;
|
||||
}
|
||||
|
||||
if (n == m_npath)
|
||||
{
|
||||
// All valid, no need to fix.
|
||||
return true;
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
// The first polyref is bad, use current safe values.
|
||||
dtVcopy(m_pos, safePos);
|
||||
m_path[0] = safeRef;
|
||||
m_npath = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The path is partially usable.
|
||||
m_npath = n;
|
||||
}
|
||||
|
||||
// Clamp target pos to last poly
|
||||
float tgt[3];
|
||||
dtVcopy(tgt, m_target);
|
||||
navquery->closestPointOnPolyBoundary(m_path[m_npath-1], tgt, m_target);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @par
|
||||
///
|
||||
/// The path can be invalidated if there are structural changes to the underlying navigation mesh, or the state of
|
||||
/// a polygon within the path changes resulting in it being filtered out. (E.g. An exclusion or inclusion flag changes.)
|
||||
bool dtPathCorridor::isValid(const int maxLookAhead, dtNavMeshQuery* navquery, const dtQueryFilter* filter)
|
||||
{
|
||||
// Check that all polygons still pass query filter.
|
||||
const int n = dtMin(m_npath, maxLookAhead);
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (!navquery->isValidPolyRef(m_path[i], filter))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
200
dep/recastnavigation/DetourCrowd/Source/DetourPathQueue.cpp
Normal file
200
dep/recastnavigation/DetourCrowd/Source/DetourPathQueue.cpp
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include "DetourPathQueue.h"
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourNavMeshQuery.h"
|
||||
#include "DetourAlloc.h"
|
||||
#include "DetourCommon.h"
|
||||
|
||||
|
||||
dtPathQueue::dtPathQueue() :
|
||||
m_nextHandle(1),
|
||||
m_maxPathSize(0),
|
||||
m_queueHead(0),
|
||||
m_navquery(0)
|
||||
{
|
||||
for (int i = 0; i < MAX_QUEUE; ++i)
|
||||
m_queue[i].path = 0;
|
||||
}
|
||||
|
||||
dtPathQueue::~dtPathQueue()
|
||||
{
|
||||
purge();
|
||||
}
|
||||
|
||||
void dtPathQueue::purge()
|
||||
{
|
||||
dtFreeNavMeshQuery(m_navquery);
|
||||
m_navquery = 0;
|
||||
for (int i = 0; i < MAX_QUEUE; ++i)
|
||||
{
|
||||
dtFree(m_queue[i].path);
|
||||
m_queue[i].path = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool dtPathQueue::init(const int maxPathSize, const int maxSearchNodeCount, dtNavMesh* nav)
|
||||
{
|
||||
purge();
|
||||
|
||||
m_navquery = dtAllocNavMeshQuery();
|
||||
if (!m_navquery)
|
||||
return false;
|
||||
if (dtStatusFailed(m_navquery->init(nav, maxSearchNodeCount)))
|
||||
return false;
|
||||
|
||||
m_maxPathSize = maxPathSize;
|
||||
for (int i = 0; i < MAX_QUEUE; ++i)
|
||||
{
|
||||
m_queue[i].ref = DT_PATHQ_INVALID;
|
||||
m_queue[i].path = (dtPolyRef*)dtAlloc(sizeof(dtPolyRef)*m_maxPathSize, DT_ALLOC_PERM);
|
||||
if (!m_queue[i].path)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_queueHead = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dtPathQueue::update(const int maxIters)
|
||||
{
|
||||
static const int MAX_KEEP_ALIVE = 2; // in update ticks.
|
||||
|
||||
// Update path request until there is nothing to update
|
||||
// or upto maxIters pathfinder iterations has been consumed.
|
||||
int iterCount = maxIters;
|
||||
|
||||
for (int i = 0; i < MAX_QUEUE; ++i)
|
||||
{
|
||||
PathQuery& q = m_queue[m_queueHead % MAX_QUEUE];
|
||||
|
||||
// Skip inactive requests.
|
||||
if (q.ref == DT_PATHQ_INVALID)
|
||||
{
|
||||
m_queueHead++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle completed request.
|
||||
if (dtStatusSucceed(q.status) || dtStatusFailed(q.status))
|
||||
{
|
||||
// If the path result has not been read in few frames, free the slot.
|
||||
q.keepAlive++;
|
||||
if (q.keepAlive > MAX_KEEP_ALIVE)
|
||||
{
|
||||
q.ref = DT_PATHQ_INVALID;
|
||||
q.status = 0;
|
||||
}
|
||||
|
||||
m_queueHead++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Handle query start.
|
||||
if (q.status == 0)
|
||||
{
|
||||
q.status = m_navquery->initSlicedFindPath(q.startRef, q.endRef, q.startPos, q.endPos, q.filter);
|
||||
}
|
||||
// Handle query in progress.
|
||||
if (dtStatusInProgress(q.status))
|
||||
{
|
||||
int iters = 0;
|
||||
q.status = m_navquery->updateSlicedFindPath(iterCount, &iters);
|
||||
iterCount -= iters;
|
||||
}
|
||||
if (dtStatusSucceed(q.status))
|
||||
{
|
||||
q.status = m_navquery->finalizeSlicedFindPath(q.path, &q.npath, m_maxPathSize);
|
||||
}
|
||||
|
||||
if (iterCount <= 0)
|
||||
break;
|
||||
|
||||
m_queueHead++;
|
||||
}
|
||||
}
|
||||
|
||||
dtPathQueueRef dtPathQueue::request(dtPolyRef startRef, dtPolyRef endRef,
|
||||
const float* startPos, const float* endPos,
|
||||
const dtQueryFilter* filter)
|
||||
{
|
||||
// Find empty slot
|
||||
int slot = -1;
|
||||
for (int i = 0; i < MAX_QUEUE; ++i)
|
||||
{
|
||||
if (m_queue[i].ref == DT_PATHQ_INVALID)
|
||||
{
|
||||
slot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Could not find slot.
|
||||
if (slot == -1)
|
||||
return DT_PATHQ_INVALID;
|
||||
|
||||
dtPathQueueRef ref = m_nextHandle++;
|
||||
if (m_nextHandle == DT_PATHQ_INVALID) m_nextHandle++;
|
||||
|
||||
PathQuery& q = m_queue[slot];
|
||||
q.ref = ref;
|
||||
dtVcopy(q.startPos, startPos);
|
||||
q.startRef = startRef;
|
||||
dtVcopy(q.endPos, endPos);
|
||||
q.endRef = endRef;
|
||||
|
||||
q.status = 0;
|
||||
q.npath = 0;
|
||||
q.filter = filter;
|
||||
q.keepAlive = 0;
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
dtStatus dtPathQueue::getRequestStatus(dtPathQueueRef ref) const
|
||||
{
|
||||
for (int i = 0; i < MAX_QUEUE; ++i)
|
||||
{
|
||||
if (m_queue[i].ref == ref)
|
||||
return m_queue[i].status;
|
||||
}
|
||||
return DT_FAILURE;
|
||||
}
|
||||
|
||||
dtStatus dtPathQueue::getPathResult(dtPathQueueRef ref, dtPolyRef* path, int* pathSize, const int maxPath)
|
||||
{
|
||||
for (int i = 0; i < MAX_QUEUE; ++i)
|
||||
{
|
||||
if (m_queue[i].ref == ref)
|
||||
{
|
||||
PathQuery& q = m_queue[i];
|
||||
dtStatus details = q.status & DT_STATUS_DETAIL_MASK;
|
||||
// Free request for reuse.
|
||||
q.ref = DT_PATHQ_INVALID;
|
||||
q.status = 0;
|
||||
// Copy path
|
||||
int n = dtMin(q.npath, maxPath);
|
||||
memcpy(path, q.path, sizeof(dtPolyRef)*n);
|
||||
*pathSize = n;
|
||||
return details | DT_SUCCESS;
|
||||
}
|
||||
}
|
||||
return DT_FAILURE;
|
||||
}
|
||||
194
dep/recastnavigation/DetourCrowd/Source/DetourProximityGrid.cpp
Normal file
194
dep/recastnavigation/DetourCrowd/Source/DetourProximityGrid.cpp
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#include <string.h>
|
||||
#include <new>
|
||||
#include "DetourProximityGrid.h"
|
||||
#include "DetourCommon.h"
|
||||
#include "DetourMath.h"
|
||||
#include "DetourAlloc.h"
|
||||
#include "DetourAssert.h"
|
||||
|
||||
|
||||
dtProximityGrid* dtAllocProximityGrid()
|
||||
{
|
||||
void* mem = dtAlloc(sizeof(dtProximityGrid), DT_ALLOC_PERM);
|
||||
if (!mem) return 0;
|
||||
return new(mem) dtProximityGrid;
|
||||
}
|
||||
|
||||
void dtFreeProximityGrid(dtProximityGrid* ptr)
|
||||
{
|
||||
if (!ptr) return;
|
||||
ptr->~dtProximityGrid();
|
||||
dtFree(ptr);
|
||||
}
|
||||
|
||||
|
||||
inline int hashPos2(int x, int y, int n)
|
||||
{
|
||||
return ((x*73856093) ^ (y*19349663)) & (n-1);
|
||||
}
|
||||
|
||||
|
||||
dtProximityGrid::dtProximityGrid() :
|
||||
m_maxItems(0),
|
||||
m_cellSize(0),
|
||||
m_pool(0),
|
||||
m_poolHead(0),
|
||||
m_poolSize(0),
|
||||
m_buckets(0),
|
||||
m_bucketsSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
dtProximityGrid::~dtProximityGrid()
|
||||
{
|
||||
dtFree(m_buckets);
|
||||
dtFree(m_pool);
|
||||
}
|
||||
|
||||
bool dtProximityGrid::init(const int poolSize, const float cellSize)
|
||||
{
|
||||
dtAssert(poolSize > 0);
|
||||
dtAssert(cellSize > 0.0f);
|
||||
|
||||
m_cellSize = cellSize;
|
||||
m_invCellSize = 1.0f / m_cellSize;
|
||||
|
||||
// Allocate hashs buckets
|
||||
m_bucketsSize = dtNextPow2(poolSize);
|
||||
m_buckets = (unsigned short*)dtAlloc(sizeof(unsigned short)*m_bucketsSize, DT_ALLOC_PERM);
|
||||
if (!m_buckets)
|
||||
return false;
|
||||
|
||||
// Allocate pool of items.
|
||||
m_poolSize = poolSize;
|
||||
m_poolHead = 0;
|
||||
m_pool = (Item*)dtAlloc(sizeof(Item)*m_poolSize, DT_ALLOC_PERM);
|
||||
if (!m_pool)
|
||||
return false;
|
||||
|
||||
clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void dtProximityGrid::clear()
|
||||
{
|
||||
memset(m_buckets, 0xff, sizeof(unsigned short)*m_bucketsSize);
|
||||
m_poolHead = 0;
|
||||
m_bounds[0] = 0xffff;
|
||||
m_bounds[1] = 0xffff;
|
||||
m_bounds[2] = -0xffff;
|
||||
m_bounds[3] = -0xffff;
|
||||
}
|
||||
|
||||
void dtProximityGrid::addItem(const unsigned short id,
|
||||
const float minx, const float miny,
|
||||
const float maxx, const float maxy)
|
||||
{
|
||||
const int iminx = (int)dtMathFloorf(minx * m_invCellSize);
|
||||
const int iminy = (int)dtMathFloorf(miny * m_invCellSize);
|
||||
const int imaxx = (int)dtMathFloorf(maxx * m_invCellSize);
|
||||
const int imaxy = (int)dtMathFloorf(maxy * m_invCellSize);
|
||||
|
||||
m_bounds[0] = dtMin(m_bounds[0], iminx);
|
||||
m_bounds[1] = dtMin(m_bounds[1], iminy);
|
||||
m_bounds[2] = dtMax(m_bounds[2], imaxx);
|
||||
m_bounds[3] = dtMax(m_bounds[3], imaxy);
|
||||
|
||||
for (int y = iminy; y <= imaxy; ++y)
|
||||
{
|
||||
for (int x = iminx; x <= imaxx; ++x)
|
||||
{
|
||||
if (m_poolHead < m_poolSize)
|
||||
{
|
||||
const int h = hashPos2(x, y, m_bucketsSize);
|
||||
const unsigned short idx = (unsigned short)m_poolHead;
|
||||
m_poolHead++;
|
||||
Item& item = m_pool[idx];
|
||||
item.x = (short)x;
|
||||
item.y = (short)y;
|
||||
item.id = id;
|
||||
item.next = m_buckets[h];
|
||||
m_buckets[h] = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int dtProximityGrid::queryItems(const float minx, const float miny,
|
||||
const float maxx, const float maxy,
|
||||
unsigned short* ids, const int maxIds) const
|
||||
{
|
||||
const int iminx = (int)dtMathFloorf(minx * m_invCellSize);
|
||||
const int iminy = (int)dtMathFloorf(miny * m_invCellSize);
|
||||
const int imaxx = (int)dtMathFloorf(maxx * m_invCellSize);
|
||||
const int imaxy = (int)dtMathFloorf(maxy * m_invCellSize);
|
||||
|
||||
int n = 0;
|
||||
|
||||
for (int y = iminy; y <= imaxy; ++y)
|
||||
{
|
||||
for (int x = iminx; x <= imaxx; ++x)
|
||||
{
|
||||
const int h = hashPos2(x, y, m_bucketsSize);
|
||||
unsigned short idx = m_buckets[h];
|
||||
while (idx != 0xffff)
|
||||
{
|
||||
Item& item = m_pool[idx];
|
||||
if ((int)item.x == x && (int)item.y == y)
|
||||
{
|
||||
// Check if the id exists already.
|
||||
const unsigned short* end = ids + n;
|
||||
unsigned short* i = ids;
|
||||
while (i != end && *i != item.id)
|
||||
++i;
|
||||
// Item not found, add it.
|
||||
if (i == end)
|
||||
{
|
||||
if (n >= maxIds)
|
||||
return n;
|
||||
ids[n++] = item.id;
|
||||
}
|
||||
}
|
||||
idx = item.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int dtProximityGrid::getItemCountAt(const int x, const int y) const
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
const int h = hashPos2(x, y, m_bucketsSize);
|
||||
unsigned short idx = m_buckets[h];
|
||||
while (idx != 0xffff)
|
||||
{
|
||||
Item& item = m_pool[idx];
|
||||
if ((int)item.x == x && (int)item.y == y)
|
||||
n++;
|
||||
idx = item.next;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
212
dep/recastnavigation/DetourTileCache/Include/DetourTileCache.h
Normal file
212
dep/recastnavigation/DetourTileCache/Include/DetourTileCache.h
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
#ifndef DETOURTILECACHE_H
|
||||
#define DETOURTILECACHE_H
|
||||
|
||||
#include "DetourStatus.h"
|
||||
|
||||
|
||||
|
||||
typedef unsigned int dtObstacleRef;
|
||||
|
||||
typedef unsigned int dtCompressedTileRef;
|
||||
|
||||
/// Flags for addTile
|
||||
enum dtCompressedTileFlags
|
||||
{
|
||||
DT_COMPRESSEDTILE_FREE_DATA = 0x01, ///< Navmesh owns the tile memory and should free it.
|
||||
};
|
||||
|
||||
struct dtCompressedTile
|
||||
{
|
||||
unsigned int salt; ///< Counter describing modifications to the tile.
|
||||
struct dtTileCacheLayerHeader* header;
|
||||
unsigned char* compressed;
|
||||
int compressedSize;
|
||||
unsigned char* data;
|
||||
int dataSize;
|
||||
unsigned int flags;
|
||||
dtCompressedTile* next;
|
||||
};
|
||||
|
||||
enum ObstacleState
|
||||
{
|
||||
DT_OBSTACLE_EMPTY,
|
||||
DT_OBSTACLE_PROCESSING,
|
||||
DT_OBSTACLE_PROCESSED,
|
||||
DT_OBSTACLE_REMOVING,
|
||||
};
|
||||
|
||||
static const int DT_MAX_TOUCHED_TILES = 8;
|
||||
struct dtTileCacheObstacle
|
||||
{
|
||||
float pos[3], radius, height;
|
||||
dtCompressedTileRef touched[DT_MAX_TOUCHED_TILES];
|
||||
dtCompressedTileRef pending[DT_MAX_TOUCHED_TILES];
|
||||
unsigned short salt;
|
||||
unsigned char state;
|
||||
unsigned char ntouched;
|
||||
unsigned char npending;
|
||||
dtTileCacheObstacle* next;
|
||||
};
|
||||
|
||||
struct dtTileCacheParams
|
||||
{
|
||||
float orig[3];
|
||||
float cs, ch;
|
||||
int width, height;
|
||||
float walkableHeight;
|
||||
float walkableRadius;
|
||||
float walkableClimb;
|
||||
float maxSimplificationError;
|
||||
int maxTiles;
|
||||
int maxObstacles;
|
||||
};
|
||||
|
||||
struct dtTileCacheMeshProcess
|
||||
{
|
||||
virtual ~dtTileCacheMeshProcess() { }
|
||||
|
||||
virtual void process(struct dtNavMeshCreateParams* params,
|
||||
unsigned char* polyAreas, unsigned short* polyFlags) = 0;
|
||||
};
|
||||
|
||||
|
||||
class dtTileCache
|
||||
{
|
||||
public:
|
||||
dtTileCache();
|
||||
~dtTileCache();
|
||||
|
||||
struct dtTileCacheAlloc* getAlloc() { return m_talloc; }
|
||||
struct dtTileCacheCompressor* getCompressor() { return m_tcomp; }
|
||||
const dtTileCacheParams* getParams() const { return &m_params; }
|
||||
|
||||
inline int getTileCount() const { return m_params.maxTiles; }
|
||||
inline const dtCompressedTile* getTile(const int i) const { return &m_tiles[i]; }
|
||||
|
||||
inline int getObstacleCount() const { return m_params.maxObstacles; }
|
||||
inline const dtTileCacheObstacle* getObstacle(const int i) const { return &m_obstacles[i]; }
|
||||
|
||||
const dtTileCacheObstacle* getObstacleByRef(dtObstacleRef ref);
|
||||
|
||||
dtObstacleRef getObstacleRef(const dtTileCacheObstacle* obmin) const;
|
||||
|
||||
dtStatus init(const dtTileCacheParams* params,
|
||||
struct dtTileCacheAlloc* talloc,
|
||||
struct dtTileCacheCompressor* tcomp,
|
||||
struct dtTileCacheMeshProcess* tmproc);
|
||||
|
||||
int getTilesAt(const int tx, const int ty, dtCompressedTileRef* tiles, const int maxTiles) const ;
|
||||
|
||||
dtCompressedTile* getTileAt(const int tx, const int ty, const int tlayer);
|
||||
dtCompressedTileRef getTileRef(const dtCompressedTile* tile) const;
|
||||
const dtCompressedTile* getTileByRef(dtCompressedTileRef ref) const;
|
||||
|
||||
dtStatus addTile(unsigned char* data, const int dataSize, unsigned char flags, dtCompressedTileRef* result);
|
||||
|
||||
dtStatus removeTile(dtCompressedTileRef ref, unsigned char** data, int* dataSize);
|
||||
|
||||
dtStatus addObstacle(const float* pos, const float radius, const float height, dtObstacleRef* result);
|
||||
dtStatus removeObstacle(const dtObstacleRef ref);
|
||||
|
||||
dtStatus queryTiles(const float* bmin, const float* bmax,
|
||||
dtCompressedTileRef* results, int* resultCount, const int maxResults) const;
|
||||
|
||||
dtStatus update(const float /*dt*/, class dtNavMesh* navmesh);
|
||||
|
||||
dtStatus buildNavMeshTilesAt(const int tx, const int ty, class dtNavMesh* navmesh);
|
||||
|
||||
dtStatus buildNavMeshTile(const dtCompressedTileRef ref, class dtNavMesh* navmesh);
|
||||
|
||||
void calcTightTileBounds(const struct dtTileCacheLayerHeader* header, float* bmin, float* bmax) const;
|
||||
|
||||
void getObstacleBounds(const struct dtTileCacheObstacle* ob, float* bmin, float* bmax) const;
|
||||
|
||||
|
||||
/// Encodes a tile id.
|
||||
inline dtCompressedTileRef encodeTileId(unsigned int salt, unsigned int it) const
|
||||
{
|
||||
return ((dtCompressedTileRef)salt << m_tileBits) | (dtCompressedTileRef)it;
|
||||
}
|
||||
|
||||
/// Decodes a tile salt.
|
||||
inline unsigned int decodeTileIdSalt(dtCompressedTileRef ref) const
|
||||
{
|
||||
const dtCompressedTileRef saltMask = ((dtCompressedTileRef)1<<m_saltBits)-1;
|
||||
return (unsigned int)((ref >> m_tileBits) & saltMask);
|
||||
}
|
||||
|
||||
/// Decodes a tile id.
|
||||
inline unsigned int decodeTileIdTile(dtCompressedTileRef ref) const
|
||||
{
|
||||
const dtCompressedTileRef tileMask = ((dtCompressedTileRef)1<<m_tileBits)-1;
|
||||
return (unsigned int)(ref & tileMask);
|
||||
}
|
||||
|
||||
/// Encodes an obstacle id.
|
||||
inline dtObstacleRef encodeObstacleId(unsigned int salt, unsigned int it) const
|
||||
{
|
||||
return ((dtObstacleRef)salt << 16) | (dtObstacleRef)it;
|
||||
}
|
||||
|
||||
/// Decodes an obstacle salt.
|
||||
inline unsigned int decodeObstacleIdSalt(dtObstacleRef ref) const
|
||||
{
|
||||
const dtObstacleRef saltMask = ((dtObstacleRef)1<<16)-1;
|
||||
return (unsigned int)((ref >> 16) & saltMask);
|
||||
}
|
||||
|
||||
/// Decodes an obstacle id.
|
||||
inline unsigned int decodeObstacleIdObstacle(dtObstacleRef ref) const
|
||||
{
|
||||
const dtObstacleRef tileMask = ((dtObstacleRef)1<<16)-1;
|
||||
return (unsigned int)(ref & tileMask);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
enum ObstacleRequestAction
|
||||
{
|
||||
REQUEST_ADD,
|
||||
REQUEST_REMOVE,
|
||||
};
|
||||
|
||||
struct ObstacleRequest
|
||||
{
|
||||
int action;
|
||||
dtObstacleRef ref;
|
||||
};
|
||||
|
||||
int m_tileLutSize; ///< Tile hash lookup size (must be pot).
|
||||
int m_tileLutMask; ///< Tile hash lookup mask.
|
||||
|
||||
dtCompressedTile** m_posLookup; ///< Tile hash lookup.
|
||||
dtCompressedTile* m_nextFreeTile; ///< Freelist of tiles.
|
||||
dtCompressedTile* m_tiles; ///< List of tiles.
|
||||
|
||||
unsigned int m_saltBits; ///< Number of salt bits in the tile ID.
|
||||
unsigned int m_tileBits; ///< Number of tile bits in the tile ID.
|
||||
|
||||
dtTileCacheParams m_params;
|
||||
|
||||
dtTileCacheAlloc* m_talloc;
|
||||
dtTileCacheCompressor* m_tcomp;
|
||||
dtTileCacheMeshProcess* m_tmproc;
|
||||
|
||||
dtTileCacheObstacle* m_obstacles;
|
||||
dtTileCacheObstacle* m_nextFreeObstacle;
|
||||
|
||||
static const int MAX_REQUESTS = 64;
|
||||
ObstacleRequest m_reqs[MAX_REQUESTS];
|
||||
int m_nreqs;
|
||||
|
||||
static const int MAX_UPDATE = 64;
|
||||
dtCompressedTileRef m_update[MAX_UPDATE];
|
||||
int m_nupdate;
|
||||
|
||||
};
|
||||
|
||||
dtTileCache* dtAllocTileCache();
|
||||
void dtFreeTileCache(dtTileCache* tc);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef DETOURTILECACHEBUILDER_H
|
||||
#define DETOURTILECACHEBUILDER_H
|
||||
|
||||
#include "DetourAlloc.h"
|
||||
#include "DetourStatus.h"
|
||||
|
||||
static const int DT_TILECACHE_MAGIC = 'D'<<24 | 'T'<<16 | 'L'<<8 | 'R'; ///< 'DTLR';
|
||||
static const int DT_TILECACHE_VERSION = 1;
|
||||
|
||||
static const unsigned char DT_TILECACHE_NULL_AREA = 0;
|
||||
static const unsigned char DT_TILECACHE_WALKABLE_AREA = 63;
|
||||
static const unsigned short DT_TILECACHE_NULL_IDX = 0xffff;
|
||||
|
||||
struct dtTileCacheLayerHeader
|
||||
{
|
||||
int magic; ///< Data magic
|
||||
int version; ///< Data version
|
||||
int tx,ty,tlayer;
|
||||
float bmin[3], bmax[3];
|
||||
unsigned short hmin, hmax; ///< Height min/max range
|
||||
unsigned char width, height; ///< Dimension of the layer.
|
||||
unsigned char minx, maxx, miny, maxy; ///< Usable sub-region.
|
||||
};
|
||||
|
||||
struct dtTileCacheLayer
|
||||
{
|
||||
dtTileCacheLayerHeader* header;
|
||||
unsigned char regCount; ///< Region count.
|
||||
unsigned char* heights;
|
||||
unsigned char* areas;
|
||||
unsigned char* cons;
|
||||
unsigned char* regs;
|
||||
};
|
||||
|
||||
struct dtTileCacheContour
|
||||
{
|
||||
int nverts;
|
||||
unsigned char* verts;
|
||||
unsigned char reg;
|
||||
unsigned char area;
|
||||
};
|
||||
|
||||
struct dtTileCacheContourSet
|
||||
{
|
||||
int nconts;
|
||||
dtTileCacheContour* conts;
|
||||
};
|
||||
|
||||
struct dtTileCachePolyMesh
|
||||
{
|
||||
int nvp;
|
||||
int nverts; ///< Number of vertices.
|
||||
int npolys; ///< Number of polygons.
|
||||
unsigned short* verts; ///< Vertices of the mesh, 3 elements per vertex.
|
||||
unsigned short* polys; ///< Polygons of the mesh, nvp*2 elements per polygon.
|
||||
unsigned short* flags; ///< Per polygon flags.
|
||||
unsigned char* areas; ///< Area ID of polygons.
|
||||
};
|
||||
|
||||
|
||||
struct dtTileCacheAlloc
|
||||
{
|
||||
virtual ~dtTileCacheAlloc() { }
|
||||
|
||||
virtual void reset()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void* alloc(const int size)
|
||||
{
|
||||
return dtAlloc(size, DT_ALLOC_TEMP);
|
||||
}
|
||||
|
||||
virtual void free(void* ptr)
|
||||
{
|
||||
dtFree(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
struct dtTileCacheCompressor
|
||||
{
|
||||
virtual ~dtTileCacheCompressor() { }
|
||||
|
||||
virtual int maxCompressedSize(const int bufferSize) = 0;
|
||||
virtual dtStatus compress(const unsigned char* buffer, const int bufferSize,
|
||||
unsigned char* compressed, const int maxCompressedSize, int* compressedSize) = 0;
|
||||
virtual dtStatus decompress(const unsigned char* compressed, const int compressedSize,
|
||||
unsigned char* buffer, const int maxBufferSize, int* bufferSize) = 0;
|
||||
};
|
||||
|
||||
|
||||
dtStatus dtBuildTileCacheLayer(dtTileCacheCompressor* comp,
|
||||
dtTileCacheLayerHeader* header,
|
||||
const unsigned char* heights,
|
||||
const unsigned char* areas,
|
||||
const unsigned char* cons,
|
||||
unsigned char** outData, int* outDataSize);
|
||||
|
||||
void dtFreeTileCacheLayer(dtTileCacheAlloc* alloc, dtTileCacheLayer* layer);
|
||||
|
||||
dtStatus dtDecompressTileCacheLayer(dtTileCacheAlloc* alloc, dtTileCacheCompressor* comp,
|
||||
unsigned char* compressed, const int compressedSize,
|
||||
dtTileCacheLayer** layerOut);
|
||||
|
||||
dtTileCacheContourSet* dtAllocTileCacheContourSet(dtTileCacheAlloc* alloc);
|
||||
void dtFreeTileCacheContourSet(dtTileCacheAlloc* alloc, dtTileCacheContourSet* cset);
|
||||
|
||||
dtTileCachePolyMesh* dtAllocTileCachePolyMesh(dtTileCacheAlloc* alloc);
|
||||
void dtFreeTileCachePolyMesh(dtTileCacheAlloc* alloc, dtTileCachePolyMesh* lmesh);
|
||||
|
||||
dtStatus dtMarkCylinderArea(dtTileCacheLayer& layer, const float* orig, const float cs, const float ch,
|
||||
const float* pos, const float radius, const float height, const unsigned char areaId);
|
||||
|
||||
dtStatus dtBuildTileCacheRegions(dtTileCacheAlloc* alloc,
|
||||
dtTileCacheLayer& layer,
|
||||
const int walkableClimb);
|
||||
|
||||
dtStatus dtBuildTileCacheContours(dtTileCacheAlloc* alloc,
|
||||
dtTileCacheLayer& layer,
|
||||
const int walkableClimb, const float maxError,
|
||||
dtTileCacheContourSet& lcset);
|
||||
|
||||
dtStatus dtBuildTileCachePolyMesh(dtTileCacheAlloc* alloc,
|
||||
dtTileCacheContourSet& lcset,
|
||||
dtTileCachePolyMesh& mesh);
|
||||
|
||||
/// Swaps the endianess of the compressed tile data's header (#dtTileCacheLayerHeader).
|
||||
/// Tile layer data does not need endian swapping as it consits only of bytes.
|
||||
/// @param[in,out] data The tile data array.
|
||||
/// @param[in] dataSize The size of the data array.
|
||||
bool dtTileCacheHeaderSwapEndian(unsigned char* data, const int dataSize);
|
||||
|
||||
|
||||
#endif // DETOURTILECACHEBUILDER_H
|
||||
704
dep/recastnavigation/DetourTileCache/Source/DetourTileCache.cpp
Normal file
704
dep/recastnavigation/DetourTileCache/Source/DetourTileCache.cpp
Normal file
|
|
@ -0,0 +1,704 @@
|
|||
#include "DetourTileCache.h"
|
||||
#include "DetourTileCacheBuilder.h"
|
||||
#include "DetourNavMeshBuilder.h"
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourCommon.h"
|
||||
#include "DetourMath.h"
|
||||
#include "DetourAlloc.h"
|
||||
#include "DetourAssert.h"
|
||||
#include <string.h>
|
||||
#include <new>
|
||||
|
||||
dtTileCache* dtAllocTileCache()
|
||||
{
|
||||
void* mem = dtAlloc(sizeof(dtTileCache), DT_ALLOC_PERM);
|
||||
if (!mem) return 0;
|
||||
return new(mem) dtTileCache;
|
||||
}
|
||||
|
||||
void dtFreeTileCache(dtTileCache* tc)
|
||||
{
|
||||
if (!tc) return;
|
||||
tc->~dtTileCache();
|
||||
dtFree(tc);
|
||||
}
|
||||
|
||||
static bool contains(const dtCompressedTileRef* a, const int n, const dtCompressedTileRef v)
|
||||
{
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (a[i] == v)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline int computeTileHash(int x, int y, const int mask)
|
||||
{
|
||||
const unsigned int h1 = 0x8da6b343; // Large multiplicative constants;
|
||||
const unsigned int h2 = 0xd8163841; // here arbitrarily chosen primes
|
||||
unsigned int n = h1 * x + h2 * y;
|
||||
return (int)(n & mask);
|
||||
}
|
||||
|
||||
|
||||
struct BuildContext
|
||||
{
|
||||
inline BuildContext(struct dtTileCacheAlloc* a) : layer(0), lcset(0), lmesh(0), alloc(a) {}
|
||||
inline ~BuildContext() { purge(); }
|
||||
void purge()
|
||||
{
|
||||
dtFreeTileCacheLayer(alloc, layer);
|
||||
layer = 0;
|
||||
dtFreeTileCacheContourSet(alloc, lcset);
|
||||
lcset = 0;
|
||||
dtFreeTileCachePolyMesh(alloc, lmesh);
|
||||
lmesh = 0;
|
||||
}
|
||||
struct dtTileCacheLayer* layer;
|
||||
struct dtTileCacheContourSet* lcset;
|
||||
struct dtTileCachePolyMesh* lmesh;
|
||||
struct dtTileCacheAlloc* alloc;
|
||||
};
|
||||
|
||||
|
||||
dtTileCache::dtTileCache() :
|
||||
m_tileLutSize(0),
|
||||
m_tileLutMask(0),
|
||||
m_posLookup(0),
|
||||
m_nextFreeTile(0),
|
||||
m_tiles(0),
|
||||
m_saltBits(0),
|
||||
m_tileBits(0),
|
||||
m_talloc(0),
|
||||
m_tcomp(0),
|
||||
m_tmproc(0),
|
||||
m_obstacles(0),
|
||||
m_nextFreeObstacle(0),
|
||||
m_nreqs(0),
|
||||
m_nupdate(0)
|
||||
{
|
||||
memset(&m_params, 0, sizeof(m_params));
|
||||
}
|
||||
|
||||
dtTileCache::~dtTileCache()
|
||||
{
|
||||
for (int i = 0; i < m_params.maxTiles; ++i)
|
||||
{
|
||||
if (m_tiles[i].flags & DT_COMPRESSEDTILE_FREE_DATA)
|
||||
{
|
||||
dtFree(m_tiles[i].data);
|
||||
m_tiles[i].data = 0;
|
||||
}
|
||||
}
|
||||
dtFree(m_obstacles);
|
||||
m_obstacles = 0;
|
||||
dtFree(m_posLookup);
|
||||
m_posLookup = 0;
|
||||
dtFree(m_tiles);
|
||||
m_tiles = 0;
|
||||
m_nreqs = 0;
|
||||
m_nupdate = 0;
|
||||
}
|
||||
|
||||
const dtCompressedTile* dtTileCache::getTileByRef(dtCompressedTileRef ref) const
|
||||
{
|
||||
if (!ref)
|
||||
return 0;
|
||||
unsigned int tileIndex = decodeTileIdTile(ref);
|
||||
unsigned int tileSalt = decodeTileIdSalt(ref);
|
||||
if ((int)tileIndex >= m_params.maxTiles)
|
||||
return 0;
|
||||
const dtCompressedTile* tile = &m_tiles[tileIndex];
|
||||
if (tile->salt != tileSalt)
|
||||
return 0;
|
||||
return tile;
|
||||
}
|
||||
|
||||
|
||||
dtStatus dtTileCache::init(const dtTileCacheParams* params,
|
||||
dtTileCacheAlloc* talloc,
|
||||
dtTileCacheCompressor* tcomp,
|
||||
dtTileCacheMeshProcess* tmproc)
|
||||
{
|
||||
m_talloc = talloc;
|
||||
m_tcomp = tcomp;
|
||||
m_tmproc = tmproc;
|
||||
m_nreqs = 0;
|
||||
memcpy(&m_params, params, sizeof(m_params));
|
||||
|
||||
// Alloc space for obstacles.
|
||||
m_obstacles = (dtTileCacheObstacle*)dtAlloc(sizeof(dtTileCacheObstacle)*m_params.maxObstacles, DT_ALLOC_PERM);
|
||||
if (!m_obstacles)
|
||||
return DT_FAILURE | DT_OUT_OF_MEMORY;
|
||||
memset(m_obstacles, 0, sizeof(dtTileCacheObstacle)*m_params.maxObstacles);
|
||||
m_nextFreeObstacle = 0;
|
||||
for (int i = m_params.maxObstacles-1; i >= 0; --i)
|
||||
{
|
||||
m_obstacles[i].salt = 1;
|
||||
m_obstacles[i].next = m_nextFreeObstacle;
|
||||
m_nextFreeObstacle = &m_obstacles[i];
|
||||
}
|
||||
|
||||
// Init tiles
|
||||
m_tileLutSize = dtNextPow2(m_params.maxTiles/4);
|
||||
if (!m_tileLutSize) m_tileLutSize = 1;
|
||||
m_tileLutMask = m_tileLutSize-1;
|
||||
|
||||
m_tiles = (dtCompressedTile*)dtAlloc(sizeof(dtCompressedTile)*m_params.maxTiles, DT_ALLOC_PERM);
|
||||
if (!m_tiles)
|
||||
return DT_FAILURE | DT_OUT_OF_MEMORY;
|
||||
m_posLookup = (dtCompressedTile**)dtAlloc(sizeof(dtCompressedTile*)*m_tileLutSize, DT_ALLOC_PERM);
|
||||
if (!m_posLookup)
|
||||
return DT_FAILURE | DT_OUT_OF_MEMORY;
|
||||
memset(m_tiles, 0, sizeof(dtCompressedTile)*m_params.maxTiles);
|
||||
memset(m_posLookup, 0, sizeof(dtCompressedTile*)*m_tileLutSize);
|
||||
m_nextFreeTile = 0;
|
||||
for (int i = m_params.maxTiles-1; i >= 0; --i)
|
||||
{
|
||||
m_tiles[i].salt = 1;
|
||||
m_tiles[i].next = m_nextFreeTile;
|
||||
m_nextFreeTile = &m_tiles[i];
|
||||
}
|
||||
|
||||
// Init ID generator values.
|
||||
m_tileBits = dtIlog2(dtNextPow2((unsigned int)m_params.maxTiles));
|
||||
// Only allow 31 salt bits, since the salt mask is calculated using 32bit uint and it will overflow.
|
||||
m_saltBits = dtMin((unsigned int)31, 32 - m_tileBits);
|
||||
if (m_saltBits < 10)
|
||||
return DT_FAILURE | DT_INVALID_PARAM;
|
||||
|
||||
return DT_SUCCESS;
|
||||
}
|
||||
|
||||
int dtTileCache::getTilesAt(const int tx, const int ty, dtCompressedTileRef* tiles, const int maxTiles) const
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
// Find tile based on hash.
|
||||
int h = computeTileHash(tx,ty,m_tileLutMask);
|
||||
dtCompressedTile* tile = m_posLookup[h];
|
||||
while (tile)
|
||||
{
|
||||
if (tile->header &&
|
||||
tile->header->tx == tx &&
|
||||
tile->header->ty == ty)
|
||||
{
|
||||
if (n < maxTiles)
|
||||
tiles[n++] = getTileRef(tile);
|
||||
}
|
||||
tile = tile->next;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
dtCompressedTile* dtTileCache::getTileAt(const int tx, const int ty, const int tlayer)
|
||||
{
|
||||
// Find tile based on hash.
|
||||
int h = computeTileHash(tx,ty,m_tileLutMask);
|
||||
dtCompressedTile* tile = m_posLookup[h];
|
||||
while (tile)
|
||||
{
|
||||
if (tile->header &&
|
||||
tile->header->tx == tx &&
|
||||
tile->header->ty == ty &&
|
||||
tile->header->tlayer == tlayer)
|
||||
{
|
||||
return tile;
|
||||
}
|
||||
tile = tile->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
dtCompressedTileRef dtTileCache::getTileRef(const dtCompressedTile* tile) const
|
||||
{
|
||||
if (!tile) return 0;
|
||||
const unsigned int it = (unsigned int)(tile - m_tiles);
|
||||
return (dtCompressedTileRef)encodeTileId(tile->salt, it);
|
||||
}
|
||||
|
||||
dtObstacleRef dtTileCache::getObstacleRef(const dtTileCacheObstacle* ob) const
|
||||
{
|
||||
if (!ob) return 0;
|
||||
const unsigned int idx = (unsigned int)(ob - m_obstacles);
|
||||
return encodeObstacleId(ob->salt, idx);
|
||||
}
|
||||
|
||||
const dtTileCacheObstacle* dtTileCache::getObstacleByRef(dtObstacleRef ref)
|
||||
{
|
||||
if (!ref)
|
||||
return 0;
|
||||
unsigned int idx = decodeObstacleIdObstacle(ref);
|
||||
if ((int)idx >= m_params.maxObstacles)
|
||||
return 0;
|
||||
const dtTileCacheObstacle* ob = &m_obstacles[idx];
|
||||
unsigned int salt = decodeObstacleIdSalt(ref);
|
||||
if (ob->salt != salt)
|
||||
return 0;
|
||||
return ob;
|
||||
}
|
||||
|
||||
dtStatus dtTileCache::addTile(unsigned char* data, const int dataSize, unsigned char flags, dtCompressedTileRef* result)
|
||||
{
|
||||
// Make sure the data is in right format.
|
||||
dtTileCacheLayerHeader* header = (dtTileCacheLayerHeader*)data;
|
||||
if (header->magic != DT_TILECACHE_MAGIC)
|
||||
return DT_FAILURE | DT_WRONG_MAGIC;
|
||||
if (header->version != DT_TILECACHE_VERSION)
|
||||
return DT_FAILURE | DT_WRONG_VERSION;
|
||||
|
||||
// Make sure the location is free.
|
||||
if (getTileAt(header->tx, header->ty, header->tlayer))
|
||||
return DT_FAILURE;
|
||||
|
||||
// Allocate a tile.
|
||||
dtCompressedTile* tile = 0;
|
||||
if (m_nextFreeTile)
|
||||
{
|
||||
tile = m_nextFreeTile;
|
||||
m_nextFreeTile = tile->next;
|
||||
tile->next = 0;
|
||||
}
|
||||
|
||||
// Make sure we could allocate a tile.
|
||||
if (!tile)
|
||||
return DT_FAILURE | DT_OUT_OF_MEMORY;
|
||||
|
||||
// Insert tile into the position lut.
|
||||
int h = computeTileHash(header->tx, header->ty, m_tileLutMask);
|
||||
tile->next = m_posLookup[h];
|
||||
m_posLookup[h] = tile;
|
||||
|
||||
// Init tile.
|
||||
const int headerSize = dtAlign4(sizeof(dtTileCacheLayerHeader));
|
||||
tile->header = (dtTileCacheLayerHeader*)data;
|
||||
tile->data = data;
|
||||
tile->dataSize = dataSize;
|
||||
tile->compressed = tile->data + headerSize;
|
||||
tile->compressedSize = tile->dataSize - headerSize;
|
||||
tile->flags = flags;
|
||||
|
||||
if (result)
|
||||
*result = getTileRef(tile);
|
||||
|
||||
return DT_SUCCESS;
|
||||
}
|
||||
|
||||
dtStatus dtTileCache::removeTile(dtCompressedTileRef ref, unsigned char** data, int* dataSize)
|
||||
{
|
||||
if (!ref)
|
||||
return DT_FAILURE | DT_INVALID_PARAM;
|
||||
unsigned int tileIndex = decodeTileIdTile(ref);
|
||||
unsigned int tileSalt = decodeTileIdSalt(ref);
|
||||
if ((int)tileIndex >= m_params.maxTiles)
|
||||
return DT_FAILURE | DT_INVALID_PARAM;
|
||||
dtCompressedTile* tile = &m_tiles[tileIndex];
|
||||
if (tile->salt != tileSalt)
|
||||
return DT_FAILURE | DT_INVALID_PARAM;
|
||||
|
||||
// Remove tile from hash lookup.
|
||||
const int h = computeTileHash(tile->header->tx,tile->header->ty,m_tileLutMask);
|
||||
dtCompressedTile* prev = 0;
|
||||
dtCompressedTile* cur = m_posLookup[h];
|
||||
while (cur)
|
||||
{
|
||||
if (cur == tile)
|
||||
{
|
||||
if (prev)
|
||||
prev->next = cur->next;
|
||||
else
|
||||
m_posLookup[h] = cur->next;
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
// Reset tile.
|
||||
if (tile->flags & DT_COMPRESSEDTILE_FREE_DATA)
|
||||
{
|
||||
// Owns data
|
||||
dtFree(tile->data);
|
||||
tile->data = 0;
|
||||
tile->dataSize = 0;
|
||||
if (data) *data = 0;
|
||||
if (dataSize) *dataSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (data) *data = tile->data;
|
||||
if (dataSize) *dataSize = tile->dataSize;
|
||||
}
|
||||
|
||||
tile->header = 0;
|
||||
tile->data = 0;
|
||||
tile->dataSize = 0;
|
||||
tile->compressed = 0;
|
||||
tile->compressedSize = 0;
|
||||
tile->flags = 0;
|
||||
|
||||
// Update salt, salt should never be zero.
|
||||
tile->salt = (tile->salt+1) & ((1<<m_saltBits)-1);
|
||||
if (tile->salt == 0)
|
||||
tile->salt++;
|
||||
|
||||
// Add to free list.
|
||||
tile->next = m_nextFreeTile;
|
||||
m_nextFreeTile = tile;
|
||||
|
||||
return DT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
dtObstacleRef dtTileCache::addObstacle(const float* pos, const float radius, const float height, dtObstacleRef* result)
|
||||
{
|
||||
if (m_nreqs >= MAX_REQUESTS)
|
||||
return DT_FAILURE | DT_BUFFER_TOO_SMALL;
|
||||
|
||||
dtTileCacheObstacle* ob = 0;
|
||||
if (m_nextFreeObstacle)
|
||||
{
|
||||
ob = m_nextFreeObstacle;
|
||||
m_nextFreeObstacle = ob->next;
|
||||
ob->next = 0;
|
||||
}
|
||||
if (!ob)
|
||||
return DT_FAILURE | DT_OUT_OF_MEMORY;
|
||||
|
||||
unsigned short salt = ob->salt;
|
||||
memset(ob, 0, sizeof(dtTileCacheObstacle));
|
||||
ob->salt = salt;
|
||||
ob->state = DT_OBSTACLE_PROCESSING;
|
||||
dtVcopy(ob->pos, pos);
|
||||
ob->radius = radius;
|
||||
ob->height = height;
|
||||
|
||||
ObstacleRequest* req = &m_reqs[m_nreqs++];
|
||||
memset(req, 0, sizeof(ObstacleRequest));
|
||||
req->action = REQUEST_ADD;
|
||||
req->ref = getObstacleRef(ob);
|
||||
|
||||
if (result)
|
||||
*result = req->ref;
|
||||
|
||||
return DT_SUCCESS;
|
||||
}
|
||||
|
||||
dtObstacleRef dtTileCache::removeObstacle(const dtObstacleRef ref)
|
||||
{
|
||||
if (!ref)
|
||||
return DT_SUCCESS;
|
||||
if (m_nreqs >= MAX_REQUESTS)
|
||||
return DT_FAILURE | DT_BUFFER_TOO_SMALL;
|
||||
|
||||
ObstacleRequest* req = &m_reqs[m_nreqs++];
|
||||
memset(req, 0, sizeof(ObstacleRequest));
|
||||
req->action = REQUEST_REMOVE;
|
||||
req->ref = ref;
|
||||
|
||||
return DT_SUCCESS;
|
||||
}
|
||||
|
||||
dtStatus dtTileCache::queryTiles(const float* bmin, const float* bmax,
|
||||
dtCompressedTileRef* results, int* resultCount, const int maxResults) const
|
||||
{
|
||||
const int MAX_TILES = 32;
|
||||
dtCompressedTileRef tiles[MAX_TILES];
|
||||
|
||||
int n = 0;
|
||||
|
||||
const float tw = m_params.width * m_params.cs;
|
||||
const float th = m_params.height * m_params.cs;
|
||||
const int tx0 = (int)dtMathFloorf((bmin[0]-m_params.orig[0]) / tw);
|
||||
const int tx1 = (int)dtMathFloorf((bmax[0]-m_params.orig[0]) / tw);
|
||||
const int ty0 = (int)dtMathFloorf((bmin[2]-m_params.orig[2]) / th);
|
||||
const int ty1 = (int)dtMathFloorf((bmax[2]-m_params.orig[2]) / th);
|
||||
|
||||
for (int ty = ty0; ty <= ty1; ++ty)
|
||||
{
|
||||
for (int tx = tx0; tx <= tx1; ++tx)
|
||||
{
|
||||
const int ntiles = getTilesAt(tx,ty,tiles,MAX_TILES);
|
||||
|
||||
for (int i = 0; i < ntiles; ++i)
|
||||
{
|
||||
const dtCompressedTile* tile = &m_tiles[decodeTileIdTile(tiles[i])];
|
||||
float tbmin[3], tbmax[3];
|
||||
calcTightTileBounds(tile->header, tbmin, tbmax);
|
||||
|
||||
if (dtOverlapBounds(bmin,bmax, tbmin,tbmax))
|
||||
{
|
||||
if (n < maxResults)
|
||||
results[n++] = tiles[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*resultCount = n;
|
||||
|
||||
return DT_SUCCESS;
|
||||
}
|
||||
|
||||
dtStatus dtTileCache::update(const float /*dt*/, dtNavMesh* navmesh)
|
||||
{
|
||||
if (m_nupdate == 0)
|
||||
{
|
||||
// Process requests.
|
||||
for (int i = 0; i < m_nreqs; ++i)
|
||||
{
|
||||
ObstacleRequest* req = &m_reqs[i];
|
||||
|
||||
unsigned int idx = decodeObstacleIdObstacle(req->ref);
|
||||
if ((int)idx >= m_params.maxObstacles)
|
||||
continue;
|
||||
dtTileCacheObstacle* ob = &m_obstacles[idx];
|
||||
unsigned int salt = decodeObstacleIdSalt(req->ref);
|
||||
if (ob->salt != salt)
|
||||
continue;
|
||||
|
||||
if (req->action == REQUEST_ADD)
|
||||
{
|
||||
// Find touched tiles.
|
||||
float bmin[3], bmax[3];
|
||||
getObstacleBounds(ob, bmin, bmax);
|
||||
|
||||
int ntouched = 0;
|
||||
queryTiles(bmin, bmax, ob->touched, &ntouched, DT_MAX_TOUCHED_TILES);
|
||||
ob->ntouched = (unsigned char)ntouched;
|
||||
// Add tiles to update list.
|
||||
ob->npending = 0;
|
||||
for (int j = 0; j < ob->ntouched; ++j)
|
||||
{
|
||||
if (m_nupdate < MAX_UPDATE)
|
||||
{
|
||||
if (!contains(m_update, m_nupdate, ob->touched[j]))
|
||||
m_update[m_nupdate++] = ob->touched[j];
|
||||
ob->pending[ob->npending++] = ob->touched[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (req->action == REQUEST_REMOVE)
|
||||
{
|
||||
// Prepare to remove obstacle.
|
||||
ob->state = DT_OBSTACLE_REMOVING;
|
||||
// Add tiles to update list.
|
||||
ob->npending = 0;
|
||||
for (int j = 0; j < ob->ntouched; ++j)
|
||||
{
|
||||
if (m_nupdate < MAX_UPDATE)
|
||||
{
|
||||
if (!contains(m_update, m_nupdate, ob->touched[j]))
|
||||
m_update[m_nupdate++] = ob->touched[j];
|
||||
ob->pending[ob->npending++] = ob->touched[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_nreqs = 0;
|
||||
}
|
||||
|
||||
// Process updates
|
||||
if (m_nupdate)
|
||||
{
|
||||
// Build mesh
|
||||
const dtCompressedTileRef ref = m_update[0];
|
||||
dtStatus status = buildNavMeshTile(ref, navmesh);
|
||||
m_nupdate--;
|
||||
if (m_nupdate > 0)
|
||||
memmove(m_update, m_update+1, m_nupdate*sizeof(dtCompressedTileRef));
|
||||
|
||||
// Update obstacle states.
|
||||
for (int i = 0; i < m_params.maxObstacles; ++i)
|
||||
{
|
||||
dtTileCacheObstacle* ob = &m_obstacles[i];
|
||||
if (ob->state == DT_OBSTACLE_PROCESSING || ob->state == DT_OBSTACLE_REMOVING)
|
||||
{
|
||||
// Remove handled tile from pending list.
|
||||
for (int j = 0; j < (int)ob->npending; j++)
|
||||
{
|
||||
if (ob->pending[j] == ref)
|
||||
{
|
||||
ob->pending[j] = ob->pending[(int)ob->npending-1];
|
||||
ob->npending--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If all pending tiles processed, change state.
|
||||
if (ob->npending == 0)
|
||||
{
|
||||
if (ob->state == DT_OBSTACLE_PROCESSING)
|
||||
{
|
||||
ob->state = DT_OBSTACLE_PROCESSED;
|
||||
}
|
||||
else if (ob->state == DT_OBSTACLE_REMOVING)
|
||||
{
|
||||
ob->state = DT_OBSTACLE_EMPTY;
|
||||
// Update salt, salt should never be zero.
|
||||
ob->salt = (ob->salt+1) & ((1<<16)-1);
|
||||
if (ob->salt == 0)
|
||||
ob->salt++;
|
||||
// Return obstacle to free list.
|
||||
ob->next = m_nextFreeObstacle;
|
||||
m_nextFreeObstacle = ob;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dtStatusFailed(status))
|
||||
return status;
|
||||
}
|
||||
|
||||
return DT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
dtStatus dtTileCache::buildNavMeshTilesAt(const int tx, const int ty, dtNavMesh* navmesh)
|
||||
{
|
||||
const int MAX_TILES = 32;
|
||||
dtCompressedTileRef tiles[MAX_TILES];
|
||||
const int ntiles = getTilesAt(tx,ty,tiles,MAX_TILES);
|
||||
|
||||
for (int i = 0; i < ntiles; ++i)
|
||||
{
|
||||
dtStatus status = buildNavMeshTile(tiles[i], navmesh);
|
||||
if (dtStatusFailed(status))
|
||||
return status;
|
||||
}
|
||||
|
||||
return DT_SUCCESS;
|
||||
}
|
||||
|
||||
dtStatus dtTileCache::buildNavMeshTile(const dtCompressedTileRef ref, dtNavMesh* navmesh)
|
||||
{
|
||||
dtAssert(m_talloc);
|
||||
dtAssert(m_tcomp);
|
||||
|
||||
unsigned int idx = decodeTileIdTile(ref);
|
||||
if (idx > (unsigned int)m_params.maxTiles)
|
||||
return DT_FAILURE | DT_INVALID_PARAM;
|
||||
const dtCompressedTile* tile = &m_tiles[idx];
|
||||
unsigned int salt = decodeTileIdSalt(ref);
|
||||
if (tile->salt != salt)
|
||||
return DT_FAILURE | DT_INVALID_PARAM;
|
||||
|
||||
m_talloc->reset();
|
||||
|
||||
BuildContext bc(m_talloc);
|
||||
const int walkableClimbVx = (int)(m_params.walkableClimb / m_params.ch);
|
||||
dtStatus status;
|
||||
|
||||
// Decompress tile layer data.
|
||||
status = dtDecompressTileCacheLayer(m_talloc, m_tcomp, tile->data, tile->dataSize, &bc.layer);
|
||||
if (dtStatusFailed(status))
|
||||
return status;
|
||||
|
||||
// Rasterize obstacles.
|
||||
for (int i = 0; i < m_params.maxObstacles; ++i)
|
||||
{
|
||||
const dtTileCacheObstacle* ob = &m_obstacles[i];
|
||||
if (ob->state == DT_OBSTACLE_EMPTY || ob->state == DT_OBSTACLE_REMOVING)
|
||||
continue;
|
||||
if (contains(ob->touched, ob->ntouched, ref))
|
||||
{
|
||||
dtMarkCylinderArea(*bc.layer, tile->header->bmin, m_params.cs, m_params.ch,
|
||||
ob->pos, ob->radius, ob->height, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Build navmesh
|
||||
status = dtBuildTileCacheRegions(m_talloc, *bc.layer, walkableClimbVx);
|
||||
if (dtStatusFailed(status))
|
||||
return status;
|
||||
|
||||
bc.lcset = dtAllocTileCacheContourSet(m_talloc);
|
||||
if (!bc.lcset)
|
||||
return status;
|
||||
status = dtBuildTileCacheContours(m_talloc, *bc.layer, walkableClimbVx,
|
||||
m_params.maxSimplificationError, *bc.lcset);
|
||||
if (dtStatusFailed(status))
|
||||
return status;
|
||||
|
||||
bc.lmesh = dtAllocTileCachePolyMesh(m_talloc);
|
||||
if (!bc.lmesh)
|
||||
return status;
|
||||
status = dtBuildTileCachePolyMesh(m_talloc, *bc.lcset, *bc.lmesh);
|
||||
if (dtStatusFailed(status))
|
||||
return status;
|
||||
|
||||
// Early out if the mesh tile is empty.
|
||||
if (!bc.lmesh->npolys)
|
||||
return DT_SUCCESS;
|
||||
|
||||
dtNavMeshCreateParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.verts = bc.lmesh->verts;
|
||||
params.vertCount = bc.lmesh->nverts;
|
||||
params.polys = bc.lmesh->polys;
|
||||
params.polyAreas = bc.lmesh->areas;
|
||||
params.polyFlags = bc.lmesh->flags;
|
||||
params.polyCount = bc.lmesh->npolys;
|
||||
params.nvp = DT_VERTS_PER_POLYGON;
|
||||
params.walkableHeight = m_params.walkableHeight;
|
||||
params.walkableRadius = m_params.walkableRadius;
|
||||
params.walkableClimb = m_params.walkableClimb;
|
||||
params.tileX = tile->header->tx;
|
||||
params.tileY = tile->header->ty;
|
||||
params.tileLayer = tile->header->tlayer;
|
||||
params.cs = m_params.cs;
|
||||
params.ch = m_params.ch;
|
||||
params.buildBvTree = false;
|
||||
dtVcopy(params.bmin, tile->header->bmin);
|
||||
dtVcopy(params.bmax, tile->header->bmax);
|
||||
|
||||
if (m_tmproc)
|
||||
{
|
||||
m_tmproc->process(¶ms, bc.lmesh->areas, bc.lmesh->flags);
|
||||
}
|
||||
|
||||
unsigned char* navData = 0;
|
||||
int navDataSize = 0;
|
||||
if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize))
|
||||
return DT_FAILURE;
|
||||
|
||||
// Remove existing tile.
|
||||
navmesh->removeTile(navmesh->getTileRefAt(tile->header->tx,tile->header->ty,tile->header->tlayer),0,0);
|
||||
|
||||
// Add new tile, or leave the location empty.
|
||||
if (navData)
|
||||
{
|
||||
// Let the navmesh own the data.
|
||||
status = navmesh->addTile(navData,navDataSize,DT_TILE_FREE_DATA,0,0);
|
||||
if (dtStatusFailed(status))
|
||||
{
|
||||
dtFree(navData);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return DT_SUCCESS;
|
||||
}
|
||||
|
||||
void dtTileCache::calcTightTileBounds(const dtTileCacheLayerHeader* header, float* bmin, float* bmax) const
|
||||
{
|
||||
const float cs = m_params.cs;
|
||||
bmin[0] = header->bmin[0] + header->minx*cs;
|
||||
bmin[1] = header->bmin[1];
|
||||
bmin[2] = header->bmin[2] + header->miny*cs;
|
||||
bmax[0] = header->bmin[0] + (header->maxx+1)*cs;
|
||||
bmax[1] = header->bmax[1];
|
||||
bmax[2] = header->bmin[2] + (header->maxy+1)*cs;
|
||||
}
|
||||
|
||||
void dtTileCache::getObstacleBounds(const struct dtTileCacheObstacle* ob, float* bmin, float* bmax) const
|
||||
{
|
||||
bmin[0] = ob->pos[0] - ob->radius;
|
||||
bmin[1] = ob->pos[1];
|
||||
bmin[2] = ob->pos[2] - ob->radius;
|
||||
bmax[0] = ob->pos[0] + ob->radius;
|
||||
bmax[1] = ob->pos[1] + ob->height;
|
||||
bmax[2] = ob->pos[2] + ob->radius;
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
27
dep/recastnavigation/Docs/Conceptual/license_c.txt
Normal file
27
dep/recastnavigation/Docs/Conceptual/license_c.txt
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
/**
|
||||
@page License License
|
||||
|
||||
<pre>
|
||||
Copyright (c) 2009-2011 Mikko Mononen memon@inside.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
</pre>
|
||||
|
||||
*/
|
||||
95
dep/recastnavigation/Docs/Conceptual/mainpage_c.txt
Normal file
95
dep/recastnavigation/Docs/Conceptual/mainpage_c.txt
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/// @mainpage Recast Navigation
|
||||
///
|
||||
/// @image html recast_intro.png
|
||||
///
|
||||
/// <h2>Recast</h2>
|
||||
///
|
||||
/// _Recast_ is state of the art navigation mesh construction toolset for
|
||||
/// games.
|
||||
///
|
||||
/// - It is automatic, which means that you can throw any level
|
||||
/// geometry at it and you will get a robust mesh out.
|
||||
/// - It is fast which means swift turnaround times for level designers.
|
||||
/// - It is open source so it comes with full source and you can
|
||||
/// customize it to your hearts content.
|
||||
///
|
||||
/// The latest version can be found on
|
||||
/// <a href="https://github.com/memononen/recastnavigation">GitHub</a>.
|
||||
///
|
||||
/// The _Recast_ process starts with constructing a voxel mold from level
|
||||
/// geometry and then casting a navigation mesh over it. The process
|
||||
/// consists of three steps, building the voxel mold, partitioning the
|
||||
/// mold into simple regions, and peeling off the regions as simple polygons.
|
||||
///
|
||||
/// -# The voxel mold is built from the input triangle mesh by
|
||||
/// rasterizing the triangles into a multi-layer heightfield. Some
|
||||
/// simple filters are then applied to the mold to prune out locations
|
||||
/// where the character would not be able to move.
|
||||
/// -# The walkable areas described by the mold are divided into simple
|
||||
/// overlayed 2D regions. The resulting regions have only one
|
||||
/// non-overlapping contour, which simplifies the final step of the
|
||||
/// process tremendously.
|
||||
/// -# The navigation polygons are peeled off from the regions by first
|
||||
/// tracing the boundaries and then simplifying them. The resulting
|
||||
/// polygons are finally converted to convex polygons which makes them
|
||||
/// perfect for pathfinding and spatial reasoning about the level.
|
||||
///
|
||||
/// <h2>Detour</h2>
|
||||
///
|
||||
/// _Recast_ is accompanied by _Detour_, a path-finding and spatial reasoning
|
||||
/// toolkit. You can use any navigation mesh with _Detour_, but of course
|
||||
/// the data generated by _Recast_ fits perfectly.
|
||||
///
|
||||
/// _Detour_ offers a simple static navigation mesh that is suitable for
|
||||
/// many simple cases, as well as a tiled navigation mesh that allows you
|
||||
/// to add and remove pieces of the mesh. The tiled mesh allows you to
|
||||
/// create systems where you stream new navigation data in and out as
|
||||
/// the player progresses the level, or regenerate tiles as the
|
||||
/// world changes.
|
||||
///
|
||||
/// <h2>Recast Demo</h2>
|
||||
///
|
||||
/// You can find a comprehensive demo project in the `RecastDemo` folder. It
|
||||
/// is a kitchen sink demo containing all the functionality of the library.
|
||||
/// If you are new to _Recast_ & _Detour_, check out
|
||||
/// <a href="https://github.com/memononen/recastnavigation/blob/master/RecastDemo/Source/Sample_SoloMesh.cpp">
|
||||
/// Sample_SoloMesh.cpp</a> to get started with building navmeshes and
|
||||
/// <a href="https://github.com/memononen/recastnavigation/blob/master/RecastDemo/Source/NavMeshTesterTool.cpp">
|
||||
/// NavMeshTesterTool.cpp</a> to see how _Detour_ can be used to find paths.
|
||||
///
|
||||
/// <h3>Building RecastDemo</h3>
|
||||
///
|
||||
/// _RecastDemo_ uses <a href="http://industriousone.com/premake">premake4</a>
|
||||
/// to build platform specific projects, now is good time to install it if
|
||||
/// you don't have it already. To build _RecastDemo_, in your favourite terminal
|
||||
/// navigate into the `RecastDemo` folder, then:
|
||||
///
|
||||
/// - OS X: `premake4 xcode4`
|
||||
/// - Windows: `premake4 vs2010`
|
||||
/// - Linux: `premake4 gmake`
|
||||
///
|
||||
/// See the _premake4_ documentation for full list of supported build file types.
|
||||
/// The projects will be created in the `RecastDemo/Build` folder. After you have
|
||||
/// compiled the project, the _RecastDemo_ executable will be located in
|
||||
/// `RecastDemo/Bin` folder.
|
||||
///
|
||||
/// <h2>Integrating With Your Own Project</h2>
|
||||
///
|
||||
/// It is recommended to add the source directories `DebugUtils`, `Detour`,
|
||||
/// `DetourCrowd`, `DetourTileCache`, and `Recast` into your own project
|
||||
/// depending on which parts of the project you need. For example your
|
||||
/// level building tool could include `DebugUtils`, `Recast`, and `Detour`,
|
||||
/// and your game runtime could just include `Detour`.
|
||||
///
|
||||
/// <h2>Discuss</h2>
|
||||
///
|
||||
/// - Discuss _Recast_ and _Detour_:
|
||||
/// <a href="http://groups.google.com/group/recastnavigation">
|
||||
/// Recast Navigation Group</a>
|
||||
/// - Development Blog:
|
||||
/// <a href="http://digestingduck.blogspot.com/">Digesting Duck</a>
|
||||
///
|
||||
/// <h2>License</h2>
|
||||
///
|
||||
/// _Recast Navigation_ is licensed under the ZLib license.
|
||||
///
|
||||
194
dep/recastnavigation/Docs/DoxygenLayout.xml
Normal file
194
dep/recastnavigation/Docs/DoxygenLayout.xml
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
<doxygenlayout version="1.0">
|
||||
<!-- Generated by doxygen 1.8.6 -->
|
||||
<!-- Navigation index tabs for HTML output -->
|
||||
<navindex>
|
||||
<tab type="mainpage" visible="yes" title=""/>
|
||||
<tab type="pages" visible="yes" title="" intro=""/>
|
||||
<tab type="modules" visible="yes" title="" intro=""/>
|
||||
<tab type="namespaces" visible="no" title="">
|
||||
<tab type="namespacelist" visible="yes" title="" intro=""/>
|
||||
<tab type="namespacemembers" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="classes" visible="yes" title="">
|
||||
<tab type="classlist" visible="yes" title="" intro=""/>
|
||||
<tab type="classindex" visible="yes" title=""/>
|
||||
<tab type="hierarchy" visible="yes" title="" intro=""/>
|
||||
<tab type="classmembers" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="files" visible="yes" title="">
|
||||
<tab type="filelist" visible="yes" title="" intro=""/>
|
||||
<tab type="globals" visible="yes" title="" intro=""/>
|
||||
</tab>
|
||||
<tab type="examples" visible="yes" title="" intro=""/>
|
||||
</navindex>
|
||||
|
||||
<!-- Layout definition for a class page -->
|
||||
<class>
|
||||
<briefdescription visible="yes"/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<inheritancegraph visible="$CLASS_GRAPH"/>
|
||||
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
|
||||
<memberdecl>
|
||||
<nestedclasses visible="yes" title=""/>
|
||||
<publictypes title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<publicslots title=""/>
|
||||
<signals title=""/>
|
||||
<publicmethods title=""/>
|
||||
<publicstaticmethods title=""/>
|
||||
<publicattributes title=""/>
|
||||
<publicstaticattributes title=""/>
|
||||
<protectedtypes title=""/>
|
||||
<protectedslots title=""/>
|
||||
<protectedmethods title=""/>
|
||||
<protectedstaticmethods title=""/>
|
||||
<protectedattributes title=""/>
|
||||
<protectedstaticattributes title=""/>
|
||||
<packagetypes title=""/>
|
||||
<packagemethods title=""/>
|
||||
<packagestaticmethods title=""/>
|
||||
<packageattributes title=""/>
|
||||
<packagestaticattributes title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
<privatetypes title=""/>
|
||||
<privateslots title=""/>
|
||||
<privatemethods title=""/>
|
||||
<privatestaticmethods title=""/>
|
||||
<privateattributes title=""/>
|
||||
<privatestaticattributes title=""/>
|
||||
<friends title=""/>
|
||||
<related title="" subtitle=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title="Description"/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<services title=""/>
|
||||
<interfaces title=""/>
|
||||
<constructors title=""/>
|
||||
<functions title=""/>
|
||||
<related title=""/>
|
||||
<variables title=""/>
|
||||
<properties title=""/>
|
||||
<events title=""/>
|
||||
</memberdef>
|
||||
<allmemberslink visible="yes"/>
|
||||
<usedfiles visible="$SHOW_USED_FILES"/>
|
||||
<authorsection visible="yes"/>
|
||||
</class>
|
||||
|
||||
<!-- Layout definition for a namespace page -->
|
||||
<namespace>
|
||||
<briefdescription visible="yes"/>
|
||||
<memberdecl>
|
||||
<nestednamespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title="Description"/>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</namespace>
|
||||
|
||||
<!-- Layout definition for a file page -->
|
||||
<file>
|
||||
<briefdescription visible="Description"/>
|
||||
<detaileddescription title=""/>
|
||||
<includes visible="$SHOW_INCLUDE_FILES"/>
|
||||
<includegraph visible="$INCLUDE_GRAPH"/>
|
||||
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
|
||||
<sourcelink visible="yes"/>
|
||||
<memberdecl>
|
||||
<classes visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<constantgroups visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<memberdef>
|
||||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
</memberdef>
|
||||
<authorsection/>
|
||||
</file>
|
||||
|
||||
<!-- Layout definition for a group page -->
|
||||
<group>
|
||||
<briefdescription visible="yes"/>
|
||||
<groupgraph visible="$GROUP_GRAPHS"/>
|
||||
<memberdecl>
|
||||
<nestedgroups visible="yes" title=""/>
|
||||
<dirs visible="yes" title=""/>
|
||||
<files visible="yes" title=""/>
|
||||
<namespaces visible="yes" title=""/>
|
||||
<classes visible="yes" title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
<membergroups visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title="Description"/>
|
||||
<memberdef>
|
||||
<pagedocs/>
|
||||
<inlineclasses title=""/>
|
||||
<defines title=""/>
|
||||
<typedefs title=""/>
|
||||
<enums title=""/>
|
||||
<enumvalues title=""/>
|
||||
<functions title=""/>
|
||||
<variables title=""/>
|
||||
<signals title=""/>
|
||||
<publicslots title=""/>
|
||||
<protectedslots title=""/>
|
||||
<privateslots title=""/>
|
||||
<events title=""/>
|
||||
<properties title=""/>
|
||||
<friends title=""/>
|
||||
</memberdef>
|
||||
<authorsection visible="yes"/>
|
||||
</group>
|
||||
|
||||
<!-- Layout definition for a directory page -->
|
||||
<directory>
|
||||
<briefdescription visible="yes"/>
|
||||
<directorygraph visible="yes"/>
|
||||
<memberdecl>
|
||||
<dirs visible="yes"/>
|
||||
<files visible="yes"/>
|
||||
</memberdecl>
|
||||
<detaileddescription title=""/>
|
||||
</directory>
|
||||
</doxygenlayout>
|
||||
587
dep/recastnavigation/Docs/Extern/Recast_api.txt
vendored
Normal file
587
dep/recastnavigation/Docs/Extern/Recast_api.txt
vendored
Normal file
|
|
@ -0,0 +1,587 @@
|
|||
// This file contains the detail API documentation for
|
||||
// elements defined in the Recast.h.
|
||||
|
||||
/**
|
||||
|
||||
@defgroup recast Recast
|
||||
|
||||
Members in this module are used to create mesh data that is then
|
||||
used to create Detour navigation meshes.
|
||||
|
||||
The are a large number of possible ways to building navigation mesh data.
|
||||
One of the simple piplines is as follows:
|
||||
|
||||
-# Prepare the input triangle mesh.
|
||||
-# Build a #rcHeightfield.
|
||||
-# Build a #rcCompactHeightfield.
|
||||
-# Build a #rcContourSet.
|
||||
-# Build a #rcPolyMesh.
|
||||
-# Build a #rcPolyMeshDetail.
|
||||
-# Use the rcPolyMesh and rcPolyMeshDetail to build a Detour navigation mesh
|
||||
tile.
|
||||
|
||||
The general life-cycle of the main classes is as follows:
|
||||
|
||||
-# Allocate the object using the Recast allocator. (E.g. #rcAllocHeightfield)
|
||||
-# Initialize or build the object. (E.g. #rcCreateHeightfield)
|
||||
-# Update the object as needed. (E.g. #rcRasterizeTriangles)
|
||||
-# Use the object as part of the pipeline.
|
||||
-# Free the object using the Recast allocator. (E.g. #rcFreeHeightField)
|
||||
|
||||
@note This is a summary list of members. Use the index or search
|
||||
feature to find minor members.
|
||||
|
||||
@struct rcConfig
|
||||
@par
|
||||
|
||||
The is a convenience structure that represents an aggregation of parameters
|
||||
used at different stages in the Recast build process. Some
|
||||
values are derived during the build process. Not all parameters
|
||||
are used for all build processes.
|
||||
|
||||
Units are usually in voxels (vx) or world units (wu). The units for voxels,
|
||||
grid size, and cell size are all based on the values of #cs and #ch.
|
||||
|
||||
In this documentation, the term 'field' refers to heightfield and
|
||||
contour data structures that define spacial information using an integer
|
||||
grid.
|
||||
|
||||
The upper and lower limits for the various parameters often depend on
|
||||
the platform's floating point accuraccy as well as interdependencies between
|
||||
the values of multiple parameters. See the individual parameter
|
||||
documentation for details.
|
||||
|
||||
@var rcConfig::borderSize
|
||||
@par
|
||||
|
||||
This value represents the the closest the walkable area of the heightfield
|
||||
should come to the xz-plane AABB of the field. It does not have any
|
||||
impact on the borders around internal obstructions.
|
||||
|
||||
@var rcConfig::tileSize
|
||||
@par
|
||||
|
||||
This field is only used when building multi-tile meshes.
|
||||
|
||||
@var rcConfig::cs
|
||||
@par
|
||||
|
||||
@p cs and #ch define voxel/grid/cell size. So their values have significant
|
||||
side effects on all parameters defined in voxel units.
|
||||
|
||||
The minimum value for this parameter depends on the platform's floating point
|
||||
accuracy, with the practical minimum usually around 0.05.
|
||||
|
||||
@var rcConfig::ch
|
||||
@par
|
||||
|
||||
#cs and @p ch define voxel/grid/cell size. So their values have significant
|
||||
side effects on all parameters defined in voxel units.
|
||||
|
||||
The minimum value for this parameter depends on the platform's floating point
|
||||
accuracy, with the practical minimum usually around 0.05.
|
||||
|
||||
@var rcConfig::walkableSlopeAngle
|
||||
@par
|
||||
|
||||
The practical upper limit for this parameter is usually around 85 degrees.
|
||||
|
||||
@var rcConfig::walkableHeight
|
||||
@par
|
||||
|
||||
Permits detection of overhangs in the source geometry that make the geometry
|
||||
below un-walkable. The value is usually set to the maximum agent height.
|
||||
|
||||
@var rcConfig::walkableClimb
|
||||
@par
|
||||
|
||||
Allows the mesh to flow over low lying obstructions such as curbs and
|
||||
up/down stairways. The value is usually set to how far up/down an agent can step.
|
||||
|
||||
@var rcConfig::walkableRadius
|
||||
@par
|
||||
|
||||
In general, this is the closest any part of the final mesh should get to an
|
||||
obstruction in the source geometry. It is usually set to the maximum
|
||||
agent radius.
|
||||
|
||||
While a value of zero is legal, it is not recommended and can result in
|
||||
odd edge case issues.
|
||||
|
||||
@var rcConfig::maxEdgeLen
|
||||
@par
|
||||
|
||||
Extra vertices will be inserted as needed to keep contour edges below this
|
||||
length. A value of zero effectively disables this feature.
|
||||
|
||||
@var rcConfig::maxSimplificationError
|
||||
@par
|
||||
|
||||
The effect of this parameter only applies to the xz-plane.
|
||||
|
||||
@var rcConfig::minRegionArea
|
||||
@par
|
||||
|
||||
Any regions that are smaller than this area will be marked as unwalkable.
|
||||
This is useful in removing useless regions that can sometimes form on
|
||||
geometry such as table tops, box tops, etc.
|
||||
|
||||
@var rcConfig::maxVertsPerPoly
|
||||
@par
|
||||
|
||||
If the mesh data is to be used to construct a Detour navigation mesh, then the upper limit
|
||||
is limited to <= #DT_VERTS_PER_POLYGON.
|
||||
|
||||
|
||||
@struct rcHeightfield
|
||||
@par
|
||||
|
||||
The grid of a heightfield is layed out on the xz-plane based on the
|
||||
value of #cs. Spans exist within the grid columns with the span
|
||||
min/max values at increments of #ch from the base of the grid. The smallest
|
||||
possible span size is <tt>(#cs width) * (#cs depth) * (#ch height)</tt>. (Which is a single voxel.)
|
||||
|
||||
The standard process for buidling a heightfield is to allocate it using
|
||||
#rcAllocHeightfield, initialize it using #rcCreateHeightfield, then
|
||||
add spans using the various helper functions such as #rcRasterizeTriangle.
|
||||
|
||||
Building a heightfield is one of the first steps in creating a polygon mesh
|
||||
from source geometry. After it is populated, it is used to build a
|
||||
rcCompactHeightfield.
|
||||
|
||||
Example of iterating the spans in a heightfield:
|
||||
@code
|
||||
// Where hf is a reference to an heightfield object.
|
||||
|
||||
const float* orig = hf.bmin;
|
||||
const float cs = hf.cs;
|
||||
const float ch = hf.ch;
|
||||
|
||||
const int w = hf.width;
|
||||
const int h = hf.height;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
// Deriving the minimum corner of the grid location.
|
||||
float fx = orig[0] + x*cs;
|
||||
float fz = orig[2] + y*cs;
|
||||
// The base span in the column. (May be null.)
|
||||
const rcSpan* s = hf.spans[x + y*w];
|
||||
while (s)
|
||||
{
|
||||
// Detriving the minium and maximum world position of the span.
|
||||
float fymin = orig[1]+s->smin*ch;
|
||||
float fymax = orig[1] + s->smax*ch;
|
||||
// Do other things with the span before moving up the column.
|
||||
s = s->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see rcAllocHeightfield, rcFreeHeightField, rcCreateHeightfield
|
||||
|
||||
@struct rcCompactCell
|
||||
@par
|
||||
|
||||
See the rcCompactHeightfield documentation for an example of how compact cells
|
||||
are used to iterate the heightfield.
|
||||
|
||||
Useful instances of this type can only by obtained from a #rcCompactHeightfield object.
|
||||
|
||||
@see rcCompactHeightfield
|
||||
|
||||
@struct rcCompactSpan
|
||||
@par
|
||||
|
||||
The span represents open, unobstructed space within a compact heightfield column.
|
||||
See the rcCompactHeightfield documentation for an example of iterating spans and searching
|
||||
span connections.
|
||||
|
||||
Useful instances of this type can only by obtained from a #rcCompactHeightfield object.
|
||||
|
||||
@see rcCompactHeightfield
|
||||
|
||||
|
||||
@struct rcCompactHeightfield
|
||||
@par
|
||||
|
||||
For this type of heightfield, the spans represent the open (unobstructed)
|
||||
space above the solid surfaces of a voxel field. It is usually created from
|
||||
a #rcHeightfield object. Data is stored in a compact, efficient manner,
|
||||
but the structure is not condusive to adding and removing spans.
|
||||
|
||||
The standard process for buidling a compact heightfield is to allocate it
|
||||
using #rcAllocCompactHeightfield, build it using #rcBuildCompactHeightfield,
|
||||
then run it through the various helper functions to generate neighbor
|
||||
and region data.
|
||||
|
||||
Connected neighbor spans form non-overlapping surfaces. When neighbor
|
||||
information is generated, spans will include data that can be used to
|
||||
locate axis-neighbors. Axis-neighbors are connected
|
||||
spans that are offset from the current cell column as follows:
|
||||
<pre>
|
||||
Direction 0 = (-1, 0)
|
||||
Direction 1 = (0, 1)
|
||||
Direction 2 = (1, 0)
|
||||
Direction 3 = (0, -1)
|
||||
</pre>
|
||||
|
||||
Example of iterating and inspecting spans, including connected neighbors:
|
||||
|
||||
@code
|
||||
// Where chf is an instance of a rcCompactHeightfield.
|
||||
|
||||
const float cs = chf.cs;
|
||||
const float ch = chf.ch;
|
||||
|
||||
for (int y = 0; y < chf.height; ++y)
|
||||
{
|
||||
for (int x = 0; x < chf.width; ++x)
|
||||
{
|
||||
// Deriving the minimum corner of the grid location.
|
||||
const float fx = chf.bmin[0] + x*cs;
|
||||
const float fz = chf.bmin[2] + y*cs;
|
||||
|
||||
// Get the cell for the grid location then iterate
|
||||
// up the column.
|
||||
const rcCompactCell& c = chf.cells[x+y*chf.width];
|
||||
for (unsigned i = c.index, ni = c.index+c.count; i < ni; ++i)
|
||||
{
|
||||
const rcCompactSpan& s = chf.spans[i];
|
||||
|
||||
Deriving the minimum (floor) of the span.
|
||||
const float fy = chf.bmin[1] + (s.y+1)*ch;
|
||||
|
||||
// Testing the area assignment of the span.
|
||||
if (chf.areas[i] == RC_WALKABLE_AREA)
|
||||
{
|
||||
// The span is in the default 'walkable area'.
|
||||
}
|
||||
else if (chf.areas[i] == RC_NULL_AREA)
|
||||
{
|
||||
// The surface is not considered walkable.
|
||||
// E.g. It was filtered out during the build processes.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do something. (Only applicable for custom build
|
||||
// build processes.)
|
||||
}
|
||||
|
||||
// Iterating the connected axis-neighbor spans.
|
||||
for (int dir = 0; dir < 4; ++dir)
|
||||
{
|
||||
if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
|
||||
{
|
||||
// There is a neighbor in this direction.
|
||||
const int nx = x + rcGetDirOffsetX(dir);
|
||||
const int ny = y + rcGetDirOffsetY(dir);
|
||||
const int ni = (int)chf.cells[nx+ny*w].index + rcGetCon(s, 0);
|
||||
const rcCompactSpan& ns = chf.spans[ni];
|
||||
// Do something with the neighbor span.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see rcAllocCompactHeightfield, rcFreeCompactHeightfield, rcBuildCompactHeightfield
|
||||
|
||||
@struct rcContour
|
||||
@par
|
||||
|
||||
A contour only exists within the context of a #rcContourSet object.
|
||||
|
||||
While the height of the contour's border may vary, the contour will always
|
||||
form a simple polygon when projected onto the xz-plane.
|
||||
|
||||
Example of converting vertices into world space:
|
||||
|
||||
@code
|
||||
// Where cset is the rcContourSet object to which the contour belongs.
|
||||
float worldX = cset.bmin[0] + vertX * cset.cs;
|
||||
float worldY = cset.bmin[1] + vertY * cset.ch;
|
||||
float worldZ = cset.bmin[2] + vertZ * cset.cs;
|
||||
@endcode
|
||||
|
||||
@see rcContourSet
|
||||
|
||||
@var rcContour::verts
|
||||
@par
|
||||
|
||||
The simplified contour is a version of the raw contour with all
|
||||
'unnecessary' vertices removed. Whether a vertex is
|
||||
considered unnecessary depends on the contour build process.
|
||||
|
||||
The data format is as follows: (x, y, z, r) * #nverts
|
||||
|
||||
A contour edge is formed by the current and next vertex. The r-value
|
||||
represents region and connection information for the edge. For example:
|
||||
|
||||
@code
|
||||
int r = verts[i*4+3];
|
||||
|
||||
int regionId = r & RC_CONTOUR_REG_MASK;
|
||||
|
||||
if (r & RC_BORDER_VERTEX)
|
||||
{
|
||||
// The edge represents a solid border.
|
||||
}
|
||||
|
||||
if (r & RC_AREA_BORDER)
|
||||
{
|
||||
// The edge represents a transition between different areas.
|
||||
}
|
||||
@endcode
|
||||
|
||||
@var rcContour::rverts
|
||||
@par
|
||||
|
||||
See #verts for information on element layout.
|
||||
|
||||
@struct rcContourSet
|
||||
@par
|
||||
|
||||
All contours within the set share the minimum bounds and cell sizes of the set.
|
||||
|
||||
The standard process for building a contour set is to allocate it
|
||||
using #rcAllocContourSet, then initialize it using #rcBuildContours.
|
||||
|
||||
@see rcAllocContourSet, rcFreeContourSet, rcBuildContours
|
||||
|
||||
@struct rcPolyMesh
|
||||
@par
|
||||
|
||||
A mesh of potentially overlapping convex polygons of between three
|
||||
and #nvp vertices. The mesh exists within the context of an axis-aligned
|
||||
bounding box (AABB) with vertices laid out in an evenly spaced grid, based
|
||||
on the values of #cs and #ch.
|
||||
|
||||
The standard process for building a contour set is to allocate it using
|
||||
#rcAllocPolyMesh, the initialize it using #rcBuildPolyMesh
|
||||
|
||||
Example of iterating the polygons:
|
||||
|
||||
@code
|
||||
// Where mesh is a reference to a rcPolyMesh object.
|
||||
|
||||
const int nvp = mesh.nvp;
|
||||
const float cs = mesh.cs;
|
||||
const float ch = mesh.ch;
|
||||
const float* orig = mesh.bmin;
|
||||
|
||||
for (int i = 0; i < mesh.npolys; ++i)
|
||||
{
|
||||
const unsigned short* p = &mesh.polys[i*nvp*2];
|
||||
|
||||
// Iterate the vertices.
|
||||
unsigned short vi[3]; // The vertex indices.
|
||||
for (int j = 0; j < nvp; ++j)
|
||||
{
|
||||
if (p[j] == RC_MESH_NULL_IDX)
|
||||
break; // End of vertices.
|
||||
|
||||
if (p[j + nvp] == RC_MESH_NULL_IDX)
|
||||
{
|
||||
// The edge beginning with this vertex is a solid border.
|
||||
}
|
||||
else
|
||||
{
|
||||
// The edge beginning with this vertex connects to
|
||||
// polygon p[j + nvp].
|
||||
}
|
||||
|
||||
// Convert to world space.
|
||||
const unsigned short* v = &mesh.verts[p[j]*3];
|
||||
const float x = orig[0] + v[0]*cs;
|
||||
const float y = orig[1] + v[1]*ch;
|
||||
const float z = orig[2] + v[2]*cs;
|
||||
// Do something with the vertices.
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
@see rcAllocPolyMesh, rcFreePolyMesh, rcBuildPolyMesh
|
||||
|
||||
@var rcPolyMesh::verts
|
||||
@par
|
||||
|
||||
The values of #bmin ,#cs, and #ch are used to convert vertex coordinates
|
||||
to world space as follows:
|
||||
|
||||
@code
|
||||
float worldX = bmin[0] + verts[i*3+0] * cs
|
||||
float worldY = bmin[1] + verts[i*3+1] * ch
|
||||
float worldZ = bmin[2] + verts[i*3+2] * cs
|
||||
@endcode
|
||||
|
||||
@var rcPolyMesh::polys
|
||||
@par
|
||||
|
||||
Each entry is <tt>2 * #nvp</tt> in length. The first half of the entry
|
||||
contains the indices of the polygon. The first instance of #RC_MESH_NULL_IDX
|
||||
indicates the end of the indices for the entry. The second half contains
|
||||
indices to neighbor polygons. A value of #RC_MESH_NULL_IDX indicates no
|
||||
connection for the associated edge. (I.e. The edge is a solid border.)
|
||||
|
||||
For example:
|
||||
<pre>
|
||||
nvp = 6
|
||||
For the entry: (1, 3, 4, 8, RC_MESH_NULL_IDX, RC_MESH_NULL_IDX,
|
||||
18, RC_MESH_NULL_IDX , 21, RC_MESH_NULL_IDX, RC_MESH_NULL_IDX, RC_MESH_NULL_IDX)
|
||||
|
||||
(1, 3, 4, 8) defines a polygon with 4 vertices.
|
||||
Edge 1->3 is shared with polygon 18.
|
||||
Edge 4->8 is shared with polygon 21.
|
||||
Edges 3->4 and 4->8 are border edges not shared with any other polygon.
|
||||
</pre>
|
||||
|
||||
@var rcPolyMesh::areas
|
||||
@par
|
||||
|
||||
The standard build process assigns the value of #RC_WALKABLE_AREA to all walkable polygons.
|
||||
This value can then be changed to meet user requirements.
|
||||
|
||||
@struct rcPolyMeshDetail
|
||||
@par
|
||||
|
||||
The detail mesh is made up of triangle sub-meshes that provide extra
|
||||
height detail for each polygon in its assoicated polygon mesh.
|
||||
|
||||
The standard process for building a detail mesh is to allocate it
|
||||
using #rcAllocPolyMeshDetail, then build it using #rcBuildPolyMeshDetail.
|
||||
|
||||
See the individual field definitions for details realted to the structure
|
||||
the mesh.
|
||||
|
||||
@see rcAllocPolyMeshDetail, rcFreePolyMeshDetail, rcBuildPolyMeshDetail, rcPolyMesh
|
||||
|
||||
@var rcPolyMeshDetail::meshes
|
||||
@par
|
||||
|
||||
[(baseVertIndex, vertCount, baseTriIndex, triCount) * #nmeshes]
|
||||
|
||||
Maximum number of vertices per sub-mesh: 127<br/>
|
||||
Maximum number of triangles per sub-mesh: 255
|
||||
|
||||
The sub-meshes are stored in the same order as the polygons from the
|
||||
rcPolyMesh they represent. E.g. rcPolyMeshDetail sub-mesh 5 is associated
|
||||
with #rcPolyMesh polygon 5.
|
||||
|
||||
Example of iterating the triangles in a sub-mesh.
|
||||
|
||||
@code
|
||||
// Where dmesh is a reference to a rcPolyMeshDetail object.
|
||||
|
||||
// Iterate the sub-meshes. (One for each source polygon.)
|
||||
for (int i = 0; i < dmesh.nmeshes; ++i)
|
||||
{
|
||||
const unsigned int* meshDef = &dmesh.meshes[i*4];
|
||||
const unsigned int baseVerts = meshDef[0];
|
||||
const unsigned int baseTri = meshDef[2];
|
||||
const int ntris = (int)meshDef[3];
|
||||
|
||||
const float* verts = &dmesh.verts[baseVerts*3];
|
||||
const unsigned char* tris = &dmesh.tris[baseTri*4];
|
||||
|
||||
// Iterate the sub-mesh's triangles.
|
||||
for (int j = 0; j < ntris; ++j)
|
||||
{
|
||||
const float x = verts[tris[j*4+0]*3];
|
||||
const float y = verts[tris[j*4+1]*3];
|
||||
const float z = verts[tris[j*4+2]*3];
|
||||
// Do something with the vertex.
|
||||
}
|
||||
}
|
||||
@endcode
|
||||
|
||||
@var rcPolyMeshDetail::verts
|
||||
@par
|
||||
|
||||
[(x, y, z) * #nverts]
|
||||
|
||||
The vertices are grouped by sub-mesh and will contain duplicates since
|
||||
each sub-mesh is independently defined.
|
||||
|
||||
The first group of vertices for each sub-mesh are in the same order as
|
||||
the vertices for the sub-mesh's associated PolyMesh polygon. These
|
||||
vertices are followed by any additional detail vertices. So it the
|
||||
associated polygon has 5 vertices, the sub-mesh will have a minimum
|
||||
of 5 vertices and the first 5 vertices will be equivalent to the 5
|
||||
polygon vertices.
|
||||
|
||||
@var rcPolyMeshDetail::tris
|
||||
@par
|
||||
|
||||
[(vertIndexA, vertIndexB, vertIndexC, flags) * #ntris]
|
||||
|
||||
The triangles are grouped by sub-mesh.
|
||||
|
||||
<b>Vertex Indices</b>
|
||||
|
||||
The vertex indices in the triangle array are local to the sub-mesh, not global.
|
||||
To translate into an global index in the vertices array, the values must be
|
||||
offset by the sub-mesh's base vertex index.
|
||||
|
||||
Example: If the baseVertexIndex for the sub-mesh is 5 and the triangle entry
|
||||
is (4, 8, 7, 0), then the actual indices for the vertices are (4 + 5, 8 + 5, 7 + 5).
|
||||
|
||||
@b Flags
|
||||
|
||||
The flags entry indicates which edges are internal and which are external to
|
||||
the sub-mesh. Internal edges connect to other triangles within the same sub-mesh.
|
||||
External edges represent portals to other sub-meshes or the null region.
|
||||
|
||||
Each flag is stored in a 2-bit position. Where position 0 is the lowest 2-bits
|
||||
and position 4 is the highest 2-bits:
|
||||
|
||||
<tt>
|
||||
Position 0: Edge AB (>> 0)<br/>
|
||||
Position 1: Edge BC (>> 2)<br/>
|
||||
Position 2: Edge CA (>> 4)<br/>
|
||||
Position 4: Unused<br/>
|
||||
</tt>
|
||||
|
||||
Testing can be performed as follows:
|
||||
|
||||
@code
|
||||
if (((flags >> 2) & 0x3) != 0)
|
||||
{
|
||||
// Edge BC is an external edge.
|
||||
}
|
||||
@endcode
|
||||
|
||||
@fn void rcSetCon(rcCompactSpan &s, int dir, int i)
|
||||
@par
|
||||
|
||||
This function is used by the build process. It is rarely of use to end users.
|
||||
|
||||
@see #rcCompactHeightfield, #rcCompactSpan
|
||||
|
||||
@fn int rcGetCon(const rcCompactSpan &s, int dir)
|
||||
@par
|
||||
|
||||
Can be used to locate neighbor spans in a compact heightfield. See the
|
||||
#rcCompactHeightfield documentation for details on its use.
|
||||
|
||||
@see #rcCompactHeightfield, #rcCompactSpan
|
||||
|
||||
@fn int rcGetDirOffsetX(int dir)
|
||||
@par
|
||||
|
||||
The value of @p dir will be automatically wrapped. So a value of 6 will be interpreted as 2.
|
||||
|
||||
See the #rcCompactHeightfield documentation for usage details.
|
||||
|
||||
@fn int rcGetDirOffsetY(int dir)
|
||||
@par
|
||||
|
||||
The value of @p dir will be automatically wrapped. So a value of 6 will be interpreted as 2.
|
||||
|
||||
See the #rcCompactHeightfield documentation for usage details.
|
||||
|
||||
*/
|
||||
BIN
dep/recastnavigation/Docs/Images/recast_intro.png
Normal file
BIN
dep/recastnavigation/Docs/Images/recast_intro.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 370 KiB |
64
dep/recastnavigation/Docs/Readme.txt
Normal file
64
dep/recastnavigation/Docs/Readme.txt
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
This directory contains source for the documentation. It is also the
|
||||
build target for doxygen output.
|
||||
|
||||
Directory Layout
|
||||
|
||||
. (Docs root)
|
||||
|
||||
High level content and format files. (E.g. css, header, footer.)
|
||||
|
||||
./Conceptual
|
||||
|
||||
Conceptual (non-api) documentation such as overviews, how-to's, etc.
|
||||
The main index page content is also in this directory.
|
||||
|
||||
./Extern
|
||||
|
||||
API documentation that is located outside the source files.
|
||||
|
||||
When the API documentation gets too big or complex for the header
|
||||
and source files, it goes in this directory.
|
||||
|
||||
./Images
|
||||
|
||||
Images related to the documentation.
|
||||
|
||||
./html
|
||||
|
||||
The target for the Doxygen build. (Created during the build process.)
|
||||
|
||||
Miscellany
|
||||
|
||||
One of the requirements for the API documentation is that it
|
||||
has the minimum possible impact on the declarations in the
|
||||
header files. So, in general, the header file declarations only
|
||||
contain summary documentation. The detail documentation
|
||||
is placed as follows:
|
||||
|
||||
1. If an element is defined in a cpp file, then place
|
||||
the detail documentation in the source file.
|
||||
2. If an element does not have an associated cpp file, then
|
||||
place the detail documentation at the end of the header file.
|
||||
3. If there is a lot of detail documentation cluttering up
|
||||
the end of a header file, then the content is moved to
|
||||
a separate file in the Extern directory.
|
||||
|
||||
Building the Documentation
|
||||
|
||||
1. Download and install the appropriate Doxygen version. (See the first
|
||||
line in the Doxyfile for the current version.)
|
||||
2. Run "doxygen" in the project root directory. (The location of the Doxyfile.)
|
||||
No arguments are required.
|
||||
|
||||
The generated html files will be located in the /Docs/html directory.
|
||||
|
||||
If you want to "version" the documentation, you can set the PROJECT_NUMBER
|
||||
setting in the Doxyfile. E.g. PROJECT_NUMBER = "(2014-04-23)". The project
|
||||
number will be added to the header of the documentation.
|
||||
E.g. "Recast Navigation (2014-04-23)"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
21
dep/recastnavigation/Docs/footer.html
Normal file
21
dep/recastnavigation/Docs/footer.html
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<!-- HTML footer for doxygen 1.8.6-->
|
||||
<!-- start footer part -->
|
||||
<!--BEGIN GENERATE_TREEVIEW-->
|
||||
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
|
||||
<ul>
|
||||
$navpath
|
||||
<a href="https://github.com/memononen/recastnavigation">Project Home</a>
|
||||
| <a href="./License.html">Licence: ZLib</a>
|
||||
| Copyright (c) 2009-2014 Mikko Mononen
|
||||
</ul>
|
||||
</div>
|
||||
<!--END GENERATE_TREEVIEW-->
|
||||
<!--BEGIN !GENERATE_TREEVIEW-->
|
||||
<hr class="footer"/><address class="footer"><small>
|
||||
<a href="https://github.com/memononen/recastnavigation">Project Home</a>
|
||||
| <a href="./License.html">Licence: ZLib</a>
|
||||
| Copyright (c) 2009-2014 Mikko Mononen
|
||||
</small></address>
|
||||
<!--END !GENERATE_TREEVIEW-->
|
||||
</body>
|
||||
</html>
|
||||
55
dep/recastnavigation/Docs/header.html
Normal file
55
dep/recastnavigation/Docs/header.html
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<!-- HTML header for doxygen 1.8.6-->
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||||
<meta name="generator" content="Doxygen $doxygenversion"/>
|
||||
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
|
||||
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
|
||||
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
|
||||
<script type="text/javascript" src="$relpath^jquery.js"></script>
|
||||
<script type="text/javascript" src="$relpath^dynsections.js"></script>
|
||||
$treeview
|
||||
$search
|
||||
$mathjax
|
||||
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
|
||||
$extrastylesheet
|
||||
</head>
|
||||
<body>
|
||||
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
|
||||
|
||||
<!--BEGIN TITLEAREA-->
|
||||
<div id="titlearea">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr style="height: 56px;">
|
||||
<!--BEGIN PROJECT_LOGO-->
|
||||
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
|
||||
<!--END PROJECT_LOGO-->
|
||||
<!--BEGIN PROJECT_NAME-->
|
||||
<td style="padding-left: 0.5em;">
|
||||
<div id="projectname">$projectname
|
||||
<!--BEGIN PROJECT_NUMBER--> <span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->
|
||||
</div>
|
||||
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
|
||||
</td>
|
||||
<!--END PROJECT_NAME-->
|
||||
<!--BEGIN !PROJECT_NAME-->
|
||||
<!--BEGIN PROJECT_BRIEF-->
|
||||
<td style="padding-left: 0.5em;">
|
||||
<div id="projectbrief">$projectbrief</div>
|
||||
</td>
|
||||
<!--END PROJECT_BRIEF-->
|
||||
<!--END !PROJECT_NAME-->
|
||||
<!--BEGIN DISABLE_INDEX-->
|
||||
<!--BEGIN SEARCHENGINE-->
|
||||
<td>$searchbox</td>
|
||||
<!--END SEARCHENGINE-->
|
||||
<!--END DISABLE_INDEX-->
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!--END TITLEAREA-->
|
||||
<!-- end header part -->
|
||||
2342
dep/recastnavigation/Doxyfile
Normal file
2342
dep/recastnavigation/Doxyfile
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -2,11 +2,7 @@
|
|||
Recast & Detour
|
||||
===============
|
||||
|
||||
[](https://travis-ci.org/recastnavigation/recastnavigation)
|
||||
[](https://ci.appveyor.com/project/recastnavigation/recastnavigation/branch/master)
|
||||
|
||||
[](http://www.issuestats.com/github/recastnavigation/recastnavigation)
|
||||
[](http://www.issuestats.com/github/recastnavigation/recastnavigation)
|
||||
[](https://bitdeli.com/free "Bitdeli Badge")
|
||||
|
||||

|
||||
|
||||
|
|
@ -23,7 +19,7 @@ and then casting a navigation mesh over it. The process consists of three steps,
|
|||
building the voxel mold, partitioning the mold into simple regions, peeling off
|
||||
the regions as simple polygons.
|
||||
|
||||
1. The voxel mold is built from the input triangle mesh by rasterizing the triangles into a multi-layer heightfield. Some simple filters are then applied to the mold to prune out locations where the character would not be able to move.
|
||||
1. The voxel mold is build from the input triangle mesh by rasterizing the triangles into a multi-layer heightfield. Some simple filters are then applied to the mold to prune out locations where the character would not be able to move.
|
||||
2. The walkable areas described by the mold are divided into simple overlayed 2D regions. The resulting regions have only one non-overlapping contour, which simplifies the final step of the process tremendously.
|
||||
3. The navigation polygons are peeled off from the regions by first tracing the boundaries and then simplifying them. The resulting polygons are finally converted to convex polygons which makes them perfect for pathfinding and spatial reasoning about the level.
|
||||
|
||||
|
|
@ -41,49 +37,26 @@ You can find a comprehensive demo project in RecastDemo folder. It is a kitchen
|
|||
|
||||
### Building RecastDemo
|
||||
|
||||
RecastDemo uses [premake5](http://premake.github.io/) to build platform specific projects. Download it and make sure it's available on your path, or specify the path to it.
|
||||
RecastDemo uses [premake4](http://industriousone.com/premake) to build platform specific projects, now is good time to install it if you don't have it already. To build *RecasDemo*, in your favorite terminal navigate into the `RecastDemo` folder, then:
|
||||
|
||||
#### Linux
|
||||
- *OS X*: `premake4 xcode4`
|
||||
- *Windows*: `premake4 vs2010`
|
||||
- *Linux*: `premake4 gmake`
|
||||
|
||||
- Install SDL2 and its dependencies according to your distro's guidelines.
|
||||
- run `premake5 gmake` from the `RecastDemo` folder.
|
||||
- `cd Build/gmake` then `make`
|
||||
- Run `RecastDemo\Bin\RecastDemo`
|
||||
See premake4 documentation for full list of supported build file types. The projects will be created in `RecastDemo/Build` folder. And after you have compiled the project, the *RecastDemo* executable will be located in `RecastDemo/Bin` folder.
|
||||
|
||||
#### OSX
|
||||
|
||||
- Grab the latest SDL2 development library dmg from [here](https://www.libsdl.org/download-2.0.php) and place `SDL2.framework` in `/Library/Frameworks/`
|
||||
- Navigate to the `RecastDemo` folder and run `premake5 xcode4`
|
||||
- Open `Build/xcode4/recastnavigation.xcworkspace`
|
||||
- Select the "RecastDemo" project in the left pane, go to the "BuildPhases" tab and expand "Link Binary With Libraries"
|
||||
- Remove the existing entry for SDL2 (it should have a white box icon) and re-add it by hitting the plus, selecting "Add Other", and selecting `/Library/Frameworks/SDL2.framework`. It should now have a suitcase icon.
|
||||
- Set the RecastDemo project as the target and build.
|
||||
|
||||
#### Windows
|
||||
|
||||
- Grab the latest SDL2 development library release from [here](https://www.libsdl.org/download-2.0.php) and unzip it `RecastDemo\Contrib`. Rename the SDL folder such that the path `RecastDemo\Contrib\SDL\lib\x86` is valid.
|
||||
- Run `"premake5" vs2015` from the `RecastDemo` folder
|
||||
- Open the solution, build, and run.
|
||||
|
||||
### Running Unit tests
|
||||
|
||||
- Follow the instructions to build RecastDemo above. Premake should generate another build target called "Tests".
|
||||
- Build the "Tests" project. This will generate an executable named "Tests" in `RecastDemo/Bin/`
|
||||
- Run the "Tests" executable. It will execute all the unit tests, indicate those that failed, and display a count of those that succeeded.
|
||||
|
||||
## Integrating with your own project
|
||||
|
||||
It is recommended to add the source directories `DebugUtils`, `Detour`, `DetourCrowd`, `DetourTileCache`, and `Recast` into your own project depending on which parts of the project you need. For example your level building tool could include `DebugUtils`, `Recast`, and `Detour`, and your game runtime could just include `Detour`.
|
||||
It is recommended to add the source directories `DebugUtils`, `Detour`, `DetourCrowd`, `DetourTileCache`, and `Recast` into your own project depending on which parts of the project you need. For example your level building tool could include DebugUtils, Recast, and Detour, and your game runtime could just include Detour.
|
||||
|
||||
## Contributing
|
||||
|
||||
See the [Contributing document](CONTRIBUTING.md) for guidelines for making contributions.
|
||||
|
||||
## Discuss
|
||||
|
||||
- Discuss Recast & Detour: http://groups.google.com/group/recastnavigation
|
||||
- Development blog: http://digestingduck.blogspot.com/
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Recast & Detour is licensed under ZLib license, see License.txt for more information.
|
||||
|
|
|
|||
|
|
@ -1,17 +1,40 @@
|
|||
project(Recast VERSION 1.0.0)
|
||||
# MaNGOS is a full featured server for World of Warcraft, supporting
|
||||
# the following clients: 1.12.x, 2.4.3, 3.2.5a, 4.2.3 and 5.4.8
|
||||
#
|
||||
# Copyright (C) 2005-2019 MaNGOS project <http://getmangos.eu>
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
# and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
|
||||
file(GLOB RCT_SOURCES Source/*.cpp)
|
||||
file(GLOB RCT_INCLUDES Include/*.h)
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define the Recast library
|
||||
file(GLOB sources Source/*.cpp)
|
||||
file(GLOB headers Include/*.h)
|
||||
|
||||
add_library(Recast STATIC ${RCT_SOURCES} ${RCT_INCLUDES})
|
||||
add_library(RecastNavigation::Recast ALIAS Recast)
|
||||
set(Recast_LIB_SRCS ${sources} ${headers})
|
||||
|
||||
target_include_directories(Recast
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Include
|
||||
include_directories(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Include"
|
||||
)
|
||||
|
||||
set_target_properties(Recast
|
||||
PROPERTIES
|
||||
VERSION 1.0.0
|
||||
)
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build the Recast library
|
||||
add_library(recast STATIC ${Recast_LIB_SRCS})
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
26
dep/recastnavigation/Recast/win/Recast_VC110.sln
Normal file
26
dep/recastnavigation/Recast/win/Recast_VC110.sln
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Recast", "VC110\Recast.vcxproj", "{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|x64.Build.0 = Debug|x64
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|Win32.Build.0 = Release|Win32
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|x64.ActiveCfg = Release|x64
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
28
dep/recastnavigation/Recast/win/Recast_VC120.sln
Normal file
28
dep/recastnavigation/Recast/win/Recast_VC120.sln
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Recast", "VC120\Recast.vcxproj", "{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Debug|x64.Build.0 = Debug|x64
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|Win32.Build.0 = Release|Win32
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|x64.ActiveCfg = Release|x64
|
||||
{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
6
dep/recastnavigation/Recast/win/VC110/.gitignore
vendored
Normal file
6
dep/recastnavigation/Recast/win/VC110/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
*__Win32_Release
|
||||
*__Win32_Debug
|
||||
*__x64_Release
|
||||
*__x64_Debug
|
||||
*.user
|
||||
161
dep/recastnavigation/Recast/win/VC110/Recast.vcxproj
Normal file
161
dep/recastnavigation/Recast/win/VC110/Recast.vcxproj
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}</ProjectGuid>
|
||||
<RootNamespace>Recast</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;DEBUG;_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;DEBUG;_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\Include\Recast.h" />
|
||||
<ClInclude Include="..\..\Include\RecastAlloc.h" />
|
||||
<ClInclude Include="..\..\Include\RecastAssert.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\Source\Recast.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastAlloc.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastArea.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastContour.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastFilter.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastMesh.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastMeshDetail.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastRasterization.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastRegion.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
51
dep/recastnavigation/Recast/win/VC110/Recast.vcxproj.filters
Normal file
51
dep/recastnavigation/Recast/win/VC110/Recast.vcxproj.filters
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
<UniqueIdentifier>{ef95c759-27da-462b-9f5e-d599017cb842}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="include">
|
||||
<UniqueIdentifier>{4ea80bc1-958b-4d16-b708-675bc74de83d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\Include\Recast.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\RecastAlloc.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\RecastAssert.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\Source\Recast.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastAlloc.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastArea.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastContour.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastFilter.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastMesh.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastMeshDetail.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastRasterization.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastRegion.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
dep/recastnavigation/Recast/win/VC120/.gitignore
vendored
Normal file
6
dep/recastnavigation/Recast/win/VC120/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
*__Win32_Release
|
||||
*__Win32_Debug
|
||||
*__x64_Release
|
||||
*__x64_Debug
|
||||
*.user
|
||||
161
dep/recastnavigation/Recast/win/VC120/Recast.vcxproj
Normal file
161
dep/recastnavigation/Recast/win/VC120/Recast.vcxproj
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{00B9DC66-96A6-465D-A6C1-5DFF94E48A64}</ProjectGuid>
|
||||
<RootNamespace>Recast</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(ProjectDir)\..\..\..\..\lib\$(Platform)_$(Configuration)\</OutDir>
|
||||
<IntDir>.\$(ProjectName)__$(Platform)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;DEBUG;_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;DEBUG;_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_MBCS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\Include\Recast.h" />
|
||||
<ClInclude Include="..\..\Include\RecastAlloc.h" />
|
||||
<ClInclude Include="..\..\Include\RecastAssert.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\Source\Recast.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastAlloc.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastArea.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastContour.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastFilter.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastMesh.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastMeshDetail.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastRasterization.cpp" />
|
||||
<ClCompile Include="..\..\Source\RecastRegion.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
51
dep/recastnavigation/Recast/win/VC120/Recast.vcxproj.filters
Normal file
51
dep/recastnavigation/Recast/win/VC120/Recast.vcxproj.filters
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="src">
|
||||
<UniqueIdentifier>{ef95c759-27da-462b-9f5e-d599017cb842}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="include">
|
||||
<UniqueIdentifier>{4ea80bc1-958b-4d16-b708-675bc74de83d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\Include\Recast.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\RecastAlloc.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Include\RecastAssert.h">
|
||||
<Filter>include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\Source\Recast.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastAlloc.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastArea.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastContour.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastFilter.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastMesh.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastMeshDetail.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastRasterization.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\Source\RecastRegion.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
60
dep/recastnavigation/RecastDemo/CMakeLists.txt
Normal file
60
dep/recastnavigation/RecastDemo/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
# MaNGOS is a full featured server for World of Warcraft, supporting
|
||||
# the following clients: 1.12.x, 2.4.3, 3.2.5a, 4.2.3 and 5.4.8
|
||||
#
|
||||
# Copyright (C) 2005-2019 MaNGOS project <http://getmangos.eu>
|
||||
#
|
||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
# ***** END GPL LICENSE BLOCK *****
|
||||
#
|
||||
# World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
||||
# and lore are copyrighted by Blizzard Entertainment, Inc.
|
||||
|
||||
include(MacroMangosSourceGroup)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define the RecastDemo dependencies
|
||||
find_package(OpenGL REQUIRED)
|
||||
find_package(SDL REQUIRED)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Define the RecastDemo executable
|
||||
file(GLOB sources Source/*.cpp)
|
||||
file(GLOB headers Include/*.h)
|
||||
|
||||
set(RecastDemo_LIB_SRCS ${sources} ${headers})
|
||||
|
||||
mangos_source_group(${RecastDemo_LIB_SRCS})
|
||||
|
||||
include_directories(
|
||||
${SDL_INCLUDE_DIR}
|
||||
${OPENGL_INCLUDE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Contrib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../DebugUtils/Include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../Detour/Include/
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../Recast/Include/
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Build the RecastDemo executable
|
||||
if(WIN32)
|
||||
add_executable(RecastDemo WIN32 ${RecastDemo_LIB_SRCS})
|
||||
else()
|
||||
add_executable(RecastDemo ${RecastDemo_LIB_SRCS})
|
||||
endif()
|
||||
target_link_libraries(RecastDemo DebugUtils Detour Recast ${SDL_LIBRARY} ${OPENGL_LIBRARIES})
|
||||
75
dep/recastnavigation/RecastDemo/Contrib/fastlz/README.TXT
Normal file
75
dep/recastnavigation/RecastDemo/Contrib/fastlz/README.TXT
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Author: Ariya Hidayat
|
||||
Official website: http://www.fastlz.org
|
||||
|
||||
FastLZ is distributed using the MIT license, see file LICENSE
|
||||
for details.
|
||||
|
||||
FastLZ consists of two files: fastlz.h and fastlz.c. Just add these
|
||||
files to your project in order to use FastLZ. For information on
|
||||
compression and decompression routines, see fastlz.h.
|
||||
|
||||
A simple file compressor called 6pack is included as an example
|
||||
on how to use FastLZ. The corresponding decompressor is 6unpack.
|
||||
|
||||
To compile using GCC:
|
||||
|
||||
gcc -o 6pack 6pack.c fastlz.c
|
||||
gcc -o 6unpack 6unpack.c fastlz.c
|
||||
|
||||
To compile using MinGW:
|
||||
|
||||
mingw32-gcc -o 6pack 6pack.c fastlz.c
|
||||
mingw32-gcc -o 6unpack 6unpack.c fastlz.c
|
||||
|
||||
To compile using Microsoft Visual C++:
|
||||
|
||||
cl 6pack.c fastlz.c
|
||||
cl 6unpack.c fastlz.c
|
||||
|
||||
To compile using Borland C++:
|
||||
|
||||
bcc32 6pack.c fastlz.c
|
||||
bcc32 6unpack.c fastlz.c
|
||||
|
||||
To compile using OpenWatcom C/C++:
|
||||
|
||||
cl386 6pack.c fastlz.c
|
||||
cl386 6unpack.c fastlz.c
|
||||
|
||||
To compile using Intel C++ compiler for Windows:
|
||||
|
||||
icl 6pack.c fastlz.c
|
||||
icl 6unpack.c fastlz.c
|
||||
|
||||
To compile using Intel C++ compiler for Linux:
|
||||
|
||||
icc -o 6pack 6pack.c fastlz.c
|
||||
icc -o 6unpack 6unpack.c fastlz.c
|
||||
|
||||
To compile 6pack using LCC-Win32:
|
||||
|
||||
lc 6pack.c fastlz.c
|
||||
lc 6unpack.c fastlz.c
|
||||
|
||||
To compile 6pack using Pelles C:
|
||||
|
||||
pocc 6pack.c
|
||||
pocc 6unpack.c
|
||||
pocc fastlz.c
|
||||
polink 6pack.obj fastlz.obj
|
||||
polink 6unpack.obj fastlz.obj
|
||||
|
||||
For speed optimization, always use proper compile flags for optimization options.
|
||||
Typical compiler flags are given below:
|
||||
|
||||
* GCC (pre 4.2): -march=pentium -O3 -fomit-frame-pointer -mtune=pentium
|
||||
* GCC 4.2 or later: -march=pentium -O3 -fomit-frame-pointer -mtune=generic
|
||||
* Digital Mars C/C++: -o+all -5
|
||||
* Intel C++ (Windows): /O3 /Qipo
|
||||
* Intel C++ (Linux): -O2 -march=pentium -mtune=pentium
|
||||
* Borland C++: -O2 -5
|
||||
* LCC-Win32: -O
|
||||
* Pelles C: /O2
|
||||
|
||||
551
dep/recastnavigation/RecastDemo/Contrib/fastlz/fastlz.c
Normal file
551
dep/recastnavigation/RecastDemo/Contrib/fastlz/fastlz.c
Normal file
|
|
@ -0,0 +1,551 @@
|
|||
/*
|
||||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
||||
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
|
||||
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
|
||||
|
||||
/*
|
||||
* Always check for bound when decompressing.
|
||||
* Generally it is best to leave it defined.
|
||||
*/
|
||||
#define FASTLZ_SAFE
|
||||
|
||||
/*
|
||||
* Give hints to the compiler for branch prediction optimization.
|
||||
*/
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2)
|
||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
|
||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
|
||||
#else
|
||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
|
||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use inlined functions for supported systems.
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
|
||||
#define FASTLZ_INLINE inline
|
||||
#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
|
||||
#define FASTLZ_INLINE __inline
|
||||
#else
|
||||
#define FASTLZ_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prevent accessing more than 8-bit at once, except on x86 architectures.
|
||||
*/
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
#define FASTLZ_STRICT_ALIGN
|
||||
#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(_M_IX86) /* Intel, MSVC */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__386)
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(_X86_) /* MinGW */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__I86__) /* Digital Mars */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* FIXME: use preprocessor magic to set this on different platforms!
|
||||
*/
|
||||
typedef unsigned char flzuint8;
|
||||
typedef unsigned short flzuint16;
|
||||
typedef unsigned int flzuint32;
|
||||
|
||||
/* prototypes */
|
||||
int fastlz_compress(const void* input, int length, void* output);
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
|
||||
#define MAX_COPY 32
|
||||
#define MAX_LEN 264 /* 256 + 8 */
|
||||
#define MAX_DISTANCE 8192
|
||||
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
#define FASTLZ_READU16(p) *((const flzuint16*)(p))
|
||||
#else
|
||||
#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
|
||||
#endif
|
||||
|
||||
#define HASH_LOG 13
|
||||
#define HASH_SIZE (1<< HASH_LOG)
|
||||
#define HASH_MASK (HASH_SIZE-1)
|
||||
#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
|
||||
|
||||
#undef FASTLZ_LEVEL
|
||||
#define FASTLZ_LEVEL 1
|
||||
|
||||
#undef FASTLZ_COMPRESSOR
|
||||
#undef FASTLZ_DECOMPRESSOR
|
||||
#define FASTLZ_COMPRESSOR fastlz1_compress
|
||||
#define FASTLZ_DECOMPRESSOR fastlz1_decompress
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
|
||||
#include "fastlz.c"
|
||||
|
||||
#undef FASTLZ_LEVEL
|
||||
#define FASTLZ_LEVEL 2
|
||||
|
||||
#undef MAX_DISTANCE
|
||||
#define MAX_DISTANCE 8191
|
||||
#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
|
||||
|
||||
#undef FASTLZ_COMPRESSOR
|
||||
#undef FASTLZ_DECOMPRESSOR
|
||||
#define FASTLZ_COMPRESSOR fastlz2_compress
|
||||
#define FASTLZ_DECOMPRESSOR fastlz2_decompress
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
|
||||
#include "fastlz.c"
|
||||
|
||||
int fastlz_compress(const void* input, int length, void* output)
|
||||
{
|
||||
/* for short block, choose fastlz1 */
|
||||
if(length < 65536)
|
||||
return fastlz1_compress(input, length, output);
|
||||
|
||||
/* else... */
|
||||
return fastlz2_compress(input, length, output);
|
||||
}
|
||||
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout)
|
||||
{
|
||||
/* magic identifier for compression level */
|
||||
int level = ((*(const flzuint8*)input) >> 5) + 1;
|
||||
|
||||
if(level == 1)
|
||||
return fastlz1_decompress(input, length, output, maxout);
|
||||
if(level == 2)
|
||||
return fastlz2_decompress(input, length, output, maxout);
|
||||
|
||||
/* unknown level, trigger error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output)
|
||||
{
|
||||
if(level == 1)
|
||||
return fastlz1_compress(input, length, output);
|
||||
if(level == 2)
|
||||
return fastlz2_compress(input, length, output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
|
||||
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
|
||||
{
|
||||
const flzuint8* ip = (const flzuint8*) input;
|
||||
const flzuint8* ip_bound = ip + length - 2;
|
||||
const flzuint8* ip_limit = ip + length - 12;
|
||||
flzuint8* op = (flzuint8*) output;
|
||||
|
||||
const flzuint8* htab[HASH_SIZE];
|
||||
const flzuint8** hslot;
|
||||
flzuint32 hval;
|
||||
|
||||
flzuint32 copy;
|
||||
|
||||
/* sanity check */
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
|
||||
{
|
||||
if(length)
|
||||
{
|
||||
/* create literal copy only */
|
||||
*op++ = length-1;
|
||||
ip_bound++;
|
||||
while(ip <= ip_bound)
|
||||
*op++ = *ip++;
|
||||
return length+1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initializes hash table */
|
||||
for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
|
||||
*hslot = ip;
|
||||
|
||||
/* we start with literal copy */
|
||||
copy = 2;
|
||||
*op++ = MAX_COPY-1;
|
||||
*op++ = *ip++;
|
||||
*op++ = *ip++;
|
||||
|
||||
/* main loop */
|
||||
while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
|
||||
{
|
||||
const flzuint8* ref;
|
||||
flzuint32 distance;
|
||||
|
||||
/* minimum match length */
|
||||
flzuint32 len = 3;
|
||||
|
||||
/* comparison starting-point */
|
||||
const flzuint8* anchor = ip;
|
||||
|
||||
/* check for a run */
|
||||
#if FASTLZ_LEVEL==2
|
||||
if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
|
||||
{
|
||||
distance = 1;
|
||||
ip += 3;
|
||||
ref = anchor - 1 + 3;
|
||||
goto match;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* find potential match */
|
||||
HASH_FUNCTION(hval,ip);
|
||||
hslot = htab + hval;
|
||||
ref = htab[hval];
|
||||
|
||||
/* calculate distance to the match */
|
||||
distance = anchor - ref;
|
||||
|
||||
/* update hash table */
|
||||
*hslot = anchor;
|
||||
|
||||
/* is this a match? check the first 3 bytes */
|
||||
if(distance==0 ||
|
||||
#if FASTLZ_LEVEL==1
|
||||
(distance >= MAX_DISTANCE) ||
|
||||
#else
|
||||
(distance >= MAX_FARDISTANCE) ||
|
||||
#endif
|
||||
*ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
|
||||
goto literal;
|
||||
|
||||
#if FASTLZ_LEVEL==2
|
||||
/* far, needs at least 5-byte match */
|
||||
if(distance >= MAX_DISTANCE)
|
||||
{
|
||||
if(*ip++ != *ref++ || *ip++!= *ref++)
|
||||
goto literal;
|
||||
len += 2;
|
||||
}
|
||||
|
||||
match:
|
||||
#endif
|
||||
|
||||
/* last matched byte */
|
||||
ip = anchor + len;
|
||||
|
||||
/* distance is biased */
|
||||
distance--;
|
||||
|
||||
if(!distance)
|
||||
{
|
||||
/* zero distance means a run */
|
||||
flzuint8 x = ip[-1];
|
||||
while(ip < ip_bound)
|
||||
if(*ref++ != x) break; else ip++;
|
||||
}
|
||||
else
|
||||
for(;;)
|
||||
{
|
||||
/* safe because the outer check against ip limit */
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
while(ip < ip_bound)
|
||||
if(*ref++ != *ip++) break;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if we have copied something, adjust the copy count */
|
||||
if(copy)
|
||||
/* copy is biased, '0' means 1 byte copy */
|
||||
*(op-copy-1) = copy-1;
|
||||
else
|
||||
/* back, to overwrite the copy count */
|
||||
op--;
|
||||
|
||||
/* reset literal counter */
|
||||
copy = 0;
|
||||
|
||||
/* length is biased, '1' means a match of 3 bytes */
|
||||
ip -= 3;
|
||||
len = ip - anchor;
|
||||
|
||||
/* encode the match */
|
||||
#if FASTLZ_LEVEL==2
|
||||
if(distance < MAX_DISTANCE)
|
||||
{
|
||||
if(len < 7)
|
||||
{
|
||||
*op++ = (len << 5) + (distance >> 8);
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
for(len-=7; len >= 255; len-= 255)
|
||||
*op++ = 255;
|
||||
*op++ = len;
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* far away, but not yet in the another galaxy... */
|
||||
if(len < 7)
|
||||
{
|
||||
distance -= MAX_DISTANCE;
|
||||
*op++ = (len << 5) + 31;
|
||||
*op++ = 255;
|
||||
*op++ = distance >> 8;
|
||||
*op++ = distance & 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance -= MAX_DISTANCE;
|
||||
*op++ = (7 << 5) + 31;
|
||||
for(len-=7; len >= 255; len-= 255)
|
||||
*op++ = 255;
|
||||
*op++ = len;
|
||||
*op++ = 255;
|
||||
*op++ = distance >> 8;
|
||||
*op++ = distance & 255;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
|
||||
while(len > MAX_LEN-2)
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
*op++ = MAX_LEN - 2 - 7 -2;
|
||||
*op++ = (distance & 255);
|
||||
len -= MAX_LEN-2;
|
||||
}
|
||||
|
||||
if(len < 7)
|
||||
{
|
||||
*op++ = (len << 5) + (distance >> 8);
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
*op++ = len - 7;
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* update the hash at match boundary */
|
||||
HASH_FUNCTION(hval,ip);
|
||||
htab[hval] = ip++;
|
||||
HASH_FUNCTION(hval,ip);
|
||||
htab[hval] = ip++;
|
||||
|
||||
/* assuming literal copy */
|
||||
*op++ = MAX_COPY-1;
|
||||
|
||||
continue;
|
||||
|
||||
literal:
|
||||
*op++ = *anchor++;
|
||||
ip = anchor;
|
||||
copy++;
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
|
||||
{
|
||||
copy = 0;
|
||||
*op++ = MAX_COPY-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* left-over as literal copy */
|
||||
ip_bound++;
|
||||
while(ip <= ip_bound)
|
||||
{
|
||||
*op++ = *ip++;
|
||||
copy++;
|
||||
if(copy == MAX_COPY)
|
||||
{
|
||||
copy = 0;
|
||||
*op++ = MAX_COPY-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we have copied something, adjust the copy length */
|
||||
if(copy)
|
||||
*(op-copy-1) = copy-1;
|
||||
else
|
||||
op--;
|
||||
|
||||
#if FASTLZ_LEVEL==2
|
||||
/* marker for fastlz2 */
|
||||
*(flzuint8*)output |= (1 << 5);
|
||||
#endif
|
||||
|
||||
return op - (flzuint8*)output;
|
||||
}
|
||||
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
|
||||
{
|
||||
const flzuint8* ip = (const flzuint8*) input;
|
||||
const flzuint8* ip_limit = ip + length;
|
||||
flzuint8* op = (flzuint8*) output;
|
||||
flzuint8* op_limit = op + maxout;
|
||||
flzuint32 ctrl = (*ip++) & 31;
|
||||
int loop = 1;
|
||||
|
||||
do
|
||||
{
|
||||
const flzuint8* ref = op;
|
||||
flzuint32 len = ctrl >> 5;
|
||||
flzuint32 ofs = (ctrl & 31) << 8;
|
||||
|
||||
if(ctrl >= 32)
|
||||
{
|
||||
#if FASTLZ_LEVEL==2
|
||||
flzuint8 code;
|
||||
#endif
|
||||
len--;
|
||||
ref -= ofs;
|
||||
if (len == 7-1)
|
||||
#if FASTLZ_LEVEL==1
|
||||
len += *ip++;
|
||||
ref -= *ip++;
|
||||
#else
|
||||
do
|
||||
{
|
||||
code = *ip++;
|
||||
len += code;
|
||||
} while (code==255);
|
||||
code = *ip++;
|
||||
ref -= code;
|
||||
|
||||
/* match from 16-bit distance */
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
|
||||
if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
|
||||
{
|
||||
ofs = (*ip++) << 8;
|
||||
ofs += *ip++;
|
||||
ref = op - ofs - MAX_DISTANCE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FASTLZ_SAFE
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
|
||||
return 0;
|
||||
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
|
||||
ctrl = *ip++;
|
||||
else
|
||||
loop = 0;
|
||||
|
||||
if(ref == op)
|
||||
{
|
||||
/* optimize copy for a run */
|
||||
flzuint8 b = ref[-1];
|
||||
*op++ = b;
|
||||
*op++ = b;
|
||||
*op++ = b;
|
||||
for(; len; --len)
|
||||
*op++ = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
const flzuint16* p;
|
||||
flzuint16* q;
|
||||
#endif
|
||||
/* copy from reference */
|
||||
ref--;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
/* copy a byte, so that now it's word aligned */
|
||||
if(len & 1)
|
||||
{
|
||||
*op++ = *ref++;
|
||||
len--;
|
||||
}
|
||||
|
||||
/* copy 16-bit at once */
|
||||
q = (flzuint16*) op;
|
||||
op += len;
|
||||
p = (const flzuint16*) ref;
|
||||
for(len>>=1; len > 4; len-=4)
|
||||
{
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
}
|
||||
for(; len; --len)
|
||||
*q++ = *p++;
|
||||
#else
|
||||
for(; len; --len)
|
||||
*op++ = *ref++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl++;
|
||||
#ifdef FASTLZ_SAFE
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
|
||||
return 0;
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
*op++ = *ip++;
|
||||
for(--ctrl; ctrl; ctrl--)
|
||||
*op++ = *ip++;
|
||||
|
||||
loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
|
||||
if(loop)
|
||||
ctrl = *ip++;
|
||||
}
|
||||
}
|
||||
while(FASTLZ_EXPECT_CONDITIONAL(loop));
|
||||
|
||||
return op - (flzuint8*)output;
|
||||
}
|
||||
|
||||
#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
|
||||
100
dep/recastnavigation/RecastDemo/Contrib/fastlz/fastlz.h
Normal file
100
dep/recastnavigation/RecastDemo/Contrib/fastlz/fastlz.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
|
||||
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
|
||||
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FASTLZ_H
|
||||
#define FASTLZ_H
|
||||
|
||||
#define FASTLZ_VERSION 0x000100
|
||||
|
||||
#define FASTLZ_VERSION_MAJOR 0
|
||||
#define FASTLZ_VERSION_MINOR 0
|
||||
#define FASTLZ_VERSION_REVISION 0
|
||||
|
||||
#define FASTLZ_VERSION_STRING "0.1.0"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
minimum input buffer size is 16.
|
||||
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
and can not be smaller than 66 bytes.
|
||||
|
||||
If the input is not compressible, the return value might be larger than
|
||||
length (input buffer size).
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
*/
|
||||
|
||||
int fastlz_compress(const void* input, int length, void* output);
|
||||
|
||||
/**
|
||||
Decompress a block of compressed data and returns the size of the
|
||||
decompressed block. If error occurs, e.g. the compressed data is
|
||||
corrupted or the output buffer is not large enough, then 0 (zero)
|
||||
will be returned instead.
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
|
||||
Decompression is memory safe and guaranteed not to write the output buffer
|
||||
more than what is specified in maxout.
|
||||
*/
|
||||
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
|
||||
/**
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
minimum input buffer size is 16.
|
||||
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
and can not be smaller than 66 bytes.
|
||||
|
||||
If the input is not compressible, the return value might be larger than
|
||||
length (input buffer size).
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
|
||||
Compression level can be specified in parameter level. At the moment,
|
||||
only level 1 and level 2 are supported.
|
||||
Level 1 is the fastest compression and generally useful for short data.
|
||||
Level 2 is slightly slower but it gives better compression ratio.
|
||||
|
||||
Note that the compressed data, regardless of the level, can always be
|
||||
decompressed using the function fastlz_decompress above.
|
||||
*/
|
||||
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FASTLZ_H */
|
||||
BIN
dep/recastnavigation/RecastDemo/English.lproj/InfoPlist.strings
Normal file
BIN
dep/recastnavigation/RecastDemo/English.lproj/InfoPlist.strings
Normal file
Binary file not shown.
3034
dep/recastnavigation/RecastDemo/English.lproj/MainMenu.xib
Normal file
3034
dep/recastnavigation/RecastDemo/English.lproj/MainMenu.xib
Normal file
File diff suppressed because it is too large
Load diff
BIN
dep/recastnavigation/RecastDemo/Icon.icns
Normal file
BIN
dep/recastnavigation/RecastDemo/Icon.icns
Normal file
Binary file not shown.
51
dep/recastnavigation/RecastDemo/Include/NavMeshPruneTool.h
Normal file
51
dep/recastnavigation/RecastDemo/Include/NavMeshPruneTool.h
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef NAVMESHPRUNETOOL_H
|
||||
#define NAVMESHPRUNETOOL_H
|
||||
|
||||
#include "Sample.h"
|
||||
|
||||
// Prune navmesh to accessible locations from a point.
|
||||
|
||||
class NavMeshPruneTool : public SampleTool
|
||||
{
|
||||
Sample* m_sample;
|
||||
|
||||
class NavmeshFlags* m_flags;
|
||||
|
||||
float m_hitPos[3];
|
||||
bool m_hitPosSet;
|
||||
|
||||
public:
|
||||
NavMeshPruneTool();
|
||||
~NavMeshPruneTool();
|
||||
|
||||
virtual int type() { return TOOL_NAVMESH_PRUNE; }
|
||||
virtual void init(Sample* sample);
|
||||
virtual void reset();
|
||||
virtual void handleMenu();
|
||||
virtual void handleClick(const float* s, const float* p, bool shift);
|
||||
virtual void handleToggle();
|
||||
virtual void handleStep();
|
||||
virtual void handleUpdate(const float dt);
|
||||
virtual void handleRender();
|
||||
virtual void handleRenderOverlay(double* proj, double* model, int* view);
|
||||
};
|
||||
|
||||
#endif // NAVMESHPRUNETOOL_H
|
||||
81
dep/recastnavigation/RecastDemo/Include/Sample_SoloMesh.h
Normal file
81
dep/recastnavigation/RecastDemo/Include/Sample_SoloMesh.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef RECASTSAMPLESOLOMESH_H
|
||||
#define RECASTSAMPLESOLOMESH_H
|
||||
|
||||
#include "Sample.h"
|
||||
#include "DetourNavMesh.h"
|
||||
#include "Recast.h"
|
||||
|
||||
class Sample_SoloMesh : public Sample
|
||||
{
|
||||
protected:
|
||||
bool m_keepInterResults;
|
||||
float m_totalBuildTimeMs;
|
||||
|
||||
unsigned char* m_triareas;
|
||||
rcHeightfield* m_solid;
|
||||
rcCompactHeightfield* m_chf;
|
||||
rcContourSet* m_cset;
|
||||
rcPolyMesh* m_pmesh;
|
||||
rcConfig m_cfg;
|
||||
rcPolyMeshDetail* m_dmesh;
|
||||
|
||||
enum DrawMode
|
||||
{
|
||||
DRAWMODE_NAVMESH,
|
||||
DRAWMODE_NAVMESH_TRANS,
|
||||
DRAWMODE_NAVMESH_BVTREE,
|
||||
DRAWMODE_NAVMESH_NODES,
|
||||
DRAWMODE_NAVMESH_INVIS,
|
||||
DRAWMODE_MESH,
|
||||
DRAWMODE_VOXELS,
|
||||
DRAWMODE_VOXELS_WALKABLE,
|
||||
DRAWMODE_COMPACT,
|
||||
DRAWMODE_COMPACT_DISTANCE,
|
||||
DRAWMODE_COMPACT_REGIONS,
|
||||
DRAWMODE_REGION_CONNECTIONS,
|
||||
DRAWMODE_RAW_CONTOURS,
|
||||
DRAWMODE_BOTH_CONTOURS,
|
||||
DRAWMODE_CONTOURS,
|
||||
DRAWMODE_POLYMESH,
|
||||
DRAWMODE_POLYMESH_DETAIL,
|
||||
MAX_DRAWMODE
|
||||
};
|
||||
|
||||
DrawMode m_drawMode;
|
||||
|
||||
void cleanup();
|
||||
|
||||
public:
|
||||
Sample_SoloMesh();
|
||||
virtual ~Sample_SoloMesh();
|
||||
|
||||
virtual void handleSettings();
|
||||
virtual void handleTools();
|
||||
virtual void handleDebugMode();
|
||||
|
||||
virtual void handleRender();
|
||||
virtual void handleRenderOverlay(double* proj, double* model, int* view);
|
||||
virtual void handleMeshChanged(class InputGeom* geom);
|
||||
virtual bool handleBuild();
|
||||
};
|
||||
|
||||
|
||||
#endif // RECASTSAMPLESOLOMESHSIMPLE_H
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#ifndef RECASTSAMPLETEMPOBSTACLE_H
|
||||
#define RECASTSAMPLETEMPOBSTACLE_H
|
||||
|
||||
#include "Sample.h"
|
||||
#include "DetourNavMesh.h"
|
||||
#include "Recast.h"
|
||||
#include "ChunkyTriMesh.h"
|
||||
|
||||
|
||||
class Sample_TempObstacles : public Sample
|
||||
{
|
||||
protected:
|
||||
bool m_keepInterResults;
|
||||
|
||||
struct LinearAllocator* m_talloc;
|
||||
struct FastLZCompressor* m_tcomp;
|
||||
struct MeshProcess* m_tmproc;
|
||||
|
||||
class dtTileCache* m_tileCache;
|
||||
|
||||
float m_cacheBuildTimeMs;
|
||||
int m_cacheCompressedSize;
|
||||
int m_cacheRawSize;
|
||||
int m_cacheLayerCount;
|
||||
int m_cacheBuildMemUsage;
|
||||
|
||||
enum DrawMode
|
||||
{
|
||||
DRAWMODE_NAVMESH,
|
||||
DRAWMODE_NAVMESH_TRANS,
|
||||
DRAWMODE_NAVMESH_BVTREE,
|
||||
DRAWMODE_NAVMESH_NODES,
|
||||
DRAWMODE_NAVMESH_PORTALS,
|
||||
DRAWMODE_NAVMESH_INVIS,
|
||||
DRAWMODE_MESH,
|
||||
DRAWMODE_CACHE_BOUNDS,
|
||||
MAX_DRAWMODE
|
||||
};
|
||||
|
||||
DrawMode m_drawMode;
|
||||
|
||||
int m_maxTiles;
|
||||
int m_maxPolysPerTile;
|
||||
float m_tileSize;
|
||||
|
||||
public:
|
||||
Sample_TempObstacles();
|
||||
virtual ~Sample_TempObstacles();
|
||||
|
||||
virtual void handleSettings();
|
||||
virtual void handleTools();
|
||||
virtual void handleDebugMode();
|
||||
virtual void handleRender();
|
||||
virtual void handleRenderOverlay(double* proj, double* model, int* view);
|
||||
virtual void handleMeshChanged(class InputGeom* geom);
|
||||
virtual bool handleBuild();
|
||||
virtual void handleUpdate(const float dt);
|
||||
|
||||
void getTilePos(const float* pos, int& tx, int& ty);
|
||||
|
||||
void renderCachedTile(const int tx, const int ty, const int type);
|
||||
void renderCachedTileOverlay(const int tx, const int ty, double* proj, double* model, int* view);
|
||||
|
||||
void addTempObstacle(const float* pos);
|
||||
void removeTempObstacle(const float* sp, const float* sq);
|
||||
void clearAllTempObstacles();
|
||||
};
|
||||
|
||||
|
||||
#endif // RECASTSAMPLETEMPOBSTACLE_H
|
||||
28
dep/recastnavigation/RecastDemo/Info.plist
Normal file
28
dep/recastnavigation/RecastDemo/Info.plist
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>Icon.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.yourcompany.${PRODUCT_NAME:identifier}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
354
dep/recastnavigation/RecastDemo/Source/NavMeshPruneTool.cpp
Normal file
354
dep/recastnavigation/RecastDemo/Source/NavMeshPruneTool.cpp
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <float.h>
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
#include "imgui.h"
|
||||
#include "NavMeshPruneTool.h"
|
||||
#include "InputGeom.h"
|
||||
#include "Sample.h"
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourCommon.h"
|
||||
#include "DetourAssert.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Copy/paste from Recast int array
|
||||
class PolyRefArray
|
||||
{
|
||||
dtPolyRef* m_data;
|
||||
int m_size, m_cap;
|
||||
inline PolyRefArray(const PolyRefArray&);
|
||||
inline PolyRefArray& operator=(const PolyRefArray&);
|
||||
public:
|
||||
|
||||
inline PolyRefArray() : m_data(0), m_size(0), m_cap(0) {}
|
||||
inline PolyRefArray(int n) : m_data(0), m_size(0), m_cap(0) { resize(n); }
|
||||
inline ~PolyRefArray() { dtFree(m_data); }
|
||||
void resize(int n)
|
||||
{
|
||||
if (n > m_cap)
|
||||
{
|
||||
if (!m_cap) m_cap = n;
|
||||
while (m_cap < n) m_cap *= 2;
|
||||
dtPolyRef* newData = (dtPolyRef*)dtAlloc(m_cap*sizeof(dtPolyRef), DT_ALLOC_TEMP);
|
||||
if (m_size && newData) memcpy(newData, m_data, m_size*sizeof(dtPolyRef));
|
||||
dtFree(m_data);
|
||||
m_data = newData;
|
||||
}
|
||||
m_size = n;
|
||||
}
|
||||
inline void push(dtPolyRef item) { resize(m_size+1); m_data[m_size-1] = item; }
|
||||
inline dtPolyRef pop() { if (m_size > 0) m_size--; return m_data[m_size]; }
|
||||
inline const dtPolyRef& operator[](int i) const { return m_data[i]; }
|
||||
inline dtPolyRef& operator[](int i) { return m_data[i]; }
|
||||
inline int size() const { return m_size; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class NavmeshFlags
|
||||
{
|
||||
struct TileFlags
|
||||
{
|
||||
inline void purge() { dtFree(flags); }
|
||||
unsigned char* flags;
|
||||
int nflags;
|
||||
dtPolyRef base;
|
||||
};
|
||||
|
||||
const dtNavMesh* m_nav;
|
||||
TileFlags* m_tiles;
|
||||
int m_ntiles;
|
||||
|
||||
public:
|
||||
NavmeshFlags() :
|
||||
m_nav(0), m_tiles(0), m_ntiles(0)
|
||||
{
|
||||
}
|
||||
|
||||
~NavmeshFlags()
|
||||
{
|
||||
for (int i = 0; i < m_ntiles; ++i)
|
||||
m_tiles[i].purge();
|
||||
dtFree(m_tiles);
|
||||
}
|
||||
|
||||
bool init(const dtNavMesh* nav)
|
||||
{
|
||||
m_ntiles = nav->getMaxTiles();
|
||||
if (!m_ntiles)
|
||||
return true;
|
||||
m_tiles = (TileFlags*)dtAlloc(sizeof(TileFlags)*m_ntiles, DT_ALLOC_TEMP);
|
||||
if (!m_tiles)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memset(m_tiles, 0, sizeof(TileFlags)*m_ntiles);
|
||||
|
||||
// Alloc flags for each tile.
|
||||
for (int i = 0; i < nav->getMaxTiles(); ++i)
|
||||
{
|
||||
const dtMeshTile* tile = nav->getTile(i);
|
||||
if (!tile->header) continue;
|
||||
TileFlags* tf = &m_tiles[i];
|
||||
tf->nflags = tile->header->polyCount;
|
||||
tf->base = nav->getPolyRefBase(tile);
|
||||
if (tf->nflags)
|
||||
{
|
||||
tf->flags = (unsigned char*)dtAlloc(tf->nflags, DT_ALLOC_TEMP);
|
||||
if (!tf->flags)
|
||||
return false;
|
||||
memset(tf->flags, 0, tf->nflags);
|
||||
}
|
||||
}
|
||||
|
||||
m_nav = nav;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void clearAllFlags()
|
||||
{
|
||||
for (int i = 0; i < m_ntiles; ++i)
|
||||
{
|
||||
TileFlags* tf = &m_tiles[i];
|
||||
if (tf->nflags)
|
||||
memset(tf->flags, 0, tf->nflags);
|
||||
}
|
||||
}
|
||||
|
||||
inline unsigned char getFlags(dtPolyRef ref)
|
||||
{
|
||||
dtAssert(m_nav);
|
||||
dtAssert(m_ntiles);
|
||||
// Assume the ref is valid, no bounds checks.
|
||||
unsigned int salt, it, ip;
|
||||
m_nav->decodePolyId(ref, salt, it, ip);
|
||||
return m_tiles[it].flags[ip];
|
||||
}
|
||||
|
||||
inline void setFlags(dtPolyRef ref, unsigned char flags)
|
||||
{
|
||||
dtAssert(m_nav);
|
||||
dtAssert(m_ntiles);
|
||||
// Assume the ref is valid, no bounds checks.
|
||||
unsigned int salt, it, ip;
|
||||
m_nav->decodePolyId(ref, salt, it, ip);
|
||||
m_tiles[it].flags[ip] = flags;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static void floodNavmesh(dtNavMesh* nav, NavmeshFlags* flags, dtPolyRef start, unsigned char flag)
|
||||
{
|
||||
// If already visited, skip.
|
||||
if (flags->getFlags(start))
|
||||
return;
|
||||
|
||||
PolyRefArray openList;
|
||||
openList.push(start);
|
||||
|
||||
while (openList.size())
|
||||
{
|
||||
const dtPolyRef ref = openList.pop();
|
||||
// Get current poly and tile.
|
||||
// The API input has been cheked already, skip checking internal data.
|
||||
const dtMeshTile* tile = 0;
|
||||
const dtPoly* poly = 0;
|
||||
nav->getTileAndPolyByRefUnsafe(ref, &tile, &poly);
|
||||
|
||||
// Visit linked polygons.
|
||||
for (unsigned int i = poly->firstLink; i != DT_NULL_LINK; i = tile->links[i].next)
|
||||
{
|
||||
const dtPolyRef neiRef = tile->links[i].ref;
|
||||
// Skip invalid and already visited.
|
||||
if (!neiRef || flags->getFlags(neiRef))
|
||||
continue;
|
||||
// Mark as visited
|
||||
flags->setFlags(neiRef, flag);
|
||||
// Visit neighbours
|
||||
openList.push(neiRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void disableUnvisitedPolys(dtNavMesh* nav, NavmeshFlags* flags)
|
||||
{
|
||||
for (int i = 0; i < nav->getMaxTiles(); ++i)
|
||||
{
|
||||
const dtMeshTile* tile = ((const dtNavMesh*)nav)->getTile(i);
|
||||
if (!tile->header) continue;
|
||||
const dtPolyRef base = nav->getPolyRefBase(tile);
|
||||
for (int j = 0; j < tile->header->polyCount; ++j)
|
||||
{
|
||||
const dtPolyRef ref = base | (unsigned int)j;
|
||||
if (!flags->getFlags(ref))
|
||||
{
|
||||
unsigned short f = 0;
|
||||
nav->getPolyFlags(ref, &f);
|
||||
nav->setPolyFlags(ref, f | SAMPLE_POLYFLAGS_DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NavMeshPruneTool::NavMeshPruneTool() :
|
||||
m_flags(0),
|
||||
m_hitPosSet(false)
|
||||
{
|
||||
}
|
||||
|
||||
NavMeshPruneTool::~NavMeshPruneTool()
|
||||
{
|
||||
delete m_flags;
|
||||
}
|
||||
|
||||
void NavMeshPruneTool::init(Sample* sample)
|
||||
{
|
||||
m_sample = sample;
|
||||
}
|
||||
|
||||
void NavMeshPruneTool::reset()
|
||||
{
|
||||
m_hitPosSet = false;
|
||||
delete m_flags;
|
||||
m_flags = 0;
|
||||
}
|
||||
|
||||
void NavMeshPruneTool::handleMenu()
|
||||
{
|
||||
dtNavMesh* nav = m_sample->getNavMesh();
|
||||
if (!nav) return;
|
||||
if (!m_flags) return;
|
||||
|
||||
if (imguiButton("Clear Selection"))
|
||||
{
|
||||
m_flags->clearAllFlags();
|
||||
}
|
||||
|
||||
if (imguiButton("Prune Unselected"))
|
||||
{
|
||||
disableUnvisitedPolys(nav, m_flags);
|
||||
delete m_flags;
|
||||
m_flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void NavMeshPruneTool::handleClick(const float* s, const float* p, bool shift)
|
||||
{
|
||||
rcIgnoreUnused(s);
|
||||
rcIgnoreUnused(shift);
|
||||
|
||||
if (!m_sample) return;
|
||||
InputGeom* geom = m_sample->getInputGeom();
|
||||
if (!geom) return;
|
||||
dtNavMesh* nav = m_sample->getNavMesh();
|
||||
if (!nav) return;
|
||||
dtNavMeshQuery* query = m_sample->getNavMeshQuery();
|
||||
if (!query) return;
|
||||
|
||||
dtVcopy(m_hitPos, p);
|
||||
m_hitPosSet = true;
|
||||
|
||||
if (!m_flags)
|
||||
{
|
||||
m_flags = new NavmeshFlags;
|
||||
m_flags->init(nav);
|
||||
}
|
||||
|
||||
const float ext[3] = {2,4,2};
|
||||
dtQueryFilter filter;
|
||||
dtPolyRef ref = 0;
|
||||
query->findNearestPoly(p, ext, &filter, &ref, 0);
|
||||
|
||||
floodNavmesh(nav, m_flags, ref, 1);
|
||||
}
|
||||
|
||||
void NavMeshPruneTool::handleToggle()
|
||||
{
|
||||
}
|
||||
|
||||
void NavMeshPruneTool::handleStep()
|
||||
{
|
||||
}
|
||||
|
||||
void NavMeshPruneTool::handleUpdate(const float /*dt*/)
|
||||
{
|
||||
}
|
||||
|
||||
void NavMeshPruneTool::handleRender()
|
||||
{
|
||||
DebugDrawGL dd;
|
||||
|
||||
if (m_hitPosSet)
|
||||
{
|
||||
const float s = m_sample->getAgentRadius();
|
||||
const unsigned int col = duRGBA(255,255,255,255);
|
||||
dd.begin(DU_DRAW_LINES);
|
||||
dd.vertex(m_hitPos[0]-s,m_hitPos[1],m_hitPos[2], col);
|
||||
dd.vertex(m_hitPos[0]+s,m_hitPos[1],m_hitPos[2], col);
|
||||
dd.vertex(m_hitPos[0],m_hitPos[1]-s,m_hitPos[2], col);
|
||||
dd.vertex(m_hitPos[0],m_hitPos[1]+s,m_hitPos[2], col);
|
||||
dd.vertex(m_hitPos[0],m_hitPos[1],m_hitPos[2]-s, col);
|
||||
dd.vertex(m_hitPos[0],m_hitPos[1],m_hitPos[2]+s, col);
|
||||
dd.end();
|
||||
}
|
||||
|
||||
const dtNavMesh* nav = m_sample->getNavMesh();
|
||||
if (m_flags && nav)
|
||||
{
|
||||
for (int i = 0; i < nav->getMaxTiles(); ++i)
|
||||
{
|
||||
const dtMeshTile* tile = nav->getTile(i);
|
||||
if (!tile->header) continue;
|
||||
const dtPolyRef base = nav->getPolyRefBase(tile);
|
||||
for (int j = 0; j < tile->header->polyCount; ++j)
|
||||
{
|
||||
const dtPolyRef ref = base | (unsigned int)j;
|
||||
if (m_flags->getFlags(ref))
|
||||
{
|
||||
duDebugDrawNavMeshPoly(&dd, *nav, ref, duRGBA(255,255,255,128));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void NavMeshPruneTool::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
{
|
||||
rcIgnoreUnused(model);
|
||||
rcIgnoreUnused(proj);
|
||||
|
||||
// Tool help
|
||||
const int h = view[3];
|
||||
|
||||
imguiDrawText(280, h-40, IMGUI_ALIGN_LEFT, "LMB: Click fill area.", imguiRGBA(255,255,255,192));
|
||||
}
|
||||
732
dep/recastnavigation/RecastDemo/Source/Sample_SoloMesh.cpp
Normal file
732
dep/recastnavigation/RecastDemo/Source/Sample_SoloMesh.cpp
Normal file
|
|
@ -0,0 +1,732 @@
|
|||
//
|
||||
// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would be
|
||||
// appreciated but is not required.
|
||||
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||
// misrepresented as being the original software.
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "SDL.h"
|
||||
#include "SDL_opengl.h"
|
||||
#include "imgui.h"
|
||||
#include "InputGeom.h"
|
||||
#include "Sample.h"
|
||||
#include "Sample_SoloMesh.h"
|
||||
#include "Recast.h"
|
||||
#include "RecastDebugDraw.h"
|
||||
#include "RecastDump.h"
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourNavMeshBuilder.h"
|
||||
#include "DetourDebugDraw.h"
|
||||
#include "NavMeshTesterTool.h"
|
||||
#include "NavMeshPruneTool.h"
|
||||
#include "OffMeshConnectionTool.h"
|
||||
#include "ConvexVolumeTool.h"
|
||||
#include "CrowdTool.h"
|
||||
|
||||
#ifdef WIN32
|
||||
# define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
|
||||
Sample_SoloMesh::Sample_SoloMesh() :
|
||||
m_keepInterResults(true),
|
||||
m_totalBuildTimeMs(0),
|
||||
m_triareas(0),
|
||||
m_solid(0),
|
||||
m_chf(0),
|
||||
m_cset(0),
|
||||
m_pmesh(0),
|
||||
m_dmesh(0),
|
||||
m_drawMode(DRAWMODE_NAVMESH)
|
||||
{
|
||||
setTool(new NavMeshTesterTool);
|
||||
}
|
||||
|
||||
Sample_SoloMesh::~Sample_SoloMesh()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void Sample_SoloMesh::cleanup()
|
||||
{
|
||||
delete [] m_triareas;
|
||||
m_triareas = 0;
|
||||
rcFreeHeightField(m_solid);
|
||||
m_solid = 0;
|
||||
rcFreeCompactHeightfield(m_chf);
|
||||
m_chf = 0;
|
||||
rcFreeContourSet(m_cset);
|
||||
m_cset = 0;
|
||||
rcFreePolyMesh(m_pmesh);
|
||||
m_pmesh = 0;
|
||||
rcFreePolyMeshDetail(m_dmesh);
|
||||
m_dmesh = 0;
|
||||
dtFreeNavMesh(m_navMesh);
|
||||
m_navMesh = 0;
|
||||
}
|
||||
|
||||
void Sample_SoloMesh::handleSettings()
|
||||
{
|
||||
Sample::handleCommonSettings();
|
||||
|
||||
if (imguiCheck("Keep Itermediate Results", m_keepInterResults))
|
||||
m_keepInterResults = !m_keepInterResults;
|
||||
|
||||
imguiSeparator();
|
||||
|
||||
char msg[64];
|
||||
snprintf(msg, 64, "Build Time: %.1fms", m_totalBuildTimeMs);
|
||||
imguiLabel(msg);
|
||||
|
||||
imguiSeparator();
|
||||
}
|
||||
|
||||
void Sample_SoloMesh::handleTools()
|
||||
{
|
||||
int type = !m_tool ? TOOL_NONE : m_tool->type();
|
||||
|
||||
if (imguiCheck("Test Navmesh", type == TOOL_NAVMESH_TESTER))
|
||||
{
|
||||
setTool(new NavMeshTesterTool);
|
||||
}
|
||||
if (imguiCheck("Prune Navmesh", type == TOOL_NAVMESH_PRUNE))
|
||||
{
|
||||
setTool(new NavMeshPruneTool);
|
||||
}
|
||||
if (imguiCheck("Create Off-Mesh Connections", type == TOOL_OFFMESH_CONNECTION))
|
||||
{
|
||||
setTool(new OffMeshConnectionTool);
|
||||
}
|
||||
if (imguiCheck("Create Convex Volumes", type == TOOL_CONVEX_VOLUME))
|
||||
{
|
||||
setTool(new ConvexVolumeTool);
|
||||
}
|
||||
if (imguiCheck("Create Crowds", type == TOOL_CROWD))
|
||||
{
|
||||
setTool(new CrowdTool);
|
||||
}
|
||||
|
||||
imguiSeparatorLine();
|
||||
|
||||
imguiIndent();
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleMenu();
|
||||
|
||||
imguiUnindent();
|
||||
|
||||
}
|
||||
|
||||
void Sample_SoloMesh::handleDebugMode()
|
||||
{
|
||||
// Check which modes are valid.
|
||||
bool valid[MAX_DRAWMODE];
|
||||
for (int i = 0; i < MAX_DRAWMODE; ++i)
|
||||
valid[i] = false;
|
||||
|
||||
if (m_geom)
|
||||
{
|
||||
valid[DRAWMODE_NAVMESH] = m_navMesh != 0;
|
||||
valid[DRAWMODE_NAVMESH_TRANS] = m_navMesh != 0;
|
||||
valid[DRAWMODE_NAVMESH_BVTREE] = m_navMesh != 0;
|
||||
valid[DRAWMODE_NAVMESH_NODES] = m_navQuery != 0;
|
||||
valid[DRAWMODE_NAVMESH_INVIS] = m_navMesh != 0;
|
||||
valid[DRAWMODE_MESH] = true;
|
||||
valid[DRAWMODE_VOXELS] = m_solid != 0;
|
||||
valid[DRAWMODE_VOXELS_WALKABLE] = m_solid != 0;
|
||||
valid[DRAWMODE_COMPACT] = m_chf != 0;
|
||||
valid[DRAWMODE_COMPACT_DISTANCE] = m_chf != 0;
|
||||
valid[DRAWMODE_COMPACT_REGIONS] = m_chf != 0;
|
||||
valid[DRAWMODE_REGION_CONNECTIONS] = m_cset != 0;
|
||||
valid[DRAWMODE_RAW_CONTOURS] = m_cset != 0;
|
||||
valid[DRAWMODE_BOTH_CONTOURS] = m_cset != 0;
|
||||
valid[DRAWMODE_CONTOURS] = m_cset != 0;
|
||||
valid[DRAWMODE_POLYMESH] = m_pmesh != 0;
|
||||
valid[DRAWMODE_POLYMESH_DETAIL] = m_dmesh != 0;
|
||||
}
|
||||
|
||||
int unavail = 0;
|
||||
for (int i = 0; i < MAX_DRAWMODE; ++i)
|
||||
if (!valid[i]) unavail++;
|
||||
|
||||
if (unavail == MAX_DRAWMODE)
|
||||
return;
|
||||
|
||||
imguiLabel("Draw");
|
||||
if (imguiCheck("Input Mesh", m_drawMode == DRAWMODE_MESH, valid[DRAWMODE_MESH]))
|
||||
m_drawMode = DRAWMODE_MESH;
|
||||
if (imguiCheck("Navmesh", m_drawMode == DRAWMODE_NAVMESH, valid[DRAWMODE_NAVMESH]))
|
||||
m_drawMode = DRAWMODE_NAVMESH;
|
||||
if (imguiCheck("Navmesh Invis", m_drawMode == DRAWMODE_NAVMESH_INVIS, valid[DRAWMODE_NAVMESH_INVIS]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_INVIS;
|
||||
if (imguiCheck("Navmesh Trans", m_drawMode == DRAWMODE_NAVMESH_TRANS, valid[DRAWMODE_NAVMESH_TRANS]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_TRANS;
|
||||
if (imguiCheck("Navmesh BVTree", m_drawMode == DRAWMODE_NAVMESH_BVTREE, valid[DRAWMODE_NAVMESH_BVTREE]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_BVTREE;
|
||||
if (imguiCheck("Navmesh Nodes", m_drawMode == DRAWMODE_NAVMESH_NODES, valid[DRAWMODE_NAVMESH_NODES]))
|
||||
m_drawMode = DRAWMODE_NAVMESH_NODES;
|
||||
if (imguiCheck("Voxels", m_drawMode == DRAWMODE_VOXELS, valid[DRAWMODE_VOXELS]))
|
||||
m_drawMode = DRAWMODE_VOXELS;
|
||||
if (imguiCheck("Walkable Voxels", m_drawMode == DRAWMODE_VOXELS_WALKABLE, valid[DRAWMODE_VOXELS_WALKABLE]))
|
||||
m_drawMode = DRAWMODE_VOXELS_WALKABLE;
|
||||
if (imguiCheck("Compact", m_drawMode == DRAWMODE_COMPACT, valid[DRAWMODE_COMPACT]))
|
||||
m_drawMode = DRAWMODE_COMPACT;
|
||||
if (imguiCheck("Compact Distance", m_drawMode == DRAWMODE_COMPACT_DISTANCE, valid[DRAWMODE_COMPACT_DISTANCE]))
|
||||
m_drawMode = DRAWMODE_COMPACT_DISTANCE;
|
||||
if (imguiCheck("Compact Regions", m_drawMode == DRAWMODE_COMPACT_REGIONS, valid[DRAWMODE_COMPACT_REGIONS]))
|
||||
m_drawMode = DRAWMODE_COMPACT_REGIONS;
|
||||
if (imguiCheck("Region Connections", m_drawMode == DRAWMODE_REGION_CONNECTIONS, valid[DRAWMODE_REGION_CONNECTIONS]))
|
||||
m_drawMode = DRAWMODE_REGION_CONNECTIONS;
|
||||
if (imguiCheck("Raw Contours", m_drawMode == DRAWMODE_RAW_CONTOURS, valid[DRAWMODE_RAW_CONTOURS]))
|
||||
m_drawMode = DRAWMODE_RAW_CONTOURS;
|
||||
if (imguiCheck("Both Contours", m_drawMode == DRAWMODE_BOTH_CONTOURS, valid[DRAWMODE_BOTH_CONTOURS]))
|
||||
m_drawMode = DRAWMODE_BOTH_CONTOURS;
|
||||
if (imguiCheck("Contours", m_drawMode == DRAWMODE_CONTOURS, valid[DRAWMODE_CONTOURS]))
|
||||
m_drawMode = DRAWMODE_CONTOURS;
|
||||
if (imguiCheck("Poly Mesh", m_drawMode == DRAWMODE_POLYMESH, valid[DRAWMODE_POLYMESH]))
|
||||
m_drawMode = DRAWMODE_POLYMESH;
|
||||
if (imguiCheck("Poly Mesh Detail", m_drawMode == DRAWMODE_POLYMESH_DETAIL, valid[DRAWMODE_POLYMESH_DETAIL]))
|
||||
m_drawMode = DRAWMODE_POLYMESH_DETAIL;
|
||||
|
||||
if (unavail)
|
||||
{
|
||||
imguiValue("Tick 'Keep Itermediate Results'");
|
||||
imguiValue("to see more debug mode options.");
|
||||
}
|
||||
}
|
||||
|
||||
void Sample_SoloMesh::handleRender()
|
||||
{
|
||||
if (!m_geom || !m_geom->getMesh())
|
||||
return;
|
||||
|
||||
DebugDrawGL dd;
|
||||
|
||||
glEnable(GL_FOG);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
const float texScale = 1.0f / (m_cellSize * 10.0f);
|
||||
|
||||
if (m_drawMode != DRAWMODE_NAVMESH_TRANS)
|
||||
{
|
||||
// Draw mesh
|
||||
duDebugDrawTriMeshSlope(&dd, m_geom->getMesh()->getVerts(), m_geom->getMesh()->getVertCount(),
|
||||
m_geom->getMesh()->getTris(), m_geom->getMesh()->getNormals(), m_geom->getMesh()->getTriCount(),
|
||||
m_agentMaxSlope, texScale);
|
||||
m_geom->drawOffMeshConnections(&dd);
|
||||
}
|
||||
|
||||
glDisable(GL_FOG);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
// Draw bounds
|
||||
const float* bmin = m_geom->getMeshBoundsMin();
|
||||
const float* bmax = m_geom->getMeshBoundsMax();
|
||||
duDebugDrawBoxWire(&dd, bmin[0],bmin[1],bmin[2], bmax[0],bmax[1],bmax[2], duRGBA(255,255,255,128), 1.0f);
|
||||
dd.begin(DU_DRAW_POINTS, 5.0f);
|
||||
dd.vertex(bmin[0],bmin[1],bmin[2],duRGBA(255,255,255,128));
|
||||
dd.end();
|
||||
|
||||
if (m_navMesh && m_navQuery &&
|
||||
(m_drawMode == DRAWMODE_NAVMESH ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_TRANS ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_BVTREE ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_NODES ||
|
||||
m_drawMode == DRAWMODE_NAVMESH_INVIS))
|
||||
{
|
||||
if (m_drawMode != DRAWMODE_NAVMESH_INVIS)
|
||||
duDebugDrawNavMeshWithClosedList(&dd, *m_navMesh, *m_navQuery, m_navMeshDrawFlags);
|
||||
if (m_drawMode == DRAWMODE_NAVMESH_BVTREE)
|
||||
duDebugDrawNavMeshBVTree(&dd, *m_navMesh);
|
||||
if (m_drawMode == DRAWMODE_NAVMESH_NODES)
|
||||
duDebugDrawNavMeshNodes(&dd, *m_navQuery);
|
||||
duDebugDrawNavMeshPolysWithFlags(&dd, *m_navMesh, SAMPLE_POLYFLAGS_DISABLED, duRGBA(0,0,0,128));
|
||||
}
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
if (m_chf && m_drawMode == DRAWMODE_COMPACT)
|
||||
duDebugDrawCompactHeightfieldSolid(&dd, *m_chf);
|
||||
|
||||
if (m_chf && m_drawMode == DRAWMODE_COMPACT_DISTANCE)
|
||||
duDebugDrawCompactHeightfieldDistance(&dd, *m_chf);
|
||||
if (m_chf && m_drawMode == DRAWMODE_COMPACT_REGIONS)
|
||||
duDebugDrawCompactHeightfieldRegions(&dd, *m_chf);
|
||||
if (m_solid && m_drawMode == DRAWMODE_VOXELS)
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
duDebugDrawHeightfieldSolid(&dd, *m_solid);
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
if (m_solid && m_drawMode == DRAWMODE_VOXELS_WALKABLE)
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
duDebugDrawHeightfieldWalkable(&dd, *m_solid);
|
||||
glDisable(GL_FOG);
|
||||
}
|
||||
if (m_cset && m_drawMode == DRAWMODE_RAW_CONTOURS)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawRawContours(&dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_cset && m_drawMode == DRAWMODE_BOTH_CONTOURS)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawRawContours(&dd, *m_cset, 0.5f);
|
||||
duDebugDrawContours(&dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_cset && m_drawMode == DRAWMODE_CONTOURS)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawContours(&dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_chf && m_cset && m_drawMode == DRAWMODE_REGION_CONNECTIONS)
|
||||
{
|
||||
duDebugDrawCompactHeightfieldRegions(&dd, *m_chf);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawRegionConnections(&dd, *m_cset);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_pmesh && m_drawMode == DRAWMODE_POLYMESH)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawPolyMesh(&dd, *m_pmesh);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
if (m_dmesh && m_drawMode == DRAWMODE_POLYMESH_DETAIL)
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
duDebugDrawPolyMeshDetail(&dd, *m_dmesh);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
m_geom->drawConvexVolumes(&dd);
|
||||
|
||||
if (m_tool)
|
||||
m_tool->handleRender();
|
||||
renderToolStates();
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
void Sample_SoloMesh::handleRenderOverlay(double* proj, double* model, int* view)
|
||||
{
|
||||
if (m_tool)
|
||||
m_tool->handleRenderOverlay(proj, model, view);
|
||||
renderOverlayToolStates(proj, model, view);
|
||||
}
|
||||
|
||||
void Sample_SoloMesh::handleMeshChanged(class InputGeom* geom)
|
||||
{
|
||||
Sample::handleMeshChanged(geom);
|
||||
|
||||
dtFreeNavMesh(m_navMesh);
|
||||
m_navMesh = 0;
|
||||
|
||||
if (m_tool)
|
||||
{
|
||||
m_tool->reset();
|
||||
m_tool->init(this);
|
||||
}
|
||||
resetToolStates();
|
||||
initToolStates(this);
|
||||
}
|
||||
|
||||
|
||||
bool Sample_SoloMesh::handleBuild()
|
||||
{
|
||||
if (!m_geom || !m_geom->getMesh())
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Input mesh is not specified.");
|
||||
return false;
|
||||
}
|
||||
|
||||
cleanup();
|
||||
|
||||
const float* bmin = m_geom->getMeshBoundsMin();
|
||||
const float* bmax = m_geom->getMeshBoundsMax();
|
||||
const float* verts = m_geom->getMesh()->getVerts();
|
||||
const int nverts = m_geom->getMesh()->getVertCount();
|
||||
const int* tris = m_geom->getMesh()->getTris();
|
||||
const int ntris = m_geom->getMesh()->getTriCount();
|
||||
|
||||
//
|
||||
// Step 1. Initialize build config.
|
||||
//
|
||||
|
||||
// Init build configuration from GUI
|
||||
memset(&m_cfg, 0, sizeof(m_cfg));
|
||||
m_cfg.cs = m_cellSize;
|
||||
m_cfg.ch = m_cellHeight;
|
||||
m_cfg.walkableSlopeAngle = m_agentMaxSlope;
|
||||
m_cfg.walkableHeight = (int)ceilf(m_agentHeight / m_cfg.ch);
|
||||
m_cfg.walkableClimb = (int)floorf(m_agentMaxClimb / m_cfg.ch);
|
||||
m_cfg.walkableRadius = (int)ceilf(m_agentRadius / m_cfg.cs);
|
||||
m_cfg.maxEdgeLen = (int)(m_edgeMaxLen / m_cellSize);
|
||||
m_cfg.maxSimplificationError = m_edgeMaxError;
|
||||
m_cfg.minRegionArea = (int)rcSqr(m_regionMinSize); // Note: area = size*size
|
||||
m_cfg.mergeRegionArea = (int)rcSqr(m_regionMergeSize); // Note: area = size*size
|
||||
m_cfg.maxVertsPerPoly = (int)m_vertsPerPoly;
|
||||
m_cfg.detailSampleDist = m_detailSampleDist < 0.9f ? 0 : m_cellSize * m_detailSampleDist;
|
||||
m_cfg.detailSampleMaxError = m_cellHeight * m_detailSampleMaxError;
|
||||
|
||||
// Set the area where the navigation will be build.
|
||||
// Here the bounds of the input mesh are used, but the
|
||||
// area could be specified by an user defined box, etc.
|
||||
rcVcopy(m_cfg.bmin, bmin);
|
||||
rcVcopy(m_cfg.bmax, bmax);
|
||||
rcCalcGridSize(m_cfg.bmin, m_cfg.bmax, m_cfg.cs, &m_cfg.width, &m_cfg.height);
|
||||
|
||||
// Reset build times gathering.
|
||||
m_ctx->resetTimers();
|
||||
|
||||
// Start the build process.
|
||||
m_ctx->startTimer(RC_TIMER_TOTAL);
|
||||
|
||||
m_ctx->log(RC_LOG_PROGRESS, "Building navigation:");
|
||||
m_ctx->log(RC_LOG_PROGRESS, " - %d x %d cells", m_cfg.width, m_cfg.height);
|
||||
m_ctx->log(RC_LOG_PROGRESS, " - %.1fK verts, %.1fK tris", nverts/1000.0f, ntris/1000.0f);
|
||||
|
||||
//
|
||||
// Step 2. Rasterize input polygon soup.
|
||||
//
|
||||
|
||||
// Allocate voxel heightfield where we rasterize our input data to.
|
||||
m_solid = rcAllocHeightfield();
|
||||
if (!m_solid)
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'solid'.");
|
||||
return false;
|
||||
}
|
||||
if (!rcCreateHeightfield(m_ctx, *m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create solid heightfield.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allocate array that can hold triangle area types.
|
||||
// If you have multiple meshes you need to process, allocate
|
||||
// and array which can hold the max number of triangles you need to process.
|
||||
m_triareas = new unsigned char[ntris];
|
||||
if (!m_triareas)
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'm_triareas' (%d).", ntris);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find triangles which are walkable based on their slope and rasterize them.
|
||||
// If your input data is multiple meshes, you can transform them here, calculate
|
||||
// the are type for each of the meshes and rasterize them.
|
||||
memset(m_triareas, 0, ntris*sizeof(unsigned char));
|
||||
rcMarkWalkableTriangles(m_ctx, m_cfg.walkableSlopeAngle, verts, nverts, tris, ntris, m_triareas);
|
||||
rcRasterizeTriangles(m_ctx, verts, nverts, tris, m_triareas, ntris, *m_solid, m_cfg.walkableClimb);
|
||||
|
||||
if (!m_keepInterResults)
|
||||
{
|
||||
delete [] m_triareas;
|
||||
m_triareas = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// Step 3. Filter walkables surfaces.
|
||||
//
|
||||
|
||||
// Once all geoemtry is rasterized, we do initial pass of filtering to
|
||||
// remove unwanted overhangs caused by the conservative rasterization
|
||||
// as well as filter spans where the character cannot possibly stand.
|
||||
rcFilterLowHangingWalkableObstacles(m_ctx, m_cfg.walkableClimb, *m_solid);
|
||||
rcFilterLedgeSpans(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid);
|
||||
rcFilterWalkableLowHeightSpans(m_ctx, m_cfg.walkableHeight, *m_solid);
|
||||
|
||||
|
||||
//
|
||||
// Step 4. Partition walkable surface to simple regions.
|
||||
//
|
||||
|
||||
// Compact the heightfield so that it is faster to handle from now on.
|
||||
// This will result more cache coherent data as well as the neighbours
|
||||
// between walkable cells will be calculated.
|
||||
m_chf = rcAllocCompactHeightfield();
|
||||
if (!m_chf)
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'chf'.");
|
||||
return false;
|
||||
}
|
||||
if (!rcBuildCompactHeightfield(m_ctx, m_cfg.walkableHeight, m_cfg.walkableClimb, *m_solid, *m_chf))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build compact data.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_keepInterResults)
|
||||
{
|
||||
rcFreeHeightField(m_solid);
|
||||
m_solid = 0;
|
||||
}
|
||||
|
||||
// Erode the walkable area by agent radius.
|
||||
if (!rcErodeWalkableArea(m_ctx, m_cfg.walkableRadius, *m_chf))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not erode.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// (Optional) Mark areas.
|
||||
const ConvexVolume* vols = m_geom->getConvexVolumes();
|
||||
for (int i = 0; i < m_geom->getConvexVolumeCount(); ++i)
|
||||
rcMarkConvexPolyArea(m_ctx, vols[i].verts, vols[i].nverts, vols[i].hmin, vols[i].hmax, (unsigned char)vols[i].area, *m_chf);
|
||||
|
||||
|
||||
// Partition the heightfield so that we can use simple algorithm later to triangulate the walkable areas.
|
||||
// There are 3 martitioning methods, each with some pros and cons:
|
||||
// 1) Watershed partitioning
|
||||
// - the classic Recast partitioning
|
||||
// - creates the nicest tessellation
|
||||
// - usually slowest
|
||||
// - partitions the heightfield into nice regions without holes or overlaps
|
||||
// - the are some corner cases where this method creates produces holes and overlaps
|
||||
// - holes may appear when a small obstacles is close to large open area (triangulation can handle this)
|
||||
// - overlaps may occur if you have narrow spiral corridors (i.e stairs), this make triangulation to fail
|
||||
// * generally the best choice if you precompute the nacmesh, use this if you have large open areas
|
||||
// 2) Monotone partioning
|
||||
// - fastest
|
||||
// - partitions the heightfield into regions without holes and overlaps (guaranteed)
|
||||
// - creates long thin polygons, which sometimes causes paths with detours
|
||||
// * use this if you want fast navmesh generation
|
||||
// 3) Layer partitoining
|
||||
// - quite fast
|
||||
// - partitions the heighfield into non-overlapping regions
|
||||
// - relies on the triangulation code to cope with holes (thus slower than monotone partitioning)
|
||||
// - produces better triangles than monotone partitioning
|
||||
// - does not have the corner cases of watershed partitioning
|
||||
// - can be slow and create a bit ugly tessellation (still better than monotone)
|
||||
// if you have large open areas with small obstacles (not a problem if you use tiles)
|
||||
// * good choice to use for tiled navmesh with medium and small sized tiles
|
||||
|
||||
if (m_partitionType == SAMPLE_PARTITION_WATERSHED)
|
||||
{
|
||||
// Prepare for region partitioning, by calculating distance field along the walkable surface.
|
||||
if (!rcBuildDistanceField(m_ctx, *m_chf))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build distance field.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Partition the walkable surface into simple regions without holes.
|
||||
if (!rcBuildRegions(m_ctx, *m_chf, 0, m_cfg.minRegionArea, m_cfg.mergeRegionArea))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build watershed regions.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (m_partitionType == SAMPLE_PARTITION_MONOTONE)
|
||||
{
|
||||
// Partition the walkable surface into simple regions without holes.
|
||||
// Monotone partitioning does not need distancefield.
|
||||
if (!rcBuildRegionsMonotone(m_ctx, *m_chf, 0, m_cfg.minRegionArea, m_cfg.mergeRegionArea))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build monotone regions.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else // SAMPLE_PARTITION_LAYERS
|
||||
{
|
||||
// Partition the walkable surface into simple regions without holes.
|
||||
if (!rcBuildLayerRegions(m_ctx, *m_chf, 0, m_cfg.minRegionArea))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build layer regions.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Step 5. Trace and simplify region contours.
|
||||
//
|
||||
|
||||
// Create contours.
|
||||
m_cset = rcAllocContourSet();
|
||||
if (!m_cset)
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'cset'.");
|
||||
return false;
|
||||
}
|
||||
if (!rcBuildContours(m_ctx, *m_chf, m_cfg.maxSimplificationError, m_cfg.maxEdgeLen, *m_cset))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not create contours.");
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Step 6. Build polygons mesh from contours.
|
||||
//
|
||||
|
||||
// Build polygon navmesh from the contours.
|
||||
m_pmesh = rcAllocPolyMesh();
|
||||
if (!m_pmesh)
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmesh'.");
|
||||
return false;
|
||||
}
|
||||
if (!rcBuildPolyMesh(m_ctx, *m_cset, m_cfg.maxVertsPerPoly, *m_pmesh))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not triangulate contours.");
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// Step 7. Create detail mesh which allows to access approximate height on each polygon.
|
||||
//
|
||||
|
||||
m_dmesh = rcAllocPolyMeshDetail();
|
||||
if (!m_dmesh)
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Out of memory 'pmdtl'.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rcBuildPolyMeshDetail(m_ctx, *m_pmesh, *m_chf, m_cfg.detailSampleDist, m_cfg.detailSampleMaxError, *m_dmesh))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "buildNavigation: Could not build detail mesh.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_keepInterResults)
|
||||
{
|
||||
rcFreeCompactHeightfield(m_chf);
|
||||
m_chf = 0;
|
||||
rcFreeContourSet(m_cset);
|
||||
m_cset = 0;
|
||||
}
|
||||
|
||||
// At this point the navigation mesh data is ready, you can access it from m_pmesh.
|
||||
// See duDebugDrawPolyMesh or dtCreateNavMeshData as examples how to access the data.
|
||||
|
||||
//
|
||||
// (Optional) Step 8. Create Detour data from Recast poly mesh.
|
||||
//
|
||||
|
||||
// The GUI may allow more max points per polygon than Detour can handle.
|
||||
// Only build the detour navmesh if we do not exceed the limit.
|
||||
if (m_cfg.maxVertsPerPoly <= DT_VERTS_PER_POLYGON)
|
||||
{
|
||||
unsigned char* navData = 0;
|
||||
int navDataSize = 0;
|
||||
|
||||
// Update poly flags from areas.
|
||||
for (int i = 0; i < m_pmesh->npolys; ++i)
|
||||
{
|
||||
if (m_pmesh->areas[i] == RC_WALKABLE_AREA)
|
||||
m_pmesh->areas[i] = SAMPLE_POLYAREA_GROUND;
|
||||
|
||||
if (m_pmesh->areas[i] == SAMPLE_POLYAREA_GROUND ||
|
||||
m_pmesh->areas[i] == SAMPLE_POLYAREA_GRASS ||
|
||||
m_pmesh->areas[i] == SAMPLE_POLYAREA_ROAD)
|
||||
{
|
||||
m_pmesh->flags[i] = SAMPLE_POLYFLAGS_WALK;
|
||||
}
|
||||
else if (m_pmesh->areas[i] == SAMPLE_POLYAREA_WATER)
|
||||
{
|
||||
m_pmesh->flags[i] = SAMPLE_POLYFLAGS_SWIM;
|
||||
}
|
||||
else if (m_pmesh->areas[i] == SAMPLE_POLYAREA_DOOR)
|
||||
{
|
||||
m_pmesh->flags[i] = SAMPLE_POLYFLAGS_WALK | SAMPLE_POLYFLAGS_DOOR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dtNavMeshCreateParams params;
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
params.verts = m_pmesh->verts;
|
||||
params.vertCount = m_pmesh->nverts;
|
||||
params.polys = m_pmesh->polys;
|
||||
params.polyAreas = m_pmesh->areas;
|
||||
params.polyFlags = m_pmesh->flags;
|
||||
params.polyCount = m_pmesh->npolys;
|
||||
params.nvp = m_pmesh->nvp;
|
||||
params.detailMeshes = m_dmesh->meshes;
|
||||
params.detailVerts = m_dmesh->verts;
|
||||
params.detailVertsCount = m_dmesh->nverts;
|
||||
params.detailTris = m_dmesh->tris;
|
||||
params.detailTriCount = m_dmesh->ntris;
|
||||
params.offMeshConVerts = m_geom->getOffMeshConnectionVerts();
|
||||
params.offMeshConRad = m_geom->getOffMeshConnectionRads();
|
||||
params.offMeshConDir = m_geom->getOffMeshConnectionDirs();
|
||||
params.offMeshConAreas = m_geom->getOffMeshConnectionAreas();
|
||||
params.offMeshConFlags = m_geom->getOffMeshConnectionFlags();
|
||||
params.offMeshConUserID = m_geom->getOffMeshConnectionId();
|
||||
params.offMeshConCount = m_geom->getOffMeshConnectionCount();
|
||||
params.walkableHeight = m_agentHeight;
|
||||
params.walkableRadius = m_agentRadius;
|
||||
params.walkableClimb = m_agentMaxClimb;
|
||||
rcVcopy(params.bmin, m_pmesh->bmin);
|
||||
rcVcopy(params.bmax, m_pmesh->bmax);
|
||||
params.cs = m_cfg.cs;
|
||||
params.ch = m_cfg.ch;
|
||||
params.buildBvTree = true;
|
||||
|
||||
if (!dtCreateNavMeshData(¶ms, &navData, &navDataSize))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "Could not build Detour navmesh.");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_navMesh = dtAllocNavMesh();
|
||||
if (!m_navMesh)
|
||||
{
|
||||
dtFree(navData);
|
||||
m_ctx->log(RC_LOG_ERROR, "Could not create Detour navmesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
dtStatus status;
|
||||
|
||||
status = m_navMesh->init(navData, navDataSize, DT_TILE_FREE_DATA);
|
||||
if (dtStatusFailed(status))
|
||||
{
|
||||
dtFree(navData);
|
||||
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh");
|
||||
return false;
|
||||
}
|
||||
|
||||
status = m_navQuery->init(m_navMesh, 2048);
|
||||
if (dtStatusFailed(status))
|
||||
{
|
||||
m_ctx->log(RC_LOG_ERROR, "Could not init Detour navmesh query");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_ctx->stopTimer(RC_TIMER_TOTAL);
|
||||
|
||||
// Show performance stats.
|
||||
duLogBuildTimes(*m_ctx, m_ctx->getAccumulatedTime(RC_TIMER_TOTAL));
|
||||
m_ctx->log(RC_LOG_PROGRESS, ">> Polymesh: %d vertices %d polygons", m_pmesh->nverts, m_pmesh->npolys);
|
||||
|
||||
m_totalBuildTimeMs = m_ctx->getAccumulatedTime(RC_TIMER_TOTAL)/1000.0f;
|
||||
|
||||
if (m_tool)
|
||||
m_tool->init(this);
|
||||
initToolStates(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
1363
dep/recastnavigation/RecastDemo/Source/Sample_TempObstacles.cpp
Normal file
1363
dep/recastnavigation/RecastDemo/Source/Sample_TempObstacles.cpp
Normal file
File diff suppressed because it is too large
Load diff
178
dep/recastnavigation/RecastDemo/premake4.lua
Normal file
178
dep/recastnavigation/RecastDemo/premake4.lua
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
--
|
||||
-- premake4 file to build RecastDemo
|
||||
-- http://industriousone.com/premake
|
||||
--
|
||||
|
||||
local action = _ACTION or ""
|
||||
local todir = "Build/" .. action
|
||||
|
||||
solution "recastnavigation"
|
||||
configurations {
|
||||
"Debug",
|
||||
"Release"
|
||||
}
|
||||
location (todir)
|
||||
|
||||
-- extra warnings, no exceptions or rtti
|
||||
flags {
|
||||
"ExtraWarnings",
|
||||
"FloatFast",
|
||||
"NoExceptions",
|
||||
"NoRTTI",
|
||||
"Symbols"
|
||||
}
|
||||
|
||||
-- debug configs
|
||||
configuration "Debug*"
|
||||
defines { "DEBUG" }
|
||||
targetdir ( todir .. "/lib/Debug" )
|
||||
|
||||
-- release configs
|
||||
configuration "Release*"
|
||||
defines { "NDEBUG" }
|
||||
flags { "Optimize" }
|
||||
targetdir ( todir .. "/lib/Release" )
|
||||
|
||||
-- windows specific
|
||||
configuration "windows"
|
||||
defines { "WIN32", "_WINDOWS", "_CRT_SECURE_NO_WARNINGS" }
|
||||
|
||||
|
||||
project "DebugUtils"
|
||||
language "C++"
|
||||
kind "StaticLib"
|
||||
includedirs {
|
||||
"../DebugUtils/Include",
|
||||
"../Detour/Include",
|
||||
"../DetourTileCache/Include",
|
||||
"../Recast/Include"
|
||||
}
|
||||
files {
|
||||
"../DebugUtils/Include/*.h",
|
||||
"../DebugUtils/Source/*.cpp"
|
||||
}
|
||||
|
||||
project "Detour"
|
||||
language "C++"
|
||||
kind "StaticLib"
|
||||
includedirs {
|
||||
"../Detour/Include"
|
||||
}
|
||||
files {
|
||||
"../Detour/Include/*.h",
|
||||
"../Detour/Source/*.cpp"
|
||||
}
|
||||
|
||||
project "DetourCrowd"
|
||||
language "C++"
|
||||
kind "StaticLib"
|
||||
includedirs {
|
||||
"../DetourCrowd/Include",
|
||||
"../Detour/Include",
|
||||
"../Recast/Include"
|
||||
}
|
||||
files {
|
||||
"../DetourCrowd/Include/*.h",
|
||||
"../DetourCrowd/Source/*.cpp"
|
||||
}
|
||||
|
||||
project "DetourTileCache"
|
||||
language "C++"
|
||||
kind "StaticLib"
|
||||
includedirs {
|
||||
"../DetourTileCache/Include",
|
||||
"../Detour/Include",
|
||||
"../Recast/Include"
|
||||
}
|
||||
files {
|
||||
"../DetourTileCache/Include/*.h",
|
||||
"../DetourTileCache/Source/*.cpp"
|
||||
}
|
||||
|
||||
project "Recast"
|
||||
language "C++"
|
||||
kind "StaticLib"
|
||||
includedirs {
|
||||
"../Recast/Include"
|
||||
}
|
||||
files {
|
||||
"../Recast/Include/*.h",
|
||||
"../Recast/Source/*.cpp"
|
||||
}
|
||||
|
||||
project "RecastDemo"
|
||||
language "C++"
|
||||
kind "WindowedApp"
|
||||
includedirs {
|
||||
"../RecastDemo/Include",
|
||||
"../RecastDemo/Contrib",
|
||||
"../RecastDemo/Contrib/fastlz",
|
||||
"../DebugUtils/Include",
|
||||
"../Detour/Include",
|
||||
"../DetourCrowd/Include",
|
||||
"../DetourTileCache/Include",
|
||||
"../Recast/Include"
|
||||
}
|
||||
files {
|
||||
"../RecastDemo/Include/*.h",
|
||||
"../RecastDemo/Source/*.cpp",
|
||||
"../RecastDemo/Contrib/fastlz/*.h",
|
||||
"../RecastDemo/Contrib/fastlz/*.c"
|
||||
}
|
||||
|
||||
-- project dependencies
|
||||
links {
|
||||
"DebugUtils",
|
||||
"Detour",
|
||||
"DetourCrowd",
|
||||
"DetourTileCache",
|
||||
"Recast"
|
||||
}
|
||||
|
||||
-- distribute executable in RecastDemo/Bin directory
|
||||
targetdir "Bin"
|
||||
|
||||
-- linux library cflags and libs
|
||||
configuration { "linux", "gmake" }
|
||||
buildoptions {
|
||||
"`pkg-config --cflags sdl`",
|
||||
"`pkg-config --cflags gl`",
|
||||
"`pkg-config --cflags glu`"
|
||||
}
|
||||
linkoptions {
|
||||
"`pkg-config --libs sdl`",
|
||||
"`pkg-config --libs gl`",
|
||||
"`pkg-config --libs glu`"
|
||||
}
|
||||
|
||||
-- windows library cflags and libs
|
||||
configuration { "windows" }
|
||||
includedirs { "../RecastDemo/Contrib/SDL/include" }
|
||||
libdirs { "../RecastDemo/Contrib/SDL/lib/x86" }
|
||||
links {
|
||||
"opengl32",
|
||||
"glu32",
|
||||
"sdlmain",
|
||||
"sdl"
|
||||
}
|
||||
|
||||
-- mac includes and libs
|
||||
configuration { "macosx" }
|
||||
kind "ConsoleApp" -- xcode4 failes to run the project if using WindowedApp
|
||||
includedirs { "/Library/Frameworks/SDL.framework/Headers" }
|
||||
buildoptions { "-Wunused-value -Wshadow -Wreorder -Wsign-compare -Wall" }
|
||||
links {
|
||||
"OpenGL.framework",
|
||||
"/Library/Frameworks/SDL.framework",
|
||||
"Cocoa.framework",
|
||||
}
|
||||
|
||||
files {
|
||||
"../RecastDemo/Include/SDLMain.h",
|
||||
"../RecastDemo/Source/SDLMain.m",
|
||||
-- These don't seem to work in xcode4 target yet.
|
||||
-- "Info.plist",
|
||||
-- "Icon.icns",
|
||||
-- "English.lproj/InfoPlist.strings",
|
||||
-- "English.lproj/MainMenu.xib",
|
||||
}
|
||||
BIN
dep/recastnavigation/RecastDemo/screenshot.png
Normal file
BIN
dep/recastnavigation/RecastDemo/screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 450 KiB |
Loading…
Add table
Add a link
Reference in a new issue