First pass of load files through an interface (to allow loading from memory, zip file etc). So instead of posix fopen/fread, using CommonFileIOInterface.
A fileIO plugin can override custom file IO operations. As a small test, load files from a zipfile in memory. Default fileIO implementation is in examples/Utils/b3BulletDefaultFileIO.h Affects URDF, SDF, MJCF, Wavefront OBJ, STL, DAE, images.
This commit is contained in:
175
examples/Utils/b3BulletDefaultFileIO.h
Normal file
175
examples/Utils/b3BulletDefaultFileIO.h
Normal file
@@ -0,0 +1,175 @@
|
||||
|
||||
#ifndef B3_BULLET_DEFAULT_FILE_IO_H
|
||||
#define B3_BULLET_DEFAULT_FILE_IO_H
|
||||
|
||||
#include "../CommonInterfaces/CommonFileIOInterface.h"
|
||||
#include "b3ResourcePath.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#define B3_FILEIO_MAX_FILES 1024
|
||||
|
||||
struct b3BulletDefaultFileIO : public CommonFileIOInterface
|
||||
{
|
||||
static bool FileIOPluginFindFile(void* userPtr, const char* orgFileName, char* relativeFileName, int maxRelativeFileNameMaxLen)
|
||||
{
|
||||
b3BulletDefaultFileIO* fileIo = (b3BulletDefaultFileIO*) userPtr;
|
||||
return fileIo->findFile(orgFileName, relativeFileName, maxRelativeFileNameMaxLen);
|
||||
}
|
||||
|
||||
FILE* m_fileHandles[B3_FILEIO_MAX_FILES];
|
||||
int m_numFileHandles;
|
||||
|
||||
b3BulletDefaultFileIO()
|
||||
:m_numFileHandles(0)
|
||||
{
|
||||
for (int i=0;i<B3_FILEIO_MAX_FILES;i++)
|
||||
{
|
||||
m_fileHandles[i]=0;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~b3BulletDefaultFileIO()
|
||||
{
|
||||
}
|
||||
virtual int fileOpen(const char* fileName, const char* mode)
|
||||
{
|
||||
//search a free slot
|
||||
int slot = -1;
|
||||
for (int i=0;i<B3_FILEIO_MAX_FILES;i++)
|
||||
{
|
||||
if (m_fileHandles[i]==0)
|
||||
{
|
||||
slot=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (slot>=0)
|
||||
{
|
||||
FILE*f = ::fopen(fileName, mode);
|
||||
if (f)
|
||||
{
|
||||
m_fileHandles[slot]=f;
|
||||
} else
|
||||
{
|
||||
slot=-1;
|
||||
}
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
virtual int fileRead(int fileHandle, char* destBuffer, int numBytes)
|
||||
{
|
||||
if (fileHandle>=0 && fileHandle < B3_FILEIO_MAX_FILES)
|
||||
{
|
||||
FILE* f = m_fileHandles[fileHandle];
|
||||
if (f)
|
||||
{
|
||||
int readBytes = ::fread(destBuffer, 1, numBytes, f);
|
||||
return readBytes;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
||||
}
|
||||
virtual int fileWrite(int fileHandle,const char* sourceBuffer, int numBytes)
|
||||
{
|
||||
if (fileHandle>=0 && fileHandle < B3_FILEIO_MAX_FILES)
|
||||
{
|
||||
FILE* f = m_fileHandles[fileHandle];
|
||||
if (f)
|
||||
{
|
||||
return ::fwrite(sourceBuffer, 1, numBytes,m_fileHandles[fileHandle]);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
virtual void fileClose(int fileHandle)
|
||||
{
|
||||
if (fileHandle>=0 && fileHandle < B3_FILEIO_MAX_FILES)
|
||||
{
|
||||
FILE* f = m_fileHandles[fileHandle];
|
||||
if (f)
|
||||
{
|
||||
::fclose(f);
|
||||
m_fileHandles[fileHandle]=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool findResourcePath(const char* fileName, char* relativeFileName, int relativeFileNameSizeInBytes)
|
||||
{
|
||||
return b3ResourcePath::findResourcePath(fileName, relativeFileName, relativeFileNameSizeInBytes, b3BulletDefaultFileIO::FileIOPluginFindFile, this);
|
||||
}
|
||||
|
||||
|
||||
virtual bool findFile(const char* orgFileName, char* relativeFileName, int maxRelativeFileNameMaxLen)
|
||||
{
|
||||
FILE* f = 0;
|
||||
f = fopen(orgFileName, "rb");
|
||||
if (f)
|
||||
{
|
||||
//printf("original file found: [%s]\n", orgFileName);
|
||||
sprintf(relativeFileName, "%s", orgFileName);
|
||||
fclose(f);
|
||||
return true;
|
||||
}
|
||||
|
||||
//printf("Trying various directories, relative to current working directory\n");
|
||||
const char* prefix[] = {"./", "./data/", "../data/", "../../data/", "../../../data/", "../../../../data/"};
|
||||
int numPrefixes = sizeof(prefix) / sizeof(const char*);
|
||||
|
||||
f = 0;
|
||||
bool fileFound = false;
|
||||
|
||||
for (int i = 0; !f && i < numPrefixes; i++)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
sprintf_s(relativeFileName, maxRelativeFileNameMaxLen, "%s%s", prefix[i], orgFileName);
|
||||
#else
|
||||
sprintf(relativeFileName, "%s%s", prefix[i], orgFileName);
|
||||
#endif
|
||||
f = fopen(relativeFileName, "rb");
|
||||
if (f)
|
||||
{
|
||||
fileFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
return fileFound;
|
||||
}
|
||||
virtual char* readLine(int fileHandle, char* destBuffer, int numBytes)
|
||||
{
|
||||
if (fileHandle>=0 && fileHandle < B3_FILEIO_MAX_FILES)
|
||||
{
|
||||
FILE* f = m_fileHandles[fileHandle];
|
||||
if (f)
|
||||
{
|
||||
return ::fgets(destBuffer, numBytes, m_fileHandles[fileHandle]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
virtual int getFileSize(int fileHandle)
|
||||
{
|
||||
int size = 0;
|
||||
if (fileHandle>=0 && fileHandle < B3_FILEIO_MAX_FILES)
|
||||
{
|
||||
FILE* f = m_fileHandles[fileHandle];
|
||||
if (f)
|
||||
{
|
||||
|
||||
if (fseek(f, 0, SEEK_END) || (size = ftell(f)) == EOF || fseek(f, 0, SEEK_SET))
|
||||
{
|
||||
printf("Error: Cannot access file to determine size\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //B3_BULLET_DEFAULT_FILE_IO_H
|
||||
@@ -87,12 +87,21 @@ void b3ResourcePath::setAdditionalSearchPath(const char* path)
|
||||
}
|
||||
}
|
||||
|
||||
int b3ResourcePath::findResourcePath(const char* resourceName, char* resourcePathOut, int resourcePathMaxNumBytes)
|
||||
bool b3MyFindFile(void* userPointer, const char* orgFileName, char* relativeFileName, int maxRelativeFileNameMaxLen)
|
||||
{
|
||||
return b3FileUtils::findFile(orgFileName, relativeFileName, maxRelativeFileNameMaxLen);
|
||||
}
|
||||
|
||||
int b3ResourcePath::findResourcePath(const char* resourceName, char* resourcePathOut, int resourcePathMaxNumBytes, PFN_FIND_FILE findFile, void* userPointer)
|
||||
{
|
||||
if (findFile==0)
|
||||
{
|
||||
findFile=b3MyFindFile;
|
||||
}
|
||||
//first find in a resource/<exeName> location, then in various folders within 'data' using b3FileUtils
|
||||
char exePath[B3_MAX_EXE_PATH_LEN];
|
||||
|
||||
bool res = b3FileUtils::findFile(resourceName, resourcePathOut, resourcePathMaxNumBytes);
|
||||
bool res = findFile(userPointer, resourceName, resourcePathOut, resourcePathMaxNumBytes);
|
||||
if (res)
|
||||
{
|
||||
return strlen(resourcePathOut);
|
||||
@@ -104,7 +113,7 @@ int b3ResourcePath::findResourcePath(const char* resourceName, char* resourcePat
|
||||
char* resourcePathIn = tmpPath.m_path;
|
||||
sprintf(resourcePathIn, "%s/%s", sAdditionalSearchPath, resourceName);
|
||||
//printf("try resource at %s\n", resourcePath);
|
||||
if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
|
||||
if (findFile(userPointer, resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
|
||||
{
|
||||
return strlen(resourcePathOut);
|
||||
}
|
||||
@@ -122,20 +131,20 @@ int b3ResourcePath::findResourcePath(const char* resourceName, char* resourcePat
|
||||
char* resourcePathIn = tmpPath.m_path;
|
||||
sprintf(resourcePathIn, "%s../data/%s", pathToExe, resourceName);
|
||||
//printf("try resource at %s\n", resourcePath);
|
||||
if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
|
||||
if (findFile(userPointer, resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
|
||||
{
|
||||
return strlen(resourcePathOut);
|
||||
}
|
||||
|
||||
sprintf(resourcePathIn, "%s../resources/%s/%s", pathToExe, &exePath[exeNamePos], resourceName);
|
||||
//printf("try resource at %s\n", resourcePath);
|
||||
if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
|
||||
if (findFile(userPointer, resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
|
||||
{
|
||||
return strlen(resourcePathOut);
|
||||
}
|
||||
sprintf(resourcePathIn, "%s.runfiles/google3/third_party/bullet/data/%s", exePath, resourceName);
|
||||
//printf("try resource at %s\n", resourcePath);
|
||||
if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
|
||||
if (findFile(userPointer, resourcePathIn, resourcePathOut, resourcePathMaxNumBytes))
|
||||
{
|
||||
return strlen(resourcePathOut);
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
typedef bool (* PFN_FIND_FILE)(void* userPointer, const char* orgFileName, char* relativeFileName, int maxRelativeFileNameMaxLen);
|
||||
|
||||
class b3ResourcePath
|
||||
{
|
||||
public:
|
||||
static int getExePath(char* path, int maxPathLenInBytes);
|
||||
static int findResourcePath(const char* sourceName, char* resourcePath, int maxResourcePathLenInBytes);
|
||||
static int findResourcePath(const char* resourceName, char* resourcePathOut, int resourcePathMaxNumBytes, PFN_FIND_FILE findFile, void* userPointer=0);
|
||||
static void setAdditionalSearchPath(const char* path);
|
||||
};
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user