From Sondra Iversion "Loading a single model from an externally
referenced file is a standard option for OpenFlight and is specified by including the modelname in angle brackets, such as: filename<modelname>. The attached code identifies and handles this case."
This commit is contained in:
@@ -131,6 +131,10 @@ SOURCE=..\..\..\src\osgPlugins\flt\FaceRecord.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\flt\FindExternalModelVisitor.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\flt\flt.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@@ -323,6 +327,10 @@ SOURCE=..\..\..\src\osgPlugins\flt\FaceRecord.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\flt\FindExternalModelVisitor.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\..\src\osgPlugins\flt\flt.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@@ -25,6 +25,65 @@ ExternalRecord::~ExternalRecord()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the filename of the external record. External references are
|
||||
* specified as either:
|
||||
* filename - include the entire file
|
||||
* filename<modelname> - include only the specified model from the file
|
||||
*
|
||||
* Therefore, the filename is either the entire string or the portion of the
|
||||
* string prior to the first '<' character.
|
||||
**/
|
||||
const std::string ExternalRecord::getFilename( void )
|
||||
{
|
||||
std::string wholeFilename(getData()->szPath);
|
||||
std::string filename;
|
||||
|
||||
size_t pos = wholeFilename.find_first_of( "<" );
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
filename = wholeFilename.substr( 0, pos );
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = wholeFilename;
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return the modelname of the external record. External references are
|
||||
* specified as either:
|
||||
* filename - include the entire file
|
||||
* filename<modelname> - include only the specified model from the file
|
||||
*
|
||||
* Therefore, the modelname is the portion of the string between '<' and '>'
|
||||
* characters when those characters are present. Otherwise there is no
|
||||
* modelname.
|
||||
**/
|
||||
std::string ExternalRecord::getModelName( void )
|
||||
{
|
||||
std::string wholeFilename(getData()->szPath);
|
||||
std::string modelName;
|
||||
|
||||
size_t pos = wholeFilename.find_first_of( "<" );
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
size_t pos2 = wholeFilename.find_first_of( ">" );
|
||||
|
||||
// Starting after the first '<', return the characters prior to the
|
||||
// first '>'.
|
||||
modelName = wholeFilename.substr( pos+1, pos2-pos-1 );
|
||||
}
|
||||
|
||||
return modelName;
|
||||
}
|
||||
|
||||
|
||||
void ExternalRecord::setExternal(FltFile* pExternal)
|
||||
{
|
||||
|
||||
@@ -45,8 +45,11 @@ class ExternalRecord : public PrimNodeRecord
|
||||
SExternalReference* getData() const { return (SExternalReference*)_pData; }
|
||||
|
||||
void setExternal(FltFile* pExternal);
|
||||
|
||||
FltFile* getExternal() { return _fltfile.get(); }
|
||||
const std::string getFilename( void ) const { return std::string(getData()->szPath); }
|
||||
|
||||
const std::string getFilename( void );
|
||||
std::string getModelName() ;
|
||||
|
||||
enum Flag
|
||||
{
|
||||
|
||||
18
src/osgPlugins/flt/FindExternalModelVisitor.cpp
Normal file
18
src/osgPlugins/flt/FindExternalModelVisitor.cpp
Normal file
@@ -0,0 +1,18 @@
|
||||
// FindExternalModelVisitor.cpp
|
||||
|
||||
#include "FindExternalModelVisitor.h"
|
||||
|
||||
using namespace flt;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void FindExternalModelVisitor::apply( osg::Node &node )
|
||||
{
|
||||
if ( node.getName() == _modelName )
|
||||
_model = &node; // Store the node. No need to process children.
|
||||
else
|
||||
traverse( node );
|
||||
}
|
||||
|
||||
36
src/osgPlugins/flt/FindExternalModelVisitor.h
Normal file
36
src/osgPlugins/flt/FindExternalModelVisitor.h
Normal file
@@ -0,0 +1,36 @@
|
||||
// FindExternalModelVisitor.h
|
||||
|
||||
#ifndef __FIND_EXTERNAL_MODEL_VISITOR_H_
|
||||
#define __FIND_EXTERNAL_MODEL_VISITOR_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <osg/Node>
|
||||
#include <osg/NodeVisitor>
|
||||
|
||||
namespace flt {
|
||||
|
||||
/**
|
||||
* A visitor to find a named node.
|
||||
*/
|
||||
class FindExternalModelVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
FindExternalModelVisitor( ) : osg::NodeVisitor( TRAVERSE_ALL_CHILDREN ) {}
|
||||
|
||||
virtual void apply( osg::Node &node );
|
||||
|
||||
void setModelName( std::string modelName ) { _modelName = modelName; }
|
||||
|
||||
osg::Node *getModel() { return _model.get(); }
|
||||
|
||||
private:
|
||||
|
||||
std::string _modelName;
|
||||
osg::ref_ptr<osg::Node> _model;
|
||||
|
||||
};
|
||||
|
||||
}; // end namespace flt
|
||||
|
||||
#endif // __FIND_EXTERNAL_MODEL_VISITOR_H_
|
||||
|
||||
@@ -209,7 +209,7 @@ bool FltFile::readFile(const std::string& fileName)
|
||||
MaterialPool* pMaterialPool = NULL;
|
||||
LtPtAppearancePool* pLtPtAppearancePool = NULL;
|
||||
LtPtAnimationPool* pLtPtAnimationPool = NULL;
|
||||
std::string filename(pSExternal->szPath);
|
||||
std::string filename( rec.getFilename() );
|
||||
|
||||
osg::notify(osg::INFO) << "External=" << filename << std::endl;
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ CXXFILES =\
|
||||
MultiTextureRecord.cpp\
|
||||
UVListRecord.cpp\
|
||||
BSPRecord.cpp\
|
||||
FindExternalModelVisitor.cpp\
|
||||
# PointLight.cpp\
|
||||
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@
|
||||
#include "LightSourcePaletteRecord.h"
|
||||
#include "AttrData.h"
|
||||
#include "BSPRecord.h"
|
||||
#include "FindExternalModelVisitor.h"
|
||||
|
||||
static int dprint = 0 ;
|
||||
#define DPRINT if(dprint)fprintf
|
||||
@@ -2448,7 +2449,47 @@ osg::Group* ConvertFromFLT::visitExternal(osg::Group& osgParent, ExternalRecord*
|
||||
pFile->setDesiredUnits( rec->getFltFile()->getDesiredUnits() );
|
||||
external = pFile->convert();
|
||||
if (external)
|
||||
visitAncillary(osgParent, *external, rec)->addChild(external);
|
||||
{
|
||||
osg::Group *tempParent = visitAncillary(osgParent, *external, rec);
|
||||
|
||||
// In the situation in which only one model is required from an
|
||||
// externally referenced file, it would be more efficient to only
|
||||
// convert that one model from the FltFile records. (This would be
|
||||
// the preferred method if this loader is rewritten.) However,
|
||||
// since this situation is fairly rare and it is currently much
|
||||
// more straight forward to work with the OSG structure, we will
|
||||
// just pull out the part of the OSG tree that is needed at this
|
||||
// point.
|
||||
|
||||
// If a model name was specified, find and add the node with
|
||||
// that name. Otherwise, add the entire tree.
|
||||
|
||||
std::string modelName = rec->getModelName();
|
||||
if ( modelName.empty() )
|
||||
{
|
||||
// Add the entire externally referenced file
|
||||
tempParent->addChild(external);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the specified model
|
||||
FindExternalModelVisitor findExternalModelVisitor;
|
||||
findExternalModelVisitor.setModelName( modelName );
|
||||
external->accept( findExternalModelVisitor );
|
||||
osg::Node *model = findExternalModelVisitor.getModel();
|
||||
if (model)
|
||||
{
|
||||
tempParent->addChild(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::WARN) << "In ConvertFromFLT::visitExternal,"
|
||||
<< " the requested model " << modelName
|
||||
<< " was not found in external file "
|
||||
<< rec->getFilename() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return external;
|
||||
|
||||
Reference in New Issue
Block a user