Added XML support and slideshow constructor to slideshow3D example, now
renamed from the previous osgslideshow.
This commit is contained in:
178
examples/slideshow3D/DefaultPresentation.cpp
Normal file
178
examples/slideshow3D/DefaultPresentation.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <osg/Switch>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/Quat>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/Geode>
|
||||
#include <osg/PolygonOffset>
|
||||
|
||||
#include <osgText/Text>
|
||||
|
||||
osg::MatrixTransform* createPositionedAndScaledModel(osg::Node* model,const osg::Vec3& pos, float radius, osg::Quat rotation)
|
||||
{
|
||||
osg::MatrixTransform* transform = new osg::MatrixTransform;
|
||||
|
||||
const osg::BoundingSphere& bs = model->getBound();
|
||||
|
||||
transform->setDataVariance(osg::Object::STATIC);
|
||||
transform->setMatrix(osg::Matrix::translate(-bs.center())*
|
||||
osg::Matrix::scale(radius/bs.radius(),radius/bs.radius(),radius/bs.radius())*
|
||||
osg::Matrix::rotate(rotation)*
|
||||
osg::Matrix::translate(pos));
|
||||
|
||||
transform->addChild(model);
|
||||
|
||||
return transform;
|
||||
}
|
||||
|
||||
osg::Vec4 layoutColor(1.0f,1.0f,1.0f,1.0f);
|
||||
float layoutCharacterSize = 50.0f;
|
||||
std::string fontStr("fonts/arial.ttf");
|
||||
|
||||
osg::Geode* createText(osg::Vec3& cursor,const std::string& str)
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
|
||||
osgText::Text* text = new osgText::Text;
|
||||
text->setFont(fontStr);
|
||||
text->setColor(layoutColor);
|
||||
text->setCharacterSize(layoutCharacterSize);
|
||||
text->setAxisAlignment(osgText::Text::XZ_PLANE);
|
||||
text->setPosition(cursor);
|
||||
|
||||
text->setText(str);
|
||||
|
||||
osg::BoundingBox bb = text->getBound();
|
||||
cursor.z() = bb.zMin()-layoutCharacterSize;
|
||||
|
||||
geode->addDrawable(text);
|
||||
|
||||
return geode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
osg::Node* createDefaultPresentation()
|
||||
{
|
||||
osg::Switch* presentation = new osg::Switch;
|
||||
presentation->setName("Presentation default");
|
||||
|
||||
float width = 1280.0f;
|
||||
float height = 1024.0f;
|
||||
|
||||
osg::Geometry* backgroundQuad = osg::createTexturedQuadGeometry(osg::Vec3(0.0f,0.0f,0.0f),
|
||||
osg::Vec3(width,0.0f,0.0f),
|
||||
osg::Vec3(0.0f,0.0f,height));
|
||||
|
||||
osg::Geode* background = new osg::Geode;
|
||||
|
||||
osg::StateSet* backgroundStateSet = background->getOrCreateStateSet();
|
||||
backgroundStateSet->setAttributeAndModes(
|
||||
new osg::PolygonOffset(1.0f,1.0f),
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
backgroundStateSet->setTextureAttributeAndModes(0,
|
||||
new osg::Texture2D(osgDB::readImageFile("lz.rgb")),
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
background->addDrawable(backgroundQuad);
|
||||
|
||||
osg::Geode* background2 = new osg::Geode;
|
||||
|
||||
background2->getOrCreateStateSet()->setTextureAttributeAndModes(0,
|
||||
new osg::Texture2D(osgDB::readImageFile("reflect.rgb")),
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
background2->addDrawable(backgroundQuad);
|
||||
|
||||
{
|
||||
osg::Switch* slide = new osg::Switch;
|
||||
slide->setName("Slide 0");
|
||||
|
||||
osg::Vec3 cursor(width*0.25f,0.0f,height*.75f);
|
||||
|
||||
osg::Group* layer_0 = new osg::Group;
|
||||
{
|
||||
|
||||
layer_0->setName("Layer 0");
|
||||
layer_0->addChild(background);
|
||||
layer_0->addChild(createText(cursor,"The is layer 0"));
|
||||
|
||||
slide->addChild(layer_0);
|
||||
}
|
||||
|
||||
osg::Group* layer_1 = new osg::Group;
|
||||
{
|
||||
layer_1->setName("Layer 1");
|
||||
layer_1->addChild(layer_0);
|
||||
layer_1->addChild(createText(cursor,"The is layer 1"));
|
||||
|
||||
slide->addChild(layer_1);
|
||||
}
|
||||
|
||||
osg::Group* layer_2 = new osg::Group;
|
||||
{
|
||||
layer_2->setName("Layer 2");
|
||||
layer_2->addChild(layer_1);
|
||||
layer_2->addChild(createText(cursor,"The is layer 2\nWe can have multiple lines of text..."));
|
||||
|
||||
slide->addChild(layer_2);
|
||||
}
|
||||
|
||||
{
|
||||
osg::Group* layer_3 = new osg::Group;
|
||||
layer_3->setName("Layer 3");
|
||||
|
||||
layer_3->addChild(layer_2);
|
||||
|
||||
layer_3->addChild(createText(cursor,"The is layer 3, with cow.osg"));
|
||||
|
||||
layer_3->addChild(createPositionedAndScaledModel(osgDB::readNodeFile("cow.osg"),
|
||||
osg::Vec3(600.0f,0.0f,300.0f),500.0f,
|
||||
osg::Quat()));
|
||||
|
||||
slide->addChild(layer_3);
|
||||
}
|
||||
|
||||
presentation->addChild(slide);
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
osg::Switch* slide = new osg::Switch;
|
||||
slide->setName("Slide 1");
|
||||
|
||||
{
|
||||
osg::Group* group = new osg::Group;
|
||||
group->setName("Layer 0");
|
||||
|
||||
group->addChild(background);
|
||||
|
||||
group->addChild(createPositionedAndScaledModel(osgDB::readNodeFile("glider.osg"),
|
||||
osg::Vec3(600.0f,0.0f,600.0f),500.0f,
|
||||
osg::Quat()));
|
||||
|
||||
slide->addChild(group);
|
||||
}
|
||||
|
||||
{
|
||||
osg::Group* group = new osg::Group;
|
||||
group->setName("Layer 1");
|
||||
|
||||
group->addChild(background2);
|
||||
|
||||
group->addChild(createPositionedAndScaledModel(osgDB::readNodeFile("Town.osg"),
|
||||
osg::Vec3(600.0f,0.0f,600.0f),500.0f,
|
||||
osg::Quat()));
|
||||
|
||||
slide->addChild(group);
|
||||
}
|
||||
|
||||
presentation->addChild(slide);
|
||||
|
||||
}
|
||||
|
||||
return presentation;
|
||||
}
|
||||
24
examples/slideshow3D/GNUmakefile
Normal file
24
examples/slideshow3D/GNUmakefile
Normal file
@@ -0,0 +1,24 @@
|
||||
TOPDIR = ../..
|
||||
include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
SlideShowConstructor.cpp\
|
||||
SlideEventHandler.cpp\
|
||||
DefaultPresentation.cpp\
|
||||
ReaderWriterXML.cpp\
|
||||
slideshow3D.cpp\
|
||||
|
||||
CXXFLAGS += -I/usr/include/libxml2
|
||||
LIBS += -lxml2 -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
|
||||
|
||||
INSTFILES = \
|
||||
$(CXXFILES)\
|
||||
GNUmakefile.inst=GNUmakefile
|
||||
|
||||
EXEC = slideshow3D
|
||||
|
||||
INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include
|
||||
LDFLAGS += $(PRODUCER_LIB_DIR)
|
||||
|
||||
include $(TOPDIR)/Make/makerules
|
||||
|
||||
19
examples/slideshow3D/GNUmakefile.inst
Normal file
19
examples/slideshow3D/GNUmakefile.inst
Normal file
@@ -0,0 +1,19 @@
|
||||
TOPDIR = ../..
|
||||
include $(TOPDIR)/Make/makedefs
|
||||
|
||||
CXXFILES =\
|
||||
SlideShowConstructor.cpp\
|
||||
SlideEventHandler.cpp\
|
||||
DefaultPresentation.cpp\
|
||||
ReaderWriterXML.cpp\
|
||||
slideshow3D.cpp\
|
||||
|
||||
CXXFLAGS += -I/usr/include/libxml2
|
||||
LIBS += -lxml2 -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS)
|
||||
|
||||
EXEC = slideshow3D
|
||||
|
||||
INC += $(PRODUCER_INCLUDE_DIR) -I/usr/X11R6/include
|
||||
LDFLAGS += $(PRODUCER_LIB_DIR)
|
||||
|
||||
include $(TOPDIR)/Make/makerules
|
||||
256
examples/slideshow3D/ReaderWriterXML.cpp
Normal file
256
examples/slideshow3D/ReaderWriterXML.cpp
Normal file
@@ -0,0 +1,256 @@
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/Registry>
|
||||
|
||||
#include "SlideShowConstructor.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/parser.h>
|
||||
|
||||
|
||||
/**
|
||||
* OpenSceneGraph plugin wrapper/converter.
|
||||
*/
|
||||
class ReaderWriterSS3D : public osgDB::ReaderWriter
|
||||
{
|
||||
public:
|
||||
ReaderWriterSS3D() { }
|
||||
|
||||
virtual const char* className()
|
||||
{
|
||||
return "slideshow3D XML Reader/Writer";
|
||||
}
|
||||
|
||||
virtual bool acceptsExtension(const std::string& extension)
|
||||
{
|
||||
return osgDB::equalCaseInsensitive(extension,"ss3d") ||
|
||||
osgDB::equalCaseInsensitive(extension,"xml") ;
|
||||
}
|
||||
|
||||
virtual ReadResult readNode(const std::string& fileName,
|
||||
const osgDB::ReaderWriter::Options* options);
|
||||
|
||||
|
||||
void parseModel(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur);
|
||||
|
||||
void parseLayer(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur);
|
||||
|
||||
void parseSlide (SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur);
|
||||
|
||||
osg::Vec4 mapStringToColor(const std::string& str)
|
||||
{
|
||||
if (str=="BLACK") return osg::Vec4(0.0f,0.0f,0.0f,1.0f);
|
||||
else return osg::Vec4(1.0f,1.0f,1.0f,1.0f);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// Register with Registry to instantiate the above reader/writer.
|
||||
osgDB::RegisterReaderWriterProxy<ReaderWriterSS3D> g_readerWriter_SS3D_Proxy;
|
||||
|
||||
|
||||
void ReaderWriterSS3D::parseModel(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur)
|
||||
{
|
||||
std::string filename;
|
||||
float scale = 1.0f;
|
||||
float rotation = 0.0f;
|
||||
float position = 0.5f;
|
||||
|
||||
printf(" new model\n");
|
||||
xmlChar *key;
|
||||
cur = cur->xmlChildrenNode;
|
||||
while (cur != NULL)
|
||||
{
|
||||
if ((!xmlStrcmp(cur->name, (const xmlChar *)"filename")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
printf(" filename: %s\n", key);
|
||||
xmlFree(key);
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"scale")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
printf(" scale: %s\n", key);
|
||||
xmlFree(key);
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"rotation")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
printf(" rotation: %s\n", key);
|
||||
xmlFree(key);
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"position")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
printf(" position: %s\n", key);
|
||||
xmlFree(key);
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
if (!filename.empty()) constructor.addModel(filename,scale,rotation,position);
|
||||
}
|
||||
|
||||
void ReaderWriterSS3D::parseLayer(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur)
|
||||
{
|
||||
constructor.addLayer();
|
||||
|
||||
printf(" new layer\n");
|
||||
xmlChar *key;
|
||||
cur = cur->xmlChildrenNode;
|
||||
while (cur != NULL)
|
||||
{
|
||||
if ((!xmlStrcmp(cur->name, (const xmlChar *)"bullet")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
constructor.addBullet((const char*)key);
|
||||
printf(" bullet: %s\n", key);
|
||||
xmlFree(key);
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"paragraph")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
printf(" paragraph: %s\n", key);
|
||||
constructor.addParagraph((const char*)key);
|
||||
xmlFree(key);
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"image")))
|
||||
{
|
||||
std::string filename;
|
||||
float height = 1.0f;
|
||||
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
printf(" image: %s\n", key);
|
||||
filename = (const char*)key;
|
||||
xmlFree(key);
|
||||
|
||||
key = xmlGetProp (cur, (const xmlChar *)"height");
|
||||
if (key)
|
||||
{
|
||||
printf(" height: %s\n", key);
|
||||
height = atoi((const char*)key);
|
||||
xmlFree(key);
|
||||
}
|
||||
|
||||
constructor.addImage(filename,height);
|
||||
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"model")))
|
||||
{
|
||||
parseModel(constructor, doc,cur);
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ReaderWriterSS3D::parseSlide (SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur)
|
||||
{
|
||||
|
||||
printf("new slide\n");
|
||||
|
||||
constructor.addSlide();
|
||||
|
||||
xmlChar *key;
|
||||
cur = cur->xmlChildrenNode;
|
||||
while (cur != NULL)
|
||||
{
|
||||
if ((!xmlStrcmp(cur->name, (const xmlChar *)"title")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
constructor.setSlideTitle((const char*)key);
|
||||
printf(" title: %s\n", key);
|
||||
xmlFree(key);
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"background")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
constructor.setSlideBackground((const char*)key);
|
||||
printf(" background: %s\n", key);
|
||||
xmlFree(key);
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"layer")))
|
||||
{
|
||||
parseLayer (constructor, doc, cur);
|
||||
}
|
||||
cur = cur->next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
osgDB::ReaderWriter::ReadResult ReaderWriterSS3D::readNode(const std::string& fileName,
|
||||
const osgDB::ReaderWriter::Options* options)
|
||||
{
|
||||
std::string ext = osgDB::getLowerCaseFileExtension(fileName);
|
||||
if (!acceptsExtension(ext))
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
|
||||
|
||||
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr cur;
|
||||
|
||||
doc = xmlParseFile(fileName.c_str());
|
||||
|
||||
if (doc == NULL ) {
|
||||
fprintf(stderr,"Document not parsed successfully. \n");
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
|
||||
cur = xmlDocGetRootElement(doc);
|
||||
|
||||
if (cur == NULL) {
|
||||
fprintf(stderr,"empty document\n");
|
||||
xmlFreeDoc(doc);
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
|
||||
if (xmlStrcmp(cur->name, (const xmlChar *) "presentation")) {
|
||||
fprintf(stderr,"document of the wrong type, root node != story");
|
||||
xmlFreeDoc(doc);
|
||||
return ReadResult::FILE_NOT_HANDLED;
|
||||
}
|
||||
|
||||
SlideShowConstructor constructor;
|
||||
|
||||
xmlChar *key;
|
||||
cur = cur->xmlChildrenNode;
|
||||
while (cur != NULL) {
|
||||
|
||||
if ((!xmlStrcmp(cur->name, (const xmlChar *)"name")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
constructor.setPresentationName((const char*)key);
|
||||
printf("name: %s\n", key);
|
||||
xmlFree(key);
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"bgcolor")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
constructor.setBackgroundColor(mapStringToColor((const char*)key));
|
||||
printf("bgcolor: %s\n", key);
|
||||
xmlFree(key);
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"textcolor")))
|
||||
{
|
||||
key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
|
||||
constructor.setTextColor(mapStringToColor((const char*)key));
|
||||
printf("textcolor: %s\n", key);
|
||||
xmlFree(key);
|
||||
}
|
||||
else if ((!xmlStrcmp(cur->name, (const xmlChar *)"slide")))
|
||||
{
|
||||
parseSlide (constructor, doc, cur);
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
|
||||
return constructor.takePresentation();
|
||||
}
|
||||
|
||||
274
examples/slideshow3D/SlideEventHandler.cpp
Normal file
274
examples/slideshow3D/SlideEventHandler.cpp
Normal file
@@ -0,0 +1,274 @@
|
||||
#include "SlideEventHandler.h"
|
||||
|
||||
class FindNamedSwitchVisitor : public osg::NodeVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
FindNamedSwitchVisitor(const std::string& name):
|
||||
osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
|
||||
_name(name),
|
||||
_switch(0) {}
|
||||
|
||||
void apply(osg::Switch& sw)
|
||||
{
|
||||
if (sw.getName().find(_name)!=std::string::npos)
|
||||
{
|
||||
_switch = &sw;
|
||||
return; // note, no need to do traverse now we've located the relevant switch
|
||||
}
|
||||
|
||||
traverse(sw);
|
||||
}
|
||||
|
||||
std::string _name;
|
||||
osg::Switch* _switch;
|
||||
|
||||
};
|
||||
|
||||
|
||||
SlideEventHandler::SlideEventHandler():
|
||||
_presentationSwitch(0),
|
||||
_activeSlide(0),
|
||||
_slideSwitch(0),
|
||||
_activeLayer(0),
|
||||
_firstTraversal(true),
|
||||
_previousTime(-1.0f),
|
||||
_timePerSlide(1.0),
|
||||
_autoSteppingActive(false),
|
||||
_loopPresentation(true),
|
||||
_pause(false)
|
||||
{
|
||||
}
|
||||
|
||||
void SlideEventHandler::set(osg::Node* model)
|
||||
{
|
||||
FindNamedSwitchVisitor findPresentation("Presentation");
|
||||
model->accept(findPresentation);
|
||||
|
||||
if (findPresentation._switch)
|
||||
{
|
||||
std::cout<<"Found presenation '"<<model->getName()<<"'"<<std::endl;
|
||||
_presentationSwitch = findPresentation._switch;
|
||||
selectSlide(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout<<"Not found presenation "<<std::endl;
|
||||
|
||||
_presentationSwitch = 0;
|
||||
_activeSlide = 0;
|
||||
|
||||
FindNamedSwitchVisitor findSlide("Slide");
|
||||
model->accept(findSlide);
|
||||
|
||||
if (findSlide._switch)
|
||||
{
|
||||
std::cout<<"Found presenation slide"<<findSlide._switch->getName()<<std::endl;
|
||||
|
||||
_slideSwitch = findSlide._switch;
|
||||
selectLayer(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout<<"Not found slide either "<<std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool SlideEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
|
||||
{
|
||||
switch(ea.getEventType())
|
||||
{
|
||||
case(osgGA::GUIEventAdapter::FRAME):
|
||||
{
|
||||
if (_autoSteppingActive)
|
||||
{
|
||||
double time = ea.time();
|
||||
|
||||
if (_firstTraversal)
|
||||
{
|
||||
_firstTraversal = false;
|
||||
_previousTime = time;
|
||||
}
|
||||
else if (time-_previousTime>_timePerSlide)
|
||||
{
|
||||
_previousTime = time;
|
||||
|
||||
nextLayerOrSlide();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
case(osgGA::GUIEventAdapter::KEYDOWN):
|
||||
{
|
||||
if (ea.getKey()=='a')
|
||||
{
|
||||
_autoSteppingActive = !_autoSteppingActive;
|
||||
_previousTime = ea.time();
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Home ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Home)
|
||||
{
|
||||
_autoSteppingActive = false;
|
||||
selectSlide(0);
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_End ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_End)
|
||||
{
|
||||
_autoSteppingActive = false;
|
||||
selectSlide(LAST_POSITION,LAST_POSITION);
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='n' ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_Down ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Down)
|
||||
{
|
||||
_autoSteppingActive = false;
|
||||
nextLayerOrSlide();
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='p' ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_Up ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Up)
|
||||
{
|
||||
_autoSteppingActive = false;
|
||||
previousLayerOrSlide();
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='N' ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_Right ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Right ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Down ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Down)
|
||||
{
|
||||
_autoSteppingActive = false;
|
||||
nextSlide();
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()=='P' ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_Left ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Left ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_Page_Up ||
|
||||
ea.getKey()==osgGA::GUIEventAdapter::KEY_KP_Page_Up)
|
||||
{
|
||||
_autoSteppingActive = false;
|
||||
previousSlide();
|
||||
return true;
|
||||
}
|
||||
else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Pause)
|
||||
{
|
||||
_pause = !_pause;
|
||||
if (_pause) std::cout<<"Pause"<<std::endl;
|
||||
else std::cout<<"End Pause"<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SlideEventHandler::getUsage(osg::ApplicationUsage& usage) const
|
||||
{
|
||||
usage.addKeyboardMouseBinding("a","Toggle on/off the automatic advancement for image to image");
|
||||
usage.addKeyboardMouseBinding("n","Advance to next layer or slide");
|
||||
usage.addKeyboardMouseBinding("p","Move to previous layer or slide");
|
||||
}
|
||||
|
||||
bool SlideEventHandler::selectSlide(unsigned int slideNum,unsigned int layerNum)
|
||||
{
|
||||
if (!_presentationSwitch) return false;
|
||||
|
||||
if (slideNum==LAST_POSITION && _presentationSwitch->getNumChildren()>0)
|
||||
{
|
||||
slideNum = _presentationSwitch->getNumChildren()-1;
|
||||
}
|
||||
|
||||
if (slideNum>=_presentationSwitch->getNumChildren()) return false;
|
||||
|
||||
|
||||
_activeSlide = slideNum;
|
||||
_presentationSwitch->setSingleChildOn(_activeSlide);
|
||||
|
||||
//std::cout<<"Selected slide '"<<_presentationSwitch->getChild(_activeSlide)->getName()<<"'"<<std::endl;
|
||||
|
||||
|
||||
FindNamedSwitchVisitor findSlide("Slide");
|
||||
_presentationSwitch->getChild(_activeSlide)->accept(findSlide);
|
||||
|
||||
if (findSlide._switch)
|
||||
{
|
||||
//std::cout<<"Found slide '"<<findSlide._switch->getName()<<"'"<<std::endl;
|
||||
_slideSwitch = findSlide._switch;
|
||||
return selectLayer(layerNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cout<<"Not found slide"<<std::endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool SlideEventHandler::selectLayer(unsigned int layerNum)
|
||||
{
|
||||
if (!_slideSwitch) return false;
|
||||
|
||||
if (layerNum==LAST_POSITION && _slideSwitch->getNumChildren()>0)
|
||||
{
|
||||
layerNum = _slideSwitch->getNumChildren()-1;
|
||||
}
|
||||
|
||||
if (layerNum>=_slideSwitch->getNumChildren()) return false;
|
||||
|
||||
_activeLayer = layerNum;
|
||||
_slideSwitch->setSingleChildOn(_activeLayer);
|
||||
|
||||
//std::cout<<"Selected layer '"<<_slideSwitch->getChild(_activeLayer)->getName()<<"' num="<<_activeLayer<< std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SlideEventHandler::nextLayerOrSlide()
|
||||
{
|
||||
if (nextLayer()) return true;
|
||||
else return nextSlide();
|
||||
}
|
||||
|
||||
bool SlideEventHandler::previousLayerOrSlide()
|
||||
{
|
||||
if (previousLayer()) return true;
|
||||
else return previousSlide();
|
||||
}
|
||||
|
||||
bool SlideEventHandler::nextSlide()
|
||||
{
|
||||
if (selectSlide(_activeSlide+1)) return true;
|
||||
else if (_loopPresentation) return selectSlide(0);
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool SlideEventHandler::previousSlide()
|
||||
{
|
||||
if (_activeSlide>0) return selectSlide(_activeSlide-1,LAST_POSITION);
|
||||
else if (_loopPresentation && _presentationSwitch.valid()) return selectSlide(_presentationSwitch->getNumChildren()-1,LAST_POSITION);
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool SlideEventHandler::nextLayer()
|
||||
{
|
||||
return selectLayer(_activeLayer+1);
|
||||
}
|
||||
|
||||
bool SlideEventHandler::previousLayer()
|
||||
{
|
||||
if (_activeLayer>0) return selectLayer(_activeLayer-1);
|
||||
else return false;
|
||||
}
|
||||
78
examples/slideshow3D/SlideEventHandler.h
Normal file
78
examples/slideshow3D/SlideEventHandler.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SLIDEEVENTHANDLER
|
||||
#define SLIDEEVENTHANDLER 1
|
||||
|
||||
#include <osg/Switch>
|
||||
|
||||
#include <osgGA/GUIEventHandler>
|
||||
|
||||
class SlideEventHandler : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
|
||||
SlideEventHandler();
|
||||
|
||||
META_Object(osgslideshowApp,SlideEventHandler);
|
||||
|
||||
void set(osg::Node* model);
|
||||
|
||||
virtual void accept(osgGA::GUIEventHandlerVisitor& v) { v.visit(*this); }
|
||||
|
||||
virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&);
|
||||
|
||||
virtual void getUsage(osg::ApplicationUsage& usage) const;
|
||||
|
||||
enum WhichPosition
|
||||
{
|
||||
FIRST_POSITION = 0,
|
||||
LAST_POSITION = 0xffffffff,
|
||||
};
|
||||
|
||||
bool selectSlide(unsigned int slideNum,unsigned int layerNum=FIRST_POSITION);
|
||||
bool selectLayer(unsigned int layerNum);
|
||||
|
||||
bool nextLayerOrSlide();
|
||||
bool previousLayerOrSlide();
|
||||
|
||||
bool nextSlide();
|
||||
bool previousSlide();
|
||||
|
||||
bool nextLayer();
|
||||
bool previousLayer();
|
||||
|
||||
protected:
|
||||
|
||||
~SlideEventHandler() {}
|
||||
SlideEventHandler(const SlideEventHandler&,const osg::CopyOp&) {}
|
||||
|
||||
osg::ref_ptr<osg::Switch> _presentationSwitch;
|
||||
unsigned int _activeSlide;
|
||||
|
||||
osg::ref_ptr<osg::Switch> _slideSwitch;
|
||||
unsigned int _activeLayer;
|
||||
|
||||
bool _firstTraversal;
|
||||
double _previousTime;
|
||||
double _timePerSlide;
|
||||
bool _autoSteppingActive;
|
||||
bool _loopPresentation;
|
||||
bool _pause;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
262
examples/slideshow3D/SlideShowConstructor.cpp
Normal file
262
examples/slideshow3D/SlideShowConstructor.cpp
Normal file
@@ -0,0 +1,262 @@
|
||||
#include "SlideShowConstructor.h"
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/PolygonOffset>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/MatrixTransform>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
|
||||
#include <osgText/Text>
|
||||
|
||||
|
||||
SlideShowConstructor::SlideShowConstructor()
|
||||
{
|
||||
_slideOrigin.set(0.0f,0.0f,0.0f);
|
||||
_slideWidth = 1280.0f;
|
||||
_slideHeight = 1024.0f;
|
||||
|
||||
_backgroundColor.set(0.0f,0.0f,0.0f,1.0f);
|
||||
_textColor.set(1.0f,1.0f,1.0f,1.0f);
|
||||
_textFont = "fonts/arial.ttf";
|
||||
|
||||
}
|
||||
|
||||
void SlideShowConstructor::createPresentation()
|
||||
{
|
||||
_titleHeight = _slideHeight*0.08f;
|
||||
_titleOrigin = _slideOrigin + osg::Vec3(_slideWidth*0.5f,0.0f,_slideHeight*0.98f-_titleHeight);
|
||||
|
||||
_textHeight = _slideHeight*0.05f;
|
||||
|
||||
_textOrigin = _slideOrigin + osg::Vec3(_slideWidth*0.1f,0.0f,_titleOrigin.z()-2*_textHeight);
|
||||
_imageOrigin = _slideOrigin + osg::Vec3(_slideWidth*0.7f,0.0f,_titleOrigin.z()*0.5f);
|
||||
_modelLeft = _slideOrigin + osg::Vec3(_slideWidth*0.0f,0.0f,_titleOrigin.z()*0.5f);
|
||||
_modelRight = _slideOrigin + osg::Vec3(_slideWidth*1.0f,0.0f,_titleOrigin.z()*0.5f);
|
||||
|
||||
_root = new osg::ClearNode;
|
||||
_root->setClearColor(_backgroundColor);
|
||||
|
||||
_presentationSwitch = new osg::Switch;
|
||||
_presentationSwitch->setName(std::string("Presentation_")+_presentationName);
|
||||
|
||||
_root->addChild(_presentationSwitch.get());
|
||||
|
||||
}
|
||||
|
||||
void SlideShowConstructor::setBackgroundColor(const osg::Vec4& color)
|
||||
{
|
||||
_backgroundColor = color;
|
||||
if (_root.valid()) _root->setClearColor(_backgroundColor);
|
||||
}
|
||||
|
||||
void SlideShowConstructor::setTextColor(const osg::Vec4& color)
|
||||
{
|
||||
_textColor = color;
|
||||
}
|
||||
|
||||
void SlideShowConstructor::setPresentationName(const std::string& name)
|
||||
{
|
||||
_presentationName = name;
|
||||
if (_presentationSwitch.valid()) _presentationSwitch->setName(std::string("Presentation_")+_presentationName);
|
||||
}
|
||||
|
||||
|
||||
void SlideShowConstructor::addSlide()
|
||||
{
|
||||
if (!_presentationSwitch) createPresentation();
|
||||
|
||||
// reset cursors
|
||||
_textCursor = _textOrigin;
|
||||
_imageCursor = _imageOrigin;
|
||||
_modelCursor = _modelLeft*0.5f + _modelRight*0.5f;
|
||||
|
||||
_slide = new osg::Switch;
|
||||
_slide->setName(std::string("Slide_")+_slideTitle);
|
||||
|
||||
_presentationSwitch->addChild(_slide.get());
|
||||
|
||||
_previousLayer = 0;
|
||||
_currentLayer = 0;
|
||||
}
|
||||
|
||||
void SlideShowConstructor::addLayer()
|
||||
{
|
||||
if (!_slide) addSlide();
|
||||
|
||||
_previousLayer = _currentLayer;
|
||||
|
||||
_currentLayer = new osg::Group;
|
||||
|
||||
_slide->addChild(_currentLayer.get());
|
||||
|
||||
if (!_previousLayer)
|
||||
{
|
||||
// create the background and title..
|
||||
if (!_slideBackgroundImageFileName.empty())
|
||||
{
|
||||
osg::Geometry* backgroundQuad = osg::createTexturedQuadGeometry(_slideOrigin,
|
||||
osg::Vec3(_slideWidth,0.0f,0.0f),
|
||||
osg::Vec3(0.0f,0.0f,_slideHeight));
|
||||
|
||||
osg::Geode* background = new osg::Geode;
|
||||
|
||||
osg::StateSet* backgroundStateSet = background->getOrCreateStateSet();
|
||||
backgroundStateSet->setAttributeAndModes(
|
||||
new osg::PolygonOffset(1.0f,1.0f),
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
backgroundStateSet->setTextureAttributeAndModes(0,
|
||||
new osg::Texture2D(osgDB::readImageFile(_slideBackgroundImageFileName)),
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
background->addDrawable(backgroundQuad);
|
||||
|
||||
_currentLayer->addChild(background);
|
||||
}
|
||||
|
||||
if (!_slideTitle.empty())
|
||||
{
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
|
||||
osgText::Text* text = new osgText::Text;
|
||||
text->setFont(_textFont);
|
||||
text->setColor(_textColor);
|
||||
text->setCharacterSize(_titleHeight);
|
||||
text->setAxisAlignment(osgText::Text::XZ_PLANE);
|
||||
text->setAlignment(osgText::Text::CENTER_BASE_LINE);
|
||||
text->setPosition(_titleOrigin);
|
||||
|
||||
text->setText(_slideTitle);
|
||||
|
||||
geode->addDrawable(text);
|
||||
|
||||
_currentLayer->addChild(geode);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// copy previous layer's children across into new layer.
|
||||
for(unsigned int i=0;i<_previousLayer->getNumChildren();++i)
|
||||
{
|
||||
_currentLayer->addChild(_previousLayer->getChild(i));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SlideShowConstructor::addBullet(const std::string& bullet)
|
||||
{
|
||||
if (!_currentLayer) addLayer();
|
||||
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
|
||||
osgText::Text* text = new osgText::Text;
|
||||
|
||||
text->setFont(_textFont);
|
||||
text->setColor(_textColor);
|
||||
text->setCharacterSize(_textHeight);
|
||||
text->setAxisAlignment(osgText::Text::XZ_PLANE);
|
||||
text->setAlignment(osgText::Text::BASE_LINE);
|
||||
text->setPosition(_textCursor);
|
||||
|
||||
text->setText(bullet);
|
||||
|
||||
osg::BoundingBox bb = text->getBound();
|
||||
_textCursor.z() = bb.zMin()-_textHeight;
|
||||
|
||||
geode->addDrawable(text);
|
||||
|
||||
_currentLayer->addChild(geode);
|
||||
|
||||
}
|
||||
|
||||
void SlideShowConstructor::addParagraph(const std::string& paragraph)
|
||||
{
|
||||
if (!_currentLayer) addLayer();
|
||||
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
|
||||
osgText::Text* text = new osgText::Text;
|
||||
|
||||
text->setFont(_textFont);
|
||||
text->setColor(_textColor);
|
||||
text->setCharacterSize(_textHeight);
|
||||
text->setAxisAlignment(osgText::Text::XZ_PLANE);
|
||||
text->setAlignment(osgText::Text::BASE_LINE);
|
||||
text->setPosition(_textCursor);
|
||||
|
||||
text->setText(paragraph);
|
||||
|
||||
osg::BoundingBox bb = text->getBound();
|
||||
_textCursor.z() = bb.zMin()-_textHeight;
|
||||
|
||||
geode->addDrawable(text);
|
||||
|
||||
_currentLayer->addChild(geode);
|
||||
}
|
||||
|
||||
void SlideShowConstructor::addImage(const std::string& filename,float height)
|
||||
{
|
||||
if (!_currentLayer) addLayer();
|
||||
|
||||
osg::Image* image = osgDB::readImageFile(filename);
|
||||
|
||||
if (!image) return;
|
||||
|
||||
float s = image->s();
|
||||
float t = image->t();
|
||||
|
||||
float image_height = _slideHeight*0.6f;
|
||||
float image_width = image_height*s/t;
|
||||
|
||||
osg::Vec3 pos = _imageCursor + osg::Vec3(-image_width*0.5f,-height*image_height*0.1f,-image_height*0.5f);
|
||||
|
||||
osg::Geometry* backgroundQuad = osg::createTexturedQuadGeometry(pos,
|
||||
osg::Vec3(image_width,0.0f,0.0f),
|
||||
osg::Vec3(0.0f,0.0f,image_height));
|
||||
|
||||
osg::Geode* background = new osg::Geode;
|
||||
|
||||
osg::StateSet* backgroundStateSet = background->getOrCreateStateSet();
|
||||
|
||||
backgroundStateSet->setTextureAttributeAndModes(0,
|
||||
new osg::Texture2D(image),
|
||||
osg::StateAttribute::ON);
|
||||
|
||||
background->addDrawable(backgroundQuad);
|
||||
|
||||
_currentLayer->addChild(background);
|
||||
}
|
||||
|
||||
void SlideShowConstructor::addModel(const std::string& filename,float scale,float rotation,float position)
|
||||
{
|
||||
if (!_currentLayer) addLayer();
|
||||
|
||||
osg::Node* model = osgDB::readNodeFile(filename);
|
||||
|
||||
if (!model) return;
|
||||
|
||||
osg::Vec3 pos = _modelLeft*(1.0f-position) + _modelRight*position;
|
||||
float radius = scale*_slideHeight*0.7f;
|
||||
osg::Quat quat;
|
||||
quat.makeRotate(osg::DegreesToRadians(rotation),0.0f,0.0f,1.0f);
|
||||
|
||||
osg::MatrixTransform* transform = new osg::MatrixTransform;
|
||||
|
||||
const osg::BoundingSphere& bs = model->getBound();
|
||||
|
||||
transform->setDataVariance(osg::Object::STATIC);
|
||||
transform->setMatrix(osg::Matrix::translate(-bs.center())*
|
||||
osg::Matrix::scale(radius/bs.radius(),radius/bs.radius(),radius/bs.radius())*
|
||||
osg::Matrix::rotate(quat)*
|
||||
osg::Matrix::translate(pos));
|
||||
|
||||
transform->addChild(model);
|
||||
|
||||
_currentLayer->addChild(transform);
|
||||
|
||||
}
|
||||
|
||||
86
examples/slideshow3D/SlideShowConstructor.h
Normal file
86
examples/slideshow3D/SlideShowConstructor.h
Normal file
@@ -0,0 +1,86 @@
|
||||
#ifndef SLIDESHOWCONSTUCTOR
|
||||
#define SLIDESHOWCONSTRUCTOR
|
||||
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec4>
|
||||
#include <osg/Group>
|
||||
#include <osg/ClearNode>
|
||||
#include <osg/Switch>
|
||||
|
||||
class SlideShowConstructor
|
||||
{
|
||||
public:
|
||||
|
||||
SlideShowConstructor();
|
||||
|
||||
void createPresentation();
|
||||
|
||||
void setBackgroundColor(const osg::Vec4& color);
|
||||
|
||||
void setTextColor(const osg::Vec4& color);
|
||||
|
||||
void setPresentationName(const std::string& name);
|
||||
|
||||
void addSlide();
|
||||
|
||||
void setSlideTitle(const std::string& name) { _slideTitle = name; }
|
||||
|
||||
void setSlideBackground(const std::string& name) { _slideBackgroundImageFileName = name; }
|
||||
|
||||
void addLayer();
|
||||
|
||||
void addBullet(const std::string& bullet);
|
||||
|
||||
void addParagraph(const std::string& paragraph);
|
||||
|
||||
void addImage(const std::string& filename,float height);
|
||||
|
||||
void addModel(const std::string& filename,float scale,float rotation,float position);
|
||||
|
||||
osg::ClearNode* takePresentation() { return _root.release(); }
|
||||
|
||||
osg::ClearNode* getPresentation() { return _root.get(); }
|
||||
|
||||
osg::Switch* getPresentationSwitch() { return _presentationSwitch.get(); }
|
||||
|
||||
osg::Switch* getCurrentSlide() { return _slide.get(); }
|
||||
|
||||
osg::Group* getCurrentLayer() { return _currentLayer.get(); }
|
||||
|
||||
protected:
|
||||
|
||||
osg::Vec3 _slideOrigin;
|
||||
float _slideWidth;
|
||||
float _slideHeight;
|
||||
|
||||
osg::Vec4 _backgroundColor;
|
||||
osg::Vec4 _textColor;
|
||||
std::string _textFont;
|
||||
float _titleHeight;
|
||||
float _textHeight;
|
||||
std::string _presentationName;
|
||||
|
||||
|
||||
osg::Vec3 _titleOrigin;
|
||||
osg::Vec3 _textOrigin;
|
||||
osg::Vec3 _imageOrigin;
|
||||
osg::Vec3 _modelLeft;
|
||||
osg::Vec3 _modelRight;
|
||||
|
||||
osg::Vec3 _textCursor;
|
||||
osg::Vec3 _imageCursor;
|
||||
osg::Vec3 _modelCursor;
|
||||
|
||||
osg::ref_ptr<osg::ClearNode> _root;
|
||||
osg::ref_ptr<osg::Switch> _presentationSwitch;
|
||||
|
||||
osg::ref_ptr<osg::Switch> _slide;
|
||||
std::string _slideTitle;
|
||||
std::string _slideBackgroundImageFileName;
|
||||
|
||||
osg::ref_ptr<osg::Group> _previousLayer;
|
||||
osg::ref_ptr<osg::Group> _currentLayer;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
119
examples/slideshow3D/slideshow3D.cpp
Normal file
119
examples/slideshow3D/slideshow3D.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 Robert Osfield
|
||||
*
|
||||
* This application is open source and may be redistributed and/or modified
|
||||
* freely and without restriction, both in commericial and non commericial applications,
|
||||
* as long as this copyright notice is maintained.
|
||||
*
|
||||
* This application is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgUtil/Optimizer>
|
||||
#include <osgProducer/Viewer>
|
||||
|
||||
#include "SlideEventHandler.h"
|
||||
|
||||
extern osg::Node* createDefaultPresentation();
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
|
||||
// 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.
|
||||
arguments.getApplicationUsage()->setApplicationName(arguments.getApplicationName());
|
||||
arguments.getApplicationUsage()->setDescription(arguments.getApplicationName()+" is the standard OpenSceneGraph example which loads and visualises 3d models.");
|
||||
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] filename ...");
|
||||
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
|
||||
|
||||
|
||||
// construct the viewer.
|
||||
osgProducer::Viewer viewer(arguments);
|
||||
|
||||
// set up the value with sensible default event handlers.
|
||||
viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS);
|
||||
|
||||
// get details on keyboard and mouse bindings used by the viewer.
|
||||
viewer.getUsage(*arguments.getApplicationUsage());
|
||||
|
||||
// register the slide event handler - which moves the presentation from slide to slide, layer to layer.
|
||||
SlideEventHandler* seh = new SlideEventHandler;
|
||||
viewer.getEventHandlerList().push_front(seh);
|
||||
|
||||
// if user request help write it out to cout.
|
||||
if (arguments.read("-h") || arguments.read("--help"))
|
||||
{
|
||||
arguments.getApplicationUsage()->write(std::cout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// any option left unread are 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(std::cout);
|
||||
return 1;
|
||||
}
|
||||
|
||||
osg::Timer timer;
|
||||
osg::Timer_t start_tick = timer.tick();
|
||||
|
||||
// read the scene from the list of file specified commandline args.
|
||||
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
|
||||
|
||||
// if no model loaded create a default presentation.
|
||||
if (!loadedModel)
|
||||
{
|
||||
loadedModel = createDefaultPresentation();
|
||||
}
|
||||
|
||||
|
||||
// if no model has been successfully loaded report failure.
|
||||
if (!loadedModel)
|
||||
{
|
||||
std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
osg::Timer_t end_tick = timer.tick();
|
||||
|
||||
std::cout << "Time to load = "<<timer.delta_s(start_tick,end_tick)<<std::endl;
|
||||
|
||||
// optimize the scene graph, remove rendundent nodes and state etc.
|
||||
osgUtil::Optimizer optimizer;
|
||||
optimizer.optimize(loadedModel.get());
|
||||
|
||||
// pass the model to the slide event handler so it knows which to manipulate.
|
||||
seh->set(loadedModel.get());
|
||||
|
||||
// set the scene to render
|
||||
viewer.setSceneData(loadedModel.get());
|
||||
|
||||
// create the windows and run the threads.
|
||||
viewer.realize();
|
||||
|
||||
while( !viewer.done() )
|
||||
{
|
||||
// wait for all cull and draw threads to complete.
|
||||
viewer.sync();
|
||||
|
||||
// update the scene by traversing it with the the update visitor which will
|
||||
// call all node update callbacks and animations.
|
||||
viewer.update();
|
||||
|
||||
// fire off the cull and draw traversals of the scene.
|
||||
viewer.frame();
|
||||
|
||||
}
|
||||
|
||||
// wait for all cull and draw threads to complete before exit.
|
||||
viewer.sync();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user