polys(alloc, maxVertsPerCont*MAX_VERTS_PER_POLY);
+ if (!polys)
+ return DT_FAILURE | DT_OUT_OF_MEMORY;
+
+ for (int i = 0; i < lcset.nconts; ++i)
+ {
+ dtTileCacheContour& cont = lcset.conts[i];
+
+ // Skip null contours.
+ if (cont.nverts < 3)
+ continue;
+
+ // Triangulate contour
+ for (int j = 0; j < cont.nverts; ++j)
+ indices[j] = (unsigned short)j;
+
+ int ntris = triangulate(cont.nverts, cont.verts, &indices[0], &tris[0]);
+ if (ntris <= 0)
+ {
+ // TODO: issue warning!
+ ntris = -ntris;
+ }
+
+ // Add and merge vertices.
+ for (int j = 0; j < cont.nverts; ++j)
+ {
+ const unsigned char* v = &cont.verts[j*4];
+ indices[j] = addVertex((unsigned short)v[0], (unsigned short)v[1], (unsigned short)v[2],
+ mesh.verts, firstVert, nextVert, mesh.nverts);
+ if (v[3] & 0x80)
+ {
+ // This vertex should be removed.
+ vflags[indices[j]] = 1;
+ }
+ }
+
+ // Build initial polygons.
+ int npolys = 0;
+ memset(polys, 0xff, sizeof(unsigned short) * maxVertsPerCont * MAX_VERTS_PER_POLY);
+ for (int j = 0; j < ntris; ++j)
+ {
+ const unsigned short* t = &tris[j*3];
+ if (t[0] != t[1] && t[0] != t[2] && t[1] != t[2])
+ {
+ polys[npolys*MAX_VERTS_PER_POLY+0] = indices[t[0]];
+ polys[npolys*MAX_VERTS_PER_POLY+1] = indices[t[1]];
+ polys[npolys*MAX_VERTS_PER_POLY+2] = indices[t[2]];
+ npolys++;
+ }
+ }
+ if (!npolys)
+ continue;
+
+ // Merge polygons.
+ int maxVertsPerPoly =MAX_VERTS_PER_POLY ;
+ if (maxVertsPerPoly > 3)
+ {
+ for(;;)
+ {
+ // Find best polygons to merge.
+ int bestMergeVal = 0;
+ int bestPa = 0, bestPb = 0, bestEa = 0, bestEb = 0;
+
+ for (int j = 0; j < npolys-1; ++j)
+ {
+ unsigned short* pj = &polys[j*MAX_VERTS_PER_POLY];
+ for (int k = j+1; k < npolys; ++k)
+ {
+ unsigned short* pk = &polys[k*MAX_VERTS_PER_POLY];
+ int ea, eb;
+ int v = getPolyMergeValue(pj, pk, mesh.verts, ea, eb);
+ if (v > bestMergeVal)
+ {
+ bestMergeVal = v;
+ bestPa = j;
+ bestPb = k;
+ bestEa = ea;
+ bestEb = eb;
+ }
+ }
+ }
+
+ if (bestMergeVal > 0)
+ {
+ // Found best, merge.
+ unsigned short* pa = &polys[bestPa*MAX_VERTS_PER_POLY];
+ unsigned short* pb = &polys[bestPb*MAX_VERTS_PER_POLY];
+ mergePolys(pa, pb, bestEa, bestEb);
+ memcpy(pb, &polys[(npolys-1)*MAX_VERTS_PER_POLY], sizeof(unsigned short)*MAX_VERTS_PER_POLY);
+ npolys--;
+ }
+ else
+ {
+ // Could not merge any polygons, stop.
+ break;
+ }
+ }
+ }
+
+ // Store polygons.
+ for (int j = 0; j < npolys; ++j)
+ {
+ unsigned short* p = &mesh.polys[mesh.npolys*MAX_VERTS_PER_POLY*2];
+ unsigned short* q = &polys[j*MAX_VERTS_PER_POLY];
+ for (int k = 0; k < MAX_VERTS_PER_POLY; ++k)
+ p[k] = q[k];
+ mesh.areas[mesh.npolys] = cont.area;
+ mesh.npolys++;
+ if (mesh.npolys > maxTris)
+ return DT_FAILURE | DT_BUFFER_TOO_SMALL;
+ }
+ }
+
+
+ // Remove edge vertices.
+ for (int i = 0; i < mesh.nverts; ++i)
+ {
+ if (vflags[i])
+ {
+ if (!canRemoveVertex(mesh, (unsigned short)i))
+ continue;
+ dtStatus status = removeVertex(mesh, (unsigned short)i, maxTris);
+ if (dtStatusFailed(status))
+ return status;
+ // Remove vertex
+ // Note: mesh.nverts is already decremented inside removeVertex()!
+ for (int j = i; j < mesh.nverts; ++j)
+ vflags[j] = vflags[j+1];
+ --i;
+ }
+ }
+
+ // Calculate adjacency.
+ if (!buildMeshAdjacency(alloc, mesh.polys, mesh.npolys, mesh.verts, mesh.nverts, lcset))
+ return DT_FAILURE | DT_OUT_OF_MEMORY;
+
+ return DT_SUCCESS;
+}
+
+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)
+{
+ float bmin[3], bmax[3];
+ bmin[0] = pos[0] - radius;
+ bmin[1] = pos[1];
+ bmin[2] = pos[2] - radius;
+ bmax[0] = pos[0] + radius;
+ bmax[1] = pos[1] + height;
+ bmax[2] = pos[2] + radius;
+ const float r2 = dtSqr(radius/cs + 0.5f);
+
+ const int w = (int)layer.header->width;
+ const int h = (int)layer.header->height;
+ const float ics = 1.0f/cs;
+ const float ich = 1.0f/ch;
+
+ const float px = (pos[0]-orig[0])*ics;
+ const float pz = (pos[2]-orig[2])*ics;
+
+ int minx = (int)dtMathFloorf((bmin[0]-orig[0])*ics);
+ int miny = (int)dtMathFloorf((bmin[1]-orig[1])*ich);
+ int minz = (int)dtMathFloorf((bmin[2]-orig[2])*ics);
+ int maxx = (int)dtMathFloorf((bmax[0]-orig[0])*ics);
+ int maxy = (int)dtMathFloorf((bmax[1]-orig[1])*ich);
+ int maxz = (int)dtMathFloorf((bmax[2]-orig[2])*ics);
+
+ if (maxx < 0) return DT_SUCCESS;
+ if (minx >= w) return DT_SUCCESS;
+ if (maxz < 0) return DT_SUCCESS;
+ if (minz >= h) return DT_SUCCESS;
+
+ if (minx < 0) minx = 0;
+ if (maxx >= w) maxx = w-1;
+ if (minz < 0) minz = 0;
+ if (maxz >= h) maxz = h-1;
+
+ for (int z = minz; z <= maxz; ++z)
+ {
+ for (int x = minx; x <= maxx; ++x)
+ {
+ const float dx = (float)(x+0.5f) - px;
+ const float dz = (float)(z+0.5f) - pz;
+ if (dx*dx + dz*dz > r2)
+ continue;
+ const int y = layer.heights[x+z*w];
+ if (y < miny || y > maxy)
+ continue;
+ layer.areas[x+z*w] = areaId;
+ }
+ }
+
+ return DT_SUCCESS;
+}
+
+dtStatus dtMarkBoxArea(dtTileCacheLayer& layer, const float* orig, const float cs, const float ch,
+ const float* bmin, const float* bmax, const unsigned char areaId)
+{
+ const int w = (int)layer.header->width;
+ const int h = (int)layer.header->height;
+ const float ics = 1.0f/cs;
+ const float ich = 1.0f/ch;
+
+ int minx = (int)floorf((bmin[0]-orig[0])*ics);
+ int miny = (int)floorf((bmin[1]-orig[1])*ich);
+ int minz = (int)floorf((bmin[2]-orig[2])*ics);
+ int maxx = (int)floorf((bmax[0]-orig[0])*ics);
+ int maxy = (int)floorf((bmax[1]-orig[1])*ich);
+ int maxz = (int)floorf((bmax[2]-orig[2])*ics);
+
+ if (maxx < 0) return DT_SUCCESS;
+ if (minx >= w) return DT_SUCCESS;
+ if (maxz < 0) return DT_SUCCESS;
+ if (minz >= h) return DT_SUCCESS;
+
+ if (minx < 0) minx = 0;
+ if (maxx >= w) maxx = w-1;
+ if (minz < 0) minz = 0;
+ if (maxz >= h) maxz = h-1;
+
+ for (int z = minz; z <= maxz; ++z)
+ {
+ for (int x = minx; x <= maxx; ++x)
+ {
+ const int y = layer.heights[x+z*w];
+ if (y < miny || y > maxy)
+ continue;
+ layer.areas[x+z*w] = areaId;
+ }
+ }
+
+ return DT_SUCCESS;
+}
+
+dtStatus dtMarkBoxArea(dtTileCacheLayer& layer, const float* orig, const float cs, const float ch,
+ const float* center, const float* halfExtents, const float* rotAux, const unsigned char areaId)
+{
+ const int w = (int)layer.header->width;
+ const int h = (int)layer.header->height;
+ const float ics = 1.0f/cs;
+ const float ich = 1.0f/ch;
+
+ float cx = (center[0] - orig[0])*ics;
+ float cz = (center[2] - orig[2])*ics;
+
+ float maxr = 1.41f*dtMax(halfExtents[0], halfExtents[2]);
+ int minx = (int)floorf(cx - maxr*ics);
+ int maxx = (int)floorf(cx + maxr*ics);
+ int minz = (int)floorf(cz - maxr*ics);
+ int maxz = (int)floorf(cz + maxr*ics);
+ int miny = (int)floorf((center[1]-halfExtents[1]-orig[1])*ich);
+ int maxy = (int)floorf((center[1]+halfExtents[1]-orig[1])*ich);
+
+ if (maxx < 0) return DT_SUCCESS;
+ if (minx >= w) return DT_SUCCESS;
+ if (maxz < 0) return DT_SUCCESS;
+ if (minz >= h) return DT_SUCCESS;
+
+ if (minx < 0) minx = 0;
+ if (maxx >= w) maxx = w-1;
+ if (minz < 0) minz = 0;
+ if (maxz >= h) maxz = h-1;
+
+ float xhalf = halfExtents[0]*ics + 0.5f;
+ float zhalf = halfExtents[2]*ics + 0.5f;
+
+ for (int z = minz; z <= maxz; ++z)
+ {
+ for (int x = minx; x <= maxx; ++x)
+ {
+ float x2 = 2.0f*(float(x) - cx);
+ float z2 = 2.0f*(float(z) - cz);
+ float xrot = rotAux[1]*x2 + rotAux[0]*z2;
+ if (xrot > xhalf || xrot < -xhalf)
+ continue;
+ float zrot = rotAux[1]*z2 - rotAux[0]*x2;
+ if (zrot > zhalf || zrot < -zhalf)
+ continue;
+ const int y = layer.heights[x+z*w];
+ if (y < miny || y > maxy)
+ continue;
+ layer.areas[x+z*w] = areaId;
+ }
+ }
+
+ return DT_SUCCESS;
+}
+
+dtStatus dtBuildTileCacheLayer(dtTileCacheCompressor* comp,
+ dtTileCacheLayerHeader* header,
+ const unsigned char* heights,
+ const unsigned char* areas,
+ const unsigned char* cons,
+ unsigned char** outData, int* outDataSize)
+{
+ const int headerSize = dtAlign4(sizeof(dtTileCacheLayerHeader));
+ const int gridSize = (int)header->width * (int)header->height;
+ const int maxDataSize = headerSize + comp->maxCompressedSize(gridSize*3);
+ unsigned char* data = (unsigned char*)dtAlloc(maxDataSize, DT_ALLOC_PERM);
+ if (!data)
+ return DT_FAILURE | DT_OUT_OF_MEMORY;
+ memset(data, 0, maxDataSize);
+
+ // Store header
+ memcpy(data, header, sizeof(dtTileCacheLayerHeader));
+
+ // Concatenate grid data for compression.
+ const int bufferSize = gridSize*3;
+ unsigned char* buffer = (unsigned char*)dtAlloc(bufferSize, DT_ALLOC_TEMP);
+ if (!buffer)
+ {
+ dtFree(data);
+ return DT_FAILURE | DT_OUT_OF_MEMORY;
+ }
+
+ memcpy(buffer, heights, gridSize);
+ memcpy(buffer+gridSize, areas, gridSize);
+ memcpy(buffer+gridSize*2, cons, gridSize);
+
+ // Compress
+ unsigned char* compressed = data + headerSize;
+ const int maxCompressedSize = maxDataSize - headerSize;
+ int compressedSize = 0;
+ dtStatus status = comp->compress(buffer, bufferSize, compressed, maxCompressedSize, &compressedSize);
+ if (dtStatusFailed(status))
+ {
+ dtFree(buffer);
+ dtFree(data);
+ return status;
+ }
+
+ *outData = data;
+ *outDataSize = headerSize + compressedSize;
+
+ dtFree(buffer);
+
+ return DT_SUCCESS;
+}
+
+void dtFreeTileCacheLayer(dtTileCacheAlloc* alloc, dtTileCacheLayer* layer)
+{
+ dtAssert(alloc);
+ // The layer is allocated as one conitguous blob of data.
+ alloc->free(layer);
+}
+
+dtStatus dtDecompressTileCacheLayer(dtTileCacheAlloc* alloc, dtTileCacheCompressor* comp,
+ unsigned char* compressed, const int compressedSize,
+ dtTileCacheLayer** layerOut)
+{
+ dtAssert(alloc);
+ dtAssert(comp);
+
+ if (!layerOut)
+ return DT_FAILURE | DT_INVALID_PARAM;
+ if (!compressed)
+ return DT_FAILURE | DT_INVALID_PARAM;
+
+ *layerOut = 0;
+
+ dtTileCacheLayerHeader* compressedHeader = (dtTileCacheLayerHeader*)compressed;
+ if (compressedHeader->magic != DT_TILECACHE_MAGIC)
+ return DT_FAILURE | DT_WRONG_MAGIC;
+ if (compressedHeader->version != DT_TILECACHE_VERSION)
+ return DT_FAILURE | DT_WRONG_VERSION;
+
+ const int layerSize = dtAlign4(sizeof(dtTileCacheLayer));
+ const int headerSize = dtAlign4(sizeof(dtTileCacheLayerHeader));
+ const int gridSize = (int)compressedHeader->width * (int)compressedHeader->height;
+ const int bufferSize = layerSize + headerSize + gridSize*4;
+
+ unsigned char* buffer = (unsigned char*)alloc->alloc(bufferSize);
+ if (!buffer)
+ return DT_FAILURE | DT_OUT_OF_MEMORY;
+ memset(buffer, 0, bufferSize);
+
+ dtTileCacheLayer* layer = (dtTileCacheLayer*)buffer;
+ dtTileCacheLayerHeader* header = (dtTileCacheLayerHeader*)(buffer + layerSize);
+ unsigned char* grids = buffer + layerSize + headerSize;
+ const int gridsSize = bufferSize - (layerSize + headerSize);
+
+ // Copy header
+ memcpy(header, compressedHeader, headerSize);
+ // Decompress grid.
+ int size = 0;
+ dtStatus status = comp->decompress(compressed+headerSize, compressedSize-headerSize,
+ grids, gridsSize, &size);
+ if (dtStatusFailed(status))
+ {
+ alloc->free(buffer);
+ return status;
+ }
+
+ layer->header = header;
+ layer->heights = grids;
+ layer->areas = grids + gridSize;
+ layer->cons = grids + gridSize*2;
+ layer->regs = grids + gridSize*3;
+
+ *layerOut = layer;
+
+ return DT_SUCCESS;
+}
+
+
+
+bool dtTileCacheHeaderSwapEndian(unsigned char* data, const int dataSize)
+{
+ dtIgnoreUnused(dataSize);
+ dtTileCacheLayerHeader* header = (dtTileCacheLayerHeader*)data;
+
+ int swappedMagic = DT_TILECACHE_MAGIC;
+ int swappedVersion = DT_TILECACHE_VERSION;
+ dtSwapEndian(&swappedMagic);
+ dtSwapEndian(&swappedVersion);
+
+ if ((header->magic != DT_TILECACHE_MAGIC || header->version != DT_TILECACHE_VERSION) &&
+ (header->magic != swappedMagic || header->version != swappedVersion))
+ {
+ return false;
+ }
+
+ dtSwapEndian(&header->magic);
+ dtSwapEndian(&header->version);
+ dtSwapEndian(&header->tx);
+ dtSwapEndian(&header->ty);
+ dtSwapEndian(&header->tlayer);
+ dtSwapEndian(&header->bmin[0]);
+ dtSwapEndian(&header->bmin[1]);
+ dtSwapEndian(&header->bmin[2]);
+ dtSwapEndian(&header->bmax[0]);
+ dtSwapEndian(&header->bmax[1]);
+ dtSwapEndian(&header->bmax[2]);
+ dtSwapEndian(&header->hmin);
+ dtSwapEndian(&header->hmax);
+
+ // width, height, minx, maxx, miny, maxy are unsigned char, no need to swap.
+
+ return true;
+}
+
diff --git a/extern/recastnavigation/Docs/Conceptual/license_c.txt b/extern/recastnavigation/Docs/Conceptual/license_c.txt
new file mode 100644
index 000000000..c2a3c1e85
--- /dev/null
+++ b/extern/recastnavigation/Docs/Conceptual/license_c.txt
@@ -0,0 +1,27 @@
+
+/**
+@page License License
+
+
+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.
+
+
+*/
\ No newline at end of file
diff --git a/extern/recastnavigation/Docs/Conceptual/mainpage_c.txt b/extern/recastnavigation/Docs/Conceptual/mainpage_c.txt
new file mode 100644
index 000000000..14dd1cf8f
--- /dev/null
+++ b/extern/recastnavigation/Docs/Conceptual/mainpage_c.txt
@@ -0,0 +1,109 @@
+/// @mainpage Recast Navigation
+///
+/// @image html recast_intro.png
+///
+/// Recast
+///
+/// _Recast_ is a 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
+/// GitHub.
+///
+/// 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 triangulating 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 generated 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.
+///
+/// Detour
+///
+/// _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.
+///
+/// Recast Demo
+///
+/// You can find a comprehensive demo project in the `RecastDemo` folder. It
+/// is a kitchen sink demo containing all the major functionality of the library.
+/// If you are new to _Recast_ & _Detour_, check out
+///
+/// Sample_SoloMesh.cpp to get started with building navmeshes and
+///
+/// NavMeshTesterTool.cpp to see how _Detour_ can be used to find paths.
+///
+/// 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.
+///
+/// Linux
+///
+/// - 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`
+///
+/// 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.
+///
+/// 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`.
+///
+/// Contributing
+/// All development is centralized in github. Check out the Contributing Guidelines for more information.
+///
+/// Discuss
+///
+/// - Discuss _Recast_ and _Detour_:
+///
+/// Recast Navigation Group
+/// - Development Blog:
+/// Digesting Duck
+///
+/// License
+///
+/// _Recast Navigation_ is licensed under the ZLib license.
+///
diff --git a/extern/recastnavigation/Docs/DoxygenLayout.xml b/extern/recastnavigation/Docs/DoxygenLayout.xml
new file mode 100644
index 000000000..b20079c91
--- /dev/null
+++ b/extern/recastnavigation/Docs/DoxygenLayout.xml
@@ -0,0 +1,194 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/extern/recastnavigation/Docs/Extern/Recast_api.txt b/extern/recastnavigation/Docs/Extern/Recast_api.txt
new file mode 100644
index 000000000..f6ff06444
--- /dev/null
+++ b/extern/recastnavigation/Docs/Extern/Recast_api.txt
@@ -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 (#cs width) * (#cs depth) * (#ch height). (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:
+
+Direction 0 = (-1, 0)
+Direction 1 = (0, 1)
+Direction 2 = (1, 0)
+Direction 3 = (0, -1)
+
+
+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 2 * #nvp 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:
+
+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.
+
+
+@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
+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.
+
+Vertex Indices
+
+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:
+
+
+Position 0: Edge AB (>> 0)
+Position 1: Edge BC (>> 2)
+Position 2: Edge CA (>> 4)
+Position 4: Unused
+
+
+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.
+
+*/
diff --git a/extern/recastnavigation/Docs/Images/recast_intro.png b/extern/recastnavigation/Docs/Images/recast_intro.png
new file mode 100644
index 000000000..ad18ac610
Binary files /dev/null and b/extern/recastnavigation/Docs/Images/recast_intro.png differ
diff --git a/extern/recastnavigation/Docs/Readme.txt b/extern/recastnavigation/Docs/Readme.txt
new file mode 100644
index 000000000..be153b94b
--- /dev/null
+++ b/extern/recastnavigation/Docs/Readme.txt
@@ -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)"
+
+
+
+
+
+
diff --git a/extern/recastnavigation/Docs/footer.html b/extern/recastnavigation/Docs/footer.html
new file mode 100644
index 000000000..5bd570ad1
--- /dev/null
+++ b/extern/recastnavigation/Docs/footer.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+