OpenWalnut 1.2.5
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #include <sstream> 00026 00027 #include <osg/LineWidth> 00028 00029 #include "../callbacks/WGEFunctorCallback.h" 00030 #include "../../common/math/linearAlgebra/WLinearAlgebra.h" 00031 #include "../WGEGeodeUtils.h" 00032 00033 #include "WGEGridNode.h" 00034 00035 WGEGridNode::WGEGridNode( WGridRegular3D::ConstSPtr grid ): 00036 m_boundaryGeode( new osg::Geode() ), 00037 m_innerGridGeode( new osg::Geode() ), 00038 m_labelGeode( new osg::Geode() ), 00039 m_gridUpdate( true ), 00040 m_gridGeometryUpdate( true ), 00041 m_showLabels( true ), 00042 m_bbColor( WColor( 0.3, 0.3, 0.3, 1.0 ) ), 00043 m_gridColor( WColor( 0.1, 0.1, 0.1, 1.0 ) ) 00044 { 00045 m_grid.getWriteTicket()->get() = grid; 00046 00047 // init the boundary geometry 00048 m_boundaryGeode->addDrawable( wge::createUnitCubeAsLines( m_bbColor ) ); 00049 00050 // init labels 00051 // Therefore: create prototype 00052 WGELabel::SPtr label = new WGELabel(); 00053 label->setAlignment( osgText::Text::CENTER_TOP ); 00054 label->setColor( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) ); 00055 00056 // add several copies and set position accordingly 00057 00058 // Front face ( z = 0 ) 00059 // bottom left 00060 label->setPosition( osg::Vec3( 0.0, 0.0, 0.0 ) ); 00061 label->setCharacterSize( 6 ); 00062 m_labelGeode->addDrawable( label ); 00063 m_borderLabels[0] = label; 00064 00065 // bottom right 00066 label = new WGELabel( *label ); 00067 label->setPosition( osg::Vec3( 1.0, 0.0, 0.0 ) ); 00068 m_labelGeode->addDrawable( label ); 00069 m_borderLabels[1] = label; 00070 00071 // top right 00072 label = new WGELabel( *label ); 00073 label->setPosition( osg::Vec3( 1.0, 1.0, 0.0 ) ); 00074 m_labelGeode->addDrawable( label ); 00075 m_borderLabels[2] = label; 00076 00077 // top left 00078 label = new WGELabel( *label ); 00079 label->setPosition( osg::Vec3( 0.0, 1.0, 0.0 ) ); 00080 m_labelGeode->addDrawable( label ); 00081 m_borderLabels[3] = label; 00082 00083 // Back face ( z = 1 ) 00084 // bottom left 00085 label = new WGELabel( *label ); 00086 label->setPosition( osg::Vec3( 0.0, 0.0, 1.0 ) ); 00087 m_labelGeode->addDrawable( label ); 00088 m_borderLabels[4] = label; 00089 00090 // bottom right 00091 label = new WGELabel( *label ); 00092 label->setPosition( osg::Vec3( 1.0, 0.0, 1.0 ) ); 00093 m_labelGeode->addDrawable( label ); 00094 m_borderLabels[5] = label; 00095 00096 // top right 00097 label = new WGELabel( *label ); 00098 label->setPosition( osg::Vec3( 1.0, 1.0, 1.0 ) ); 00099 m_labelGeode->addDrawable( label ); 00100 m_borderLabels[6] = label; 00101 00102 // top left 00103 label = new WGELabel( *label ); 00104 label->setPosition( osg::Vec3( 0.0, 1.0, 1.0 ) ); 00105 m_labelGeode->addDrawable( label ); 00106 m_borderLabels[7] = label; 00107 00108 // add the others too 00109 addChild( m_boundaryGeode ); 00110 addChild( m_innerGridGeode ); 00111 addChild( m_labelGeode ); 00112 00113 m_boundaryGeode->getOrCreateStateSet()->setAttributeAndModes( new osg::LineWidth( 4.0 ), osg::StateAttribute::ON ); 00114 00115 addUpdateCallback( new WGEFunctorCallback< osg::Node >( boost::bind( &WGEGridNode::callback, this, _1 ) ) ); 00116 00117 // no blending 00118 getOrCreateStateSet()->setMode( GL_BLEND, osg::StateAttribute::OFF ); 00119 // disable light for this node 00120 getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED ); 00121 } 00122 00123 WGEGridNode::~WGEGridNode() 00124 { 00125 // cleanup 00126 } 00127 00128 void WGEGridNode::setGrid( WGridRegular3D::ConstSPtr grid ) 00129 { 00130 m_grid.getWriteTicket()->get() = grid; 00131 m_gridUpdate = true; 00132 m_gridGeometryUpdate = true; 00133 } 00134 00135 WGridRegular3D::ConstSPtr WGEGridNode::getGrid() const 00136 { 00137 return m_grid.getReadTicket()->get(); 00138 } 00139 00140 bool WGEGridNode::getEnableLabels() const 00141 { 00142 return m_showLabels; 00143 } 00144 00145 void WGEGridNode::setEnableLabels( bool enable ) 00146 { 00147 m_showLabels = enable; 00148 m_gridUpdate = true; 00149 } 00150 00151 bool WGEGridNode::getEnableBBox() const 00152 { 00153 return m_showBBox; 00154 } 00155 00156 void WGEGridNode::setEnableBBox( bool enable ) 00157 { 00158 m_showBBox = enable; 00159 m_gridUpdate = true; 00160 } 00161 00162 bool WGEGridNode::getEnableGrid() const 00163 { 00164 return m_showGrid; 00165 } 00166 00167 void WGEGridNode::setEnableGrid( bool enable ) 00168 { 00169 m_showGrid = enable; 00170 m_gridUpdate = true; 00171 } 00172 00173 const WColor& WGEGridNode::getBBoxColor() const 00174 { 00175 return m_bbColor; 00176 } 00177 00178 void WGEGridNode::setBBoxColor( const WColor& color ) 00179 { 00180 m_bbColor = color; 00181 m_gridUpdate = true; 00182 } 00183 00184 const WColor& WGEGridNode::getGridColor() const 00185 { 00186 return m_gridColor; 00187 } 00188 00189 void WGEGridNode::setGridColor( const WColor& color ) 00190 { 00191 m_gridColor = color; 00192 m_gridUpdate = true; 00193 } 00194 00195 /** 00196 * Simply converts the vector to an string. 00197 * 00198 * \param vec the vector 00199 * 00200 * \return string representation 00201 */ 00202 std::string vec2str( osg::Vec3 vec ) 00203 { 00204 std::ostringstream os; 00205 os.precision( 5 ); 00206 os << "(" << vec[0] << "," << vec[1] << "," << vec[2] << ")"; 00207 return os.str(); 00208 } 00209 00210 void WGEGridNode::callback( osg::Node* /*node*/ ) 00211 { 00212 if( m_gridUpdate ) 00213 { 00214 // grab the grid 00215 WGridRegular3D::ConstSPtr grid = m_grid.getReadTicket()->get(); 00216 00217 // apply the grid transformation 00218 osg::Matrix m = osg::Matrix::scale( grid->getNbCoordsX() - 1, grid->getNbCoordsY() - 1, grid->getNbCoordsZ() - 1 ) * 00219 static_cast< osg::Matrixd >( static_cast< WMatrix4d >( grid->getTransform() ) ); 00220 setMatrix( m ); 00221 00222 // set the labels correspondingly 00223 for( size_t i = 0; i < 8; ++i ) 00224 { 00225 m_borderLabels[i]->setText( vec2str( m_borderLabels[i]->getPosition() * m ) ); 00226 } 00227 00228 // set node mask of labels, bbox and grid 00229 m_labelGeode->setNodeMask( 0xFFFFFFFF * m_showLabels ); 00230 m_boundaryGeode->setNodeMask( 0xFFFFFFFF * m_showBBox ); 00231 m_innerGridGeode->setNodeMask( 0xFFFFFFFF * m_showGrid ); 00232 00233 // color 00234 osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00235 colors->push_back( m_bbColor ); 00236 m_boundaryGeode->getDrawable( 0 )->asGeometry()->setColorArray( colors ); 00237 00238 // set color for grid too 00239 if( m_innerGridGeode->getNumDrawables() ) 00240 { 00241 osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00242 colors->push_back( m_gridColor ); 00243 m_innerGridGeode->getDrawable( 0 )->asGeometry()->setColorArray( colors ); 00244 } 00245 00246 m_gridUpdate = false; 00247 } 00248 00249 // recreate grid? 00250 if( m_gridGeometryUpdate && m_showGrid ) 00251 { 00252 // grab the grid 00253 WGridRegular3D::ConstSPtr grid = m_grid.getReadTicket()->get(); 00254 00255 osg::Geometry* gridGeometry = new osg::Geometry(); 00256 osg::ref_ptr< osg::Vec3Array > vertArray = new osg::Vec3Array( grid->size() ); 00257 00258 osg::DrawElementsUInt* gridElement = new osg::DrawElementsUInt( osg::PrimitiveSet::LINES, 0 ); 00259 gridElement->reserve( grid->size() * 2 ); 00260 00261 size_t sx = grid->getNbCoordsX(); 00262 size_t sy = grid->getNbCoordsY(); 00263 size_t sz = grid->getNbCoordsZ(); 00264 for( unsigned int vertIdX = 0; vertIdX < sx; ++vertIdX ) 00265 { 00266 for( unsigned int vertIdY = 0; vertIdY < sy; ++vertIdY ) 00267 { 00268 for( unsigned int vertIdZ = 0; vertIdZ < sz; ++vertIdZ ) 00269 { 00270 size_t id = vertIdX + vertIdY * sx + vertIdZ * sx * sy; 00271 00272 ( *vertArray )[id][0] = static_cast< float >( vertIdX ) / static_cast< float >( sx - 1 ); 00273 ( *vertArray )[id][1] = static_cast< float >( vertIdY ) / static_cast< float >( sy - 1 ); 00274 ( *vertArray )[id][2] = static_cast< float >( vertIdZ ) / static_cast< float >( sz - 1 ); 00275 00276 if( vertIdX < sx - 1 ) 00277 { 00278 gridElement->push_back( id ); 00279 gridElement->push_back( id + 1 ); 00280 } 00281 00282 if( vertIdY < sy - 1 ) 00283 { 00284 gridElement->push_back( id ); 00285 gridElement->push_back( id + sx ); 00286 } 00287 00288 if( vertIdZ < sz - 1 ) 00289 { 00290 gridElement->push_back( id ); 00291 gridElement->push_back( id + sx * sy ); 00292 } 00293 } 00294 } 00295 } 00296 00297 // done. Add it 00298 gridGeometry->setVertexArray( vertArray ); 00299 gridGeometry->addPrimitiveSet( gridElement ); 00300 00301 osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00302 // finally, the colors 00303 colors->push_back( m_gridColor ); 00304 gridGeometry->setColorArray( colors ); 00305 gridGeometry->setColorBinding( osg::Geometry::BIND_OVERALL ); 00306 00307 if( m_innerGridGeode->getNumDrawables() ) 00308 { 00309 m_innerGridGeode->setDrawable( 0, gridGeometry ); 00310 } 00311 else 00312 { 00313 m_innerGridGeode->addDrawable( gridGeometry ); 00314 } 00315 00316 // we create a unit cube here as the transformation matrix already contains the proper scaling. 00317 m_gridGeometryUpdate = false; 00318 } 00319 } 00320