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