StereoCamera/main.cxx

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

 Copyright (C) 2010 Autodesk, Inc. and/or its licensors.
 All Rights Reserved.

 The coded instructions, statements, computer programs, and/or related material 
 (collectively the "Data") in these files contain unpublished information 
 proprietary to Autodesk, Inc. and/or its licensors, which is protected by 
 Canada and United States of America federal copyright law and by international 
 treaties. 
 
 The Data may not be disclosed or distributed to third parties, in whole or in
 part, without the prior written consent of Autodesk, Inc. ("Autodesk").

 THE DATA IS PROVIDED "AS IS" AND WITHOUT WARRANTY.
 ALL WARRANTIES ARE EXPRESSLY EXCLUDED AND DISCLAIMED. AUTODESK MAKES NO
 WARRANTY OF ANY KIND WITH RESPECT TO THE DATA, EXPRESS, IMPLIED OR ARISING
 BY CUSTOM OR TRADE USAGE, AND DISCLAIMS ANY IMPLIED WARRANTIES OF TITLE, 
 NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR USE. 
 WITHOUT LIMITING THE FOREGOING, AUTODESK DOES NOT WARRANT THAT THE OPERATION
 OF THE DATA WILL BE UNINTERRUPTED OR ERROR FREE. 
 
 IN NO EVENT SHALL AUTODESK, ITS AFFILIATES, PARENT COMPANIES, LICENSORS
 OR SUPPLIERS ("AUTODESK GROUP") BE LIABLE FOR ANY LOSSES, DAMAGES OR EXPENSES
 OF ANY KIND (INCLUDING WITHOUT LIMITATION PUNITIVE OR MULTIPLE DAMAGES OR OTHER
 SPECIAL, DIRECT, INDIRECT, EXEMPLARY, INCIDENTAL, LOSS OF PROFITS, REVENUE
 OR DATA, COST OF COVER OR CONSEQUENTIAL LOSSES OR DAMAGES OF ANY KIND),
 HOWEVER CAUSED, AND REGARDLESS OF THE THEORY OF LIABILITY, WHETHER DERIVED
 FROM CONTRACT, TORT (INCLUDING, BUT NOT LIMITED TO, NEGLIGENCE), OR OTHERWISE,
 ARISING OUT OF OR RELATING TO THE DATA OR ITS USE OR ANY OTHER PERFORMANCE,
 WHETHER OR NOT AUTODESK HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH LOSS
 OR DAMAGE. 

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

//
// The example illustrates how to:
//        1) get a stereo camera from a scene
//        2) evaluate left/right camera
//        3) get local/global matrix of left and right camera
//        4) create stereo camera set
//        5) connect left/right and stereo
//
//steps:
// 1. initialize FBX sdk object.
// 2. load fbx scene form the specified file.
// 3. Get root node of the scene.
// 4. Recursively traverse each node in the scene.
// 5. Detect and get stereo camera by from node attribute type.
// 6. Get left and right camera.
// 7. Evaluate left/right camera.
// 8. Get local/global matrix of left and right camera.
// 9. Create stereo camera set after extracting stereo camera.
// 10. Connect left/right and stereo.
// 11. Get the updated values via connections.
// 12. Destroy all objects.
//

#include <fbxsdk.h>

#include "../Common/Common.h"

#define SAMPLE_FILENAME "StereoCamera.fbx"

void PrintMatrix(const KFbxXMatrix& pMatrix);

void GetStereoCameraInfo(KFbxNode* pNode);

void CreateStereoCamera(KFbxScene* pScene);

