Improved VRML1 support, including relaxed rules to support poorly structured models
This commit is contained in:
parent
ec9acfd410
commit
39ca807ac4
|
@ -287,7 +287,9 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, WRL1STATUS* sp )
|
|||
std::vector< SGCOLOR > colorlist;
|
||||
SGNODE* sgcolor = NULL;
|
||||
|
||||
switch( m_current.matbind )
|
||||
WRL1_BINDING mbind = m_current.matbind;
|
||||
|
||||
switch( mbind )
|
||||
{
|
||||
case BIND_PER_FACE:
|
||||
case BIND_PER_VERTEX:
|
||||
|
@ -301,7 +303,9 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, WRL1STATUS* sp )
|
|||
std::cerr << " * [INFO] bad model: per face indexed but no indices\n";
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
// support bad models by temporarily switching bindings
|
||||
mbind = BIND_OVERALL;
|
||||
sgcolor = m_current.mat->GetAppearance( 0 );
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -315,7 +319,9 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, WRL1STATUS* sp )
|
|||
std::cerr << matIndex.size() << "\n";
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
// support bad models by temporarily switching bindings
|
||||
mbind = BIND_OVERALL;
|
||||
sgcolor = m_current.mat->GetAppearance( 0 );
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -371,7 +377,7 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, WRL1STATUS* sp )
|
|||
std::vector< SGCOLOR > lColors; // colors points (if any) for SG node
|
||||
int nfaces = 0; // number of triangles for each face in the list
|
||||
|
||||
if( BIND_OVERALL == m_current.matbind || BIND_DEFAULT == m_current.matbind )
|
||||
if( BIND_OVERALL == mbind || BIND_DEFAULT == mbind )
|
||||
{
|
||||
// no color list
|
||||
// assuming convex polygons, create triangles for the SG node
|
||||
|
@ -445,7 +451,7 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, WRL1STATUS* sp )
|
|||
int cIndex;
|
||||
SGCOLOR pc1, pc2, pc3;
|
||||
|
||||
switch( m_current.matbind )
|
||||
switch( mbind )
|
||||
{
|
||||
case BIND_PER_VERTEX:
|
||||
cIndex = 3;
|
||||
|
@ -493,8 +499,8 @@ SGNODE* WRL1FACESET::TranslateToSG( SGNODE* aParent, WRL1STATUS* sp )
|
|||
|
||||
bool colorPerVertex = false;
|
||||
|
||||
if( BIND_PER_VERTEX == m_current.matbind
|
||||
|| BIND_PER_VERTEX_INDEXED == m_current.matbind )
|
||||
if( BIND_PER_VERTEX == mbind
|
||||
|| BIND_PER_VERTEX_INDEXED == mbind )
|
||||
colorPerVertex = true;
|
||||
|
||||
bool noidx = false;
|
||||
|
|
|
@ -417,77 +417,166 @@ 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.
|
||||
// Calculate the color based on the given index using the formula:
|
||||
// color = ( emission + ambient + diffuse + shininess * specular ) / N
|
||||
// where N = number of non-zero components or 1 (if all zero)
|
||||
// If the index exceeds the number of items in a list, use the FIRST
|
||||
// item rather than the default; this behavior caters to some bad
|
||||
// models.
|
||||
|
||||
float red, blue, green;
|
||||
WRLVEC3F rgb;
|
||||
float dRed, dBlue, dGreen;
|
||||
float eRed, eBlue, eGreen;
|
||||
float aRed, aBlue, aGreen;
|
||||
float sRed, sBlue, sGreen;
|
||||
float shiny;
|
||||
|
||||
if( aIndex < 0 || ( aIndex >= (int)diffuseColor.size()
|
||||
&& aIndex >= (int)emissiveColor.size() ) )
|
||||
if( aIndex < 0 || ( aIndex >= (int)diffuseColor.size() ) )
|
||||
{
|
||||
// If the index is out of bounds, use the default diffuse color.
|
||||
red = 0.8;
|
||||
green = 0.8;
|
||||
blue = 0.8;
|
||||
aColor->SetColor( red, green, blue );
|
||||
return;
|
||||
if( !diffuseColor.empty() )
|
||||
{
|
||||
rgb = diffuseColor.front();
|
||||
dRed = rgb.x;
|
||||
dGreen = rgb.y;
|
||||
dBlue = rgb.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
dRed = 0.8;
|
||||
dGreen = 0.8;
|
||||
dBlue = 0.8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rgb = diffuseColor[aIndex];
|
||||
dRed = rgb.x;
|
||||
dGreen = rgb.y;
|
||||
dBlue = rgb.z;
|
||||
}
|
||||
|
||||
if( aIndex >= (int)diffuseColor.size() )
|
||||
if( aIndex < 0 || ( aIndex >= (int)emissiveColor.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( !emissiveColor.empty() )
|
||||
{
|
||||
rgb = emissiveColor.front();
|
||||
eRed = rgb.x;
|
||||
eGreen = rgb.y;
|
||||
eBlue = rgb.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
eRed = 0.0;
|
||||
eGreen = 0.0;
|
||||
eBlue = 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rgb = emissiveColor[aIndex];
|
||||
eRed = rgb.x;
|
||||
eGreen = rgb.y;
|
||||
eBlue = rgb.z;
|
||||
}
|
||||
|
||||
if( aIndex >= (int)emissiveColor.size() )
|
||||
if( aIndex < 0 || ( aIndex >= (int)ambientColor.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;
|
||||
if( !ambientColor.empty() )
|
||||
{
|
||||
rgb = ambientColor.front();
|
||||
aRed = rgb.x;
|
||||
aGreen = rgb.y;
|
||||
aBlue = rgb.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
aRed = 0.2;
|
||||
aGreen = 0.2;
|
||||
aBlue = 0.2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rgb = ambientColor[aIndex];
|
||||
aRed = rgb.x;
|
||||
aGreen = rgb.y;
|
||||
aBlue = rgb.z;
|
||||
}
|
||||
|
||||
red = diffuseColor[aIndex].x;
|
||||
green = diffuseColor[aIndex].y;
|
||||
blue = diffuseColor[aIndex].z;
|
||||
if( aIndex < 0 || ( aIndex >= (int)specularColor.size() ) )
|
||||
{
|
||||
if( !specularColor.empty() )
|
||||
{
|
||||
rgb = specularColor.front();
|
||||
sRed = rgb.x;
|
||||
sGreen = rgb.y;
|
||||
sBlue = rgb.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
sRed = 0.2;
|
||||
sGreen = 0.2;
|
||||
sBlue = 0.2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rgb = specularColor[aIndex];
|
||||
sRed = rgb.x;
|
||||
sGreen = rgb.y;
|
||||
sBlue = rgb.z;
|
||||
}
|
||||
|
||||
eRed = emissiveColor[aIndex].x;
|
||||
eGreen = emissiveColor[aIndex].y;
|
||||
eBlue = emissiveColor[aIndex].z;
|
||||
|
||||
checkRange( red );
|
||||
checkRange( green );
|
||||
checkRange( blue );
|
||||
if( aIndex < 0 || ( aIndex >= (int)shininess.size() ) )
|
||||
{
|
||||
if( !shininess.empty() )
|
||||
shiny = shininess.front();
|
||||
else
|
||||
shiny = 0.2;
|
||||
}
|
||||
else
|
||||
{
|
||||
shiny = shininess[aIndex];
|
||||
}
|
||||
|
||||
checkRange( aRed );
|
||||
checkRange( aGreen );
|
||||
checkRange( aBlue );
|
||||
checkRange( eRed );
|
||||
checkRange( eGreen );
|
||||
checkRange( eBlue );
|
||||
checkRange( dRed );
|
||||
checkRange( dGreen );
|
||||
checkRange( dBlue );
|
||||
checkRange( sRed );
|
||||
checkRange( sGreen );
|
||||
checkRange( sBlue );
|
||||
|
||||
if( eRed > red )
|
||||
red = eRed;
|
||||
int n = 0;
|
||||
|
||||
if( eGreen > green )
|
||||
green = eGreen;
|
||||
if( aRed + aGreen + aBlue > 0.01 )
|
||||
++n;
|
||||
|
||||
if( eBlue > blue )
|
||||
blue = eBlue;
|
||||
if( eRed + eGreen + eBlue > 0.01 )
|
||||
++n;
|
||||
|
||||
if( dRed + dGreen + dBlue > 0.01 )
|
||||
++n;
|
||||
|
||||
if( (sRed + sGreen + sBlue) * shiny > 0.01 )
|
||||
++n;
|
||||
|
||||
if( 0 == n )
|
||||
++n;
|
||||
|
||||
float red, green, blue;
|
||||
|
||||
red = (eRed + aRed + dRed + sRed * shiny) / n;
|
||||
green = (eGreen + aGreen + dGreen + sGreen * shiny) / n;
|
||||
blue = (eBlue + aBlue + dBlue + sBlue * shiny) / n;
|
||||
checkRange( red );
|
||||
checkRange( green );
|
||||
checkRange( blue );
|
||||
aColor->SetColor( red, green, blue );
|
||||
|
||||
return;
|
||||
|
|
Loading…
Reference in New Issue