diff --git a/include/osgPresentation/SlideShowConstructor b/include/osgPresentation/SlideShowConstructor index 6bc79faaa..a47aeab7d 100644 --- a/include/osgPresentation/SlideShowConstructor +++ b/include/osgPresentation/SlideShowConstructor @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -204,6 +205,28 @@ public: osg::Vec4 backgroundColor; }; + struct VolumeData + { + enum ShadingModel + { + Standard, + Light, + Isosurface, + MaximumIntensityProjection + }; + + VolumeData(): + shadingModel(Standard), + useTabbedDragger(false), + useTrackballDragger(false) {} + + ShadingModel shadingModel; + osg::ref_ptr transferFunction; + bool useTabbedDragger; + bool useTrackballDragger; + }; + + struct FontData { FontData(): @@ -316,7 +339,7 @@ public: void addModel(const std::string& filename, const PositionData& positionData, const ModelData& modelData); - void addVolume(const std::string& filename, const PositionData& positionData); + void addVolume(const std::string& filename, const PositionData& positionData, const VolumeData& volumeData); osg::Group* takePresentation() { return _root.release(); } @@ -334,6 +357,7 @@ public: void setAutoSteppingActive(bool flag = true) { _autoSteppingActive = flag; } bool getAutoSteppingActive() const { return _autoSteppingActive; } + protected: void findImageStreamsAndAddCallbacks(osg::Node* node); diff --git a/src/osgPlugins/p3d/ReaderWriterP3D.cpp b/src/osgPlugins/p3d/ReaderWriterP3D.cpp index fdf25704a..0f7160a06 100644 --- a/src/osgPlugins/p3d/ReaderWriterP3D.cpp +++ b/src/osgPlugins/p3d/ReaderWriterP3D.cpp @@ -120,6 +120,7 @@ public: void parseModel(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur) const; + osg::TransferFunction1D* readTransferFunctionFile(const std::string& filename) const; void parseVolume(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur) const; void parseStereoPair(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur) const; @@ -831,18 +832,92 @@ void ReaderWriterP3DXML::parseModel(osgPresentation::SlideShowConstructor& const } } -void ReaderWriterP3DXML::parseVolume(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode*cur) const + + +osg::TransferFunction1D* ReaderWriterP3DXML::readTransferFunctionFile(const std::string& filename) const +{ + std::string foundFile = osgDB::findDataFile(filename); + if (foundFile.empty()) + { + std::cout<<"Error: could not find transfer function file : "<> value >> red >> green >> blue >> alpha; + if (fin) + { + std::cout<<"value = "<assign(colorMap); + + return tf; +} + + +void ReaderWriterP3DXML::parseVolume(osgPresentation::SlideShowConstructor& constructor, osgDB::XmlNode* cur) const { osgPresentation::SlideShowConstructor::PositionData positionData = constructor.getModelPositionData(); bool positionRead = getProperties(cur,positionData); - std::string filename = cur->contents; + osgPresentation::SlideShowConstructor::VolumeData volumeData; + // check the rendering technique/shading model to use + std::string technique; + if (getProperty(cur, "technique", technique)) + { + if (technique=="standard") volumeData.shadingModel = osgPresentation::SlideShowConstructor::VolumeData::Standard; + else if (technique=="mip") volumeData.shadingModel = osgPresentation::SlideShowConstructor::VolumeData::MaximumIntensityProjection; + else if (technique=="isosurface" || technique=="iso" ) volumeData.shadingModel = osgPresentation::SlideShowConstructor::VolumeData::Isosurface; + else if (technique=="light") volumeData.shadingModel = osgPresentation::SlideShowConstructor::VolumeData::Light; + } + + // check for any transfer function required + std::string transferFunctionFile; + if (getProperty(cur, "tf", transferFunctionFile)) + { + volumeData.transferFunction = readTransferFunctionFile(transferFunctionFile); + } + + // check for draggers required + std::string dragger; + if (getProperty(cur, "dragger", dragger)) + { + if (dragger=="trackball") + { + volumeData.useTabbedDragger = false; + volumeData.useTrackballDragger = true; + } + else + { + volumeData.useTabbedDragger = true; + volumeData.useTrackballDragger = false; + } + } + + std::string filename = cur->contents; if (!filename.empty()) { constructor.addVolume(filename, - positionRead ? positionData : constructor.getModelPositionData()); + positionRead ? positionData : constructor.getModelPositionData(), + volumeData); } } diff --git a/src/osgPresentation/CMakeLists.txt b/src/osgPresentation/CMakeLists.txt index 52944232c..9755e477d 100644 --- a/src/osgPresentation/CMakeLists.txt +++ b/src/osgPresentation/CMakeLists.txt @@ -29,6 +29,7 @@ ADD_LIBRARY(${LIB_NAME} LINK_INTERNAL(${LIB_NAME} osgViewer + osgManipulator osgVolume osgFX osgText diff --git a/src/osgPresentation/SlideShowConstructor.cpp b/src/osgPresentation/SlideShowConstructor.cpp index 5c0a29abe..7c047caeb 100644 --- a/src/osgPresentation/SlideShowConstructor.cpp +++ b/src/osgPresentation/SlideShowConstructor.cpp @@ -50,6 +50,10 @@ #include #include +#include +#include +#include + using namespace osgPresentation; class SetToTransparentBin : public osg::NodeVisitor @@ -1429,8 +1433,72 @@ void SlideShowConstructor::addModel(osg::Node* subgraph, const PositionData& pos _currentLayer->addChild(subgraph); } +class DraggerVolumeTileCallback : public osgManipulator::DraggerCallback +{ +public: -void SlideShowConstructor::addVolume(const std::string& filename, const PositionData& positionData) + DraggerVolumeTileCallback(osgVolume::VolumeTile* volume, osgVolume::Locator* locator): + _volume(volume), + _locator(locator) {} + + + virtual bool receive(const osgManipulator::MotionCommand& command); + + + osg::observer_ptr _volume; + osg::ref_ptr _locator; + + osg::Matrix _startMotionMatrix; + + osg::Matrix _localToWorld; + osg::Matrix _worldToLocal; + +}; + +bool DraggerVolumeTileCallback::receive(const osgManipulator::MotionCommand& command) +{ + if (!_locator) return false; + + switch (command.getStage()) + { + case osgManipulator::MotionCommand::START: + { + // Save the current matrix + _startMotionMatrix = _locator->getTransform(); + + // Get the LocalToWorld and WorldToLocal matrix for this node. + osg::NodePath nodePathToRoot; + osgManipulator::computeNodePathToRoot(*_volume,nodePathToRoot); + _localToWorld = _startMotionMatrix * osg::computeLocalToWorld(nodePathToRoot); + _worldToLocal = osg::Matrix::inverse(_localToWorld); + + return true; + } + case osgManipulator::MotionCommand::MOVE: + { + // Transform the command's motion matrix into local motion matrix. + osg::Matrix localMotionMatrix = _localToWorld * command.getWorldToLocal() + * command.getMotionMatrix() + * command.getLocalToWorld() * _worldToLocal; + + // Transform by the localMotionMatrix + _locator->setTransform(localMotionMatrix * _startMotionMatrix); + + // osg::notify(osg::NOTICE)<<"New locator matrix "<<_locator->getTransform()<(image->getUserData()); if (matrix) { - osgVolume::Locator* locator = new osgVolume::Locator(*matrix); - layer->setLocator(locator); - tile->setLocator(locator); + layer->setLocator(new osgVolume::Locator(*matrix)); + tile->setLocator(new osgVolume::Locator(*matrix)); } tile->setLayer(layer.get()); @@ -1487,6 +1554,7 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position osgVolume::AlphaFuncProperty* ap = new osgVolume::AlphaFuncProperty(alphaFunc); osgVolume::SampleDensityProperty* sd = new osgVolume::SampleDensityProperty(0.005); osgVolume::TransparencyProperty* tp = new osgVolume::TransparencyProperty(1.0); + osgVolume::TransferFunctionProperty* tfp = volumeData.transferFunction.valid() ? new osgVolume::TransferFunctionProperty(volumeData.transferFunction.get()) : 0; { // Standard @@ -1494,6 +1562,7 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position cp->addProperty(ap); cp->addProperty(sd); cp->addProperty(tp); + if (tfp) cp->addProperty(tfp); sp->addProperty(cp); } @@ -1505,6 +1574,7 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position cp->addProperty(sd); cp->addProperty(tp); cp->addProperty(new osgVolume::LightingProperty); + if (tfp) cp->addProperty(tfp); sp->addProperty(cp); } @@ -1515,6 +1585,7 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position cp->addProperty(sd); cp->addProperty(tp); cp->addProperty(new osgVolume::IsoSurfaceProperty(alphaFunc)); + if (tfp) cp->addProperty(tfp); sp->addProperty(cp); } @@ -1526,16 +1597,56 @@ void SlideShowConstructor::addVolume(const std::string& filename, const Position cp->addProperty(sd); cp->addProperty(tp); cp->addProperty(new osgVolume::MaximumIntensityProjectionProperty); + if (tfp) cp->addProperty(tfp); sp->addProperty(cp); } + switch(volumeData.shadingModel) + { + case(VolumeData::Standard): sp->setActiveProperty(0); break; + case(VolumeData::Light): sp->setActiveProperty(1); break; + case(VolumeData::Isosurface): sp->setActiveProperty(2); break; + case(VolumeData::MaximumIntensityProjection): sp->setActiveProperty(3); break; + } + layer->addProperty(sp); tile->setVolumeTechnique(new osgVolume::RayTracedTechnique); tile->setEventCallback(new osgVolume::PropertyAdjustmentCallback()); + + osg::ref_ptr model = volume.get(); + + if (volumeData.useTabbedDragger || volumeData.useTrackballDragger) + { + osg::ref_ptr group = new osg::Group; + + osg::ref_ptr dragger; + if (volumeData.useTabbedDragger) + dragger = new osgManipulator::TabBoxDragger; + else + dragger = new osgManipulator::TrackballDragger(); + + dragger->setupDefaultGeometry(); + dragger->setHandleEvents(true); + dragger->setActivationModKeyMask(osgGA::GUIEventAdapter::MODKEY_SHIFT); + dragger->addDraggerCallback(new DraggerVolumeTileCallback(tile.get(), tile->getLocator())); + dragger->setMatrix(osg::Matrix::translate(0.5,0.5,0.5)*tile->getLocator()->getTransform()); + + + group->addChild(dragger.get()); + + //dragger->addChild(volume.get()); + + group->addChild(volume.get()); + + model = group.get(); + } + + + ModelData modelData; - addModel(volume.get(), positionData, modelData); + addModel(model.get(), positionData, modelData); } bool SlideShowConstructor::attachTexMat(osg::StateSet* stateset, const ImageData& imageData, float s, float t, bool textureRectangle)