ViewScene/InitScene.cxx

/****************************************************************************************

Copyright (C) 2010 Autodesk, Inc.
All rights reserved.

Use of this software is subject to the terms of the Autodesk license agreement
provided at the time of installation or download, or which otherwise accompanies
this software in either electronic or hard copy form.

****************************************************************************************/

//
// This file contains the useful functions to: 
// 1) convert the nurbs and patch attribute types of a scene into mesh 
//    node attributes;
// 2) get the list of all the cameras in the scene.
//

#include <math.h>

#include <fbxsdk.h>

#include <fbxfilesdk/fbxfilesdk_nsuse.h>

#include "InitScene.h"
#include "Texture.h"

void ConvertNurbsAndPatchRecursive(KFbxSdkManager* pSdkManager, 
                                   KFbxNode* pNode);
void FillCameraArrayRecursive(KFbxNode* pNode, 
                              KArrayTemplate<KFbxNode*>& pCameraArray);
void LoadSupportedTexturesRecursive(const KFbxNode* pNode, TextureManager * pTextureManager);

KString ExtractDirectory(KString pFilePath);

extern KFbxImporter* gImporter;


void ConvertNurbsAndPatch(KFbxSdkManager* pSdkManager, KFbxScene* pScene)
{
    ConvertNurbsAndPatchRecursive(pSdkManager, pScene->GetRootNode());
}


void ConvertNurbsAndPatchRecursive(KFbxSdkManager* pSdkManager, KFbxNode* pNode)
{
    KFbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();

    if (lNodeAttribute)
    {
        if (lNodeAttribute->GetAttributeType() == KFbxNodeAttribute::eNURB ||
            lNodeAttribute->GetAttributeType() == KFbxNodeAttribute::ePATCH)
        {
            KFbxGeometryConverter lConverter(pSdkManager);
            lConverter.TriangulateInPlace(pNode);
        }
    }

    int i, lCount = pNode->GetChildCount();

    for (i = 0; i < lCount; i++)
    {
        ConvertNurbsAndPatchRecursive(pSdkManager, pNode->GetChild(i));
    }
}


void FillCameraArray(KFbxScene* pScene, KArrayTemplate<KFbxNode*>& pCameraArray)
{
    pCameraArray.Clear();

    FillCameraArrayRecursive(pScene->GetRootNode(), pCameraArray);
}


void FillCameraArrayRecursive(KFbxNode* pNode, KArrayTemplate<KFbxNode*>& pCameraArray)
{
    int i, lCount;

    if (pNode)
    {
        if (pNode->GetNodeAttribute())
        {
            if (pNode->GetNodeAttribute()->GetAttributeType() == KFbxNodeAttribute::eCAMERA)
            {
                pCameraArray.Add(pNode);
            }
        }

        lCount = pNode->GetChildCount();

        for (i = 0; i < lCount; i++)
        {
            FillCameraArrayRecursive(pNode->GetChild(i), pCameraArray);
        }
    }
}


void FillPoseArray(KFbxScene* pScene, KArrayTemplate<KFbxPose*>& pPoseArray)
{
    int      i, lPoseCount;

    for (i=0, lPoseCount = pScene->GetPoseCount(); i < lPoseCount; i++)
    {
        pPoseArray.Add(pScene->GetPose(i));
    }
}

void PreparePointCacheData(KFbxScene* pScene)
{
    // This function show how to cycle thru scene elements in a linear way.
    int lIndex, lNodeCount = KFbxGetSrcCount<KFbxNode>(pScene);

    for (lIndex=0; lIndex<lNodeCount; lIndex++)
    {
        KFbxNode* lNode = KFbxGetSrc<KFbxNode>(pScene, lIndex);

        if (lNode->GetGeometry()) 
        {
            int i, lVertexCacheDeformerCount = lNode->GetGeometry()->GetDeformerCount(KFbxDeformer::eVERTEX_CACHE);

            // There should be a maximum of 1 Vertex Cache Deformer for the moment
            lVertexCacheDeformerCount = lVertexCacheDeformerCount > 0 ? 1 : 0;

            for (i=0; i<lVertexCacheDeformerCount; ++i )
            {
                // Get the Point Cache object
                KFbxVertexCacheDeformer* lDeformer = static_cast<KFbxVertexCacheDeformer*>(lNode->GetGeometry()->GetDeformer(i, KFbxDeformer::eVERTEX_CACHE));
                if( !lDeformer ) continue;
                KFbxCache* lCache = lDeformer->GetCache();
                if( !lCache ) continue;

                // Process the point cache data only if the constraint is active
                if (lDeformer->IsActive())
                {
                    if (lCache->GetCacheFileFormat() == KFbxCache::ePC2)
                    {
                        // This code show how to convert from PC2 to MC point cache format
                        // turn it on if you need it.
#if 0 
                        if (!lCache->ConvertFromPC2ToMC(KFbxCache::eMC_ONE_FILE, 
                            KTime::GetFrameRate(pScene->GetGlobalTimeSettings().GetTimeMode())))
                        {
                            // Conversion failed, retrieve the error here
                            KString lTheErrorIs = lCache->GetError().GetLastErrorString();
                        }
#endif
                    }
                    else if (lCache->GetCacheFileFormat() == KFbxCache::eMC)
                    {
                        // This code show how to convert from MC to PC2 point cache format
                        // turn it on if you need it.
                        //#if 0 
                        if (!lCache->ConvertFromMCToPC2(KTime::GetFrameRate(pScene->GetGlobalSettings().GetTimeMode()), 0))
                        {
                            // Conversion failed, retrieve the error here
                            KString lTheErrorIs = lCache->GetError().GetLastErrorString();
                        }
                        //#endif
                    }


                    // Now open the cache file to read from it
                    if (!lCache->OpenFileForRead())
                    {
                        // Cannot open file 
                        KString lTheErrorIs = lCache->GetError().GetLastErrorString();

                        // Set the deformer inactive so we don't play it back
                        lDeformer->SetActive(false);
                    }
                }
            }
        }
    }
}