void FBXSceneEncoder::loadAnimationLayer(FbxAnimLayer* fbxAnimLayer, FbxNode* fbxNode, const EncoderArguments& arguments)
{
    bool animationGroupId = false;
    const char* name = fbxNode->GetName();
    // Check if this node's animations are supposed to be grouped
    if (name && arguments.containsGroupNodeId(name))
    {
        animationGroupId = true;
        _groupAnimation = new Animation();
        _groupAnimation->setId(arguments.getAnimationId(name));
    }
    Animation* animation = _groupAnimation;
    if (!animation)
    {
        animation = new Animation();
        animation->setId(name);
    }
    loadAnimationChannels(fbxAnimLayer, fbxNode, animation);

    const int childCount = fbxNode->GetChildCount();
    for (int modelCount = 0; modelCount < childCount; ++modelCount)
    {
        loadAnimationLayer(fbxAnimLayer, fbxNode->GetChild(modelCount), arguments);
    }
    if (animationGroupId)
    {
        _gamePlayFile.addAnimation(_groupAnimation);
        _groupAnimation = NULL;
    }
}
void TMXSceneEncoder::write(const EncoderArguments& arguments)
{
    XMLDocument xmlDoc;
    XMLError err;
    if ((err = xmlDoc.LoadFile(arguments.getFilePath().c_str())) != XML_NO_ERROR)
    {
        LOG(1, "Call to XMLDocument::LoadFile() failed.\n");
        LOG(1, "Error returned: %d\n\n", err);
        return;
    }
    
    // Parse the Tiled map
    TMXMap map;
    string inputDirectory = arguments.getFileDirPath();

    LOG(2, "Parsing .tmx file.\n");
    if (!parseTmx(xmlDoc, map, inputDirectory))
    {
        return;
    }

    // Apply a gutter, or skirt, around the tiles to prevent gaps
    if (arguments.generateTextureGutter())
    {
        LOG(2, "Bulding gutter tilesets.\n");
        buildTileGutter(map, inputDirectory, arguments.getOutputDirPath());
    }

    // Write the tile map
    string fileName = arguments.getFileName();
    int pos = fileName.find_last_of('.');

    LOG(2, "Writing .scene file.\n");
    writeScene(map, arguments.getOutputFilePath(), (pos == -1 ? fileName : fileName.substr(0, pos)));
}
Exemple #3
0
void generateTangentsAndBinormals(FbxNode* fbxNode, const EncoderArguments& arguments)
{
    if (!fbxNode)
        return;
    const char* name = fbxNode->GetName();
    if (name && strlen(name) > 0)
    {
        FbxMesh* fbxMesh = fbxNode->GetMesh();
        if (fbxMesh && arguments.isGenerateTangentBinormalId(string(name)))
        {
            fbxMesh->GenerateTangentsDataForAllUVSets();
        }
    }
    // visit child nodes
    const int childCount = fbxNode->GetChildCount();
    for (int i = 0; i < childCount; ++i)
    {
        generateTangentsAndBinormals(fbxNode->GetChild(i), arguments);
    }
}
void FBXSceneEncoder::write(const string& filepath, const EncoderArguments& arguments)
{
    FbxManager* sdkManager = FbxManager::Create();
    FbxIOSettings *ios = FbxIOSettings::Create(sdkManager, IOSROOT);
    sdkManager->SetIOSettings(ios);
    FbxImporter* importer = FbxImporter::Create(sdkManager,"");
    
    if (!importer->Initialize(filepath.c_str(), -1, sdkManager->GetIOSettings()))
    {
        LOG(1, "Call to FbxImporter::Initialize() failed.\n");
        LOG(1, "Error returned: %s\n\n", importer->GetLastErrorString());
        exit(-1);
    }
    
    FbxScene* fbxScene = FbxScene::Create(sdkManager,"__FBX_SCENE__");

    print("Loading FBX file.");
    importer->Import(fbxScene);
    importer->Destroy();

    // Determine if animations should be grouped.
    if (arguments.getGroupAnimationAnimationId().empty() && isGroupAnimationPossible(fbxScene))
    {
        if ( arguments.getAnimationGrouping()==EncoderArguments::ANIMATIONGROUP_AUTO || 
            (arguments.getAnimationGrouping()==EncoderArguments::ANIMATIONGROUP_PROMPT && promptUserGroupAnimations()))
        {
            _autoGroupAnimations = true;
        }
    }

    if (arguments.tangentBinormalIdCount() > 0)
    {
        generateTangentsAndBinormals(fbxScene->GetRootNode(), arguments);
    }

    print("Loading Scene.");
    loadScene(fbxScene);
    print("Load materials");
    loadMaterials(fbxScene);
    print("Loading animations.");
    loadAnimations(fbxScene, arguments);
    sdkManager->Destroy();

    print("Optimizing GamePlay Binary.");
    _gamePlayFile.adjust();
    if (_autoGroupAnimations)
    {
        _gamePlayFile.groupMeshSkinAnimations();
    }
    
    string outputFilePath = arguments.getOutputFilePath();

    if (arguments.textOutputEnabled())
    {
        int pos = outputFilePath.find_last_of('.');
        if (pos > 2)
        {
            string path = outputFilePath.substr(0, pos);
            path.append(".xml");
            LOG(1, "Saving debug file: %s\n", path.c_str());
            if (!_gamePlayFile.saveText(path))
            {
                LOG(1, "Error writing text file: %s\n", path.c_str());
            }
        }
    }
    else
    {
        LOG(1, "Saving binary file: %s\n", outputFilePath.c_str());
        if (!_gamePlayFile.saveBinary(outputFilePath))
        {
            LOG(1, "Error writing binary file: %s\n", outputFilePath.c_str());
        }
    }

    // Write the material file
    if (arguments.outputMaterialEnabled())
    {
        int pos = outputFilePath.find_last_of('.');
        if (pos > 2)
        {
            string path = outputFilePath.substr(0, pos);
            path.append(".material");
            writeMaterial(path);
        }
    }
}