Work in progress: implementing SG translation for VRML1 models
This commit is contained in:
parent
38543ab94f
commit
6b873ed46b
|
@ -616,8 +616,12 @@ void PANEL_PREV_3D::UpdateModelName( wxString const& aModelName )
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wxSizer* ws = new wxBoxSizer( wxHORIZONTAL );
|
wxSizer* ws = new wxBoxSizer( wxHORIZONTAL );
|
||||||
ws->Add( canvas, 10, wxEXPAND );
|
canvas->Set3DModel( *model );
|
||||||
preview->SetSizerAndFit( ws );
|
ws->Add( canvas, 1, wxEXPAND );
|
||||||
|
preview->SetSizer( ws );
|
||||||
|
preview->Layout();
|
||||||
|
ws->FitInside( preview );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas->Set3DModel( *model );
|
canvas->Set3DModel( *model );
|
||||||
|
|
|
@ -15,13 +15,11 @@ add_library( kicad_3dsg SHARED
|
||||||
sg_coords.cpp
|
sg_coords.cpp
|
||||||
sg_normals.cpp
|
sg_normals.cpp
|
||||||
sg_index.cpp
|
sg_index.cpp
|
||||||
sg_colorindex.cpp
|
|
||||||
sg_coordindex.cpp
|
sg_coordindex.cpp
|
||||||
ifsg_node.cpp
|
ifsg_node.cpp
|
||||||
ifsg_transform.cpp
|
ifsg_transform.cpp
|
||||||
ifsg_appearance.cpp
|
ifsg_appearance.cpp
|
||||||
ifsg_index.cpp
|
ifsg_index.cpp
|
||||||
ifsg_colorindex.cpp
|
|
||||||
ifsg_coordindex.cpp
|
ifsg_coordindex.cpp
|
||||||
ifsg_colors.cpp
|
ifsg_colors.cpp
|
||||||
ifsg_coords.cpp
|
ifsg_coords.cpp
|
||||||
|
|
|
@ -173,7 +173,7 @@ bool IFSG_COLORS::GetColorList( size_t& aListSize, SGCOLOR*& aColorList )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IFSG_COLORS::SetColorList( size_t& aListSize, const SGCOLOR* aColorList )
|
bool IFSG_COLORS::SetColorList( size_t aListSize, const SGCOLOR* aColorList )
|
||||||
{
|
{
|
||||||
if( NULL == m_node )
|
if( NULL == m_node )
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,7 +35,6 @@ SGFACESET::SGFACESET( SGNODE* aParent ) : SGNODE( aParent )
|
||||||
{
|
{
|
||||||
m_SGtype = S3D::SGTYPE_FACESET;
|
m_SGtype = S3D::SGTYPE_FACESET;
|
||||||
m_Colors = NULL;
|
m_Colors = NULL;
|
||||||
m_ColorIndices = NULL;
|
|
||||||
m_Coords = NULL;
|
m_Coords = NULL;
|
||||||
m_CoordIndices = NULL;
|
m_CoordIndices = NULL;
|
||||||
m_Normals = NULL;
|
m_Normals = NULL;
|
||||||
|
@ -107,13 +106,6 @@ SGFACESET::~SGFACESET()
|
||||||
m_Normals = NULL;
|
m_Normals = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_ColorIndices )
|
|
||||||
{
|
|
||||||
m_ColorIndices->SetParent( NULL, false );
|
|
||||||
delete m_ColorIndices;
|
|
||||||
m_ColorIndices = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_CoordIndices )
|
if( m_CoordIndices )
|
||||||
{
|
{
|
||||||
m_CoordIndices->SetParent( NULL, false );
|
m_CoordIndices->SetParent( NULL, false );
|
||||||
|
@ -173,14 +165,6 @@ SGNODE* SGFACESET::FindNode(const char *aNodeName, const SGNODE *aCaller)
|
||||||
return np;
|
return np;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_ColorIndices )
|
|
||||||
{
|
|
||||||
np = m_ColorIndices->FindNode( aNodeName, this );
|
|
||||||
|
|
||||||
if( np )
|
|
||||||
return np;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_Coords )
|
if( m_Coords )
|
||||||
{
|
{
|
||||||
np = m_Coords->FindNode( aNodeName, this );
|
np = m_Coords->FindNode( aNodeName, this );
|
||||||
|
@ -241,12 +225,6 @@ void SGFACESET::unlinkNode( const SGNODE* aNode, bool isChild )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( aNode == m_ColorIndices )
|
|
||||||
{
|
|
||||||
m_ColorIndices = NULL;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( aNode == m_CoordIndices )
|
if( aNode == m_CoordIndices )
|
||||||
{
|
{
|
||||||
m_CoordIndices = NULL;
|
m_CoordIndices = NULL;
|
||||||
|
@ -377,21 +355,6 @@ bool SGFACESET::addNode( SGNODE* aNode, bool isChild )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( S3D::SGTYPE_COLORINDEX == aNode->GetNodeType() )
|
|
||||||
{
|
|
||||||
if( m_ColorIndices )
|
|
||||||
{
|
|
||||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
|
||||||
std::cerr << " * [BUG] assigning multiple ColorIndex nodes\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ColorIndices = (SGCOLORINDEX*)aNode;
|
|
||||||
m_ColorIndices->SetParent( this );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( S3D::SGTYPE_COORDINDEX == aNode->GetNodeType() )
|
if( S3D::SGTYPE_COORDINDEX == aNode->GetNodeType() )
|
||||||
{
|
{
|
||||||
if( m_CoordIndices )
|
if( m_CoordIndices )
|
||||||
|
@ -440,9 +403,6 @@ void SGFACESET::ReNameNodes( void )
|
||||||
if( m_Colors )
|
if( m_Colors )
|
||||||
m_Colors->ReNameNodes();
|
m_Colors->ReNameNodes();
|
||||||
|
|
||||||
if( m_ColorIndices )
|
|
||||||
m_ColorIndices->ReNameNodes();
|
|
||||||
|
|
||||||
// rename all Coordinates and Indices
|
// rename all Coordinates and Indices
|
||||||
if( m_Coords )
|
if( m_Coords )
|
||||||
m_Coords->ReNameNodes();
|
m_Coords->ReNameNodes();
|
||||||
|
@ -510,9 +470,6 @@ bool SGFACESET::WriteVRML( std::ofstream& aFile, bool aReuseFlag )
|
||||||
if( m_RColors )
|
if( m_RColors )
|
||||||
m_RColors->WriteVRML( aFile, aReuseFlag );
|
m_RColors->WriteVRML( aFile, aReuseFlag );
|
||||||
|
|
||||||
if( m_ColorIndices )
|
|
||||||
m_ColorIndices->WriteVRML( aFile, aReuseFlag );
|
|
||||||
|
|
||||||
aFile << "}\n";
|
aFile << "}\n";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -553,7 +510,7 @@ bool SGFACESET::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
||||||
}
|
}
|
||||||
|
|
||||||
aFile << "[" << GetName() << "]";
|
aFile << "[" << GetName() << "]";
|
||||||
#define NITEMS 8
|
#define NITEMS 7
|
||||||
bool items[NITEMS];
|
bool items[NITEMS];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -588,10 +545,6 @@ bool SGFACESET::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
||||||
if( NULL != m_RColors )
|
if( NULL != m_RColors )
|
||||||
items[i] = true;
|
items[i] = true;
|
||||||
|
|
||||||
++i;
|
|
||||||
if( NULL != m_ColorIndices )
|
|
||||||
items[i] = true;
|
|
||||||
|
|
||||||
for( int i = 0; i < NITEMS; ++i )
|
for( int i = 0; i < NITEMS; ++i )
|
||||||
aFile.write( (char*)&items[i], sizeof(bool) );
|
aFile.write( (char*)&items[i], sizeof(bool) );
|
||||||
|
|
||||||
|
@ -616,9 +569,6 @@ bool SGFACESET::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
||||||
if( items[6] )
|
if( items[6] )
|
||||||
aFile << "[" << m_RColors->GetName() << "]";
|
aFile << "[" << m_RColors->GetName() << "]";
|
||||||
|
|
||||||
if( items[7] )
|
|
||||||
m_ColorIndices->WriteCache( aFile, this );
|
|
||||||
|
|
||||||
if( aFile.fail() )
|
if( aFile.fail() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -629,7 +579,7 @@ bool SGFACESET::WriteCache( std::ofstream& aFile, SGNODE* parentNode )
|
||||||
bool SGFACESET::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
bool SGFACESET::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
||||||
{
|
{
|
||||||
if( m_Coords || m_RCoords || m_CoordIndices
|
if( m_Coords || m_RCoords || m_CoordIndices
|
||||||
|| m_Colors || m_RColors || m_ColorIndices
|
|| m_Colors || m_RColors
|
||||||
|| m_Normals || m_RNormals )
|
|| m_Normals || m_RNormals )
|
||||||
{
|
{
|
||||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||||
|
@ -637,7 +587,7 @@ bool SGFACESET::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NITEMS 8
|
#define NITEMS 7
|
||||||
bool items[NITEMS];
|
bool items[NITEMS];
|
||||||
|
|
||||||
for( int i = 0; i < NITEMS; ++i )
|
for( int i = 0; i < NITEMS; ++i )
|
||||||
|
@ -838,28 +788,6 @@ bool SGFACESET::ReadCache( std::ifstream& aFile, SGNODE* parentNode )
|
||||||
m_RColors->addNodeRef( this );
|
m_RColors->addNodeRef( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( items[7] )
|
|
||||||
{
|
|
||||||
if( S3D::SGTYPE_COLORINDEX != S3D::ReadTag( aFile, name ) )
|
|
||||||
{
|
|
||||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
|
||||||
std::cerr << " * [INFO] corrupt data; bad color index tag at position ";
|
|
||||||
std::cerr << aFile.tellg() << "\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_ColorIndices = new SGCOLORINDEX( this );
|
|
||||||
m_ColorIndices->SetName( name.c_str() );
|
|
||||||
|
|
||||||
if( !m_ColorIndices->ReadCache( aFile, this ) )
|
|
||||||
{
|
|
||||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
|
||||||
std::cerr << " * [INFO] corrupt data while reading color index '";
|
|
||||||
std::cerr << name << "'\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( aFile.fail() )
|
if( aFile.fail() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -969,62 +897,10 @@ bool SGFACESET::validate( void )
|
||||||
|
|
||||||
if( NULL != pColors )
|
if( NULL != pColors )
|
||||||
{
|
{
|
||||||
if( NULL == m_ColorIndices )
|
// we must have at least as many colors as vertices
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
|
||||||
std::cerr << " * [INFO] bad model; no color indices\n";
|
|
||||||
#endif
|
|
||||||
validated = true;
|
|
||||||
valid = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// we must have at least 1 color in the list
|
|
||||||
size_t nColor = 0;
|
size_t nColor = 0;
|
||||||
SGCOLOR* pColor = NULL;
|
SGCOLOR* pColor = NULL;
|
||||||
pColors->GetColorList( nColor, pColor );
|
pColors->GetColorList( nColor, pColor );
|
||||||
|
|
||||||
if( nColor < 1 )
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
|
||||||
std::cerr << " * [INFO] bad model; no colors\n";
|
|
||||||
#endif
|
|
||||||
validated = true;
|
|
||||||
valid = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nCLIdx = 0;
|
|
||||||
int* pCLIdx = NULL;
|
|
||||||
m_ColorIndices->GetIndices( nCLIdx, pCLIdx );
|
|
||||||
|
|
||||||
if( nCLIdx != nCoords )
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
|
||||||
std::cerr << " * [INFO] bad model; color indices do not match number of vertices\n";
|
|
||||||
#endif
|
|
||||||
validated = true;
|
|
||||||
valid = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that color[n] >= 0 and < nColors
|
|
||||||
for( size_t i = 0; i < nCLIdx; ++i )
|
|
||||||
{
|
|
||||||
if( pCLIdx[i] < 0 || pCLIdx[i] >= nCLIdx )
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
|
||||||
std::cerr << " * [INFO] bad model; color index out of bounds\n";
|
|
||||||
#endif
|
|
||||||
validated = true;
|
|
||||||
valid = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
validated = true;
|
validated = true;
|
||||||
|
|
|
@ -51,7 +51,6 @@ private:
|
||||||
public:
|
public:
|
||||||
// owned objects
|
// owned objects
|
||||||
SGCOLORS* m_Colors;
|
SGCOLORS* m_Colors;
|
||||||
SGCOLORINDEX* m_ColorIndices;
|
|
||||||
SGCOORDS* m_Coords;
|
SGCOORDS* m_Coords;
|
||||||
SGCOORDINDEX* m_CoordIndices;
|
SGCOORDINDEX* m_CoordIndices;
|
||||||
SGNORMALS* m_Normals;
|
SGNORMALS* m_Normals;
|
||||||
|
|
|
@ -624,7 +624,6 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
|
||||||
}
|
}
|
||||||
|
|
||||||
SGCOLORS* pc = pf->m_Colors;
|
SGCOLORS* pc = pf->m_Colors;
|
||||||
SGCOLORINDEX* cidx = pf->m_ColorIndices;
|
|
||||||
SGCOORDS* pv = pf->m_Coords;
|
SGCOORDS* pv = pf->m_Coords;
|
||||||
SGCOORDINDEX* vidx = pf->m_CoordIndices;
|
SGCOORDINDEX* vidx = pf->m_CoordIndices;
|
||||||
SGNORMALS* pn = pf->m_Normals;
|
SGNORMALS* pn = pf->m_Normals;
|
||||||
|
@ -643,6 +642,24 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
|
||||||
SGPOINT* pCoords = NULL;
|
SGPOINT* pCoords = NULL;
|
||||||
pv->GetCoordsList( nCoords, pCoords );
|
pv->GetCoordsList( nCoords, pCoords );
|
||||||
|
|
||||||
|
size_t nColors = 0;
|
||||||
|
SGCOLOR* pColors = NULL;
|
||||||
|
|
||||||
|
if( pc )
|
||||||
|
{
|
||||||
|
// check the vertex colors
|
||||||
|
pc->GetColorList( nColors, pColors );
|
||||||
|
|
||||||
|
if( nColors < nCoords )
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||||
|
std::cerr << " * [INFO] bad model; not enough colors per vertex\n";
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// set the vertex indices
|
// set the vertex indices
|
||||||
size_t nvidx = 0;
|
size_t nvidx = 0;
|
||||||
int* lv = NULL;
|
int* lv = NULL;
|
||||||
|
@ -673,17 +690,39 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// construct the final vertex list
|
// construct the final vertex/color list
|
||||||
|
SFVEC3F* lColors = NULL;
|
||||||
SFVEC3F* lCoords = new SFVEC3F[ vertices.size() ];
|
SFVEC3F* lCoords = new SFVEC3F[ vertices.size() ];
|
||||||
|
double red, green, blue;
|
||||||
int ti, ii;
|
int ti, ii;
|
||||||
|
|
||||||
for( size_t i = 0; i < vertices.size(); ++i )
|
if( pc )
|
||||||
{
|
{
|
||||||
ti = vertices[i];
|
SFVEC3F* lColors = new SFVEC3F[vertices.size()];
|
||||||
glm::dvec4 pt( pCoords[ti].x, pCoords[ti].y, pCoords[ti].z, 1.0 );
|
m.m_Color = lColors;
|
||||||
pt = (*aTransform) * pt;
|
}
|
||||||
|
|
||||||
lCoords[i] = SFVEC3F( pt.x, pt.y, pt.z );
|
|
||||||
|
if( pc )
|
||||||
|
{
|
||||||
|
for( size_t i = 0; i < vertices.size(); ++i )
|
||||||
|
{
|
||||||
|
ti = vertices[i];
|
||||||
|
glm::dvec4 pt( pCoords[ti].x, pCoords[ti].y, pCoords[ti].z, 1.0 );
|
||||||
|
pt = (*aTransform) * pt;
|
||||||
|
pColors[ti].GetColor( lColors[i].x, lColors[i].y, lColors[i].z );
|
||||||
|
lCoords[i] = SFVEC3F( pt.x, pt.y, pt.z );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for( size_t i = 0; i < vertices.size(); ++i )
|
||||||
|
{
|
||||||
|
ti = vertices[i];
|
||||||
|
glm::dvec4 pt( pCoords[ti].x, pCoords[ti].y, pCoords[ti].z, 1.0 );
|
||||||
|
pt = (*aTransform) * pt;
|
||||||
|
lCoords[i] = SFVEC3F( pt.x, pt.y, pt.z );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m.m_VertexSize = (unsigned int) vertices.size();
|
m.m_VertexSize = (unsigned int) vertices.size();
|
||||||
|
@ -718,30 +757,6 @@ bool SGSHAPE::Prepare( const glm::dmat4* aTransform,
|
||||||
}
|
}
|
||||||
|
|
||||||
m.m_Normals = lNorms;
|
m.m_Normals = lNorms;
|
||||||
|
|
||||||
// use per-vertex colors if available
|
|
||||||
if( pc )
|
|
||||||
{
|
|
||||||
size_t ncidx = 0;
|
|
||||||
int* lcidx = NULL;
|
|
||||||
cidx->GetIndices( ncidx, lcidx );
|
|
||||||
|
|
||||||
// set the vertex colors
|
|
||||||
size_t nColors = 0;
|
|
||||||
SGCOLOR* pColors = NULL;
|
|
||||||
pc->GetColorList( nColors, pColors );
|
|
||||||
SFVEC3F* lColors = new SFVEC3F[ vertices.size() ];
|
|
||||||
double red, green, blue;
|
|
||||||
|
|
||||||
for( size_t i = 0; i < vertices.size(); ++i )
|
|
||||||
{
|
|
||||||
ti = vertices[i];
|
|
||||||
pColors[ lcidx[ti] ].GetColor( lColors[i].x, lColors[i].y, lColors[i].z );
|
|
||||||
}
|
|
||||||
|
|
||||||
m.m_Color = lColors;
|
|
||||||
}
|
|
||||||
|
|
||||||
meshes.push_back( m );
|
meshes.push_back( m );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include "plugins/3dapi/ifsg_colors.h"
|
#include "plugins/3dapi/ifsg_colors.h"
|
||||||
#include "plugins/3dapi/ifsg_coords.h"
|
#include "plugins/3dapi/ifsg_coords.h"
|
||||||
#include "plugins/3dapi/ifsg_faceset.h"
|
#include "plugins/3dapi/ifsg_faceset.h"
|
||||||
#include "plugins/3dapi/ifsg_colorindex.h"
|
|
||||||
#include "plugins/3dapi/ifsg_coordindex.h"
|
#include "plugins/3dapi/ifsg_coordindex.h"
|
||||||
#include "plugins/3dapi/ifsg_normals.h"
|
#include "plugins/3dapi/ifsg_normals.h"
|
||||||
#include "plugins/3dapi/ifsg_shape.h"
|
#include "plugins/3dapi/ifsg_shape.h"
|
||||||
|
|
|
@ -50,7 +50,7 @@ public:
|
||||||
bool NewNode( IFSG_NODE& aParent );
|
bool NewNode( IFSG_NODE& aParent );
|
||||||
|
|
||||||
bool GetColorList( size_t& aListSize, SGCOLOR*& aColorList );
|
bool GetColorList( size_t& aListSize, SGCOLOR*& aColorList );
|
||||||
bool SetColorList( size_t& aListSize, const SGCOLOR* aColorList );
|
bool SetColorList( size_t aListSize, const SGCOLOR* aColorList );
|
||||||
bool AddColor( double aRedValue, double aGreenValue, double aBlueValue );
|
bool AddColor( double aRedValue, double aGreenValue, double aBlueValue );
|
||||||
bool AddColor( const SGCOLOR& aColor );
|
bool AddColor( const SGCOLOR& aColor );
|
||||||
};
|
};
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "vrml1_base.h"
|
#include "vrml1_base.h"
|
||||||
#include "vrml1_faceset.h"
|
#include "vrml1_faceset.h"
|
||||||
#include "vrml1_coords.h"
|
#include "vrml1_coords.h"
|
||||||
|
#include "vrml1_material.h"
|
||||||
#include "plugins/3dapi/ifsg_all.h"
|
#include "plugins/3dapi/ifsg_all.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -172,6 +173,34 @@ bool WRL1FACESET::Read( WRLPROC& proc, WRL1BASE* aTopNode )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if( !glob.compare( "normalIndex" ) )
|
||||||
|
{
|
||||||
|
if( !proc.ReadMFInt( normIndex ) )
|
||||||
|
{
|
||||||
|
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
|
||||||
|
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||||
|
std::cerr << " * [INFO] invalid normalIndex at line " << line << ", column ";
|
||||||
|
std::cerr << column << "\n";
|
||||||
|
std::cerr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
|
||||||
|
std::cerr << " * [INFO] message: '" << proc.GetError() << "'\n";
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( !glob.compare( "textureCoordIndex" ) )
|
||||||
|
{
|
||||||
|
if( !proc.ReadMFInt( texIndex ) )
|
||||||
|
{
|
||||||
|
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
|
||||||
|
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||||
|
std::cerr << " * [INFO] invalid textureCoordIndex at line " << line << ", column ";
|
||||||
|
std::cerr << column << "\n";
|
||||||
|
std::cerr << " * [INFO] file: '" << proc.GetFileName() << "'\n";
|
||||||
|
std::cerr << " * [INFO] message: '" << proc.GetError() << "'\n";
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
|
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 1 )
|
||||||
|
@ -191,39 +220,74 @@ bool WRL1FACESET::Read( WRLPROC& proc, WRL1BASE* aTopNode )
|
||||||
|
|
||||||
SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
{
|
{
|
||||||
#ifdef NOGO
|
|
||||||
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
|
|
||||||
|
|
||||||
if( NULL != aParent && ptype != S3D::SGTYPE_SHAPE )
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_VRML1
|
|
||||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
|
||||||
std::cerr << " * [BUG] IndexedFaceSet does not have a Shape parent (parent ID: ";
|
|
||||||
std::cerr << ptype << ")\n";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_sgNode )
|
if( m_sgNode )
|
||||||
{
|
{
|
||||||
if( NULL != aParent )
|
if( NULL != aParent && !S3D::AddSGNodeRef( aParent, m_sgNode ) )
|
||||||
{
|
return NULL;
|
||||||
if( NULL == S3D::GetSGNodeParent( m_sgNode )
|
|
||||||
&& !S3D::AddSGNodeChild( aParent, m_sgNode ) )
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else if( aParent != S3D::GetSGNodeParent( m_sgNode )
|
|
||||||
&& !S3D::AddSGNodeRef( aParent, m_sgNode ) )
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_sgNode;
|
return m_sgNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_Parent )
|
||||||
|
{
|
||||||
|
WRL1STATUS* cp = m_Parent->GetCurrentSettings();
|
||||||
|
|
||||||
|
if( NULL != cp )
|
||||||
|
m_current = *cp;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( NULL == m_current.coord || NULL == m_current.mat )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// 1. create the vertex/normals/colors lists
|
||||||
|
std::vector< SGPOINT > vlist;
|
||||||
|
std::vector< SGVECTOR > nlist;
|
||||||
|
std::vector< SGCOLOR > colorlist;
|
||||||
|
SGCOLOR partColor;
|
||||||
|
SGNODE* sgcolor = NULL;
|
||||||
|
int nface = 1;
|
||||||
|
|
||||||
|
switch( m_current.matbind )
|
||||||
|
{
|
||||||
|
case BIND_OVERALL:
|
||||||
|
|
||||||
|
// use the first (non-default) appearance definition
|
||||||
|
sgcolor = m_current.mat->GetAppearance( 1 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BIND_PER_FACE:
|
||||||
|
case BIND_PER_VERTEX:
|
||||||
|
case BIND_PER_FACE_INDEXED:
|
||||||
|
case BIND_PER_VERTEX_INDEXED:
|
||||||
|
|
||||||
|
// take the first color definition from the material
|
||||||
|
m_current.mat->GetColor( &partColor, 1 );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
// use the default appearance definition
|
||||||
|
sgcolor = m_current.mat->GetAppearance( 0 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
WRLVEC3F* pts;
|
||||||
|
size_t npts;
|
||||||
|
m_current.coord->GetCoords( pts, npts );
|
||||||
|
|
||||||
|
//while()
|
||||||
|
//qwerty;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef NOGO
|
||||||
|
|
||||||
size_t vsize = coordIndex.size();
|
size_t vsize = coordIndex.size();
|
||||||
|
|
||||||
if( NULL == coord || vsize < 3 )
|
if( NULL == coord || vsize < 3 )
|
||||||
|
|
|
@ -44,6 +44,8 @@ class WRL1FACESET : public WRL1NODE
|
||||||
private:
|
private:
|
||||||
std::vector< int > coordIndex;
|
std::vector< int > coordIndex;
|
||||||
std::vector< int > matIndex;
|
std::vector< int > matIndex;
|
||||||
|
std::vector< int > normIndex;
|
||||||
|
std::vector< int > texIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WRL1FACESET( NAMEREGISTER* aDictionary );
|
WRL1FACESET( NAMEREGISTER* aDictionary );
|
||||||
|
|
|
@ -57,6 +57,13 @@ WRL1MATERIAL::~WRL1MATERIAL()
|
||||||
std::cerr << " * [INFO] Destroying Material node\n";
|
std::cerr << " * [INFO] Destroying Material node\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// destroy any orphaned color nodes
|
||||||
|
for( int i = 0; i < 2; ++i )
|
||||||
|
{
|
||||||
|
if( NULL != colors[i] && NULL == S3D::GetSGNodeParent( colors[i] ) )
|
||||||
|
S3D::DestroyNode( colors[i] );
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +91,9 @@ void WRL1MATERIAL::setDefaults( void )
|
||||||
shininess.push_back( 0.2 );
|
shininess.push_back( 0.2 );
|
||||||
transparency.push_back( 0.0 );
|
transparency.push_back( 0.0 );
|
||||||
|
|
||||||
|
colors[0] = NULL;
|
||||||
|
colors[1] = NULL;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,3 +307,209 @@ SGNODE* WRL1MATERIAL::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SGNODE* WRL1MATERIAL::GetAppearance( int aIndex )
|
||||||
|
{
|
||||||
|
// invalid indices result in the default colors
|
||||||
|
if( aIndex != 0 && aIndex != 1 )
|
||||||
|
aIndex = 0;
|
||||||
|
|
||||||
|
if( NULL != colors[ aIndex ] )
|
||||||
|
return colors[ aIndex ];
|
||||||
|
|
||||||
|
IFSG_APPEARANCE app( true );
|
||||||
|
|
||||||
|
float red, green, blue, val;
|
||||||
|
|
||||||
|
if( aIndex > (int)transparency.size() )
|
||||||
|
val = transparency[0];
|
||||||
|
else
|
||||||
|
val = transparency[aIndex];
|
||||||
|
|
||||||
|
checkRange( val );
|
||||||
|
app.SetTransparency( val );
|
||||||
|
|
||||||
|
if( aIndex > (int)shininess.size() )
|
||||||
|
val = shininess[0];
|
||||||
|
else
|
||||||
|
val = shininess[aIndex];
|
||||||
|
|
||||||
|
checkRange( val );
|
||||||
|
app.SetShininess( val );
|
||||||
|
|
||||||
|
if( aIndex > (int)ambientColor.size() )
|
||||||
|
{
|
||||||
|
red = ambientColor[0].x;
|
||||||
|
green = ambientColor[0].y;
|
||||||
|
blue = ambientColor[0].z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
red = ambientColor[aIndex].x;
|
||||||
|
green = ambientColor[aIndex].y;
|
||||||
|
blue = ambientColor[aIndex].z;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRange( red );
|
||||||
|
checkRange( green );
|
||||||
|
checkRange( blue );
|
||||||
|
val = (red + green + blue)/3.0;
|
||||||
|
app.SetAmbient( val );
|
||||||
|
|
||||||
|
if( aIndex > (int)diffuseColor.size() )
|
||||||
|
{
|
||||||
|
red = diffuseColor[0].x;
|
||||||
|
green = diffuseColor[0].y;
|
||||||
|
blue = diffuseColor[0].z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
red = diffuseColor[aIndex].x;
|
||||||
|
green = diffuseColor[aIndex].y;
|
||||||
|
blue = diffuseColor[aIndex].z;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRange( red );
|
||||||
|
checkRange( green );
|
||||||
|
checkRange( blue );
|
||||||
|
app.SetDiffuse( red, green, blue );
|
||||||
|
|
||||||
|
if( aIndex > (int)emissiveColor.size() )
|
||||||
|
{
|
||||||
|
red = emissiveColor[0].x;
|
||||||
|
green = emissiveColor[0].y;
|
||||||
|
blue = emissiveColor[0].z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
red = emissiveColor[aIndex].x;
|
||||||
|
green = emissiveColor[aIndex].y;
|
||||||
|
blue = emissiveColor[aIndex].z;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRange( red );
|
||||||
|
checkRange( green );
|
||||||
|
checkRange( blue );
|
||||||
|
app.SetEmissive( red, green, blue );
|
||||||
|
|
||||||
|
if( aIndex > (int)specularColor.size() )
|
||||||
|
{
|
||||||
|
red = specularColor[0].x;
|
||||||
|
green = specularColor[0].y;
|
||||||
|
blue = specularColor[0].z;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
red = specularColor[aIndex].x;
|
||||||
|
green = specularColor[aIndex].y;
|
||||||
|
blue = specularColor[aIndex].z;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRange( red );
|
||||||
|
checkRange( green );
|
||||||
|
checkRange( blue );
|
||||||
|
app.SetSpecular( red, green, blue );
|
||||||
|
|
||||||
|
colors[aIndex] = app.GetRawPtr();
|
||||||
|
|
||||||
|
return colors[aIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WRL1MATERIAL::GetColor( SGCOLOR* aColor, int aIndex )
|
||||||
|
{
|
||||||
|
if( NULL == aColor )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Calculate the color based on the given index.
|
||||||
|
// If the index points to a valid diffuse and emissive colors,
|
||||||
|
// take the higher value of each component.
|
||||||
|
|
||||||
|
float red, blue, green;
|
||||||
|
float eRed, eBlue, eGreen;
|
||||||
|
|
||||||
|
if( aIndex <= 0 || ( aIndex >= (int)diffuseColor.size()
|
||||||
|
&& aIndex >= (int)emissiveColor.size() ) )
|
||||||
|
{
|
||||||
|
// If the index is out of bounds, use the default diffuse color.
|
||||||
|
red = diffuseColor[0].x;
|
||||||
|
green = diffuseColor[0].y;
|
||||||
|
blue = diffuseColor[0].z;
|
||||||
|
|
||||||
|
checkRange( red );
|
||||||
|
checkRange( green );
|
||||||
|
checkRange( blue );
|
||||||
|
|
||||||
|
aColor->SetColor( red, green, blue );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aIndex >= (int)diffuseColor.size() )
|
||||||
|
{
|
||||||
|
red = emissiveColor[aIndex].x;
|
||||||
|
green = emissiveColor[aIndex].y;
|
||||||
|
blue = emissiveColor[aIndex].z;
|
||||||
|
|
||||||
|
checkRange( red );
|
||||||
|
checkRange( green );
|
||||||
|
checkRange( blue );
|
||||||
|
|
||||||
|
aColor->SetColor( red, green, blue );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( aIndex >= (int)emissiveColor.size() )
|
||||||
|
{
|
||||||
|
red = diffuseColor[aIndex].x;
|
||||||
|
green = diffuseColor[aIndex].y;
|
||||||
|
blue = diffuseColor[aIndex].z;
|
||||||
|
|
||||||
|
checkRange( red );
|
||||||
|
checkRange( green );
|
||||||
|
checkRange( blue );
|
||||||
|
|
||||||
|
aColor->SetColor( red, green, blue );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
red = diffuseColor[aIndex].x;
|
||||||
|
green = diffuseColor[aIndex].y;
|
||||||
|
blue = diffuseColor[aIndex].z;
|
||||||
|
|
||||||
|
eRed = emissiveColor[aIndex].x;
|
||||||
|
eGreen = emissiveColor[aIndex].y;
|
||||||
|
eBlue = emissiveColor[aIndex].z;
|
||||||
|
|
||||||
|
checkRange( red );
|
||||||
|
checkRange( green );
|
||||||
|
checkRange( blue );
|
||||||
|
|
||||||
|
checkRange( eRed );
|
||||||
|
checkRange( eGreen );
|
||||||
|
checkRange( eBlue );
|
||||||
|
|
||||||
|
if( eRed > red )
|
||||||
|
red = eRed;
|
||||||
|
|
||||||
|
if( eGreen > green )
|
||||||
|
green = eGreen;
|
||||||
|
|
||||||
|
if( eBlue > blue )
|
||||||
|
blue = eBlue;
|
||||||
|
|
||||||
|
aColor->SetColor( red, green, blue );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WRL1MATERIAL::checkRange( float& aValue )
|
||||||
|
{
|
||||||
|
if( aValue < 0.0 )
|
||||||
|
aValue = 0.0;
|
||||||
|
else if( aValue > 1.0 )
|
||||||
|
aValue = 1.0;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
@ -30,10 +30,12 @@
|
||||||
#define VRML1_MATERIAL_H
|
#define VRML1_MATERIAL_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
#include "vrml1_node.h"
|
#include "vrml1_node.h"
|
||||||
|
|
||||||
class WRL1BASE;
|
class WRL1BASE;
|
||||||
class SGNODE;
|
class SGNODE;
|
||||||
|
struct SGCOLOR;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class WRL1MATERIAL
|
* Class WRL1MATERIAL
|
||||||
|
@ -48,7 +50,10 @@ private:
|
||||||
std::vector< float > shininess;
|
std::vector< float > shininess;
|
||||||
std::vector< float > transparency;
|
std::vector< float > transparency;
|
||||||
|
|
||||||
|
SGNODE* colors[2];
|
||||||
|
|
||||||
void setDefaults( void );
|
void setDefaults( void );
|
||||||
|
void checkRange( float& aValue );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WRL1MATERIAL( NAMEREGISTER* aDictionary );
|
WRL1MATERIAL( NAMEREGISTER* aDictionary );
|
||||||
|
@ -61,7 +66,18 @@ public:
|
||||||
bool AddChildNode( WRL1NODE* aNode );
|
bool AddChildNode( WRL1NODE* aNode );
|
||||||
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals );
|
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals );
|
||||||
|
|
||||||
// XXX - requires a function to create/retrieve a color
|
/**
|
||||||
|
* Function GetAppearance
|
||||||
|
* returns an SGAPPEARANCE node representing the appearance
|
||||||
|
* for an IndexedFaceSet
|
||||||
|
*/
|
||||||
|
SGNODE* GetAppearance( int aIndex );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetColor
|
||||||
|
* computes an SGCOLOR representing the appearance of a vertex or face
|
||||||
|
*/
|
||||||
|
void GetColor( SGCOLOR* aColor, int aIndex );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VRML1_MATERIAL_H
|
#endif // VRML1_MATERIAL_H
|
||||||
|
|
|
@ -286,6 +286,12 @@ WRL1NODES WRL1NODE::getNodeTypeID( const std::string aNodeName )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t WRL1NODE::GetNItems( void ) const
|
||||||
|
{
|
||||||
|
return m_Items.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string WRL1NODE::GetError( void )
|
std::string WRL1NODE::GetError( void )
|
||||||
{
|
{
|
||||||
return m_error;
|
return m_error;
|
||||||
|
|
|
@ -220,6 +220,8 @@ public:
|
||||||
|
|
||||||
const char* GetNodeTypeName( WRL1NODES aNodeType ) const;
|
const char* GetNodeTypeName( WRL1NODES aNodeType ) const;
|
||||||
|
|
||||||
|
size_t GetNItems( void ) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function FindNode searches the tree of linked nodes and returns a
|
* Function FindNode searches the tree of linked nodes and returns a
|
||||||
* reference to the current node with the given name. The reference
|
* reference to the current node with the given name. The reference
|
||||||
|
|
|
@ -140,20 +140,26 @@ SGNODE* WRL1SEPARATOR::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
std::cerr << m_Items.size() << " items)\n";
|
std::cerr << m_Items.size() << " items)\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NULL;
|
if( !m_Parent )
|
||||||
|
{
|
||||||
|
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||||
|
std::cerr << " * [BUG] Separator has no parent\n";
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
if( m_Children.empty() && m_Refs.empty() )
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( WRL1_BASE != m_Parent->GetNodeType() )
|
||||||
|
m_current = *( m_Parent->GetCurrentSettings() );
|
||||||
|
else
|
||||||
|
m_current.Init();
|
||||||
|
|
||||||
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
|
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
|
||||||
|
|
||||||
if( NULL != aParent && ptype != S3D::SGTYPE_TRANSFORM )
|
if( NULL != aParent && ptype != S3D::SGTYPE_TRANSFORM )
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_VRML1
|
#ifdef DEBUG_VRML2
|
||||||
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
|
||||||
std::cerr << " * [BUG] Separator does not have a Separator parent (parent ID: ";
|
std::cerr << " * [BUG] Separator does not have a Transform parent (parent ID: ";
|
||||||
std::cerr << ptype << ")\n";
|
std::cerr << ptype << ")\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -162,80 +168,38 @@ SGNODE* WRL1SEPARATOR::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
|
|
||||||
if( m_sgNode )
|
if( m_sgNode )
|
||||||
{
|
{
|
||||||
if( NULL != aParent )
|
if( NULL == aParent )
|
||||||
{
|
return NULL;
|
||||||
if( NULL == S3D::GetSGNodeParent( m_sgNode )
|
|
||||||
&& !S3D::AddSGNodeChild( aParent, m_sgNode ) )
|
if( !S3D::AddSGNodeRef( aParent, m_sgNode ) )
|
||||||
{
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
else if( aParent != S3D::GetSGNodeParent( m_sgNode )
|
|
||||||
&& !S3D::AddSGNodeRef( aParent, m_sgNode ) )
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_sgNode;
|
return m_sgNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
IFSG_TRANSFORM txNode( aParent );
|
IFSG_TRANSFORM txNode( aParent );
|
||||||
|
bool hasContent = false;
|
||||||
|
|
||||||
std::list< WRL1NODE* >::iterator sC = m_Children.begin();
|
std::list< WRL1NODE* >::iterator sI = m_Items.begin();
|
||||||
std::list< WRL1NODE* >::iterator eC = m_Children.end();
|
std::list< WRL1NODE* >::iterator eI = m_Items.end();
|
||||||
WRL1NODES type;
|
|
||||||
|
|
||||||
// Include only the following in a Separator node:
|
SGNODE* node = txNode.GetRawPtr();
|
||||||
// Shape
|
|
||||||
// Switch
|
|
||||||
// Separator
|
|
||||||
// Inline
|
|
||||||
bool test = false; // set to true if there are any subnodes for display
|
|
||||||
|
|
||||||
for( int i = 0; i < 2; ++i )
|
while( sI != eI )
|
||||||
{
|
{
|
||||||
while( sC != eC )
|
if( NULL != (*sI)->TranslateToSG( node, calcNormals ) )
|
||||||
{
|
hasContent = true;
|
||||||
type = (*sC)->GetNodeType();
|
|
||||||
|
|
||||||
switch( type )
|
++sI;
|
||||||
{
|
|
||||||
case WRL1_SHAPE:
|
|
||||||
case WRL1_SWITCH:
|
|
||||||
case WRL1_INLINE:
|
|
||||||
case WRL1_SEPARATOR:
|
|
||||||
|
|
||||||
if( NULL != (*sC)->TranslateToSG( txNode.GetRawPtr(), calcNormals ) )
|
|
||||||
test = true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
++ sC;
|
|
||||||
}
|
|
||||||
|
|
||||||
sC = m_Refs.begin();
|
|
||||||
eC = m_Refs.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( false == test )
|
if( !hasContent )
|
||||||
{
|
{
|
||||||
txNode.Destroy();
|
txNode.Destroy();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
txNode.SetScale( SGPOINT( scale.x, scale.y, scale.z ) );
|
m_sgNode = node;
|
||||||
txNode.SetCenter( SGPOINT( center.x, center.y, center.z ) );
|
|
||||||
txNode.SetTranslation( SGPOINT( translation.x, translation.y, translation.z ) );
|
|
||||||
txNode.SetScaleOrientation( SGVECTOR( scaleOrientation.x, scaleOrientation.y,
|
|
||||||
scaleOrientation.z ), scaleOrientation.w );
|
|
||||||
txNode.SetRotation( SGVECTOR( rotation.x, rotation.y, rotation.z), rotation.w );
|
|
||||||
|
|
||||||
m_sgNode = txNode.GetRawPtr();
|
return node;
|
||||||
|
|
||||||
return m_sgNode;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,8 @@ SGNODE* WRL1SWITCH::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
|
#if defined( DEBUG_VRML1 ) && ( DEBUG_VRML1 > 2 )
|
||||||
std::cerr << " * [INFO] Translating Switch with " << m_Children.size();
|
std::cerr << " * [INFO] Translating Switch with " << m_Children.size();
|
||||||
std::cerr << " children, " << m_Refs.size() << " references and ";
|
std::cerr << " children, " << m_Refs.size() << " references and ";
|
||||||
std::cerr << m_BackPointers.size() << " backpointers\n";
|
std::cerr << m_BackPointers.size() << " backpointers (total ";
|
||||||
|
std::cerr << m_Items.size() << " items)\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if( m_Items.empty() )
|
if( m_Items.empty() )
|
||||||
|
@ -201,7 +202,12 @@ SGNODE* WRL1SWITCH::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
std::list< WRL1NODE* >::iterator ip = m_Items.begin();
|
std::list< WRL1NODE* >::iterator ip = m_Items.begin();
|
||||||
std::advance( ip, whichChild );
|
std::advance( ip, whichChild );
|
||||||
|
|
||||||
m_current = *( m_Parent->GetCurrentSettings() );
|
IFSG_TRANSFORM txNode( aParent );
|
||||||
|
|
||||||
|
if( WRL1_BASE != m_Parent->GetNodeType() )
|
||||||
|
m_current = *( m_Parent->GetCurrentSettings() );
|
||||||
|
else
|
||||||
|
m_current.Init();
|
||||||
|
|
||||||
return (*ip)->TranslateToSG( aParent, calcNormals );
|
return (*ip)->TranslateToSG( aParent, calcNormals );
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,3 +194,30 @@ SGNODE* WRL2COLOR::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
// any data manipulation must be performed by the parent node
|
// any data manipulation must be performed by the parent node
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool WRL2COLOR::HasColors( void )
|
||||||
|
{
|
||||||
|
if( colors.empty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WRL2COLOR::GetColor( int aIndex, float& red, float& green, float& blue )
|
||||||
|
{
|
||||||
|
if( aIndex < 0 || aIndex >= colors.size() )
|
||||||
|
{
|
||||||
|
red = 0.8;
|
||||||
|
green = 0.8;
|
||||||
|
blue = 0.8;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
red = colors[aIndex].x;
|
||||||
|
green = colors[aIndex].x;
|
||||||
|
blue = colors[aIndex].x;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
|
@ -59,6 +59,18 @@ public:
|
||||||
bool AddRefNode( WRL2NODE* aNode );
|
bool AddRefNode( WRL2NODE* aNode );
|
||||||
bool AddChildNode( WRL2NODE* aNode );
|
bool AddChildNode( WRL2NODE* aNode );
|
||||||
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals );
|
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function HasColors
|
||||||
|
* returns true if the color set is non-empty
|
||||||
|
*/
|
||||||
|
bool HasColors( void );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetColor
|
||||||
|
* retrieves the given color (or default 0.8, 0.8, 0.8 if index is invalid)
|
||||||
|
*/
|
||||||
|
void GetColor( int aIndex, float& red, float& green, float& blue );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VRML2_COLOR_H
|
#endif // VRML2_COLOR_H
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "vrml2_base.h"
|
#include "vrml2_base.h"
|
||||||
#include "vrml2_faceset.h"
|
#include "vrml2_faceset.h"
|
||||||
#include "vrml2_coords.h"
|
#include "vrml2_coords.h"
|
||||||
|
#include "vrml2_color.h"
|
||||||
#include "plugins/3dapi/ifsg_all.h"
|
#include "plugins/3dapi/ifsg_all.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -632,44 +633,139 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
std::vector< int > lCIdx; // coordinate index list for SG node (must be triads)
|
std::vector< int > lCIdx; // coordinate index list for SG node (must be triads)
|
||||||
std::vector< SGVECTOR > lCNorm; // per-vertex normals
|
std::vector< SGVECTOR > lCNorm; // per-vertex normals
|
||||||
std::vector< int > faces; // tracks the number of polygons for the entire set
|
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
|
int nfaces = 0; // number of triangles for each face in the list
|
||||||
|
|
||||||
// assuming convex polygons, create triangles for the SG node
|
if( NULL == color )
|
||||||
for( idx = 3; idx < vsize; )
|
|
||||||
{
|
{
|
||||||
lCIdx.push_back( i1 );
|
// assuming convex polygons, create triangles for the SG node
|
||||||
|
for( idx = 3; idx < vsize; )
|
||||||
if( ccw )
|
|
||||||
{
|
{
|
||||||
lCIdx.push_back( i2 );
|
lCIdx.push_back( i1 );
|
||||||
lCIdx.push_back( i3 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lCIdx.push_back( i3 );
|
|
||||||
lCIdx.push_back( i2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
++nfaces;
|
if( ccw )
|
||||||
i2 = i3;
|
|
||||||
i3 = coordIndex[idx++];
|
|
||||||
|
|
||||||
while( ( i1 < 0 || i2 < 0 || i3 < 0 ) && ( idx < vsize ) )
|
|
||||||
{
|
|
||||||
if( i3 < 0 )
|
|
||||||
{
|
{
|
||||||
faces.push_back( nfaces );
|
lCIdx.push_back( i2 );
|
||||||
nfaces = 0;
|
lCIdx.push_back( i3 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lCIdx.push_back( i3 );
|
||||||
|
lCIdx.push_back( i2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
i1 = i2;
|
++nfaces;
|
||||||
i2 = i3;
|
i2 = i3;
|
||||||
i3 = coordIndex[idx++];
|
i3 = coordIndex[idx++];
|
||||||
|
|
||||||
// any invalid polygons shall void the entire faceset; this is a requirement
|
while( ( i1 < 0 || i2 < 0 || i3 < 0 ) && ( idx < vsize ) )
|
||||||
// to ensure correct handling of the normals
|
{
|
||||||
if( ( i1 < 0 && i2 < 0 ) || ( i1 < 0 && i3 < 0 ) || ( i2 < 0 && i3 < 0 ) )
|
if( i3 < 0 )
|
||||||
return NULL;
|
{
|
||||||
|
faces.push_back( nfaces );
|
||||||
|
nfaces = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int cIndex;
|
||||||
|
WRL2COLOR* cn = (WRL2COLOR*) color;
|
||||||
|
SGCOLOR pc1, pc2, pc3;
|
||||||
|
WRLVEC3F tc;
|
||||||
|
cn->GetColor( 0, tc.x, tc.y, tc.z );
|
||||||
|
pc1.SetColor( tc.x, tc.y, tc.z );
|
||||||
|
|
||||||
|
|
||||||
|
if( colorPerVertex )
|
||||||
|
{
|
||||||
|
cIndex = 3;
|
||||||
|
cn->GetColor( 1, tc.x, tc.y, tc.z );
|
||||||
|
pc2.SetColor( tc.x, tc.y, tc.z );
|
||||||
|
cn->GetColor( 2, tc.x, tc.y, tc.z );
|
||||||
|
pc3.SetColor( tc.x, tc.y, tc.z );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cIndex = 1;
|
||||||
|
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
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
++nfaces;
|
||||||
|
i2 = i3;
|
||||||
|
i3 = coordIndex[idx++];
|
||||||
|
|
||||||
|
if( colorPerVertex && i1 >= 0 && i2 >= 0 && i3 >= 0 )
|
||||||
|
{
|
||||||
|
pc1.SetColor( pc2 );
|
||||||
|
pc2.SetColor( pc3 );
|
||||||
|
cn->GetColor( cIndex++, tc.x, tc.y, tc.z );
|
||||||
|
pc3.SetColor( tc.x, tc.y, tc.z );
|
||||||
|
}
|
||||||
|
|
||||||
|
while( ( i1 < 0 || i2 < 0 || i3 < 0 ) && ( idx < vsize ) )
|
||||||
|
{
|
||||||
|
if( i3 < 0 )
|
||||||
|
{
|
||||||
|
faces.push_back( nfaces );
|
||||||
|
nfaces = 0;
|
||||||
|
|
||||||
|
if( !colorPerVertex )
|
||||||
|
{
|
||||||
|
cn->GetColor( 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;
|
||||||
|
i3 = coordIndex[idx++];
|
||||||
|
|
||||||
|
if( colorPerVertex )
|
||||||
|
{
|
||||||
|
pc1.SetColor( pc2 );
|
||||||
|
pc2.SetColor( pc3 );
|
||||||
|
cn->GetColor( cIndex++, tc.x, tc.y, tc.z );
|
||||||
|
pc3.SetColor( tc.x, tc.y, tc.z );
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,6 +851,12 @@ SGNODE* WRL2FACESET::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
IFSG_NORMALS nmNode( fsNode );
|
IFSG_NORMALS nmNode( fsNode );
|
||||||
nmNode.SetNormalList( lCNorm.size(), &lCNorm[0] );
|
nmNode.SetNormalList( lCNorm.size(), &lCNorm[0] );
|
||||||
|
|
||||||
|
if( !lColors.empty() )
|
||||||
|
{
|
||||||
|
IFSG_COLORS nmColor( fsNode );
|
||||||
|
nmColor.SetColorList( lColors.size(), &lColors[0] );
|
||||||
|
}
|
||||||
|
|
||||||
m_sgNode = fsNode.GetRawPtr();
|
m_sgNode = fsNode.GetRawPtr();
|
||||||
|
|
||||||
return m_sgNode;
|
return m_sgNode;
|
||||||
|
@ -805,3 +907,12 @@ void WRL2FACESET::unlinkRefNode( const WRL2NODE* aNode )
|
||||||
WRL2NODE::unlinkRefNode( aNode );
|
WRL2NODE::unlinkRefNode( aNode );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool WRL2FACESET::HasColors( void )
|
||||||
|
{
|
||||||
|
if( NULL == color )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return ((WRL2COLOR*) color)->HasColors();
|
||||||
|
}
|
||||||
|
|
|
@ -88,6 +88,12 @@ public:
|
||||||
bool AddRefNode( WRL2NODE* aNode );
|
bool AddRefNode( WRL2NODE* aNode );
|
||||||
bool AddChildNode( WRL2NODE* aNode );
|
bool AddChildNode( WRL2NODE* aNode );
|
||||||
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals );
|
SGNODE* TranslateToSG( SGNODE* aParent, bool calcNormals );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function HasColors
|
||||||
|
* returns true if the face set has a color node
|
||||||
|
*/
|
||||||
|
bool HasColors( void );
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VRML2_FACESET_H
|
#endif // VRML2_FACESET_H
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "vrml2_base.h"
|
#include "vrml2_base.h"
|
||||||
#include "vrml2_shape.h"
|
#include "vrml2_shape.h"
|
||||||
#include "plugins/3dapi/ifsg_all.h"
|
#include "plugins/3dapi/ifsg_all.h"
|
||||||
|
#include "vrml2_faceset.h"
|
||||||
|
|
||||||
|
|
||||||
WRL2SHAPE::WRL2SHAPE() : WRL2NODE()
|
WRL2SHAPE::WRL2SHAPE() : WRL2NODE()
|
||||||
|
@ -318,9 +319,20 @@ bool WRL2SHAPE::Read( WRLPROC& proc, WRL2BASE* aTopNode )
|
||||||
|
|
||||||
SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
{
|
{
|
||||||
if( NULL == appearance || NULL == geometry )
|
// XXX - TO BE IMPLEMENTED:
|
||||||
|
if( NULL == geometry )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// if there is no appearance, make use of the per vertex colors if available
|
||||||
|
if( NULL == appearance )
|
||||||
|
{
|
||||||
|
if( WRL2_INDEXEDFACESET != geometry->GetNodeType() )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if( !((WRL2FACESET*)geometry)->HasColors() )
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
|
S3D::SGTYPES ptype = S3D::GetSGNodeType( aParent );
|
||||||
|
|
||||||
if( NULL != aParent && ptype != S3D::SGTYPE_TRANSFORM )
|
if( NULL != aParent && ptype != S3D::SGTYPE_TRANSFORM )
|
||||||
|
@ -356,10 +368,13 @@ SGNODE* WRL2SHAPE::TranslateToSG( SGNODE* aParent, bool calcNormals )
|
||||||
IFSG_SHAPE shNode( aParent );
|
IFSG_SHAPE shNode( aParent );
|
||||||
|
|
||||||
SGNODE* pShape = shNode.GetRawPtr();
|
SGNODE* pShape = shNode.GetRawPtr();
|
||||||
SGNODE* pApp = appearance->TranslateToSG( pShape, calcNormals );
|
|
||||||
SGNODE* pGeom = geometry->TranslateToSG( pShape, calcNormals );
|
SGNODE* pGeom = geometry->TranslateToSG( pShape, calcNormals );
|
||||||
|
SGNODE* pApp = NULL;
|
||||||
|
|
||||||
if( NULL == pApp || NULL == pGeom )
|
if( NULL != appearance )
|
||||||
|
pApp = appearance->TranslateToSG( pShape, calcNormals );
|
||||||
|
|
||||||
|
if( ( NULL != appearance && NULL == pApp ) || NULL == pGeom )
|
||||||
{
|
{
|
||||||
if( pGeom )
|
if( pGeom )
|
||||||
{
|
{
|
||||||
|
|
|
@ -87,14 +87,15 @@ enum WRL1NODES
|
||||||
};
|
};
|
||||||
|
|
||||||
// VRML1 Material/Normal Binding values
|
// VRML1 Material/Normal Binding values
|
||||||
|
// note: PART/FACE have the same meaning in the specification
|
||||||
enum WRL1_BINDING
|
enum WRL1_BINDING
|
||||||
{
|
{
|
||||||
BIND_DEFAULT = 0,
|
BIND_DEFAULT = 0,
|
||||||
BIND_OVERALL,
|
BIND_OVERALL,
|
||||||
BIND_PER_PART,
|
BIND_PER_PART,
|
||||||
|
BIND_PER_FACE = BIND_PER_PART,
|
||||||
BIND_PER_PART_INDEXED,
|
BIND_PER_PART_INDEXED,
|
||||||
BIND_PER_FACE,
|
BIND_PER_FACE_INDEXED = BIND_PER_PART_INDEXED,
|
||||||
BIND_PER_FACE_INDEXED,
|
|
||||||
BIND_PER_VERTEX,
|
BIND_PER_VERTEX,
|
||||||
BIND_PER_VERTEX_INDEXED,
|
BIND_PER_VERTEX_INDEXED,
|
||||||
BIND_END
|
BIND_END
|
||||||
|
|
Loading…
Reference in New Issue