Fix blank assignments while advancing through buffer, using new dtGetThenAdvanceBufferPointer

This commit is contained in:
Ben Hymers 2016-02-16 14:12:16 +00:00
parent d7d58b98d9
commit 40a88dae73
3 changed files with 50 additions and 29 deletions

View File

@ -20,6 +20,7 @@
#define DETOURCOMMON_H #define DETOURCOMMON_H
#include "DetourMath.h" #include "DetourMath.h"
#include <stddef.h>
/** /**
@defgroup detour Detour @defgroup detour Detour
@ -482,6 +483,23 @@ inline void dtSwapEndian(float* v)
void dtRandomPointInConvexPoly(const float* pts, const int npts, float* areas, void dtRandomPointInConvexPoly(const float* pts, const int npts, float* areas,
const float s, const float t, float* out); const float s, const float t, float* out);
template<typename TypeToRetrieveAs>
TypeToRetrieveAs* dtGetThenAdvanceBufferPointer(const unsigned char*& buffer, const size_t distanceToAdvance)
{
TypeToRetrieveAs* returnPointer = reinterpret_cast<TypeToRetrieveAs*>(buffer);
buffer += distanceToAdvance;
return returnPointer;
}
template<typename TypeToRetrieveAs>
TypeToRetrieveAs* dtGetThenAdvanceBufferPointer(unsigned char*& buffer, const size_t distanceToAdvance)
{
TypeToRetrieveAs* returnPointer = reinterpret_cast<TypeToRetrieveAs*>(buffer);
buffer += distanceToAdvance;
return returnPointer;
}
/// @} /// @}
#endif // DETOURCOMMON_H #endif // DETOURCOMMON_H

View File

@ -917,14 +917,14 @@ dtStatus dtNavMesh::addTile(unsigned char* data, int dataSize, int flags,
const int offMeshLinksSize = dtAlign4(sizeof(dtOffMeshConnection)*header->offMeshConCount); const int offMeshLinksSize = dtAlign4(sizeof(dtOffMeshConnection)*header->offMeshConCount);
unsigned char* d = data + headerSize; unsigned char* d = data + headerSize;
tile->verts = (float*)d; d += vertsSize; tile->verts = dtGetThenAdvanceBufferPointer<float>(d, vertsSize);
tile->polys = (dtPoly*)d; d += polysSize; tile->polys = dtGetThenAdvanceBufferPointer<dtPoly>(d, polysSize);
tile->links = (dtLink*)d; d += linksSize; tile->links = dtGetThenAdvanceBufferPointer<dtLink>(d, linksSize);
tile->detailMeshes = (dtPolyDetail*)d; d += detailMeshesSize; tile->detailMeshes = dtGetThenAdvanceBufferPointer<dtPolyDetail>(d, detailMeshesSize);
tile->detailVerts = (float*)d; d += detailVertsSize; tile->detailVerts = dtGetThenAdvanceBufferPointer<float>(d, detailVertsSize);
tile->detailTris = (unsigned char*)d; d += detailTrisSize; tile->detailTris = dtGetThenAdvanceBufferPointer<unsigned char>(d, detailTrisSize);
tile->bvTree = (dtBVNode*)d; d += bvtreeSize; tile->bvTree = dtGetThenAdvanceBufferPointer<dtBVNode>(d, bvtreeSize);
tile->offMeshCons = (dtOffMeshConnection*)d; d += offMeshLinksSize; tile->offMeshCons = dtGetThenAdvanceBufferPointer<dtOffMeshConnection>(d, offMeshLinksSize);
// If there are no items in the bvtree, reset the tree pointer. // If there are no items in the bvtree, reset the tree pointer.
if (!bvtreeSize) if (!bvtreeSize)
@ -1322,8 +1322,8 @@ dtStatus dtNavMesh::storeTileState(const dtMeshTile* tile, unsigned char* data,
if (maxDataSize < sizeReq) if (maxDataSize < sizeReq)
return DT_FAILURE | DT_BUFFER_TOO_SMALL; return DT_FAILURE | DT_BUFFER_TOO_SMALL;
dtTileState* tileState = (dtTileState*)data; data += dtAlign4(sizeof(dtTileState)); dtTileState* tileState = dtGetThenAdvanceBufferPointer<dtTileState>(data, dtAlign4(sizeof(dtTileState)));
dtPolyState* polyStates = (dtPolyState*)data; data += dtAlign4(sizeof(dtPolyState) * tile->header->polyCount); dtPolyState* polyStates = dtGetThenAdvanceBufferPointer<dtPolyState>(data, dtAlign4(sizeof(dtPolyState) * tile->header->polyCount));
// Store tile state. // Store tile state.
tileState->magic = DT_NAVMESH_STATE_MAGIC; tileState->magic = DT_NAVMESH_STATE_MAGIC;
@ -1354,8 +1354,8 @@ dtStatus dtNavMesh::restoreTileState(dtMeshTile* tile, const unsigned char* data
if (maxDataSize < sizeReq) if (maxDataSize < sizeReq)
return DT_FAILURE | DT_INVALID_PARAM; return DT_FAILURE | DT_INVALID_PARAM;
const dtTileState* tileState = (const dtTileState*)data; data += dtAlign4(sizeof(dtTileState)); const dtTileState* tileState = dtGetThenAdvanceBufferPointer<const dtTileState>(data, dtAlign4(sizeof(dtTileState)));
const dtPolyState* polyStates = (const dtPolyState*)data; data += dtAlign4(sizeof(dtPolyState) * tile->header->polyCount); const dtPolyState* polyStates = dtGetThenAdvanceBufferPointer<const dtPolyState>(data, dtAlign4(sizeof(dtPolyState) * tile->header->polyCount));
// Check that the restore is possible. // Check that the restore is possible.
if (tileState->magic != DT_NAVMESH_STATE_MAGIC) if (tileState->magic != DT_NAVMESH_STATE_MAGIC)

View File

@ -421,15 +421,16 @@ bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData,
memset(data, 0, dataSize); memset(data, 0, dataSize);
unsigned char* d = data; unsigned char* d = data;
dtMeshHeader* header = (dtMeshHeader*)d; d += headerSize;
float* navVerts = (float*)d; d += vertsSize; dtMeshHeader* header = dtGetThenAdvanceBufferPointer<dtMeshHeader>(d, headerSize);
dtPoly* navPolys = (dtPoly*)d; d += polysSize; float* navVerts = dtGetThenAdvanceBufferPointer<float>(d, vertsSize);
d += linksSize; dtPoly* navPolys = dtGetThenAdvanceBufferPointer<dtPoly>(d, polysSize);
dtPolyDetail* navDMeshes = (dtPolyDetail*)d; d += detailMeshesSize; d += linksSize; // Ignore links; just leave enough space for them. They'll be created on load.
float* navDVerts = (float*)d; d += detailVertsSize; dtPolyDetail* navDMeshes = dtGetThenAdvanceBufferPointer<dtPolyDetail>(d, detailMeshesSize);
unsigned char* navDTris = (unsigned char*)d; d += detailTrisSize; float* navDVerts = dtGetThenAdvanceBufferPointer<float>(d, detailVertsSize);
dtBVNode* navBvtree = (dtBVNode*)d; d += bvTreeSize; unsigned char* navDTris = dtGetThenAdvanceBufferPointer<unsigned char>(d, detailTrisSize);
dtOffMeshConnection* offMeshCons = (dtOffMeshConnection*)d; d += offMeshConsSize; dtBVNode* navBvtree = dtGetThenAdvanceBufferPointer<dtBVNode>(d, bvTreeSize);
dtOffMeshConnection* offMeshCons = dtGetThenAdvanceBufferPointer<dtOffMeshConnection>(d, offMeshConsSize);
// Store header // Store header
@ -705,14 +706,16 @@ bool dtNavMeshDataSwapEndian(unsigned char* data, const int /*dataSize*/)
const int offMeshLinksSize = dtAlign4(sizeof(dtOffMeshConnection)*header->offMeshConCount); const int offMeshLinksSize = dtAlign4(sizeof(dtOffMeshConnection)*header->offMeshConCount);
unsigned char* d = data + headerSize; unsigned char* d = data + headerSize;
float* verts = (float*)d; d += vertsSize; float* verts = dtGetThenAdvanceBufferPointer<float>(d, vertsSize);
dtPoly* polys = (dtPoly*)d; d += polysSize; dtPoly* polys = dtGetThenAdvanceBufferPointer<dtPoly>(d, polysSize);
/*dtLink* links = (dtLink*)d;*/ d += linksSize; d += linksSize; // Ignore links; they technically should be endian-swapped but all their data is overwritten on load anyway.
dtPolyDetail* detailMeshes = (dtPolyDetail*)d; d += detailMeshesSize; //dtLink* links = dtGetThenAdvanceBufferPointer<dtLink>(d, linksSize);
float* detailVerts = (float*)d; d += detailVertsSize; dtPolyDetail* detailMeshes = dtGetThenAdvanceBufferPointer<dtPolyDetail>(d, detailMeshesSize);
/*unsigned char* detailTris = (unsigned char*)d;*/ d += detailTrisSize; float* detailVerts = dtGetThenAdvanceBufferPointer<float>(d, detailVertsSize);
dtBVNode* bvTree = (dtBVNode*)d; d += bvtreeSize; d += detailTrisSize; // Ignore detail tris; single bytes can't be endian-swapped.
dtOffMeshConnection* offMeshCons = (dtOffMeshConnection*)d; d += offMeshLinksSize; //unsigned char* detailTris = dtGetThenAdvanceBufferPointer<unsigned char>(d, detailTrisSize);
dtBVNode* bvTree = dtGetThenAdvanceBufferPointer<dtBVNode>(d, bvtreeSize);
dtOffMeshConnection* offMeshCons = dtGetThenAdvanceBufferPointer<dtOffMeshConnection>(d, offMeshLinksSize);
// Vertices // Vertices
for (int i = 0; i < header->vertCount*3; ++i) for (int i = 0; i < header->vertCount*3; ++i)