int main(int argc, char** argv)
{
    KFbxSdkManager* lSdkManager = NULL;
    KFbxScene* lScene = NULL;
    bool lResult;

    // Prepare the FBX SDK.
    InitializeSdkObjects(lSdkManager, lScene);

    // Load the scene.
    // The example can take a FBX file as an argument.
    if(argc > 1)
    {
        printf("\n\nFile: %s\n\n", argv[1]);
        lResult = LoadScene(lSdkManager, lScene, argv[1]);
    }
    else
    {
        printf("\n\nFile: %s\n\n", SAMPLE_FILENAME);
        lResult = LoadScene(lSdkManager, lScene, SAMPLE_FILENAME);
    }

    if(lResult == false)
    {
        printf("\n\nAn error occurred while loading the scene...");
    }
    else 
    {
        if(!lScene)
        {
            K_ASSERT_MSG_NOW("null scene");
        }

        //get root node of the fbx scene
        KFbxNode* lRootNode = lScene->GetRootNode();

        //This function illustrates how to get stereo camera info from scene.
        GetStereoCameraInfo(lRootNode);

        //create your own stereo camera set
        CreateStereoCamera(lScene);
    }

    //Destroy all objects created by the FBX SDK.
    DestroySdkObjects(lSdkManager);
    return 0;
}

//This function illustrates how to get stereo camera info from scene.
void GetStereoCameraInfo(KFbxNode* pNode)
{
    if(!pNode)
        return;

    //detect stereo camera by node attribute type
    if(pNode->GetNodeAttribute() && pNode->GetNodeAttribute()->GetAttributeType() == KFbxNodeAttribute::eCAMERA_STEREO)
    {
        //get stereo camera
        KFbxCameraStereo* lStereoCamera = (KFbxCameraStereo*)pNode->GetNodeAttribute();

        //once we get the KFbxCameraStereo, its connection has already been done.
        //it's easy to get its left and right camera
        //get left camera
        KFbxCamera* lLeftCamera = lStereoCamera->GetLeftCamera();
        KString lLeftName = lLeftCamera->GetName();
        printf("left camera: %s\n", lLeftName.Buffer());
        //get right camera
        KFbxCamera* lRightCamera = lStereoCamera->GetRightCamera();
        KString lRightName = lRightCamera->GetName();
        printf("right camera: %s\n", lRightName.Buffer());

        //FBX SDK support reevaluation functionality
        //reevaluate left/right camera
        double lLeftOffsetX = lStereoCamera->ReevaluateLeftCameraFilmOffsetX();
        printf("reevaluated left camera film offset: %f\n", lLeftOffsetX);
        double lLeftFbxOffsetX = lLeftCamera->FilmOffsetX.Get();
        printf("The original FBX left camera film offset: %f\n", lLeftFbxOffsetX);
        double lRightOffsetX = lStereoCamera->ReevaluateRightCameraFilmOffsetX();
        printf("reevaluated right camera film offset: %f\n", lRightOffsetX);
        double lRightFbxOffsetX = lRightCamera->FilmOffsetX.Get();
        printf("The original FBX right camera film offset: %f\n", lRightFbxOffsetX);

        //get local/global matrix of left and right camera
        //Then you can get their Translate, Rotate and Scale info.
        KFbxXMatrix lLeft_localMatrix = lStereoCamera->GetLeftCameraLocalMatrix();
        KFbxXMatrix lRight_localMatrix = lStereoCamera->GetRightCameraLocalMatrix();
        KFbxXMatrix lLeft_globalMatrix = lStereoCamera->GetLeftCameraGlobalMatrix();
        KFbxXMatrix lRight_globalMatrix = lStereoCamera->GetRightCameraGlobalMatrix();

        //print the local and global TRS for left camera
        printf("===local TRS of left camera===\n");
        PrintMatrix(lLeft_localMatrix);
        printf("===global TRS of left camera===\n");
        PrintMatrix(lLeft_globalMatrix);

        //print the local and global TRS for right camera
        printf("===local TRS of right camera===\n");
        PrintMatrix(lRight_localMatrix);
        printf("===global TRS of right camera===\n");
        PrintMatrix(lRight_globalMatrix);
    }// end if pNode->GetNodeAttribute()


    //recursively traverse each node in the scene
    int i, lCount = pNode->GetChildCount();
    for (i = 0; i < lCount; i++)
    {
        GetStereoCameraInfo(pNode->GetChild(i));
    }
}

