Added support for correct sizing of the created presentation w.r.t the

size of the scene, a default home position, handling of <ratio> field
in the slideshow xml file, and support for stereo image pairs.
This commit is contained in:
Robert Osfield
2003-09-15 13:54:19 +00:00
parent c1d2d67d66
commit 3ae5b72030
7 changed files with 246 additions and 204 deletions

View File

@@ -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

View File

@@ -1,178 +0,0 @@
#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;
}

View File

@@ -5,7 +5,6 @@ CXXFILES =\
SlideShowConstructor.cpp\
SlideEventHandler.cpp\
PointsEventHandler.cpp\
DefaultPresentation.cpp\
ReaderWriterXML.cpp\
slideshow3D.cpp\

View File

@@ -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);

View File

@@ -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"<<std::endl;
std::cout<<" valid types are \"Reality Theatre\", \"Desktop\" or a numerical value."<<std::endl;
}
}
}
void SlideShowConstructor::createPresentation()
{
_titleHeight = _slideHeight*0.08f;
@@ -45,6 +68,17 @@ void SlideShowConstructor::createPresentation()
_root->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<osg::Image> imageLeft = osgDB::readImageFile(filenameLeft);
osg::ref_ptr<osg::Image> 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)

View File

@@ -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(); }

View File

@@ -13,11 +13,65 @@
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osgProducer/Viewer>
#include <osgGA/TrackballManipulator>
#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<SlideShowConstructor::HomePosition*>(node.getUserData());
if (homePosition)
{
_homePosition = homePosition;
}
traverse(node);
}
osg::ref_ptr<SlideShowConstructor::HomePosition> _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<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)
{
@@ -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.