From Jason Daly, "'ve been busy working on the Source engine plugins. There are several contributions in this submission:

osgDB/FileUtils.cpp:
Needed this extra code to allow a true case-insensitive search.  This is because the HL2 map and model files are often sloppy with case.  For example, the file might look for materials/models/alyx/alyx_sheet.vtf, but the file is actually in materials/Models/Alyx/alyx_sheet.vtf.  In case-insensitive mode, the new code recursively disassembles the path and checks each path element without regard to case.  In case-sensitive mode, the code behaves exactly as it used to.  The new code is also mostly skipped on Windows because of the case-insensitive file system.  Previously, I did all of this with custom search code in the .bsp plugin, but this allows the user to tailor the search using OSGFILEPATH.  There are some instructions in the plugins' README files about this.

osgPlugins/mdl:
This is a new plug-in for Half-Life 2 models (as opposed to maps).  This allows you to load Source models individually, as well as allowing the .bsp plugin to load models (props) that are embedded into maps.  Mdl files can contain simple object (crates, barrels, bottles), as well as fully articulated characters with skeletal animations.  Currently, it can load the simple objects.  It can also load the characters, but it can't load the skeletons or animations.

osgPlugins/bsp:
This contains all of the changes needed to load props along with the basic map geometry.  There are also
several bugs fixed.

osgPlugins/vtf:
This is the loader for Valve's texture format.  Previously, we had agreed to put this in with the bsp plugin, but I didn't think of the .mdl plugin at that time.  It's conceivable that a user might want to load models individually (not as part of a map), so the vtf reader does have to be separate.  I also fixed a rather significant bug.

I tested all of this code on RHEL 5.2 (32-bit), and Fedora 9 (64-bit).  I'll be testing on Windows soon.

I also attached a simple .mdl file, along with it's associated files and textures.  Just extract the tarball into it's own directory, set your OSGFILEPATH to point at that directory, and load the model like this:

 osgviewer models/props_junk/gascan001a.mdl"
This commit is contained in:
Robert Osfield
2008-12-20 13:35:49 +00:00
parent 05cb054140
commit 28ca8277f8
34 changed files with 4608 additions and 670 deletions

View File

@@ -378,38 +378,122 @@ std::string osgDB::findFileInDirectory(const std::string& fileName,const std::st
bool needDirectoryName = true;
osgDB::DirectoryContents dc;
if (dirName.empty())
std::string realDirName = dirName;
std::string realFileName = fileName;
// Skip case-insensitive recursion if on Windows
#ifdef WIN32
bool win32 = true;
#else
bool win32 = false;
#endif
// If the fileName contains extra path information, make that part of the
// directory name instead
if (fileName != getSimpleFileName(fileName))
{
// See if we need to add a slash between the directory and file
if (realDirName.empty())
{
realDirName = getFilePath(fileName);
}
else if (realDirName=="." || realDirName=="./" || realDirName==".\\")
{
realDirName = "./" + getFilePath(fileName);
}
else
{
char lastChar = dirName[dirName.size()-1];
if ((lastChar == '/') || (lastChar == '\\'))
realDirName = dirName + getFilePath(fileName);
else
realDirName = dirName + "/" + getFilePath(fileName);
}
// Simplify the file name
realFileName = getSimpleFileName(fileName);
}
osg::notify(osg::DEBUG_INFO) << "findFileInDirectory() : looking for " << realFileName << " in " << realDirName << "...\n";
if (realDirName.empty())
{
dc = osgDB::getDirectoryContents(".");
needFollowingBackslash = false;
needDirectoryName = false;
}
else if (dirName=="." || dirName=="./" || dirName==".\\")
else if (realDirName=="." || realDirName=="./" || realDirName==".\\")
{
dc = osgDB::getDirectoryContents(".");
needFollowingBackslash = false;
needDirectoryName = false;
}
else if (realDirName=="/")
{
dc = osgDB::getDirectoryContents("/");
needFollowingBackslash = false;
needDirectoryName = true;
}
else
{
dc = osgDB::getDirectoryContents(dirName);
char lastChar = dirName[dirName.size()-1];
if (lastChar=='/') needFollowingBackslash = false;
else if (lastChar=='\\') needFollowingBackslash = false;
else needFollowingBackslash = true;
needDirectoryName = true;
// See if we're working in case insensitive mode, and that we're not
// using Windows (the recursive search is not needed in these
// cases)
if ((caseSensitivity == CASE_INSENSITIVE) && (!win32))
{
// Split the last path element from the directory name
std::string parentPath = getFilePath(realDirName);
std::string lastElement = getSimpleFileName(realDirName);
// See if we're already at the top level of the filesystem
if ((parentPath.empty()) && (!lastElement.empty()))
{
// Search for the first path element (ignoring case) in
// the top-level directory
realDirName = findFileInDirectory(lastElement, "/",
CASE_INSENSITIVE);
dc = osgDB::getDirectoryContents(realDirName);
needFollowingBackslash = true;
needDirectoryName = true;
}
else
{
// Recursively search for the last path element (ignoring case)
// in the parent path
realDirName = findFileInDirectory(lastElement, parentPath,
CASE_INSENSITIVE);
dc = osgDB::getDirectoryContents(realDirName);
char lastChar = realDirName[realDirName.size()-1];
if (lastChar=='/') needFollowingBackslash = false;
else if (lastChar=='\\') needFollowingBackslash = false;
else needFollowingBackslash = true;
needDirectoryName = true;
}
}
else
{
// No need for recursive search if we're doing an exact comparison
dc = osgDB::getDirectoryContents(realDirName);
char lastChar = realDirName[realDirName.size()-1];
if (lastChar=='/') needFollowingBackslash = false;
else if (lastChar=='\\') needFollowingBackslash = false;
else needFollowingBackslash = true;
needDirectoryName = true;
}
}
for(osgDB::DirectoryContents::iterator itr=dc.begin();
itr!=dc.end();
++itr)
{
if ((caseSensitivity==CASE_INSENSITIVE && osgDB::equalCaseInsensitive(fileName,*itr)) ||
(fileName==*itr))
if ((caseSensitivity==CASE_INSENSITIVE && osgDB::equalCaseInsensitive(realFileName,*itr)) ||
(realFileName==*itr))
{
if (!needDirectoryName) return *itr;
else if (needFollowingBackslash) return dirName+'/'+*itr;
else return dirName+*itr;
else if (needFollowingBackslash) return realDirName+'/'+*itr;
else return realDirName+*itr;
}
}
return "";