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 <string> 00026 00027 #include <osg/Array> 00028 #include <osg/Geode> 00029 #include <osg/Geometry> 00030 #include <osg/LineWidth> 00031 #include <osg/MatrixTransform> 00032 #include <osg/ShapeDrawable> 00033 #include <osg/Vec3> 00034 #include <osg/LightModel> 00035 #include <osg/Material> 00036 00037 #include "../common/math/linearAlgebra/WLinearAlgebra.h" 00038 #include "../common/WPathHelper.h" 00039 #include "../common/math/WMath.h" 00040 #include "WGESubdividedPlane.h" 00041 #include "WGEGeodeUtils.h" 00042 #include "WGEGeometryUtils.h" 00043 #include "WGEUtils.h" 00044 #include "WGEGroupNode.h" 00045 #include "shaders/WGEShader.h" 00046 #include "widgets/labeling/WGELabel.h" 00047 00048 osg::ref_ptr< osg::Geode > wge::generateBoundingBoxGeode( const WBoundingBox& bb, const WColor& color ) 00049 { 00050 const WBoundingBox::vec_type& pos1 = bb.getMin(); 00051 const WBoundingBox::vec_type& pos2 = bb.getMax(); 00052 00053 WAssert( pos1[0] <= pos2[0] && pos1[1] <= pos2[1] && pos1[2] <= pos2[2], "pos1 does not seem to be the frontLowerLeft corner of the BB!" ); 00054 using osg::ref_ptr; 00055 ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array ); 00056 ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00057 ref_ptr< osg::Geometry > geometry = ref_ptr< osg::Geometry >( new osg::Geometry ); 00058 00059 vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos1[2] ) ); 00060 vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos1[2] ) ); 00061 vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos1[2] ) ); 00062 vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos1[2] ) ); 00063 vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos1[2] ) ); 00064 vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos2[2] ) ); 00065 vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos2[2] ) ); 00066 vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos2[2] ) ); 00067 vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos2[2] ) ); 00068 vertices->push_back( osg::Vec3( pos1[0], pos1[1], pos2[2] ) ); 00069 00070 geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, vertices->size() ) ); 00071 00072 vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos1[2] ) ); 00073 vertices->push_back( osg::Vec3( pos1[0], pos2[1], pos2[2] ) ); 00074 vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos1[2] ) ); 00075 vertices->push_back( osg::Vec3( pos2[0], pos2[1], pos2[2] ) ); 00076 vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos1[2] ) ); 00077 vertices->push_back( osg::Vec3( pos2[0], pos1[1], pos2[2] ) ); 00078 00079 geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINES, vertices->size() - 6, 6 ) ); 00080 00081 geometry->setVertexArray( vertices ); 00082 colors->push_back( color ); 00083 geometry->setColorArray( colors ); 00084 geometry->setColorBinding( osg::Geometry::BIND_OVERALL ); 00085 osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode ); 00086 geode->addDrawable( geometry ); 00087 00088 // disable light for this geode as lines can't be lit properly 00089 osg::StateSet* state = geode->getOrCreateStateSet(); 00090 state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED ); 00091 00092 return geode; 00093 } 00094 00095 osg::ref_ptr< osg::Geometry > wge::createUnitCube( const WColor& color ) 00096 { 00097 // create the unit cube manually as the ShapeDrawable and osg::Box does not provide 3D texture coordinates 00098 osg::ref_ptr< osg::Geometry > cube = new osg::Geometry(); 00099 osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array ); 00100 osg::ref_ptr< osg::Vec3Array > normals = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array ); 00101 osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00102 00103 // front face 00104 vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) ); 00105 vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) ); 00106 vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) ); 00107 vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) ); 00108 normals->push_back( osg::Vec3( 0.0, 0.0, -1.0 ) ); 00109 00110 // back face 00111 vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) ); 00112 vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) ); 00113 vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) ); 00114 vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) ); 00115 normals->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) ); 00116 00117 // left 00118 vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) ); 00119 vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) ); 00120 vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) ); 00121 vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) ); 00122 normals->push_back( osg::Vec3( -1.0, 0.0, 0.0 ) ); 00123 00124 // right 00125 vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) ); 00126 vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) ); 00127 vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) ); 00128 vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) ); 00129 normals->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) ); 00130 00131 // bottom 00132 vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) ); 00133 vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) ); 00134 vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) ); 00135 vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) ); 00136 normals->push_back( osg::Vec3( 0.0, -1.0, 0.0 ) ); 00137 00138 // top 00139 vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) ); 00140 vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) ); 00141 vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) ); 00142 vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) ); 00143 normals->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) ); 00144 00145 // set it up and set arrays 00146 cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, vertices->size() ) ); 00147 cube->setVertexArray( vertices ); 00148 00149 // set 3D texture coordinates here. 00150 cube->setTexCoordArray( 0, vertices ); 00151 00152 // set normals 00153 cube->setNormalArray( normals ); 00154 cube->setNormalBinding( osg::Geometry::BIND_PER_PRIMITIVE ); 00155 00156 // finally, the colors 00157 colors->push_back( color ); 00158 cube->setColorArray( colors ); 00159 cube->setColorBinding( osg::Geometry::BIND_OVERALL ); 00160 00161 return cube; 00162 } 00163 00164 osg::ref_ptr< osg::Geometry > wge::createUnitCubeAsLines( const WColor& color ) 00165 { 00166 // create the unit cube manually as the ShapeDrawable and osg::Box does not provide 3D texture coordinates 00167 osg::ref_ptr< osg::Geometry > cube = new osg::Geometry(); 00168 osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array ); 00169 osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00170 00171 vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) ); 00172 vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) ); 00173 vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) ); 00174 vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) ); 00175 vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) ); 00176 vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) ); 00177 vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) ); 00178 vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) ); 00179 vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) ); 00180 vertices->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) ); 00181 00182 cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, vertices->size() ) ); 00183 00184 vertices->push_back( osg::Vec3( 0.0, 1.0, 0.0 ) ); 00185 vertices->push_back( osg::Vec3( 0.0, 1.0, 1.0 ) ); 00186 vertices->push_back( osg::Vec3( 1.0, 0.0, 0.0 ) ); 00187 vertices->push_back( osg::Vec3( 1.0, 0.0, 1.0 ) ); 00188 vertices->push_back( osg::Vec3( 1.0, 1.0, 0.0 ) ); 00189 vertices->push_back( osg::Vec3( 1.0, 1.0, 1.0 ) ); 00190 00191 cube->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINES, vertices->size() - 6, 6 ) ); 00192 00193 // set it up and set arrays 00194 cube->setVertexArray( vertices ); 00195 00196 // set 3D texture coordinates here. 00197 cube->setTexCoordArray( 0, vertices ); 00198 00199 // finally, the colors 00200 colors->push_back( color ); 00201 cube->setColorArray( colors ); 00202 cube->setColorBinding( osg::Geometry::BIND_OVERALL ); 00203 00204 return cube; 00205 } 00206 00207 osg::ref_ptr< osg::Node > wge::generateSolidBoundingBoxNode( const WBoundingBox& bb, const WColor& color, bool threeDTexCoords ) 00208 { 00209 WAssert( bb.valid(), "Invalid bounding box!" ); 00210 00211 // create a uni cube 00212 osg::ref_ptr< osg::Geode > cube = new osg::Geode(); 00213 cube->setName( "Solid Bounding Box" ); 00214 if( threeDTexCoords ) 00215 { 00216 cube->addDrawable( createUnitCube( color ) ); 00217 } 00218 else 00219 { 00220 osg::ref_ptr< osg::ShapeDrawable > cubeDrawable = new osg::ShapeDrawable( new osg::Box( osg::Vec3( 0.5, 0.5, 0.5 ), 1.0 ) ); 00221 cubeDrawable->setColor( color ); 00222 cube->addDrawable( cubeDrawable ); 00223 } 00224 00225 // transform the cube to match the bbox 00226 osg::Matrixd transformM; 00227 osg::Matrixd scaleM; 00228 transformM.makeTranslate( bb.getMin() ); 00229 scaleM.makeScale( bb.getMax() - bb.getMin() ); 00230 00231 // apply transformation to bbox 00232 osg::ref_ptr< osg::MatrixTransform > transform = new osg::MatrixTransform(); 00233 transform->setMatrix( scaleM * transformM ); 00234 transform->addChild( cube ); 00235 00236 // we do not need light 00237 osg::StateSet* state = cube->getOrCreateStateSet(); 00238 state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED ); 00239 00240 return transform; 00241 } 00242 00243 osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh, 00244 const WColor& defaultColor, 00245 bool includeNormals, 00246 bool lighting, 00247 bool useMeshColor ) 00248 { 00249 osg::ref_ptr< osg::Geometry> geometry( new osg::Geometry ); 00250 geometry->setVertexArray( mesh->getVertexArray() ); 00251 00252 osg::DrawElementsUInt* surfaceElement; 00253 00254 surfaceElement = new osg::DrawElementsUInt( osg::PrimitiveSet::TRIANGLES, 0 ); 00255 00256 std::vector< size_t > tris = mesh->getTriangles(); 00257 surfaceElement->reserve( tris.size() ); 00258 00259 for( unsigned int vertId = 0; vertId < tris.size(); ++vertId ) 00260 { 00261 surfaceElement->push_back( tris[vertId] ); 00262 } 00263 geometry->addPrimitiveSet( surfaceElement ); 00264 00265 // add the mesh colors 00266 if( mesh->getVertexColorArray() && useMeshColor ) 00267 { 00268 geometry->setColorArray( mesh->getVertexColorArray() ); 00269 geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 00270 } 00271 else 00272 { 00273 osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00274 colors->push_back( defaultColor ); 00275 geometry->setColorArray( colors ); 00276 geometry->setColorBinding( osg::Geometry::BIND_OVERALL ); 00277 } 00278 00279 // ------------------------------------------------ 00280 // normals 00281 if( includeNormals ) 00282 { 00283 geometry->setNormalArray( mesh->getVertexNormalArray() ); 00284 geometry->setNormalBinding( osg::Geometry::BIND_PER_VERTEX ); 00285 00286 if( lighting ) 00287 { 00288 // if normals are specified, we also setup a default lighting. 00289 osg::StateSet* state = geometry->getOrCreateStateSet(); 00290 osg::ref_ptr<osg::LightModel> lightModel = new osg::LightModel(); 00291 lightModel->setTwoSided( true ); 00292 state->setAttributeAndModes( lightModel.get(), osg::StateAttribute::ON ); 00293 state->setMode( GL_BLEND, osg::StateAttribute::ON ); 00294 { 00295 osg::ref_ptr< osg::Material > material = new osg::Material(); 00296 material->setDiffuse( osg::Material::FRONT, osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) ); 00297 material->setSpecular( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) ); 00298 material->setAmbient( osg::Material::FRONT, osg::Vec4( 0.1, 0.1, 0.1, 1.0 ) ); 00299 material->setEmission( osg::Material::FRONT, osg::Vec4( 0.0, 0.0, 0.0, 1.0 ) ); 00300 material->setShininess( osg::Material::FRONT, 25.0 ); 00301 state->setAttribute( material ); 00302 } 00303 } 00304 } 00305 00306 // enable VBO 00307 geometry->setUseDisplayList( false ); 00308 geometry->setUseVertexBufferObjects( true ); 00309 00310 return geometry; 00311 } 00312 00313 osg::ref_ptr< osg::Geometry > wge::convertToOsgGeometry( WTriangleMesh::SPtr mesh, const WColoredVertices& colorMap, const WColor& defaultColor, 00314 bool includeNormals, bool lighting ) 00315 { 00316 osg::Geometry* geometry = convertToOsgGeometry( mesh, defaultColor, includeNormals, lighting, false ); 00317 00318 // ------------------------------------------------ 00319 // colors 00320 osg::ref_ptr< osg::Vec4Array > colors = osg::ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00321 for( size_t i = 0; i < mesh->vertSize(); ++i ) 00322 { 00323 colors->push_back( defaultColor ); 00324 } 00325 for( std::map< size_t, WColor >::const_iterator vc = colorMap.getData().begin(); vc != colorMap.getData().end(); ++vc ) 00326 { 00327 // ATTENTION: the colormap might not be available and hence an old one, but the new mesh might have triggered the update 00328 if( vc->first < colors->size() ) 00329 { 00330 colors->at( vc->first ) = vc->second; 00331 } 00332 } 00333 00334 geometry->setColorArray( colors ); 00335 geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 00336 00337 return geometry; 00338 } 00339 00340 osg::ref_ptr< osg::Geode > wge::generateLineStripGeode( const WLine& line, const float thickness, const WColor& color ) 00341 { 00342 using osg::ref_ptr; 00343 ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array ); 00344 ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00345 ref_ptr< osg::Geometry > geometry = ref_ptr< osg::Geometry >( new osg::Geometry ); 00346 00347 for( size_t i = 1; i < line.size(); ++i ) 00348 { 00349 vertices->push_back( osg::Vec3( line[i-1][0], line[i-1][1], line[i-1][2] ) ); 00350 colors->push_back( wge::getRGBAColorFromDirection( line[i-1], line[i] ) ); 00351 } 00352 vertices->push_back( osg::Vec3( line.back()[0], line.back()[1], line.back()[2] ) ); 00353 colors->push_back( colors->back() ); 00354 00355 geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, line.size() ) ); 00356 geometry->setVertexArray( vertices ); 00357 00358 if( color != WColor( 0, 0, 0, 0 ) ) 00359 { 00360 colors->clear(); 00361 colors->push_back( color ); 00362 geometry->setColorArray( colors ); 00363 geometry->setColorBinding( osg::Geometry::BIND_OVERALL ); 00364 } 00365 else 00366 { 00367 geometry->setColorArray( colors ); 00368 geometry->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 00369 } 00370 00371 // line width 00372 osg::StateSet* stateset = geometry->getOrCreateStateSet(); 00373 stateset->setAttributeAndModes( new osg::LineWidth( thickness ), osg::StateAttribute::ON ); 00374 stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); 00375 00376 osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode ); 00377 geode->addDrawable( geometry ); 00378 return geode; 00379 } 00380 00381 osg::ref_ptr< osg::PositionAttitudeTransform > wge::addLabel( osg::Vec3 position, std::string text ) 00382 { 00383 osg::ref_ptr< osgText::Text > label = osg::ref_ptr< osgText::Text >( new osgText::Text() ); 00384 osg::ref_ptr< osg::Geode > labelGeode = osg::ref_ptr< osg::Geode >( new osg::Geode() ); 00385 00386 labelGeode->addDrawable( label ); 00387 00388 // setup font 00389 label->setFont( WPathHelper::getAllFonts().Default.file_string() ); 00390 label->setBackdropType( osgText::Text::OUTLINE ); 00391 label->setCharacterSize( 6 ); 00392 00393 label->setText( text ); 00394 label->setAxisAlignment( osgText::Text::SCREEN ); 00395 label->setDrawMode( osgText::Text::TEXT ); 00396 label->setAlignment( osgText::Text::CENTER_TOP ); 00397 label->setPosition( osg::Vec3( 0.0, 0.0, 0.0 ) ); 00398 label->setColor( osg::Vec4( 1.0f, 1.0f, 1.0f, 1.0f ) ); 00399 00400 osg::ref_ptr< osg::PositionAttitudeTransform > labelXform = 00401 osg::ref_ptr< osg::PositionAttitudeTransform >( new osg::PositionAttitudeTransform() ); 00402 labelXform->setPosition( position ); 00403 00404 labelXform->addChild( labelGeode ); 00405 00406 return labelXform; 00407 } 00408 00409 osg::ref_ptr< osg::PositionAttitudeTransform > wge::vector2label( osg::Vec3 position ) 00410 { 00411 std::string label = "(" + boost::lexical_cast< std::string >( position[0] ) + "," + 00412 boost::lexical_cast< std::string >( position[1] ) + "," + boost::lexical_cast< std::string >( position[2] ) + ")"; 00413 return ( addLabel( position, label ) ); 00414 } 00415 00416 osg::ref_ptr< osg::Geode > wge::genFinitePlane( double xSize, double ySize, const WPlane& p, const WColor& color, bool border ) 00417 { 00418 using osg::ref_ptr; 00419 ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array ); 00420 ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00421 ref_ptr< osg::Geometry > geometry = ref_ptr< osg::Geometry >( new osg::Geometry ); 00422 00423 colors->push_back( color ); 00424 00425 vertices->push_back( p.getPointInPlane( xSize, ySize ) ); 00426 vertices->push_back( p.getPointInPlane( -xSize, ySize ) ); 00427 vertices->push_back( p.getPointInPlane( -xSize, -ySize ) ); 00428 vertices->push_back( p.getPointInPlane( xSize, -ySize ) ); 00429 00430 geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) ); 00431 geometry->setVertexArray( vertices ); 00432 geometry->setColorArray( colors ); 00433 geometry->setColorBinding( osg::Geometry::BIND_OVERALL ); 00434 00435 osg::StateSet* stateset = new osg::StateSet; 00436 stateset->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); 00437 geometry->setStateSet( stateset ); 00438 00439 osg::ref_ptr< osg::Geode > geode = osg::ref_ptr< osg::Geode >( new osg::Geode ); 00440 geode->addDrawable( geometry ); 00441 00442 if( border ) 00443 { 00444 vertices->push_back( vertices->front() ); 00445 ref_ptr< osg::Geometry > borderGeom = ref_ptr< osg::Geometry >( new osg::Geometry ); 00446 borderGeom->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 0, 4 ) ); 00447 borderGeom->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::LINE_STRIP, 3, 2 ) ); 00448 ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array ); 00449 colors->push_back( inverseColor( color ) ); 00450 borderGeom->setColorArray( colors ); 00451 borderGeom->setColorBinding( osg::Geometry::BIND_OVERALL ); 00452 borderGeom->setVertexArray( vertices ); 00453 geode->addDrawable( borderGeom ); 00454 } 00455 return geode; 00456 } 00457 00458 osg::ref_ptr< osg::Geode > wge::genFinitePlane( osg::Vec3 const& base, osg::Vec3 const& a, osg::Vec3 const& b ) 00459 { 00460 // the stuff needed by the OSG to create a geometry instance 00461 osg::ref_ptr< osg::Vec3Array > vertices = new osg::Vec3Array; 00462 osg::ref_ptr< osg::Vec3Array > texcoords0 = new osg::Vec3Array; 00463 osg::ref_ptr< osg::Vec3Array > normals = new osg::Vec3Array; 00464 osg::ref_ptr< osg::Vec4Array > colors = new osg::Vec4Array; 00465 00466 osg::Vec3 aPlusB = a + b; 00467 00468 vertices->push_back( base ); 00469 vertices->push_back( base + a ); 00470 vertices->push_back( base + aPlusB ); 00471 vertices->push_back( base + b ); 00472 00473 osg::Vec3 aCrossB = a ^ b; 00474 aCrossB.normalize(); 00475 osg::Vec3 aNorm = a; 00476 aNorm.normalize(); 00477 osg::Vec3 bNorm = b; 00478 bNorm.normalize(); 00479 00480 normals->push_back( aCrossB ); 00481 colors->push_back( osg::Vec4( 1.0, 1.0, 1.0, 1.0 ) ); 00482 texcoords0->push_back( osg::Vec3( 0.0, 0.0, 0.0 ) ); 00483 texcoords0->push_back( aNorm ); 00484 texcoords0->push_back( aNorm + bNorm ); 00485 texcoords0->push_back( bNorm ); 00486 00487 // put it all together 00488 osg::ref_ptr< osg::Geometry > geometry = new osg::Geometry(); 00489 geometry->setVertexArray( vertices ); 00490 geometry->setTexCoordArray( 0, texcoords0 ); 00491 geometry->setNormalBinding( osg::Geometry::BIND_OVERALL ); 00492 geometry->setColorBinding( osg::Geometry::BIND_OVERALL ); 00493 geometry->setNormalArray( normals ); 00494 geometry->setColorArray( colors ); 00495 geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) ); 00496 00497 osg::ref_ptr< osg::Geode > geode = new osg::Geode(); 00498 geode->addDrawable( geometry ); 00499 return geode; 00500 } 00501 00502 osg::ref_ptr< WGESubdividedPlane > wge::genUnitSubdividedPlane( size_t resX, size_t resY, double spacing ) 00503 { 00504 WAssert( resX > 0 && resY > 0, "A Plane with no quad is not supported, use another datatype for that!" ); 00505 double dx = ( resX > 1 ? 1.0 / ( resX - 1 ) : 1.0 ); 00506 double dy = ( resY > 1 ? 1.0 / ( resY - 1 ) : 1.0 ); 00507 00508 size_t numQuads = resX * resY; 00509 00510 using osg::ref_ptr; 00511 ref_ptr< osg::Vec3Array > vertices = ref_ptr< osg::Vec3Array >( new osg::Vec3Array( numQuads * 4 ) ); 00512 ref_ptr< osg::Vec3Array > centers = ref_ptr< osg::Vec3Array >( new osg::Vec3Array( numQuads ) ); 00513 ref_ptr< osg::Vec4Array > colors = ref_ptr< osg::Vec4Array >( new osg::Vec4Array( numQuads ) ); 00514 00515 for( size_t yQuad = 0; yQuad < resY; ++yQuad ) 00516 { 00517 for( size_t xQuad = 0; xQuad < resX; ++xQuad ) 00518 { 00519 size_t qIndex = yQuad * resX + xQuad; 00520 size_t vIndex = qIndex * 4; // since there are 4 corners 00521 vertices->at( vIndex ) = osg::Vec3( xQuad * dx + spacing, yQuad * dy + spacing, 0.0 ); 00522 vertices->at( vIndex + 1 ) = osg::Vec3( xQuad * dx + dx - spacing, yQuad * dy + spacing, 0.0 ); 00523 vertices->at( vIndex + 2 ) = osg::Vec3( xQuad * dx + dx - spacing, yQuad * dy + dy - spacing, 0.0 ); 00524 vertices->at( vIndex + 3 ) = osg::Vec3( xQuad * dx + spacing, yQuad * dy + dy - spacing, 0.0 ); 00525 centers->at( qIndex ) = osg::Vec3( xQuad * dx + dx / 2.0, yQuad * dy + dy / 2.0, 0.0 ); 00526 colors->at( qIndex ) = osg::Vec4( 0.1 + static_cast< double >( qIndex ) / numQuads * 0.6, 00527 0.1 + static_cast< double >( qIndex ) / numQuads * 0.6, 00528 1.0, 1.0 ); 00529 } 00530 } 00531 00532 ref_ptr< osg::Geometry > geometry = ref_ptr< osg::Geometry >( new osg::Geometry ); 00533 geometry->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, vertices->size() ) ); 00534 geometry->setVertexArray( vertices ); 00535 geometry->setColorArray( colors ); 00536 geometry->setColorBinding( osg::Geometry::BIND_PER_PRIMITIVE ); 00537 00538 ref_ptr< osg::Vec3Array > normals = ref_ptr< osg::Vec3Array >( new osg::Vec3Array ); 00539 normals->push_back( osg::Vec3( 0.0, 0.0, 1.0 ) ); 00540 geometry->setNormalArray( normals ); 00541 geometry->setNormalBinding( osg::Geometry::BIND_OVERALL ); 00542 osg::ref_ptr< WGESubdividedPlane > geode = osg::ref_ptr< WGESubdividedPlane >( new WGESubdividedPlane ); 00543 geode->addDrawable( geometry ); 00544 geode->setCenterArray( centers ); 00545 00546 // we need to disable light, since the order of the vertices may be wrong and with lighting you won't see anything but black surfaces 00547 osg::StateSet* state = geode->getOrCreateStateSet(); 00548 state->setMode( GL_BLEND, osg::StateAttribute::ON ); 00549 state->setMode( GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED ); 00550 00551 return geode; 00552 } 00553 00554 osg::ref_ptr< osg::Group > wge::creatCoordinateSystem( 00555 osg::Vec3 middle, 00556 double sizeX, 00557 double sizeY, 00558 double sizeZ 00559 ) 00560 { 00561 osg::ref_ptr< WGEGroupNode >groupNode = new WGEGroupNode(); 00562 osg::ref_ptr< WGEShader > shaderCoordinateSystem( new WGEShader( "WGECoordinateSystem" ) ); 00563 00564 osg::ref_ptr< osg::Geode > graphX( new osg::Geode ); 00565 osg::ref_ptr< osg::Geode > graphY( new osg::Geode ); 00566 osg::ref_ptr< osg::Geode > graphZ( new osg::Geode ); 00567 00568 osg::ref_ptr< osg::Geode > graphXCylinder( new osg::Geode ); 00569 osg::ref_ptr< osg::Geode > graphYCylinder( new osg::Geode ); 00570 osg::ref_ptr< osg::Geode > graphZCylinder( new osg::Geode ); 00571 00572 // X 00573 osg::ref_ptr< osg::ShapeDrawable > cylinderX = new osg::ShapeDrawable( new osg::Cylinder( 00574 middle, 1, sizeX + ( sizeX * 0.5 ) 00575 ) ); 00576 osg::ref_ptr< osg::ShapeDrawable > cylinderXEnd = new osg::ShapeDrawable( new osg::Cylinder( 00577 osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeX + ( sizeX * 0.5 ) ) / 2.0 ), 1.0, 1.0 00578 ) ); 00579 osg::ref_ptr< osg::ShapeDrawable > coneX = new osg::ShapeDrawable( new osg::Cone( 00580 osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeX + ( sizeX * 0.5 ) ) / 2.0 ), 2.0, 5.0 00581 ) ); 00582 cylinderXEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); 00583 graphXCylinder->addDrawable( cylinderX ); 00584 graphX->addDrawable( coneX ); 00585 graphX->addDrawable( cylinderXEnd ); 00586 00587 osg::ref_ptr< osg::Material > matX = new osg::Material(); 00588 matX->setDiffuse( osg::Material::FRONT, WColor( 1.0, 0.0, 0.0, 1.0 ) ); 00589 cylinderX->getOrCreateStateSet()->setAttribute( matX, osg::StateAttribute::ON ); 00590 coneX->getOrCreateStateSet()->setAttribute( matX, osg::StateAttribute::ON ); 00591 00592 // Y 00593 osg::ref_ptr< osg::ShapeDrawable > cylinderY = new osg::ShapeDrawable( new osg::Cylinder( 00594 middle, 1, sizeY + ( sizeY * 0.5 ) 00595 ) ); 00596 osg::ref_ptr< osg::ShapeDrawable > cylinderYEnd = new osg::ShapeDrawable( new osg::Cylinder( 00597 osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeY + ( sizeY * 0.5 ) ) / 2.0 ), 1.0, 1.0 00598 ) ); 00599 osg::ref_ptr< osg::ShapeDrawable > coneY = new osg::ShapeDrawable( new osg::Cone( 00600 osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeY + ( sizeY * 0.5 ) ) / 2.0 ), 2.0, 5.0 00601 ) ); 00602 cylinderYEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); 00603 00604 graphYCylinder->addDrawable( cylinderY ); 00605 graphY->addDrawable( coneY ); 00606 graphY->addDrawable( cylinderYEnd ); 00607 00608 osg::ref_ptr< osg::Material > matY = new osg::Material(); 00609 matY->setDiffuse( osg::Material::FRONT, WColor( 0.0, 1.0, 0.0, 1.0 ) ); 00610 cylinderY->getOrCreateStateSet()->setAttribute( matY, osg::StateAttribute::ON ); 00611 coneY->getOrCreateStateSet()->setAttribute( matY, osg::StateAttribute::ON ); 00612 00613 00614 // Z 00615 osg::ref_ptr< osg::ShapeDrawable > cylinderZ = new osg::ShapeDrawable( new osg::Cylinder( 00616 middle, 1, sizeZ + ( sizeZ * 0.5 ) 00617 ) ); 00618 osg::ref_ptr< osg::ShapeDrawable > cylinderZEnd = new osg::ShapeDrawable( new osg::Cylinder( 00619 osg::Vec3( middle.x(), middle.y(), middle.z() - ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 ), 1.0, 1.0 00620 ) ); 00621 osg::ref_ptr< osg::ShapeDrawable > coneZ = new osg::ShapeDrawable( new osg::Cone( 00622 osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 ), 2.0, 5.0 00623 ) ); 00624 cylinderZEnd->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); 00625 00626 graphZCylinder->addDrawable( cylinderZ ); 00627 graphZ->addDrawable( coneZ ); 00628 graphZ->addDrawable( cylinderZEnd ); 00629 00630 osg::ref_ptr< osg::Material > matZ = new osg::Material(); 00631 matZ->setDiffuse( osg::Material::FRONT, WColor( 0.0, 0.0, 1.0, 1.0 ) ); 00632 cylinderZ->getOrCreateStateSet()->setAttribute( matZ, osg::StateAttribute::ON ); 00633 coneZ->getOrCreateStateSet()->setAttribute( matZ, osg::StateAttribute::ON ); 00634 00635 shaderCoordinateSystem->apply( graphXCylinder ); 00636 shaderCoordinateSystem->apply( graphYCylinder ); 00637 shaderCoordinateSystem->apply( graphZCylinder ); 00638 00639 osg::ref_ptr< WGELabel > graphXLabel = new WGELabel(); 00640 graphXLabel->setText( "X" ); 00641 graphXLabel->setCharacterSize( 10 ); 00642 graphXLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeX + ( sizeX * 0.5 ) ) / 2.0 + 5.0 ) ); 00643 graphXLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); 00644 graphX->addDrawable( graphXLabel ); 00645 00646 osg::ref_ptr< WGELabel > graphYLabel = new WGELabel(); 00647 graphYLabel->setText( "Y" ); 00648 graphYLabel->setCharacterSize( 10 ); 00649 graphYLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeY + ( sizeY * 0.5 ) ) / 2.0 + 5.0 ) ); 00650 graphYLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); 00651 graphY->addDrawable( graphYLabel ); 00652 00653 osg::ref_ptr< WGELabel > graphZLabel = new WGELabel(); 00654 graphZLabel->setText( "Z" ); 00655 graphZLabel->setCharacterSize( 10 ); 00656 graphZLabel->setPosition( osg::Vec3( middle.x(), middle.y(), middle.z() + ( sizeZ + ( sizeZ * 0.5 ) ) / 2.0 + 5.0 ) ); 00657 graphZLabel->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); 00658 graphZ->addDrawable( graphZLabel ); 00659 00660 00661 osg::ref_ptr< osg::MatrixTransform > graphXTransform = new osg::MatrixTransform(); 00662 graphXTransform->addChild( graphX ); 00663 graphXTransform->addChild( graphXCylinder ); 00664 osg::ref_ptr< osg::MatrixTransform > graphYTransform = new osg::MatrixTransform(); 00665 graphYTransform->addChild( graphY ); 00666 graphYTransform->addChild( graphYCylinder ); 00667 osg::ref_ptr< osg::MatrixTransform > graphZTransform = new osg::MatrixTransform(); 00668 graphZTransform->addChild( graphZ ); 00669 graphZTransform->addChild( graphZCylinder ); 00670 00671 osg::Matrixd matrixTranslateTo0 = osg::Matrixd::translate( -middle.x(), -middle.y(), -middle.z() ); 00672 osg::Matrixd matrixTranslateFrom0 = osg::Matrixd::translate( middle.x(), middle.y(), middle.z() ); 00673 00674 graphXTransform->setMatrix( matrixTranslateTo0 * osg::Matrixd::rotate( 00675 90.0 * piDouble / 180.0, 00676 osg::Vec3f( 0.0, 1.0, 0.0 ) ) * matrixTranslateFrom0 00677 ); 00678 graphYTransform->setMatrix( matrixTranslateTo0 * osg::Matrixd::rotate( 00679 -90.0 * piDouble / 180.0, 00680 osg::Vec3f( 1.0, 0.0, 0.0 ) ) * matrixTranslateFrom0 00681 ); 00682 00683 groupNode->insert( graphXTransform ); 00684 groupNode->insert( graphYTransform ); 00685 groupNode->insert( graphZTransform ); 00686 00687 return groupNode; 00688 }