00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <map>
00026 #include <string>
00027 #include <vector>
00028
00029 #include <osg/Array>
00030 #include <osgUtil/DelaunayTriangulator>
00031
00032 #include "../common/math/linearAlgebra/WLinearAlgebra.h"
00033 #include "WGEGeometryUtils.h"
00034 #include "WGEUtils.h"
00035 #include "WTriangleMesh.h"
00036 #include "exceptions/WGEException.h"
00037
00038 osg::ref_ptr< osg::Vec3Array > wge::generateCuboidQuads( const std::vector< WPosition >& corners )
00039 {
00040 osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
00041
00042
00043 vertices->push_back( corners[0] );
00044 vertices->push_back( corners[1] );
00045 vertices->push_back( corners[2] );
00046 vertices->push_back( corners[3] );
00047
00048 vertices->push_back( corners[1] );
00049 vertices->push_back( corners[5] );
00050 vertices->push_back( corners[6] );
00051 vertices->push_back( corners[2] );
00052
00053 vertices->push_back( corners[5] );
00054 vertices->push_back( corners[4] );
00055 vertices->push_back( corners[7] );
00056 vertices->push_back( corners[6] );
00057
00058 vertices->push_back( corners[4] );
00059 vertices->push_back( corners[0] );
00060 vertices->push_back( corners[3] );
00061 vertices->push_back( corners[7] );
00062
00063 vertices->push_back( corners[3] );
00064 vertices->push_back( corners[2] );
00065 vertices->push_back( corners[6] );
00066 vertices->push_back( corners[7] );
00067
00068 vertices->push_back( corners[0] );
00069 vertices->push_back( corners[1] );
00070 vertices->push_back( corners[5] );
00071 vertices->push_back( corners[4] );
00072 return vertices;
00073 }
00074
00075 osg::Vec3 wge::getQuadNormal( const WPosition& a,
00076 const WPosition& b,
00077 const WPosition& c )
00078 {
00079 WVector3d vec1 = a - b;
00080 WVector3d vec2 = c - b;
00081 WVector3d normal = cross( vec2, vec1 );
00082 return normalize( normal );
00083 }
00084
00085 osg::ref_ptr< osg::Vec3Array > wge::generateCuboidQuadNormals( const std::vector< WPosition >& corners )
00086 {
00087 osg::ref_ptr< osg::Vec3Array > vertices = osg::ref_ptr< osg::Vec3Array >( new osg::Vec3Array );
00088
00089 vertices->push_back( getQuadNormal( corners[0], corners[1], corners[2] ) );
00090 vertices->push_back( getQuadNormal( corners[1], corners[5], corners[6] ) );
00091 vertices->push_back( getQuadNormal( corners[5], corners[4], corners[7] ) );
00092 vertices->push_back( getQuadNormal( corners[4], corners[0], corners[3] ) );
00093 vertices->push_back( getQuadNormal( corners[3], corners[2], corners[6] ) );
00094 vertices->push_back( getQuadNormal( corners[0], corners[1], corners[5] ) );
00095 return vertices;
00096 }
00097
00098 WTriangleMesh::SPtr wge::triangulate( const std::vector< WPosition >& points, double transformationFactor )
00099 {
00100 WAssert( points.size() > 2, "The Delaunay triangulation needs at least 3 vertices!" );
00101
00102 osg::ref_ptr< osg::Vec3Array > osgPoints = wge::osgVec3Array( points );
00103
00104 if( transformationFactor != 0.0 )
00105 {
00106
00107
00108 osg::Vec3 centroid;
00109 for( std::size_t pointID = 0; pointID < osgPoints->size(); ++pointID )
00110 {
00111 centroid += (*osgPoints)[pointID];
00112 }
00113 centroid /= osgPoints->size();
00114
00115 for( std::size_t pointID = 0; pointID < osgPoints->size(); ++pointID )
00116 {
00117 const double factor = ( (*osgPoints)[pointID].z() - centroid.z() ) * transformationFactor + 1.0;
00118 (*osgPoints)[pointID].x() = ( (*osgPoints)[pointID].x() - centroid.x() ) * factor + centroid.x();
00119 (*osgPoints)[pointID].y() = ( (*osgPoints)[pointID].y() - centroid.y() ) * factor + centroid.y();
00120 }
00121 }
00122
00123
00124
00125
00126
00127 std::map< osg::Vec3, size_t > map;
00128 for( size_t index = 0; index < osgPoints->size(); ++index )
00129 {
00130 map[ (*osgPoints)[index] ] = index;
00131 }
00132
00133 osg::ref_ptr< osgUtil::DelaunayTriangulator > triangulator( new osgUtil::DelaunayTriangulator( osgPoints ) );
00134
00135 bool triangulationResult = triangulator->triangulate();
00136
00137 WAssert( triangulationResult, "Something went wrong in triangulation." );
00138
00139 osg::ref_ptr< const osg::DrawElementsUInt > osgTriangles( triangulator->getTriangles() );
00140 size_t nbTriangles = osgTriangles->size() / 3;
00141 std::vector< size_t > triangles( osgTriangles->size() );
00142 for( size_t triangleID = 0; triangleID < nbTriangles; ++triangleID )
00143 {
00144
00145
00146 size_t vertID = triangleID * 3;
00147 triangles[vertID + 0] = map[ (*osgPoints)[ (*osgTriangles)[vertID + 0] ] ];
00148 triangles[vertID + 1] = map[ (*osgPoints)[ (*osgTriangles)[vertID + 1] ] ];
00149 triangles[vertID + 2] = map[ (*osgPoints)[ (*osgTriangles)[vertID + 2] ] ];
00150 }
00151
00152
00153 return WTriangleMesh::SPtr( new WTriangleMesh( wge::osgVec3Array( points ), triangles ) );
00154 }