Index: /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/ReaderWriterFBX.cpp
===================================================================
--- /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/ReaderWriterFBX.cpp (revision 11214)
+++ /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/ReaderWriterFBX.cpp (revision 11264)
@@ -1,5 +1,4 @@
 #include <sstream>
 #include <memory>
-#include <cassert>
 
 #include <osg/Notify>
@@ -99,4 +98,28 @@
 };
 
+//Some files don't correctly mark their skeleton nodes, so this function infers
+//them from the nodes that skin deformers linked to.
+void findLinkedFbxSkeletonNodes(KFbxNode* pNode, std::set<const KFbxNode*>& fbxSkeletons)
+{
+    if (const KFbxGeometry* pMesh = dynamic_cast<const KFbxGeometry*>(pNode->GetNodeAttribute()))
+    {
+        for (int i = 0; i < pMesh->GetDeformerCount(KFbxDeformer::eSKIN); ++i)
+        {
+            const KFbxSkin* pSkin = (const KFbxSkin*)pMesh->GetDeformer(i, KFbxDeformer::eSKIN);
+
+            for (int j = 0; j < pSkin->GetClusterCount(); ++j)
+            {
+                const KFbxNode* pSkeleton = pSkin->GetCluster(j)->GetLink();
+                fbxSkeletons.insert(pSkeleton);
+            }
+        }
+    }
+
+    for (int i = 0; i < pNode->GetChildCount(); ++i)
+    {
+        findLinkedFbxSkeletonNodes(pNode->GetChild(i), fbxSkeletons);
+    }
+}
+
 void resolveBindMatrices(
     osg::Node& root,
@@ -143,5 +166,5 @@
 
                     osgAnimation::RigGeometry* pRigGeometry = it->first.second;
-                    
+
                     osgAnimation::VertexInfluenceMap* vertexInfluences = pRigGeometry->getInfluenceMap();
 
@@ -158,5 +181,5 @@
                     else
                     {
-                        assert(0);
+                        osg::notify(osg::WARN) << "No vertex influences found for \"" << osgBone.getName() << "\"" << std::endl;
                     }
                 }
@@ -165,5 +188,6 @@
         else
         {
-            assert(0);
+            osg::notify(osg::WARN) << "No bone found for \"" << fbxBone->GetName() << "\"" << std::endl;
+            ++it;
         }
     }
@@ -262,4 +286,7 @@
             FbxMaterialToOsgStateSet fbxMaterialToOsgStateSet(filePath, localOptions.get());
 
+            std::set<const KFbxNode*> fbxSkeletons;
+            findLinkedFbxSkeletonNodes(pNode, fbxSkeletons);
+
             std::map<KFbxNode*, osg::Node*> nodeMap;
             BindMatrixMap boneBindMatrices;
@@ -267,8 +294,10 @@
             ReadResult res = readFbxNode(*pSdkManager, pNode, pAnimationManager,
                 bIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap,
-                boneBindMatrices, skeletonMap, localOptions.get());
+                boneBindMatrices, fbxSkeletons, skeletonMap, localOptions.get());
 
             if (res.success())
             {
+                fbxMaterialToOsgStateSet.checkInvertTransparency();
+
                 resolveBindMatrices(*res.getNode(), boneBindMatrices, nodeMap);
 
Index: /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRNode.cpp
===================================================================
--- /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRNode.cpp (revision 11213)
+++ /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRNode.cpp (revision 11264)
@@ -325,4 +325,5 @@
     std::map<KFbxNode*, osg::Node*>& nodeMap,
     BindMatrixMap& boneBindMatrices,
+    const std::set<const KFbxNode*>& fbxSkeletons,
     std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
     const osgDB::ReaderWriter::Options* options)
@@ -349,4 +350,9 @@
             bIsBone = true;
         }
+    }
+
+    if (!bIsBone && fbxSkeletons.find(pNode) != fbxSkeletons.end())
+    {
+        bIsBone = true;
     }
 
@@ -378,5 +384,5 @@
             pSdkManager, pChildNode, pAnimationManager,
             bChildIsBone, nLightCount, fbxMaterialToOsgStateSet, nodeMap,
-            boneBindMatrices, skeletonMap, options);
+            boneBindMatrices, fbxSkeletons, skeletonMap, options);
         if (childResult.error())
         {
@@ -426,5 +432,6 @@
             size_t bindMatrixCount = boneBindMatrices.size();
             osgDB::ReaderWriter::ReadResult meshRes = readFbxMesh(pSdkManager,
-                pNode, pAnimationManager, stateSetList, boneBindMatrices, skeletonMap);
+                pNode, pAnimationManager, stateSetList, boneBindMatrices,
+                fbxSkeletons, skeletonMap);
             if (meshRes.error())
             {
@@ -491,5 +498,5 @@
     if (bCreateSkeleton)
     {
-        osgAnimation::Skeleton* osgSkeleton = getSkeleton(pNode, skeletonMap);
+        osgAnimation::Skeleton* osgSkeleton = getSkeleton(pNode, fbxSkeletons, skeletonMap);
         osgSkeleton->setDefaultUpdateCallback();
         pAddChildrenTo->addChild(osgSkeleton);
@@ -511,10 +518,12 @@
 
 osgAnimation::Skeleton* getSkeleton(KFbxNode* fbxNode,
+    const std::set<const KFbxNode*>& fbxSkeletons,
     std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
 {
     //Find the first non-skeleton ancestor of the node.
     while (fbxNode &&
-        fbxNode->GetNodeAttribute() &&
-        fbxNode->GetNodeAttribute()->GetAttributeType() == KFbxNodeAttribute::eSKELETON)
+        ((fbxNode->GetNodeAttribute() &&
+        fbxNode->GetNodeAttribute()->GetAttributeType() == KFbxNodeAttribute::eSKELETON) ||
+        fbxSkeletons.find(fbxNode) != fbxSkeletons.end()))
     {
         fbxNode = fbxNode->GetParent();
Index: /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRNode.h
===================================================================
--- /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRNode.h (revision 11213)
+++ /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRNode.h (revision 11264)
@@ -11,5 +11,7 @@
 typedef std::map<std::pair<KFbxNode*, osgAnimation::RigGeometry*>, osg::Matrix> BindMatrixMap;
 
-osgAnimation::Skeleton* getSkeleton(KFbxNode*, std::map<KFbxNode*, osgAnimation::Skeleton*>&);
+osgAnimation::Skeleton* getSkeleton(KFbxNode*,
+    const std::set<const KFbxNode*>& fbxSkeletons,
+    std::map<KFbxNode*, osgAnimation::Skeleton*>&);
 
 osgDB::ReaderWriter::ReadResult readFbxNode(
@@ -22,4 +24,5 @@
     std::map<KFbxNode*, osg::Node*>& nodeMap,
     BindMatrixMap& boneBindMatrices,
+    const std::set<const KFbxNode*>& fbxSkeletons,
     std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
     const osgDB::ReaderWriter::Options* options = NULL);
Index: /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRMesh.cpp
===================================================================
--- /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRMesh.cpp (revision 11213)
+++ /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRMesh.cpp (revision 11264)
@@ -293,4 +293,5 @@
     const char* szName,
     BindMatrixMap& boneBindMatrices,
+    const std::set<const KFbxNode*>& fbxSkeletons,
     std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
 {
@@ -300,5 +301,5 @@
     pGeode->setName(szName);
 
-    const KFbxLayer* pFbxLayer = 0;
+    const KFbxLayer* pFbxLayer = fbxMesh->GetLayer(0);
     const KFbxLayerElementNormal* pFbxNormals = 0;
     const KFbxLayerElementUV* pFbxUVs = 0;
@@ -308,5 +309,5 @@
     const KFbxVector4* pFbxVertices = fbxMesh->GetControlPoints();
 
-    if (pFbxLayer = fbxMesh->GetLayer(0))
+    if (pFbxLayer)
     {
         pFbxNormals = pFbxLayer->GetNormals();
@@ -615,5 +616,6 @@
         if (pSkin->GetClusterCount())
         {
-            osgAnimation::Skeleton* pSkeleton = getSkeleton(pSkin->GetCluster(0)->GetLink(), skeletonMap);
+            osgAnimation::Skeleton* pSkeleton = getSkeleton(
+                pSkin->GetCluster(0)->GetLink(), fbxSkeletons, skeletonMap);
             pSkeleton->addChild(pResult);
             return osgDB::ReaderWriter::ReadResult::FILE_LOADED;
@@ -629,4 +631,5 @@
     std::vector<StateSetContent>& stateSetList,
     BindMatrixMap& boneBindMatrices,
+    const std::set<const KFbxNode*>& fbxSkeletons,
     std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
 {
@@ -639,4 +642,4 @@
 
     return readMesh(pSdkManager, pNode, lMesh, pAnimationManager, stateSetList,
-        pNode->GetName(), boneBindMatrices, skeletonMap);
-}
+        pNode->GetName(), boneBindMatrices, fbxSkeletons, skeletonMap);
+}
Index: /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRMesh.h
===================================================================
--- /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRMesh.h (revision 11213)
+++ /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRMesh.h (revision 11264)
@@ -12,4 +12,5 @@
     std::vector<StateSetContent>&,
     BindMatrixMap& boneBindMatrices,
+    const std::set<const KFbxNode*>& fbxSkeletons,
     std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap);
 
Index: /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp
===================================================================
--- /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp (revision 11213)
+++ /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.cpp (revision 11264)
@@ -81,5 +81,7 @@
         }
     }
-    return std::make_pair(pOsgMat.release(), pOsgTex.release());
+    StateSetContent result(pOsgMat.release(), pOsgTex.release());
+    _kFbxMaterialMap.insert(KFbxMaterialMap::value_type(pFbxMat, result));
+    return result;
 }
 
@@ -110,2 +112,33 @@
     }
 }
+
+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;
+        float alpha = pMaterial->getDiffuse(osg::Material::FRONT).a();
+        if (alpha > 0.999f)
+        {
+            ++oneAlpha;
+        }
+        else if (alpha < 0.001f)
+        {
+            ++zeroAlpha;
+        }
+    }
+
+    if (zeroAlpha > oneAlpha)
+    {
+        //Transparency values seem to be back to front so invert them.
+
+        for (KFbxMaterialMap::const_iterator it = _kFbxMaterialMap.begin(); it != _kFbxMaterialMap.end(); ++it)
+        {
+            osg::Material* pMaterial = it->second.first;
+            osg::Vec4 diffuse = pMaterial->getDiffuse(osg::Material::FRONT);
+            diffuse.a() = 1.0f - diffuse.a();
+            pMaterial->setDiffuse(osg::Material::FRONT_AND_BACK, diffuse);
+        }
+    }
+}
Index: /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h
===================================================================
--- /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h (revision 11213)
+++ /OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxMaterialToOsgStateSet.h (revision 11264)
@@ -34,4 +34,6 @@
         _options(options),
         _dir(dir) {}
+
+    void checkInvertTransparency();
 private:
     //Convert a texture fbx to an osg texture.
