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