Added new osg::ApplicationUsage and osg::ArgumentParser to help streamline
application/example developement.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
TOPDIR = ../../..
|
||||
TOPDIR = ../../../
|
||||
include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
//Distributed under the terms of the GNU LIBRARY GENERAL PUBLIC LICENSE (LGPL)
|
||||
//as published by the Free Software Foundation.
|
||||
|
||||
#include <osg/ArgumentParser>
|
||||
#include <osg/ApplicationUsage>
|
||||
|
||||
|
||||
#include <osgUtil/Optimizer>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
@@ -15,83 +19,85 @@
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
||||
// create the commandline args.
|
||||
// use an ArgumentParser object to manage the program arguments.
|
||||
osg::ArgumentParser arguments(&argc,argv);
|
||||
|
||||
// set up the usage document, in case we need to print out how to use this program.
|
||||
osg::ApplicationUsage::instance()->setCommandLineUsage(arguments.getProgramName()+" [options] filename ...");
|
||||
osg::ApplicationUsage::instance()->addCommandLineOption("-h or --help","Display this information");
|
||||
osg::ApplicationUsage::instance()->addCommandLineOption("-p <filename>","Specify camera path file to animate the camera through the loaded scene");
|
||||
|
||||
|
||||
// construct the viewer.
|
||||
osgProducer::Viewer viewer(arguments);
|
||||
|
||||
// set up the value with sensible default event handlers.
|
||||
viewer.setUpViewer();
|
||||
|
||||
// if a pathfile has been specified on command line use it to animate the camera via an AnimationPathManipulator.
|
||||
std::string pathfile;
|
||||
std::string configfile;
|
||||
std::vector<std::string> commandLine;
|
||||
for(int i=1;i<argc;++i) {
|
||||
if( std::string(argv[i]) == "-p" ) {
|
||||
if( (i+1) >= argc ) {
|
||||
std::cout << "path argument required for -p option."<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
pathfile = std::string(argv[++i]);
|
||||
}
|
||||
else
|
||||
if( std::string(argv[i]) == "-c" ) {
|
||||
if( (i+1) >= argc ) {
|
||||
std::cout << "path argument required for -c option."<<std::endl;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
configfile = std::string(argv[++i]);
|
||||
}
|
||||
else
|
||||
commandLine.push_back(argv[i]);
|
||||
}
|
||||
|
||||
osg::DisplaySettings::instance()->readCommandLine(commandLine);
|
||||
osgDB::readCommandLine(commandLine);
|
||||
|
||||
osgProducer::Viewer* viewer = 0;
|
||||
if (!configfile.empty()) viewer = new osgProducer::Viewer(configfile);
|
||||
else viewer = new osgProducer::Viewer;
|
||||
|
||||
|
||||
// configure the plugin registry from the commandline arguments, and
|
||||
// eat any parameters that have been matched.
|
||||
osgDB::readCommandLine(commandLine);
|
||||
|
||||
|
||||
// read the scene.
|
||||
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(commandLine);
|
||||
if (!loadedModel) return 1;
|
||||
|
||||
// optimize it, remove rendundent nodes and state etc.
|
||||
osgUtil::Optimizer optimizer;
|
||||
optimizer.optimize(loadedModel.get());
|
||||
|
||||
|
||||
// set up the value with sensible defaults.
|
||||
viewer->setUpViewer();
|
||||
|
||||
if( !pathfile.empty() ) {
|
||||
while (arguments.read("-p",pathfile))
|
||||
{
|
||||
osg::ref_ptr<osgGA::AnimationPathManipulator> apm = new osgGA::AnimationPathManipulator(pathfile);
|
||||
if( apm.valid() && apm->valid() )
|
||||
{
|
||||
unsigned int num = viewer->addCameraManipulator(apm.get());
|
||||
viewer->selectCameraManipulator(num);
|
||||
unsigned int num = viewer.addCameraManipulator(apm.get());
|
||||
viewer.selectCameraManipulator(num);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if user request help pritn it out to cout.
|
||||
if (arguments.read("-h") || arguments.read("--help"))
|
||||
{
|
||||
osg::ApplicationUsage::instance()->write(cout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// read the scene from the list of file specified commandline args.
|
||||
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
|
||||
|
||||
// any option left unread a converted into errors to write out later.
|
||||
arguments.reportRemainingOptionsAsUnrecognized();
|
||||
|
||||
// report any errors if they have occured when parsing the program aguments.
|
||||
if (arguments.errors())
|
||||
{
|
||||
arguments.writeErrorMessages(cout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// if no model has been successfully loaded report failure.
|
||||
if (!loadedModel)
|
||||
{
|
||||
std::cout << arguments.getProgramName() <<": No input files" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// optimize the scene graph, remove rendundent nodes and state etc.
|
||||
osgUtil::Optimizer optimizer;
|
||||
optimizer.optimize(loadedModel.get());
|
||||
|
||||
// set the scene to render
|
||||
viewer->setSceneData(loadedModel.get());
|
||||
viewer.setSceneData(loadedModel.get());
|
||||
|
||||
// create the windows and run the threads.
|
||||
viewer->realize(Producer::CameraGroup::ThreadPerCamera);
|
||||
viewer.realize(Producer::CameraGroup::ThreadPerCamera);
|
||||
|
||||
while( !viewer->done() )
|
||||
while( !viewer.done() )
|
||||
{
|
||||
// wait for all cull and draw threads to complete.
|
||||
viewer->sync();
|
||||
viewer.sync();
|
||||
|
||||
// update the scene by traversing it with the the update visitor which will
|
||||
// call all node update callbacks and animations.
|
||||
viewer->update();
|
||||
viewer.update();
|
||||
|
||||
// fire off the cull and draw traversals of the scene.
|
||||
viewer->frame();
|
||||
viewer.frame();
|
||||
|
||||
}
|
||||
return 0;
|
||||
|
||||
171
src/osg/ApplicationUsage.cpp
Normal file
171
src/osg/ApplicationUsage.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#include <osg/ApplicationUsage>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
ApplicationUsage::ApplicationUsage(const std::string& commandLineUsage):
|
||||
_commandLineUsage(commandLineUsage)
|
||||
{
|
||||
}
|
||||
|
||||
ApplicationUsage* ApplicationUsage::instance()
|
||||
{
|
||||
static ApplicationUsage s_applicationUsage;
|
||||
return &s_applicationUsage;
|
||||
}
|
||||
|
||||
void ApplicationUsage::addUsageExplanation(Type type,const std::string& option,const std::string& explanation)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case(COMMAND_LINE_OPTION):
|
||||
addCommandLineOption(option,explanation);
|
||||
break;
|
||||
case(ENVIRONMENTAL_VARIABLE):
|
||||
addEnvironmentalVariable(option,explanation);
|
||||
break;
|
||||
case(KEYBOARD_MOUSE_BINDING):
|
||||
addKeyboardMouseBinding(option,explanation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationUsage::addCommandLineOption(const std::string& option,const std::string& explanation)
|
||||
{
|
||||
_commandLineOptions[option]=explanation;
|
||||
}
|
||||
|
||||
void ApplicationUsage::addEnvironmentalVariable(const std::string& option,const std::string& explanation)
|
||||
{
|
||||
_environmentalVariables[option]=explanation;
|
||||
}
|
||||
|
||||
void ApplicationUsage::addKeyboardMouseBinding(const std::string& option,const std::string& explanation)
|
||||
{
|
||||
_keyboardMouse[option]=explanation;
|
||||
}
|
||||
|
||||
void ApplicationUsage::write(std::ostream& output, const ApplicationUsage::UsageMap& um,unsigned int widthOfOutput)
|
||||
{
|
||||
unsigned int maxNumCharsInOptions = 0;
|
||||
ApplicationUsage::UsageMap::const_iterator citr;
|
||||
for(citr=um.begin();
|
||||
citr!=um.end();
|
||||
++citr)
|
||||
{
|
||||
maxNumCharsInOptions = std::max(maxNumCharsInOptions,citr->first.length());
|
||||
}
|
||||
|
||||
unsigned int fullWidth = widthOfOutput;
|
||||
unsigned int optionPos = 2;
|
||||
unsigned int optionWidth = maxNumCharsInOptions;
|
||||
unsigned int explanationPos = 2+maxNumCharsInOptions+2;
|
||||
unsigned int explanationWidth = fullWidth-explanationPos;
|
||||
|
||||
std::string line;
|
||||
|
||||
for(citr=um.begin();
|
||||
citr!=um.end();
|
||||
++citr)
|
||||
{
|
||||
line.assign(fullWidth,' ');
|
||||
line.replace(optionPos,optionWidth,citr->first);
|
||||
|
||||
const std::string& explanation = citr->second;
|
||||
unsigned int pos = 0;
|
||||
unsigned int offset = 0;
|
||||
bool firstInLine = true;
|
||||
while (pos<explanation.length())
|
||||
{
|
||||
if (firstInLine) offset = 0;
|
||||
|
||||
// skip any leading white space.
|
||||
while (pos<explanation.length() && explanation[pos]==' ')
|
||||
{
|
||||
if (firstInLine) ++offset;
|
||||
++pos;
|
||||
}
|
||||
|
||||
firstInLine = false;
|
||||
|
||||
unsigned int width = std::min(explanation.length()-pos,explanationWidth-offset);
|
||||
unsigned int slashn_pos = explanation.find('\n',pos);
|
||||
unsigned int extraSkip = 0;
|
||||
bool concatinated = false;
|
||||
if (slashn_pos!=std::string::npos)
|
||||
{
|
||||
if (slashn_pos<pos+width)
|
||||
{
|
||||
width = slashn_pos-pos;
|
||||
++extraSkip;
|
||||
firstInLine = true;
|
||||
}
|
||||
else if (slashn_pos==pos+width)
|
||||
{
|
||||
++extraSkip;
|
||||
firstInLine = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos+width<explanation.length())
|
||||
{
|
||||
// now reduce width until we get a space or a return
|
||||
// so that we ensure that whole words are printed.
|
||||
while (width>0 &&
|
||||
explanation[pos+width]!=' ' &&
|
||||
explanation[pos+width]!='\n') --width;
|
||||
|
||||
if (width==0)
|
||||
{
|
||||
// word must be longer than a whole line so will need
|
||||
// to concatinate it.
|
||||
width = explanationWidth-1;
|
||||
concatinated = true;
|
||||
}
|
||||
}
|
||||
|
||||
line.replace(explanationPos+offset,explanationWidth, explanation, pos, width);
|
||||
if (concatinated) output << line << '-' << std::endl;
|
||||
else output << line << std::endl;
|
||||
|
||||
|
||||
// move to the next line of output.
|
||||
line.assign(fullWidth,' ');
|
||||
pos += width+extraSkip;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationUsage::write(std::ostream& output,unsigned int widthOfOutput)
|
||||
{
|
||||
|
||||
output << "Usage: "<<getCommandLineUsage()<<std::endl;
|
||||
bool needspace = false;
|
||||
if (!getCommandLineOptions().empty())
|
||||
{
|
||||
if (needspace) output << std::endl;
|
||||
output << "Options:"<<std::endl;
|
||||
write(output,getCommandLineOptions(),widthOfOutput);
|
||||
needspace = true;
|
||||
}
|
||||
|
||||
if (!getEnvironmentalVariables().empty())
|
||||
{
|
||||
if (needspace) output << std::endl;
|
||||
output << "Environmental Variables:"<<std::endl;
|
||||
write(output,getEnvironmentalVariables(),widthOfOutput);
|
||||
needspace = true;
|
||||
}
|
||||
|
||||
if (!getKeyboardMouseBindings().empty())
|
||||
{
|
||||
if (needspace) output << std::endl;
|
||||
output << "Keyboard and Mouse Bindings:"<<std::endl;
|
||||
write(output,getKeyboardMouseBindings(),widthOfOutput);
|
||||
needspace = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
286
src/osg/ArgumentParser.cpp
Normal file
286
src/osg/ArgumentParser.cpp
Normal file
@@ -0,0 +1,286 @@
|
||||
#include <osg/ArgumentParser>
|
||||
|
||||
using namespace osg;
|
||||
|
||||
std::string ArgumentParser::getProgramName() const
|
||||
{
|
||||
if (_argc>0) return std::string(_argv[0]);
|
||||
return "";
|
||||
}
|
||||
|
||||
int ArgumentParser::find(const std::string& str) const
|
||||
{
|
||||
for(int pos=1;pos<*_argc;++pos)
|
||||
{
|
||||
if (str==_argv[pos]) return pos;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ArgumentParser::match(int pos, const std::string& str) const
|
||||
{
|
||||
return pos<*_argc && str==_argv[pos];
|
||||
}
|
||||
|
||||
bool ArgumentParser::isOption(int pos) const
|
||||
{
|
||||
return (pos<*_argc && _argv[pos][0]=='-');
|
||||
}
|
||||
|
||||
bool ArgumentParser::isString(int pos) const
|
||||
{
|
||||
return pos<*_argc && !isOption(pos);
|
||||
}
|
||||
|
||||
bool ArgumentParser::isNumber(int pos) const
|
||||
{
|
||||
if (pos>=*_argc) return false;
|
||||
|
||||
bool hadPlusMinus = false;
|
||||
bool hadDecimalPlace = false;
|
||||
bool hadExponent = false;
|
||||
bool couldBeInt = true;
|
||||
bool couldBeFloat = true;
|
||||
int noZeroToNine = 0;
|
||||
|
||||
const char* ptr = _argv[pos];
|
||||
|
||||
// check if could be a hex number.
|
||||
if (strncmp(ptr,"0x",2)==0)
|
||||
{
|
||||
// skip over leading 0x, and then go through rest of string
|
||||
// checking to make sure all values are 0...9 or a..f.
|
||||
ptr+=2;
|
||||
while (
|
||||
*ptr!=0 &&
|
||||
((*ptr>='0' && *ptr<='9') ||
|
||||
(*ptr>='a' && *ptr<='f') ||
|
||||
(*ptr>='A' && *ptr<='F'))
|
||||
)
|
||||
{
|
||||
++ptr;
|
||||
}
|
||||
|
||||
// got to end of string without failure, therefore must be a hex integer.
|
||||
if (*ptr==0) return true;
|
||||
}
|
||||
|
||||
ptr = _argv[pos];
|
||||
// check if a float or an int.
|
||||
while (*ptr!=0 && couldBeFloat)
|
||||
{
|
||||
if (*ptr=='+' || *ptr=='-')
|
||||
{
|
||||
if (hadPlusMinus)
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
} else hadPlusMinus = true;
|
||||
}
|
||||
else if (*ptr>='0' && *ptr<='9')
|
||||
{
|
||||
noZeroToNine++;
|
||||
}
|
||||
else if (*ptr=='.')
|
||||
{
|
||||
if (hadDecimalPlace)
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hadDecimalPlace = true;
|
||||
couldBeInt = false;
|
||||
}
|
||||
}
|
||||
else if (*ptr=='e' || *ptr=='E')
|
||||
{
|
||||
if (hadExponent || noZeroToNine==0)
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
hadExponent = true;
|
||||
couldBeInt = false;
|
||||
hadDecimalPlace = false;
|
||||
hadPlusMinus = false;
|
||||
noZeroToNine=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
couldBeInt = false;
|
||||
couldBeFloat = false;
|
||||
}
|
||||
++ptr;
|
||||
}
|
||||
|
||||
if (couldBeInt && noZeroToNine>0) return true;
|
||||
if (couldBeFloat && noZeroToNine>0) return true;
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool ArgumentParser::containsOptions() const
|
||||
{
|
||||
for(int pos=1;pos<*_argc;++pos)
|
||||
{
|
||||
if (isOption(pos)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ArgumentParser::remove(int pos,int num)
|
||||
{
|
||||
if (num==0) return;
|
||||
|
||||
for(;pos+num<*_argc;++pos)
|
||||
{
|
||||
_argv[pos]=_argv[pos+num];
|
||||
}
|
||||
for(;pos<*_argc;++pos)
|
||||
{
|
||||
_argv[pos]=0;
|
||||
}
|
||||
*_argc-=num;
|
||||
}
|
||||
|
||||
bool ArgumentParser::read(const std::string& str)
|
||||
{
|
||||
int pos=find(str);
|
||||
if (pos<=0) return false;
|
||||
remove(pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArgumentParser::read(const std::string& str,std::string& value1)
|
||||
{
|
||||
int pos=find(str);
|
||||
if (pos<=0) return false;
|
||||
if (!isString(pos+1))
|
||||
{
|
||||
reportError("argument to `"+str+"` is missing");
|
||||
return false;
|
||||
}
|
||||
value1 = _argv[pos+1];
|
||||
remove(pos,2);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArgumentParser::read(const std::string& str,std::string& value1,std::string& value2)
|
||||
{
|
||||
int pos=find(str);
|
||||
if (pos<=0) return false;
|
||||
if (!isString(pos+1) || !isString(pos+2) )
|
||||
{
|
||||
reportError("argument to `"+str+"` is missing");
|
||||
return false;
|
||||
}
|
||||
value1 = _argv[pos+1];
|
||||
value2 = _argv[pos+2];
|
||||
remove(pos,3);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArgumentParser::read(const std::string& str,std::string& value1,std::string& value2,std::string& value3)
|
||||
{
|
||||
int pos=find(str);
|
||||
if (pos<=0) return false;
|
||||
if (!isString(pos+1) || !isString(pos+2) || !isString(pos+3))
|
||||
{
|
||||
reportError("argument to `"+str+"` is missing");
|
||||
return false;
|
||||
}
|
||||
value1 = _argv[pos+1];
|
||||
value2 = _argv[pos+2];
|
||||
value3 = _argv[pos+3];
|
||||
remove(pos,4);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ArgumentParser::read(const std::string& str,float& value1)
|
||||
{
|
||||
int pos=find(str);
|
||||
if (pos<=0) return false;
|
||||
if (!isNumber(pos+1))
|
||||
{
|
||||
reportError("argument to `"+str+"` is missing");
|
||||
return false;
|
||||
}
|
||||
value1 = atof(_argv[pos+1]);
|
||||
remove(pos,2);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArgumentParser::read(const std::string& str,float& value1,float& value2)
|
||||
{
|
||||
int pos=find(str);
|
||||
if (pos<=0) return false;
|
||||
if (!isNumber(pos+1) || !isNumber(pos+2) )
|
||||
{
|
||||
reportError("argument to `"+str+"` is missing");
|
||||
return false;
|
||||
}
|
||||
value1 = atof(_argv[pos+1]);
|
||||
value2 = atof(_argv[pos+2]);
|
||||
remove(pos,3);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArgumentParser::read(const std::string& str,float& value1,float& value2,float& value3)
|
||||
{
|
||||
int pos=find(str);
|
||||
if (pos<=0) return false;
|
||||
if (!isNumber(pos+1) || !isNumber(pos+2) || !isNumber(pos+3))
|
||||
{
|
||||
reportError("argument to `"+str+"` is missing");
|
||||
return false;
|
||||
}
|
||||
value1 = atof(_argv[pos+1]);
|
||||
value2 = atof(_argv[pos+2]);
|
||||
value3 = atof(_argv[pos+3]);
|
||||
remove(pos,4);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ArgumentParser::errors(ErrorSeverity severity) const
|
||||
{
|
||||
for(ErrorMessageMap::const_iterator itr=_errorMessageMap.begin();
|
||||
itr!=_errorMessageMap.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->second>=severity) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ArgumentParser::reportError(const std::string& message,ErrorSeverity severity)
|
||||
{
|
||||
_errorMessageMap[message]=severity;
|
||||
}
|
||||
|
||||
void ArgumentParser::reportRemainingOptionsAsUnrecognized(ErrorSeverity severity)
|
||||
{
|
||||
for(int pos=1;pos<argc();++pos)
|
||||
{
|
||||
if (isOption(pos)) reportError(getProgramName() +": unrceognized option "+_argv[pos],severity);
|
||||
}
|
||||
}
|
||||
void ArgumentParser::writeErrorMessages(std::ostream& output,ErrorSeverity severity)
|
||||
{
|
||||
for(ErrorMessageMap::iterator itr=_errorMessageMap.begin();
|
||||
itr!=_errorMessageMap.end();
|
||||
++itr)
|
||||
{
|
||||
if (itr->second>=severity)
|
||||
{
|
||||
output<<getProgramName()<<": "<<itr->first<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
#include <osg/DisplaySettings>
|
||||
#include <osg/ApplicationUsage>
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -104,6 +105,17 @@ void DisplaySettings::setDefaults()
|
||||
#endif
|
||||
}
|
||||
|
||||
ApplicationUsageProxy e0(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO_MODE <mode>","QUAD_BUFFER | ANAGLYPHIC | HORIZONTAL_SPLIT | VERTICAL_SPLIT | LEFT_EYE | RIGHT_EYE");
|
||||
ApplicationUsageProxy e1(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_STEREO <mode>","OFF | ON");
|
||||
ApplicationUsageProxy e2(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_EYE_SEPARATION <float>","physical distance between eyes");
|
||||
ApplicationUsageProxy e3(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_DISTANCE <float>","physical distance between eyes and screen");
|
||||
ApplicationUsageProxy e4(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SCREEN_HEIGHT <float>","physical screen height");
|
||||
ApplicationUsageProxy e5(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_EYE_MAPPING <mode>","LEFT_EYE_LEFT_VIEWPORT | LEFT_EYE_RIGHT_VIEWPORT");
|
||||
ApplicationUsageProxy e8(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_HORIZONTAL_SEPARATION <float>","number of pixels between viewports");
|
||||
ApplicationUsageProxy e9(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_EYE_MAPPING <mode>","LEFT_EYE_TOP_VIEWPORT | LEFT_EYE_BOTTOM_VIEWPORT");
|
||||
ApplicationUsageProxy e11(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_SPLIT_STEREO_VERTICAL_SEPARATION <float>","number of pixels between viewports");
|
||||
ApplicationUsageProxy e12(ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_MAX_NUMBER_OF_GRAPHICS_CONTEXTS <int>","maximum number of graphics contexts to be used with applications.");
|
||||
|
||||
void DisplaySettings::readEnvironmentalVariables()
|
||||
{
|
||||
char *ptr;
|
||||
@@ -281,3 +293,31 @@ void DisplaySettings::readCommandLine(std::vector<std::string>& commandLine)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DisplaySettings::readCommandLine(ArgumentParser& parser)
|
||||
{
|
||||
int pos;
|
||||
while ((pos=parser.find("-stereo"))!=0)
|
||||
{
|
||||
if (parser.match(pos+1,"ANAGLYPHIC")) { parser.remove(pos,2); _stereo = true;_stereoMode = ANAGLYPHIC; }
|
||||
else if (parser.match(pos+1,"QUAD_BUFFER")) { parser.remove(pos,2); _stereo = true;_stereoMode = QUAD_BUFFER; }
|
||||
else if (parser.match(pos+1,"HORIZONTAL_SPLIT")) { parser.remove(pos,2); _stereo = true;_stereoMode = HORIZONTAL_SPLIT; }
|
||||
else if (parser.match(pos+1,"VERTICAL_SPLIT")) { parser.remove(pos,2); _stereo = true;_stereoMode = VERTICAL_SPLIT; }
|
||||
else if (parser.match(pos+1,"LEFT_EYE")) { parser.remove(pos,2); _stereo = true;_stereoMode = LEFT_EYE; }
|
||||
else if (parser.match(pos+1,"RIGHT_EYE")) { parser.remove(pos,2); _stereo = true;_stereoMode = RIGHT_EYE; }
|
||||
else if (parser.match(pos+1,"ON")) { parser.remove(pos,2); _stereo = true; }
|
||||
else if (parser.match(pos+1,"OFF")) { parser.remove(pos,2); _stereo = false; }
|
||||
else { parser.remove(pos); _stereo = true; }
|
||||
}
|
||||
|
||||
while (parser.read("-rgba"))
|
||||
{
|
||||
_RGB = true;
|
||||
_minimumNumberAlphaBits = 1;
|
||||
}
|
||||
|
||||
while (parser.read("-stencil"))
|
||||
{
|
||||
_minimumNumberStencilBits = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ include $(TOPDIR)/Make/makedefs
|
||||
CXXFILES =\
|
||||
AlphaFunc.cpp\
|
||||
AnimationPath.cpp\
|
||||
ApplicationUsage.cpp\
|
||||
ArgumentParser.cpp\
|
||||
Array.cpp\
|
||||
Billboard.cpp\
|
||||
BoundingBox.cpp\
|
||||
|
||||
@@ -96,3 +96,52 @@ Node* osgDB::readNodeFiles(std::vector<std::string>& commandLine)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Node* osgDB::readNodeFiles(osg::ArgumentParser& arguments)
|
||||
{
|
||||
osgDB::readCommandLine(arguments);
|
||||
|
||||
typedef std::vector<osg::Node*> NodeList;
|
||||
NodeList nodeList;
|
||||
|
||||
// note currently doesn't delete the loaded file entries from the command line yet...
|
||||
|
||||
for(int pos=1;pos<arguments.argc();++pos)
|
||||
{
|
||||
if (!arguments.isOption(pos))
|
||||
{
|
||||
// not an option so assume string is a filename.
|
||||
osg::Node *node = osgDB::readNodeFile( arguments[pos] );
|
||||
|
||||
if(node)
|
||||
{
|
||||
if (node->getName().empty()) node->setName( arguments[pos] );
|
||||
nodeList.push_back(node);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeList.empty())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nodeList.size()==1)
|
||||
{
|
||||
return nodeList.front();
|
||||
}
|
||||
else // size >1
|
||||
{
|
||||
osg::Group* group = new osg::Group;
|
||||
for(NodeList::iterator itr=nodeList.begin();
|
||||
itr!=nodeList.end();
|
||||
++itr)
|
||||
{
|
||||
group->addChild(*itr);
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <osg/Node>
|
||||
#include <osg/Group>
|
||||
#include <osg/Geode>
|
||||
#include <osg/ApplicationUsage>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
#include <osgDB/FileUtils>
|
||||
@@ -83,7 +84,11 @@ Registry::~Registry()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
osg::ApplicationUsageProxy e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_FILE_PATH <path>[:path]..","Paths for locating datafiles");
|
||||
#else
|
||||
osg::ApplicationUsageProxy e0(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_FILE_PATH <path>[;path]..","Paths for locating datafiles");
|
||||
#endif
|
||||
|
||||
void Registry::initDataFilePathList()
|
||||
{
|
||||
@@ -106,6 +111,12 @@ void Registry::initDataFilePathList()
|
||||
PrintFilePathList(osg::notify(INFO),getDataFilePathList());
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
osg::ApplicationUsageProxy e1(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_LIBRARY_PATH <path>[:path]..","Paths for locating libraries/ plugins");
|
||||
#else
|
||||
osg::ApplicationUsageProxy e1(osg::ApplicationUsage::ENVIRONMENTAL_VARIABLE,"OSG_LIBRARY_PATH <path>[;path]..","Paths for locating libraries/ plugins");
|
||||
#endif
|
||||
|
||||
void Registry::initLibraryFilePathList()
|
||||
{
|
||||
//
|
||||
@@ -266,6 +277,27 @@ void Registry::readCommandLine(std::vector<std::string>& commandLine)
|
||||
}
|
||||
}
|
||||
|
||||
void Registry::readCommandLine(osg::ArgumentParser& parser)
|
||||
{
|
||||
|
||||
std::string value;
|
||||
while(parser.read("-l",value))
|
||||
{
|
||||
loadLibrary(value);
|
||||
}
|
||||
|
||||
while(parser.read("-e",value))
|
||||
{
|
||||
std::string libName = createLibraryNameForExt(value);
|
||||
loadLibrary(libName);
|
||||
}
|
||||
|
||||
while(parser.read("-O",value))
|
||||
{
|
||||
setOptions(new osgDB::ReaderWriter::Options(value));
|
||||
}
|
||||
}
|
||||
|
||||
void Registry::addDotOsgWrapper(DotOsgWrapper* wrapper)
|
||||
{
|
||||
if (wrapper==0L) return;
|
||||
|
||||
@@ -14,18 +14,33 @@ std::string findCameraConfigFile(const std::string& configFile)
|
||||
else return foundFile;
|
||||
}
|
||||
|
||||
std::string extractCameraConfigFile(osg::ArgumentParser& arguments)
|
||||
{
|
||||
std::string filename;
|
||||
if (arguments.read("-c",filename)) return filename;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
CameraGroup::CameraGroup() : Producer::CameraGroup()
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
CameraGroup::CameraGroup(Producer::CameraConfig *cfg): Producer::CameraGroup(cfg)
|
||||
CameraGroup::CameraGroup(Producer::CameraConfig *cfg):
|
||||
Producer::CameraGroup(cfg)
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
CameraGroup::CameraGroup(const std::string& configFile) : Producer::CameraGroup(findCameraConfigFile(configFile))
|
||||
CameraGroup::CameraGroup(const std::string& configFile):
|
||||
Producer::CameraGroup(findCameraConfigFile(configFile))
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
CameraGroup::CameraGroup(osg::ArgumentParser& arguments):
|
||||
Producer::CameraGroup(extractCameraConfigFile(arguments))
|
||||
{
|
||||
_init();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
#include <osgUtil/UpdateVisitor>
|
||||
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include <osgGA/AnimationPathManipulator>
|
||||
#include <osgGA/TrackballManipulator>
|
||||
#include <osgGA/FlightManipulator>
|
||||
#include <osgGA/DriveManipulator>
|
||||
@@ -13,6 +16,7 @@
|
||||
|
||||
using namespace osgProducer;
|
||||
|
||||
|
||||
Viewer::Viewer():
|
||||
_done(0),
|
||||
_frameNumber(0),
|
||||
@@ -36,6 +40,27 @@ Viewer::Viewer(const std::string& configFile):
|
||||
{
|
||||
}
|
||||
|
||||
Viewer::Viewer(osg::ArgumentParser& arguments):
|
||||
CameraGroup(arguments),
|
||||
_done(false),
|
||||
_frameNumber(0),
|
||||
_kbmcb(0)
|
||||
{
|
||||
osg::DisplaySettings::instance()->readCommandLine(arguments);
|
||||
|
||||
std::string pathfile;
|
||||
while (arguments.read("-p",pathfile))
|
||||
{
|
||||
osg::ref_ptr<osgGA::AnimationPathManipulator> apm = new osgGA::AnimationPathManipulator(pathfile);
|
||||
if( apm.valid() && apm->valid() )
|
||||
{
|
||||
unsigned int num = addCameraManipulator(apm.get());
|
||||
selectCameraManipulator(num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Viewer::setUpViewer(unsigned int options)
|
||||
{
|
||||
|
||||
@@ -108,7 +133,7 @@ void Viewer::setUpViewer(unsigned int options)
|
||||
if (options&STATS_MANIPULATOR)
|
||||
{
|
||||
// register the drawing of stats to pipe 0.
|
||||
Producer::FrameStatsHandler* fsh = new Producer::FrameStatsHandler;
|
||||
FrameStatsHandler* fsh = new FrameStatsHandler;
|
||||
setStatsHandler(fsh);
|
||||
getCamera(0)->addPostDrawCallback(fsh);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user