mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-07-13 07:34:45 +00:00
update recast
This commit is contained in:
parent
e079536122
commit
8aa48ff21b
34 changed files with 1138 additions and 407 deletions
|
|
@ -23,6 +23,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <new>
|
||||
#include "Recast.h"
|
||||
#include "RecastAlloc.h"
|
||||
#include "RecastAssert.h"
|
||||
|
|
@ -72,23 +73,39 @@ void rcContext::log(const rcLogCategory category, const char* format, ...)
|
|||
|
||||
rcHeightfield* rcAllocHeightfield()
|
||||
{
|
||||
rcHeightfield* hf = (rcHeightfield*)rcAlloc(sizeof(rcHeightfield), RC_ALLOC_PERM);
|
||||
memset(hf, 0, sizeof(rcHeightfield));
|
||||
return hf;
|
||||
return new (rcAlloc(sizeof(rcHeightfield), RC_ALLOC_PERM)) rcHeightfield;
|
||||
}
|
||||
|
||||
rcHeightfield::rcHeightfield()
|
||||
: width()
|
||||
, height()
|
||||
, bmin()
|
||||
, bmax()
|
||||
, cs()
|
||||
, ch()
|
||||
, spans()
|
||||
, pools()
|
||||
, freelist()
|
||||
{
|
||||
}
|
||||
|
||||
rcHeightfield::~rcHeightfield()
|
||||
{
|
||||
// Delete span array.
|
||||
rcFree(spans);
|
||||
// Delete span pools.
|
||||
while (pools)
|
||||
{
|
||||
rcSpanPool* next = pools->next;
|
||||
rcFree(pools);
|
||||
pools = next;
|
||||
}
|
||||
}
|
||||
|
||||
void rcFreeHeightField(rcHeightfield* hf)
|
||||
{
|
||||
if (!hf) return;
|
||||
// Delete span array.
|
||||
rcFree(hf->spans);
|
||||
// Delete span pools.
|
||||
while (hf->pools)
|
||||
{
|
||||
rcSpanPool* next = hf->pools->next;
|
||||
rcFree(hf->pools);
|
||||
hf->pools = next;
|
||||
}
|
||||
hf->~rcHeightfield();
|
||||
rcFree(hf);
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +126,6 @@ void rcFreeCompactHeightfield(rcCompactHeightfield* chf)
|
|||
rcFree(chf);
|
||||
}
|
||||
|
||||
|
||||
rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet()
|
||||
{
|
||||
rcHeightfieldLayerSet* lset = (rcHeightfieldLayerSet*)rcAlloc(sizeof(rcHeightfieldLayerSet), RC_ALLOC_PERM);
|
||||
|
|
@ -245,11 +261,12 @@ static void calcTriNormal(const float* v0, const float* v1, const float* v2, flo
|
|||
///
|
||||
/// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles
|
||||
void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle,
|
||||
const float* verts, int /*nv*/,
|
||||
const float* verts, int nv,
|
||||
const int* tris, int nt,
|
||||
unsigned char* areas)
|
||||
{
|
||||
rcIgnoreUnused(ctx);
|
||||
rcIgnoreUnused(nv);
|
||||
|
||||
const float walkableThr = cosf(walkableSlopeAngle/180.0f*RC_PI);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "RecastAlloc.h"
|
||||
#include "RecastAssert.h"
|
||||
|
||||
static void *rcAllocDefault(size_t size, rcAllocHint)
|
||||
{
|
||||
|
|
@ -77,6 +78,7 @@ void rcIntArray::doResize(int n)
|
|||
if (!m_cap) m_cap = n;
|
||||
while (m_cap < n) m_cap *= 2;
|
||||
int* newData = (int*)rcAlloc(m_cap*sizeof(int), RC_ALLOC_TEMP);
|
||||
rcAssert(newData);
|
||||
if (m_size && newData) memcpy(newData, m_data, m_size*sizeof(int));
|
||||
rcFree(m_data);
|
||||
m_data = newData;
|
||||
|
|
|
|||
35
Engine/lib/recast/Recast/Source/RecastAssert.cpp
Normal file
35
Engine/lib/recast/Recast/Source/RecastAssert.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// 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 "RecastAssert.h"
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
static rcAssertFailFunc* sRecastAssertFailFunc = 0;
|
||||
|
||||
void rcAssertFailSetCustom(rcAssertFailFunc *assertFailFunc)
|
||||
{
|
||||
sRecastAssertFailFunc = assertFailFunc;
|
||||
}
|
||||
|
||||
rcAssertFailFunc* rcAssertFailGetCustom()
|
||||
{
|
||||
return sRecastAssertFailFunc;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -27,7 +27,9 @@
|
|||
#include "RecastAssert.h"
|
||||
|
||||
|
||||
static const int RC_MAX_LAYERS = RC_NOT_CONNECTED;
|
||||
// Must be 255 or smaller (not 256) because layer IDs are stored as
|
||||
// a byte where 255 is a special value.
|
||||
static const int RC_MAX_LAYERS = 63;
|
||||
static const int RC_MAX_NEIS = 16;
|
||||
|
||||
struct rcLayerRegion
|
||||
|
|
@ -42,25 +44,31 @@ struct rcLayerRegion
|
|||
};
|
||||
|
||||
|
||||
static void addUnique(unsigned char* a, unsigned char& an, unsigned char v)
|
||||
{
|
||||
const int n = (int)an;
|
||||
for (int i = 0; i < n; ++i)
|
||||
if (a[i] == v)
|
||||
return;
|
||||
a[an] = v;
|
||||
an++;
|
||||
}
|
||||
|
||||
static bool contains(const unsigned char* a, const unsigned char an, const unsigned char v)
|
||||
{
|
||||
const int n = (int)an;
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
if (a[i] == v)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool addUnique(unsigned char* a, unsigned char& an, int anMax, unsigned char v)
|
||||
{
|
||||
if (contains(a, an, v))
|
||||
return true;
|
||||
|
||||
if ((int)an >= anMax)
|
||||
return false;
|
||||
|
||||
a[an] = v;
|
||||
an++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline bool overlapRange(const unsigned short amin, const unsigned short amax,
|
||||
const unsigned short bmin, const unsigned short bmax)
|
||||
{
|
||||
|
|
@ -258,8 +266,13 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
|
|||
const int ay = y + rcGetDirOffsetY(dir);
|
||||
const int ai = (int)chf.cells[ax+ay*w].index + rcGetCon(s, dir);
|
||||
const unsigned char rai = srcReg[ai];
|
||||
if (rai != 0xff && rai != ri && regs[ri].nneis < RC_MAX_NEIS)
|
||||
addUnique(regs[ri].neis, regs[ri].nneis, rai);
|
||||
if (rai != 0xff && rai != ri)
|
||||
{
|
||||
// Don't check return value -- if we cannot add the neighbor
|
||||
// it will just cause a few more regions to be created, which
|
||||
// is fine.
|
||||
addUnique(regs[ri].neis, regs[ri].nneis, RC_MAX_NEIS, rai);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -274,8 +287,13 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
|
|||
{
|
||||
rcLayerRegion& ri = regs[lregs[i]];
|
||||
rcLayerRegion& rj = regs[lregs[j]];
|
||||
addUnique(ri.layers, ri.nlayers, lregs[j]);
|
||||
addUnique(rj.layers, rj.nlayers, lregs[i]);
|
||||
|
||||
if (!addUnique(ri.layers, ri.nlayers, RC_MAX_LAYERS, lregs[j]) ||
|
||||
!addUnique(rj.layers, rj.nlayers, RC_MAX_LAYERS, lregs[i]))
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: layer overflow (too many overlapping walkable platforms). Try increasing RC_MAX_LAYERS.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -338,7 +356,13 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
|
|||
regn.layerId = layerId;
|
||||
// Merge current layers to root.
|
||||
for (int k = 0; k < regn.nlayers; ++k)
|
||||
addUnique(root.layers, root.nlayers, regn.layers[k]);
|
||||
{
|
||||
if (!addUnique(root.layers, root.nlayers, RC_MAX_LAYERS, regn.layers[k]))
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: layer overflow (too many overlapping walkable platforms). Try increasing RC_MAX_LAYERS.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
root.ymin = rcMin(root.ymin, regn.ymin);
|
||||
root.ymax = rcMax(root.ymax, regn.ymax);
|
||||
}
|
||||
|
|
@ -416,7 +440,14 @@ bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf,
|
|||
rj.layerId = newId;
|
||||
// Add overlaid layers from 'rj' to 'ri'.
|
||||
for (int k = 0; k < rj.nlayers; ++k)
|
||||
addUnique(ri.layers, ri.nlayers, rj.layers[k]);
|
||||
{
|
||||
if (!addUnique(ri.layers, ri.nlayers, RC_MAX_LAYERS, rj.layers[k]))
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildHeightfieldLayers: layer overflow (too many overlapping walkable platforms). Try increasing RC_MAX_LAYERS.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Update height bounds.
|
||||
ri.ymin = rcMin(ri.ymin, rj.ymin);
|
||||
ri.ymax = rcMax(ri.ymax, rj.ymax);
|
||||
|
|
|
|||
|
|
@ -379,7 +379,7 @@ static int triangulate(int n, const int* verts, int* indices, int* tris)
|
|||
// We might get here because the contour has overlapping segments, like this:
|
||||
//
|
||||
// A o-o=====o---o B
|
||||
// / |C D| \
|
||||
// / |C D| \.
|
||||
// o o o o
|
||||
// : : : :
|
||||
// We'll try to recover by loosing up the inCone test a bit so that a diagonal
|
||||
|
|
|
|||
|
|
@ -647,11 +647,10 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
|
|||
int hull[MAX_VERTS];
|
||||
int nhull = 0;
|
||||
|
||||
nverts = 0;
|
||||
nverts = nin;
|
||||
|
||||
for (int i = 0; i < nin; ++i)
|
||||
rcVcopy(&verts[i*3], &in[i*3]);
|
||||
nverts = nin;
|
||||
|
||||
edges.resize(0);
|
||||
tris.resize(0);
|
||||
|
|
@ -777,7 +776,7 @@ static bool buildPolyDetail(rcContext* ctx, const float* in, const int nin,
|
|||
|
||||
// Tessellate the base mesh.
|
||||
// We're using the triangulateHull instead of delaunayHull as it tends to
|
||||
// create a bit better triangulation for long thing triangles when there
|
||||
// create a bit better triangulation for long thin triangles when there
|
||||
// are no internal points.
|
||||
triangulateHull(nverts, verts, nhull, hull, tris);
|
||||
|
||||
|
|
|
|||
|
|
@ -1575,12 +1575,6 @@ bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf,
|
|||
// Make sure border will not overflow.
|
||||
const int bw = rcMin(w, borderSize);
|
||||
const int bh = rcMin(h, borderSize);
|
||||
|
||||
if (regionId > 0xFFFB)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildRegions: Region ID overflow");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Paint regions
|
||||
paintRectRegion(0, bw, 0, h, regionId|RC_BORDER_REG, chf, srcReg); regionId++;
|
||||
|
|
@ -1690,7 +1684,7 @@ bool rcBuildLayerRegions(rcContext* ctx, rcCompactHeightfield& chf,
|
|||
rcScopedDelete<unsigned short> srcReg((unsigned short*)rcAlloc(sizeof(unsigned short)*chf.spanCount, RC_ALLOC_TEMP));
|
||||
if (!srcReg)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildRegionsMonotone: Out of memory 'src' (%d).", chf.spanCount);
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildLayerRegions: Out of memory 'src' (%d).", chf.spanCount);
|
||||
return false;
|
||||
}
|
||||
memset(srcReg,0,sizeof(unsigned short)*chf.spanCount);
|
||||
|
|
@ -1699,7 +1693,7 @@ bool rcBuildLayerRegions(rcContext* ctx, rcCompactHeightfield& chf,
|
|||
rcScopedDelete<rcSweepSpan> sweeps((rcSweepSpan*)rcAlloc(sizeof(rcSweepSpan)*nsweeps, RC_ALLOC_TEMP));
|
||||
if (!sweeps)
|
||||
{
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildRegionsMonotone: Out of memory 'sweeps' (%d).", nsweeps);
|
||||
ctx->log(RC_LOG_ERROR, "rcBuildLayerRegions: Out of memory 'sweeps' (%d).", nsweeps);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue