Refactored the texture setup to streamline it and make it easier to adapt

This commit is contained in:
Robert Osfield 2018-03-10 17:51:52 +00:00
parent 9010fd8035
commit 125263f216
3 changed files with 158 additions and 337 deletions

View File

@ -1,9 +1,37 @@
#include "fbxMaterialToOsgStateSet.h" #include "fbxMaterialToOsgStateSet.h"
#include <sstream> #include <sstream>
#include <osg/TexMat>
#include <osgDB/ReadFile> #include <osgDB/ReadFile>
#include <osgDB/FileUtils> #include <osgDB/FileUtils>
#include <osgDB/FileNameUtils> #include <osgDB/FileNameUtils>
TextureDetails::TextureDetails():
factor(1.0),
scale(1.0, 1.0)
{
}
bool TextureDetails::transparent() const
{
const osg::Image* image = texture.valid() ? texture->getImage() : 0;
return image!=0 ? image->isImageTranslucent() : false;
}
void TextureDetails::assignTextureIfRequired(osg::StateSet* stateSet, unsigned int unit)
{
if (!texture) return;
stateSet->setTextureAttributeAndModes(unit, texture.get());
}
void TextureDetails::assignTexMatIfRequired(osg::StateSet* stateSet, unsigned int unit)
{
if (scale.x() != 1.0 || scale.y() != 1.0)
{
// set UV scaling...
stateSet->setTextureAttributeAndModes(unit, new osg::TexMat(osg::Matrix::scale(scale.x(), scale.y(), 1.0)), osg::StateAttribute::ON);
}
}
static osg::Texture::WrapMode convertWrap(FbxFileTexture::EWrapMode wrap) static osg::Texture::WrapMode convertWrap(FbxFileTexture::EWrapMode wrap)
{ {
@ -11,8 +39,7 @@ static osg::Texture::WrapMode convertWrap(FbxFileTexture::EWrapMode wrap)
osg::Texture2D::REPEAT : osg::Texture2D::CLAMP_TO_EDGE; osg::Texture2D::REPEAT : osg::Texture2D::CLAMP_TO_EDGE;
} }
StateSetContent StateSetContent FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
{ {
FbxMaterialMap::const_iterator it = _fbxMaterialMap.find(pFbxMat); FbxMaterialMap::const_iterator it = _fbxMaterialMap.find(pFbxMat);
if (it != _fbxMaterialMap.end()) if (it != _fbxMaterialMap.end())
@ -30,30 +57,12 @@ FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
const FbxSurfaceLambert* pFbxLambert = FbxCast<FbxSurfaceLambert>(pFbxMat); const FbxSurfaceLambert* pFbxLambert = FbxCast<FbxSurfaceLambert>(pFbxMat);
// diffuse map... // diffuse map...
const FbxProperty lProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sDiffuse); result.diffuse = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sDiffuse));
if (lProperty.IsValid())
{
int lNbTex = lProperty.GetSrcObjectCount<FbxFileTexture>();
for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
{
FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
if (lTexture)
{
result.diffuseTexture = fbxTextureToOsgTexture(lTexture);
result.diffuseChannel = lTexture->UVSet.Get();
result.diffuseScaleU = lTexture->GetScaleU();
result.diffuseScaleV = lTexture->GetScaleV();
}
//For now only allow 1 texture
break;
}
}
// opacity map...
double transparencyColorFactor = 1.0; double transparencyColorFactor = 1.0;
bool useTransparencyColorFactor = false; bool useTransparencyColorFactor = false;
// opacity map...
const FbxProperty lOpacityProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sTransparentColor); const FbxProperty lOpacityProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sTransparentColor);
if (lOpacityProperty.IsValid()) if (lOpacityProperty.IsValid())
{ {
@ -64,152 +73,27 @@ FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
useTransparencyColorFactor = true; useTransparencyColorFactor = true;
} }
int lNbTex = lOpacityProperty.GetSrcObjectCount<FbxFileTexture>(); result.opacity = selectTextureDetails(lOpacityProperty);
for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
{
FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lOpacityProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
if (lTexture)
{
// TODO: if texture image does NOT have an alpha channel, should it be added?
result.opacityTexture = fbxTextureToOsgTexture(lTexture);
result.opacityChannel = lTexture->UVSet.Get();
result.opacityScaleU = lTexture->GetScaleU();
result.opacityScaleV = lTexture->GetScaleV();
}
//For now only allow 1 texture
break;
}
} }
// reflection map... // reflection map...
const FbxProperty lReflectionProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sReflection); result.reflection = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sReflection));
if (lReflectionProperty.IsValid())
{
int lNbTex = lReflectionProperty.GetSrcObjectCount<FbxFileTexture>();
for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
{
FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lReflectionProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
if (lTexture)
{
// support only spherical reflection maps...
if (FbxFileTexture::eUMT_ENVIRONMENT == lTexture->CurrentMappingType.Get())
{
result.reflectionTexture = fbxTextureToOsgTexture(lTexture);
result.reflectionChannel = lTexture->UVSet.Get();
}
}
//For now only allow 1 texture
break;
}
}
// emissive map... // emissive map...
const FbxProperty lEmissiveProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sEmissive); result.emissive = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sEmissive));
if (lEmissiveProperty.IsValid())
{
int lNbTex = lEmissiveProperty.GetSrcObjectCount<FbxFileTexture>();
for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
{
FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lEmissiveProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
if (lTexture)
{
result.emissiveTexture = fbxTextureToOsgTexture(lTexture);
result.emissiveChannel = lTexture->UVSet.Get();
result.emissiveScaleU = lTexture->GetScaleU();
result.emissiveScaleV = lTexture->GetScaleV();
}
//For now only allow 1 texture
break;
}
}
// ambient map... // ambient map...
const FbxProperty lAmbientProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sAmbient); result.ambient = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sAmbient));
if (lAmbientProperty.IsValid())
{
int lNbTex = lAmbientProperty.GetSrcObjectCount<FbxFileTexture>();
for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
{
FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lAmbientProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
if (lTexture)
{
result.ambientTexture = fbxTextureToOsgTexture(lTexture);
result.ambientChannel = lTexture->UVSet.Get();
result.ambientScaleU = lTexture->GetScaleU();
result.ambientScaleV = lTexture->GetScaleV();
}
//For now only allow 1 texture
break;
}
}
// normal map... // normal map...
const FbxProperty lNormalProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sNormalMap); result.normalMap = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sNormalMap));
if (lNormalProperty.IsValid())
{
int lNbTex = lNormalProperty.GetSrcObjectCount<FbxFileTexture>();
for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
{
FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lNormalProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
if (lTexture)
{
result.normalTexture = fbxTextureToOsgTexture(lTexture);
result.normalChannel = lTexture->UVSet.Get();
result.normalScaleU = lTexture->GetScaleU();
result.normalScaleV = lTexture->GetScaleV();
}
//For now only allow 1 texture
break;
}
}
// specular map... // specular map...
const FbxProperty lSpecularProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sSpecular); result.specular = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sSpecular));
if (lSpecularProperty.IsValid())
{
int lNbTex = lSpecularProperty.GetSrcObjectCount<FbxFileTexture>();
for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
{
FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lSpecularProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
if (lTexture)
{
result.specularTexture = fbxTextureToOsgTexture(lTexture);
result.specularChannel = lTexture->UVSet.Get();
result.specularScaleU = lTexture->GetScaleU();
result.specularScaleV = lTexture->GetScaleV();
}
//For now only allow 1 texture
break;
}
}
// shininess map... // shininess map...
const FbxProperty lShininessProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sShininess); result.shininess = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sShininess));
if (lShininessProperty.IsValid())
{
int lNbTex = lShininessProperty.GetSrcObjectCount<FbxFileTexture>();
for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
{
FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lShininessProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
if (lTexture)
{
result.shininessTexture = fbxTextureToOsgTexture(lTexture);
result.shininessChannel = lTexture->UVSet.Get();
result.shininessScaleU = lTexture->GetScaleU();
result.shininessScaleV = lTexture->GetScaleV();
}
//For now only allow 1 texture
break;
}
}
if (pFbxLambert) if (pFbxLambert)
{ {
@ -239,10 +123,10 @@ FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
1.0f)); 1.0f));
// get maps factors... // get maps factors...
result.diffuseFactor = pFbxLambert->DiffuseFactor.Get(); if (result.diffuse.valid()) result.diffuse->factor = pFbxLambert->DiffuseFactor.Get();
result.emissiveFactor = pFbxLambert->EmissiveFactor.Get(); if (result.emissive.valid()) result.emissive->factor = pFbxLambert->EmissiveFactor.Get();
result.ambientFactor = pFbxLambert->AmbientFactor.Get(); if (result.ambient.valid()) result.ambient->factor = pFbxLambert->AmbientFactor.Get();
result.normalFactor = pFbxLambert->BumpFactor.Get(); if (result.normalMap.valid()) result.normalMap->factor = pFbxLambert->BumpFactor.Get();
if (const FbxSurfacePhong* pFbxPhong = FbxCast<FbxSurfacePhong>(pFbxLambert)) if (const FbxSurfacePhong* pFbxPhong = FbxCast<FbxSurfacePhong>(pFbxLambert))
{ {
@ -261,8 +145,8 @@ FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
static_cast<float>(shininess)); static_cast<float>(shininess));
// get maps factors... // get maps factors...
result.reflectionFactor = pFbxPhong->ReflectionFactor.Get(); if (result.reflection.valid()) result.reflection->factor = pFbxPhong->ReflectionFactor.Get();
result.specularFactor = pFbxPhong->SpecularFactor.Get(); if (result.specular.valid()) result.specular->factor = pFbxPhong->SpecularFactor.Get();
// get more factors here... // get more factors here...
} }
} }
@ -270,7 +154,7 @@ FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
if (_lightmapTextures) if (_lightmapTextures)
{ {
// if using an emission map then adjust material properties accordingly... // if using an emission map then adjust material properties accordingly...
if (result.emissiveTexture) if (result.emissive.valid())
{ {
osg::Vec4 diffuse = pOsgMat->getDiffuse(osg::Material::FRONT_AND_BACK); osg::Vec4 diffuse = pOsgMat->getDiffuse(osg::Material::FRONT_AND_BACK);
pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, diffuse); pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, diffuse);
@ -283,8 +167,7 @@ FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
return result; return result;
} }
osg::ref_ptr<osg::Texture2D> osg::ref_ptr<osg::Texture2D> FbxMaterialToOsgStateSet::fbxTextureToOsgTexture(const FbxFileTexture* fbx)
FbxMaterialToOsgStateSet::fbxTextureToOsgTexture(const FbxFileTexture* fbx)
{ {
ImageMap::iterator it = _imageMap.find(fbx->GetFileName()); ImageMap::iterator it = _imageMap.find(fbx->GetFileName());
if (it != _imageMap.end()) if (it != _imageMap.end())
@ -310,6 +193,38 @@ FbxMaterialToOsgStateSet::fbxTextureToOsgTexture(const FbxFileTexture* fbx)
} }
} }
FbxFileTexture* FbxMaterialToOsgStateSet::selectFbxFileTexture(const FbxProperty& lProperty)
{
if (lProperty.IsValid())
{
int lNbTex = lProperty.GetSrcObjectCount<FbxFileTexture>();
for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
{
FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
if (lTexture) return lTexture;
}
}
return 0;
}
TextureDetails* FbxMaterialToOsgStateSet::selectTextureDetails(const FbxProperty& lProperty)
{
if (lProperty.IsValid())
{
FbxFileTexture* fileTexture = selectFbxFileTexture(lProperty);
if (fileTexture)
{
TextureDetails* textureDetails = new TextureDetails();
textureDetails->texture = fbxTextureToOsgTexture(fileTexture);
textureDetails->channel = fileTexture->UVSet.Get();
textureDetails->scale.set(fileTexture->GetScaleU(), fileTexture->GetScaleV());
return textureDetails;
}
}
return 0;
}
void FbxMaterialToOsgStateSet::checkInvertTransparency() void FbxMaterialToOsgStateSet::checkInvertTransparency()
{ {
int zeroAlpha = 0, oneAlpha = 0; int zeroAlpha = 0, oneAlpha = 0;

View File

@ -17,66 +17,29 @@
//The only things we need to create a new StateSet are texture and materials. So we store that in a pair. //The only things we need to create a new StateSet are texture and materials. So we store that in a pair.
//We Don't store directly in stateSet because getOrCreateStateSet function set some parameters. //We Don't store directly in stateSet because getOrCreateStateSet function set some parameters.
struct TextureDetails : public osg::Referenced
{
TextureDetails();
bool valid() const { return texture.valid(); }
bool transparent() const;
void assignTextureIfRequired(osg::StateSet* stateSet, unsigned int unit);
void assignTexMatIfRequired(osg::StateSet* stateSet, unsigned int unit);
std::string channel;
osg::ref_ptr<osg::Texture2D> texture;
double factor;
osg::Vec2d scale;
};
struct StateSetContent struct StateSetContent
{ {
StateSetContent() StateSetContent()
: diffuseFactor(1.0),
reflectionFactor(1.0),
emissiveFactor(1.0),
ambientFactor(1.0),
normalFactor(1.0),
specularFactor(1.0)
{ {
} }
osg::ref_ptr<osg::Material> material;
// textures objects...
osg::ref_ptr<osg::Texture2D> diffuseTexture;
osg::ref_ptr<osg::Texture2D> opacityTexture;
osg::ref_ptr<osg::Texture2D> reflectionTexture;
osg::ref_ptr<osg::Texture2D> emissiveTexture;
osg::ref_ptr<osg::Texture2D> ambientTexture;
osg::ref_ptr<osg::Texture2D> normalTexture;
osg::ref_ptr<osg::Texture2D> specularTexture;
osg::ref_ptr<osg::Texture2D> shininessTexture;
// more textures types here...
// textures maps channels names...
std::string diffuseChannel;
std::string opacityChannel;
std::string reflectionChannel;
std::string emissiveChannel;
std::string ambientChannel;
std::string normalChannel;
std::string specularChannel;
std::string shininessChannel;
// more channels names here...
// combining factors...
double diffuseFactor;
double reflectionFactor;
double emissiveFactor;
double ambientFactor;
double normalFactor;
double specularFactor;
// more combining factors here...
double diffuseScaleU;
double diffuseScaleV;
double opacityScaleU;
double opacityScaleV;
double emissiveScaleU;
double emissiveScaleV;
double ambientScaleU;
double ambientScaleV;
double normalScaleU;
double normalScaleV;
double specularScaleU;
double specularScaleV;
double shininessScaleU;
double shininessScaleV;
// texture units (eventually used for each texture map)... // texture units (eventually used for each texture map)...
enum TextureUnit enum TextureUnit
{ {
@ -90,6 +53,19 @@ struct StateSetContent
SHININESS_TEXTURE_UNIT SHININESS_TEXTURE_UNIT
// more texture units here... // more texture units here...
}; };
osg::ref_ptr<osg::Material> material;
osg::ref_ptr<TextureDetails> diffuse;
osg::ref_ptr<TextureDetails> opacity;
osg::ref_ptr<TextureDetails> reflection;
osg::ref_ptr<TextureDetails> emissive;
osg::ref_ptr<TextureDetails> ambient;
osg::ref_ptr<TextureDetails> normalMap;
osg::ref_ptr<TextureDetails> specular;
osg::ref_ptr<TextureDetails> shininess;
}; };
//We use the pointers set by the importer to not duplicate materials and textures. //We use the pointers set by the importer to not duplicate materials and textures.
@ -111,10 +87,15 @@ public:
_lightmapTextures(lightmapTextures){} _lightmapTextures(lightmapTextures){}
void checkInvertTransparency(); void checkInvertTransparency();
private: private:
//Convert a texture fbx to an osg texture. //Convert a texture fbx to an osg texture.
osg::ref_ptr<osg::Texture2D> osg::ref_ptr<osg::Texture2D> fbxTextureToOsgTexture(const FbxFileTexture* pOsgTex);
fbxTextureToOsgTexture(const FbxFileTexture* pOsgTex);
FbxFileTexture* selectFbxFileTexture(const FbxProperty& lProperty);
TextureDetails* selectTextureDetails(const FbxProperty& lProperty);
FbxMaterialMap _fbxMaterialMap; FbxMaterialMap _fbxMaterialMap;
ImageMap _imageMap; ImageMap _imageMap;
const osgDB::Options* _options; const osgDB::Options* _options;

View File

@ -218,24 +218,14 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap,
transparent = pMaterial->getDiffuse(osg::Material::FRONT).w() < 1.0f; transparent = pMaterial->getDiffuse(osg::Material::FRONT).w() < 1.0f;
} }
// diffuse texture map... if (ssc.diffuse.valid())
if (ssc.diffuseTexture)
{ {
stateSet->setTextureAttributeAndModes(StateSetContent::DIFFUSE_TEXTURE_UNIT, ssc.diffuseTexture.get()); ssc.diffuse->assignTextureIfRequired(stateSet, StateSetContent::DIFFUSE_TEXTURE_UNIT);
ssc.diffuse->assignTexMatIfRequired(stateSet, StateSetContent::DIFFUSE_TEXTURE_UNIT);
if (ssc.diffuseScaleU != 1.0 || ssc.diffuseScaleV != 1.0)
{
// set UV scaling...
osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat();
osg::Matrix uvScaling;
uvScaling.makeScale(osg::Vec3(ssc.diffuseScaleU, ssc.diffuseScaleV, 1.0));
texmat->setMatrix(uvScaling);
stateSet->setTextureAttributeAndModes(StateSetContent::DIFFUSE_TEXTURE_UNIT, texmat.get(), osg::StateAttribute::ON);
}
if (lightmapTextures) if (lightmapTextures)
{ {
double factor = ssc.diffuseFactor; double factor = ssc.diffuse->factor;
osg::ref_ptr<osg::TexEnvCombine> texenv = new osg::TexEnvCombine(); osg::ref_ptr<osg::TexEnvCombine> texenv = new osg::TexEnvCombine();
texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE);
@ -245,25 +235,13 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap,
stateSet->setTextureAttributeAndModes(StateSetContent::DIFFUSE_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); stateSet->setTextureAttributeAndModes(StateSetContent::DIFFUSE_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON);
} }
// setup transparency if (!transparent) transparent = ssc.diffuse->transparent();
if (!transparent && ssc.diffuseTexture->getImage())
transparent = ssc.diffuseTexture->getImage()->isImageTranslucent();
} }
// opacity texture map... if (ssc.opacity.valid())
if (ssc.opacityTexture)
{ {
stateSet->setTextureAttributeAndModes(StateSetContent::OPACITY_TEXTURE_UNIT, ssc.opacityTexture.get()); ssc.opacity->assignTextureIfRequired(stateSet, StateSetContent::OPACITY_TEXTURE_UNIT);
ssc.opacity->assignTexMatIfRequired(stateSet, StateSetContent::OPACITY_TEXTURE_UNIT);
if (ssc.opacityScaleU != 1.0 || ssc.opacityScaleV != 1.0)
{
// set UV scaling...
osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat();
osg::Matrix uvScaling;
uvScaling.makeScale(osg::Vec3(ssc.opacityScaleU, ssc.opacityScaleV, 1.0));
texmat->setMatrix(uvScaling);
stateSet->setTextureAttributeAndModes(StateSetContent::OPACITY_TEXTURE_UNIT, texmat.get(), osg::StateAttribute::ON);
}
// setup combiner to ignore RGB... // setup combiner to ignore RGB...
osg::ref_ptr<osg::TexEnvCombine> texenv = new osg::TexEnvCombine(); osg::ref_ptr<osg::TexEnvCombine> texenv = new osg::TexEnvCombine();
@ -271,15 +249,12 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap,
texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS); texenv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
stateSet->setTextureAttributeAndModes(StateSetContent::OPACITY_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); stateSet->setTextureAttributeAndModes(StateSetContent::OPACITY_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON);
// setup transparency... if (!transparent) transparent = ssc.opacity->transparent();
if (!transparent && ssc.opacityTexture->getImage())
transparent = ssc.opacityTexture->getImage()->isImageTranslucent();
} }
// reflection texture map... if (ssc.reflection.valid())
if (ssc.reflectionTexture)
{ {
stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, ssc.reflectionTexture.get()); ssc.reflection->assignTextureIfRequired(stateSet, StateSetContent::REFLECTION_TEXTURE_UNIT);
// setup spherical map... // setup spherical map...
osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen(); osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen();
@ -287,7 +262,7 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap,
stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, texgen.get(), osg::StateAttribute::ON); stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, texgen.get(), osg::StateAttribute::ON);
// setup combiner for factor... // setup combiner for factor...
double factor = ssc.reflectionFactor; double factor = ssc.reflection->factor;
osg::ref_ptr<osg::TexEnvCombine> texenv = new osg::TexEnvCombine(); osg::ref_ptr<osg::TexEnvCombine> texenv = new osg::TexEnvCombine();
texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE);
texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE);
@ -297,84 +272,34 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap,
stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON);
} }
// emissive texture map if (ssc.emissive.valid())
if (ssc.emissiveTexture)
{ {
if (ssc.emissiveScaleU != 1.0 || ssc.emissiveScaleV != 1.0) ssc.emissive->assignTextureIfRequired(stateSet, StateSetContent::EMISSIVE_TEXTURE_UNIT);
{ ssc.emissive->assignTexMatIfRequired(stateSet, StateSetContent::EMISSIVE_TEXTURE_UNIT);
// set UV scaling...
osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat();
osg::Matrix uvScaling;
uvScaling.makeScale(osg::Vec3(ssc.emissiveScaleU, ssc.emissiveScaleV, 1.0));
texmat->setMatrix(uvScaling);
stateSet->setTextureAttributeAndModes(StateSetContent::EMISSIVE_TEXTURE_UNIT, texmat.get(), osg::StateAttribute::ON);
} }
stateSet->setTextureAttributeAndModes(StateSetContent::EMISSIVE_TEXTURE_UNIT, ssc.emissiveTexture.get()); if (ssc.ambient.valid())
{
ssc.ambient->assignTextureIfRequired(stateSet, StateSetContent::AMBIENT_TEXTURE_UNIT);
ssc.ambient->assignTexMatIfRequired(stateSet, StateSetContent::AMBIENT_TEXTURE_UNIT);
} }
// ambient texture map if (ssc.normalMap.valid())
if (ssc.ambientTexture)
{ {
if (ssc.ambientScaleU != 1.0 || ssc.ambientScaleV != 1.0) ssc.normalMap->assignTextureIfRequired(stateSet, StateSetContent::NORMAL_TEXTURE_UNIT);
{ ssc.normalMap->assignTexMatIfRequired(stateSet, StateSetContent::NORMAL_TEXTURE_UNIT);
// set UV scaling...
osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat();
osg::Matrix uvScaling;
uvScaling.makeScale(osg::Vec3(ssc.ambientScaleU, ssc.ambientScaleV, 1.0));
texmat->setMatrix(uvScaling);
stateSet->setTextureAttributeAndModes(StateSetContent::AMBIENT_TEXTURE_UNIT, texmat.get(), osg::StateAttribute::ON);
} }
stateSet->setTextureAttributeAndModes(StateSetContent::AMBIENT_TEXTURE_UNIT, ssc.ambientTexture.get()); if (ssc.specular.valid())
{
ssc.specular->assignTextureIfRequired(stateSet, StateSetContent::SPECULAR_TEXTURE_UNIT);
ssc.specular->assignTexMatIfRequired(stateSet, StateSetContent::SPECULAR_TEXTURE_UNIT);
} }
// normal texture map if (ssc.shininess.valid())
if (ssc.normalTexture)
{ {
if (ssc.normalScaleU != 1.0 || ssc.normalScaleV != 1.0) ssc.shininess->assignTextureIfRequired(stateSet, StateSetContent::SHININESS_TEXTURE_UNIT);
{ ssc.shininess->assignTexMatIfRequired(stateSet, StateSetContent::SHININESS_TEXTURE_UNIT);
// set UV scaling...
osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat();
osg::Matrix uvScaling;
uvScaling.makeScale(osg::Vec3(ssc.normalScaleU, ssc.normalScaleV, 1.0));
texmat->setMatrix(uvScaling);
stateSet->setTextureAttributeAndModes(StateSetContent::NORMAL_TEXTURE_UNIT, texmat.get(), osg::StateAttribute::ON);
}
stateSet->setTextureAttributeAndModes(StateSetContent::NORMAL_TEXTURE_UNIT, ssc.normalTexture.get());
}
// specular texture map
if (ssc.specularTexture)
{
if (ssc.specularScaleU != 1.0 || ssc.specularScaleV != 1.0)
{
// set UV scaling...
osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat();
osg::Matrix uvScaling;
uvScaling.makeScale(osg::Vec3(ssc.specularScaleU, ssc.specularScaleV, 1.0));
texmat->setMatrix(uvScaling);
stateSet->setTextureAttributeAndModes(StateSetContent::SPECULAR_TEXTURE_UNIT, texmat.get(), osg::StateAttribute::ON);
}
stateSet->setTextureAttributeAndModes(StateSetContent::SPECULAR_TEXTURE_UNIT, ssc.specularTexture.get());
}
// shininess texture map
if (ssc.shininessTexture)
{
if (ssc.shininessScaleU != 1.0 || ssc.shininessScaleV != 1.0)
{
// set UV scaling...
osg::ref_ptr<osg::TexMat> texmat = new osg::TexMat();
osg::Matrix uvScaling;
uvScaling.makeScale(osg::Vec3(ssc.shininessScaleU, ssc.shininessScaleV, 1.0));
texmat->setMatrix(uvScaling);
stateSet->setTextureAttributeAndModes(StateSetContent::SHININESS_TEXTURE_UNIT, texmat.get(), osg::StateAttribute::ON);
}
stateSet->setTextureAttributeAndModes(StateSetContent::SHININESS_TEXTURE_UNIT, ssc.shininessTexture.get());
} }
// add more texture maps here... // add more texture maps here...
@ -551,22 +476,22 @@ std::string getUVChannelForTextureMap(std::vector<StateSetContent>& stateSetList
// TODO: what if more than one channel for the same map type? // TODO: what if more than one channel for the same map type?
for (unsigned int i = 0; i < stateSetList.size(); i++) for (unsigned int i = 0; i < stateSetList.size(); i++)
{ {
if (0 == strcmp(pName, FbxSurfaceMaterial::sDiffuse)) if (stateSetList[i].diffuse.valid() && (0 == strcmp(pName, FbxSurfaceMaterial::sDiffuse)))
return stateSetList[i].diffuseChannel; return stateSetList[i].diffuse->channel;
if (0 == strcmp(pName, FbxSurfaceMaterial::sTransparentColor)) if (stateSetList[i].shininess.valid() && (0 == strcmp(pName, FbxSurfaceMaterial::sTransparentColor)))
return stateSetList[i].opacityChannel; return stateSetList[i].opacity->channel;
if (0 == strcmp(pName, FbxSurfaceMaterial::sReflection)) if (stateSetList[i].shininess.valid() && (0 == strcmp(pName, FbxSurfaceMaterial::sReflection)))
return stateSetList[i].reflectionChannel; return stateSetList[i].reflection->channel;
if (0 == strcmp(pName, FbxSurfaceMaterial::sEmissive)) if (stateSetList[i].shininess.valid() && (0 == strcmp(pName, FbxSurfaceMaterial::sEmissive)))
return stateSetList[i].emissiveChannel; return stateSetList[i].emissive->channel;
if (0 == strcmp(pName, FbxSurfaceMaterial::sAmbient)) if (stateSetList[i].shininess.valid() && (0 == strcmp(pName, FbxSurfaceMaterial::sAmbient)))
return stateSetList[i].ambientChannel; return stateSetList[i].ambient->channel;
if (0 == strcmp(pName, FbxSurfaceMaterial::sNormalMap)) if (stateSetList[i].shininess.valid() && (0 == strcmp(pName, FbxSurfaceMaterial::sNormalMap)))
return stateSetList[i].normalChannel; return stateSetList[i].normalMap->channel;
if (0 == strcmp(pName, FbxSurfaceMaterial::sSpecular)) if (stateSetList[i].shininess.valid() && (0 == strcmp(pName, FbxSurfaceMaterial::sSpecular)))
return stateSetList[i].specularChannel; return stateSetList[i].specular->channel;
if (0 == strcmp(pName, FbxSurfaceMaterial::sShininess)) if (stateSetList[i].shininess.valid() && (0 == strcmp(pName, FbxSurfaceMaterial::sShininess)))
return stateSetList[i].shininessChannel; return stateSetList[i].shininess->channel;
// more here... // more here...
} }