123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <float.h>
- #include "DetourNavMesh.h"
- #include "DetourCommon.h"
- #include "DetourMath.h"
- #include "DetourNavMeshBuilder.h"
- #include "DetourAlloc.h"
- #include "DetourAssert.h"
- static unsigned short MESH_NULL_IDX = 0xffff;
- struct BVItem
- {
- unsigned short bmin[3];
- unsigned short bmax[3];
- int i;
- };
- static int compareItemX(const void* va, const void* vb)
- {
- const BVItem* a = (const BVItem*)va;
- const BVItem* b = (const BVItem*)vb;
- if (a->bmin[0] < b->bmin[0])
- return -1;
- if (a->bmin[0] > b->bmin[0])
- return 1;
- return 0;
- }
- static int compareItemY(const void* va, const void* vb)
- {
- const BVItem* a = (const BVItem*)va;
- const BVItem* b = (const BVItem*)vb;
- if (a->bmin[1] < b->bmin[1])
- return -1;
- if (a->bmin[1] > b->bmin[1])
- return 1;
- return 0;
- }
- static int compareItemZ(const void* va, const void* vb)
- {
- const BVItem* a = (const BVItem*)va;
- const BVItem* b = (const BVItem*)vb;
- if (a->bmin[2] < b->bmin[2])
- return -1;
- if (a->bmin[2] > b->bmin[2])
- return 1;
- return 0;
- }
- static void calcExtends(BVItem* items, const int , const int imin, const int imax,
- unsigned short* bmin, unsigned short* bmax)
- {
- bmin[0] = items[imin].bmin[0];
- bmin[1] = items[imin].bmin[1];
- bmin[2] = items[imin].bmin[2];
-
- bmax[0] = items[imin].bmax[0];
- bmax[1] = items[imin].bmax[1];
- bmax[2] = items[imin].bmax[2];
-
- for (int i = imin+1; i < imax; ++i)
- {
- const BVItem& it = items[i];
- if (it.bmin[0] < bmin[0]) bmin[0] = it.bmin[0];
- if (it.bmin[1] < bmin[1]) bmin[1] = it.bmin[1];
- if (it.bmin[2] < bmin[2]) bmin[2] = it.bmin[2];
-
- if (it.bmax[0] > bmax[0]) bmax[0] = it.bmax[0];
- if (it.bmax[1] > bmax[1]) bmax[1] = it.bmax[1];
- if (it.bmax[2] > bmax[2]) bmax[2] = it.bmax[2];
- }
- }
- inline int longestAxis(unsigned short x, unsigned short y, unsigned short z)
- {
- int axis = 0;
- unsigned short maxVal = x;
- if (y > maxVal)
- {
- axis = 1;
- maxVal = y;
- }
- if (z > maxVal)
- {
- axis = 2;
- maxVal = z;
- }
- return axis;
- }
- static void subdivide(BVItem* items, int nitems, int imin, int imax, int& curNode, dtBVNode* nodes)
- {
- int inum = imax - imin;
- int icur = curNode;
-
- dtBVNode& node = nodes[curNode++];
-
- if (inum == 1)
- {
-
- node.bmin[0] = items[imin].bmin[0];
- node.bmin[1] = items[imin].bmin[1];
- node.bmin[2] = items[imin].bmin[2];
-
- node.bmax[0] = items[imin].bmax[0];
- node.bmax[1] = items[imin].bmax[1];
- node.bmax[2] = items[imin].bmax[2];
-
- node.i = items[imin].i;
- }
- else
- {
-
- calcExtends(items, nitems, imin, imax, node.bmin, node.bmax);
-
- int axis = longestAxis(node.bmax[0] - node.bmin[0],
- node.bmax[1] - node.bmin[1],
- node.bmax[2] - node.bmin[2]);
-
- if (axis == 0)
- {
-
- qsort(items+imin, inum, sizeof(BVItem), compareItemX);
- }
- else if (axis == 1)
- {
-
- qsort(items+imin, inum, sizeof(BVItem), compareItemY);
- }
- else
- {
-
- qsort(items+imin, inum, sizeof(BVItem), compareItemZ);
- }
-
- int isplit = imin+inum/2;
-
-
- subdivide(items, nitems, imin, isplit, curNode, nodes);
-
- subdivide(items, nitems, isplit, imax, curNode, nodes);
-
- int iescape = curNode - icur;
-
- node.i = -iescape;
- }
- }
- static int createBVTree(const unsigned short* verts, const int ,
- const unsigned short* polys, const int npolys, const int nvp,
- const float cs, const float ch,
- const int , dtBVNode* nodes)
- {
-
- BVItem* items = (BVItem*)dtAlloc(sizeof(BVItem)*npolys, DT_ALLOC_TEMP);
- for (int i = 0; i < npolys; i++)
- {
- BVItem& it = items[i];
- it.i = i;
-
- const unsigned short* p = &polys[i*nvp*2];
- it.bmin[0] = it.bmax[0] = verts[p[0]*3+0];
- it.bmin[1] = it.bmax[1] = verts[p[0]*3+1];
- it.bmin[2] = it.bmax[2] = verts[p[0]*3+2];
-
- for (int j = 1; j < nvp; ++j)
- {
- if (p[j] == MESH_NULL_IDX) break;
- unsigned short x = verts[p[j]*3+0];
- unsigned short y = verts[p[j]*3+1];
- unsigned short z = verts[p[j]*3+2];
-
- if (x < it.bmin[0]) it.bmin[0] = x;
- if (y < it.bmin[1]) it.bmin[1] = y;
- if (z < it.bmin[2]) it.bmin[2] = z;
-
- if (x > it.bmax[0]) it.bmax[0] = x;
- if (y > it.bmax[1]) it.bmax[1] = y;
- if (z > it.bmax[2]) it.bmax[2] = z;
- }
-
- it.bmin[1] = (unsigned short)dtMathFloorf((float)it.bmin[1]*ch/cs);
- it.bmax[1] = (unsigned short)dtMathCeilf((float)it.bmax[1]*ch/cs);
- }
-
- int curNode = 0;
- subdivide(items, npolys, 0, npolys, curNode, nodes);
-
- dtFree(items);
-
- return curNode;
- }
- static unsigned char classifyOffMeshPoint(const float* pt, const float* bmin, const float* bmax)
- {
- static const unsigned char XP = 1<<0;
- static const unsigned char ZP = 1<<1;
- static const unsigned char XM = 1<<2;
- static const unsigned char ZM = 1<<3;
- unsigned char outcode = 0;
- outcode |= (pt[0] >= bmax[0]) ? XP : 0;
- outcode |= (pt[2] >= bmax[2]) ? ZP : 0;
- outcode |= (pt[0] < bmin[0]) ? XM : 0;
- outcode |= (pt[2] < bmin[2]) ? ZM : 0;
- switch (outcode)
- {
- case XP: return 0;
- case XP|ZP: return 1;
- case ZP: return 2;
- case XM|ZP: return 3;
- case XM: return 4;
- case XM|ZM: return 5;
- case ZM: return 6;
- case XP|ZM: return 7;
- };
- return 0xff;
- }
- bool dtCreateNavMeshData(dtNavMeshCreateParams* params, unsigned char** outData, int* outDataSize)
- {
- if (params->nvp > DT_VERTS_PER_POLYGON)
- return false;
- if (params->vertCount >= 0xffff)
- return false;
- if (!params->vertCount || !params->verts)
- return false;
- if (!params->polyCount || !params->polys)
- return false;
- const int nvp = params->nvp;
-
-
-
- unsigned char* offMeshConClass = 0;
- int storedOffMeshConCount = 0;
- int offMeshConLinkCount = 0;
-
- if (params->offMeshConCount > 0)
- {
- offMeshConClass = (unsigned char*)dtAlloc(sizeof(unsigned char)*params->offMeshConCount*2, DT_ALLOC_TEMP);
- if (!offMeshConClass)
- return false;
-
- float hmin = FLT_MAX;
- float hmax = -FLT_MAX;
-
- if (params->detailVerts && params->detailVertsCount)
- {
- for (int i = 0; i < params->detailVertsCount; ++i)
- {
- const float h = params->detailVerts[i*3+1];
- hmin = dtMin(hmin,h);
- hmax = dtMax(hmax,h);
- }
- }
- else
- {
- for (int i = 0; i < params->vertCount; ++i)
- {
- const unsigned short* iv = ¶ms->verts[i*3];
- const float h = params->bmin[1] + iv[1] * params->ch;
- hmin = dtMin(hmin,h);
- hmax = dtMax(hmax,h);
- }
- }
- hmin -= params->walkableClimb;
- hmax += params->walkableClimb;
- float bmin[3], bmax[3];
- dtVcopy(bmin, params->bmin);
- dtVcopy(bmax, params->bmax);
- bmin[1] = hmin;
- bmax[1] = hmax;
- for (int i = 0; i < params->offMeshConCount; ++i)
- {
- const float* p0 = ¶ms->offMeshConVerts[(i*2+0)*3];
- const float* p1 = ¶ms->offMeshConVerts[(i*2+1)*3];
- offMeshConClass[i*2+0] = classifyOffMeshPoint(p0, bmin, bmax);
- offMeshConClass[i*2+1] = classifyOffMeshPoint(p1, bmin, bmax);
-
- if (offMeshConClass[i*2+0] == 0xff)
- {
- if (p0[1] < bmin[1] || p0[1] > bmax[1])
- offMeshConClass[i*2+0] = 0;
- }
-
- if (offMeshConClass[i*2+0] == 0xff)
- offMeshConLinkCount++;
- if (offMeshConClass[i*2+1] == 0xff)
- offMeshConLinkCount++;
- if (offMeshConClass[i*2+0] == 0xff)
- storedOffMeshConCount++;
- }
- }
-
-
- const int totPolyCount = params->polyCount + storedOffMeshConCount;
- const int totVertCount = params->vertCount + storedOffMeshConCount*2;
-
-
- int edgeCount = 0;
- int portalCount = 0;
- for (int i = 0; i < params->polyCount; ++i)
- {
- const unsigned short* p = ¶ms->polys[i*2*nvp];
- for (int j = 0; j < nvp; ++j)
- {
- if (p[j] == MESH_NULL_IDX) break;
- edgeCount++;
-
- if (p[nvp+j] & 0x8000)
- {
- unsigned short dir = p[nvp+j] & 0xf;
- if (dir != 0xf)
- portalCount++;
- }
- }
- }
- const int maxLinkCount = edgeCount + portalCount*2 + offMeshConLinkCount*2;
-
-
- int uniqueDetailVertCount = 0;
- int detailTriCount = 0;
- if (params->detailMeshes)
- {
-
- detailTriCount = params->detailTriCount;
- for (int i = 0; i < params->polyCount; ++i)
- {
- const unsigned short* p = ¶ms->polys[i*nvp*2];
- int ndv = params->detailMeshes[i*4+1];
- int nv = 0;
- for (int j = 0; j < nvp; ++j)
- {
- if (p[j] == MESH_NULL_IDX) break;
- nv++;
- }
- ndv -= nv;
- uniqueDetailVertCount += ndv;
- }
- }
- else
- {
-
- uniqueDetailVertCount = 0;
- detailTriCount = 0;
- for (int i = 0; i < params->polyCount; ++i)
- {
- const unsigned short* p = ¶ms->polys[i*nvp*2];
- int nv = 0;
- for (int j = 0; j < nvp; ++j)
- {
- if (p[j] == MESH_NULL_IDX) break;
- nv++;
- }
- detailTriCount += nv-2;
- }
- }
-
-
- const int headerSize = dtAlign4(sizeof(dtMeshHeader));
- const int vertsSize = dtAlign4(sizeof(float)*3*totVertCount);
- const int polysSize = dtAlign4(sizeof(dtPoly)*totPolyCount);
- const int linksSize = dtAlign4(sizeof(dtLink)*maxLinkCount);
- const int detailMeshesSize = dtAlign4(sizeof(dtPolyDetail)*params->polyCount);
- const int detailVertsSize = dtAlign4(sizeof(float)*3*uniqueDetailVertCount);
- const int detailTrisSize = dtAlign4(sizeof(unsigned char)*4*detailTriCount);
- const int bvTreeSize = params->buildBvTree ? dtAlign4(sizeof(dtBVNode)*params->polyCount*2) : 0;
- const int offMeshConsSize = dtAlign4(sizeof(dtOffMeshConnection)*storedOffMeshConCount);
-
- const int dataSize = headerSize + vertsSize + polysSize + linksSize +
- detailMeshesSize + detailVertsSize + detailTrisSize +
- bvTreeSize + offMeshConsSize;
-
- unsigned char* data = (unsigned char*)dtAlloc(sizeof(unsigned char)*dataSize, DT_ALLOC_PERM);
- if (!data)
- {
- dtFree(offMeshConClass);
- return false;
- }
- memset(data, 0, dataSize);
-
- unsigned char* d = data;
- dtMeshHeader* header = (dtMeshHeader*)d; d += headerSize;
- float* navVerts = (float*)d; d += vertsSize;
- dtPoly* navPolys = (dtPoly*)d; d += polysSize;
- d += linksSize;
- dtPolyDetail* navDMeshes = (dtPolyDetail*)d; d += detailMeshesSize;
- float* navDVerts = (float*)d; d += detailVertsSize;
- unsigned char* navDTris = (unsigned char*)d; d += detailTrisSize;
- dtBVNode* navBvtree = (dtBVNode*)d; d += bvTreeSize;
- dtOffMeshConnection* offMeshCons = (dtOffMeshConnection*)d; d += offMeshConsSize;
-
-
-
- header->magic = DT_NAVMESH_MAGIC;
- header->version = DT_NAVMESH_VERSION;
- header->x = params->tileX;
- header->y = params->tileY;
- header->layer = params->tileLayer;
- header->userId = params->userId;
- header->polyCount = totPolyCount;
- header->vertCount = totVertCount;
- header->maxLinkCount = maxLinkCount;
- dtVcopy(header->bmin, params->bmin);
- dtVcopy(header->bmax, params->bmax);
- header->detailMeshCount = params->polyCount;
- header->detailVertCount = uniqueDetailVertCount;
- header->detailTriCount = detailTriCount;
- header->bvQuantFactor = 1.0f / params->cs;
- header->offMeshBase = params->polyCount;
- header->walkableHeight = params->walkableHeight;
- header->walkableRadius = params->walkableRadius;
- header->walkableClimb = params->walkableClimb;
- header->offMeshConCount = storedOffMeshConCount;
- header->bvNodeCount = params->buildBvTree ? params->polyCount*2 : 0;
-
- const int offMeshVertsBase = params->vertCount;
- const int offMeshPolyBase = params->polyCount;
-
-
-
- for (int i = 0; i < params->vertCount; ++i)
- {
- const unsigned short* iv = ¶ms->verts[i*3];
- float* v = &navVerts[i*3];
- v[0] = params->bmin[0] + iv[0] * params->cs;
- v[1] = params->bmin[1] + iv[1] * params->ch;
- v[2] = params->bmin[2] + iv[2] * params->cs;
- }
-
- int n = 0;
- for (int i = 0; i < params->offMeshConCount; ++i)
- {
-
- if (offMeshConClass[i*2+0] == 0xff)
- {
- const float* linkv = ¶ms->offMeshConVerts[i*2*3];
- float* v = &navVerts[(offMeshVertsBase + n*2)*3];
- dtVcopy(&v[0], &linkv[0]);
- dtVcopy(&v[3], &linkv[3]);
- n++;
- }
- }
-
-
-
- const unsigned short* src = params->polys;
- for (int i = 0; i < params->polyCount; ++i)
- {
- dtPoly* p = &navPolys[i];
- p->vertCount = 0;
- p->flags = params->polyFlags[i];
- p->setArea(params->polyAreas[i]);
- p->setType(DT_POLYTYPE_GROUND);
- for (int j = 0; j < nvp; ++j)
- {
- if (src[j] == MESH_NULL_IDX) break;
- p->verts[j] = src[j];
- if (src[nvp+j] & 0x8000)
- {
-
- unsigned short dir = src[nvp+j] & 0xf;
- if (dir == 0xf)
- p->neis[j] = 0;
- else if (dir == 0)
- p->neis[j] = DT_EXT_LINK | 4;
- else if (dir == 1)
- p->neis[j] = DT_EXT_LINK | 2;
- else if (dir == 2)
- p->neis[j] = DT_EXT_LINK | 0;
- else if (dir == 3)
- p->neis[j] = DT_EXT_LINK | 6;
- }
- else
- {
-
- p->neis[j] = src[nvp+j]+1;
- }
-
- p->vertCount++;
- }
- src += nvp*2;
- }
-
- n = 0;
- for (int i = 0; i < params->offMeshConCount; ++i)
- {
-
- if (offMeshConClass[i*2+0] == 0xff)
- {
- dtPoly* p = &navPolys[offMeshPolyBase+n];
- p->vertCount = 2;
- p->verts[0] = (unsigned short)(offMeshVertsBase + n*2+0);
- p->verts[1] = (unsigned short)(offMeshVertsBase + n*2+1);
- p->flags = params->offMeshConFlags[i];
- p->setArea(params->offMeshConAreas[i]);
- p->setType(DT_POLYTYPE_OFFMESH_CONNECTION);
- n++;
- }
- }
-
-
-
- if (params->detailMeshes)
- {
- unsigned short vbase = 0;
- for (int i = 0; i < params->polyCount; ++i)
- {
- dtPolyDetail& dtl = navDMeshes[i];
- const int vb = (int)params->detailMeshes[i*4+0];
- const int ndv = (int)params->detailMeshes[i*4+1];
- const int nv = navPolys[i].vertCount;
- dtl.vertBase = (unsigned int)vbase;
- dtl.vertCount = (unsigned char)(ndv-nv);
- dtl.triBase = (unsigned int)params->detailMeshes[i*4+2];
- dtl.triCount = (unsigned char)params->detailMeshes[i*4+3];
-
- if (ndv-nv)
- {
- memcpy(&navDVerts[vbase*3], ¶ms->detailVerts[(vb+nv)*3], sizeof(float)*3*(ndv-nv));
- vbase += (unsigned short)(ndv-nv);
- }
- }
-
- memcpy(navDTris, params->detailTris, sizeof(unsigned char)*4*params->detailTriCount);
- }
- else
- {
-
- int tbase = 0;
- for (int i = 0; i < params->polyCount; ++i)
- {
- dtPolyDetail& dtl = navDMeshes[i];
- const int nv = navPolys[i].vertCount;
- dtl.vertBase = 0;
- dtl.vertCount = 0;
- dtl.triBase = (unsigned int)tbase;
- dtl.triCount = (unsigned char)(nv-2);
-
- for (int j = 2; j < nv; ++j)
- {
- unsigned char* t = &navDTris[tbase*4];
- t[0] = 0;
- t[1] = (unsigned char)(j-1);
- t[2] = (unsigned char)j;
-
- t[3] = (1<<2);
- if (j == 2) t[3] |= (1<<0);
- if (j == nv-1) t[3] |= (1<<4);
- tbase++;
- }
- }
- }
-
-
- if (params->buildBvTree)
- {
- createBVTree(params->verts, params->vertCount, params->polys, params->polyCount,
- nvp, params->cs, params->ch, params->polyCount*2, navBvtree);
- }
-
-
- n = 0;
- for (int i = 0; i < params->offMeshConCount; ++i)
- {
-
- if (offMeshConClass[i*2+0] == 0xff)
- {
- dtOffMeshConnection* con = &offMeshCons[n];
- con->poly = (unsigned short)(offMeshPolyBase + n);
-
- const float* endPts = ¶ms->offMeshConVerts[i*2*3];
- dtVcopy(&con->pos[0], &endPts[0]);
- dtVcopy(&con->pos[3], &endPts[3]);
- con->rad = params->offMeshConRad[i];
- con->flags = params->offMeshConDir[i] ? DT_OFFMESH_CON_BIDIR : 0;
- con->side = offMeshConClass[i*2+1];
- if (params->offMeshConUserID)
- con->userId = params->offMeshConUserID[i];
- n++;
- }
- }
-
- dtFree(offMeshConClass);
-
- *outData = data;
- *outDataSize = dataSize;
-
- return true;
- }
- bool dtNavMeshHeaderSwapEndian(unsigned char* data, const int )
- {
- dtMeshHeader* header = (dtMeshHeader*)data;
-
- int swappedMagic = DT_NAVMESH_MAGIC;
- int swappedVersion = DT_NAVMESH_VERSION;
- dtSwapEndian(&swappedMagic);
- dtSwapEndian(&swappedVersion);
-
- if ((header->magic != DT_NAVMESH_MAGIC || header->version != DT_NAVMESH_VERSION) &&
- (header->magic != swappedMagic || header->version != swappedVersion))
- {
- return false;
- }
-
- dtSwapEndian(&header->magic);
- dtSwapEndian(&header->version);
- dtSwapEndian(&header->x);
- dtSwapEndian(&header->y);
- dtSwapEndian(&header->layer);
- dtSwapEndian(&header->userId);
- dtSwapEndian(&header->polyCount);
- dtSwapEndian(&header->vertCount);
- dtSwapEndian(&header->maxLinkCount);
- dtSwapEndian(&header->detailMeshCount);
- dtSwapEndian(&header->detailVertCount);
- dtSwapEndian(&header->detailTriCount);
- dtSwapEndian(&header->bvNodeCount);
- dtSwapEndian(&header->offMeshConCount);
- dtSwapEndian(&header->offMeshBase);
- dtSwapEndian(&header->walkableHeight);
- dtSwapEndian(&header->walkableRadius);
- dtSwapEndian(&header->walkableClimb);
- 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->bvQuantFactor);
-
- return true;
- }
- bool dtNavMeshDataSwapEndian(unsigned char* data, const int )
- {
-
- dtMeshHeader* header = (dtMeshHeader*)data;
- if (header->magic != DT_NAVMESH_MAGIC)
- return false;
- if (header->version != DT_NAVMESH_VERSION)
- return false;
-
-
- const int headerSize = dtAlign4(sizeof(dtMeshHeader));
- const int vertsSize = dtAlign4(sizeof(float)*3*header->vertCount);
- const int polysSize = dtAlign4(sizeof(dtPoly)*header->polyCount);
- const int linksSize = dtAlign4(sizeof(dtLink)*(header->maxLinkCount));
- const int detailMeshesSize = dtAlign4(sizeof(dtPolyDetail)*header->detailMeshCount);
- const int detailVertsSize = dtAlign4(sizeof(float)*3*header->detailVertCount);
- const int detailTrisSize = dtAlign4(sizeof(unsigned char)*4*header->detailTriCount);
- const int bvtreeSize = dtAlign4(sizeof(dtBVNode)*header->bvNodeCount);
- const int offMeshLinksSize = dtAlign4(sizeof(dtOffMeshConnection)*header->offMeshConCount);
-
- unsigned char* d = data + headerSize;
- float* verts = (float*)d; d += vertsSize;
- dtPoly* polys = (dtPoly*)d; d += polysSize;
- d += linksSize;
- dtPolyDetail* detailMeshes = (dtPolyDetail*)d; d += detailMeshesSize;
- float* detailVerts = (float*)d; d += detailVertsSize;
- d += detailTrisSize;
- dtBVNode* bvTree = (dtBVNode*)d; d += bvtreeSize;
- dtOffMeshConnection* offMeshCons = (dtOffMeshConnection*)d; d += offMeshLinksSize;
-
-
- for (int i = 0; i < header->vertCount*3; ++i)
- {
- dtSwapEndian(&verts[i]);
- }
-
- for (int i = 0; i < header->polyCount; ++i)
- {
- dtPoly* p = &polys[i];
-
- for (int j = 0; j < DT_VERTS_PER_POLYGON; ++j)
- {
- dtSwapEndian(&p->verts[j]);
- dtSwapEndian(&p->neis[j]);
- }
- dtSwapEndian(&p->flags);
- }
-
-
- for (int i = 0; i < header->detailMeshCount; ++i)
- {
- dtPolyDetail* pd = &detailMeshes[i];
- dtSwapEndian(&pd->vertBase);
- dtSwapEndian(&pd->triBase);
- }
-
-
- for (int i = 0; i < header->detailVertCount*3; ++i)
- {
- dtSwapEndian(&detailVerts[i]);
- }
-
- for (int i = 0; i < header->bvNodeCount; ++i)
- {
- dtBVNode* node = &bvTree[i];
- for (int j = 0; j < 3; ++j)
- {
- dtSwapEndian(&node->bmin[j]);
- dtSwapEndian(&node->bmax[j]);
- }
- dtSwapEndian(&node->i);
- }
-
- for (int i = 0; i < header->offMeshConCount; ++i)
- {
- dtOffMeshConnection* con = &offMeshCons[i];
- for (int j = 0; j < 6; ++j)
- dtSwapEndian(&con->pos[j]);
- dtSwapEndian(&con->rad);
- dtSwapEndian(&con->poly);
- }
-
- return true;
- }
|