From 359b6b480d7bfc8d16ae1eb587955e7e2719ecf7 Mon Sep 17 00:00:00 2001 From: Michael PLATINGS Date: Fri, 4 Jun 2010 19:50:32 +0000 Subject: [PATCH] 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. --- src/osgPlugins/fbx/CMakeLists.txt | 8 +- src/osgPlugins/fbx/ReaderWriterFBX.cpp | 75 ++++- src/osgPlugins/fbx/ReaderWriterFBX.h | 1 + .../fbx/fbxMaterialToOsgStateSet.cpp | 113 ++++++- src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h | 53 +++- src/osgPlugins/fbx/fbxRAnimation.cpp | 11 +- src/osgPlugins/fbx/fbxRAnimation.h | 12 - src/osgPlugins/fbx/fbxRCamera.cpp | 4 +- src/osgPlugins/fbx/fbxRCamera.h | 10 - src/osgPlugins/fbx/fbxRLight.cpp | 4 +- src/osgPlugins/fbx/fbxRLight.h | 10 - src/osgPlugins/fbx/fbxRMesh.cpp | 281 ++++++++++++++---- src/osgPlugins/fbx/fbxRMesh.h | 19 -- src/osgPlugins/fbx/fbxRNode.cpp | 32 +- src/osgPlugins/fbx/fbxRNode.h | 31 -- src/osgPlugins/fbx/fbxReader.h | 82 +++++ 16 files changed, 547 insertions(+), 199 deletions(-) delete mode 100644 src/osgPlugins/fbx/fbxRAnimation.h delete mode 100644 src/osgPlugins/fbx/fbxRCamera.h delete mode 100644 src/osgPlugins/fbx/fbxRLight.h delete mode 100644 src/osgPlugins/fbx/fbxRMesh.h delete mode 100644 src/osgPlugins/fbx/fbxRNode.h create mode 100644 src/osgPlugins/fbx/fbxReader.h diff --git a/src/osgPlugins/fbx/CMakeLists.txt b/src/osgPlugins/fbx/CMakeLists.txt index df997b4bd..4cd4bbb6c 100644 --- a/src/osgPlugins/fbx/CMakeLists.txt +++ b/src/osgPlugins/fbx/CMakeLists.txt @@ -13,15 +13,11 @@ SET(TARGET_SRC ) SET(TARGET_H - fbxRAnimation.h - fbxRCamera.h - fbxRLight.h - fbxRMesh.h - fbxRNode.h + fbxMaterialToOsgStateSet.h + fbxReader.h ReaderWriterFBX.h WriterCompareTriangle.h WriterNodeVisitor.h - fbxMaterialToOsgStateSet.h ) ADD_DEFINITIONS(-DKFBX_PLUGIN -DKFBX_FBXSDK -DKFBX_NODLL) diff --git a/src/osgPlugins/fbx/ReaderWriterFBX.cpp b/src/osgPlugins/fbx/ReaderWriterFBX.cpp index 165c14d47..5e5895f4b 100644 --- a/src/osgPlugins/fbx/ReaderWriterFBX.cpp +++ b/src/osgPlugins/fbx/ReaderWriterFBX.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -23,8 +24,7 @@ #include #include "ReaderWriterFBX.h" -#include "fbxRNode.h" -#include "fbxMaterialToOsgStateSet.h" +#include "fbxReader.h" #include "WriterNodeVisitor.h" /// Returns true if the given node is a basic root group with no special information. @@ -255,6 +255,7 @@ ReaderWriterFBX::readNode(const std::string& filenameInit, pScene->SetCurrentTake(pScene->GetCurrentTakeName()); bool useFbxRoot = false; + bool lightmapTextures = false; if (options) { std::istringstream iss(options->getOptionString()); @@ -265,10 +266,13 @@ ReaderWriterFBX::readNode(const std::string& filenameInit, { useFbxRoot = true; } + if (opt == "LightmapTextures") + { + lightmapTextures = true; + } } } - osg::ref_ptr pAnimationManager; bool bIsBone = false; int nLightCount = 0; osg::ref_ptr localOptions = NULL; @@ -279,29 +283,59 @@ ReaderWriterFBX::readNode(const std::string& filenameInit, localOptions->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_IMAGES); std::string filePath = osgDB::getFilePath(filename); - FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get()); + FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get(), lightmapTextures); std::set fbxSkeletons; findLinkedFbxSkeletonNodes(pNode, fbxSkeletons); - std::map nodeMap; - BindMatrixMap boneBindMatrices; - std::map skeletonMap; - ReadResult res = readFbxNode(*pSdkManager, *pScene, pNode, pAnimationManager, - bIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap, - boneBindMatrices, fbxSkeletons, skeletonMap, *localOptions); + OsgFbxReader::AuthoringTool authoringTool = OsgFbxReader::UNKNOWN; + if (KFbxDocumentInfo* pDocInfo = pScene->GetDocumentInfo()) + { + struct ToolName + { + const char* name; + OsgFbxReader::AuthoringTool tool; + }; + + ToolName authoringTools[] = { + {"OpenSceneGraph", OsgFbxReader::OPENSCENEGRAPH}, + {"3ds Max", OsgFbxReader::AUTODESK_3DSTUDIO_MAX} + }; + + fbxString appName = pDocInfo->LastSaved_ApplicationName.Get(); + + for (int i = 0; i < sizeof(authoringTools) / sizeof(authoringTools[0]); ++i) + { + if (0 == _strnicmp(appName, authoringTools[i].name, strlen(authoringTools[i].name))) + { + authoringTool = authoringTools[i].tool; + break; + } + } + } + + + OsgFbxReader reader(*pSdkManager, + *pScene, + fbxMaterialToOsgStateSet, + fbxSkeletons, + *localOptions, + authoringTool, + lightmapTextures); + + ReadResult res = reader.readFbxNode(pNode, bIsBone, nLightCount); if (res.success()) { fbxMaterialToOsgStateSet.checkInvertTransparency(); - resolveBindMatrices(*res.getNode(), boneBindMatrices, nodeMap); + resolveBindMatrices(*res.getNode(), reader.boneBindMatrices, reader.nodeMap); osg::Node* osgNode = res.getNode(); osgNode->getOrCreateStateSet()->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON); osgNode->getOrCreateStateSet()->setMode(GL_NORMALIZE,osg::StateAttribute::ON); - if (pAnimationManager.valid()) + if (reader.pAnimationManager.valid()) { if (osgNode->getUpdateCallback()) { @@ -311,8 +345,8 @@ ReaderWriterFBX::readNode(const std::string& filenameInit, } //because the animations may be altered after registering - pAnimationManager->buildTargetReference(); - osgNode->setUpdateCallback(pAnimationManager.get()); + reader.pAnimationManager->buildTargetReference(); + osgNode->setUpdateCallback(reader.pAnimationManager.get()); } KFbxAxisSystem fbxAxis = pScene->GetGlobalSettings().GetAxisSystem(); @@ -439,6 +473,19 @@ osgDB::ReaderWriter::WriteResult ReaderWriterFBX::writeNode( const_cast(node).accept(writerNodeVisitor); } + KFbxDocumentInfo* pDocInfo = pScene->GetDocumentInfo(); + bool needNewDocInfo = pDocInfo != NULL; + if (needNewDocInfo) + { + pDocInfo = KFbxDocumentInfo::Create(pSdkManager, ""); + } + pDocInfo->LastSaved_ApplicationName.Set(fbxString("OpenSceneGraph")); + pDocInfo->LastSaved_ApplicationVersion.Set(fbxString(osgGetVersion())); + if (needNewDocInfo) + { + pScene->SetDocumentInfo(pDocInfo); + } + KFbxExporter* lExporter = KFbxExporter::Create(pSdkManager, ""); pScene->GetGlobalSettings().SetAxisSystem(KFbxAxisSystem::eOpenGL); diff --git a/src/osgPlugins/fbx/ReaderWriterFBX.h b/src/osgPlugins/fbx/ReaderWriterFBX.h index add68c84d..a7f059a09 100644 --- a/src/osgPlugins/fbx/ReaderWriterFBX.h +++ b/src/osgPlugins/fbx/ReaderWriterFBX.h @@ -16,6 +16,7 @@ public: supportsExtension("fbx", "FBX format"); supportsOption("Embedded", "(Write option) Embed textures in FBX file"); supportsOption("UseFbxRoot", "(Read/write option) If the source OSG root node is a simple group with no stateset, the writer will put its children directly under the FBX root, and vice-versa for reading"); + supportsOption("LightmapTextures", "(Read option) Interpret texture maps as overriding the lighting. 3D Studio Max may export files that should be interpreted in this way."); } const char* className() const { return "FBX reader/writer"; } diff --git a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp index 9a1d2d83e..af8ca9d21 100644 --- a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp +++ b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp @@ -18,12 +18,26 @@ FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat) if (it != _kFbxMaterialMap.end()) return it->second; static int nbMat = 0; + osg::ref_ptr pOsgMat = new osg::Material; - osg::ref_ptr pOsgTex = NULL; 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; + + fbxString shadingModel = pFbxMat->GetShadingModel().Get(); const KFbxSurfaceLambert* pFbxLambert = dynamic_cast(pFbxMat); + // diffuse map... const KFbxProperty lProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sDiffuse); if (lProperty.IsValid()) { @@ -33,13 +47,82 @@ FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat) KFbxTexture* lTexture = KFbxCast(lProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex)); if (lTexture) { - pOsgTex = fbxTextureToOsgTexture(lTexture); + pOsgDiffuseTex = fbxTextureToOsgTexture(lTexture); + result.diffuseTexture = pOsgDiffuseTex.release(); + result.diffuseChannel = lTexture->UVSet.Get(); } //For now only allow 1 texture break; } } + + // opacity map... + const KFbxProperty lOpacityProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sTransparentColor); + if (lOpacityProperty.IsValid()) + { + int lNbTex = lOpacityProperty.GetSrcObjectCount(KFbxTexture::ClassId); + for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) + { + KFbxTexture* lTexture = KFbxCast(lOpacityProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex)); + if (lTexture) + { + // TODO: if texture image does NOT have an alpha channel, should it be added? + + pOsgOpacityTex = fbxTextureToOsgTexture(lTexture); + result.opacityTexture = pOsgOpacityTex.release(); + result.opacityChannel = lTexture->UVSet.Get(); + } + + //For now only allow 1 texture + break; + } + } + + // reflection map... + const KFbxProperty lReflectionProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sReflection); + if (lReflectionProperty.IsValid()) + { + int lNbTex = lReflectionProperty.GetSrcObjectCount(KFbxTexture::ClassId); + for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) + { + KFbxTexture* lTexture = KFbxCast(lReflectionProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex)); + if (lTexture) + { + // support only spherical reflection maps... + if (KFbxTexture::eUMT_ENVIRONMENT == lTexture->GetMappingType()) + { + pOsgReflectionTex = fbxTextureToOsgTexture(lTexture); + result.reflectionTexture = pOsgReflectionTex.release(); + result.reflectionChannel = lTexture->UVSet.Get(); + } + } + + //For now only allow 1 texture + break; + } + } + + // emissive map... + const KFbxProperty lEmissiveProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sEmissive); + if (lEmissiveProperty.IsValid()) + { + int lNbTex = lEmissiveProperty.GetSrcObjectCount(KFbxTexture::ClassId); + for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) + { + KFbxTexture* lTexture = KFbxCast(lEmissiveProperty.GetSrcObject(KFbxTexture::ClassId, lTextureIndex)); + if (lTexture) + { + pOsgEmissiveTex = fbxTextureToOsgTexture(lTexture); + result.emissiveTexture = pOsgEmissiveTex.release(); + result.emissiveChannel = lTexture->UVSet.Get(); + } + + //For now only allow 1 texture + break; + } + } + if (pFbxLambert) { fbxDouble3 color = pFbxLambert->GetDiffuseColor().Get(); @@ -78,10 +161,28 @@ FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat) pOsgMat->setShininess(osg::Material::FRONT_AND_BACK, static_cast(pFbxPhong->GetShininess().Get())); + + // get maps factors... + result.diffuseFactor = pFbxPhong->GetDiffuseFactor().Get(); + result.reflectionFactor = pFbxPhong->GetReflectionFactor().Get(); + result.opacityFactor = pFbxPhong->GetTransparencyFactor().Get(); + // get more factors here... } } - StateSetContent result(pOsgMat.release(), pOsgTex.release()); - _kFbxMaterialMap.insert(KFbxMaterialMap::value_type(pFbxMat, result)); + + if (_lightmapTextures) + { + // if using an emission map then adjust material properties accordingly... + if (result.emissiveTexture) + { + osg::Vec4 diffuse = pOsgMat->getDiffuse(osg::Material::FRONT_AND_BACK); + pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, diffuse); + pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a())); + pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a())); + } + } + + _kFbxMaterialMap.insert(KFbxMaterialMap::value_type(pFbxMat, result)); return result; } @@ -117,7 +218,7 @@ void FbxMaterialToOsgStateSet::checkInvertTransparency() int zeroAlpha = 0, oneAlpha = 0; for (KFbxMaterialMap::const_iterator it = _kFbxMaterialMap.begin(); it != _kFbxMaterialMap.end(); ++it) { - const osg::Material* pMaterial = it->second.first; + const osg::Material* pMaterial = it->second.material.get(); float alpha = pMaterial->getDiffuse(osg::Material::FRONT).a(); if (alpha > 0.999f) { @@ -135,7 +236,7 @@ void FbxMaterialToOsgStateSet::checkInvertTransparency() for (KFbxMaterialMap::const_iterator it = _kFbxMaterialMap.begin(); it != _kFbxMaterialMap.end(); ++it) { - osg::Material* pMaterial = it->second.first; + osg::Material* pMaterial = it->second.material.get(); osg::Vec4 diffuse = pMaterial->getDiffuse(osg::Material::FRONT); diffuse.a() = 1.0f - diffuse.a(); pMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse); diff --git a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h index c89da51e0..fa70fdd77 100644 --- a/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h +++ b/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h @@ -15,9 +15,52 @@ //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. -typedef std::pair StateSetContent; -//We use the pointers setted by the importer to not duplicate materials and textures. +struct StateSetContent +{ + StateSetContent() + : diffuseFactor(1.0), + opacityFactor(1.0), + reflectionFactor(1.0), + emissiveFactor(1.0) + { + } + + osg::ref_ptr material; + + // textures objects... + osg::ref_ptr diffuseTexture; + osg::ref_ptr opacityTexture; + osg::ref_ptr reflectionTexture; + osg::ref_ptr emissiveTexture; + // more textures types here... + + // textures maps channels names... + std::string diffuseChannel; + std::string opacityChannel; + std::string reflectionChannel; + std::string emissiveChannel; + // more channels names here... + + // combining factors... + double diffuseFactor; + double opacityFactor; + double reflectionFactor; + double emissiveFactor; + // more combining factors here... + + // texture units (eventually used for each texture map)... + enum TextureUnit + { + DIFFUSE_TEXTURE_UNIT = 0, + OPACITY_TEXTURE_UNIT, + REFLECTION_TEXTURE_UNIT, + EMISSIVE_TEXTURE_UNIT, + // more texture units here... + }; +}; + +//We use the pointers set by the importer to not duplicate materials and textures. typedef std::map KFbxMaterialMap; //This map is used to not load the same image more than 1 time. @@ -30,9 +73,10 @@ public: StateSetContent convert(const KFbxSurfaceMaterial* pFbxMat); //dir is the directory where fbx is stored (for relative path). - FbxMaterialToOsgStateSet(const std::string& dir, const osgDB::Options* options) : + FbxMaterialToOsgStateSet(const std::string& dir, const osgDB::Options* options, bool lightmapTextures) : _options(options), - _dir(dir) {} + _dir(dir), + _lightmapTextures(lightmapTextures){} void checkInvertTransparency(); private: @@ -43,6 +87,7 @@ private: ImageMap _imageMap; const osgDB::Options* _options; const std::string _dir; + bool _lightmapTextures; }; diff --git a/src/osgPlugins/fbx/fbxRAnimation.cpp b/src/osgPlugins/fbx/fbxRAnimation.cpp index 17189fc52..848c7f380 100644 --- a/src/osgPlugins/fbx/fbxRAnimation.cpp +++ b/src/osgPlugins/fbx/fbxRAnimation.cpp @@ -11,6 +11,8 @@ #include #include +#include "fbxReader.h" + osg::Quat makeQuat(const fbxDouble3&, ERotationOrder); osg::Quat makeQuat(const osg::Vec3& radians, ERotationOrder fbxRotOrder) @@ -219,10 +221,7 @@ osgAnimation::Animation* readFbxAnimation(KFbxNode* pNode, return addChannels(pTranslationChannel, pRotationChannel, pScaleChannel, pAnimManager, pTakeName); } -std::string readFbxAnimation(KFbxNode* pNode, - KFbxScene& fbxScene, - osg::ref_ptr& pAnimManager, - const char* targetName) +std::string OsgFbxReader::readFbxAnimation(KFbxNode* pNode, const char* targetName) { std::string result; for (int i = 0; i < fbxScene.GetSrcObjectCount(FBX_TYPE(KFbxAnimStack)); ++i) @@ -240,8 +239,8 @@ std::string readFbxAnimation(KFbxNode* pNode, { KFbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(KFbxAnimLayer), j); - if (osgAnimation::Animation* pAnimation = readFbxAnimation( - pNode, pAnimLayer, pTakeName, targetName, pAnimManager)) + if (osgAnimation::Animation* pAnimation = ::readFbxAnimation( + pNode, pAnimLayer, pTakeName, targetName, pAnimationManager)) { result = targetName; } diff --git a/src/osgPlugins/fbx/fbxRAnimation.h b/src/osgPlugins/fbx/fbxRAnimation.h deleted file mode 100644 index f44c85bed..000000000 --- a/src/osgPlugins/fbx/fbxRAnimation.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef FBXRANIMATION_H -#define FBXRANIMATION_H - -#include - -std::string readFbxAnimation( - KFbxNode*, - KFbxScene& fbxScene, - osg::ref_ptr&, - const char* targetName); - -#endif diff --git a/src/osgPlugins/fbx/fbxRCamera.cpp b/src/osgPlugins/fbx/fbxRCamera.cpp index 87de1200d..a9814d905 100644 --- a/src/osgPlugins/fbx/fbxRCamera.cpp +++ b/src/osgPlugins/fbx/fbxRCamera.cpp @@ -8,9 +8,9 @@ #endif #include -#include "fbxRCamera.h" +#include "fbxReader.h" -osgDB::ReaderWriter::ReadResult readFbxCamera(KFbxNode* pNode) +osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxCamera(KFbxNode* pNode) { const KFbxCamera* fbxCamera = dynamic_cast(pNode->GetNodeAttribute()); diff --git a/src/osgPlugins/fbx/fbxRCamera.h b/src/osgPlugins/fbx/fbxRCamera.h deleted file mode 100644 index ea9a1a6b6..000000000 --- a/src/osgPlugins/fbx/fbxRCamera.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef FBXRCAMERA_H -#define FBXRCAMERA_H - -#include -#include - -osgDB::ReaderWriter::ReadResult readFbxCamera( - KFbxNode* pNode); - -#endif diff --git a/src/osgPlugins/fbx/fbxRLight.cpp b/src/osgPlugins/fbx/fbxRLight.cpp index f643f6090..6f06f112b 100644 --- a/src/osgPlugins/fbx/fbxRLight.cpp +++ b/src/osgPlugins/fbx/fbxRLight.cpp @@ -7,9 +7,9 @@ #endif #include -#include "fbxRLight.h" +#include "fbxReader.h" -osgDB::ReaderWriter::ReadResult readFbxLight(KFbxNode* pNode, int& nLightCount) +osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxLight(KFbxNode* pNode, int& nLightCount) { const KFbxLight* fbxLight = dynamic_cast(pNode->GetNodeAttribute()); diff --git a/src/osgPlugins/fbx/fbxRLight.h b/src/osgPlugins/fbx/fbxRLight.h deleted file mode 100644 index ff74d0134..000000000 --- a/src/osgPlugins/fbx/fbxRLight.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef FBXRLIGHT_H -#define FBXRLIGHT_H - -#include -#include - -osgDB::ReaderWriter::ReadResult readFbxLight( - KFbxNode* pNode, int& nLightCount); - -#endif diff --git a/src/osgPlugins/fbx/fbxRMesh.cpp b/src/osgPlugins/fbx/fbxRMesh.cpp index d57a6a1a5..a396d57aa 100644 --- a/src/osgPlugins/fbx/fbxRMesh.cpp +++ b/src/osgPlugins/fbx/fbxRMesh.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include @@ -19,8 +21,7 @@ #endif #include -#include "fbxRMesh.h" -#include "fbxRNode.h" +#include "fbxReader.h" enum GeometryType { @@ -138,7 +139,16 @@ osg::Array* createVec4Array(bool doublePrecision) osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, std::vector& stateSetList, - GeometryType gt, unsigned int mti, bool bNormal, bool bTexCoord, bool bColor, const osgDB::Options& options) + GeometryType gt, + unsigned int mti, + bool bNormal, + bool useDiffuseMap, + bool useOpacityMap, + bool useEmissiveMap, + // more here... + bool bColor, + const osgDB::Options& options, + bool lightmapTextures) { GeometryMap::iterator it = geometryMap.find(mti); @@ -161,30 +171,109 @@ osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap, pGeometry->setVertexData(osg::Geometry::ArrayData(createVec3Array((precision & osgDB::Options::DOUBLE_PRECISION_VERTEX) != 0), osg::Geometry::BIND_PER_VERTEX)); if (bNormal) pGeometry->setNormalData(osg::Geometry::ArrayData(createVec3Array((precision & osgDB::Options::DOUBLE_PRECISION_NORMAL) != 0), osg::Geometry::BIND_PER_VERTEX)); - if (bTexCoord) pGeometry->setTexCoordData(0, osg::Geometry::ArrayData(createVec2Array((precision & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0), osg::Geometry::BIND_PER_VERTEX)); + + // create as much textures coordinates as needed... + if (useDiffuseMap) + pGeometry->setTexCoordData(StateSetContent::DIFFUSE_TEXTURE_UNIT, osg::Geometry::ArrayData(createVec2Array((precision & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0), osg::Geometry::BIND_PER_VERTEX)); + if (useOpacityMap) + pGeometry->setTexCoordData(StateSetContent::OPACITY_TEXTURE_UNIT, osg::Geometry::ArrayData(createVec2Array((precision & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0), osg::Geometry::BIND_PER_VERTEX)); + if (useEmissiveMap) + pGeometry->setTexCoordData(StateSetContent::EMISSIVE_TEXTURE_UNIT, osg::Geometry::ArrayData(createVec2Array((precision & osgDB::Options::DOUBLE_PRECISION_TEX_COORD) != 0), osg::Geometry::BIND_PER_VERTEX)); + // create more textures coordinates here... + if (bColor) pGeometry->setColorData(osg::Geometry::ArrayData(createVec4Array((precision & osgDB::Options::DOUBLE_PRECISION_COLOR) != 0), osg::Geometry::BIND_PER_VERTEX)); if (mti < stateSetList.size()) { + osg::StateSet* stateSet = pGeometry->getOrCreateStateSet(); + bool transparent = false; - const StateSetContent& ss = stateSetList[mti]; - if (osg::Material* pMaterial = ss.first) + const StateSetContent& ssc = stateSetList[mti]; + + // set material... + if (osg::Material* pMaterial = ssc.material.get()) { - pGeometry->getOrCreateStateSet()->setAttributeAndModes(pMaterial); + stateSet->setAttributeAndModes(pMaterial); transparent = pMaterial->getDiffuse(osg::Material::FRONT).w() < 1.0f; } - if (osg::Texture2D* pTexture = ss.second) + + // diffuse texture map... + if (ssc.diffuseTexture) { - pGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, pTexture); - if (!transparent && pTexture->getImage()) - { - transparent = pTexture->getImage()->isImageTranslucent(); - } + stateSet->setTextureAttributeAndModes(StateSetContent::DIFFUSE_TEXTURE_UNIT, ssc.diffuseTexture.get()); + + if (lightmapTextures) + { + double factor = ssc.diffuseFactor; + osg::ref_ptr texenv = new osg::TexEnvCombine(); + texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); + texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); + texenv->setConstantColor(osg::Vec4(factor, factor, factor, factor)); + stateSet->setTextureAttributeAndModes(StateSetContent::DIFFUSE_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); + } + + // setup transparency + if (!transparent && ssc.diffuseTexture->getImage()) + transparent = ssc.diffuseTexture->getImage()->isImageTranslucent(); } + // opacity texture map... + if (ssc.opacityTexture) + { + stateSet->setTextureAttributeAndModes(StateSetContent::OPACITY_TEXTURE_UNIT, ssc.opacityTexture.get()); + + // 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. + double factor = ssc.opacityFactor; + osg::ref_ptr texenv = new osg::TexEnvCombine(); + texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); + texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); + texenv->setConstantColor(osg::Vec4(factor, factor, factor, factor)); + stateSet->setTextureAttributeAndModes(StateSetContent::OPACITY_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); + + // setup transparency... + if (!transparent && ssc.opacityTexture->getImage()) + transparent = ssc.opacityTexture->getImage()->isImageTranslucent(); + } + + // reflection texture map... + if (ssc.reflectionTexture) + { + stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, ssc.reflectionTexture.get()); + + // setup spherical map... + osg::ref_ptr texgen = new osg::TexGen(); + texgen->setMode(osg::TexGen::SPHERE_MAP); + stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, texgen.get(), osg::StateAttribute::ON); + + // setup combiner for factor... + double factor = ssc.reflectionFactor; + osg::ref_ptr texenv = new osg::TexEnvCombine(); + texenv->setCombine_RGB(osg::TexEnvCombine::INTERPOLATE); + texenv->setSource0_RGB(osg::TexEnvCombine::TEXTURE); + texenv->setSource1_RGB(osg::TexEnvCombine::PREVIOUS); + texenv->setSource2_RGB(osg::TexEnvCombine::CONSTANT); + texenv->setConstantColor(osg::Vec4(factor, factor, factor, factor)); + stateSet->setTextureAttributeAndModes(StateSetContent::REFLECTION_TEXTURE_UNIT, texenv.get(), osg::StateAttribute::ON); + } + + // emissive texture map + if (ssc.emissiveTexture) + { + stateSet->setTextureAttributeAndModes(StateSetContent::EMISSIVE_TEXTURE_UNIT, ssc.emissiveTexture.get()); + } + + // add more texture maps here... + if (transparent) { - pGeometry->getOrCreateStateSet()->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + stateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + stateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); } } @@ -348,41 +437,106 @@ void addColorArrayElement(osg::Array& a, const KFbxColor& c) } } -osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, - KFbxScene& fbxScene, - KFbxNode* pNode, KFbxMesh* fbxMesh, - osg::ref_ptr& pAnimationManager, +// scans StateSetList looking for the (first) channel name for the specified map type... +std::string getUVChannelForTextureMap(std::vector& stateSetList, const char* pName) +{ + // 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++) + { + if (0 == strcmp(pName, KFbxSurfaceMaterial::sDiffuse)) + return stateSetList[i].diffuseChannel; + if (0 == strcmp(pName, KFbxSurfaceMaterial::sTransparentColor)) + return stateSetList[i].opacityChannel; + if (0 == strcmp(pName, KFbxSurfaceMaterial::sReflection)) + return stateSetList[i].reflectionChannel; + if (0 == strcmp(pName, KFbxSurfaceMaterial::sEmissive)) + return stateSetList[i].emissiveChannel; + // more here... + } + + return ""; +} + +// scans mesh layers looking for the UV element corrensponding to the specified channel name... +const KFbxLayerElementUV* getUVElementForChannel(std::string pUVChannel, KFbxMesh* pFbxMesh) +{ + const KFbxLayer* pFbxLayer = 0; + const KFbxLayerElementUV* uv = 0; + + // scan layers for specified UV channel... + for (int cLayerIndex=0; cLayerIndex < pFbxMesh->GetLayerCount(); cLayerIndex++) + { + pFbxLayer = pFbxMesh->GetLayer(cLayerIndex); + if (!pFbxLayer) + continue; + + uv = pFbxLayer->GetUVs(); + if (uv) + { + if (0 == pUVChannel.compare(uv->GetName())) + return uv; + } + } + + return 0; +} + +osgDB::ReaderWriter::ReadResult OsgFbxReader::readMesh( + KFbxNode* pNode, + KFbxMesh* fbxMesh, std::vector& stateSetList, - const char* szName, - BindMatrixMap& boneBindMatrices, - const std::set& fbxSkeletons, - std::map& skeletonMap, - const osgDB::Options& options) + const char* szName) { GeometryMap geometryMap; osg::Geode* pGeode = new osg::Geode; pGeode->setName(szName); - const KFbxLayer* pFbxLayer = fbxMesh->GetLayer(0); + const KFbxLayer* pFbxLayer = 0; + const KFbxLayerElementNormal* pFbxNormals = 0; - const KFbxLayerElementUV* pFbxUVs = 0; const KFbxLayerElementVertexColor* pFbxColors = 0; const KFbxLayerElementMaterial* pFbxMaterials = 0; const KFbxVector4* pFbxVertices = fbxMesh->GetControlPoints(); - if (pFbxLayer) + // scan layers for Normals, Colors and Materials elements (this will get the first available elements)... + for (int cLayerIndex=0; cLayerIndex < fbxMesh->GetLayerCount(); cLayerIndex++) { - pFbxNormals = pFbxLayer->GetNormals(); - pFbxColors = pFbxLayer->GetVertexColors(); - pFbxUVs = pFbxLayer->GetUVs(); - pFbxMaterials = pFbxLayer->GetMaterials(); + pFbxLayer = fbxMesh->GetLayer(cLayerIndex); + if (!pFbxLayer) + continue; - if (!layerElementValid(pFbxNormals)) pFbxNormals = 0; - if (!layerElementValid(pFbxColors)) pFbxColors = 0; - if (!layerElementValid(pFbxUVs)) pFbxUVs = 0; - } + // get normals, colors and materials... + if (!pFbxNormals) + pFbxNormals = pFbxLayer->GetNormals(); + if (!pFbxColors) + pFbxColors = pFbxLayer->GetVertexColors(); + if (!pFbxMaterials) + pFbxMaterials = pFbxLayer->GetMaterials(); + } + + // 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);; + // 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); + // more UV elements here... + + // check elements validity... + if (!layerElementValid(pFbxNormals)) pFbxNormals = 0; + if (!layerElementValid(pFbxColors)) pFbxColors = 0; + + if (!layerElementValid(pFbxUVs_diffuse)) pFbxUVs_diffuse = 0; + if (!layerElementValid(pFbxUVs_opacity)) pFbxUVs_opacity = 0; + if (!layerElementValid(pFbxUVs_emissive)) pFbxUVs_emissive = 0; + // more here... int nPolys = fbxMesh->GetPolygonCount(); @@ -415,11 +569,24 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, osg::Geometry* pGeometry = getGeometry(pGeode, geometryMap, stateSetList, geomType, materialIndex, - pFbxNormals != 0, pFbxUVs != 0, pFbxColors != 0, options); + pFbxNormals != 0, + pFbxUVs_diffuse != 0, + pFbxUVs_opacity != 0, + pFbxUVs_emissive != 0, + // more UV elements here... + pFbxColors != 0, + options, + lightmapTextures); osg::Array* pVertices = pGeometry->getVertexArray(); osg::Array* pNormals = pGeometry->getNormalArray(); - osg::Array* pTexCoords = pGeometry->getTexCoordArray(0); + + // get texture coordinates... + 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); + // more texture coordinates here... + osg::Array* pColors = pGeometry->getColorArray(); int nVertex0 = nVertex; @@ -455,12 +622,29 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, addVec3ArrayElement(*pNormals, pFbxNormals->GetDirectArray().GetAt(n2)); } - if (pTexCoords) + // add texture maps data (avoid duplicates)... + if (pTexCoords_diffuse) { - addVec2ArrayElement(*pTexCoords, getElement(pFbxUVs, fbxMesh, i, 0, nVertex0)); - addVec2ArrayElement(*pTexCoords, getElement(pFbxUVs, fbxMesh, i, j - 1, nVertex - 1)); - addVec2ArrayElement(*pTexCoords, getElement(pFbxUVs, fbxMesh, i, j, nVertex)); + addVec2ArrayElement(*pTexCoords_diffuse, getElement(pFbxUVs_diffuse, fbxMesh, i, 0, nVertex0)); + addVec2ArrayElement(*pTexCoords_diffuse, getElement(pFbxUVs_diffuse, fbxMesh, i, j - 1, nVertex - 1)); + addVec2ArrayElement(*pTexCoords_diffuse, getElement(pFbxUVs_diffuse, fbxMesh, i, j, nVertex)); } + if (pTexCoords_opacity && (pTexCoords_opacity != pTexCoords_diffuse)) + { + addVec2ArrayElement(*pTexCoords_opacity, getElement(pFbxUVs_opacity, fbxMesh, i, 0, nVertex0)); + addVec2ArrayElement(*pTexCoords_opacity, getElement(pFbxUVs_opacity, fbxMesh, i, j - 1, nVertex - 1)); + addVec2ArrayElement(*pTexCoords_opacity, getElement(pFbxUVs_opacity, fbxMesh, i, j, nVertex)); + } + + // Only spherical reflection maps are supported (so do not add coordinates for the reflection map) + + if (pTexCoords_emissive && (pTexCoords_emissive != pTexCoords_opacity) && (pTexCoords_emissive != pTexCoords_diffuse)) + { + addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, 0, nVertex0)); + addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, j - 1, nVertex - 1)); + addVec2ArrayElement(*pTexCoords_emissive, getElement(pFbxUVs_emissive, fbxMesh, i, j, nVertex)); + } + // add more texture maps here... if (pColors) { @@ -701,15 +885,8 @@ osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager, return osgDB::ReaderWriter::ReadResult(pResult); } -osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxSdkManager& pSdkManager, - KFbxScene& fbxScene, - KFbxNode* pNode, - osg::ref_ptr& pAnimationManager, - std::vector& stateSetList, - BindMatrixMap& boneBindMatrices, - const std::set& fbxSkeletons, - std::map& skeletonMap, - const osgDB::Options& options) +osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxMesh(KFbxNode* pNode, + std::vector& stateSetList) { KFbxMesh* lMesh = dynamic_cast(pNode->GetNodeAttribute()); @@ -718,6 +895,6 @@ osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxSdkManager& pSdkManager, return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE; } - return readMesh(pSdkManager, fbxScene, pNode, lMesh, pAnimationManager, stateSetList, - pNode->GetName(), boneBindMatrices, fbxSkeletons, skeletonMap, options); -} + return readMesh(pNode, lMesh, stateSetList, + pNode->GetName()); +} \ No newline at end of file diff --git a/src/osgPlugins/fbx/fbxRMesh.h b/src/osgPlugins/fbx/fbxRMesh.h deleted file mode 100644 index 3601f4651..000000000 --- a/src/osgPlugins/fbx/fbxRMesh.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef FBXRMESH_H -#define FBXRMESH_H - -#include -#include -#include -#include "fbxRNode.h" -osgDB::ReaderWriter::ReadResult readFbxMesh( - KFbxSdkManager& pSdkManager, - KFbxScene& fbxScene, - KFbxNode* pNode, - osg::ref_ptr& pAnimationManager, - std::vector&, - BindMatrixMap& boneBindMatrices, - const std::set& fbxSkeletons, - std::map& skeletonMap, - const osgDB::Options&); - -#endif diff --git a/src/osgPlugins/fbx/fbxRNode.cpp b/src/osgPlugins/fbx/fbxRNode.cpp index f80f496a2..a269fdd9c 100644 --- a/src/osgPlugins/fbx/fbxRNode.cpp +++ b/src/osgPlugins/fbx/fbxRNode.cpp @@ -25,12 +25,7 @@ #endif #include -#include "fbxRAnimation.h" -#include "fbxRCamera.h" -#include "fbxRLight.h" -#include "fbxRMesh.h" -#include "fbxRNode.h" -#include "fbxMaterialToOsgStateSet.h" +#include "fbxReader.h" osg::Quat makeQuat(const fbxDouble3& degrees, ERotationOrder fbxRotOrder) { @@ -317,18 +312,9 @@ osg::Group* createGroupNode(KFbxSdkManager& pSdkManager, KFbxNode* pNode, } } -osgDB::ReaderWriter::ReadResult readFbxNode( - KFbxSdkManager& pSdkManager, - KFbxScene& fbxScene, +osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxNode( KFbxNode* pNode, - osg::ref_ptr& pAnimationManager, - bool& bIsBone, int& nLightCount, - FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet, - std::map& nodeMap, - BindMatrixMap& boneBindMatrices, - const std::set& fbxSkeletons, - std::map& skeletonMap, - const osgDB::Options& options) + bool& bIsBone, int& nLightCount) { if (KFbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute()) { @@ -383,9 +369,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode( bool bChildIsBone = false; osgDB::ReaderWriter::ReadResult childResult = readFbxNode( - pSdkManager, fbxScene, pChildNode, pAnimationManager, - bChildIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap, - boneBindMatrices, fbxSkeletons, skeletonMap, options); + pChildNode, bChildIsBone, nLightCount); if (childResult.error()) { return childResult; @@ -404,7 +388,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode( } } - std::string animName = readFbxAnimation(pNode, fbxScene, pAnimationManager, pNode->GetName()); + std::string animName = readFbxAnimation(pNode, pNode->GetName()); osg::Matrix localMatrix; makeLocalMatrix(pNode, localMatrix); @@ -419,9 +403,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode( case KFbxNodeAttribute::eMESH: { size_t bindMatrixCount = boneBindMatrices.size(); - osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pSdkManager, fbxScene, - pNode, pAnimationManager, stateSetList, boneBindMatrices, - fbxSkeletons, skeletonMap, options); + osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pNode, stateSetList); if (meshRes.error()) { return meshRes; @@ -485,7 +467,7 @@ osgDB::ReaderWriter::ReadResult readFbxNode( osg::Group* pAddChildrenTo = osgGroup.get(); if (bCreateSkeleton) - { + { osgAnimation::Skeleton* osgSkeleton = getSkeleton(pNode, fbxSkeletons, skeletonMap); osgSkeleton->setDefaultUpdateCallback(); pAddChildrenTo->addChild(osgSkeleton); diff --git a/src/osgPlugins/fbx/fbxRNode.h b/src/osgPlugins/fbx/fbxRNode.h deleted file mode 100644 index 6eb3e1538..000000000 --- a/src/osgPlugins/fbx/fbxRNode.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef FBXRNODE_H -#define FBXRNODE_H - -#include "fbxMaterialToOsgStateSet.h" -namespace osgAnimation -{ - class AnimationManagerBase; - class RigGeometry; -} - -typedef std::map, osg::Matrix> BindMatrixMap; - -osgAnimation::Skeleton* getSkeleton(KFbxNode*, - const std::set& fbxSkeletons, - std::map&); - -osgDB::ReaderWriter::ReadResult readFbxNode( - KFbxSdkManager& pSdkManager, - KFbxScene& fbxScene, - KFbxNode* pNode, - osg::ref_ptr& pAnimationManager, - bool& bIsBone, - int& nLightCount, - FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet, - std::map& nodeMap, - BindMatrixMap& boneBindMatrices, - const std::set& fbxSkeletons, - std::map& skeletonMap, - const osgDB::Options&); - -#endif diff --git a/src/osgPlugins/fbx/fbxReader.h b/src/osgPlugins/fbx/fbxReader.h new file mode 100644 index 000000000..2a2710a64 --- /dev/null +++ b/src/osgPlugins/fbx/fbxReader.h @@ -0,0 +1,82 @@ +#ifndef FBXRANIMATION_H +#define FBXRANIMATION_H + +#include +#include +#include +#include "fbxMaterialToOsgStateSet.h" + +namespace osgAnimation +{ + class AnimationManagerBase; + class RigGeometry; + class Skeleton; +} + +typedef std::map, osg::Matrix> BindMatrixMap; + +class OsgFbxReader +{ +public: + KFbxSdkManager& pSdkManager; + KFbxScene& fbxScene; + osg::ref_ptr pAnimationManager; + FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet; + std::map nodeMap; + BindMatrixMap boneBindMatrices; + const std::set& fbxSkeletons; + std::map skeletonMap; + const osgDB::Options& options; + bool lightmapTextures; + + enum AuthoringTool + { + UNKNOWN, + OPENSCENEGRAPH, + AUTODESK_3DSTUDIO_MAX + } authoringTool; + + OsgFbxReader( + KFbxSdkManager& pSdkManager1, + KFbxScene& fbxScene1, + FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet1, + const std::set& fbxSkeletons1, + const osgDB::Options& options1, + AuthoringTool authoringTool1, + bool lightmapTextures1) + : pSdkManager(pSdkManager1), + fbxScene(fbxScene1), + fbxMaterialToOsgStateSet(fbxMaterialToOsgStateSet1), + fbxSkeletons(fbxSkeletons1), + options(options1), + authoringTool(authoringTool1), + lightmapTextures(lightmapTextures1) + {} + + osgDB::ReaderWriter::ReadResult readFbxNode( + KFbxNode*, bool& bIsBone, int& nLightCount); + + std::string readFbxAnimation( + KFbxNode*, const char* targetName); + + osgDB::ReaderWriter::ReadResult readFbxCamera( + KFbxNode* pNode); + + osgDB::ReaderWriter::ReadResult readFbxLight( + KFbxNode* pNode, int& nLightCount); + + osgDB::ReaderWriter::ReadResult readMesh( + KFbxNode* pNode, KFbxMesh* fbxMesh, + std::vector& stateSetList, + const char* szName); + + osgDB::ReaderWriter::ReadResult readFbxMesh( + KFbxNode* pNode, + std::vector&); +}; + +osgAnimation::Skeleton* getSkeleton(KFbxNode*, + const std::set& fbxSkeletons, + std::map&); + +#endif