Commit 09735ed9 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[ADD] mesh reader now supports loading OBJ files with included normal info.

parent 442abc14
......@@ -58,6 +58,7 @@ WTriangleMesh::WTriangleMesh( size_t vertNum, size_t triangleNum )
: m_countVerts( 0 ),
m_countTriangles( 0 ),
m_meshDirty( true ),
m_autoNormal( true ),
m_neighborsCalculated( false ),
m_curvatureCalculated( false )
{
......@@ -75,6 +76,7 @@ WTriangleMesh::WTriangleMesh( osg::ref_ptr< osg::Vec3Array > vertices, const std
: m_countVerts( vertices->size() ),
m_countTriangles( triangles.size() / 3 ),
m_meshDirty( true ),
m_autoNormal( true ),
m_neighborsCalculated( false ),
m_verts( vertices ),
m_textureCoordinates( new osg::Vec3Array( vertices->size() ) ),
......@@ -91,14 +93,19 @@ WTriangleMesh::~WTriangleMesh()
{
}
void WTriangleMesh::addVertex( float x, float y, float z )
void WTriangleMesh::setAutoRecalcNormals( bool autoRecalc )
{
addVertex( osg::Vec3( x, y, z ) );
m_autoNormal = autoRecalc;
}
void WTriangleMesh::addVertex( WPosition vert )
size_t WTriangleMesh::addVertex( float x, float y, float z )
{
addVertex( osg::Vec3( vert[0], vert[1], vert[2] ) );
return addVertex( osg::Vec3( x, y, z ) );
}
size_t WTriangleMesh::addVertex( WPosition vert )
{
return addVertex( osg::Vec3( vert[0], vert[1], vert[2] ) );
}
void WTriangleMesh::addTriangle( size_t vert0, size_t vert1, size_t vert2 )
......@@ -129,10 +136,14 @@ void WTriangleMesh::setVertexNormal( size_t index, osg::Vec3 normal )
void WTriangleMesh::setVertexNormal( size_t index, WPosition normal )
{
WAssert( index < m_countVerts, "set vertex normal: index out of range" );
setVertexNormal( index, osg::Vec3( normal[0], normal[1], normal[2] ) );
}
void WTriangleMesh::setVertexNormal( size_t index, float x, float y, float z )
{
setVertexNormal( index, osg::Vec3( x, y, z ) );
}
void WTriangleMesh::setVertexColor( size_t index, osg::Vec4 color )
{
WAssert( index < m_countVerts, "set vertex color: index out of range" );
......@@ -167,7 +178,7 @@ osg::ref_ptr< const osg::Vec3Array > WTriangleMesh::getTextureCoordinateArray()
osg::ref_ptr< osg::Vec3Array >WTriangleMesh::getVertexNormalArray( bool forceRecalc )
{
if( forceRecalc || m_meshDirty )
if( forceRecalc || ( m_meshDirty && m_autoNormal ) )
{
recalcVertNormals();
}
......@@ -176,7 +187,7 @@ osg::ref_ptr< osg::Vec3Array >WTriangleMesh::getVertexNormalArray( bool forceRec
osg::ref_ptr< osg::Vec3Array >WTriangleMesh::getTriangleNormalArray( bool forceRecalc )
{
if( forceRecalc || m_meshDirty )
if( forceRecalc || ( m_meshDirty && m_autoNormal ) )
{
recalcVertNormals();
}
......
......@@ -101,8 +101,9 @@ public:
* adds a vertex position to the mesh
*
* \param vert
* \return the index of the vertex
*/
void addVertex( osg::Vec3 vert );
size_t addVertex( osg::Vec3 vert );
/**
* adds a vertex position to the mesh
......@@ -110,15 +111,18 @@ public:
* \param x
* \param y
* \param z
*
* \return the index of the vertex
*/
void addVertex( float x, float y, float z );
size_t addVertex( float x, float y, float z );
/**
* adds a vertex position to the mesh
*
* \param vert
* \param vert vertex to add
* \return the index of the vertex
*/
void addVertex( WPosition vert );
size_t addVertex( WPosition vert );
/**
* Adds a texture coordinate for the vertex.
......@@ -170,6 +174,16 @@ public:
*/
void setVertexNormal( size_t index, osg::Vec3 normal );
/**
* sets the normal for a given vertex
*
* \param index
* \param x x coordinate
* \param y y coordinate
* \param z z coordinate
*/
void setVertexNormal( size_t index, float x, float y, float z );
/**
* sets the normal for a given vertex
*
......@@ -457,6 +471,13 @@ public:
*/
osg::ref_ptr< osg::Vec3Array > getSecondaryPrincipalCurvatureDirectionArray();
/**
* Set this to true to force automatic normal calculation. Set it to false if you specify your own normals.
*
* \param autoRecalc auto normal calculation.
*/
void setAutoRecalcNormals( bool autoRecalc = true );
protected:
static boost::shared_ptr< WPrototyped > m_prototype; //!< The prototype as singleton.
private:
......@@ -704,6 +725,8 @@ private:
bool m_meshDirty; //!< flag indicating a change took place which requires a recalculation of components
bool m_autoNormal; //!< flag denoting whether normals should be calculated automatically.
bool m_neighborsCalculated; //!< flag indicating whether the neighbor information has been calculated yet
//! Indicates whether the curvature and its principal directions have been calculated.
......@@ -786,7 +809,7 @@ inline void WTriangleMesh::addTextureCoordinate( float x, float y, float z )
addTextureCoordinate( osg::Vec3( x, y, z ) );
}
inline void WTriangleMesh::addVertex( osg::Vec3 vert )
inline size_t WTriangleMesh::addVertex( osg::Vec3 vert )
{
if( ( *m_verts ).size() == m_countVerts )
{
......@@ -800,9 +823,17 @@ inline void WTriangleMesh::addVertex( osg::Vec3 vert )
{
( *m_vertColors ).resize( m_countVerts + 1 );
}
if( ( *m_vertNormals ).size() == m_countVerts )
{
( *m_vertNormals ).resize( m_countVerts + 1 );
}
size_t index = m_countVerts;
( *m_verts )[index] = vert;
( *m_vertNormals )[index] = osg::Vec3( 1.0, 1.0, 1.0 );
( *m_verts )[m_countVerts] = vert;
++m_countVerts;
return index;
}
inline const std::string WTriangleMesh::getName() const
......
......@@ -59,7 +59,9 @@ WTriangleMesh::SPtr WMeshReaderOBJ::operator()( WProgressCombiner::SPtr parentPr
// regex for the different lines possible in OBJ
static const boost::regex faceRegex( "^ *[f,F] *([0-9]*) *([0-9]*) *([0-9]*) *$" );
static const boost::regex vertexRegex( "^ *[v,V] *(-?[0-9]*\\.?[0-9]*) *(-?[0-9]*\\.?[0-9]*) *(-?[0-9]*\\.?[0-9]*).*$" );
static const boost::regex faceComplexRegex( "^ *[f,F] *([0-9]*)/([0-9]*)/([0-9]*) *([0-9]*)/([0-9]*)/([0-9]*) *([0-9]*)/([0-9]*)/([0-9]*) *$" );
static const boost::regex vertexRegex( "^ *[v,V][^n] *(-?[0-9]*\\.?[0-9]*) *(-?[0-9]*\\.?[0-9]*) *(-?[0-9]*\\.?[0-9]*).*$" );
static const boost::regex normalRegex( "^ *[v,V][n,N] *(-?[0-9]*\\.?[0-9]*) *(-?[0-9]*\\.?[0-9]*) *(-?[0-9]*\\.?[0-9]*).*$" );
static const boost::regex commentRegex( "^ *#.*$" );
// please note that there are several more possible definitions ... Please see http://en.wikipedia.org/wiki/Wavefront_.obj_file
......@@ -69,6 +71,7 @@ WTriangleMesh::SPtr WMeshReaderOBJ::operator()( WProgressCombiner::SPtr parentPr
std::vector< float > vertices;
std::vector< size_t > faces;
std::vector< size_t > normals;
vertices.reserve( 3000 );
faces.reserve( 3000 );
......@@ -96,6 +99,12 @@ WTriangleMesh::SPtr WMeshReaderOBJ::operator()( WProgressCombiner::SPtr parentPr
vertices.push_back( string_utils::fromString< float >( matches[2] ) );
vertices.push_back( string_utils::fromString< float >( matches[3] ) );
}
else if( boost::regex_match( line, matches, normalRegex ) )
{
normals.push_back( string_utils::fromString< float >( matches[1] ) );
normals.push_back( string_utils::fromString< float >( matches[2] ) );
normals.push_back( string_utils::fromString< float >( matches[3] ) );
}
// check whether this is a face definition
else if( boost::regex_match( line, matches, faceRegex ) )
{
......@@ -104,6 +113,13 @@ WTriangleMesh::SPtr WMeshReaderOBJ::operator()( WProgressCombiner::SPtr parentPr
faces.push_back( string_utils::fromString< size_t >( matches[2] ) - 1 );
faces.push_back( string_utils::fromString< size_t >( matches[3] ) - 1 );
}
else if( boost::regex_match( line, matches, faceComplexRegex ) )
{
// NOTE: indices are stored beginning at 1
faces.push_back( string_utils::fromString< size_t >( matches[1] ) - 1 );
faces.push_back( string_utils::fromString< size_t >( matches[4] ) - 1 );
faces.push_back( string_utils::fromString< size_t >( matches[7] ) - 1 );
}
// check whether this is a comment
else if( boost::regex_match( line, matches, commentRegex ) )
{
......@@ -126,6 +142,9 @@ WTriangleMesh::SPtr WMeshReaderOBJ::operator()( WProgressCombiner::SPtr parentPr
// build triMesh instance
WTriangleMesh::SPtr triMesh( new WTriangleMesh( vertices.size() / 3, faces.size() / 3 ) );
//triMesh->setAutoRecalcNormals( false );
WAssert( ( vertices.size() == normals.size() ) || ( normals.size() == 0 ), "Number of normals and vertices do not match." );
for( size_t i = 0; i < vertices.size(); i += 3 )
{
......@@ -135,6 +154,10 @@ WTriangleMesh::SPtr WMeshReaderOBJ::operator()( WProgressCombiner::SPtr parentPr
{
triMesh->addTriangle( faces[ i + 0 ], faces[ i + 1 ], faces[ i + 2 ] );
}
for( size_t i = 0; i < normals.size(); i += 3 )
{
triMesh->setVertexNormal( i / 3, normals[ i + 0 ], normals[ i + 1 ], normals[ i + 2 ] );
}
// done.
progress->finish();
......
......@@ -293,9 +293,9 @@ void WMTriangleMeshRenderer::moduleMain()
new WGEShaderPropertyDefineOptions< WPropBool >( m_colormap, "COLORMAPPING_DISABLED", "COLORMAPPING_ENABLED" ) )
);
// set the opacity and material color property as GLSL uniforms:
moduleNodeState->addUniform( new WGEPropertyUniform< WPropDouble >( "u_opacity", m_opacity ) );
moduleNodeState->addUniform( new WGEPropertyUniform< WPropBool >( "u_outline", m_showOutline ) );
// loop until the module container requests the module to quit
while( !m_shutdownFlag() )
......
......@@ -36,6 +36,11 @@ varying vec3 v_normal;
*/
uniform float u_opacity;
/**
* True if in outline mode
*/
uniform bool u_outline;
/**
* The colormap ratio specified by the user in [0,1]
*/
......@@ -51,7 +56,7 @@ void main()
#endif
// calculate lighting
float light = blinnPhongIlluminationIntensity( normalize( -v_normal ) );
col*=light;
col *= u_outline ? 1.0 : light;
// finally, apply opacity
col.a = u_opacity* 0.01;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment