示例#1
0
void FBXSceneEncoder::loadCamera(FbxNode* fbxNode, Node* node)
{
    FbxCamera* fbxCamera = fbxNode->GetCamera();
    if (!fbxCamera)
    {
        return;
    }
    Camera* camera = new Camera();
    const char* name = fbxNode->GetName();
    if (name)
    {
        string id(name);
        id.append("_Camera");
        camera->setId(id);
    }

	// Clip planes have to by divided by the forward scale of the camera (x-axis) to get right values
	float scale = (float)fbxCamera->GetNode()->LclScaling.Get()[0];

    camera->setAspectRatio(getAspectRatio(fbxCamera));
	camera->setNearPlane((float)fbxCamera->NearPlane.Get() / scale);
	camera->setFarPlane((float)fbxCamera->FarPlane.Get() / scale);

    if (fbxCamera->ProjectionType.Get() == FbxCamera::eOrthogonal)
    {
        camera->setOrthographic();
        camera->setViewportWidth((float)fbxCamera->GetApertureWidth());
        camera->setViewportWidth((float)fbxCamera->GetApertureHeight());
        // xmag in FBX can be calculated from: OrthoZoom * 30.0 / 2.0
        camera->setViewportWidth((float)fbxCamera->OrthoZoom.Get() * 15.0f);
    }
    else if (fbxCamera->ProjectionType.Get() == FbxCamera::ePerspective)
    {
        camera->setPerspective();
        camera->setFieldOfView(getFieldOfView(fbxCamera));
    }
    else
    {
        LOG(2, "Warning: Unknown camera type in node.\n");
        return;
    }
    _gamePlayFile.addCamera(camera);
    node->setCamera(camera);
}
示例#2
0
void FbxParser::ProcessCamera(FbxNode* pNode, GS::Camera& camera)
{
	FbxCamera* lCamera = (FbxCamera*) pNode->GetNodeAttribute();
	if (lCamera == NULL)
		return ;
	FbxNode* pTargetNode = pNode->GetTarget();
	FbxNode* pTargetUpNode = pNode->GetTargetUp();
	FbxVector4  lEye = lCamera->Position.Get();
    FbxVector4  lUp; 
	FbxVector4 lCenter;
	if (!pTargetNode)
	   lCenter = lCamera->InterestPosition.Get();
	if (!pTargetUpNode)
		lUp = lCamera->UpVector.Get();
	  
   double lRadians = PI * lCamera->Roll.Get() / 180.0;
    // Align the up vector.
   FbxVector4 lForward = lCenter - lEye;
   lForward.Normalize();
   FbxVector4 lRight = lForward.CrossProduct(lUp);
   lRight.Normalize();
   lUp = lRight.CrossProduct(lForward);
   lUp.Normalize();
   lUp *= cos(lRadians);
   lRight *= sin(lRadians);
   lUp = lUp + lRight;
	GS::float3 pos(lEye[0], lEye[1], lEye[2]);
	GS::float3 up(lUp[0], lUp[1], lUp[2]);
	GS::float3 target(lCenter[0], lCenter[1], lCenter[2]);
	GS::Camera cam(pos, target, up);
	float lNearPlane = 0.01f;
    if (lCamera)
		lNearPlane = lCamera->GetNearPlane();
    float lFarPlane = 1000.0;
    if (lCamera)
		lFarPlane = lCamera->GetFarPlane();
    bool bPerspectice =  lCamera->ProjectionType.Get() == FbxCamera::ePerspective ;
    //bPerspectice = true;
	cam.SetProjectionMode(bPerspectice);
	cam.SetProjectionPlanes(lNearPlane, lFarPlane);
	camera = cam;

}
示例#3
0
ofxFBXNode * ofxFBXScene::parseCameraInfo(FbxNode* pNode, FbxAnimLayer * pAnimLayer){
    FbxCamera* lCamera = pNode->GetCamera();

	ofxFBXCamera camera;

	camera.nodeName = lCamera->GetName();

	parsePositionCurve(camera,pAnimLayer,pNode->LclTranslation);

	parseScaleCurve(camera,pAnimLayer,pNode->LclScaling);
	//camera.originalScale.set(1,1,1);

	parseRotationCurve(camera,pAnimLayer,pNode,pNode->LclRotation);

	camera.setPosition(camera.originalPosition);

	if(pNode->GetTarget()){
		camera.target = ofxFBXNodePosition(pNode->GetTarget());
		//TODO: process lookAt animation
	}else{
		camera.target = toOf(lCamera->InterestPosition.Get());
	}


	float lNearPlane = lCamera->GetNearPlane();
	float lFarPlane = lCamera->GetFarPlane();

	//Get global scaling.
	FbxVector4 lCameraScaling = pNode->Scaling.Get();//GetGlobalPosition(pNode, 0).GetS();
	static const int  FORWARD_SCALE = 2;

	//scaling near plane and far plane
	//lNearPlane *= lCameraScaling[FORWARD_SCALE];
	//lFarPlane *= lCameraScaling[FORWARD_SCALE];


	FbxCamera::EAspectRatioMode lCamAspectRatioMode = lCamera->GetAspectRatioMode();
	double lAspectX = lCamera->AspectWidth.Get();
	double lAspectY = lCamera->AspectHeight.Get();
	double lAspectRatio = 1.333333;
	switch( lCamAspectRatioMode)
	{
	case FbxCamera::eWindowSize:
		lAspectRatio = lAspectX / lAspectY;
		break;
	case FbxCamera::eFixedRatio:
		lAspectRatio = lAspectX;

		break;
	case FbxCamera::eFixedResolution:
		lAspectRatio = lAspectX / lAspectY * lCamera->GetPixelRatio();
		break;
	case FbxCamera::eFixedWidth:
		lAspectRatio = lCamera->GetPixelRatio() / lAspectY;
		break;
	case FbxCamera::eFixedHeight:
		lAspectRatio = lCamera->GetPixelRatio() * lAspectX;
		break;
	default:
		break;

	}

	//get the aperture ratio
	double lFilmHeight = lCamera->GetApertureHeight();
	double lFilmWidth = lCamera->GetApertureWidth() * lCamera->GetSqueezeRatio();
	//here we use Height : Width
	double lApertureRatio = lFilmHeight / lFilmWidth;


	//change the aspect ratio to Height : Width
	lAspectRatio = 1 / lAspectRatio;
	//revise the aspect ratio and aperture ratio
	FbxCamera::EGateFit lCameraGateFit = lCamera->GateFit.Get();
	switch( lCameraGateFit )
	{

	case FbxCamera::eFitFill:
		if( lApertureRatio > lAspectRatio)  // the same as eHORIZONTAL_FIT
		{
			lFilmHeight = lFilmWidth * lAspectRatio;
			lCamera->SetApertureHeight( lFilmHeight);
			lApertureRatio = lFilmHeight / lFilmWidth;
		}
		else if( lApertureRatio < lAspectRatio) //the same as eVERTICAL_FIT
		{
			lFilmWidth = lFilmHeight / lAspectRatio;
			lCamera->SetApertureWidth( lFilmWidth);
			lApertureRatio = lFilmHeight / lFilmWidth;
		}
		break;
	case FbxCamera::eFitVertical:
		lFilmWidth = lFilmHeight / lAspectRatio;
		lCamera->SetApertureWidth( lFilmWidth);
		lApertureRatio = lFilmHeight / lFilmWidth;
		break;
	case FbxCamera::eFitHorizontal:
		lFilmHeight = lFilmWidth * lAspectRatio;
		lCamera->SetApertureHeight( lFilmHeight);
		lApertureRatio = lFilmHeight / lFilmWidth;
		break;
	case FbxCamera::eFitStretch:
		lAspectRatio = lApertureRatio;
		break;
	case FbxCamera::eFitOverscan:
		if( lFilmWidth > lFilmHeight)
		{
			lFilmHeight = lFilmWidth * lAspectRatio;
		}
		else
		{
			lFilmWidth = lFilmHeight / lAspectRatio;
		}
		lApertureRatio = lFilmHeight / lFilmWidth;
		break;
	case FbxCamera::eFitNone:
	default:
		break;
	}
	//change the aspect ratio to Width : Height
	lAspectRatio = 1 / lAspectRatio;

	double lFieldOfViewX = 0.0;
	double lFieldOfViewY = 0.0;
	if ( lCamera->GetApertureMode() == FbxCamera::eVertical)
	{
		lFieldOfViewY = lCamera->FieldOfView.Get();
		lFieldOfViewX = VFOV2HFOV( lFieldOfViewY, 1 / lApertureRatio);
	}
	else if (lCamera->GetApertureMode() == FbxCamera::eHorizontal)
	{
		lFieldOfViewX = lCamera->FieldOfView.Get(); //get HFOV
		lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio);
	}
	else if (lCamera->GetApertureMode() == FbxCamera::eFocalLength)
	{
		lFieldOfViewX = lCamera->ComputeFieldOfView(lCamera->FocalLength.Get());    //get HFOV
		lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio);
	}
	else if (lCamera->GetApertureMode() == FbxCamera::eHorizAndVert) {
		lFieldOfViewX = lCamera->FieldOfViewX.Get();
		lFieldOfViewY = lCamera->FieldOfViewY.Get();
	}


	//revise the Perspective since we have film offset
	double lFilmOffsetX = lCamera->FilmOffsetX.Get();
	double lFilmOffsetY = lCamera->FilmOffsetY.Get();
	lFilmOffsetX = 0 - lFilmOffsetX / lFilmWidth * 2.0;
	lFilmOffsetY = 0 - lFilmOffsetY / lFilmHeight * 2.0;

	camera.setFov(lFieldOfViewY);
	camera.setNearClip(lNearPlane);
	camera.setFarClip(lFarPlane);


	camerasList.push_back(camera);
	return &camerasList.back();


}
示例#4
0
SceneNode *SceneConverter::makeSceneNode(FbxNode *node)
{
    SceneNode *sceneNode = new SceneNode();

    if (node->GetParent() == NULL) // The root
    {
        // Type
        sceneNode->type = FbxString("root");
        
        // Name
        sceneNode->attributes.push_back(std::make_pair(FbxString("name"), node->GetName()));
        
        // Transformation
        FbxAMatrix m = node->EvaluateGlobalTransform();

        const FbxVector4 translation = m.GetT();
        const FbxVector4 rotation    = m.GetR();
        const FbxVector4 scaling     = m.GetS();
        
        char buffer[1024];
        FBXSDK_sprintf(buffer, 1024, "s:%8.5f,%8.5f,%8.5f,r:%8.5f,%8.5f,%8.5f,t:%8.5f,%8.5f,%8.5f",
            (float)scaling[0], (float)scaling[1], (float)scaling[2],
            (float)rotation[0], (float)rotation[1], (float)rotation[2],
            (float)translation[0], (float)translation[1], (float)translation[2]);

        sceneNode->attributes.push_back(std::make_pair(FbxString("transform"), FbxString(buffer)));
    }
    else
    {
        FbxCamera *camera = node->GetCamera();
        if (camera != NULL)
        {
            sceneNode->type = FbxString("camera");
        
            sceneNode->attributes.push_back(std::make_pair(FbxString("name"), node->GetName()));

            sceneNode->attributes.push_back(std::make_pair(FbxString("fixed"), FbxString("true")));

            FbxVector4 position = camera->EvaluatePosition();
            FbxVector4 center = camera->EvaluateLookAtPosition();
            // FIXME: seems EvaluateUpDirection doesn't give correct result as it 
            // is affected by its parent nodes' tranforms however we attach camera
            // to the root in paper3d's scene.
            // FbxVector4 up = camera->EvaluateUpDirection(position, center);
            FbxDouble3 up = camera->UpVector.Get();

            char buffer[1024];
            FBXSDK_sprintf(buffer, 1024, "eye:%8.5f,%8.5f,%8.5f,center:%8.5f,%8.5f,%8.5f,up:%8.5f,%8.5f,%8.5f",
                    (float)position[0], (float)position[1], (float)position[2],
                    (float)center[0], (float)center[1], (float)center[2],
                    (float)up[0], (float)up[1], (float)up[2]);
            sceneNode->attributes.push_back(std::make_pair(FbxString("lookat"), FbxString(buffer)));

            float nearZ = (float)camera->GetNearPlane();
            float farZ = (float)camera->GetFarPlane();

            if (camera->ProjectionType.Get() == FbxCamera::ePerspective)
            {
                FbxCamera::EAspectRatioMode lCamAspectRatioMode = camera->GetAspectRatioMode();
                double lAspectX = camera->AspectWidth.Get();
                double lAspectY = camera->AspectHeight.Get();
                double lAspectRatio = 1.333333;
                switch( lCamAspectRatioMode)
                {
                    case FbxCamera::eWindowSize:
                        lAspectRatio = lAspectX / lAspectY;
                        break;
                    case FbxCamera::eFixedRatio:
                        lAspectRatio = lAspectX;

                        break;
                    case FbxCamera::eFixedResolution:
                        lAspectRatio = lAspectX / lAspectY * camera->GetPixelRatio();
                        break;
                    case FbxCamera::eFixedWidth:
                        lAspectRatio = camera->GetPixelRatio() / lAspectY;
                        break;
                    case FbxCamera::eFixedHeight:
                        lAspectRatio = camera->GetPixelRatio() * lAspectX;
                        break;
                    default:
                        break;

                }

                //get the aperture ratio
                double lFilmHeight = camera->GetApertureHeight();
                double lFilmWidth = camera->GetApertureWidth() * camera->GetSqueezeRatio();
                //here we use Height : Width
                double lApertureRatio = lFilmHeight / lFilmWidth;

                //change the aspect ratio to Height : Width
                lAspectRatio = 1 / lAspectRatio;
                //revise the aspect ratio and aperture ratio
                FbxCamera::EGateFit lCameraGateFit = camera->GateFit.Get();
                switch( lCameraGateFit )
                {

                    case FbxCamera::eFitFill:
                        if( lApertureRatio > lAspectRatio)  // the same as eHORIZONTAL_FIT
                        {
                            lFilmHeight = lFilmWidth * lAspectRatio;
                            camera->SetApertureHeight( lFilmHeight);
                            lApertureRatio = lFilmHeight / lFilmWidth;
                        }
                        else if( lApertureRatio < lAspectRatio) //the same as eVERTICAL_FIT
                        {
                            lFilmWidth = lFilmHeight / lAspectRatio;
                            camera->SetApertureWidth( lFilmWidth);
                            lApertureRatio = lFilmHeight / lFilmWidth;
                        }
                        break;
                    case FbxCamera::eFitVertical:
                        lFilmWidth = lFilmHeight / lAspectRatio;
                        camera->SetApertureWidth( lFilmWidth);
                        lApertureRatio = lFilmHeight / lFilmWidth;
                        break;
                    case FbxCamera::eFitHorizontal:
                        lFilmHeight = lFilmWidth * lAspectRatio;
                        camera->SetApertureHeight( lFilmHeight);
                        lApertureRatio = lFilmHeight / lFilmWidth;
                        break;
                    case FbxCamera::eFitStretch:
                        lAspectRatio = lApertureRatio;
                        break;
                    case FbxCamera::eFitOverscan:
                        if( lFilmWidth > lFilmHeight)
                        {
                            lFilmHeight = lFilmWidth * lAspectRatio;
                        }
                        else
                        {
                            lFilmWidth = lFilmHeight / lAspectRatio;
                        }
                        lApertureRatio = lFilmHeight / lFilmWidth;
                        break;
                    case FbxCamera::eFitNone:
                    default:
                        break;
                }
                //change the aspect ratio to Width : Height
                lAspectRatio = 1 / lAspectRatio;

#define HFOV2VFOV(h, ar) (2.0 * atan((ar) * tan( (h * FBXSDK_PI_DIV_180) * 0.5)) * FBXSDK_180_DIV_PI) //ar : aspectY / aspectX
#define VFOV2HFOV(v, ar) (2.0 * atan((ar) * tan( (v * FBXSDK_PI_DIV_180) * 0.5)) * FBXSDK_180_DIV_PI) //ar : aspectX / aspectY
                double lFieldOfViewX = 0.0;
                double lFieldOfViewY = 0.0;
                if (camera->GetApertureMode() == FbxCamera::eVertical)
                {
                    lFieldOfViewY = camera->FieldOfView.Get();
                    lFieldOfViewX = VFOV2HFOV( lFieldOfViewY, 1 / lApertureRatio);
                }
                else if (camera->GetApertureMode() == FbxCamera::eHorizontal)
                {
                    lFieldOfViewX = camera->FieldOfView.Get(); //get HFOV
                    lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio);
                }
                else if (camera->GetApertureMode() == FbxCamera::eFocalLength)
                {
                    lFieldOfViewX = camera->ComputeFieldOfView(camera->FocalLength.Get());    //get HFOV
                    lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio);
                }
                else if (camera->GetApertureMode() == FbxCamera::eHorizAndVert) 
                {
                    lFieldOfViewX = camera->FieldOfViewX.Get();
                    lFieldOfViewY = camera->FieldOfViewY.Get();
                }
#undef HFOV2VFOV
#undef VFOV2HFOV

                FBXSDK_sprintf(buffer, 1024, "perspective,fov:%8.5f,aspect:-1,znear:%8.5f,zfar:%8.5f",
                        (float)lFieldOfViewY, nearZ, farZ);
                sceneNode->attributes.push_back(std::make_pair(FbxString("projection"), FbxString(buffer)));

            }
            else
            {
                FBXSDK_sprintf(buffer, 1024, "orthogonal,aspect:-1,znear:%8.5f,zfar:%8.5f", nearZ, farZ);
                sceneNode->attributes.push_back(std::make_pair(FbxString("projection"), FbxString(buffer)));
            }

                
            m_numCameras++;
        }
        else
        {
            FbxLight *light = node->GetLight();
            if (light != NULL)
            {
                m_numLights++;

                FBX_ASSERT(!"Not implemented!");
            }
            else
            {
                // Type
                sceneNode->type = FbxString("drawable");

                // Name
                sceneNode->attributes.push_back(std::make_pair(FbxString("name"), node->GetName()));

                // Transformation
                FbxAMatrix m = node->EvaluateLocalTransform();
                //FbxAMatrix m1 = node->EvaluateGlobalTransform();


                const FbxVector4 translation = m.GetT();
                const FbxVector4 rotation    = m.GetR();
                const FbxVector4 scaling     = m.GetS();

                float s[3], r[3], t[3];
                t[0] = (float)translation.mData[0];
                t[1] = (float)translation.mData[1];
                t[2] = (float)translation.mData[2];

                r[0] = (float)(rotation[0] * FBXSDK_DEG_TO_RAD);
                r[1] = (float)(rotation[1] * FBXSDK_DEG_TO_RAD);
                r[2] = (float)(rotation[2] * FBXSDK_DEG_TO_RAD);

                s[0] = (float)scaling[0];
                s[1] = (float)scaling[1];
                s[2] = (float)scaling[2];

                //const FbxVector4 translation1 = m1.GetT();
                //const FbxVector4 rotation1    = m1.GetR();
                //const FbxVector4 scaling1     = m1.GetS();


                char buffer[1024];
                FBXSDK_sprintf(buffer, 1024, "s:%8.5f,%8.5f,%8.5f,r:%8.5f,%8.5f,%8.5f,t:%8.5f,%8.5f,%8.5f",
                        s[0], s[1], s[2], r[0], r[1], r[2], t[0], t[1], t[2]);

                sceneNode->attributes.push_back(std::make_pair(FbxString("transform"), FbxString(buffer)));

                // Mesh
                //if (node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eCamera)
                //{
                //    FBXSDK_printf("f**k");
                //}

                static FbxUInt32 i = 0;
                if (node->GetMesh() == NULL)
                {
                    sceneNode->type = FbxString("node");
                }
                else
                {
                    const char *meshName = node->GetMesh()->GetName();
                    if (meshName == NULL || meshName[0] == 0)
                    {
                        meshName = node->GetName();
                    }

                    FbxString prefix;
                    if (meshName == NULL || meshName[0] == 0)
                    {
                        prefix = FbxString("mesh_") + FbxString(int(i++));
                    }
                    else
                    {
                        prefix = FbxString(meshName);
                    }
                    sceneNode->geometry = prefix + FbxString(".") + m_arguments->meshFormat;

                    // Material
                    FbxSurfaceMaterial *material = node->GetMaterial(0); 

                    if (material != NULL)
                    {
                        // This only gets the material of type sDiffuse, you probably need to
                        // traverse all Standard Material Property by its name to get all
                        // possible textures.
                        FbxProperty prop = material->FindProperty(FbxSurfaceMaterial::sDiffuse);

                        // Check if it's layeredtextures
                        int layeredTextureCount = prop.GetSrcObjectCount<FbxLayeredTexture>();

                        if (prop.GetSrcObjectCount<FbxTexture>() > 0)
                        {
                            FbxFileTexture *lTex = prop.GetSrcObject<FbxFileTexture>(0);
                            FbxString filename = FbxPathUtils::GetFileName(lTex->GetFileName());
                            sceneNode->texture = filename.Lower();

                            m_textures.push_back(FbxString(lTex->GetFileName()));
                        }

                        // root node is not counted as a drawable.
                        m_numDrawables++;
                    }
                }
            }
        }
    }
    
    return sceneNode;
}
void CameraZoom(FbxScene* pScene, int pZoomDepth, int pZoomMode)
{
    FbxCamera* lCamera = GetCurrentCamera(pScene);
    if( lCamera == NULL)
        return;
    if( pZoomMode == SceneContext::ZOOM_FOCAL_LENGTH)
    {
        if (lCamera->ProjectionType.Get() == FbxCamera::ePerspective)
        {
            double lTransform = 0 - pZoomDepth / 100.0;

            double lApertureW = lCamera->GetApertureWidth();
            lApertureW = TransformAperture( lApertureW, lTransform);

            double lApertureH = lCamera->GetApertureHeight();
            lApertureH = TransformAperture( lApertureH, lTransform);

            UpdatePerspCameraAttributes( lCamera, lApertureW, lApertureH);


        }
        else
        {
            if( pZoomDepth > 0)
                gsOrthoCameraScale *= 0.8;
            else
                gsOrthoCameraScale *= 1.25;
        }
    }
    else
    {
        FbxNode*   lCameraNode = lCamera ? lCamera->GetNode() : NULL;

        // Compute the camera position and direction.
        FbxVector4 lEye(0,0,1);
        FbxVector4 lCenter(0,0,0);
        FbxVector4 lForward(0,0,0);

        if (lCamera)
        {
            lEye = lCamera->Position.Get();
        }

        if (lCameraNode && lCameraNode->GetTarget())
        {
            lCenter = lCameraNode->GetTarget()->LclTranslation.Get();
            lForward = lCenter - lEye;
        }
        else
        {
            if (!lCameraNode || IsProducerCamera(pScene, lCamera))
            {
                if (lCamera)
                {
                    lCenter = lCamera->InterestPosition.Get();
                    lForward = lCenter - lEye;
                }
            }
            else
            {
                // Get the direction
                FbxAMatrix lGlobalRotation;
                FbxVector4 lRotationVector( lCameraNode->LclRotation.Get());
                lGlobalRotation.SetR(lRotationVector);

                // Set the center.
                // A camera with rotation = {0,0,0} points to the X direction. So create a
                // vector in the X direction, rotate that vector by the global rotation amount
                // and then position the center by scaling and translating the resulting vector
                lRotationVector = FbxVector4(1.0,0,0);
                lForward = lGlobalRotation.MultT(lRotationVector);
            }
        }
        lForward.Normalize();
        lEye += lForward * pZoomDepth;
        FbxDouble3 lPosition(lEye[0], lEye[1], lEye[2]);
        lCamera->Position.Set(lPosition);
        
    }
}
// Get the animated parameters of a camera contained in the scene
// and store them in the associated member variables contained in 
// the camera.
void GetCameraAnimatedParameters(FbxNode* pNode, FbxTime& pTime, FbxAnimLayer* pAnimLayer)
{
    FbxCamera* lCamera = (FbxCamera*) pNode->GetNodeAttribute();
    lCamera->Position.Set(GetGlobalPosition(pNode, pTime).GetT());

    FbxAnimCurve* fc = lCamera->Roll.GetCurve(pAnimLayer);
    if (fc)
        lCamera->Roll.Set(fc->Evaluate(pTime));

    FbxCamera::EApertureMode lCameraApertureMode = lCamera->GetApertureMode();
    if (lCameraApertureMode == FbxCamera::eHorizontal || 
        lCameraApertureMode == FbxCamera::eVertical) 
    {
        double lFieldOfView = lCamera->FieldOfView.Get();
        fc = lCamera->FieldOfView.GetCurve(pAnimLayer);
        if (fc)
            lFieldOfView = fc->Evaluate(pTime);

        //update FOV and focal length
        lCamera->FieldOfView.Set( lFieldOfView);
        lCamera->FocalLength.Set( lCamera->ComputeFocalLength( lFieldOfView));
        
    }
    else if ( lCameraApertureMode == FbxCamera::eHorizAndVert)
    {
        double lOldFieldOfViewX = lCamera->FieldOfViewX.Get();
        double lOldFieldOfViewY = lCamera->FieldOfViewY.Get();

        //update FOV
        double lNewFieldOfViewX = lOldFieldOfViewX;
        double lNewFieldOfViewY = lOldFieldOfViewY;
        fc = lCamera->FieldOfViewX.GetCurve(pAnimLayer);
        if (fc)
            lNewFieldOfViewX = fc->Evaluate(pTime);

        fc = lCamera->FieldOfViewY.GetCurve(pAnimLayer);
        if (fc)
            lNewFieldOfViewY = fc->Evaluate(pTime);

        lCamera->FieldOfViewX.Set(lNewFieldOfViewX);
        lCamera->FieldOfViewY.Set(lNewFieldOfViewY);

        //update aspect
        double lUpdatedApertureX = lCamera->GetApertureWidth();
        double lUpdatedApertureY = lCamera->GetApertureHeight();
        lUpdatedApertureX *= tan( lNewFieldOfViewX * 0.5 * FBXSDK_PI_DIV_180) / tan( lOldFieldOfViewX * 0.5 * FBXSDK_PI_DIV_180);
        lUpdatedApertureY *= tan( lNewFieldOfViewY * 0.5 * FBXSDK_PI_DIV_180) / tan( lOldFieldOfViewY * 0.5 * FBXSDK_PI_DIV_180);
        
        lCamera->FilmWidth.Set( lUpdatedApertureX);
        lCamera->FilmHeight.Set( lUpdatedApertureY);
        lCamera->FilmAspectRatio.Set( lUpdatedApertureX / lUpdatedApertureY);


    }
    else if ( lCameraApertureMode == FbxCamera::eFocalLength)
    {
        double lFocalLength = lCamera->FocalLength.Get();
        fc = lCamera->FocalLength.GetCurve(pAnimLayer);
        if (fc && fc ->Evaluate(pTime))
            lFocalLength = fc->Evaluate( pTime);
            

        //update FOV and focal length
        lCamera->FocalLength.Set( lFocalLength);
        lCamera->FieldOfView.Set( lCamera->ComputeFieldOfView( lFocalLength));
    }
}
// Set the view to the current camera settings.
void SetCamera(FbxScene* pScene, 
               FbxTime& pTime, 
               FbxAnimLayer* pAnimLayer,
               const FbxArray<FbxNode*>& pCameraArray,
               int pWindowWidth, int pWindowHeight)
{
    // Find the current camera at the given time.
    FbxCamera* lCamera = GetCurrentCamera(pScene, pTime, pAnimLayer, pCameraArray);
    if( lCamera == NULL)
        return;
    FbxNode*   lCameraNode = lCamera ? lCamera->GetNode() : NULL;

    // Compute the camera position and direction.
    FbxVector4 lEye(0,0,1);
    FbxVector4 lCenter(0,0,0);
    FbxVector4 lUp(0,1,0);
    FbxVector4 lForward, lRight;

    if (lCamera)
    {
        lEye = lCamera->Position.Get();
        lUp = lCamera->UpVector.Get();
    }

    if (lCameraNode && lCameraNode->GetTarget())
    {
        lCenter = GetGlobalPosition(lCameraNode->GetTarget(), pTime).GetT();
    }
    else
    {
        if (!lCameraNode || IsProducerCamera(pScene, lCamera))
        {
            if (lCamera)
                lCenter = lCamera->InterestPosition.Get();
        }
        else
        {
            // Get the direction
            FbxAMatrix lGlobalRotation;
            FbxVector4 lRotationVector(GetGlobalPosition(lCameraNode, pTime).GetR());
            lGlobalRotation.SetR(lRotationVector);

            // Get the length
            FbxVector4 lInterestPosition(lCamera->InterestPosition.Get());
            FbxVector4 lCameraGlobalPosition(GetGlobalPosition(lCameraNode, pTime).GetT());
            double      lLength = (FbxVector4(lInterestPosition - lCameraGlobalPosition).Length());

            // Set the center.
            // A camera with rotation = {0,0,0} points to the X direction. So create a
            // vector in the X direction, rotate that vector by the global rotation amount
            // and then position the center by scaling and translating the resulting vector
            lRotationVector = FbxVector4(1.0,0,0);
            lCenter = lGlobalRotation.MultT(lRotationVector);
            lCenter *= lLength;
            lCenter += lEye;

            // Update the default up vector with the camera rotation.
            lRotationVector = FbxVector4(0,1.0,0);
            lUp = lGlobalRotation.MultT(lRotationVector);
        }
    }

    // Align the up vector.
    lForward = lCenter - lEye;
    lForward.Normalize();
    lRight = lForward.CrossProduct(lUp);
    lRight.Normalize();
    lUp = lRight.CrossProduct(lForward);
    lUp.Normalize();

    // Rotate the up vector with the roll value.
    double lRadians = 0;

    if (lCamera)
        lRadians = lCamera->Roll.Get() * FBXSDK_PI_DIV_180;
    lUp = lUp * cos( lRadians) + lRight * sin(lRadians);

    
    double lNearPlane = 0.01;
    if (lCamera)
        lNearPlane = lCamera->GetNearPlane();    
    double lFarPlane = 4000.0;
    if (lCamera)
        lFarPlane = lCamera->GetFarPlane();

    //Get global scaling.
    FbxVector4 lCameraScaling = GetGlobalPosition(lCameraNode, pTime).GetS();
    static const int  FORWARD_SCALE = 2;
    
    //scaling near plane and far plane
    lNearPlane *= lCameraScaling[ FORWARD_SCALE];
    lFarPlane *= lCameraScaling[ FORWARD_SCALE];






    // Get the relevant camera settings for a perspective view.
    if (lCamera && lCamera->ProjectionType.Get() == FbxCamera::ePerspective)
    {
        //get the aspect ratio
        FbxCamera::EAspectRatioMode lCamAspectRatioMode = lCamera->GetAspectRatioMode();
        double lAspectX = lCamera->AspectWidth.Get(); //ºñÀ²
        double lAspectY = lCamera->AspectHeight.Get();
        double lAspectRatio = 1.333333;
        switch( lCamAspectRatioMode)
        {
        case FbxCamera::eWindowSize:
            lAspectRatio = lAspectX / lAspectY;
            break;
        case FbxCamera::eFixedRatio:
            lAspectRatio = lAspectX;

            break;
        case FbxCamera::eFixedResolution:
            lAspectRatio = lAspectX / lAspectY * lCamera->GetPixelRatio();
            break;
        case FbxCamera::eFixedWidth:
            lAspectRatio = lCamera->GetPixelRatio() / lAspectY;
            break;
        case FbxCamera::eFixedHeight:
            lAspectRatio = lCamera->GetPixelRatio() * lAspectX;
            break;
        default:
            break;

        }

        //get the aperture ratio
        double lFilmHeight = lCamera->GetApertureHeight();
        double lFilmWidth = lCamera->GetApertureWidth() * lCamera->GetSqueezeRatio();
        //here we use Height : Width
        double lApertureRatio = lFilmHeight / lFilmWidth;


        //change the aspect ratio to Height : Width
        lAspectRatio = 1 / lAspectRatio;
        //revise the aspect ratio and aperture ratio
        FbxCamera::EGateFit lCameraGateFit = lCamera->GateFit.Get();
        switch( lCameraGateFit )
        {

        case FbxCamera::eFitFill:
            if( lApertureRatio > lAspectRatio)  // the same as eHORIZONTAL_FIT
            {
                lFilmHeight = lFilmWidth * lAspectRatio;
                lCamera->SetApertureHeight( lFilmHeight);
                lApertureRatio = lFilmHeight / lFilmWidth;
            }
            else if( lApertureRatio < lAspectRatio) //the same as eVERTICAL_FIT
            {
                lFilmWidth = lFilmHeight / lAspectRatio;
                lCamera->SetApertureWidth( lFilmWidth);
                lApertureRatio = lFilmHeight / lFilmWidth;
            }
            break;
        case FbxCamera::eFitVertical:
            lFilmWidth = lFilmHeight / lAspectRatio;
            lCamera->SetApertureWidth( lFilmWidth);
            lApertureRatio = lFilmHeight / lFilmWidth;
            break;
        case FbxCamera::eFitHorizontal:
            lFilmHeight = lFilmWidth * lAspectRatio;
            lCamera->SetApertureHeight( lFilmHeight);
            lApertureRatio = lFilmHeight / lFilmWidth;
            break;
        case FbxCamera::eFitStretch:
            lAspectRatio = lApertureRatio;
            break;
        case FbxCamera::eFitOverscan:
            if( lFilmWidth > lFilmHeight)
            {
                lFilmHeight = lFilmWidth * lAspectRatio;
            }
            else
            {
                lFilmWidth = lFilmHeight / lAspectRatio;
            }
            lApertureRatio = lFilmHeight / lFilmWidth;
            break;
        case FbxCamera::eFitNone:
        default:
            break;
        }
        //change the aspect ratio to Width : Height
        lAspectRatio = 1 / lAspectRatio;

        double lFieldOfViewX = 0.0;
        double lFieldOfViewY = 0.0;
        if ( lCamera->GetApertureMode() == FbxCamera::eVertical)
        {
                lFieldOfViewY = lCamera->FieldOfView.Get();
                lFieldOfViewX = VFOV2HFOV( lFieldOfViewY, 1 / lApertureRatio);
        }
        else if (lCamera->GetApertureMode() == FbxCamera::eHorizontal)
        {
            lFieldOfViewX = lCamera->FieldOfView.Get(); //get HFOV
            lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio);
        }
        else if (lCamera->GetApertureMode() == FbxCamera::eFocalLength)
        {
            lFieldOfViewX = lCamera->ComputeFieldOfView(lCamera->FocalLength.Get());    //get HFOV
            lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio);
        }
        else if (lCamera->GetApertureMode() == FbxCamera::eHorizAndVert) {
            lFieldOfViewX = lCamera->FieldOfViewX.Get();
            lFieldOfViewY = lCamera->FieldOfViewY.Get();
        }



        double lRealScreenRatio = (double)pWindowWidth / (double)pWindowHeight;
        int  lViewPortPosX = 0, 
            lViewPortPosY = 0, 
            lViewPortSizeX = pWindowWidth, 
            lViewPortSizeY = pWindowHeight;
        //compute the view port
        if( lRealScreenRatio > lAspectRatio)
        {
            lViewPortSizeY = pWindowHeight;
            lViewPortSizeX = (int)( lViewPortSizeY * lAspectRatio);
            lViewPortPosY = 0;
            lViewPortPosX = (int)((pWindowWidth - lViewPortSizeX) * 0.5);
        }
        else
        {
            lViewPortSizeX = pWindowWidth;
            lViewPortSizeY = (int)(lViewPortSizeX / lAspectRatio);
            lViewPortPosX = 0;
            lViewPortPosY = (int)((pWindowHeight - lViewPortSizeY) * 0.5);
        }

        //revise the Perspective since we have film offset
        double lFilmOffsetX = lCamera->FilmOffsetX.Get();
        double lFilmOffsetY = lCamera->FilmOffsetY.Get();
        lFilmOffsetX = 0 - lFilmOffsetX / lFilmWidth * 2.0;
        lFilmOffsetY = 0 - lFilmOffsetY / lFilmHeight * 2.0;

        GlSetCameraPerspective( lFieldOfViewY, lAspectRatio, lNearPlane, lFarPlane, lEye, lCenter, lUp, lFilmOffsetX, lFilmOffsetY);



    //glMatrixMode(GL_PROJECTION);
    //double lTestPerpMatrix[ 16];
    //glGetDoublev( GL_PROJECTION_MATRIX, lTestPerpMatrix);

    //lTestPerpMatrix[ 8] -= lFilmOffsetX;
    //lTestPerpMatrix[ 9] -= lFilmOffsetY;
    //
    //glLoadMatrixd( lTestPerpMatrix);
    //glMatrixMode(GL_MODELVIEW);
        

        glViewport( lViewPortPosX, lViewPortPosY, lViewPortSizeX, lViewPortSizeY);
        

    }
    // Get the relevant camera settings for an orthogonal view.
    else
    {
        double lPixelRatio = 1.0;
        if (lCamera)
            lPixelRatio = lCamera->GetPixelRatio();  

        double lLeftPlane, lRightPlane, lBottomPlane, lTopPlane;

        if(pWindowWidth < pWindowHeight) 
        {   
            lLeftPlane   = -gsOrthoCameraScale * lPixelRatio;
            lRightPlane  =  gsOrthoCameraScale * lPixelRatio;
            lBottomPlane = -gsOrthoCameraScale * pWindowHeight / pWindowWidth;
            lTopPlane    =  gsOrthoCameraScale * pWindowHeight / pWindowWidth;
        } 
        else 
        {
            pWindowWidth *= (int) lPixelRatio;
            lLeftPlane   = -gsOrthoCameraScale * pWindowWidth / pWindowHeight;
            lRightPlane  =  gsOrthoCameraScale * pWindowWidth / pWindowHeight;
            lBottomPlane = -gsOrthoCameraScale;
            lTopPlane    =  gsOrthoCameraScale;
        }

        GlSetCameraOrthogonal(lLeftPlane,
            lRightPlane,
            lBottomPlane,
            lTopPlane,
            lNearPlane,
            lFarPlane,
            lEye,
            lCenter,
            lUp);
    }
}