Commit 90380a5d authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[FIX #282] made several improvements to ensure the OSG can get the correct bounding boxes.

parent 8c3ac123
......@@ -82,6 +82,13 @@ public:
*/
WBoundingBoxImpl( const vec_type& min, const vec_type& max );
/**
* Copy construct using a given bounding box
*
* \param bb the source bb
*/
WBoundingBoxImpl( const WBoundingBoxImpl& bb );
/**
* Destructs this instance.
*/
......@@ -199,6 +206,12 @@ inline WBoundingBoxImpl< VT >::WBoundingBoxImpl( const vec_type& min, const vec_
{
}
template< class VT >
inline WBoundingBoxImpl< VT >::WBoundingBoxImpl( const WBoundingBoxImpl< VT >& bb )
: osg::BoundingBoxImpl< VT >( bb )
{
}
template< class VT >
inline WBoundingBoxImpl< VT >::~WBoundingBoxImpl()
{
......
......@@ -92,6 +92,7 @@ namespace defaultColor
static const WColor GRAY50( 0.5, 0.5, 0.5, 1.0 ); //!< Default for gray
static const WColor GRAY75( 0.75, 0.75, 0.75, 1.0 ); //!< Default for gray
static const WColor WHITE( 1.0, 1.0, 1.0, 1.0 ); //!< Default for white
static const WColor TRANSPARENT( 1.0, 1.0, 1.0, 0.0 ); //!< Completely transparent -- NOTE: this does not belong to the default palette
// \endcond
/**
......
......@@ -34,6 +34,17 @@ WGECamera::WGECamera( int width, int height, ProjectionMode projectionMode )
{
setViewport( 0, 0, width, height );
setClearColor( osg::Vec4( 0.9, 0.9, 0.9, 1.0 ) );
// disable all culling
setCullingActive( false );
setCullingMode( osg::CullSettings::NO_CULLING );
// near-far computation is done using the bounding volumes
setComputeNearFarMode(
osg::CullSettings::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES
// osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR
// osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES
);
reset();
}
......
......@@ -30,6 +30,8 @@
#include "../common/math/linearAlgebra/WPosition.h"
#include "WGETexture.h"
#include "shaders/WGEShader.h"
#include "WGEGeodeUtils.h"
#include "WGEUtils.h"
......@@ -229,3 +231,18 @@ void wge::enableTransparency( osg::ref_ptr< osg::Node > node )
state->setMode( GL_BLEND, osg::StateAttribute::ON );
}
osg::ref_ptr< osg::Node > wge::generateCullProxy( const WBoundingBox& bbox )
{
// Create some cube. Color is uninteresting.
osg::ref_ptr< osg::Node > cullProxy = wge::generateSolidBoundingBoxNode( bbox, defaultColor::WHITE );
// Avoid picking the proxy
cullProxy->asTransform()->getChild( 0 )->setName( "_Cull Proxy Cube" ); // Be aware that this name is used in the pick handler.
// because of the underscore in front it won't be picked
// Add a shader which visually removes the proxy cube.
osg::ref_ptr< WGEShader > cullProxyShader = new WGEShader( "WGECullProxyShader" );
cullProxyShader->apply( cullProxy );
return cullProxy;
}
......@@ -35,6 +35,7 @@
#include <osg/Uniform>
#include "../common/WColor.h"
#include "../common/WBoundingBox.h"
#include "../common/WAssert.h"
#include "../common/WPropertyVariable.h"
#include "../graphicsEngine/shaders/WGEPropertyUniform.h"
......@@ -124,6 +125,17 @@ namespace wge
*/
template< typename T >
void bindAsUniform( osg::Node* node, T prop, std::string name );
/**
* Generate a proxy cube, which ensures OSG does proper near-far plane calculation and culling. This is especially useful if you create some
* geometry and modify it on the GPU by shaders. In these cases, OSG will not properly cull and near-far clip. This cull proxy is basically a
* cube, which gets shrinked to zero size on the GPU. This ensures you cannot see it, but it makes OSG see you proper bounding volume.
*
* \param bbox the bounding box to cover
*
* \return the proxy. Add it to your scene root.
*/
osg::ref_ptr< osg::Node > generateCullProxy( const WBoundingBox& bbox );
}
inline WColor wge::getRGBAColorFromDirection( const WPosition &pos1, const WPosition &pos2 )
......
......@@ -46,6 +46,7 @@ WGEOffscreenRenderPass::WGEOffscreenRenderPass( size_t textureWidth, size_t text
setReferenceFrame( osg::Transform::RELATIVE_RF );
setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
setRenderOrder( osg::Camera::PRE_RENDER, num );
setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR );
}
WGEOffscreenRenderPass::WGEOffscreenRenderPass( size_t textureWidth, size_t textureHeight, osg::ref_ptr< WGETextureHud > hud, std::string name,
......@@ -63,6 +64,7 @@ WGEOffscreenRenderPass::WGEOffscreenRenderPass( size_t textureWidth, size_t text
setReferenceFrame( osg::Transform::RELATIVE_RF );
setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
setRenderOrder( osg::Camera::PRE_RENDER, num );
setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR );
}
WGEOffscreenRenderPass::~WGEOffscreenRenderPass()
......
//---------------------------------------------------------------------------
//
// 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/>.
//
//---------------------------------------------------------------------------
#version 120
/**
* Main. Shrink box to zero size.
*/
void main()
{
// laplace filter kernel
gl_FragColor = vec4( 1.0 );
}
//---------------------------------------------------------------------------
//
// 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/>.
//
//---------------------------------------------------------------------------
#version 120
/**
* Main. Shrink box to zero size.
*/
void main()
{
// move somewhere.
gl_Position = vec4( 0.0 );
}
......@@ -40,6 +40,7 @@
#include "core/dataHandler/WGridRegular3D.h"
#include "core/graphicsEngine/WGEColormapping.h"
#include "core/graphicsEngine/WGEGeodeUtils.h"
#include "core/graphicsEngine/WGEUtils.h"
#include "core/graphicsEngine/WGETextureUtils.h"
#include "core/graphicsEngine/callbacks/WGELinearTranslationCallback.h"
#include "core/graphicsEngine/callbacks/WGENodeMaskCallback.h"
......@@ -237,6 +238,11 @@ void WMImageSpaceLIC::initOSG( boost::shared_ptr< WGridRegular3D > grid, boost::
osg::ref_ptr< osg::Node > zSlice = wge::genFinitePlane( grid->getOrigin(), grid->getNbCoordsX() * grid->getDirectionX(),
grid->getNbCoordsY() * grid->getDirectionY() );
// disable picking
xSlice->setName( "_X SLice" );
ySlice->setName( "_Y SLice" );
zSlice->setName( "_Z SLice" );
// The movement of the slice is done in the shader. An alternative would be WGELinearTranslationCallback but there, the needed matrix is
// not available in the shader
osg::StateSet* ss = xSlice->getOrCreateStateSet();
......@@ -302,7 +308,10 @@ void WMImageSpaceLIC::moduleMain()
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// create the root node for all the geometry
m_output = osg::ref_ptr< WGEManagedGroupNode > ( new WGEManagedGroupNode( m_active ) );
m_root = osg::ref_ptr< WGEManagedGroupNode > ( new WGEManagedGroupNode( m_active ) );
// root geometry node for the offscreen path
m_output = osg::ref_ptr< WGEGroupNode > ( new WGEGroupNode() );
// the WGEOffscreenRenderNode manages each of the render-passes for us
osg::ref_ptr< WGEOffscreenRenderNode > offscreen = new WGEOffscreenRenderNode(
......@@ -402,6 +411,15 @@ void WMImageSpaceLIC::moduleMain()
clipBlend->addUniform( new WGEPropertyUniform< WPropBool >( "u_useHighContrast", m_useHighContrast ) );
clipBlend->addUniform( new WGEPropertyUniform< WPropDouble >( "u_cmapRatio", m_cmapRatio ) );
// add everything to root node
m_root->insert( offscreen );
// Cull proxy. Updated on dataset change
osg::ref_ptr< osg::Node > cullProxy;
// register scene
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( m_root );
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Main loop
/////////////////////////////////////////////////////////////////////////////////////////////////////////
......@@ -441,17 +459,14 @@ void WMImageSpaceLIC::moduleMain()
continue;
}
// ensure it gets added
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( offscreen );
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->insert( offscreen );
// prefer vector dataset if existing
boost::shared_ptr< WGridRegular3D > grid;
if( dataSetVec )
{
debugLog() << "Using vector data";
// get grid and prepare OSG
boost::shared_ptr< WGridRegular3D > grid = boost::dynamic_pointer_cast< WGridRegular3D >( dataSetVec->getGrid() );
grid = boost::dynamic_pointer_cast< WGridRegular3D >( dataSetVec->getGrid() );
m_xPos->setMax( grid->getNbCoordsX() - 1 );
m_yPos->setMax( grid->getNbCoordsY() - 1 );
m_zPos->setMax( grid->getNbCoordsZ() - 1 );
......@@ -466,7 +481,7 @@ void WMImageSpaceLIC::moduleMain()
debugLog() << "Using scalar data";
// get grid and prepare OSG
boost::shared_ptr< WGridRegular3D > grid = boost::dynamic_pointer_cast< WGridRegular3D >( dataSetScal->getGrid() );
grid = boost::dynamic_pointer_cast< WGridRegular3D >( dataSetScal->getGrid() );
m_xPos->setMax( grid->getNbCoordsX() - 1 );
m_yPos->setMax( grid->getNbCoordsY() - 1 );
m_zPos->setMax( grid->getNbCoordsZ() - 1 );
......@@ -477,11 +492,17 @@ void WMImageSpaceLIC::moduleMain()
transformation->bind( dataSetScal->getTexture(), 0 );
}
// Update CullProxy when we get new data
// add a cull-proxy as we modify the geometry on the GPU
WBoundingBox bbox = grid->getVoxelBoundingBox();
m_root->remove( cullProxy );
cullProxy = wge::generateCullProxy( bbox );
m_root->insert( cullProxy );
debugLog() << "Done";
}
// clean up
offscreen->clear();
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( offscreen );
m_root->clear();
WKernel::getRunningKernel()->getGraphicsEngine()->getScene()->remove( m_root );
}
......@@ -140,7 +140,12 @@ private:
/**
* The Geode containing all the slices and the mesh
*/
osg::ref_ptr< WGEManagedGroupNode > m_output;
osg::ref_ptr< WGEGroupNode > m_output;
/**
* Scene root node.
*/
osg::ref_ptr< WGEManagedGroupNode > m_root;
WPropGroup m_sliceGroup; //!< the group contains several slice properties
......
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