root/OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp @ 11251

Revision 11251, 5.6 kB (checked in by mplatings, 5 years ago)

Workaround for models with inverted transparency

RevLine 
[11108]1#include "fbxMaterialToOsgStateSet.h"
2#include <sstream>
3#include <osgDB/ReadFile>
4#include <osgDB/FileUtils>
5#include <osgDB/FileNameUtils>
6
7
8static osg::Texture::WrapMode convertWrap(KFbxTexture::EWrapMode wrap)
9{
10    return wrap == KFbxTexture::eREPEAT ?
11        osg::Texture2D::REPEAT : osg::Texture2D::CLAMP_TO_EDGE;
12}
13
14StateSetContent
15FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat)
16{
17    KFbxMaterialMap::const_iterator it = _kFbxMaterialMap.find(pFbxMat);
18    if (it != _kFbxMaterialMap.end())
19        return it->second;
20    static int nbMat = 0;
21    osg::ref_ptr<osg::Material> pOsgMat = new osg::Material;
22    osg::ref_ptr<osg::Texture2D> pOsgTex = NULL;
23    pOsgMat->setName(pFbxMat->GetName());
24
25    const KFbxSurfaceLambert* pFbxLambert = dynamic_cast<const KFbxSurfaceLambert*>(pFbxMat);
26
27    const KFbxProperty lProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sDiffuse);
28    if (lProperty.IsValid())
29    {
30        int lNbTex = lProperty.GetSrcObjectCount(KFbxTexture::ClassId);
31        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
32        {
33            KFbxTexture* lTexture = KFbxCast<KFbxTexture>(lProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex));
34            if (lTexture)
35            {
36                pOsgTex = fbxTextureToOsgTexture(lTexture);
37            }
38
39            //For now only allow 1 texture
40            break;
41        }
42    }
43    if (pFbxLambert)
44    {
45        fbxDouble3 color = pFbxLambert->GetDiffuseColor().Get();
46        double factor = pFbxLambert->GetDiffuseFactor().Get();
47        pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(
48            static_cast<float>(color[0] * factor),
49            static_cast<float>(color[1] * factor),
50            static_cast<float>(color[2] * factor),
51            static_cast<float>(1.0 - pFbxLambert->GetTransparencyFactor().Get())));
52
53        color = pFbxLambert->GetAmbientColor().Get();
54        factor = pFbxLambert->GetAmbientFactor().Get();
55        pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(
56            static_cast<float>(color[0] * factor),
57            static_cast<float>(color[1] * factor),
58            static_cast<float>(color[2] * factor),
59            1.0f));
60
61        color = pFbxLambert->GetEmissiveColor().Get();
62        factor = pFbxLambert->GetEmissiveFactor().Get();
63        pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(
64            static_cast<float>(color[0] * factor),
65            static_cast<float>(color[1] * factor),
66            static_cast<float>(color[2] * factor),
67            1.0f));
68
69        if (const KFbxSurfacePhong* pFbxPhong = dynamic_cast<const KFbxSurfacePhong*>(pFbxLambert))
70        {
71            color = pFbxPhong->GetSpecularColor().Get();
72            factor = pFbxPhong->GetSpecularFactor().Get();
73            pOsgMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(
74                static_cast<float>(color[0] * factor),
75                static_cast<float>(color[1] * factor),
76                static_cast<float>(color[2] * factor),
77                1.0f));
78
79            pOsgMat->setShininess(osg::Material::FRONT_AND_BACK,
80                static_cast<float>(pFbxPhong->GetShininess().Get()));
81        }
82    }
[11251]83    StateSetContent result(pOsgMat.release(), pOsgTex.release());
84    _kFbxMaterialMap.insert(KFbxMaterialMap::value_type(pFbxMat, result));
85    return result;
[11108]86}
87
88osg::ref_ptr<osg::Texture2D>
89FbxMaterialToOsgStateSet::fbxTextureToOsgTexture(const KFbxTexture* fbx)
90{
91    ImageMap::iterator it = _imageMap.find(fbx->GetFileName());
92    if (it != _imageMap.end())
93        return it->second;
94    osg::ref_ptr<osg::Image> pImage = NULL;
95
96    // Warning: fbx->GetRelativeFileName() is relative TO EXECUTION DIR
97    //          fbx->GetFileName() is as stored initially in the FBX
98    if ((pImage = osgDB::readImageFile(osgDB::concatPaths(_dir, fbx->GetFileName()), _options)) ||                // First try "export dir/name"
99        (pImage = osgDB::readImageFile(fbx->GetFileName(), _options)) ||                                        // Then try  "name" (if absolute)
100        (pImage = osgDB::readImageFile(osgDB::concatPaths(_dir, fbx->GetRelativeFileName()), _options)))        // Else try  "current dir/name"
101    {
102        osg::ref_ptr<osg::Texture2D> pOsgTex = new osg::Texture2D;
103        pOsgTex->setImage(pImage.get());
104        pOsgTex->setWrap(osg::Texture2D::WRAP_S, convertWrap(fbx->GetWrapModeU()));
105        pOsgTex->setWrap(osg::Texture2D::WRAP_T, convertWrap(fbx->GetWrapModeV()));
106        _imageMap.insert(std::make_pair(fbx->GetFileName(), pOsgTex.get()));
107        return pOsgTex.release();
108    }
109    else
110    {
111        return NULL;
112    }
113}
[11251]114
115void FbxMaterialToOsgStateSet::checkInvertTransparency()
116{
117    int zeroAlpha = 0, oneAlpha = 0;
118    for (KFbxMaterialMap::const_iterator it = _kFbxMaterialMap.begin(); it != _kFbxMaterialMap.end(); ++it)
119    {
120        const osg::Material* pMaterial = it->second.first;
121        float alpha = pMaterial->getDiffuse(osg::Material::FRONT).a();
122        if (alpha > 0.999f)
123        {
124            ++oneAlpha;
125        }
126        else if (alpha < 0.001f)
127        {
128            ++zeroAlpha;
129        }
130    }
131
132    if (zeroAlpha > oneAlpha)
133    {
134        //Transparency values seem to be back to front so invert them.
135
136        for (KFbxMaterialMap::const_iterator it = _kFbxMaterialMap.begin(); it != _kFbxMaterialMap.end(); ++it)
137        {
138            osg::Material* pMaterial = it->second.first;
139            osg::Vec4 diffuse = pMaterial->getDiffuse(osg::Material::FRONT);
140            diffuse.a() = 1.0f - diffuse.a();
141            pMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
142        }
143    }
144}
Note: See TracBrowser for help on using the browser.