Show
Ignore:
Timestamp:
06/04/10 21:50:32 (5 years ago)
Author:
mplatings
Message:

From Alessandro Terenzi: modifications for supporting opacity, reflective and emissive maps beyond the already supported diffuse map in the FBX plugin.
A problem with transparency has also been fixed: objects were transparent wrt themselves but were opaque wrt to other objects.
Finally I added the support for "mixing factors" of diffuse, reflective and opacity textures/values.

From Michael Platings: added "LightmapTextures?" plugin option that changes the way textures are interpreted so Alessandro's models appear correctly. Also refactored to put many functions in one class to avoid passing around too many arguments to functions.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp

    r11251 r11582  
    1919        return it->second; 
    2020    static int nbMat = 0; 
     21 
    2122    osg::ref_ptr<osg::Material> pOsgMat = new osg::Material; 
    22     osg::ref_ptr<osg::Texture2D> pOsgTex = NULL; 
    2323    pOsgMat->setName(pFbxMat->GetName()); 
     24     
     25    // texture maps... 
     26    osg::ref_ptr<osg::Texture2D> pOsgDiffuseTex = NULL; 
     27    osg::ref_ptr<osg::Texture2D> pOsgReflectionTex = NULL; 
     28    osg::ref_ptr<osg::Texture2D> pOsgOpacityTex = NULL; 
     29    osg::ref_ptr<osg::Texture2D> pOsgEmissiveTex = NULL; 
     30    // add more maps here... 
     31 
     32    StateSetContent result; 
     33 
     34        result.material = pOsgMat; 
     35 
     36        fbxString shadingModel = pFbxMat->GetShadingModel().Get(); 
    2437 
    2538    const KFbxSurfaceLambert* pFbxLambert = dynamic_cast<const KFbxSurfaceLambert*>(pFbxMat); 
    2639 
     40    // diffuse map... 
    2741    const KFbxProperty lProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sDiffuse); 
    2842    if (lProperty.IsValid()) 
     
    3448            if (lTexture) 
    3549            { 
    36                 pOsgTex = fbxTextureToOsgTexture(lTexture); 
    37             } 
    38  
    39             //For now only allow 1 texture 
    40             break; 
    41         } 
    42     } 
     50                pOsgDiffuseTex = fbxTextureToOsgTexture(lTexture); 
     51                result.diffuseTexture = pOsgDiffuseTex.release(); 
     52                result.diffuseChannel = lTexture->UVSet.Get(); 
     53            } 
     54 
     55            //For now only allow 1 texture 
     56            break; 
     57        } 
     58    } 
     59 
     60    // opacity map... 
     61    const KFbxProperty lOpacityProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sTransparentColor); 
     62    if (lOpacityProperty.IsValid()) 
     63    { 
     64        int lNbTex = lOpacityProperty.GetSrcObjectCount(KFbxTexture::ClassId); 
     65        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) 
     66        { 
     67            KFbxTexture* lTexture = KFbxCast<KFbxTexture>(lOpacityProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex)); 
     68            if (lTexture) 
     69            { 
     70                // TODO: if texture image does NOT have an alpha channel, should it be added? 
     71 
     72                pOsgOpacityTex = fbxTextureToOsgTexture(lTexture); 
     73                result.opacityTexture = pOsgOpacityTex.release(); 
     74                result.opacityChannel = lTexture->UVSet.Get(); 
     75            } 
     76 
     77            //For now only allow 1 texture 
     78            break; 
     79        } 
     80    } 
     81 
     82    // reflection map... 
     83    const KFbxProperty lReflectionProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sReflection); 
     84    if (lReflectionProperty.IsValid()) 
     85    { 
     86        int lNbTex = lReflectionProperty.GetSrcObjectCount(KFbxTexture::ClassId); 
     87        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) 
     88        { 
     89            KFbxTexture* lTexture = KFbxCast<KFbxTexture>(lReflectionProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex)); 
     90            if (lTexture) 
     91            { 
     92                // support only spherical reflection maps... 
     93                if (KFbxTexture::eUMT_ENVIRONMENT == lTexture->GetMappingType()) 
     94                { 
     95                    pOsgReflectionTex = fbxTextureToOsgTexture(lTexture); 
     96                    result.reflectionTexture = pOsgReflectionTex.release(); 
     97                    result.reflectionChannel = lTexture->UVSet.Get(); 
     98                } 
     99            } 
     100 
     101            //For now only allow 1 texture 
     102            break; 
     103        } 
     104    } 
     105 
     106    // emissive map... 
     107    const KFbxProperty lEmissiveProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sEmissive); 
     108    if (lEmissiveProperty.IsValid()) 
     109    { 
     110        int lNbTex = lEmissiveProperty.GetSrcObjectCount(KFbxTexture::ClassId); 
     111        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) 
     112        { 
     113            KFbxTexture* lTexture = KFbxCast<KFbxTexture>(lEmissiveProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex)); 
     114            if (lTexture) 
     115            { 
     116                pOsgEmissiveTex = fbxTextureToOsgTexture(lTexture); 
     117                result.emissiveTexture = pOsgEmissiveTex.release(); 
     118                result.emissiveChannel = lTexture->UVSet.Get(); 
     119            } 
     120 
     121            //For now only allow 1 texture 
     122            break; 
     123            } 
     124    } 
     125 
    43126    if (pFbxLambert) 
    44127    { 
     
    79162            pOsgMat->setShininess(osg::Material::FRONT_AND_BACK, 
    80163                static_cast<float>(pFbxPhong->GetShininess().Get())); 
    81         } 
    82     } 
    83     StateSetContent result(pOsgMat.release(), pOsgTex.release()); 
    84     _kFbxMaterialMap.insert(KFbxMaterialMap::value_type(pFbxMat, result)); 
     164 
     165            // get maps factors... 
     166            result.diffuseFactor = pFbxPhong->GetDiffuseFactor().Get(); 
     167            result.reflectionFactor = pFbxPhong->GetReflectionFactor().Get(); 
     168            result.opacityFactor = pFbxPhong->GetTransparencyFactor().Get(); 
     169            // get more factors here... 
     170        } 
     171    } 
     172 
     173        if (_lightmapTextures) 
     174        { 
     175                // if using an emission map then adjust material properties accordingly... 
     176                if (result.emissiveTexture) 
     177                { 
     178                        osg::Vec4 diffuse = pOsgMat->getDiffuse(osg::Material::FRONT_AND_BACK); 
     179                        pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, diffuse); 
     180                        pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a())); 
     181                        pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a())); 
     182                } 
     183        } 
     184 
     185        _kFbxMaterialMap.insert(KFbxMaterialMap::value_type(pFbxMat, result)); 
    85186    return result; 
    86187} 
     
    118219    for (KFbxMaterialMap::const_iterator it = _kFbxMaterialMap.begin(); it != _kFbxMaterialMap.end(); ++it) 
    119220    { 
    120         const osg::Material* pMaterial = it->second.first; 
     221        const osg::Material* pMaterial = it->second.material.get(); 
    121222        float alpha = pMaterial->getDiffuse(osg::Material::FRONT).a(); 
    122223        if (alpha > 0.999f) 
     
    136237        for (KFbxMaterialMap::const_iterator it = _kFbxMaterialMap.begin(); it != _kFbxMaterialMap.end(); ++it) 
    137238        { 
    138             osg::Material* pMaterial = it->second.first; 
     239            osg::Material* pMaterial = it->second.material.get(); 
    139240            osg::Vec4 diffuse = pMaterial->getDiffuse(osg::Material::FRONT); 
    140241            diffuse.a() = 1.0f - diffuse.a();