//print the TRS for the given matrix
void PrintMatrix(const KFbxXMatrix& pMatrix)
{
    //print the TRS
    printf(" T : %f %f %f %f\n", 
        pMatrix.GetT()[0], 
        pMatrix.GetT()[1], 
        pMatrix.GetT()[2], 
        pMatrix.GetT()[3] );

    printf(" R : %f %f %f %f\n", 
        pMatrix.GetR()[0], 
        pMatrix.GetR()[1], 
        pMatrix.GetR()[2], 
        pMatrix.GetR()[3] );

    printf(" S : %f %f %f %f\n", 
        pMatrix.GetS()[0], 
        pMatrix.GetS()[1], 
        pMatrix.GetS()[2], 
        pMatrix.GetS()[3] );
}

//This function illustrates how to create and connect stereo camera.
void CreateStereoCamera(KFbxScene* pScene)
{
    if(!pScene)
        return;

    //create a fbx node for stereo camera
    KFbxNode* lMyStereoNode = KFbxNode::Create(pScene,"myStereoNode");
    //create a cameraStereo, it's a node attribute of stereo camera node.
    KFbxCameraStereo* lMyStereoCamera = KFbxCameraStereo::Create(pScene,"myStereoCamera");
    //set stereoCamera as a node attribute of the FBX node.
    lMyStereoNode->SetNodeAttribute (lMyStereoCamera);
    //create a camera(node attribute), it will be left camera of stereo
    KFbxCamera* lLeftCamera = KFbxCamera::Create(pScene, "leftCamera");
    //create a camera(node attribute), it will be right camera of stereo
    KFbxCamera* lRightCamera = KFbxCamera::Create(pScene, "rightCamera");
    //add left camera to stereo
    lMyStereoCamera->SetLeftCamera(lLeftCamera);
    //add right camera to stereo
    lMyStereoCamera->SetRightCamera(lRightCamera);

    //During FBXSDK reevaluating, if ConnectProperties() is called, 
    //left and right camera property will be connected to stereo camera.
    //It's used to connect the left/right camera property [FocalLength, FarPlane, NearPlane, FilmWidth,
    //FilmHeight, FilmSqueezeRatio] to stereo camera.
    //If these properties of stereo camera have been modified by SDK, 
    //FBX will not automatically sync and update the corresponding properties of left/right camera.
    //However, you could get the newest property of left/right camera since ConnectProperties() is called.
    //To get the newest property value, please use lLeft_Camera->FocalLength.GetSrcProperty().Get(&lNewValue, ...);
    //Then you can update your left/right camera properties, for example, lLeftCamera->FocalLength.Set(lNewValue);
    lMyStereoCamera->ConnectProperties();

    //test the connection
    //get the focal length value of left camera.
    double lFocalLength_Left = lLeftCamera->FocalLength.Get();
    printf("FocalLength of left camera: %f\n", lFocalLength_Left);
    double lFocalLength_Left_src = 0;
    //get source property of left focal length, it should be stereo focal length.
    KFbxProperty lLeftSrcLengthProperty = lLeftCamera->FocalLength.GetSrcProperty();
    if(lLeftSrcLengthProperty.IsValid())
    {
        bool lStatus = lLeftSrcLengthProperty.Get(&lFocalLength_Left_src, eDOUBLE1);
        printf("Initialized FocalLength of left camera source:   %f\n", lFocalLength_Left_src);
        //modify the FocalLength of stereo camera
        lMyStereoCamera->FocalLength.Set(3.333);
        //get the FocalLength of left camera. It's 34.89 now. 
        //But it should be updated to 3.33 since stereo FocalLength has changed.
        //FBX doesn't sync it from stereo camera
        lFocalLength_Left = lLeftCamera->FocalLength.Get();
        printf("FocalLength of left camera:   %f\n", lFocalLength_Left);
        //get the newest value from connected property.
        lStatus = lLeftSrcLengthProperty.Get(&lFocalLength_Left_src, eDOUBLE1);
        printf("FocalLength of left camera source:   %f\n", lFocalLength_Left_src);
    }
}