Navmesh load/save now uses builtin file abstraction.

This commit is contained in:
Daniel Buckmaster 2014-11-28 20:24:11 +11:00
parent f4c940f4fe
commit f42e12940c
5 changed files with 60 additions and 49 deletions

View file

@ -28,9 +28,9 @@
#endif #endif
#ifdef TORQUE_NAVIGATION_ENABLED #ifdef TORQUE_NAVIGATION_ENABLED
#include "walkabout/navPath.h" #include "navigation/navPath.h"
#include "walkabout/navMesh.h" #include "navigation/navMesh.h"
#include "walkabout/coverPoint.h" #include "navigation/coverPoint.h"
#endif // TORQUE_NAVIGATION_ENABLED #endif // TORQUE_NAVIGATION_ENABLED
class AIPlayer : public Player { class AIPlayer : public Player {

View file

@ -20,8 +20,6 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include <stdio.h>
#include "navMesh.h" #include "navMesh.h"
#include "navContext.h" #include "navContext.h"
#include <DetourDebugDraw.h> #include <DetourDebugDraw.h>
@ -41,6 +39,8 @@
#include "core/stream/bitStream.h" #include "core/stream/bitStream.h"
#include "math/mathIO.h" #include "math/mathIO.h"
#include "core/fileio.h"
extern bool gEditingMission; extern bool gEditingMission;
IMPLEMENT_CO_NETOBJECT_V1(NavMesh); IMPLEMENT_CO_NETOBJECT_V1(NavMesh);
@ -1496,22 +1496,31 @@ bool NavMesh::load()
if(!dStrlen(mFileName)) if(!dStrlen(mFileName))
return false; return false;
FILE* fp = fopen(mFileName, "rb"); File file;
if(!fp) if(file.open(mFileName, File::Read) != File::Ok)
{
file.close();
Con::errorf("Could not open file %s when loading navmesh %s.",
mFileName, getName() ? getName() : getIdString());
return false; return false;
}
// Read header. // Read header.
NavMeshSetHeader header; NavMeshSetHeader header;
fread(&header, sizeof(NavMeshSetHeader), 1, fp); file.read(sizeof(NavMeshSetHeader), (char*)&header);
if(header.magic != NAVMESHSET_MAGIC) if(header.magic != NAVMESHSET_MAGIC)
{ {
fclose(fp); file.close();
return 0; Con::errorf("Navmesh magic incorrect when loading navmesh %s; possible corrupt navmesh file %s.",
getName() ? getName() : getIdString(), mFileName);
return false;
} }
if(header.version != NAVMESHSET_VERSION) if(header.version != NAVMESHSET_VERSION)
{ {
fclose(fp); file.close();
return 0; Con::errorf("Navmesh version incorrect when loading navmesh %s; possible corrupt navmesh file %s.",
getName() ? getName() : getIdString(), mFileName);
return false;
} }
if(nm) if(nm)
@ -1519,14 +1528,18 @@ bool NavMesh::load()
nm = dtAllocNavMesh(); nm = dtAllocNavMesh();
if(!nm) if(!nm)
{ {
fclose(fp); file.close();
Con::errorf("Out of memory when loading navmesh %s.",
getName() ? getName() : getIdString());
return false; return false;
} }
dtStatus status = nm->init(&header.params); dtStatus status = nm->init(&header.params);
if(dtStatusFailed(status)) if(dtStatusFailed(status))
{ {
fclose(fp); file.close();
Con::errorf("Failed to initialise navmesh params when loading navmesh %s.",
getName() ? getName() : getIdString());
return false; return false;
} }
@ -1534,32 +1547,32 @@ bool NavMesh::load()
for(U32 i = 0; i < header.numTiles; ++i) for(U32 i = 0; i < header.numTiles; ++i)
{ {
NavMeshTileHeader tileHeader; NavMeshTileHeader tileHeader;
fread(&tileHeader, sizeof(tileHeader), 1, fp); file.read(sizeof(NavMeshTileHeader), (char*)&tileHeader);
if(!tileHeader.tileRef || !tileHeader.dataSize) if(!tileHeader.tileRef || !tileHeader.dataSize)
break; break;
unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM); unsigned char* data = (unsigned char*)dtAlloc(tileHeader.dataSize, DT_ALLOC_PERM);
if(!data) break; if(!data) break;
memset(data, 0, tileHeader.dataSize); memset(data, 0, tileHeader.dataSize);
fread(data, tileHeader.dataSize, 1, fp); file.read(tileHeader.dataSize, (char*)data);
nm->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0); nm->addTile(data, tileHeader.dataSize, DT_TILE_FREE_DATA, tileHeader.tileRef, 0);
} }
S32 s; S32 s;
fread(&s, sizeof(S32), 1, fp); file.read(sizeof(S32), (char*)&s);
setLinkCount(s); setLinkCount(s);
fread(const_cast<F32*>(mLinkVerts.address()), sizeof(F32), s * 6, fp); file.read(sizeof(F32) * s * 6, (char*)const_cast<F32*>(mLinkVerts.address()));
fread(const_cast<F32*>(mLinkRads.address()), sizeof(F32), s, fp); file.read(sizeof(F32) * s, (char*)const_cast<F32*>(mLinkRads.address()));
fread(const_cast<U8*>(mLinkDirs.address()), sizeof(U8), s, fp); file.read(sizeof(U8) * s, (char*)const_cast<U8*>(mLinkDirs.address()));
fread(const_cast<U8*>(mLinkAreas.address()), sizeof(U8), s, fp); file.read(sizeof(U8) * s, (char*)const_cast<U8*>(mLinkAreas.address()));
fread(const_cast<unsigned short*>(mLinkFlags.address()), sizeof(unsigned short), s, fp); file.read(sizeof(U16) * s, (char*)const_cast<U16*>(mLinkFlags.address()));
fread(const_cast<U32*>(mLinkIDs.address()), sizeof(U32), s, fp); file.read(sizeof(F32) * s, (char*)const_cast<U32*>(mLinkIDs.address()));
mLinksUnsynced.fill(false); mLinksUnsynced.fill(false);
mLinkSelectStates.fill(Unselected); mLinkSelectStates.fill(Unselected);
mDeleteLinks.fill(false); mDeleteLinks.fill(false);
fclose(fp); file.close();
updateTiles(); updateTiles();
@ -1581,18 +1594,17 @@ DefineEngineMethod(NavMesh, load, bool, (),,
bool NavMesh::save() bool NavMesh::save()
{ {
#ifdef WALKABOUT_DEMO
Con::errorf("Sorry, this demo code doesn't allow you to save NavMeshes to files.");
Con::executef("OnWalkaboutDemoSave");
return false;
#else
if(!dStrlen(mFileName) || !nm) if(!dStrlen(mFileName) || !nm)
return false; return false;
// Save our navmesh into a file to load from next time File file;
FILE* fp = fopen(mFileName, "wb"); if(file.open(mFileName, File::Write) != File::Ok)
if(!fp) {
file.close();
Con::errorf("Could not open file %s when saving navmesh %s.",
mFileName, getName() ? getName() : getIdString());
return false; return false;
}
// Store header. // Store header.
NavMeshSetHeader header; NavMeshSetHeader header;
@ -1606,7 +1618,7 @@ bool NavMesh::save()
header.numTiles++; header.numTiles++;
} }
memcpy(&header.params, nm->getParams(), sizeof(dtNavMeshParams)); memcpy(&header.params, nm->getParams(), sizeof(dtNavMeshParams));
fwrite(&header, sizeof(NavMeshSetHeader), 1, fp); file.write(sizeof(NavMeshSetHeader), (const char*)&header);
// Store tiles. // Store tiles.
for(U32 i = 0; i < nm->getMaxTiles(); ++i) for(U32 i = 0; i < nm->getMaxTiles(); ++i)
@ -1617,24 +1629,23 @@ bool NavMesh::save()
NavMeshTileHeader tileHeader; NavMeshTileHeader tileHeader;
tileHeader.tileRef = nm->getTileRef(tile); tileHeader.tileRef = nm->getTileRef(tile);
tileHeader.dataSize = tile->dataSize; tileHeader.dataSize = tile->dataSize;
fwrite(&tileHeader, sizeof(tileHeader), 1, fp);
fwrite(tile->data, tile->dataSize, 1, fp); file.write(sizeof(tileHeader), (const char*)&tileHeader);
file.write(tile->dataSize, (const char*)tile->data);
} }
S32 s = mLinkIDs.size(); S32 s = mLinkIDs.size();
fwrite(&s, sizeof(S32), 1, fp); file.write(sizeof(S32), (const char*)&s);
fwrite(mLinkVerts.address(), sizeof(F32), s * 6, fp); file.write(sizeof(F32) * s * 6, (const char*)mLinkVerts.address());
fwrite(mLinkRads.address(), sizeof(F32), s, fp); file.write(sizeof(F32) * s, (const char*)mLinkRads.address());
fwrite(mLinkDirs.address(), sizeof(U8), s, fp); file.write(sizeof(U8) * s, (const char*)mLinkDirs.address());
fwrite(mLinkAreas.address(), sizeof(U8), s, fp); file.write(sizeof(U8) * s, (const char*)mLinkAreas.address());
fwrite(mLinkFlags.address(), sizeof(unsigned short), s, fp); file.write(sizeof(U16) * s, (const char*)mLinkFlags.address());
fwrite(mLinkIDs.address(), sizeof(U32), s, fp); file.write(sizeof(U32) * s, (const char*)mLinkIDs.address());
fclose(fp); file.close();
return true; return true;
#endif
} }
DefineEngineMethod(NavMesh, save, void, (),, DefineEngineMethod(NavMesh, save, void, (),,

View file

@ -349,7 +349,7 @@ private:
Vector<F32> mLinkRads; ///< Radius of each link Vector<F32> mLinkRads; ///< Radius of each link
Vector<U8> mLinkDirs; ///< Direction (one-way or bidirectional) Vector<U8> mLinkDirs; ///< Direction (one-way or bidirectional)
Vector<U8> mLinkAreas; ///< Area ID Vector<U8> mLinkAreas; ///< Area ID
Vector<unsigned short> mLinkFlags; ///< Flags Vector<U16> mLinkFlags; ///< Flags
Vector<U32> mLinkIDs; ///< ID number of each link Vector<U32> mLinkIDs; ///< ID number of each link
Vector<U8> mLinkSelectStates; ///< Selection state of links Vector<U8> mLinkSelectStates; ///< Selection state of links
Vector<bool> mDeleteLinks; ///< Link will be deleted next build. Vector<bool> mDeleteLinks; ///< Link will be deleted next build.

View file

@ -154,7 +154,7 @@ private:
dtQueryFilter mFilter; dtQueryFilter mFilter;
S32 mCurIndex; S32 mCurIndex;
Vector<Point3F> mPoints; Vector<Point3F> mPoints;
Vector<unsigned short> mFlags; Vector<U16> mFlags;
Vector<Point3F> mVisitPoints; Vector<Point3F> mVisitPoints;
F32 mLength; F32 mLength;

View file

@ -78,7 +78,7 @@ struct LinkData {
bool ledge; bool ledge;
bool climb; bool climb;
bool teleport; bool teleport;
LinkData(unsigned short flags = 0) LinkData(U16 flags = 0)
{ {
walk = flags & WalkFlag; walk = flags & WalkFlag;
jump = flags & JumpFlag; jump = flags & JumpFlag;
@ -88,7 +88,7 @@ struct LinkData {
climb = flags & ClimbFlag; climb = flags & ClimbFlag;
teleport = flags & TeleportFlag; teleport = flags & TeleportFlag;
} }
unsigned short getFlags() const U16 getFlags() const
{ {
return return
(walk ? WalkFlag : 0) | (walk ? WalkFlag : 0) |