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