From b98744567690c5035c68e41962802dc440e3d76f Mon Sep 17 00:00:00 2001 From: Cirilo Bernardo Date: Tue, 2 Feb 2016 16:50:46 +1100 Subject: [PATCH] Forced smoothed normals calculations for VMRML2 parser --- plugins/3d/vrml/v2/vrml2_appearance.cpp | 4 +- plugins/3d/vrml/v2/vrml2_appearance.h | 2 +- plugins/3d/vrml/v2/vrml2_base.cpp | 6 +- plugins/3d/vrml/v2/vrml2_base.h | 2 +- plugins/3d/vrml/v2/vrml2_box.cpp | 2 +- plugins/3d/vrml/v2/vrml2_box.h | 2 +- plugins/3d/vrml/v2/vrml2_color.cpp | 2 +- plugins/3d/vrml/v2/vrml2_color.h | 2 +- plugins/3d/vrml/v2/vrml2_coords.cpp | 2 +- plugins/3d/vrml/v2/vrml2_coords.h | 2 +- plugins/3d/vrml/v2/vrml2_faceset.cpp | 362 ++++++------------------ plugins/3d/vrml/v2/vrml2_faceset.h | 3 +- plugins/3d/vrml/v2/vrml2_lineset.cpp | 2 +- plugins/3d/vrml/v2/vrml2_lineset.h | 2 +- plugins/3d/vrml/v2/vrml2_material.cpp | 2 +- plugins/3d/vrml/v2/vrml2_material.h | 2 +- plugins/3d/vrml/v2/vrml2_node.h | 2 +- plugins/3d/vrml/v2/vrml2_norms.cpp | 2 +- plugins/3d/vrml/v2/vrml2_norms.h | 2 +- plugins/3d/vrml/v2/vrml2_pointset.cpp | 2 +- plugins/3d/vrml/v2/vrml2_pointset.h | 2 +- plugins/3d/vrml/v2/vrml2_shape.cpp | 6 +- plugins/3d/vrml/v2/vrml2_shape.h | 2 +- plugins/3d/vrml/v2/vrml2_switch.cpp | 4 +- plugins/3d/vrml/v2/vrml2_switch.h | 2 +- plugins/3d/vrml/v2/vrml2_transform.cpp | 4 +- plugins/3d/vrml/v2/vrml2_transform.h | 2 +- plugins/3d/vrml/vrml.cpp | 2 +- plugins/3d/vrml/wrlfacet.cpp | 62 ++-- plugins/3d/vrml/wrlfacet.h | 2 +- 30 files changed, 163 insertions(+), 332 deletions(-) diff --git a/plugins/3d/vrml/v2/vrml2_appearance.cpp b/plugins/3d/vrml/v2/vrml2_appearance.cpp index c37915bb6a..a77fb3cf82 100644 --- a/plugins/3d/vrml/v2/vrml2_appearance.cpp +++ b/plugins/3d/vrml/v2/vrml2_appearance.cpp @@ -360,7 +360,7 @@ bool WRL2APPEARANCE::Read( WRLPROC& proc, WRL2BASE* aTopNode ) } -SGNODE* WRL2APPEARANCE::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2APPEARANCE::TranslateToSG( SGNODE* aParent ) { if( NULL == material && NULL == texture ) return NULL; @@ -418,7 +418,7 @@ SGNODE* WRL2APPEARANCE::TranslateToSG( SGNODE* aParent, bool calcNormals ) return m_sgNode; } - m_sgNode = material->TranslateToSG( aParent, calcNormals ); + m_sgNode = material->TranslateToSG( aParent ); return m_sgNode; } diff --git a/plugins/3d/vrml/v2/vrml2_appearance.h b/plugins/3d/vrml/v2/vrml2_appearance.h index 97bd5fc90a..637e59c156 100644 --- a/plugins/3d/vrml/v2/vrml2_appearance.h +++ b/plugins/3d/vrml/v2/vrml2_appearance.h @@ -68,7 +68,7 @@ public: bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); }; #endif // VRML2_APPEARANCE_H diff --git a/plugins/3d/vrml/v2/vrml2_base.cpp b/plugins/3d/vrml/v2/vrml2_base.cpp index bd8de96124..c8aa3efcde 100644 --- a/plugins/3d/vrml/v2/vrml2_base.cpp +++ b/plugins/3d/vrml/v2/vrml2_base.cpp @@ -910,7 +910,7 @@ bool WRL2BASE::readSwitch( WRLPROC& proc, WRL2NODE* aParent, WRL2NODE** aNode ) } -SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent ) { if( m_Children.empty() ) return NULL; @@ -967,7 +967,7 @@ SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent, bool calcNormals ) do { IFSG_TRANSFORM wrapper( topNode.GetRawPtr() ); - SGNODE* pshape = (*sC)->TranslateToSG( wrapper.GetRawPtr(), calcNormals ); + SGNODE* pshape = (*sC)->TranslateToSG( wrapper.GetRawPtr() ); if( NULL != pshape ) test = true; @@ -981,7 +981,7 @@ SGNODE* WRL2BASE::TranslateToSG( SGNODE* aParent, bool calcNormals ) case WRL2_TRANSFORM: case WRL2_SWITCH: - if( NULL != (*sC)->TranslateToSG( topNode.GetRawPtr(), calcNormals ) ) + if( NULL != (*sC)->TranslateToSG( topNode.GetRawPtr() ) ) test = true; break; diff --git a/plugins/3d/vrml/v2/vrml2_base.h b/plugins/3d/vrml/v2/vrml2_base.h index 68e3956256..377ff5f04e 100644 --- a/plugins/3d/vrml/v2/vrml2_base.h +++ b/plugins/3d/vrml/v2/vrml2_base.h @@ -111,7 +111,7 @@ public: // functions inherited from WRL2NODE bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool SetParent( WRL2NODE* aParent ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); }; #endif // VRML2_BASE_H diff --git a/plugins/3d/vrml/v2/vrml2_box.cpp b/plugins/3d/vrml/v2/vrml2_box.cpp index 20734cdbfb..2a0e1c89dc 100644 --- a/plugins/3d/vrml/v2/vrml2_box.cpp +++ b/plugins/3d/vrml/v2/vrml2_box.cpp @@ -210,7 +210,7 @@ bool WRL2BOX::AddChildNode( WRL2NODE* aNode ) } -SGNODE* WRL2BOX::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2BOX::TranslateToSG( SGNODE* aParent ) { S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent ); diff --git a/plugins/3d/vrml/v2/vrml2_box.h b/plugins/3d/vrml/v2/vrml2_box.h index 4a6d205409..3e4f175397 100644 --- a/plugins/3d/vrml/v2/vrml2_box.h +++ b/plugins/3d/vrml/v2/vrml2_box.h @@ -56,7 +56,7 @@ public: bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); }; #endif // VRML2_BOX_H diff --git a/plugins/3d/vrml/v2/vrml2_color.cpp b/plugins/3d/vrml/v2/vrml2_color.cpp index 54cddc49ab..39c54d1c49 100644 --- a/plugins/3d/vrml/v2/vrml2_color.cpp +++ b/plugins/3d/vrml/v2/vrml2_color.cpp @@ -192,7 +192,7 @@ bool WRL2COLOR::Read( WRLPROC& proc, WRL2BASE* aTopNode ) } -SGNODE* WRL2COLOR::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2COLOR::TranslateToSG( SGNODE* aParent ) { // any data manipulation must be performed by the parent node return NULL; diff --git a/plugins/3d/vrml/v2/vrml2_color.h b/plugins/3d/vrml/v2/vrml2_color.h index fc62316b16..4792a1434a 100644 --- a/plugins/3d/vrml/v2/vrml2_color.h +++ b/plugins/3d/vrml/v2/vrml2_color.h @@ -58,7 +58,7 @@ public: bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); /** * Function HasColors diff --git a/plugins/3d/vrml/v2/vrml2_coords.cpp b/plugins/3d/vrml/v2/vrml2_coords.cpp index 5fa8162caa..1f9b0bff2f 100644 --- a/plugins/3d/vrml/v2/vrml2_coords.cpp +++ b/plugins/3d/vrml/v2/vrml2_coords.cpp @@ -220,7 +220,7 @@ void WRL2COORDS::GetCoords( WRLVEC3F*& aCoordList, size_t& aListSize ) } -SGNODE* WRL2COORDS::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2COORDS::TranslateToSG( SGNODE* aParent ) { // any data manipulation must be performed by the parent node return NULL; diff --git a/plugins/3d/vrml/v2/vrml2_coords.h b/plugins/3d/vrml/v2/vrml2_coords.h index ba6f1bdecd..61c57afe4f 100644 --- a/plugins/3d/vrml/v2/vrml2_coords.h +++ b/plugins/3d/vrml/v2/vrml2_coords.h @@ -58,7 +58,7 @@ public: bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); void GetCoords( WRLVEC3F*& aCoordList, size_t& aListSize ); }; diff --git a/plugins/3d/vrml/v2/vrml2_faceset.cpp b/plugins/3d/vrml/v2/vrml2_faceset.cpp index a6aa1a8be1..007d66d97a 100644 --- a/plugins/3d/vrml/v2/vrml2_faceset.cpp +++ b/plugins/3d/vrml/v2/vrml2_faceset.cpp @@ -28,6 +28,7 @@ #include "vrml2_faceset.h" #include "vrml2_coords.h" #include "vrml2_color.h" +#include "wrlfacet.h" #include "plugins/3dapi/ifsg_all.h" @@ -78,7 +79,8 @@ void WRL2FACESET::setDefaults( void ) normalPerVertex = true; solid = true; - creaseAngle = 0.0; + creaseAngle = 0.5; + creaseLimit = 0.878; // approx cos( 0.5 ) } @@ -476,6 +478,13 @@ bool WRL2FACESET::Read( WRLPROC& proc, WRL2BASE* aTopNode ) return false; } + + if( creaseAngle < 0.0 ) + creaseAngle = 0.0; + else if( creaseAngle > M_PI_2 ) + creaseAngle = M_PI_2; + + creaseLimit = cosf( creaseAngle ); } else if( !glob.compare( "colorIndex" ) ) { @@ -587,7 +596,7 @@ bool WRL2FACESET::Read( WRLPROC& proc, WRL2BASE* aTopNode ) } -SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent ) { S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent ); @@ -633,12 +642,6 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals ) if( NULL == coord || vsize < 3 ) return NULL; - // create the index list and make sure we have >3 points - size_t idx; - int i1 = coordIndex[0]; - int i2 = coordIndex[1]; - int i3 = coordIndex[2]; - WRLVEC3F* pcoords; size_t coordsize; ((WRL2COORDS*) coord)->GetCoords( pcoords, coordsize ); @@ -647,7 +650,7 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals ) return NULL; // check that all indices are valid - for( idx = 0; idx < vsize; ++idx ) + for( size_t idx = 0; idx < vsize; ++idx ) { if( coordIndex[idx] < 0 ) continue; @@ -656,320 +659,129 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals ) return NULL; } - // if the indices are defective just give up - if( i1 < 0 || i2 < 0 || i3 < 0 - || i1 == i2 || i1 == i3 || i2 == i3 ) - return NULL; - - std::vector< SGPOINT > lCPts; // coordinate points for SG node - std::vector< int > lCIdx; // coordinate index list for SG node (must be triads) - std::vector< SGVECTOR > lCNorm; // per-vertex normals - std::vector< int > faces; // tracks the number of polygons for the entire set - std::vector< SGCOLOR > lColors; // colors points (if any) for SG node - int nfaces = 0; // number of triangles for each face in the list + SHAPE lShape; + FACET* fp = NULL; + size_t iCoord; + int idx; // coordinate index + size_t cidx = 0; // color index + SGCOLOR pc1; if( NULL == color ) { - // assuming convex polygons, create triangles for the SG node - for( idx = 3; idx <= vsize; ) + // no per-vertex colors; we can save a few CPU cycles + for( iCoord = 0; iCoord < vsize; ++iCoord ) { - lCIdx.push_back( i1 ); + idx = coordIndex[iCoord]; - if( ccw ) + if( idx < 0 ) { - lCIdx.push_back( i2 ); - lCIdx.push_back( i3 ); - } - else - { - lCIdx.push_back( i3 ); - lCIdx.push_back( i2 ); - } - - ++nfaces; - i2 = i3; - - if( idx == vsize ) - break; - - i3 = coordIndex[idx++]; - - while( ( i1 < 0 || i2 < 0 || i3 < 0 ) && ( idx < vsize ) ) - { - if( i3 < 0 ) + if( NULL != fp ) { - faces.push_back( nfaces ); - nfaces = 0; + if( fp->HasMinPoints() ) + fp = NULL; + else + fp->Init(); } - i1 = i2; - i2 = i3; - i3 = coordIndex[idx++]; - - // any invalid polygons shall void the entire faceset; this is a requirement - // to ensure correct handling of the normals - if( ( i1 < 0 && i2 < 0 ) || ( i1 < 0 && i3 < 0 ) || ( i2 < 0 && i3 < 0 ) ) - return NULL; + continue; } - if( i1 < 0 || i2 < 0 || i3 < 0 ) - break; + // if the coordinate is bad then skip it + if( idx >= (int)coordsize ) + continue; + + if( NULL == fp ) + fp = lShape.NewFacet(); + + // push the vertex value and index + fp->AddVertex( pcoords[idx], idx ); } } else { - int cIndex; WRL2COLOR* cn = (WRL2COLOR*) color; - SGCOLOR pc1, pc2, pc3; WRLVEC3F tc; - if( colorPerVertex ) + for( iCoord = 0; iCoord < vsize; ++iCoord ) { - cIndex = 3; + idx = coordIndex[iCoord]; - if( colorIndex.empty() ) + if( idx < 0 ) { - cn->GetColor( coordIndex[0], tc.x, tc.y, tc.z ); - pc1.SetColor( tc.x, tc.y, tc.z ); - cn->GetColor( coordIndex[1], tc.x, tc.y, tc.z ); - pc2.SetColor( tc.x, tc.y, tc.z ); - cn->GetColor( coordIndex[2], tc.x, tc.y, tc.z ); - pc3.SetColor( tc.x, tc.y, tc.z ); - } - else - { - if( colorIndex.size() < coordIndex.size() ) + if( NULL != fp ) { - #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 1 ) - std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; - std::cerr << " * [INFO] bad file; colorIndex.size() < coordIndex.size()\n"; - #endif - - return NULL; + if( fp->HasMinPoints() ) + fp = NULL; + else + fp->Init(); } - cn->GetColor( colorIndex[0], tc.x, tc.y, tc.z ); - pc1.SetColor( tc.x, tc.y, tc.z ); - cn->GetColor( colorIndex[1], tc.x, tc.y, tc.z ); - pc2.SetColor( tc.x, tc.y, tc.z ); - cn->GetColor( colorIndex[2], tc.x, tc.y, tc.z ); - pc3.SetColor( tc.x, tc.y, tc.z ); - } - } - else - { - cIndex = 1; + if( !colorPerVertex ) + ++cidx; - if( colorIndex.empty() ) - { - cn->GetColor( 0, tc.x, tc.y, tc.z ); - pc1.SetColor( tc.x, tc.y, tc.z ); - pc2.SetColor( tc.x, tc.y, tc.z ); - pc3.SetColor( tc.x, tc.y, tc.z ); - } - else - { - cn->GetColor( colorIndex[0], tc.x, tc.y, tc.z ); - pc1.SetColor( tc.x, tc.y, tc.z ); - pc2.SetColor( tc.x, tc.y, tc.z ); - pc3.SetColor( tc.x, tc.y, tc.z ); - } - } - - // assuming convex polygons, create triangles for the SG node - int cMaxIdx = (int) colorIndex.size(); - - for( idx = 3; idx <= vsize; ) - { - lCIdx.push_back( i1 ); - lColors.push_back( pc1 ); - lColors.push_back( pc2 ); - lColors.push_back( pc3 ); - - if( ccw ) - { - lCIdx.push_back( i2 ); - lCIdx.push_back( i3 ); - } - else - { - lCIdx.push_back( i3 ); - lCIdx.push_back( i2 ); + continue; } - ++nfaces; - i2 = i3; + // if the coordinate is bad then skip it + if( idx >= (int)coordsize ) + continue; - if( colorPerVertex && i1 >= 0 && i2 >= 0 && i3 >= 0 ) + if( NULL == fp ) + fp = lShape.NewFacet(); + + // push the vertex value and index + fp->AddVertex( pcoords[idx], idx ); + + // push the color if appropriate + if( !colorPerVertex ) { - pc1.SetColor( pc2 ); - pc2.SetColor( pc3 ); - if( colorIndex.empty() ) { - cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z ); + cn->GetColor( cidx, tc.x, tc.y, tc.z ); pc1.SetColor( tc.x, tc.y, tc.z ); - cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z ); - pc2.SetColor( tc.x, tc.y, tc.z ); - cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z ); - pc3.SetColor( tc.x, tc.y, tc.z ); + fp->AddColor( pc1 ); } else - cn->GetColor( colorIndex[cIndex++], tc.x, tc.y, tc.z ); - - pc3.SetColor( tc.x, tc.y, tc.z ); - } - - if( idx == vsize ) - break; - - i3 = coordIndex[idx++]; - - while( ( i1 < 0 || i2 < 0 || i3 < 0 ) && ( idx < vsize ) ) - { - if( i3 < 0 ) { - faces.push_back( nfaces ); - nfaces = 0; - - if( !colorPerVertex ) - { - if( colorIndex.empty() || cIndex >= cMaxIdx ) - cn->GetColor( cIndex++, tc.x, tc.y, tc.z ); - else - cn->GetColor( colorIndex[cIndex++], tc.x, tc.y, tc.z ); - - pc1.SetColor( tc.x, tc.y, tc.z ); - pc2.SetColor( tc.x, tc.y, tc.z ); - pc3.SetColor( tc.x, tc.y, tc.z ); - } - } - - i1 = i2; - i2 = i3; - - if( colorPerVertex ) - { - pc1.SetColor( pc2 ); - pc2.SetColor( pc3 ); - - if( colorIndex.empty() ) - { - cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z ); - pc1.SetColor( tc.x, tc.y, tc.z ); - cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z ); - pc2.SetColor( tc.x, tc.y, tc.z ); - cn->GetColor( coordIndex[idx], tc.x, tc.y, tc.z ); - pc3.SetColor( tc.x, tc.y, tc.z ); - } + if( cidx < colorIndex.size() ) + cn->GetColor( colorIndex[cidx], tc.x, tc.y, tc.z ); else - cn->GetColor( colorIndex[cIndex++], tc.x, tc.y, tc.z ); + cn->GetColor( colorIndex.back(), tc.x, tc.y, tc.z ); - pc3.SetColor( tc.x, tc.y, tc.z ); - } - - i3 = coordIndex[idx++]; - - // any invalid polygons shall void the entire faceset; this is a requirement - // to ensure correct handling of the normals - if( ( i1 < 0 && i2 < 0 ) || ( i1 < 0 && i3 < 0 ) || ( i2 < 0 && i3 < 0 ) ) - return NULL; - } - - if( i1 < 0 || i2 < 0 || i3 < 0 ) - break; - } - } - - if( lCIdx.empty() ) - return NULL; - - if( calcNormals || NULL == normal ) - { - // create a vertex list for per-face per-vertex normals - std::vector< int >::iterator sI = lCIdx.begin(); - std::vector< int >::iterator eI = lCIdx.end(); - - while( sI != eI ) - { - lCPts.push_back( SGPOINT( pcoords[*sI].x, pcoords[*sI].y, pcoords[*sI].z ) ); - ++sI; - } - - for( size_t i = 0; i < lCPts.size(); i += 3 ) - { - SGVECTOR sv = S3D::CalcTriNorm( lCPts[i], lCPts[i+1], lCPts[i+2] ); - lCNorm.push_back( sv ); - lCNorm.push_back( sv ); - lCNorm.push_back( sv ); - } - - } - else - { - // XXX - TO IMPLEMENT - return NULL; - /* - // use the vertex list as is - if( normalPerVertex ) - { - // normalPerVertex = TRUE - // rules: - // + if normalIndex is not EMPTY, it is used to select a normal for each vertex - // + if normalIndex is EMPTY, the normal list is used in order per vertex - - if( normalIndex.empty() ) - { - for( size_t i = 0; i < coordsize; ++i ) - { - lCPts.push_back( SGPOINT( pcoords[i].x, pcoords[i].y, pcoords[i].z ) ); - - // XXX - TO IMPLEMENT - } - } - else - { - // XXX - TO IMPLEMENT: index the normals + pc1.SetColor( tc.x, tc.y, tc.z ); + fp->AddColor( pc1 ); } } else { - // normalPerVertex = FALSE - // rules: - // + if normalIndex is not EMPTY, it is used to select a normal for each face - // + if normalIndex is EMPTY, the normal list is used in order per face + if( colorIndex.empty() ) + { + cn->GetColor( idx, tc.x, tc.y, tc.z ); + pc1.SetColor( tc.x, tc.y, tc.z ); + fp->AddColor( pc1 ); + } + else + { + if( iCoord < colorIndex.size() ) + cn->GetColor( colorIndex[iCoord], tc.x, tc.y, tc.z ); + else + cn->GetColor( colorIndex.back(), tc.x, tc.y, tc.z ); + pc1.SetColor( tc.x, tc.y, tc.z ); + fp->AddColor( pc1 ); + } } - //*/ + } } - IFSG_FACESET fsNode( aParent ); - IFSG_COORDS cpNode( fsNode ); - cpNode.SetCoordsList( lCPts.size(), &lCPts[0] ); - IFSG_COORDINDEX ciNode( fsNode ); + SGNODE* np = NULL; - if( calcNormals || NULL == normal ) - { - for( int i = 0; i < (int)lCPts.size(); ++i ) - ciNode.AddIndex( i ); - } + if( ccw ) + np = lShape.CalcShape( aParent, NULL, ORD_CCW, creaseLimit, true ); else - { - ciNode.SetIndices( lCIdx.size(), &lCIdx[0] ); - } + np = lShape.CalcShape( aParent, NULL, ORD_CLOCKWISE, creaseLimit, true ); - IFSG_NORMALS nmNode( fsNode ); - nmNode.SetNormalList( lCNorm.size(), &lCNorm[0] ); - - if( !lColors.empty() ) - { - IFSG_COLORS nmColor( fsNode ); - nmColor.SetColorList( lColors.size(), &lColors[0] ); - } - - m_sgNode = fsNode.GetRawPtr(); - - return m_sgNode; + return np; } diff --git a/plugins/3d/vrml/v2/vrml2_faceset.h b/plugins/3d/vrml/v2/vrml2_faceset.h index 5397ce8b66..c7f7044605 100644 --- a/plugins/3d/vrml/v2/vrml2_faceset.h +++ b/plugins/3d/vrml/v2/vrml2_faceset.h @@ -58,6 +58,7 @@ private: std::vector< int > normalIndex; float creaseAngle; + float creaseLimit; /** @@ -87,7 +88,7 @@ public: bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); /** * Function HasColors diff --git a/plugins/3d/vrml/v2/vrml2_lineset.cpp b/plugins/3d/vrml/v2/vrml2_lineset.cpp index a409d859ba..e55103fe20 100644 --- a/plugins/3d/vrml/v2/vrml2_lineset.cpp +++ b/plugins/3d/vrml/v2/vrml2_lineset.cpp @@ -377,7 +377,7 @@ bool WRL2LINESET::Read( WRLPROC& proc, WRL2BASE* aTopNode ) } -SGNODE* WRL2LINESET::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2LINESET::TranslateToSG( SGNODE* aParent ) { // note: there are no plans to support drawing of lines return NULL; diff --git a/plugins/3d/vrml/v2/vrml2_lineset.h b/plugins/3d/vrml/v2/vrml2_lineset.h index e7cd0ba648..509c4f82cc 100644 --- a/plugins/3d/vrml/v2/vrml2_lineset.h +++ b/plugins/3d/vrml/v2/vrml2_lineset.h @@ -77,7 +77,7 @@ public: bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); /** * Function HasColors diff --git a/plugins/3d/vrml/v2/vrml2_material.cpp b/plugins/3d/vrml/v2/vrml2_material.cpp index dab62e6abf..6452289587 100644 --- a/plugins/3d/vrml/v2/vrml2_material.cpp +++ b/plugins/3d/vrml/v2/vrml2_material.cpp @@ -296,7 +296,7 @@ bool WRL2MATERIAL::Read( WRLPROC& proc, WRL2BASE* aTopNode ) } -SGNODE* WRL2MATERIAL::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2MATERIAL::TranslateToSG( SGNODE* aParent ) { S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent ); diff --git a/plugins/3d/vrml/v2/vrml2_material.h b/plugins/3d/vrml/v2/vrml2_material.h index 1d84d0b0b1..c3daa1f953 100644 --- a/plugins/3d/vrml/v2/vrml2_material.h +++ b/plugins/3d/vrml/v2/vrml2_material.h @@ -63,7 +63,7 @@ public: bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); }; #endif // VRML2_MATERIAL_H diff --git a/plugins/3d/vrml/v2/vrml2_node.h b/plugins/3d/vrml/v2/vrml2_node.h index 5a14ad53a9..4435ee13fe 100644 --- a/plugins/3d/vrml/v2/vrml2_node.h +++ b/plugins/3d/vrml/v2/vrml2_node.h @@ -185,7 +185,7 @@ public: * @param aParent is a pointer to the parent SG node * @return is non-NULL on success */ - virtual SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ) = 0; + virtual SGNODE* TranslateToSG( SGNODE* aParent ) = 0; }; #endif // VRML2_NODE_H diff --git a/plugins/3d/vrml/v2/vrml2_norms.cpp b/plugins/3d/vrml/v2/vrml2_norms.cpp index 32347eff4f..a75622a6f4 100644 --- a/plugins/3d/vrml/v2/vrml2_norms.cpp +++ b/plugins/3d/vrml/v2/vrml2_norms.cpp @@ -192,7 +192,7 @@ bool WRL2NORMS::Read( WRLPROC& proc, WRL2BASE* aTopNode ) } -SGNODE* WRL2NORMS::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2NORMS::TranslateToSG( SGNODE* aParent ) { // any data manipulation must be performed by the parent node return NULL; diff --git a/plugins/3d/vrml/v2/vrml2_norms.h b/plugins/3d/vrml/v2/vrml2_norms.h index 929f2ee48a..7eb5a5ff34 100644 --- a/plugins/3d/vrml/v2/vrml2_norms.h +++ b/plugins/3d/vrml/v2/vrml2_norms.h @@ -58,7 +58,7 @@ public: bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); }; #endif // VRML2_NORMS_H diff --git a/plugins/3d/vrml/v2/vrml2_pointset.cpp b/plugins/3d/vrml/v2/vrml2_pointset.cpp index 0ea67d26cd..e7d10e1f83 100644 --- a/plugins/3d/vrml/v2/vrml2_pointset.cpp +++ b/plugins/3d/vrml/v2/vrml2_pointset.cpp @@ -325,7 +325,7 @@ bool WRL2POINTSET::Read( WRLPROC& proc, WRL2BASE* aTopNode ) } -SGNODE* WRL2POINTSET::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2POINTSET::TranslateToSG( SGNODE* aParent ) { // note: there are no plans to support drawing of points return NULL; diff --git a/plugins/3d/vrml/v2/vrml2_pointset.h b/plugins/3d/vrml/v2/vrml2_pointset.h index 76a57d0828..5390a3fd68 100644 --- a/plugins/3d/vrml/v2/vrml2_pointset.h +++ b/plugins/3d/vrml/v2/vrml2_pointset.h @@ -72,7 +72,7 @@ public: bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); /** * Function HasColors diff --git a/plugins/3d/vrml/v2/vrml2_shape.cpp b/plugins/3d/vrml/v2/vrml2_shape.cpp index 7d44fc5139..e5714f1a24 100644 --- a/plugins/3d/vrml/v2/vrml2_shape.cpp +++ b/plugins/3d/vrml/v2/vrml2_shape.cpp @@ -326,7 +326,7 @@ bool WRL2SHAPE::Read( WRLPROC& proc, WRL2BASE* aTopNode ) } -SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent ) { if( NULL == geometry ) return NULL; @@ -401,11 +401,11 @@ SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent, bool calcNormals ) IFSG_SHAPE shNode( aParent ); SGNODE* pShape = shNode.GetRawPtr(); - SGNODE* pGeom = geometry->TranslateToSG( pShape, calcNormals ); + SGNODE* pGeom = geometry->TranslateToSG( pShape ); SGNODE* pApp = NULL; if( NULL != appearance ) - pApp = appearance->TranslateToSG( pShape, calcNormals ); + pApp = appearance->TranslateToSG( pShape ); if( ( NULL != appearance && NULL == pApp ) || NULL == pGeom ) { diff --git a/plugins/3d/vrml/v2/vrml2_shape.h b/plugins/3d/vrml/v2/vrml2_shape.h index f351a9bf21..d29885a8ad 100644 --- a/plugins/3d/vrml/v2/vrml2_shape.h +++ b/plugins/3d/vrml/v2/vrml2_shape.h @@ -67,7 +67,7 @@ public: bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); bool AddChildNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); }; #endif // VRML2_SHAPE_H diff --git a/plugins/3d/vrml/v2/vrml2_switch.cpp b/plugins/3d/vrml/v2/vrml2_switch.cpp index a6e1bbaff8..9be5127334 100644 --- a/plugins/3d/vrml/v2/vrml2_switch.cpp +++ b/plugins/3d/vrml/v2/vrml2_switch.cpp @@ -273,7 +273,7 @@ bool WRL2SWITCH::readChildren( WRLPROC& proc, WRL2BASE* aTopNode ) } -SGNODE* WRL2SWITCH::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2SWITCH::TranslateToSG( SGNODE* aParent ) { #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 ) std::cerr << " * [INFO] Translating Switch with " << m_Children.size(); @@ -327,5 +327,5 @@ SGNODE* WRL2SWITCH::TranslateToSG( SGNODE* aParent, bool calcNormals ) return NULL; } - return choices[whichChoice]->TranslateToSG( aParent, calcNormals ); + return choices[whichChoice]->TranslateToSG( aParent ); } diff --git a/plugins/3d/vrml/v2/vrml2_switch.h b/plugins/3d/vrml/v2/vrml2_switch.h index 5ee0fa1a57..a7edf3946f 100644 --- a/plugins/3d/vrml/v2/vrml2_switch.h +++ b/plugins/3d/vrml/v2/vrml2_switch.h @@ -58,7 +58,7 @@ public: // functions inherited from WRL2NODE bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); }; #endif // VRML2_SWITCH_H diff --git a/plugins/3d/vrml/v2/vrml2_transform.cpp b/plugins/3d/vrml/v2/vrml2_transform.cpp index c430ff9103..6a91796b3d 100644 --- a/plugins/3d/vrml/v2/vrml2_transform.cpp +++ b/plugins/3d/vrml/v2/vrml2_transform.cpp @@ -363,7 +363,7 @@ bool WRL2TRANSFORM::readChildren( WRLPROC& proc, WRL2BASE* aTopNode ) } -SGNODE* WRL2TRANSFORM::TranslateToSG( SGNODE* aParent, bool calcNormals ) +SGNODE* WRL2TRANSFORM::TranslateToSG( SGNODE* aParent ) { #if defined( DEBUG_VRML2 ) && ( DEBUG_VRML2 > 2 ) std::cerr << " * [INFO] Translating Transform with " << m_Children.size(); @@ -432,7 +432,7 @@ SGNODE* WRL2TRANSFORM::TranslateToSG( SGNODE* aParent, bool calcNormals ) case WRL2_INLINE: case WRL2_TRANSFORM: - if( NULL != (*sC)->TranslateToSG( txNode.GetRawPtr(), calcNormals ) ) + if( NULL != (*sC)->TranslateToSG( txNode.GetRawPtr() ) ) test = true; break; diff --git a/plugins/3d/vrml/v2/vrml2_transform.h b/plugins/3d/vrml/v2/vrml2_transform.h index ade1fd94f1..857064eafc 100644 --- a/plugins/3d/vrml/v2/vrml2_transform.h +++ b/plugins/3d/vrml/v2/vrml2_transform.h @@ -63,7 +63,7 @@ public: // functions inherited from WRL2NODE bool Read( WRLPROC& proc, WRL2BASE* aTopNode ); bool AddRefNode( WRL2NODE* aNode ); - SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals ); + SGNODE* TranslateToSG( SGNODE* aParent ); }; #endif // VRML2_TRANSFORM_H diff --git a/plugins/3d/vrml/vrml.cpp b/plugins/3d/vrml/vrml.cpp index 27a7d721b1..e119f51e71 100644 --- a/plugins/3d/vrml/vrml.cpp +++ b/plugins/3d/vrml/vrml.cpp @@ -252,7 +252,7 @@ SCENEGRAPH* Load( char const* aFileName ) #endif // for now we recalculate all normals per-vertex per-face - scene = (SCENEGRAPH*)bp->TranslateToSG( NULL, true ); + scene = (SCENEGRAPH*)bp->TranslateToSG( NULL ); } delete bp; diff --git a/plugins/3d/vrml/wrlfacet.cpp b/plugins/3d/vrml/wrlfacet.cpp index 61d7b9956a..5d91805719 100644 --- a/plugins/3d/vrml/wrlfacet.cpp +++ b/plugins/3d/vrml/wrlfacet.cpp @@ -27,14 +27,13 @@ #include #include #include -#include #include "wrlfacet.h" static bool VDegenerate( glm::vec3* pts ) { - // note: only checks the degenerate case of zero length sized; it + // note: only checks the degenerate case of zero length sides; it // does not detect the case of 3 distinct collinear points double dx, dy, dz; @@ -43,21 +42,21 @@ static bool VDegenerate( glm::vec3* pts ) dy = pts[1].y - pts[0].y; dz = pts[1].z - pts[0].z; - if( ( dx*dx + dy*dy + dz*dz ) < 1e-6 ) + if( ( dx*dx + dy*dy + dz*dz ) < 1e-9 ) return true; dx = pts[2].x - pts[0].x; dy = pts[2].y - pts[0].y; dz = pts[2].z - pts[0].z; - if( ( dx*dx + dy*dy + dz*dz ) < 1e-6 ) + if( ( dx*dx + dy*dy + dz*dz ) < 1e-9 ) return true; dx = pts[2].x - pts[1].x; dy = pts[2].y - pts[1].y; dz = pts[2].z - pts[1].z; - if( ( dx*dx + dy*dy + dz*dz ) < 1e-6 ) + if( ( dx*dx + dy*dy + dz*dz ) < 1e-9 ) return true; return false; @@ -106,17 +105,17 @@ static float VCalcAreaSq( const WRLVEC3F& p1, const WRLVEC3F& p2, const WRLVEC3F dx = p2.x - p1.x; dy = p2.y - p1.y; dz = p2.z - p1.z; - float a = sqrt( dx*dx + dy*dy + dz*dz ); + float a = sqrtf( dx*dx + dy*dy + dz*dz ); dx = p3.x - p2.x; dy = p3.y - p2.y; dz = p3.z - p2.z; - float b = sqrt( dx*dx + dy*dy + dz*dz ); + float b = sqrtf( dx*dx + dy*dy + dz*dz ); dx = p3.x - p1.x; dy = p3.y - p1.y; dz = p3.z - p1.z; - float c = sqrt( dx*dx + dy*dy + dz*dz ); + float c = sqrtf( dx*dx + dy*dy + dz*dz ); float s = (a + b + c) * 0.5; @@ -349,7 +348,7 @@ void FACET::CalcVertexNormal( int aIndex, std::list< FACET* > &aFacetList, float continue; } - // check the create angle limit + // check the crease angle limit (*sF)->GetFaceNormal( fp[1] ); float thrs = VCalcCosAngle( fp[0], face_normal, fp[1] ); @@ -368,11 +367,16 @@ void FACET::CalcVertexNormal( int aIndex, std::list< FACET* > &aFacetList, float } // normalize the vector - glm::vec3 tri = glm::vec3( norms[idx].x, norms[idx].y, norms[idx].z ); - normalize( tri ); - norms[idx].x = tri.x; - norms[idx].y = tri.y; - norms[idx].z = tri.z; + float dn = sqrtf( norms[idx].x * norms[idx].x + + norms[idx].y * norms[idx].y + + norms[idx].z * norms[idx].z ); + + if( dn > FLT_EPSILON ) + { + norms[idx].x /= dn; + norms[idx].y /= dn; + norms[idx].z /= dn; + } return; } @@ -685,7 +689,7 @@ FACET* SHAPE::NewFacet() SGNODE* SHAPE::CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrder, - float aCreaseLimit ) + float aCreaseLimit, bool isVRML2 ) { if( facets.empty() || !facets.front()->HasMinPoints() ) return NULL; @@ -760,14 +764,19 @@ SGNODE* SHAPE::CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrd if( vertices.size() < 3 ) return NULL; - IFSG_SHAPE shapeNode( aParent ); + IFSG_SHAPE shapeNode( false ); - if( aColor ) + if( !isVRML2 ) { - if( NULL == S3D::GetSGNodeParent( aColor ) ) - shapeNode.AddChildNode( aColor ); - else - shapeNode.AddRefNode( aColor ); + shapeNode.NewNode( aParent ); + + if( aColor ) + { + if( NULL == S3D::GetSGNodeParent( aColor ) ) + shapeNode.AddChildNode( aColor ); + else + shapeNode.AddRefNode( aColor ); + } } std::vector< SGPOINT > lCPts; // vertex points in SGPOINT (double) format @@ -787,7 +796,13 @@ SGNODE* SHAPE::CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrd vertices.clear(); normals.clear(); - IFSG_FACESET fsNode( shapeNode ); + IFSG_FACESET fsNode( false ); + + if( !isVRML2 ) + fsNode.NewNode( shapeNode ); + else + fsNode.NewNode( aParent ); + IFSG_COORDS cpNode( fsNode ); cpNode.SetCoordsList( lCPts.size(), &lCPts[0] ); IFSG_COORDINDEX ciNode( fsNode ); @@ -805,5 +820,8 @@ SGNODE* SHAPE::CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrd colors.clear(); } + if( !isVRML2 ) + return shapeNode.GetRawPtr(); + return fsNode.GetRawPtr(); } diff --git a/plugins/3d/vrml/wrlfacet.h b/plugins/3d/vrml/wrlfacet.h index 2e807412b9..e3bbf2094e 100644 --- a/plugins/3d/vrml/wrlfacet.h +++ b/plugins/3d/vrml/wrlfacet.h @@ -142,7 +142,7 @@ public: FACET* NewFacet(); SGNODE* CalcShape( SGNODE* aParent, SGNODE* aColor, WRL1_ORDER aVertexOrder, - float aCreaseAngle = 0.5235983 ); + float aCreaseLimit = 0.878, bool isVRML2 = false ); }; #endif // WRLFACET_H