Commit aadb219d authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[ADD] - added comfortable WGEManagedGroupNode. If used in a module as root...

[ADD] - added comfortable WGEManagedGroupNode. If used in a module as root node, handling m_active is done automatically.
parent 7bd1da78
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <osg/ShapeDrawable>
#include <osg/MatrixTransform>
#include <osg/Geode>
#include "WGEManagedGroupNode.h"
WGEManagedGroupNode::WGEManagedGroupNode( boost::shared_ptr< WBoolFlag > active ):
WGEGroupNode(),
m_activeFlag( active )
{
setDataVariance( osg::Object::DYNAMIC );
// get change signal
m_connection = m_activeFlag->getValueChangeCondition()->subscribeSignal(
boost::bind( &WGEManagedGroupNode::activate, this )
);
// setup an update callback
addUpdateCallback( osg::ref_ptr< NodeMaskCallback >( new NodeMaskCallback( m_activeFlag ) ) );
}
WGEManagedGroupNode::~WGEManagedGroupNode()
{
// cleanup
m_connection.disconnect();
}
void WGEManagedGroupNode::activate()
{
if ( m_activeFlag->get() ) // only handle activation here
{
setNodeMask( 0xFFFFFFFF );
}
}
void WGEManagedGroupNode::NodeMaskCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
{
// Deactivate the node
if ( !m_activeFlag->get() ) // only handle deactivation here
{
node->setNodeMask( 0x0 );
// NOTE: this also deactivates the callback. So reactivating the node is done in a separate method
}
// forward the call
traverse( node, nv );
}
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut 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
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WGEMANAGEDGROUPNODE_H
#define WGEMANAGEDGROUPNODE_H
#include <boost/shared_ptr.hpp>
#include <osg/NodeCallback>
#include "WGEGroupNode.h"
#include "../common/WCondition.h"
#include "../common/WFlag.h"
/**
* This class adds some convenience methods to WGEGroupNode. It can handle bool properties which switch the node on and off.
*
* \ingroup GE
*/
class WGEManagedGroupNode: public WGEGroupNode
{
public:
/**
* Default constructor.
*
* \param active the flag denoting the node to be activated ( if flag == true ) or turned off.
*/
explicit WGEManagedGroupNode( boost::shared_ptr< WBoolFlag > active );
/**
* Destructor.
*/
virtual ~WGEManagedGroupNode();
protected:
/**
* Update callback which sets the node mask of the node according to the specified property.
*/
class NodeMaskCallback : public osg::NodeCallback
{
public:
/**
* Constructor.
*
* \param flag the flag denoting whether the node should be active or not
*/
explicit NodeMaskCallback( boost::shared_ptr< WBoolFlag > flag ): m_activeFlag( flag )
{
};
/**
* Callback method called by the NodeVisitor when visiting a node.
* Sets the nodemask of the node according to the specified property.
*
* \param node the node calling this update
* \param nv The node visitor which performs the traversal. Should be an
* update visitor.
*/
virtual void operator()( osg::Node* node, osg::NodeVisitor* nv );
/**
* Flag denoting whether the node is turned on or off. We store the copy here to avoid permanent cast to WGEManagedGroupNode.
*/
boost::shared_ptr< WBoolFlag > m_activeFlag;
};
/**
* Gets called if m_activeFlag changes. This handles activation of the node.
*/
virtual void activate();
/**
* Flag denoting whether the node is turned on or off
*/
boost::shared_ptr< WBoolFlag > m_activeFlag;
/**
* The subscription to the change signal of m_activeFlag.
*/
boost::signals2::connection m_connection;
private:
};
#endif // WGEMANAGEDGROUPNODE_H
......@@ -354,10 +354,11 @@ void WMTemplate::moduleMain()
// Most probably, your module will be a module providing some kind of visual output. In this case, the WGEManagedGroupNode is very handy.
// It allows you to insert several nodes and transform them as the WGEGroupNode (from which WGEManagedGroupNode is derived from) is also
// an osg::MatrixTransform. The transformation feature comes in handy if you want to transform your whole geometry according to a dataset
// coordinate system for example.
// But first, create the node and add it to the main scene. If you insert something into the scene, you HAVE TO remove it after your module
// coordinate system for example. Another nice feature in WGEManagedGroupNode is that it can handle the m_active flag for you. Read the
// documentation of WMTemplate::activate for more details.
// First, create the node and add it to the main scene. If you insert something into the scene, you HAVE TO remove it after your module
// has finished!
m_rootNode = new WGEGroupNode();
m_rootNode = new WGEManagedGroupNode( m_active );
// Set a new callback for this node which basically transforms the geometry according to m_aPosition. Update callbacks are the thread safe
// way to manipulate an OSG node while it is inside the scene. This module contains several of these callbacks as an example. The one used
// here is to translate the root node coordinate system in space according to m_aPosition:
......@@ -664,24 +665,18 @@ boost::shared_ptr< WPropertyVariable< WPVBaseTypes::PV_STRING >::PropertyConstra
void WMTemplate::activate()
{
// This method gets called, whenever the m_active property changes. Your module should always handle this. For more details, see the
// documentation in properties(). The most simple way is to activate or deactivate your OSG root node in this function according to
// m_active's value. At the moment, we are not 100% sure whether deactivating a node, which is currently used, is thread-safe and complies to
// OSG's requirements. Activating an inactive node is not the problem, as OSG does not traverse these nodes (and therefore could possibly
// produce issues), but deactivating an active node, which might be traversed at the same time, COULD cause problems. We'll see in the future
// whether this is problematic or not.
if ( m_rootNode ) // always ensure the root node exists
// This method gets called, whenever the m_active property changes. Your module should always handle this if you do not use the
// WGEManagedGroupNode for your scene. The user can (de-)activate modules in his GUI and you can handle this case here:
if ( m_active->get() )
{
if ( m_active->get() )
{
m_rootNode->setNodeMask( 0xFFFFFFFF );
}
else
{
m_rootNode->setNodeMask( 0x0 );
}
debugLog() << "Activate.";
}
else
{
debugLog() << "Deactivate.";
}
// The simpler way is by using WGEManagedGroupNode which deactivates itself according to m_active. See moduleMain for details.
// Always call WModule's activate!
WModule::activate();
......
......@@ -32,7 +32,7 @@
#include "../../common/WItemSelection.h"
#include "../../common/WItemSelector.h"
#include "../../graphicsEngine/WGEGroupNode.h"
#include "../../graphicsEngine/WGEManagedGroupNode.h"
#include "../../kernel/WModule.h"
#include "../../kernel/WModuleInputData.h"
......@@ -103,7 +103,7 @@ protected:
/**
* The root node used for this modules graphics. For OSG nodes, always use osg::ref_ptr to ensure proper resource management.
*/
osg::ref_ptr< WGEGroupNode > m_rootNode;
osg::ref_ptr< WGEManagedGroupNode > m_rootNode;
/**
* The geometry rendered by this module.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment