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.
This commit is contained in:
parent
af3bc7903e
commit
359b6b480d
@ -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)
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <osg/Material>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/Version>
|
||||
#include <osgDB/ConvertUTF>
|
||||
#include <osgDB/FileNameUtils>
|
||||
#include <osgDB/FileUtils>
|
||||
@ -23,8 +24,7 @@
|
||||
#include <fbxsdk.h>
|
||||
|
||||
#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<osgAnimation::AnimationManagerBase> pAnimationManager;
|
||||
bool bIsBone = false;
|
||||
int nLightCount = 0;
|
||||
osg::ref_ptr<Options> 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<const KFbxNode*> fbxSkeletons;
|
||||
findLinkedFbxSkeletonNodes(pNode, fbxSkeletons);
|
||||
|
||||
std::map<KFbxNode*, osg::Node*> nodeMap;
|
||||
BindMatrixMap boneBindMatrices;
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*> 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<osg::Node&>(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);
|
||||
|
||||
|
@ -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"; }
|
||||
|
@ -18,12 +18,26 @@ FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* pFbxMat)
|
||||
if (it != _kFbxMaterialMap.end())
|
||||
return it->second;
|
||||
static int nbMat = 0;
|
||||
|
||||
osg::ref_ptr<osg::Material> pOsgMat = new osg::Material;
|
||||
osg::ref_ptr<osg::Texture2D> pOsgTex = NULL;
|
||||
pOsgMat->setName(pFbxMat->GetName());
|
||||
|
||||
// texture maps...
|
||||
osg::ref_ptr<osg::Texture2D> pOsgDiffuseTex = NULL;
|
||||
osg::ref_ptr<osg::Texture2D> pOsgReflectionTex = NULL;
|
||||
osg::ref_ptr<osg::Texture2D> pOsgOpacityTex = NULL;
|
||||
osg::ref_ptr<osg::Texture2D> pOsgEmissiveTex = NULL;
|
||||
// add more maps here...
|
||||
|
||||
StateSetContent result;
|
||||
|
||||
result.material = pOsgMat;
|
||||
|
||||
fbxString shadingModel = pFbxMat->GetShadingModel().Get();
|
||||
|
||||
const KFbxSurfaceLambert* pFbxLambert = dynamic_cast<const KFbxSurfaceLambert*>(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<KFbxTexture>(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<KFbxTexture>(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<KFbxTexture>(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<KFbxTexture>(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<float>(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);
|
||||
|
@ -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<osg::Material *, osg::Texture2D *> 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<osg::Material> material;
|
||||
|
||||
// textures objects...
|
||||
osg::ref_ptr<osg::Texture2D> diffuseTexture;
|
||||
osg::ref_ptr<osg::Texture2D> opacityTexture;
|
||||
osg::ref_ptr<osg::Texture2D> reflectionTexture;
|
||||
osg::ref_ptr<osg::Texture2D> 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<const KFbxSurfaceMaterial *, StateSetContent> 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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <fbxsdk.h>
|
||||
#include <fbxfilesdk/fbxfilesdk_nsuse.h>
|
||||
|
||||
#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<osgAnimation::AnimationManagerBase>& 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;
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
#ifndef FBXRANIMATION_H
|
||||
#define FBXRANIMATION_H
|
||||
|
||||
#include <fbxfilesdk/fbxfilesdk_def.h>
|
||||
|
||||
std::string readFbxAnimation(
|
||||
KFbxNode*,
|
||||
KFbxScene& fbxScene,
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>&,
|
||||
const char* targetName);
|
||||
|
||||
#endif
|
@ -8,9 +8,9 @@
|
||||
#endif
|
||||
#include <fbxsdk.h>
|
||||
|
||||
#include "fbxRCamera.h"
|
||||
#include "fbxReader.h"
|
||||
|
||||
osgDB::ReaderWriter::ReadResult readFbxCamera(KFbxNode* pNode)
|
||||
osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxCamera(KFbxNode* pNode)
|
||||
{
|
||||
const KFbxCamera* fbxCamera = dynamic_cast<const KFbxCamera*>(pNode->GetNodeAttribute());
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
#ifndef FBXRCAMERA_H
|
||||
#define FBXRCAMERA_H
|
||||
|
||||
#include <fbxfilesdk/fbxfilesdk_def.h>
|
||||
#include <osgDB/ReaderWriter>
|
||||
|
||||
osgDB::ReaderWriter::ReadResult readFbxCamera(
|
||||
KFbxNode* pNode);
|
||||
|
||||
#endif
|
@ -7,9 +7,9 @@
|
||||
#endif
|
||||
#include <fbxsdk.h>
|
||||
|
||||
#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<const KFbxLight*>(pNode->GetNodeAttribute());
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
#ifndef FBXRLIGHT_H
|
||||
#define FBXRLIGHT_H
|
||||
|
||||
#include <fbxfilesdk/fbxfilesdk_def.h>
|
||||
#include <osgDB/ReaderWriter>
|
||||
|
||||
osgDB::ReaderWriter::ReadResult readFbxLight(
|
||||
KFbxNode* pNode, int& nLightCount);
|
||||
|
||||
#endif
|
@ -5,6 +5,8 @@
|
||||
#include <osg/Geode>
|
||||
#include <osg/Image>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osg/TexGen>
|
||||
#include <osg/TexEnvCombine>
|
||||
|
||||
#include <osgUtil/TriStripVisitor>
|
||||
|
||||
@ -19,8 +21,7 @@
|
||||
#endif
|
||||
#include <fbxsdk.h>
|
||||
|
||||
#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<StateSetContent>& 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<osg::TexEnvCombine> 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<osg::TexEnvCombine> 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<osg::TexGen> 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<osg::TexEnvCombine> 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<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
// scans StateSetList looking for the (first) channel name for the specified map type...
|
||||
std::string getUVChannelForTextureMap(std::vector<StateSetContent>& 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<StateSetContent>& stateSetList,
|
||||
const char* szName,
|
||||
BindMatrixMap& boneBindMatrices,
|
||||
const std::set<const KFbxNode*>& fbxSkeletons,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& 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<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
std::vector<StateSetContent>& stateSetList,
|
||||
BindMatrixMap& boneBindMatrices,
|
||||
const std::set<const KFbxNode*>& fbxSkeletons,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
|
||||
const osgDB::Options& options)
|
||||
osgDB::ReaderWriter::ReadResult OsgFbxReader::readFbxMesh(KFbxNode* pNode,
|
||||
std::vector<StateSetContent>& stateSetList)
|
||||
{
|
||||
KFbxMesh* lMesh = dynamic_cast<KFbxMesh*>(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());
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#ifndef FBXRMESH_H
|
||||
#define FBXRMESH_H
|
||||
|
||||
#include <fbxfilesdk/fbxfilesdk_def.h>
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osg/Material>
|
||||
#include "fbxRNode.h"
|
||||
osgDB::ReaderWriter::ReadResult readFbxMesh(
|
||||
KFbxSdkManager& pSdkManager,
|
||||
KFbxScene& fbxScene,
|
||||
KFbxNode* pNode,
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
std::vector<StateSetContent>&,
|
||||
BindMatrixMap& boneBindMatrices,
|
||||
const std::set<const KFbxNode*>& fbxSkeletons,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
|
||||
const osgDB::Options&);
|
||||
|
||||
#endif
|
@ -25,12 +25,7 @@
|
||||
#endif
|
||||
#include <fbxsdk.h>
|
||||
|
||||
#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<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
bool& bIsBone, int& nLightCount,
|
||||
FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet,
|
||||
std::map<KFbxNode*, osg::Node*>& nodeMap,
|
||||
BindMatrixMap& boneBindMatrices,
|
||||
const std::set<const KFbxNode*>& fbxSkeletons,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& 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);
|
||||
|
@ -1,31 +0,0 @@
|
||||
#ifndef FBXRNODE_H
|
||||
#define FBXRNODE_H
|
||||
|
||||
#include "fbxMaterialToOsgStateSet.h"
|
||||
namespace osgAnimation
|
||||
{
|
||||
class AnimationManagerBase;
|
||||
class RigGeometry;
|
||||
}
|
||||
|
||||
typedef std::map<std::pair<KFbxNode*, osgAnimation::RigGeometry*>, osg::Matrix> BindMatrixMap;
|
||||
|
||||
osgAnimation::Skeleton* getSkeleton(KFbxNode*,
|
||||
const std::set<const KFbxNode*>& fbxSkeletons,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>&);
|
||||
|
||||
osgDB::ReaderWriter::ReadResult readFbxNode(
|
||||
KFbxSdkManager& pSdkManager,
|
||||
KFbxScene& fbxScene,
|
||||
KFbxNode* pNode,
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
|
||||
bool& bIsBone,
|
||||
int& nLightCount,
|
||||
FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet,
|
||||
std::map<KFbxNode*, osg::Node*>& nodeMap,
|
||||
BindMatrixMap& boneBindMatrices,
|
||||
const std::set<const KFbxNode*>& fbxSkeletons,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap,
|
||||
const osgDB::Options&);
|
||||
|
||||
#endif
|
82
src/osgPlugins/fbx/fbxReader.h
Normal file
82
src/osgPlugins/fbx/fbxReader.h
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef FBXRANIMATION_H
|
||||
#define FBXRANIMATION_H
|
||||
|
||||
#include <fbxfilesdk/fbxfilesdk_def.h>
|
||||
#include <osgDB/ReaderWriter>
|
||||
#include <osgAnimation/BasicAnimationManager>
|
||||
#include "fbxMaterialToOsgStateSet.h"
|
||||
|
||||
namespace osgAnimation
|
||||
{
|
||||
class AnimationManagerBase;
|
||||
class RigGeometry;
|
||||
class Skeleton;
|
||||
}
|
||||
|
||||
typedef std::map<std::pair<KFbxNode*, osgAnimation::RigGeometry*>, osg::Matrix> BindMatrixMap;
|
||||
|
||||
class OsgFbxReader
|
||||
{
|
||||
public:
|
||||
KFbxSdkManager& pSdkManager;
|
||||
KFbxScene& fbxScene;
|
||||
osg::ref_ptr<osgAnimation::AnimationManagerBase> pAnimationManager;
|
||||
FbxMaterialToOsgStateSet& fbxMaterialToOsgStateSet;
|
||||
std::map<KFbxNode*, osg::Node*> nodeMap;
|
||||
BindMatrixMap boneBindMatrices;
|
||||
const std::set<const KFbxNode*>& fbxSkeletons;
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*> 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<const KFbxNode*>& 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<StateSetContent>& stateSetList,
|
||||
const char* szName);
|
||||
|
||||
osgDB::ReaderWriter::ReadResult readFbxMesh(
|
||||
KFbxNode* pNode,
|
||||
std::vector<StateSetContent>&);
|
||||
};
|
||||
|
||||
osgAnimation::Skeleton* getSkeleton(KFbxNode*,
|
||||
const std::set<const KFbxNode*>& fbxSkeletons,
|
||||
std::map<KFbxNode*, osgAnimation::Skeleton*>&);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user