root/OpenSceneGraph/branches/OpenSceneGraph-2.8/src/osgPlugins/fbx/fbxRMesh.cpp @ 11213

Revision 11213, 22.2 kB (checked in by paulmartz, 5 years ago)

Backport FBX plugin to 2.8 branch. Modified FBX to use the old osgDB::ReaderWriter::Options namespace. This commit includes a merge of r11111 (osgDB UTF mods).

  • Property svn:mime-type set to text/x-cpp
  • Property svn:eol-style set to native
Line 
1#include <cassert>
2#include <sstream>
3
4#include <osg/BlendFunc>
5#include <osg/Geode>
6#include <osg/Image>
7#include <osg/MatrixTransform>
8
9#include <osgUtil/TriStripVisitor>
10
11#include <osgDB/ReadFile>
12
13#include <osgAnimation/RigGeometry>
14#include <osgAnimation/MorphGeometry>
15#include <osgAnimation/BasicAnimationManager>
16
17#if defined(_MSC_VER)
18#pragma warning( disable : 4505 )
19#endif
20#include <fbxsdk.h>
21
22#include "fbxRMesh.h"
23#include "fbxRNode.h"
24
25enum GeometryType
26{
27    GEOMETRY_STATIC,
28    GEOMETRY_RIG,
29    GEOMETRY_MORPH
30};
31
32osg::Vec3 convertVec3(const KFbxVector4& v)
33{
34    return osg::Vec3(
35        static_cast<float>(v[0]),
36        static_cast<float>(v[1]),
37        static_cast<float>(v[2]));
38}
39
40osg::Vec2 convertVec2(const KFbxVector2& v)
41{
42    return osg::Vec2(
43        static_cast<float>(v[0]),
44        static_cast<float>(v[1]));
45}
46
47osg::Vec4 convertColor(const KFbxColor& color)
48{
49    return osg::Vec4(
50        static_cast<float>(color.mRed),
51        static_cast<float>(color.mGreen),
52        static_cast<float>(color.mBlue),
53        static_cast<float>(color.mAlpha));
54}
55
56template <typename T>
57bool layerElementValid(const KFbxLayerElementTemplate<T>* pLayerElement)
58{
59    if (!pLayerElement)
60        return false;
61
62    switch (pLayerElement->GetMappingMode())
63    {
64    case KFbxLayerElement::eBY_CONTROL_POINT:
65    case KFbxLayerElement::eBY_POLYGON_VERTEX:
66    case KFbxLayerElement::eBY_POLYGON:
67        break;
68    default:
69        return false;
70    }
71
72    switch (pLayerElement->GetReferenceMode())
73    {
74    case KFbxLayerElement::eDIRECT:
75    case KFbxLayerElement::eINDEX_TO_DIRECT:
76        return true;
77    }
78
79    return false;
80}
81
82template <typename T>
83int getVertexIndex(const KFbxLayerElementTemplate<T>* pLayerElement,
84    KFbxMesh* fbxMesh,
85    int nPolygon, int nPolyVertex, int nMeshVertex)
86{
87    int index = 0;
88
89    switch (pLayerElement->GetMappingMode())
90    {
91    case KFbxLayerElement::eBY_CONTROL_POINT:
92        index = fbxMesh->GetPolygonVertex(nPolygon, nPolyVertex);
93        break;
94    case KFbxLayerElement::eBY_POLYGON_VERTEX:
95        index = nMeshVertex;
96        break;
97    case KFbxLayerElement::eBY_POLYGON:
98        index = nPolygon;
99        break;
100    }
101
102    if (pLayerElement->GetReferenceMode() == KFbxLayerElement::eDIRECT)
103    {
104        return index;
105    }
106
107    return pLayerElement->GetIndexArray().GetAt(index);
108}
109
110template <typename T>
111int getPolygonIndex(const KFbxLayerElementTemplate<T>* pLayerElement, int nPolygon)
112{
113    if (pLayerElement &&
114        pLayerElement->GetMappingMode() == KFbxLayerElement::eBY_POLYGON)
115    {
116        switch (pLayerElement->GetReferenceMode())
117        {
118        case KFbxLayerElement::eDIRECT:
119            return nPolygon;
120        case KFbxLayerElement::eINDEX_TO_DIRECT:
121            return pLayerElement->GetIndexArray().GetAt(nPolygon);
122        }
123    }
124
125    return 0;
126}
127
128template <typename FbxT>
129FbxT getElement(const KFbxLayerElementTemplate<FbxT>* pLayerElement,
130    KFbxMesh* fbxMesh,
131    int nPolygon, int nPolyVertex, int nMeshVertex)
132{
133    return pLayerElement->GetDirectArray().GetAt(getVertexIndex(
134        pLayerElement, fbxMesh, nPolygon, nPolyVertex, nMeshVertex));
135}
136
137typedef std::map<unsigned, osg::ref_ptr<osg::Geometry> > GeometryMap;
138
139osg::Geometry* getGeometry(osg::Geode* pGeode, GeometryMap& geometryMap,
140    std::vector<StateSetContent>& stateSetList,
141    GeometryType gt, unsigned int mti, bool bNormal, bool bTexCoord, bool bColor)
142{
143    GeometryMap::iterator it = geometryMap.find(mti);
144
145    if (it != geometryMap.end())
146    {
147        return it->second.get();
148    }
149
150    osg::ref_ptr<osg::Geometry> pGeometry;
151    if (gt == GEOMETRY_MORPH)
152    {
153        pGeometry = new osgAnimation::MorphGeometry;
154    }
155    else
156    {
157        pGeometry = new osg::Geometry;
158    }
159
160    pGeometry->setVertexData(osg::Geometry::ArrayData(new osg::Vec3Array, osg::Geometry::BIND_PER_VERTEX));
161    if (bNormal) pGeometry->setNormalData(osg::Geometry::ArrayData(new osg::Vec3Array, osg::Geometry::BIND_PER_VERTEX));
162    if (bTexCoord) pGeometry->setTexCoordData(0, osg::Geometry::ArrayData(new osg::Vec2Array, osg::Geometry::BIND_PER_VERTEX));
163    if (bColor) pGeometry->setColorData(osg::Geometry::ArrayData(new osg::Vec4Array, osg::Geometry::BIND_PER_VERTEX));
164
165    if (mti < stateSetList.size())
166    {
167        bool transparent = false;
168        const StateSetContent& ss = stateSetList[mti];
169        if (osg::Material* pMaterial = ss.first)
170        {
171            pGeometry->getOrCreateStateSet()->setAttributeAndModes(pMaterial);
172            transparent = pMaterial->getDiffuse(osg::Material::FRONT).w() < 1.0f;
173        }
174        if (osg::Texture2D* pTexture = ss.second)
175        {
176            pGeometry->getOrCreateStateSet()->setTextureAttributeAndModes(0, pTexture);
177            if (!transparent && pTexture->getImage())
178            {
179                transparent = pTexture->getImage()->isImageTranslucent();
180            }
181        }
182
183        if (transparent)
184        {
185            pGeometry->getOrCreateStateSet()->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
186        }
187    }
188
189    geometryMap.insert(std::pair<unsigned, osg::ref_ptr<osg::Geometry> >(mti, pGeometry));
190    pGeode->addDrawable(pGeometry.get());
191
192    return pGeometry.get();
193}
194
195osgAnimation::VertexInfluence& getVertexInfluence(
196    osgAnimation::VertexInfluenceMap& vim, const std::string& name)
197{
198    osgAnimation::VertexInfluenceMap::iterator it = vim.lower_bound(name);
199    if (it == vim.end() || name != it->first)
200    {
201        it = vim.insert(it, osgAnimation::VertexInfluenceMap::value_type(
202            name, osgAnimation::VertexInfluence()));
203        it->second.setName(name);
204    }
205    return it->second;
206}
207
208void addChannel(
209    osgAnimation::Channel* pChannel,
210    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager,
211    const char* pTakeName)
212{
213    if (!pChannel)
214    {
215        return;
216    }
217
218    if (!pAnimManager) pAnimManager = new osgAnimation::BasicAnimationManager;
219
220    osgAnimation::Animation* pAnimation = 0;
221    const osgAnimation::AnimationList& anims = pAnimManager->getAnimationList();
222    for (size_t i = 0; i < anims.size(); ++i)
223    {
224        if (anims[i]->getName() == pTakeName)
225        {
226            pAnimation = anims[i].get();
227        }
228    }
229
230    if (!pAnimation)
231    {
232        pAnimation = new osgAnimation::Animation;
233        pAnimation->setName(pTakeName);
234        pAnimManager->registerAnimation(pAnimation);
235    }
236
237    pAnimation->addChannel(pChannel);
238}
239
240void readAnimation(KFbxNode* pNode, const std::string& targetName,
241    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
242    KFbxMesh* pMesh, int nShape)
243{
244    for (int i = 1; i < pNode->GetTakeNodeCount(); ++i)
245    {
246        const char* pTakeName = pNode->GetTakeNodeName(i);
247
248        KFCurve* pCurve = pMesh->GetShapeChannel(nShape, false, pTakeName);
249        if (!pCurve)
250        {
251            continue;
252        }
253
254        int nKeys = pCurve->KeyGetCount();
255        if (!nKeys)
256        {
257            continue;
258        }
259
260        osgAnimation::FloatLinearChannel* pChannel = new osgAnimation::FloatLinearChannel;
261        std::vector<osgAnimation::TemplateKeyframe<float> >& keyFrameCntr = *pChannel->getOrCreateSampler()->getOrCreateKeyframeContainer();
262
263        for (int k = 0; k < nKeys; ++k)
264        {
265            KFCurveKey key = pCurve->KeyGet(k);
266            float fTime = static_cast<float>(key.GetTime().GetSecondDouble());
267            float fValue = static_cast<float>(key.GetValue() * 0.01);
268            keyFrameCntr.push_back(osgAnimation::FloatKeyframe(fTime,fValue));
269        }
270
271        pChannel->setTargetName(targetName);
272        std::stringstream ss;
273        ss << nShape;
274        pChannel->setName(ss.str());
275        addChannel(pChannel, pAnimationManager, pTakeName);
276    }
277}
278
279void addBindMatrix(
280    BindMatrixMap& boneBindMatrices,
281    KFbxNode* pBone,
282    const osg::Matrix& bindMatrix,
283    osgAnimation::RigGeometry* pRigGeometry)
284{
285    boneBindMatrices.insert(BindMatrixMap::value_type(
286        BindMatrixMap::key_type(pBone, pRigGeometry), bindMatrix));
287}
288
289osgDB::ReaderWriter::ReadResult readMesh(KFbxSdkManager& pSdkManager,
290    KFbxNode* pNode, KFbxMesh* fbxMesh,
291    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
292    std::vector<StateSetContent>& stateSetList,
293    const char* szName,
294    BindMatrixMap& boneBindMatrices,
295    std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
296{
297    GeometryMap geometryMap;
298
299    osg::Geode* pGeode = new osg::Geode;
300    pGeode->setName(szName);
301
302    const KFbxLayer* pFbxLayer = 0;
303    const KFbxLayerElementNormal* pFbxNormals = 0;
304    const KFbxLayerElementUV* pFbxUVs = 0;
305    const KFbxLayerElementVertexColor* pFbxColors = 0;
306    const KFbxLayerElementMaterial* pFbxMaterials = 0;
307
308    const KFbxVector4* pFbxVertices = fbxMesh->GetControlPoints();
309
310    if (pFbxLayer = fbxMesh->GetLayer(0))
311    {
312        pFbxNormals = pFbxLayer->GetNormals();
313        pFbxColors = pFbxLayer->GetVertexColors();
314        pFbxUVs = pFbxLayer->GetUVs();
315        pFbxMaterials = pFbxLayer->GetMaterials();
316
317        if (!layerElementValid(pFbxNormals)) pFbxNormals = 0;
318        if (!layerElementValid(pFbxColors)) pFbxColors = 0;
319        if (!layerElementValid(pFbxUVs)) pFbxUVs = 0;
320    }
321
322    int nPolys = fbxMesh->GetPolygonCount();
323
324    int nDeformerCount = fbxMesh->GetDeformerCount(KFbxDeformer::eSKIN);
325    int nMorphShapeCount = 0;
326
327    GeometryType geomType = GEOMETRY_STATIC;
328
329    //determine the type of geometry
330    if (nDeformerCount)
331    {
332        geomType = GEOMETRY_RIG;
333    }
334    else if (nMorphShapeCount = fbxMesh->GetShapeCount())
335    {
336        geomType = GEOMETRY_MORPH;
337    }
338
339    typedef std::pair<osg::Geometry*, int> GIPair;
340    typedef std::multimap<int, GIPair> FbxToOsgVertexMap;
341    typedef std::map<GIPair, int> OsgToFbxNormalMap;
342    FbxToOsgVertexMap fbxToOsgVertMap;
343    OsgToFbxNormalMap osgToFbxNormMap;
344
345    for (int i = 0, nVertex = 0; i < nPolys; ++i)
346    {
347        int lPolygonSize = fbxMesh->GetPolygonSize(i);
348
349        int materialIndex = getPolygonIndex(pFbxMaterials, i);
350
351        osg::Geometry* pGeometry = getGeometry(pGeode, geometryMap,
352            stateSetList, geomType, materialIndex,
353            pFbxNormals != 0, pFbxUVs != 0, pFbxColors != 0);
354
355        osg::Vec3Array* pVertices = static_cast<osg::Vec3Array*>(
356            pGeometry->getVertexArray());
357        osg::Vec3Array* pNormals = static_cast<osg::Vec3Array*>(
358            pGeometry->getNormalArray());
359        osg::Vec2Array* pTexCoords = static_cast<osg::Vec2Array*>(
360            pGeometry->getTexCoordArray(0));
361        osg::Vec4Array* pColors = static_cast<osg::Vec4Array*>(
362            pGeometry->getColorArray());
363
364        int nVertex0 = nVertex;
365        nVertex += (std::min)(2, lPolygonSize);
366
367        //convert polygon to triangles
368        for (int j = 2; j < lPolygonSize; ++j, ++nVertex)
369        {
370            int v0 = fbxMesh->GetPolygonVertex(i, 0),
371                v1 = fbxMesh->GetPolygonVertex(i, j - 1),
372                v2 = fbxMesh->GetPolygonVertex(i, j);
373
374            fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v0, GIPair(pGeometry, pVertices->size())));
375            fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v1, GIPair(pGeometry, pVertices->size() + 1)));
376            fbxToOsgVertMap.insert(FbxToOsgVertexMap::value_type(v2, GIPair(pGeometry, pVertices->size() + 2)));
377
378            pVertices->push_back(convertVec3(pFbxVertices[v0]));
379            pVertices->push_back(convertVec3(pFbxVertices[v1]));
380            pVertices->push_back(convertVec3(pFbxVertices[v2]));
381
382            if (pNormals)
383            {
384                int n0 = getVertexIndex(pFbxNormals, fbxMesh, i, 0, nVertex0);
385                int n1 = getVertexIndex(pFbxNormals, fbxMesh, i, j - 1, nVertex - 1);
386                int n2 = getVertexIndex(pFbxNormals, fbxMesh, i, j, nVertex);
387
388                osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->size()), n0));
389                osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->size() + 1), n1));
390                osgToFbxNormMap.insert(OsgToFbxNormalMap::value_type(GIPair(pGeometry, pNormals->size() + 2), n2));
391
392                pNormals->push_back(convertVec3(pFbxNormals->GetDirectArray().GetAt(n0)));
393                pNormals->push_back(convertVec3(pFbxNormals->GetDirectArray().GetAt(n1)));
394                pNormals->push_back(convertVec3(pFbxNormals->GetDirectArray().GetAt(n2)));
395            }
396
397            if (pTexCoords)
398            {
399                pTexCoords->push_back(convertVec2(getElement(pFbxUVs, fbxMesh, i, 0, nVertex0)));
400                pTexCoords->push_back(convertVec2(getElement(pFbxUVs, fbxMesh, i, j - 1, nVertex - 1)));
401                pTexCoords->push_back(convertVec2(getElement(pFbxUVs, fbxMesh, i, j, nVertex)));
402            }
403
404            if (pColors)
405            {
406                pColors->push_back(convertColor(getElement(pFbxColors, fbxMesh, i, 0, nVertex0)));
407                pColors->push_back(convertColor(getElement(pFbxColors, fbxMesh, i, j - 1, nVertex - 1)));
408                pColors->push_back(convertColor(getElement(pFbxColors, fbxMesh, i, j, nVertex)));
409            }
410        }
411    }
412
413    for (int i = 0; i < pGeode->getNumDrawables(); ++i)
414    {
415        osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry();
416        if (pGeode->getNumDrawables() > 1)
417        {
418            std::stringstream ss;
419            ss << pGeode->getName() << " " << i + 1;
420            pGeometry->setName(ss.str());
421        }
422        else
423        {
424            pGeometry->setName(pGeode->getName());
425        }
426
427        osg::DrawArrays* pDrawArrays = new osg::DrawArrays(
428            GL_TRIANGLES, 0, pGeometry->getVertexArray()->getNumElements());
429        pGeometry->addPrimitiveSet(pDrawArrays);
430    }
431
432    if (geomType == GEOMETRY_RIG)
433    {
434        typedef std::map<osg::ref_ptr<osg::Geometry>,
435            osg::ref_ptr<osgAnimation::RigGeometry> > GeometryRigGeometryMap;
436        GeometryRigGeometryMap old2newGeometryMap;
437
438        for (int i = 0; i < pGeode->getNumDrawables(); ++i)
439        {
440            osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry();
441
442            osgAnimation::RigGeometry* pRig = new osgAnimation::RigGeometry;
443            pRig->setSourceGeometry(pGeometry);
444            pRig->copyFrom(*pGeometry);
445            old2newGeometryMap.insert(GeometryRigGeometryMap::value_type(
446                pGeometry, pRig));
447            pRig->setDataVariance(osg::Object::DYNAMIC);
448            pRig->setUseDisplayList( false );
449            pGeode->setDrawable(i, pRig);
450
451            pRig->setInfluenceMap(new osgAnimation::VertexInfluenceMap);
452            pGeometry = pRig;
453        }
454
455        for (int i = 0; i < nDeformerCount; ++i)
456        {
457            KFbxSkin* pSkin = (KFbxSkin*)fbxMesh->GetDeformer(i, KFbxDeformer::eSKIN);
458            int nClusters = pSkin->GetClusterCount();
459            for (int j = 0; j < nClusters; ++j)
460            {
461                KFbxCluster* pCluster = (KFbxCluster*)pSkin->GetCluster(j);
462                //assert(KFbxCluster::eNORMALIZE == pCluster->GetLinkMode());
463                KFbxNode* pBone = pCluster->GetLink();
464
465                KFbxXMatrix transformLink;
466                pCluster->GetTransformLinkMatrix(transformLink);
467                KFbxXMatrix transformLinkInverse = transformLink.Inverse();
468                const double* pTransformLinkInverse = transformLinkInverse;
469                osg::Matrix bindMatrix(pTransformLinkInverse);
470
471                int nIndices = pCluster->GetControlPointIndicesCount();
472                int* pIndices = pCluster->GetControlPointIndices();
473                double* pWeights = pCluster->GetControlPointWeights();
474
475                for (int k = 0; k < nIndices; ++k)
476                {
477                    int fbxIndex = pIndices[k];
478                    float weight = static_cast<float>(pWeights[k]);
479
480                    for (FbxToOsgVertexMap::const_iterator it =
481                        fbxToOsgVertMap.find(fbxIndex);
482                        it != fbxToOsgVertMap.end() &&
483                        it->first == fbxIndex; ++it)
484                    {
485                        GIPair gi = it->second;
486                        osgAnimation::RigGeometry& rig =
487                            dynamic_cast<osgAnimation::RigGeometry&>(
488                            *old2newGeometryMap[gi.first]);
489                        addBindMatrix(boneBindMatrices, pBone, bindMatrix, &rig);
490                        osgAnimation::VertexInfluenceMap& vim =
491                            *rig.getInfluenceMap();
492                        osgAnimation::VertexInfluence& vi =
493                            getVertexInfluence(vim, pBone->GetName());
494                        vi.push_back(osgAnimation::VertexIndexWeight(
495                            gi.second, weight));
496                    }
497                }
498            }
499        }
500    }
501    else if (geomType == GEOMETRY_MORPH)
502    {
503        for (int i = 0; i < pGeode->getNumDrawables(); ++i)
504        {
505            osg::Geometry* pGeometry = pGeode->getDrawable(i)->asGeometry();
506
507            osgAnimation::MorphGeometry& morph = dynamic_cast<osgAnimation::MorphGeometry&>(*pGeometry);
508
509            pGeode->addUpdateCallback(new osgAnimation::UpdateMorph(morph.getName()));
510
511            //read morph geometry
512            for (int j = 0; j < nMorphShapeCount; ++j)
513            {
514                const KFbxGeometryBase* pMorphShape = fbxMesh->GetShape(i);
515
516                const KFbxLayerElementNormal* pFbxShapeNormals = 0;
517                if (const KFbxLayer* pFbxShapeLayer = pMorphShape->GetLayer(0))
518                {
519                    pFbxShapeNormals = pFbxShapeLayer->GetNormals();
520                    if (!layerElementValid(pFbxShapeNormals)) pFbxShapeNormals = 0;
521                }
522
523                osg::Geometry* pMorphTarget = new osg::Geometry(morph);
524                pMorphTarget->setVertexArray(static_cast<osg::Array*>(
525                    pMorphTarget->getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));
526                if (pFbxShapeNormals)
527                {
528                    if (osg::Array* pNormals = pMorphTarget->getNormalArray())
529                    {
530                        pMorphTarget->setNormalArray(static_cast<osg::Array*>(
531                            pNormals->clone(osg::CopyOp::DEEP_COPY_ARRAYS)));
532                    }
533                }
534                pMorphTarget->setName(fbxMesh->GetShapeName(j));
535                morph.addMorphTarget(pMorphTarget, 0.0f);
536
537                readAnimation(pNode, morph.getName(), pAnimationManager, fbxMesh, j);
538            }
539        }
540
541        for (int i = 0; i < nMorphShapeCount; ++i)
542        {
543            const KFbxGeometryBase* pMorphShape = fbxMesh->GetShape(i);
544
545            const KFbxLayerElementNormal* pFbxShapeNormals = 0;
546            if (const KFbxLayer* pFbxShapeLayer = pMorphShape->GetLayer(0))
547            {
548                pFbxShapeNormals = pFbxShapeLayer->GetNormals();
549                if (!layerElementValid(pFbxShapeNormals)) pFbxShapeNormals = 0;
550            }
551
552            const KFbxVector4* pControlPoints = pMorphShape->GetControlPoints();
553            int nControlPoints = pMorphShape->GetControlPointsCount();
554            for (int fbxIndex = 0; fbxIndex < nControlPoints; ++fbxIndex)
555            {
556                osg::Vec3 vPos = convertVec3(pControlPoints[fbxIndex]);
557                for (FbxToOsgVertexMap::const_iterator it =
558                    fbxToOsgVertMap.find(fbxIndex);
559                    it != fbxToOsgVertMap.end() &&
560                    it->first == fbxIndex; ++it)
561                {
562                    GIPair gi = it->second;
563                    osgAnimation::MorphGeometry& morphGeom =
564                        dynamic_cast<osgAnimation::MorphGeometry&>(*gi.first);
565                    osg::Geometry* pGeometry = morphGeom.getMorphTarget(i).getGeometry();
566                    osg::Vec3Array* pVertices = static_cast<osg::Vec3Array*>(pGeometry->getVertexArray());
567                    (*pVertices)[gi.second] = vPos;
568
569                    if (pFbxShapeNormals)
570                    {
571                        if (osg::Vec3Array* pNormals = static_cast<osg::Vec3Array*>(pGeometry->getNormalArray()))
572                        {
573                            (*pNormals)[gi.second] = convertVec3(
574                                pFbxShapeNormals->GetDirectArray().GetAt(osgToFbxNormMap[gi]));
575                        }
576                    }
577                }
578            }
579        }
580    }
581
582    KFbxXMatrix fbxGeometricTransform;
583    fbxGeometricTransform.SetTRS(
584        pNode->GeometricTranslation.Get(),
585        pNode->GeometricRotation.Get(),
586        pNode->GeometricScaling.Get());
587    const double* pGeometricMat = fbxGeometricTransform;
588    osg::Matrix osgGeometricTransform(pGeometricMat);
589
590    if (geomType == GEOMETRY_RIG)
591    {
592        KFbxSkin* pSkin = (KFbxSkin*)fbxMesh->GetDeformer(0, KFbxDeformer::eSKIN);
593        if (pSkin->GetClusterCount())
594        {
595            KFbxXMatrix fbxTransformMatrix;
596            pSkin->GetCluster(0)->GetTransformMatrix(fbxTransformMatrix);
597            const double* pTransformMatrix = fbxTransformMatrix;
598            osgGeometricTransform.postMult(osg::Matrix(pTransformMatrix));
599        }
600    }
601
602    osg::Node* pResult = pGeode;
603
604    if (!osgGeometricTransform.isIdentity())
605    {
606        osg::MatrixTransform* pMatTrans = new osg::MatrixTransform(osgGeometricTransform);
607        pMatTrans->addChild(pGeode);
608        pResult = pMatTrans;
609    }
610
611    if (geomType == GEOMETRY_RIG)
612    {
613        //Add the geometry to the skeleton ancestor of one of the bones.
614        KFbxSkin* pSkin = (KFbxSkin*)fbxMesh->GetDeformer(0, KFbxDeformer::eSKIN);
615        if (pSkin->GetClusterCount())
616        {
617            osgAnimation::Skeleton* pSkeleton = getSkeleton(pSkin->GetCluster(0)->GetLink(), skeletonMap);
618            pSkeleton->addChild(pResult);
619            return osgDB::ReaderWriter::ReadResult::FILE_LOADED;
620        }
621    }
622
623    return osgDB::ReaderWriter::ReadResult(pResult);
624}
625
626osgDB::ReaderWriter::ReadResult readFbxMesh(KFbxSdkManager& pSdkManager,
627    KFbxNode* pNode,
628    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
629    std::vector<StateSetContent>& stateSetList,
630    BindMatrixMap& boneBindMatrices,
631    std::map<KFbxNode*, osgAnimation::Skeleton*>& skeletonMap)
632{
633    KFbxMesh* lMesh = dynamic_cast<KFbxMesh*>(pNode->GetNodeAttribute());
634
635    if (!lMesh)
636    {
637        return osgDB::ReaderWriter::ReadResult::ERROR_IN_READING_FILE;
638    }
639
640    return readMesh(pSdkManager, pNode, lMesh, pAnimationManager, stateSetList,
641        pNode->GetName(), boneBindMatrices, skeletonMap);
642}
Note: See TracBrowser for help on using the browser.