Added hud and billboard support to image, stereo_image, pdf, browser and vnc image placement

This commit is contained in:
Robert Osfield 2011-03-16 10:51:42 +00:00
parent f2ce2f19a9
commit 256da4879e
3 changed files with 217 additions and 85 deletions

View File

@ -32,6 +32,44 @@
namespace osgPresentation namespace osgPresentation
{ {
class OSGPRESENTATION_EXPORT HUDSettings : public osg::Referenced
{
public:
HUDSettings(double slideDistance, float eyeOffset, unsigned int leftMask, unsigned int rightMask);
virtual bool getModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const;
virtual bool getInverseModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const;
double _slideDistance;
double _eyeOffset;
unsigned int _leftMask;
unsigned int _rightMask;
protected:
virtual ~HUDSettings();
};
class OSGPRESENTATION_EXPORT HUDTransform : public osg::Transform
{
public:
HUDTransform(HUDSettings* hudSettings);
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const;
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const;
protected:
virtual ~HUDTransform();
osg::ref_ptr<HUDSettings> _hudSettings;
};
class OSGPRESENTATION_EXPORT SlideShowConstructor class OSGPRESENTATION_EXPORT SlideShowConstructor
{ {
public: public:
@ -303,6 +341,7 @@ public:
_slideTitle = name; _slideTitle = name;
} }
void setSlideBackgrondHUD(bool hud) { _slideBackgroundAsHUD = hud; }
void setSlideBackground(const std::string& name) { _slideBackgroundImageFileName = name; } void setSlideBackground(const std::string& name) { _slideBackgroundImageFileName = name; }
void setSlideDuration(double duration); void setSlideDuration(double duration);
@ -380,6 +419,10 @@ public:
void setAutoSteppingActive(bool flag = true) { _autoSteppingActive = flag; } void setAutoSteppingActive(bool flag = true) { _autoSteppingActive = flag; }
bool getAutoSteppingActive() const { return _autoSteppingActive; } bool getAutoSteppingActive() const { return _autoSteppingActive; }
void setHUDSettings(HUDSettings* hudSettings) { _hudSettings = hudSettings; }
HUDSettings* getHUDSettings() { return _hudSettings.get(); }
const HUDSettings* getHUDSettings() const { return _hudSettings.get(); }
protected: protected:
@ -416,9 +459,10 @@ protected:
double _slideWidth; double _slideWidth;
double _slideHeight; double _slideHeight;
double _slideDistance; double _slideDistance;
unsigned _leftEyeMask; unsigned int _leftEyeMask;
unsigned _rightEyeMask; unsigned int _rightEyeMask;
double _eyeOffset;
osg::ref_ptr<HUDSettings> _hudSettings;
// title settings // title settings
FontData _titleFontData; FontData _titleFontData;
@ -456,6 +500,7 @@ protected:
osg::ref_ptr<osg::Switch> _slide; osg::ref_ptr<osg::Switch> _slide;
std::string _slideTitle; std::string _slideTitle;
std::string _slideBackgroundImageFileName; std::string _slideBackgroundImageFileName;
bool _slideBackgroundAsHUD;
osg::ref_ptr<osg::Group> _previousLayer; osg::ref_ptr<osg::Group> _previousLayer;
osg::ref_ptr<osg::Group> _currentLayer; osg::ref_ptr<osg::Group> _currentLayer;

View File

@ -1550,6 +1550,14 @@ void ReaderWriterP3DXML::parseSlide (osgPresentation::SlideShowConstructor& cons
else if (cur->name == "background") else if (cur->name == "background")
{ {
constructor.setSlideBackground(cur->contents); constructor.setSlideBackground(cur->contents);
std::string str;
if (getProperty(cur, "hud", str))
{
bool hud = (str != "off" && str != "Off" && str != "OFF");
OSG_NOTIFY(_notifyLevel)<<"background hud, str="<<str<<", hud="<<hud<<std::endl;
constructor.setSlideBackgrondHUD(hud);
}
} }
else if (cur->name == "bgcolor") else if (cur->name == "bgcolor")
{ {

View File

@ -90,67 +90,74 @@ public:
} }
}; };
class HUDTransform : public osg::Transform
{
public:
HUDTransform(double slideDistance, float eyeOffset, unsigned int leftMask, unsigned int rightMask): HUDSettings::HUDSettings(double slideDistance, float eyeOffset, unsigned int leftMask, unsigned int rightMask):
_slideDistance(slideDistance), _slideDistance(slideDistance),
_eyeOffset(eyeOffset), _eyeOffset(eyeOffset),
_leftMask(leftMask), _leftMask(leftMask),
_rightMask(rightMask) _rightMask(rightMask)
{
}
HUDSettings::~HUDSettings()
{
}
bool HUDSettings::getModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
{
matrix.makeLookAt(osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,_slideDistance,0.0),osg::Vec3d(0.0,0.0,1.0));
if (nv->getTraversalMask()==_leftMask)
{
matrix.postMultTranslate(osg::Vec3(_eyeOffset,0.0,0.0));
}
else if (nv->getTraversalMask()==_rightMask)
{
matrix.postMultTranslate(osg::Vec3(-_eyeOffset,0.0,0.0));
}
return true;
}
bool HUDSettings::getInverseModelViewMatrix(osg::Matrix& matrix, osg::NodeVisitor* nv) const
{
osg::Matrix modelView;
getModelViewMatrix(modelView,nv);
matrix.invert(modelView);
return true;
}
HUDTransform::HUDTransform(HUDSettings* hudSettings):
_hudSettings(hudSettings)
{ {
setDataVariance(osg::Object::DYNAMIC); setDataVariance(osg::Object::DYNAMIC);
setReferenceFrame(osg::Transform::ABSOLUTE_RF); setReferenceFrame(osg::Transform::ABSOLUTE_RF);
} }
virtual bool computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const HUDTransform::~HUDTransform() {}
{
osgUtil::CullVisitor* cullVisitor = dynamic_cast<osgUtil::CullVisitor*>(nv);
bool HUDTransform::computeLocalToWorldMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
matrix.makeLookAt(osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,_slideDistance,0.0),osg::Vec3d(0.0,0.0,1.0));
if (cullVisitor)
{ {
if (cullVisitor->getTraversalMask()==_leftMask) return _hudSettings->getModelViewMatrix(matrix,nv);
{
matrix.postMultTranslate(osg::Vec3(_eyeOffset,0.0,0.0));
}
else if (cullVisitor->getTraversalMask()==_rightMask)
{
matrix.postMultTranslate(osg::Vec3(-_eyeOffset,0.0,0.0));
}
} }
return true; bool HUDTransform::computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor* nv) const
}
virtual bool computeWorldToLocalMatrix(osg::Matrix& matrix,osg::NodeVisitor*) const
{ {
osg::Matrix localToWorld; return _hudSettings->getInverseModelViewMatrix(matrix,nv);
localToWorld.makeLookAt(osg::Vec3d(0.0,0.0,0.0),osg::Vec3d(0.0,_slideDistance,0.0),osg::Vec3d(0.0,0.0,1.0));
matrix.invert(localToWorld);
return true;
} }
protected:
double _slideDistance;
double _eyeOffset;
unsigned int _leftMask;
unsigned int _rightMask;
};
SlideShowConstructor::SlideShowConstructor(osgDB::Options* options): SlideShowConstructor::SlideShowConstructor(osgDB::Options* options):
_options(options) _options(options)
{ {
_slideHeight = osg::DisplaySettings::instance()->getScreenHeight(); osg::DisplaySettings* ds = osg::DisplaySettings::instance();
_slideWidth = osg::DisplaySettings::instance()->getScreenWidth();
_slideDistance = osg::DisplaySettings::instance()->getScreenDistance(); _slideHeight = ds->getScreenHeight();
_slideWidth = ds->getScreenWidth();
_slideDistance = ds->getScreenDistance();
_leftEyeMask = 0x01; _leftEyeMask = 0x01;
_rightEyeMask = 0x02; _rightEyeMask = 0x02;
_eyeOffset = 0.025;
_hudSettings = new HUDSettings(_slideDistance, ds->getEyeSeparation()*0.5, _leftEyeMask, _rightEyeMask);
_backgroundColor.set(0.0f,0.0f,0.0f,1.0f); _backgroundColor.set(0.0f,0.0f,0.0f,1.0f);
@ -180,6 +187,8 @@ SlideShowConstructor::SlideShowConstructor(osgDB::Options* options):
_loopPresentation = false; _loopPresentation = false;
_autoSteppingActive = false; _autoSteppingActive = false;
_slideBackgroundAsHUD = false;
} }
void SlideShowConstructor::setPresentationAspectRatio(float aspectRatio) void SlideShowConstructor::setPresentationAspectRatio(float aspectRatio)
@ -422,8 +431,17 @@ void SlideShowConstructor::addLayer(bool inheritPreviousLayers, bool defineAsBas
background->addDrawable(backgroundQuad); background->addDrawable(backgroundQuad);
if (_slideBackgroundAsHUD)
{
HUDTransform* hudTransform = new HUDTransform(_hudSettings.get());
hudTransform->addChild(background);
_currentLayer->addChild(hudTransform);
}
else
{
_currentLayer->addChild(background); _currentLayer->addChild(background);
} }
}
if (!_slideTitle.empty()) if (!_slideTitle.empty())
{ {
@ -609,7 +627,7 @@ osg::Node* SlideShowConstructor::decorateSubgraphForPosition(osg::Node* node, Po
if (positionData.hud) if (positionData.hud)
{ {
HUDTransform* hudTransform = new HUDTransform(_slideDistance, _eyeOffset, _leftEyeMask, _rightEyeMask); HUDTransform* hudTransform = new HUDTransform(_hudSettings.get());
hudTransform->addChild(subgraph); hudTransform->addChild(subgraph);
subgraph = hudTransform; subgraph = hudTransform;
@ -928,7 +946,6 @@ void SlideShowConstructor::addImage(const std::string& filename, const PositionD
subgraph = picture; subgraph = picture;
} }
// attach any meterial animation. // attach any meterial animation.
if (positionData.requiresMaterialAnimation()) if (positionData.requiresMaterialAnimation())
subgraph = attachMaterialAnimation(subgraph,positionData); subgraph = attachMaterialAnimation(subgraph,positionData);
@ -983,6 +1000,14 @@ void SlideShowConstructor::addImage(const std::string& filename, const PositionD
subgraph = animation_transform; subgraph = animation_transform;
} }
if (positionData.hud)
{
HUDTransform* hudTransform = new HUDTransform(_hudSettings.get());
hudTransform->addChild(subgraph);
subgraph = hudTransform;
}
_currentLayer->addChild(subgraph); _currentLayer->addChild(subgraph);
} }
@ -1032,8 +1057,6 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c
float s = imageLeft->s(); float s = imageLeft->s();
float t = imageLeft->t(); float t = imageLeft->t();
// temporary hack
float height = 0.0f;
float sx = imageDataLeft.region_in_pixel_coords ? 1.0f : s; float sx = imageDataLeft.region_in_pixel_coords ? 1.0f : s;
float sy = imageDataLeft.region_in_pixel_coords ? 1.0f : t; float sy = imageDataLeft.region_in_pixel_coords ? 1.0f : t;
@ -1048,18 +1071,18 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c
float image_width = _slideWidth*positionData.scale.x(); float image_width = _slideWidth*positionData.scale.x();
float image_height = image_width*aspectRatio*positionData.scale.y()/positionData.scale.x(); float image_height = image_width*aspectRatio*positionData.scale.y()/positionData.scale.x();
float offset = height*image_height*0.1f; float offset = 0.0f;
bool usedTextureRectangle = false; bool usedTextureRectangle = false;
osg::Vec3 pos = computePositionInModelCoords(positionData) + osg::Vec3 pos = computePositionInModelCoords(positionData);
osg::Vec3(-image_width*0.5f+offset,-offset,-image_height*0.5f-offset); osg::Vec3 image_local_pos = osg::Vec3(-image_width*0.5f+offset,-offset,-image_height*0.5f-offset);
osg::Vec3 image_pos = positionData.autoRotate ? image_local_pos : (pos+image_local_pos);
osg::Geode* pictureLeft = new osg::Geode;
osg::Node* pictureLeft = 0;
{ {
pictureLeft->setNodeMask(_leftEyeMask); osg::Geometry* pictureLeftQuad = createTexturedQuadGeometry(image_pos, positionData.rotate, image_width,image_height,imageLeft.get(),usedTextureRectangle);
osg::Geometry* pictureLeftQuad = createTexturedQuadGeometry(pos, positionData.rotate, image_width,image_height,imageLeft.get(),usedTextureRectangle);
osg::StateSet* pictureLeftStateSet = pictureLeftQuad->getOrCreateStateSet(); osg::StateSet* pictureLeftStateSet = pictureLeftQuad->getOrCreateStateSet();
if (isImageTranslucent) if (isImageTranslucent)
@ -1069,15 +1092,28 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c
attachTexMat(pictureLeftStateSet, imageDataLeft, s, t, usedTextureRectangle); attachTexMat(pictureLeftStateSet, imageDataLeft, s, t, usedTextureRectangle);
pictureLeft->addDrawable(pictureLeftQuad); if (positionData.autoRotate)
{
osg::Billboard* billboard = new osg::Billboard;
billboard->setMode(osg::Billboard::POINT_ROT_EYE);
billboard->setNormal(osg::Vec3(0.0f,-1.0f,0.0f));
billboard->setAxis(osg::Vec3(0.0f,0.0f,1.0f));
billboard->addDrawable(pictureLeftQuad,pos);
pictureLeft = billboard;
}
else
{
osg::Geode* geode = new osg::Geode;
geode->addDrawable(pictureLeftQuad);
pictureLeft = geode;
} }
osg::Geode* pictureRight = new osg::Geode; pictureLeft->setNodeMask(_leftEyeMask);
{ }
pictureRight->setNodeMask(_rightEyeMask);
osg::Geometry* pictureRightQuad = createTexturedQuadGeometry(pos, positionData.rotate, image_width,image_height,imageRight.get(),usedTextureRectangle); osg::Node* pictureRight = 0;
{
osg::Geometry* pictureRightQuad = createTexturedQuadGeometry(image_pos, positionData.rotate, image_width,image_height,imageRight.get(),usedTextureRectangle);
osg::StateSet* pictureRightStateSet = pictureRightQuad->getOrCreateStateSet(); osg::StateSet* pictureRightStateSet = pictureRightQuad->getOrCreateStateSet();
if (isImageTranslucent) if (isImageTranslucent)
@ -1087,7 +1123,23 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c
attachTexMat(pictureRightStateSet, imageDataRight, s, t, usedTextureRectangle); attachTexMat(pictureRightStateSet, imageDataRight, s, t, usedTextureRectangle);
pictureRight->addDrawable(pictureRightQuad); if (positionData.autoRotate)
{
osg::Billboard* billboard = new osg::Billboard;
billboard->setMode(osg::Billboard::POINT_ROT_EYE);
billboard->setNormal(osg::Vec3(0.0f,-1.0f,0.0f));
billboard->setAxis(osg::Vec3(0.0f,0.0f,1.0f));
billboard->addDrawable(pictureRightQuad,pos);
pictureRight = billboard;
}
else
{
osg::Geode* geode = new osg::Geode;
geode->addDrawable(pictureRightQuad);
pictureRight = geode;
}
pictureRight->setNodeMask(_rightEyeMask);
} }
osg::Group* subgraph = new osg::Group; osg::Group* subgraph = new osg::Group;
@ -1145,6 +1197,14 @@ void SlideShowConstructor::addStereoImagePair(const std::string& filenameLeft, c
subgraph = animation_transform; subgraph = animation_transform;
} }
if (positionData.hud)
{
HUDTransform* hudTransform = new HUDTransform(_hudSettings.get());
hudTransform->addChild(subgraph);
subgraph = hudTransform;
}
_currentLayer->addChild(subgraph); _currentLayer->addChild(subgraph);
} }
@ -1269,9 +1329,6 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam
float s = image->s(); float s = image->s();
float t = image->t(); float t = image->t();
// temporary hack
float height = 0.0f;
float sx = imageData.region_in_pixel_coords ? 1.0f : s; float sx = imageData.region_in_pixel_coords ? 1.0f : s;
float sy = imageData.region_in_pixel_coords ? 1.0f : t; float sy = imageData.region_in_pixel_coords ? 1.0f : t;
@ -1284,16 +1341,14 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam
float image_width = _slideWidth*positionData.scale.x(); float image_width = _slideWidth*positionData.scale.x();
float image_height = image_width*aspectRatio*positionData.scale.y()/positionData.scale.x(); float image_height = image_width*aspectRatio*positionData.scale.y()/positionData.scale.x();
float offset = height*image_height*0.1f; float offset = 0.0f;
osg::Vec3 pos = computePositionInModelCoords(positionData) + osg::Vec3(-image_width*0.5f+offset,-offset,-image_height*0.5f-offset);
osg::Geode* picture = new osg::Geode;
osg::Node* subgraph = picture;
osg::Vec3 pos = computePositionInModelCoords(positionData);
osg::Vec3 image_local_pos = osg::Vec3(-image_width*0.5f+offset,-offset,-image_height*0.5f-offset);
osg::Vec3 image_pos = positionData.autoRotate ? image_local_pos : (pos+image_local_pos);
bool usedTextureRectangle = false; bool usedTextureRectangle = false;
osg::Geometry* pictureQuad = createTexturedQuadGeometry(pos, positionData.rotate, image_width, image_height, image, usedTextureRectangle); osg::Geometry* pictureQuad = createTexturedQuadGeometry(image_pos, positionData.rotate, image_width, image_height, image, usedTextureRectangle);
osg::ref_ptr<osgViewer::InteractiveImageHandler> handler = new osgViewer::InteractiveImageHandler(image); osg::ref_ptr<osgViewer::InteractiveImageHandler> handler = new osgViewer::InteractiveImageHandler(image);
pictureQuad->setEventCallback(handler.get()); pictureQuad->setEventCallback(handler.get());
@ -1305,7 +1360,23 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam
pictureStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF); pictureStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
osg::Node* subgraph = 0;
if (positionData.autoRotate)
{
osg::Billboard* picture = new osg::Billboard;
picture->setMode(osg::Billboard::POINT_ROT_EYE);
picture->setNormal(osg::Vec3(0.0f,-1.0f,0.0f));
picture->setAxis(osg::Vec3(0.0f,0.0f,1.0f));
picture->addDrawable(pictureQuad,pos);
subgraph = picture;
}
else
{
osg::Geode* picture = new osg::Geode;
picture->addDrawable(pictureQuad); picture->addDrawable(pictureQuad);
subgraph = picture;
}
// attach any meterial animation. // attach any meterial animation.
if (positionData.requiresMaterialAnimation()) if (positionData.requiresMaterialAnimation())
@ -1318,7 +1389,7 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam
osg::MatrixTransform* animation_transform = new osg::MatrixTransform; osg::MatrixTransform* animation_transform = new osg::MatrixTransform;
animation_transform->setDataVariance(osg::Object::DYNAMIC); animation_transform->setDataVariance(osg::Object::DYNAMIC);
animation_transform->setUpdateCallback( animation_transform->setUpdateCallback(
new osgUtil::TransformCallback(picture->getBound().center(), new osgUtil::TransformCallback(subgraph->getBound().center(),
osg::Vec3(positionData.rotation[1],positionData.rotation[2],positionData.rotation[3]), osg::Vec3(positionData.rotation[1],positionData.rotation[2],positionData.rotation[3]),
osg::DegreesToRadians(positionData.rotation[0]))); osg::DegreesToRadians(positionData.rotation[0])));
@ -1354,6 +1425,14 @@ osg::Image* SlideShowConstructor::addInteractiveImage(const std::string& filenam
subgraph = animation_transform; subgraph = animation_transform;
} }
if (positionData.hud)
{
HUDTransform* hudTransform = new HUDTransform(_hudSettings.get());
hudTransform->addChild(subgraph);
subgraph = hudTransform;
}
_currentLayer->addChild(subgraph); _currentLayer->addChild(subgraph);
osgWidget::PdfImage* pdfImage = dynamic_cast<osgWidget::PdfImage*>(image); osgWidget::PdfImage* pdfImage = dynamic_cast<osgWidget::PdfImage*>(image);