--
---
You received this message because you are subscribed to the Google Groups "recastnavigation" group.
To unsubscribe from this group and stop receiving emails from it, send an email to recastnavigati...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
#define TILEWID 128 //default
#define TILEHGT 128 //default
#define WORLD 0
#define _SCALE 3
#define _HGTSCALE 5
#define MAXVerts 30000 //temporary
#define MAXPolys 10000 //temporary
#define MAXREFS 30000 //temporary
sprintf(fpath,"unav.%d",WORLD); //Mikko, this is the file that I built in C# with CalculateTriangulation
sprintf(spath,"navmesh.%d",WORLD);
printf("Loading level from file %s...\n",fpath);
long lSize; int numVerts,numInds,numAreas,numPolys; int i;
uint *arData; float *vertData; uint *polys;
FILE *fp=fopen(fpath,"rb");
if(!fp) { printf("ERROR: Couldn't open navmesh file!\n"); return 1; }
// obtain file size:
fseek(fp,0,SEEK_END);
lSize = ftell(fp);
rewind(fp);
if(lSize<12) { fclose(fp); printf("ERROR: missing navmesh file header!\n"); return 1; }
fread(&numVerts,4,1,fp);
fread(&numInds,4,1,fp); numPolys=numInds/3;
fread(&numAreas,4,1,fp);
vertData=(float*)malloc(numVerts*12);
arData=(uint*)malloc(numAreas*4);
polys=(uint*)malloc(numInds*4);
fread(vertData,12,numVerts,fp); //load vertices
fread(polys,4,numInds,fp); //load indices
fread(arData,4,numAreas,fp); //load areas
fclose(fp);
float highX=0,highY=0,highZ=0;
for(int i=0;i<numVerts*3;i+=3) {
if(vertData[i]>highX) highX=vertData[i];
if(vertData[i+1]>highY) highY=vertData[i+1];
if(vertData[i+2]>highZ) highZ=vertData[i+2];
// vertData[i]*=_SCALE; vertData[i+1]*=_HGTSCALE; vertData[i+2]*=_SCALE;
}
highX=roundUp(highX,100); highY=roundUp(highY,100); highZ=roundUp(highZ,100);
printf("Detected world bounds (%f,%f,%f)\n",highX,highY,highZ);
float tileW=TILEWID,vxW;
if(WORLD==0) tileW=102.400004; //exact increment for my world 0 exported from Unity
vxW=tileW*_SCALE;
int xtiles=(int)ceil(highX/tileW),ytiles=(int)ceil(highZ/tileW);
dtNavMesh *mesh=new dtNavMesh();
dtNavMeshParams parms;
memset(&parms,0,sizeof(dtNavMeshParams));
parms.tileWidth=tileW; parms.tileHeight=tileW;
parms.maxTiles=xtiles*ytiles; parms.maxPolys=65535;
memset(parms.orig,0,12);
dtStatus initStat=mesh->init(&parms);
if(!initStat) {
printf("dtNavMesh Init failed!\n"); exit(1);
}
ushort *vertRef=(ushort*)malloc(numVerts*2);
for(int yy=0;yy<ytiles;yy++) {
for(int xx=0;xx<xtiles;xx++) {
int vptr=0,pptr=0;
float min[3],max[3];
min[0]=xx*tileW; min[1]=0; min[2]=yy*tileW;
max[0]=(xx+1)*tileW; max[1]=highY; max[2]=(yy+1)*tileW;
ushort tilePolys[MAXPolys];
float tileVerts[MAXVerts];
int cnt=0,rcnt=0;
printf("Tile %d %d\n",xx,yy);
for(int i=0;i<(numVerts*3);i+=3) {
if(vertData[i]>highX) highX=vertData[i];
if(vertData[i+1]>highY) highY=vertData[i+1];
if(vertData[i+2]>highZ) highZ=vertData[i+2];
// vertData[i]*=_SCALE; vertData[i+1]*=_HGTSCALE; vertData[i+2]*=_SCALE;
vertRef[cnt]=0xffff;
if(vertData[i]>=min[0]&&vertData[i+2]>=min[2]) {
if(vertData[i]<=max[0]&&vertData[i+2]<=max[2]) {
//// printf("%f %f %f\n",vertData[i],vertData[i+1],vertData[i+2]);
tileVerts[vptr++]=vertData[i];
tileVerts[vptr++]=vertData[i+1];
tileVerts[vptr++]=vertData[i+2];
vertRef[cnt]=(ushort)rcnt; //backwards reference from vert array
rcnt++;
}
}
cnt++;
}
int numTileVerts=vptr/3,numTilePolys=0;
for(int i=0;i<numInds;i++) {
int newInd = vertRef[polys[i]];
if(newInd!=0xffff) tilePolys[numTilePolys++]=newInd;
}
ushort *doubleInds=(ushort*)malloc(numInds*4);
for(int i=0;i<numTilePolys;i++) {
doubleInds[i*6]=tilePolys[i*3];
doubleInds[i*6+1]=tilePolys[i*3+1];
doubleInds[i*6+2]=tilePolys[i*3+2];
doubleInds[i*6+3]=tilePolys[i*3];
doubleInds[i*6+4]=tilePolys[i*3+1];
doubleInds[i*6+5]=tilePolys[i*3+2];
}
uchar *polyareas=(uchar*)malloc(numTilePolys);
for(int i=0;i<numTilePolys;i++) polyareas[i]=0; //******************* passable? or FLAGS
ushort *polyflags=(ushort*)malloc(numTilePolys*2);
for(int i=0;i<numTilePolys;i++) polyflags[i]=1; //******************* passable? or AREAS
ushort *iverts=(ushort*)malloc(numTileVerts*6);
for(i=0;i<numTileVerts;i++) {
iverts[i*3]=(ushort)(tileVerts[i*3]*_SCALE);
iverts[i*3+1]=(ushort)(tileVerts[i*3+1]*_HGTSCALE);
iverts[i*3+2]=(ushort)(tileVerts[i*3+2]*_SCALE);
}
dtNavMeshCreateParams params;
memset(¶ms, 0, sizeof(params));
params.verts = iverts;// (uint*)vertData;
params.vertCount = numTileVerts;
params.polys = doubleInds;// (uint*)(data+headerSize+verts*12);
params.polyCount = numTilePolys;
params.polyAreas = (uchar*)polyareas;
params.polyFlags = (ushort*)polyflags;
params.nvp = 3;
params.detailMeshes = 0;
params.offMeshConAreas = 0;
params.offMeshConCount = 0;
params.offMeshConDir = 0;
params.offMeshConFlags = 0;
params.offMeshConRad = 0;
params.offMeshConUserID = 0;
params.offMeshConVerts = 0;
params.walkableHeight = 1.8;//*_SCALE;
params.walkableRadius = 0.5;//*_SCALE;
params.walkableClimb = 1.2;//*_SCALE;
memcpy(params.bmin,(float*)min,12);
memcpy(params.bmax,(float*)max,12);
// params.bmin[0]=0; params.bmin[1]=0; params.bmin[2]=0;
// params.bmax[0]=10000; params.bmax[1]=600; params.bmax[2]=10000;
params.cs = 1/(float)_SCALE;
params.ch = 1/(float)_HGTSCALE;
params.buildBvTree = true;
unsigned char *data=NULL; int dlen=0;
if(!dtCreateNavMeshData(¶ms, &data, &dlen)) printf("dtCreateNavMeshdata failed! skipping...\n");
else {
if(!data) dlen=0;
if(dlen==0) {
printf("ERROR:There was no navmesh data for tile! aborting...\n");
exit(1);
}
//// printf("--> %d %c %c %c\n",dlen,data[0],data[1],data[2]);
if(!mesh->addTile(data, dlen, DT_TILE_FREE_DATA, yy*65536+xx, 0)) {
printf("addTile failed! aborting...\n"); exit(1);
}
}
free(doubleInds); free(iverts); free(polyareas); free(polyflags);
}
}
free(vertRef);
int pathCnt,sPathCnt;
dtPolyRef path[256],straightPathPolys[256];
float spath[256 * 3];
float startV[3]={4520.762f,154.73f,5782.241f},endV[3]={4519.002f,158.5f,5793.176f}; //let's get around that fence!! :)
dtQueryFilter *filter=new dtQueryFilter();
filter->setIncludeFlags(1);
dtNavMeshQuery *nav=new dtNavMeshQuery();
nav->init(mesh,2048);
printf("about to navigate...\n");
dtPolyRef m_startRef;
dtPolyRef m_endRef;
float m_polyPickExt[3];
m_polyPickExt[0] = 2;
m_polyPickExt[1] = 10;
m_polyPickExt[2] = 2;
nav->findNearestPoly(startV, m_polyPickExt, filter, &m_startRef, 0);
if (m_startRef == 0) { printf("ERROR finding polygon near start point\n"); return 1; }
printf("start ref %u\n",(uint)m_startRef);
nav->findNearestPoly(endV, m_polyPickExt, filter, &m_endRef, 0);
if (m_endRef == 0) { printf("ERROR finding polygon near end point\n"); return 1; }
printf("end ref %u\n",(uint)m_endRef);
// exit(1);
dtStatus stat=nav->findPath(m_startRef,m_endRef,startV,endV,filter,path,&pathCnt,256);
if(stat) printf("Nav returned path count: %d\n",pathCnt);
if(pathCnt>0) {
dtStatus sstat=nav->findStraightPath(startV,endV,path,pathCnt,spath,0,straightPathPolys,&sPathCnt,256);
printf("straight path returned: %d nodes!\n",sPathCnt);
for(int i=0;i<sPathCnt;i++) {
printf("Node: (%f,%f,%f)\n",spath[i*3],spath[i*3+1],spath[i*3+2]);
}
}
return 0;
const unsigned short* p = ¶ms->polys[i*2*nvp];
params.tileX=xx; params.tileY=yy; params.tileLayer=0;
...in my params.
struct rcPolyMesh
{
unsigned short* verts; ///< The mesh vertices. [Form: (x, y, z) * #nverts]
unsigned short* polys; ///< Polygon and neighbor data. [Length: #maxpolys * 2 * #nvp]
unsigned short* regs; ///< The region id assigned to each polygon. [Length: #maxpolys]
unsigned short* flags; ///< The user defined flags for each polygon. [Length: #maxpolys]
unsigned char* areas; ///< The area id assigned to each polygon. [Length: #maxpolys]
...
};
I don't know if this is my only problem. Hopefully it is. Nevertheless, I cannot figure out how to reconstruct this polygon and neighbor data without going thru the recast process. Since I already have my navmesh data from Unity and all I have is a list of verts, tris, and areas, how can I do this?
If this or any other obvious problems are visible in my code, please let me know :) Thank you!
--
Adding Tile #9507: 1, 97
TILE TRI #9507: 0 1 2 - neis: 32770 32770 1
TILE TRI #9507: 0 2 3 - neis: 0 32770 32770
Adding Tile #9508: 2, 97
TILE TRI #9508: 0 1 2 - neis: 32771 32768 1
TILE TRI #9508: 0 2 3 - neis: 0 32771 32770
Adding Tile #9509: 3, 97
TILE TRI #9509: 0 1 2 - neis: 32771 32770 1
TILE TRI #9509: 0 2 3 - neis: 0 32771 32768
Adding Tile #9510: 4, 97
TILE TRI #9510: 0 1 2 - neis: 32770 32769 1
TILE TRI #9510: 0 2 3 - neis: 0 32770 32770
Adding Tile #9511: 5, 97
TILE TRI #9511: 0 1 2 - neis: 65535 32768 1
TILE TRI #9511: 0 2 3 - neis: 0 65535 32769
Adding Tile #9512: 6, 97
TILE TRI #9512: 0 1 2 - neis: 32768 32768 1
TILE TRI #9512: 0 2 3 - neis: 0 32768 32768
Adding Tile #9513: 7, 97
TILE TRI #9513: 0 1 2 - neis: 65535 65535 1
TILE TRI #9513: 0 2 3 - neis: 0 65535 65535
TILE TRI #9513: 4 5 6 - neis: 65535 32770 65535
TILE TRI #9513: 7 8 9 - neis: 65535 65535 65535
...
But, I still can't pathfind. It can find some locations but most of locations cannot be found. And, 0,0,0 can find a close poly even though my beginning poly is quite far from 0,0,0 and my search area, or poly extents box is only {2,10,2}.
So I'm a bit confused. my CS is 1/3 and CH is 1/5. I've multiplied all verts by (3,5,3} and converted to ushorts.
Plus these three values have been multiplied by my CS value: (for ease of reference, I plugged in the actual value of 3 instead of my inverse CS var):
params.walkableHeight = 1.8 * 3;
params.walkableRadius = 0.5* 3;
params.walkableClimb = 1.2 * 3;
Does it sound like I did everything right? I must be SO CLOSE now. I even have it auto-detecting the tile borders from the data I get from Unity. So I should be able to load as many maps as I want from files exported from my custom script, and pathfind against them! It will be a remarkable goal! I literally need not give it any additional information. I'm so excited but frustrated at the same time! I look forward to your reply. Thanks in advance.