diff --git a/src/osgPlugins/fbx/ReaderWriterFBX.cpp b/src/osgPlugins/fbx/ReaderWriterFBX.cpp index 9bc26f322..8d1c72c60 100644 --- a/src/osgPlugins/fbx/ReaderWriterFBX.cpp +++ b/src/osgPlugins/fbx/ReaderWriterFBX.cpp @@ -464,7 +464,8 @@ osgDB::ReaderWriter::WriteResult ReaderWriterFBX::writeNode( { // If root node is a simple group, put all elements under the FBX root const osg::Group * osgGroup = node.asGroup(); - for(unsigned int child=0; childgetNumChildren(); ++child) { + for (unsigned int child = 0; child < osgGroup->getNumChildren(); ++child) + { const_cast(osgGroup->getChild(child))->accept(writerNodeVisitor); } } diff --git a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp index 8183e25b8..3f488d72b 100644 --- a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp +++ b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp @@ -22,13 +22,6 @@ FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat) osg::ref_ptr pOsgMat = new osg::Material; pOsgMat->setName(pFbxMat->GetName()); - // texture maps... - osg::ref_ptr pOsgDiffuseTex = NULL; - osg::ref_ptr pOsgReflectionTex = NULL; - osg::ref_ptr pOsgOpacityTex = NULL; - osg::ref_ptr pOsgEmissiveTex = NULL; - // add more maps here... - StateSetContent result; result.material = pOsgMat; @@ -47,9 +40,10 @@ FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat) KFbxTexture* lTexture = KFbxCast(lProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex)); if (lTexture) { - pOsgDiffuseTex = fbxTextureToOsgTexture(lTexture); - result.diffuseTexture = pOsgDiffuseTex.release(); + result.diffuseTexture = fbxTextureToOsgTexture(lTexture); result.diffuseChannel = lTexture->UVSet.Get(); + result.diffuseScaleU = lTexture->GetScaleU(); + result.diffuseScaleV = lTexture->GetScaleV(); } //For now only allow 1 texture @@ -67,9 +61,12 @@ FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat) KFbxTexture* lTexture = KFbxCast(lOpacityProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex)); if (lTexture) { - pOsgOpacityTex = fbxTextureToOsgTexture(lTexture); - result.opacityTexture = pOsgOpacityTex.release(); + // 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 @@ -90,8 +87,7 @@ FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat) // support only spherical reflection maps... if (KFbxTexture::eUMT_ENVIRONMENT == lTexture->GetMappingType()) { - pOsgReflectionTex = fbxTextureToOsgTexture(lTexture); - result.reflectionTexture = pOsgReflectionTex.release(); + result.reflectionTexture = fbxTextureToOsgTexture(lTexture); result.reflectionChannel = lTexture->UVSet.Get(); } } @@ -111,9 +107,10 @@ FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat) KFbxTexture* lTexture = KFbxCast(lEmissiveProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex)); if (lTexture) { - pOsgEmissiveTex = fbxTextureToOsgTexture(lTexture); - result.emissiveTexture = pOsgEmissiveTex.release(); + result.emissiveTexture = fbxTextureToOsgTexture(lTexture); result.emissiveChannel = lTexture->UVSet.Get(); + result.emissiveScaleU = lTexture->GetScaleU(); + result.emissiveScaleV = lTexture->GetScaleV(); } //For now only allow 1 texture @@ -203,7 +200,7 @@ FbxMaterialToOsgStateSet::fbxTextureToOsgTexture(const KFbxTexture* fbx) pOsgTex->setWrap(osg::Texture2D::WRAP_S, convertWrap(fbx->GetWrapModeU())); pOsgTex->setWrap(osg::Texture2D::WRAP_T, convertWrap(fbx->GetWrapModeV())); _imageMap.insert(std::make_pair(fbx->GetFileName(), pOsgTex.get())); - return pOsgTex.release(); + return pOsgTex; } else { diff --git a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h index b69d2c3e0..2e2bc97cc 100644 --- a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h +++ b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h @@ -49,6 +49,13 @@ struct StateSetContent double emissiveFactor; // more combining factors here... + double diffuseScaleU; + double diffuseScaleV; + double opacityScaleU; + double opacityScaleV; + double emissiveScaleU; + double emissiveScaleV; + // texture units (eventually used for each texture map)... enum TextureUnit { diff --git a/src/osgPlugins/fbx/fbxRMesh.cpp b/src/osgPlugins/fbx/fbxRMesh.cpp index 8052ea548..a20841cf9 100644 --- a/src/osgPlugins/fbx/fbxRMesh.cpp +++ b/src/osgPlugins/fbx/fbxRMesh.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -202,6 +203,16 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, { stateSet->setTextureAttributeAndModes(StateSetContent::DIFFUSE_TEXTURE_UNIT, ssc.diffuseTexture.get()); + if (ssc.diffuseScaleU != 1.0 || ssc.diffuseScaleV != 1.0) + { + // set UV scaling... + osg::ref_ptr 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) { double factor = ssc.diffuseFactor; @@ -224,6 +235,16 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, { stateSet->setTextureAttributeAndModes(StateSetContent::OPACITY_TEXTURE_UNIT, ssc.opacityTexture.get()); + if (ssc.opacityScaleU != 1.0 || ssc.opacityScaleV != 1.0) + { + // set UV scaling... + osg::ref_ptr 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 for factor... //In practice factor will always be zero, hence the RGB of the //opacity map will be ignored. The alpha will modulate the previous alpha. @@ -265,6 +286,16 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, // emissive texture map if (ssc.emissiveTexture) { + if (ssc.emissiveScaleU != 1.0 || ssc.emissiveScaleV != 1.0) + { + // set UV scaling... + osg::ref_ptr 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()); } @@ -442,7 +473,7 @@ std::string getUVChannelForTextureMap(std::vector& stateSetList { // will return the first occurrence in the state set list... // 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, KFbxSurfaceMaterial::sDiffuse)) return stateSetList[i].diffuseChannel; @@ -458,27 +489,36 @@ std::string getUVChannelForTextureMap(std::vector& stateSetList return ""; } -// scans mesh layers looking for the UV element corrensponding to the specified channel name... -const KFbxLayerElementUV* getUVElementForChannel(std::string pUVChannel, KFbxMesh* pFbxMesh) +// scans mesh layers looking for the UV element corresponding to the specified channel name... +const KFbxLayerElementUV* getUVElementForChannel(std::string uvChannelName, + KFbxLayerElement::ELayerElementType elementType, KFbxMesh* pFbxMesh) { - const KFbxLayer* pFbxLayer = 0; - const KFbxLayerElementUV* uv = 0; - // scan layers for specified UV channel... - for (int cLayerIndex=0; cLayerIndex < pFbxMesh->GetLayerCount(); cLayerIndex++) + for (int cLayerIndex = 0; cLayerIndex < pFbxMesh->GetLayerCount(); cLayerIndex++) { - pFbxLayer = pFbxMesh->GetLayer(cLayerIndex); + const KFbxLayer* pFbxLayer = pFbxMesh->GetLayer(cLayerIndex); if (!pFbxLayer) continue; - uv = pFbxLayer->GetUVs(); - if (uv) + if (const KFbxLayerElementUV* uv = pFbxLayer->GetUVs()) { - if (0 == pUVChannel.compare(uv->GetName())) + if (0 == uvChannelName.compare(uv->GetName())) return uv; } } + for (int cLayerIndex = 0; cLayerIndex < pFbxMesh->GetLayerCount(); cLayerIndex++) + { + const KFbxLayer* pFbxLayer = pFbxMesh->GetLayer(cLayerIndex); + if (!pFbxLayer) + continue; + + if (const KFbxLayerElementUV* uv = pFbxLayer->GetUVs(elementType)) + { + return uv; + } + } + return 0; } @@ -493,8 +533,6 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( osg::Geode* pGeode = new osg::Geode; pGeode->setName(szName); - const KFbxLayer* pFbxLayer = 0; - const KFbxLayerElementNormal* pFbxNormals = 0; const KFbxLayerElementVertexColor* pFbxColors = 0; const KFbxLayerElementMaterial* pFbxMaterials = 0; @@ -502,9 +540,9 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( const KFbxVector4* pFbxVertices = fbxMesh->GetControlPoints(); // scan layers for Normals, Colors and Materials elements (this will get the first available elements)... - for (int cLayerIndex=0; cLayerIndex < fbxMesh->GetLayerCount(); cLayerIndex++) + for (int cLayerIndex = 0; cLayerIndex < fbxMesh->GetLayerCount(); cLayerIndex++) { - pFbxLayer = fbxMesh->GetLayer(cLayerIndex); + const KFbxLayer* pFbxLayer = fbxMesh->GetLayer(cLayerIndex); if (!pFbxLayer) continue; @@ -520,13 +558,13 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( // look for UV elements (diffuse, opacity, reflection, emissive, ...) and get their channels names... std::string diffuseChannel = getUVChannelForTextureMap(stateSetList, KFbxSurfaceMaterial::sDiffuse); std::string opacityChannel = getUVChannelForTextureMap(stateSetList, KFbxSurfaceMaterial::sTransparentColor); - std::string emissiveChannel = getUVChannelForTextureMap(stateSetList, KFbxSurfaceMaterial::sEmissive);; + std::string emissiveChannel = getUVChannelForTextureMap(stateSetList, KFbxSurfaceMaterial::sEmissive); // look for more UV elements here... // UV elements... - const KFbxLayerElementUV* pFbxUVs_diffuse = getUVElementForChannel(diffuseChannel, fbxMesh); - const KFbxLayerElementUV* pFbxUVs_opacity = getUVElementForChannel(opacityChannel, fbxMesh); - const KFbxLayerElementUV* pFbxUVs_emissive = getUVElementForChannel(emissiveChannel, fbxMesh); + const KFbxLayerElementUV* pFbxUVs_diffuse = getUVElementForChannel(diffuseChannel, KFbxLayerElement::eDIFFUSE_TEXTURES, fbxMesh); + const KFbxLayerElementUV* pFbxUVs_opacity = getUVElementForChannel(opacityChannel, KFbxLayerElement::eTRANSPARENT_TEXTURES, fbxMesh); + const KFbxLayerElementUV* pFbxUVs_emissive = getUVElementForChannel(emissiveChannel, KFbxLayerElement::eEMISSIVE_TEXTURES, fbxMesh); // more UV elements here... // check elements validity...