diff --git a/VisualStudio/examples/slideshow3D/slideshow3D.dsp b/VisualStudio/examples/slideshow3D/slideshow3D.dsp index 50a885ece..abf6ce46a 100644 --- a/VisualStudio/examples/slideshow3D/slideshow3D.dsp +++ b/VisualStudio/examples/slideshow3D/slideshow3D.dsp @@ -176,13 +176,6 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - - - -SOURCE=..\..\..\examples\slideshow3D\DefaultPresentation.cpp - -# End Source File # Begin Source File diff --git a/examples/slideshow3D/DefaultPresentation.cpp b/examples/slideshow3D/DefaultPresentation.cpp deleted file mode 100644 index e6427ceb9..000000000 --- a/examples/slideshow3D/DefaultPresentation.cpp +++ /dev/null @@ -1,178 +0,0 @@ -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -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; -} diff --git a/examples/slideshow3D/GNUmakefile b/examples/slideshow3D/GNUmakefile index a5ba757ba..3ef5cdcfa 100644 --- a/examples/slideshow3D/GNUmakefile +++ b/examples/slideshow3D/GNUmakefile @@ -5,7 +5,6 @@ CXXFILES =\ SlideShowConstructor.cpp\ SlideEventHandler.cpp\ PointsEventHandler.cpp\ - DefaultPresentation.cpp\ ReaderWriterXML.cpp\ slideshow3D.cpp\ diff --git a/examples/slideshow3D/ReaderWriterXML.cpp b/examples/slideshow3D/ReaderWriterXML.cpp index f2cda05a7..9dbe73179 100644 --- a/examples/slideshow3D/ReaderWriterXML.cpp +++ b/examples/slideshow3D/ReaderWriterXML.cpp @@ -46,6 +46,8 @@ public: void parseModel(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur); + void parseStereoPair(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur); + void parseLayer(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur); void parseSlide (SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur); @@ -105,6 +107,44 @@ void ReaderWriterSS3D::parseModel(SlideShowConstructor& constructor, xmlDocPtr d if (!filename.empty()) constructor.addModel(filename,scale,rotation,position); } +void ReaderWriterSS3D::parseStereoPair(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur) +{ + std::string filenameLeft; + std::string filenameRight; + + float height = 1.0f; + xmlChar *key; + key = xmlGetProp (cur, (const xmlChar *)"height"); + if (key) height = atoi((const char*)key); + xmlFree(key); + + cur = cur->xmlChildrenNode; + + while (cur != NULL) + { + if ((!xmlStrcmp(cur->name, (const xmlChar *)"image_left"))) + { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + if (key) filenameLeft = (const char*)key; + xmlFree(key); + + + } + if ((!xmlStrcmp(cur->name, (const xmlChar *)"image_right"))) + { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + if (key) filenameRight = (const char*)key; + xmlFree(key); + + } + cur = cur->next; + } + + if (!filenameLeft.empty() && !filenameRight.empty()) + constructor.addStereoImagePair(filenameLeft,filenameRight,height); + +} + void ReaderWriterSS3D::parseLayer(SlideShowConstructor& constructor, xmlDocPtr doc, xmlNodePtr cur) { constructor.addLayer(); @@ -141,6 +181,10 @@ void ReaderWriterSS3D::parseLayer(SlideShowConstructor& constructor, xmlDocPtr d if (!filename.empty()) constructor.addImage(filename,height); } + else if ((!xmlStrcmp(cur->name, (const xmlChar *)"stereo_pair"))) + { + parseStereoPair(constructor, doc,cur); + } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"model"))) { parseModel(constructor, doc,cur); @@ -228,6 +272,12 @@ osgDB::ReaderWriter::ReadResult ReaderWriterSS3D::readNode(const std::string& fi else constructor.setPresentationName(""); xmlFree(key); } + else if ((!xmlStrcmp(cur->name, (const xmlChar *)"ratio"))) + { + key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); + if (key) constructor.setPresentationAspectRatio((const char*)key); + xmlFree(key); + } else if ((!xmlStrcmp(cur->name, (const xmlChar *)"bgcolor"))) { key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1); diff --git a/examples/slideshow3D/SlideShowConstructor.cpp b/examples/slideshow3D/SlideShowConstructor.cpp index d20e0673f..43379cb4c 100644 --- a/examples/slideshow3D/SlideShowConstructor.cpp +++ b/examples/slideshow3D/SlideShowConstructor.cpp @@ -14,8 +14,10 @@ SlideShowConstructor::SlideShowConstructor() { _slideOrigin.set(0.0f,0.0f,0.0f); - _slideWidth = 1280.0f; - _slideHeight = 1024.0f; + + _slideHeight = osg::DisplaySettings::instance()->getScreenHeight(); + + _slideWidth = _slideHeight*1280.0f/1024.f; _backgroundColor.set(0.0f,0.0f,0.0f,1.0f); _textColor.set(1.0f,1.0f,1.0f,1.0f); @@ -23,6 +25,27 @@ SlideShowConstructor::SlideShowConstructor() } +void SlideShowConstructor::setPresentationAspectRatio(float aspectRatio) +{ + _slideWidth = _slideHeight*aspectRatio; +} + +void SlideShowConstructor::setPresentationAspectRatio(const std::string& str) +{ + if (str=="Reality Theatre") setPresentationAspectRatio(3.0f); + else if (str=="Desktop") setPresentationAspectRatio(1280.0f/1024.0f); + else + { + float ratio = (float)atof(str.c_str()); + if (ratio!=0.0) setPresentationAspectRatio(1280.0f/1024.0f); + else + { + std::cout<<"Error: presentation aspect ratio incorrect type"<addChild(_presentationSwitch.get()); + osg::Vec3 slideCenter = _slideOrigin + osg::Vec3(_slideWidth*0.5f,0.0f,_slideHeight*0.5f); + + float distanceToHeightRatio = osg::DisplaySettings::instance()->getScreenDistance()/osg::DisplaySettings::instance()->getScreenHeight(); + + HomePosition* hp = new HomePosition; + hp->eye = slideCenter+osg::Vec3(0.0f,-distanceToHeightRatio*_slideHeight,0.0f); + hp->center = slideCenter; + hp->up.set(0.0f,0.0f,1.0f); + + _root->setUserData(hp); + } void SlideShowConstructor::setBackgroundColor(const osg::Vec4& color) @@ -220,21 +254,81 @@ void SlideShowConstructor::addImage(const std::string& filename,float height) osg::Vec3 pos = _imageCursor + osg::Vec3(-image_width*0.5f+offset,-offset,-image_height*0.5f-offset); - osg::Geometry* backgroundQuad = osg::createTexturedQuadGeometry(pos, + osg::Geometry* pictureQuad = 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::Geode* picture = new osg::Geode; - osg::StateSet* backgroundStateSet = background->getOrCreateStateSet(); + osg::StateSet* pictureStateSet = picture->getOrCreateStateSet(); - backgroundStateSet->setTextureAttributeAndModes(0, + pictureStateSet->setTextureAttributeAndModes(0, new osg::Texture2D(image), osg::StateAttribute::ON); - background->addDrawable(backgroundQuad); + picture->addDrawable(pictureQuad); - _currentLayer->addChild(background); + _currentLayer->addChild(picture); +} + +void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft,const std::string& filenameRight,float height) +{ + if (!_currentLayer) addLayer(); + + osg::ref_ptr imageLeft = osgDB::readImageFile(filenameLeft); + osg::ref_ptr imageRight = osgDB::readImageFile(filenameRight); + + if (!imageLeft && !imageRight) return; + + float s = imageLeft->s(); + float t = imageLeft->t(); + + float image_height = _slideHeight*0.6f; + float image_width = image_height*s/t; + float offset = height*image_height*0.1f; + + osg::Vec3 pos = _imageCursor + osg::Vec3(-image_width*0.5f+offset,-offset,-image_height*0.5f-offset); + + + osg::Geode* pictureLeft = new osg::Geode; + { + pictureLeft->setNodeMask(0x01); + + osg::StateSet* pictureLeftStateSet = pictureLeft->getOrCreateStateSet(); + + pictureLeftStateSet->setTextureAttributeAndModes(0, + new osg::Texture2D(imageLeft.get()), + osg::StateAttribute::ON); + + osg::Geometry* pictureLeftQuad = osg::createTexturedQuadGeometry(pos, + osg::Vec3(image_width,0.0f,0.0f), + osg::Vec3(0.0f,0.0f,image_height)); + pictureLeft->addDrawable(pictureLeftQuad); + + } + + osg::Geode* pictureRight = new osg::Geode; + { + pictureRight->setNodeMask(0x02); + + osg::StateSet* pictureRightStateSet = pictureRight->getOrCreateStateSet(); + + pictureRightStateSet->setTextureAttributeAndModes(0, + new osg::Texture2D(imageRight.get()), + osg::StateAttribute::ON); + + osg::Geometry* pictureRightQuad = osg::createTexturedQuadGeometry(pos, + osg::Vec3(image_width,0.0f,0.0f), + osg::Vec3(0.0f,0.0f,image_height)); + + pictureRight->addDrawable(pictureRightQuad); + } + + osg::Group* stereopair = new osg::Group; + stereopair->addChild(pictureLeft); + stereopair->addChild(pictureRight); + + _currentLayer->addChild(stereopair); } void SlideShowConstructor::addModel(const std::string& filename,float scale,float rotation,float position) diff --git a/examples/slideshow3D/SlideShowConstructor.h b/examples/slideshow3D/SlideShowConstructor.h index 45cc18084..f457fe786 100644 --- a/examples/slideshow3D/SlideShowConstructor.h +++ b/examples/slideshow3D/SlideShowConstructor.h @@ -13,6 +13,14 @@ public: SlideShowConstructor(); + struct HomePosition : public osg::Referenced + { + osg::Vec3 eye; + osg::Vec3 center; + osg::Vec3 up; + }; + + void createPresentation(); void setBackgroundColor(const osg::Vec4& color); @@ -21,6 +29,10 @@ public: void setPresentationName(const std::string& name); + void setPresentationAspectRatio(float aspectRatio); + + void setPresentationAspectRatio(const std::string& str); + void addSlide(); void setSlideTitle(const std::string& name) { _slideTitle = name; } @@ -35,6 +47,8 @@ public: void addImage(const std::string& filename,float height); + void addStereoImagePair(const std::string& filenameLeft,const std::string& filenameRight,float height); + void addModel(const std::string& filename,float scale,float rotation,float position); osg::ClearNode* takePresentation() { return _root.release(); } diff --git a/examples/slideshow3D/slideshow3D.cpp b/examples/slideshow3D/slideshow3D.cpp index f6ac6183a..05b87724a 100644 --- a/examples/slideshow3D/slideshow3D.cpp +++ b/examples/slideshow3D/slideshow3D.cpp @@ -13,11 +13,65 @@ #include #include #include +#include #include "SlideEventHandler.h" #include "PointsEventHandler.h" +#include "SlideShowConstructor.h" + + +class FindHomePositionVisitor : public osg::NodeVisitor +{ +public: + + FindHomePositionVisitor(): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} + + void apply(osg::Node& node) + { + SlideShowConstructor::HomePosition* homePosition = dynamic_cast(node.getUserData()); + if (homePosition) + { + _homePosition = homePosition; + } + + traverse(node); + } + + osg::ref_ptr _homePosition; + +}; + + +class SlideShowTrackballManipulator : public osgGA::TrackballManipulator +{ + public: + + SlideShowTrackballManipulator() + { + } + + virtual void home(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& us) + { + + FindHomePositionVisitor fhpv; + if (_node.valid()) _node->accept(fhpv); + + if (fhpv._homePosition.valid()) + { + computePosition(fhpv._homePosition->eye, + fhpv._homePosition->center, + fhpv._homePosition->up); + + us.requestRedraw(); + } + else + { + TrackballManipulator::home(ea,us); + } + } +}; -extern osg::Node* createDefaultPresentation(); int main( int argc, char **argv ) { @@ -37,8 +91,18 @@ int main( int argc, char **argv ) // construct the viewer. osgProducer::Viewer viewer(arguments); - // set up the value with sensible default event handlers. - viewer.setUpViewer(osgProducer::Viewer::STANDARD_SETTINGS); + SlideShowTrackballManipulator* sstbm = new SlideShowTrackballManipulator; + + viewer.addCameraManipulator(sstbm); + + // set up the value with sensible default event handler. + viewer.setUpViewer(osgProducer::Viewer::DRIVE_MANIPULATOR | + osgProducer::Viewer::FLIGHT_MANIPULATOR | + osgProducer::Viewer::STATE_MANIPULATOR | + osgProducer::Viewer::HEAD_LIGHT_SOURCE | + osgProducer::Viewer::STATS_MANIPULATOR | + osgProducer::Viewer::VIEWER_MANIPULATOR | + osgProducer::Viewer::ESCAPE_SETS_DONE); // read any time delay argument. float timeDelayBetweenSlides = 1.5f; @@ -84,13 +148,6 @@ int main( int argc, char **argv ) // read the scene from the list of file specified commandline args. osg::ref_ptr 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) { @@ -112,6 +169,7 @@ int main( int argc, char **argv ) // set the scene to render viewer.setSceneData(loadedModel.get()); + // pass the global stateset to the point event handler so that it can // alter the point size of all points in the scene. peh->setStateSet(viewer.getGlobalStateSet()); @@ -119,6 +177,18 @@ int main( int argc, char **argv ) // create the windows and run the threads. viewer.realize(); + // set all the sceneview's up so that their left and right add cull masks are set up. + for(osgProducer::OsgCameraGroup::SceneHandlerList::iterator itr=viewer.getSceneHandlerList().begin(); + itr!=viewer.getSceneHandlerList().end(); + ++itr) + { + osgUtil::SceneView* sceneview = (*itr)->getSceneView(); + sceneview->setCullMask(0xffffffff); + sceneview->setCullMaskLeft(0x00000001); + sceneview->setCullMaskRight(0x00000002); +// sceneview->setFusionDistance(osgUtil::SceneView::USE_FUSION_DISTANCE_VALUE,radius); + } + while( !viewer.done() ) { // wait for all cull and draw threads to complete.