diff --git a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp index 4f29eccce..12f8b65da 100644 --- a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp +++ b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp @@ -127,6 +127,27 @@ FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat) } } + // ambient map... + const FbxProperty lAmbientProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sAmbient); + if (lAmbientProperty.IsValid()) + { + int lNbTex = lAmbientProperty.GetSrcObjectCount(); + for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) + { + FbxFileTexture* lTexture = FbxCast(lAmbientProperty.GetSrcObject(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; + } + } + if (pFbxLambert) { FbxDouble3 color = pFbxLambert->Diffuse.Get(); diff --git a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h index 5edefb24f..181778b28 100644 --- a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h +++ b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h @@ -22,7 +22,8 @@ struct StateSetContent StateSetContent() : diffuseFactor(1.0), reflectionFactor(1.0), - emissiveFactor(1.0) + emissiveFactor(1.0), + ambientFactor(1.0) { } @@ -33,6 +34,7 @@ struct StateSetContent osg::ref_ptr opacityTexture; osg::ref_ptr reflectionTexture; osg::ref_ptr emissiveTexture; + osg::ref_ptr ambientTexture; // more textures types here... // textures maps channels names... @@ -40,12 +42,14 @@ struct StateSetContent std::string opacityChannel; std::string reflectionChannel; std::string emissiveChannel; + std::string ambientChannel; // more channels names here... // combining factors... double diffuseFactor; double reflectionFactor; double emissiveFactor; + double ambientFactor; // more combining factors here... double diffuseScaleU; @@ -54,6 +58,8 @@ struct StateSetContent double opacityScaleV; double emissiveScaleU; double emissiveScaleV; + double ambientScaleU; + double ambientScaleV; // texture units (eventually used for each texture map)... enum TextureUnit @@ -61,7 +67,8 @@ struct StateSetContent DIFFUSE_TEXTURE_UNIT = 0, OPACITY_TEXTURE_UNIT, REFLECTION_TEXTURE_UNIT, - EMISSIVE_TEXTURE_UNIT + EMISSIVE_TEXTURE_UNIT, + AMBIENT_TEXTURE_UNIT // more texture units here... }; }; diff --git a/src/osgPlugins/fbx/fbxRMesh.cpp b/src/osgPlugins/fbx/fbxRMesh.cpp index bbeda1ab3..d42d57abf 100644 --- a/src/osgPlugins/fbx/fbxRMesh.cpp +++ b/src/osgPlugins/fbx/fbxRMesh.cpp @@ -154,6 +154,7 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, bool useDiffuseMap, bool useOpacityMap, bool useEmissiveMap, + bool useAmbientMap, // more here... bool bColor, const osgDB::Options& options, @@ -188,6 +189,8 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, pGeometry->setTexCoordArray(StateSetContent::OPACITY_TEXTURE_UNIT, createVec2Array((precision & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0), osg::Array::BIND_PER_VERTEX); if (useEmissiveMap) pGeometry->setTexCoordArray(StateSetContent::EMISSIVE_TEXTURE_UNIT, createVec2Array((precision & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0), osg::Array::BIND_PER_VERTEX); + if (useAmbientMap) + pGeometry->setTexCoordArray(StateSetContent::AMBIENT_TEXTURE_UNIT, createVec2Array((precision & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0), osg::Array::BIND_PER_VERTEX); // create more textures coordinates here... if (bColor) pGeometry->setColorArray(createVec4Array((precision & osgDB::Options::DOUBLE_PRECISION_COLOR) != 0), osg::Array::BIND_PER_VERTEX); @@ -301,6 +304,22 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, stateSet->setTextureAttributeAndModes(StateSetContent::EMISSIVE_TEXTURE_UNIT, ssc.emissiveTexture.get()); } + // ambient texture map + if (ssc.ambientTexture) + { + if (ssc.ambientScaleU != 1.0 || ssc.ambientScaleV != 1.0) + { + // set UV scaling... + osg::ref_ptr 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()); + } + // add more texture maps here... if (transparent) @@ -483,6 +502,8 @@ std::string getUVChannelForTextureMap(std::vector& stateSetList return stateSetList[i].reflectionChannel; if (0 == strcmp(pName, FbxSurfaceMaterial::sEmissive)) return stateSetList[i].emissiveChannel; + if (0 == strcmp(pName, FbxSurfaceMaterial::sAmbient)) + return stateSetList[i].ambientChannel; // more here... } @@ -536,6 +557,7 @@ void readMeshTriangle(const FbxMesh * fbxMesh, int i /*polygonIndex*/, const FbxLayerElementUV* pFbxUVs_diffuse, const FbxLayerElementUV* pFbxUVs_opacity, const FbxLayerElementUV* pFbxUVs_emissive, + const FbxLayerElementUV* pFbxUVs_ambient, const FbxLayerElementVertexColor* pFbxColors, osg::Geometry* pGeometry, osg::Array* pVertices, @@ -543,6 +565,7 @@ void readMeshTriangle(const FbxMesh * fbxMesh, int i /*polygonIndex*/, osg::Array* pTexCoords_diffuse, osg::Array* pTexCoords_opacity, osg::Array* pTexCoords_emissive, + osg::Array* pTexCoords_ambient, osg::Array* pColors) { int v0 = fbxMesh->GetPolygonVertex(i, posInPoly0), @@ -594,6 +617,12 @@ void readMeshTriangle(const FbxMesh * fbxMesh, int i /*polygonIndex*/, addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, posInPoly1, meshVertex1)); addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, posInPoly2, meshVertex2)); } + if (pTexCoords_ambient && (pTexCoords_ambient != pTexCoords_opacity) && (pTexCoords_ambient != pTexCoords_diffuse) && (pTexCoords_ambient != pTexCoords_emissive)) + { + addVec2ArrayElement(*pTexCoords_ambient, getElement(pFbxUVs_ambient, fbxMesh, i, posInPoly0, meshVertex0)); + addVec2ArrayElement(*pTexCoords_ambient, getElement(pFbxUVs_ambient, fbxMesh, i, posInPoly1, meshVertex1)); + addVec2ArrayElement(*pTexCoords_ambient, getElement(pFbxUVs_ambient, fbxMesh, i, posInPoly2, meshVertex2)); + } // add more texture maps here... if (pColors) @@ -695,12 +724,14 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( std::string diffuseChannel = getUVChannelForTextureMap(stateSetList, FbxSurfaceMaterial::sDiffuse); std::string opacityChannel = getUVChannelForTextureMap(stateSetList, FbxSurfaceMaterial::sTransparentColor); std::string emissiveChannel = getUVChannelForTextureMap(stateSetList, FbxSurfaceMaterial::sEmissive); + std::string ambientChannel = getUVChannelForTextureMap(stateSetList, FbxSurfaceMaterial::sAmbient); // look for more UV elements here... // UV elements... const FbxLayerElementUV* pFbxUVs_diffuse = getUVElementForChannel(diffuseChannel, FbxLayerElement::eTextureDiffuse, fbxMesh); const FbxLayerElementUV* pFbxUVs_opacity = getUVElementForChannel(opacityChannel, FbxLayerElement::eTextureTransparency, fbxMesh); const FbxLayerElementUV* pFbxUVs_emissive = getUVElementForChannel(emissiveChannel, FbxLayerElement::eTextureEmissive, fbxMesh); + const FbxLayerElementUV* pFbxUVs_ambient = getUVElementForChannel(ambientChannel, FbxLayerElement::eTextureAmbient, fbxMesh); // more UV elements here... // check elements validity... @@ -710,6 +741,7 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( if (!layerElementValid(pFbxUVs_diffuse)) pFbxUVs_diffuse = 0; if (!layerElementValid(pFbxUVs_opacity)) pFbxUVs_opacity = 0; if (!layerElementValid(pFbxUVs_emissive)) pFbxUVs_emissive = 0; + if (!layerElementValid(pFbxUVs_ambient)) pFbxUVs_ambient = 0; // more here... int nPolys = fbxMesh->GetPolygonCount(); @@ -750,6 +782,7 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( pFbxUVs_diffuse != 0, pFbxUVs_opacity != 0, pFbxUVs_emissive != 0, + pFbxUVs_ambient != 0, // more UV elements here... pFbxColors != 0, options, @@ -762,6 +795,7 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( osg::Array* pTexCoords_diffuse = pGeometry->getTexCoordArray(StateSetContent::DIFFUSE_TEXTURE_UNIT); osg::Array* pTexCoords_opacity = pGeometry->getTexCoordArray(StateSetContent::OPACITY_TEXTURE_UNIT); osg::Array* pTexCoords_emissive = pGeometry->getTexCoordArray(StateSetContent::EMISSIVE_TEXTURE_UNIT); + osg::Array* pTexCoords_ambient = pGeometry->getTexCoordArray(StateSetContent::AMBIENT_TEXTURE_UNIT); // more texture coordinates here... osg::Array* pColors = pGeometry->getColorArray(); @@ -773,9 +807,9 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( 0, 1, 2, nVertex, nVertex+1, nVertex+2, fbxToOsgVertMap, osgToFbxNormMap, - pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, + pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxUVs_ambient, pFbxColors, pGeometry, - pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); + pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pTexCoords_ambient, pColors); nVertex += 3; } else if (lPolygonSize == 4) @@ -790,16 +824,16 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( 0, 1, p02, nVertex, nVertex+1, nVertex+p02, fbxToOsgVertMap, osgToFbxNormMap, - pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, + pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxUVs_ambient, pFbxColors, pGeometry, - pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); + pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pTexCoords_ambient, pColors); readMeshTriangle(fbxMesh, i, p10, 2, 3, nVertex+p10, nVertex+2, nVertex+3, fbxToOsgVertMap, osgToFbxNormMap, - pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, + pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxUVs_ambient, pFbxColors, pGeometry, - pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); + pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pTexCoords_ambient, pColors); nVertex += 4; } else if (tessellatePolygons) @@ -819,9 +853,9 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( 0, j - 1, j, nVertex0, nVertex - 1, nVertex, fbxToOsgVertMap, osgToFbxNormMap, - pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxColors, + pFbxVertices, pFbxNormals, pFbxUVs_diffuse, pFbxUVs_opacity, pFbxUVs_emissive, pFbxUVs_ambient, pFbxColors, pGeometry, - pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pColors); + pVertices, pNormals, pTexCoords_diffuse, pTexCoords_opacity, pTexCoords_emissive, pTexCoords_ambient, pColors); } } } @@ -851,6 +885,7 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( osg::Array* pTexCoords_diffuse = pGeometry->getTexCoordArray(StateSetContent::DIFFUSE_TEXTURE_UNIT); osg::Array* pTexCoords_opacity = pGeometry->getTexCoordArray(StateSetContent::OPACITY_TEXTURE_UNIT); osg::Array* pTexCoords_emissive = pGeometry->getTexCoordArray(StateSetContent::EMISSIVE_TEXTURE_UNIT); + osg::Array* pTexCoords_ambient = pGeometry->getTexCoordArray(StateSetContent::AMBIENT_TEXTURE_UNIT); osg::Array* pColors = pGeometry->getColorArray(); // Index of the 1st vertex of the polygon in the geometry int osgVertex0 = pVertices->getNumElements(); @@ -883,6 +918,10 @@ osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( { addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, j, nVertex)); } + if (pTexCoords_ambient && (pTexCoords_ambient != pTexCoords_opacity) && (pTexCoords_ambient != pTexCoords_diffuse)) + { + addVec2ArrayElement(*pTexCoords_ambient, getElement(pFbxUVs_ambient, fbxMesh, i, j, nVertex)); + } // add more texture maps here... if (pColors)