Commit 5407b175 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[FIX] - WGridTransformOrtho matrix missed scaling.[CHANGE] - bbox module now...

[FIX] - WGridTransformOrtho matrix missed scaling.[CHANGE] - bbox module now uses new WGridTransformOrtho.[ADD] - added new geode which can display the boundary of a given grid.
parent 263c89d3
......@@ -57,10 +57,20 @@ class OWDATAHANDLER_EXPORT WGridRegular3D : public WGrid // NOLINT
*/
friend class WGridRegular3DTest;
public:
/**
* Convenience typedef for a boost::shared_ptr< WGridRegular3D >.
*/
typedef boost::shared_ptr< WGridRegular3D > SPtr;
/**
* Convenience typedef for a boost::shared_ptr< const WGridRegular3D >.
*/
typedef boost::shared_ptr< const WGridRegular3D > ConstSPtr;
/**
* Defines the number of samples in each coordinate direction as ints,
* and the transformation of the grid via a grid transform.
*
*
* \param nbPosX number of positions along first axis
* \param nbPosY number of positions along second axis
* \param nbPosZ number of positions along third axis
......
......@@ -162,15 +162,15 @@ wmath::WMatrix< double > WGridTransformOrtho::getTransformationMatrix() const
{
wmath::WMatrix< double > mat( 4, 4 );
mat.makeIdentity();
mat( 0, 0 ) = m_directionX[ 0 ];
mat( 1, 0 ) = m_directionX[ 1 ];
mat( 2, 0 ) = m_directionX[ 2 ];
mat( 0, 1 ) = m_directionY[ 0 ];
mat( 1, 1 ) = m_directionY[ 1 ];
mat( 2, 1 ) = m_directionY[ 2 ];
mat( 0, 2 ) = m_directionZ[ 0 ];
mat( 1, 2 ) = m_directionZ[ 1 ];
mat( 2, 2 ) = m_directionZ[ 2 ];
mat( 0, 0 ) = m_scaling[ 0 ] * m_directionX[ 0 ];
mat( 1, 0 ) = m_scaling[ 0 ] * m_directionX[ 1 ];
mat( 2, 0 ) = m_scaling[ 0 ] * m_directionX[ 2 ];
mat( 0, 1 ) = m_scaling[ 1 ] * m_directionY[ 0 ];
mat( 1, 1 ) = m_scaling[ 1 ] * m_directionY[ 1 ];
mat( 2, 1 ) = m_scaling[ 1 ] * m_directionY[ 2 ];
mat( 0, 2 ) = m_scaling[ 2 ] * m_directionZ[ 0 ];
mat( 1, 2 ) = m_scaling[ 2 ] * m_directionZ[ 1 ];
mat( 2, 2 ) = m_scaling[ 2 ] * m_directionZ[ 2 ];
mat( 0, 3 ) = m_origin[ 0 ];
mat( 1, 3 ) = m_origin[ 1 ];
mat( 2, 3 ) = m_origin[ 2 ];
......@@ -183,3 +183,24 @@ bool WGridTransformOrtho::isNotRotated() const
&& m_directionY == wmath::WVector3D( 0.0, 1.0, 0.0 )
&& m_directionZ == wmath::WVector3D( 0.0, 0.0, 1.0 );
}
WGridTransformOrtho::operator wmath::WMatrix4x4() const
{
// NOTE: OSG matrices are row-major!
wmath::WMatrix4x4 mat;
mat.makeIdentity();
mat( 0, 0 ) = m_scaling[ 0 ] * m_directionX[ 0 ];
mat( 0, 1 ) = m_scaling[ 0 ] * m_directionX[ 1 ];
mat( 0, 2 ) = m_scaling[ 0 ] * m_directionX[ 2 ];
mat( 1, 0 ) = m_scaling[ 1 ] * m_directionY[ 0 ];
mat( 1, 1 ) = m_scaling[ 1 ] * m_directionY[ 1 ];
mat( 1, 2 ) = m_scaling[ 1 ] * m_directionY[ 2 ];
mat( 2, 0 ) = m_scaling[ 2 ] * m_directionZ[ 0 ];
mat( 2, 1 ) = m_scaling[ 2 ] * m_directionZ[ 1 ];
mat( 2, 2 ) = m_scaling[ 2 ] * m_directionZ[ 2 ];
mat( 3, 0 ) = m_origin[ 0 ];
mat( 3, 1 ) = m_origin[ 1 ];
mat( 3, 2 ) = m_origin[ 2 ];
return mat;
}
......@@ -27,6 +27,7 @@
#include "../common/math/WVector3D.h"
#include "../common/math/WMatrix.h"
#include "../common/math/WMatrix4x4.h"
/**
* Implements an orthogonal grid transformation.
......@@ -152,6 +153,13 @@ public:
// adapted to the grid transform object
wmath::WMatrix< double > getTransformationMatrix() const;
/**
* Cast the transformation to the corresponding 4x4 matrix.
*
* \return the matrix representing the transform
*/
operator wmath::WMatrix4x4() const;
/**
* Check if this transform does not include a rotation.
*
......
......@@ -156,6 +156,49 @@ osg::ref_ptr< osg::Geometry > wge::createUnitCube( const WColor& color )
return cube;
}
osg::ref_ptr< osg::Geometry > wge::createUnitCubeAsLines( const WColor& color )
{
// create the unit cube manually as the ShapeDrawable and osg::Box does not provide 3D texture coordinates
osg::ref_ptr< osg::Geometry > cube = new osg::Geometry();
osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array );
vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) );
vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) );
cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, vertices->size() ) );
vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) );
vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) );
vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) );
vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) );
vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) );
vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) );
cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINES, vertices->size() - 6, 6 ) );
// set it up and set arrays
cube->setVertexArray( vertices );
// set 3D texture coordinates here.
cube->setTexCoordArray( 0, vertices );
// finally, the colors
colors->push_back( color );
cube->setColorArray( colors );
cube->setColorBinding( osg::Geometry::BIND_OVERALL );
return cube;
}
osg::ref_ptr< osg::Node > wge::generateSolidBoundingBoxNode( const WBoundingBox& bb, const WColor& color, bool threeDTexCoords )
{
WAssert( bb.valid(), "Invalid bounding box!" );
......
......@@ -79,6 +79,15 @@ namespace wge
*/
osg::ref_ptr< osg::Geometry > WGE_EXPORT createUnitCube( const WColor& color );
/**
* Creates a osg::Geometry containing an unit cube as line-strips, having 3D texture coordinates.
*
* \param color the color to set for all vertices
*
* \return the geometry
*/
osg::ref_ptr< osg::Geometry > WGE_EXPORT createUnitCubeAsLines( const WColor& color );
/**
* Extract the vertices and triangles from a WTriangleMesh and save them
* into an osg::Geometry.
......
//---------------------------------------------------------------------------
//
// 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 <sstream>
#include "../callbacks/WGEFunctorCallback.h"
#include "../WGEGeodeUtils.h"
#include "WGEGridNode.h"
WGEGridNode::WGEGridNode( WGridRegular3D::ConstSPtr grid ):
m_boundaryGeode( new osg::Geode() ),
m_innerGridGeode( new osg::Geode() ),
m_labelGeode( new osg::Geode() ),
m_gridUpdate( true ),
m_showLabels( true )
{
m_grid.getWriteTicket()->get() = grid;
// init the boundary geometry
m_boundaryGeode->addDrawable( wge::createUnitCubeAsLines( WColor( 0.3, 0.3, 0.3, 1.0 ) ) );
// init labels
// Therefore: create prototype
WGELabel::SPtr label = new WGELabel();
label->setAlignment( osgText::Text::CENTER_TOP );
label->setColor( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) );
// add several copies and set position accordingly
// Front face ( z = 0 )
// bottom left
label->setPosition( osg::Vec3( 0.0, 0.0, 0.0 ) );
label->setCharacterSize( 6 );
m_labelGeode->addDrawable( label );
m_borderLabels[0] = label;
// bottom right
label = new WGELabel( *label );
label->setPosition( osg::Vec3( 1.0, 0.0, 0.0 ) );
m_labelGeode->addDrawable( label );
m_borderLabels[1] = label;
// top right
label = new WGELabel( *label );
label->setPosition( osg::Vec3( 1.0, 1.0, 0.0 ) );
m_labelGeode->addDrawable( label );
m_borderLabels[2] = label;
// top left
label = new WGELabel( *label );
label->setPosition( osg::Vec3( 0.0, 1.0, 0.0 ) );
m_labelGeode->addDrawable( label );
m_borderLabels[3] = label;
// Back face ( z = 1 )
// bottom left
label = new WGELabel( *label );
label->setPosition( osg::Vec3( 0.0, 0.0, 1.0 ) );
m_labelGeode->addDrawable( label );
m_borderLabels[4] = label;
// bottom right
label = new WGELabel( *label );
label->setPosition( osg::Vec3( 1.0, 0.0, 1.0 ) );
m_labelGeode->addDrawable( label );
m_borderLabels[5] = label;
// top right
label = new WGELabel( *label );
label->setPosition( osg::Vec3( 1.0, 1.0, 1.0 ) );
m_labelGeode->addDrawable( label );
m_borderLabels[6] = label;
// top left
label = new WGELabel( *label );
label->setPosition( osg::Vec3( 0.0, 1.0, 1.0 ) );
m_labelGeode->addDrawable( label );
m_borderLabels[7] = label;
// add the others too
addChild( m_boundaryGeode );
addChild( m_innerGridGeode );
addChild( m_labelGeode );
addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WGEGridNode::callback, this, _1 ) ) );
// no blending
getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::OFF );
// disable light for this node
getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED );
}
WGEGridNode::~WGEGridNode()
{
// cleanup
}
void WGEGridNode::setGrid( WGridRegular3D::ConstSPtr grid )
{
m_grid.getWriteTicket()->get() = grid;
m_gridUpdate = true;
}
WGridRegular3D::ConstSPtr WGEGridNode::getGrid() const
{
return m_grid.getReadTicket()->get();
}
bool WGEGridNode::getEnableLabels() const
{
return m_showLabels;
}
void WGEGridNode::setEnableLabels( bool enable )
{
m_showLabels = enable;
m_gridUpdate = true;
}
/**
* Simply converts the vector to an string.
*
* \param vec the vector
*
* \return string representation
*/
std::string vec2str( osg::Vec3 vec )
{
std::ostringstream os;
os.precision( 5 );
os << "(" << vec[0] << "," << vec[1] << "," << vec[2] << ")";
return os.str();
}
void WGEGridNode::callback( osg::Node* /*node*/ )
{
if ( m_gridUpdate )
{
// grab the grid
WGridRegular3D::ConstSPtr grid = m_grid.getReadTicket()->get();
// apply the grid transformation
osg::Matrix m = osg::Matrix::scale( grid->getNbCoordsX() - 1, grid->getNbCoordsY() - 1, grid->getNbCoordsZ() - 1 ) *
grid->getTransform();
setMatrix( m );
// set the labels correspondingly
for ( size_t i = 0; i < 8; ++i )
{
m_borderLabels[i]->setText( vec2str( m_borderLabels[i]->getPosition() * m ) );
}
// set node mask of labels
m_labelGeode->setNodeMask( 0xFFFFFFFF * m_showLabels );
m_gridUpdate = false;
}
}
//---------------------------------------------------------------------------
//
// 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 WGEGRIDNODE_H
#define WGEGRIDNODE_H
#include <osg/Geode>
#include <osg/MatrixTransform>
#include "../../dataHandler/WGridRegular3D.h"
#include "../../common/WSharedObject.h"
#include "../../common/WProperties_Fwd.h"
#include "../widgets/labeling/WGELabel.h"
#include "../WExportWGE.h"
/**
* This node is able to represent a grid in certain ways. It can show its boundary or the whole grid if desired.
*/
class WGE_EXPORT WGEGridNode: public osg::MatrixTransform
{
public:
/**
* Convenience typedef for a osg::ref_ptr< WGEGridNode >.
*/
typedef osg::ref_ptr< WGEGridNode > SPtr;
/**
* Convenience typedef for a osg::ref_ptr< const WGEGridNode >.
*/
typedef osg::ref_ptr< const WGEGridNode > ConstSPtr;
/**
* Creates a node representing the specified grid.
*
* \param grid the grid to represent.
*/
explicit WGEGridNode( WGridRegular3D::ConstSPtr grid );
/**
* Destructor.
*/
virtual ~WGEGridNode();
/**
* Updates the node to use the new specified grid
*
* \param grid the new grid to use
*/
void setGrid( WGridRegular3D::ConstSPtr grid );
/**
* Returns the currently set grid.
*
* \return the current grid.
*/
WGridRegular3D::ConstSPtr getGrid() const;
// TODO(all): add setter and getter for boundary colors and so on.
/**
* Returns whether labels on the corners are enabled or not.
*
* \return true if labels are enabled
*/
bool getEnableLabels() const;
/**
* En- or disable labels on the boundary corners.
*
* \param enable true to enbable
*/
void setEnableLabels( bool enable = true );
protected:
private:
/**
* The actual grid which should be represented by this node.
*/
WSharedObject< WGridRegular3D::ConstSPtr > m_grid;
/**
* The geometry for the boundary.
*/
osg::ref_ptr< osg::Geode > m_boundaryGeode;
/**
* The geometry for the whole grid.
*/
osg::ref_ptr< osg::Geode > m_innerGridGeode;
/**
* The labels at the corner.
*/
WGELabel::SPtr m_borderLabels[8];
/**
* The geode keeping the labels
*/
osg::ref_ptr< osg::Geode > m_labelGeode;
/**
* The actual callback handling changes in the grid
*
* \param node the node. This will be the this pointer.
*/
void callback( osg::Node* node );
/**
* If true, the labels and geometry gets adapted properly.
*/
bool m_gridUpdate;
/**
* If true, labels get used.
*/
bool m_showLabels;
};
#endif // WGEGRIDNODE_H
......@@ -40,6 +40,16 @@ class WGE_EXPORT WGELabel: public osgText::Text,
{
public:
/**
* Convenience typedef for a osg::ref_ptr< WGELabel >.
*/
typedef osg::ref_ptr< WGELabel > SPtr;
/**
* Convenience typedef for a osg::ref_ptr< const WGELabel >.
*/
typedef osg::ref_ptr< const WGELabel > ConstSPtr;
/**
* Default constructor.
*/
......
......@@ -40,6 +40,7 @@
#include "../../common/WStringUtils.h"
#include "../../dataHandler/WGridRegular3D.h"
#include "../../graphicsEngine/WGEGeodeUtils.h"
#include "../../graphicsEngine/callbacks/WGENodeMaskCallback.h"
#include "../../kernel/modules/data/WMData.h"
#include "../../kernel/WKernel.h"
#include "WMBoundingBox.h"
......@@ -95,6 +96,9 @@ void WMBoundingBox::moduleMain()
// loop until the module container requests the module to quit
while( !m_shutdownFlag() )
{
debugLog() << "Waiting for data ...";
m_moduleState.wait();
boost::shared_ptr< WDataSetSingle > dataSet = m_input->getData();
bool dataValid = ( dataSet );
......@@ -102,54 +106,32 @@ void WMBoundingBox::moduleMain()
{
// OK, the output has not yet sent data
// NOTE: see comment at the end of this while loop for m_moduleState
debugLog() << "Waiting for data ...";
m_moduleState.wait();
WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_gridNode );
continue;
}
createGFX();
// this waits for m_moduleState to fire. By default, this is only the m_shutdownFlag condition.
// NOTE: you can add your own conditions to m_moduleState using m_moduleState.add( ... )
m_moduleState.wait();
}
WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_bBoxNode );
}
void WMBoundingBox::createGFX()
{
boost::shared_ptr< WDataSetSingle > dataSet = m_input->getData();
boost::shared_ptr< WGridRegular3D > grid = boost::shared_dynamic_cast< WGridRegular3D >( dataSet->getGrid() );
WAssert( grid, "Seems that grid is of wrong type." );
WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_bBoxNode );
WBoundingBox bb = grid->getBoundingBox();
m_bBoxNode = osg::ref_ptr< WGEGroupNode >( new WGEGroupNode );
m_bBoxNode->setNodeMask( m_active->get() ? 0xFFFFFFFF : 0x0 );
WGridRegular3D::SPtr regGrid = boost::shared_dynamic_cast< WGridRegular3D >( dataSet->getGrid() );
if ( !regGrid )
{
// the data has no regular 3d grid.
errorLog() << "Dataset does not contain a regular 3D grid.";
WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_gridNode );
continue;
}
m_bBoxNode->insert( wge::generateBoundingBoxGeode( bb, WColor( 0.3, 0.3, 0.3, 1 ) ) );
// create the new grid node if it not exists
if ( !m_gridNode )
{
m_gridNode = new WGEGridNode( regGrid );
m_gridNode->addUpdateCallback( new WGENodeMaskCallback( m_active ) );
WGraphicsEngine::getGraphicsEngine()->getScene()->insert( m_gridNode );
}
if( m_showCornerCoordinates->get( true ) )
{
const wmath::WVector3D& pos1 = bb.getMin();
const wmath::WVector3D& pos2 = bb.getMax();
m_bBoxNode->addChild( wge::vector2label( osg::Vec3( pos1[0], pos1[1], pos1[2] ) ) );
m_bBoxNode->addChild( wge::vector2label( osg::Vec3( pos2[0], pos2[1], pos2[2] ) ) );
m_bBoxNode->addChild( wge::vector2label( osg::Vec3( pos2[0], pos2[1], pos1[2] ) ) );
m_bBoxNode->addChild( wge::vector2label( osg::Vec3( pos1[0], pos2[1], pos1[2] ) ) );
m_bBoxNode->addChild( wge::vector2label( osg::Vec3( pos2[0], pos1[1], pos1[2] ) ) );
m_bBoxNode->addChild( wge::vector2label( osg::Vec3( pos1[0], pos2[1], pos2[2] ) ) );
m_bBoxNode->addChild( wge::vector2label( osg::Vec3( pos2[0], pos1[1], pos2[2] ) ) );
m_bBoxNode->addChild( wge::vector2label( osg::Vec3( pos1[0], pos1[1], pos2[2] ) ) );
m_gridNode->setEnableLabels( m_showCornerCoordinates->get( true ) );
m_gridNode->setGrid( regGrid );
}
WGraphicsEngine::getGraphicsEngine()->getScene()->insert( m_bBoxNode );
WGraphicsEngine::getGraphicsEngine()->getScene()->remove( m_gridNode );
}