#include <fbxsdk.h>
#include "GetPosition.h"
#include "GlFunctions.h"
#include "SetCamera.h"
#include "SceneContext.h"
#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
FbxCamera* GetCurrentCamera(FbxScene* pScene,
FbxTime& pTime,
FbxAnimLayer* pAnimLayer,
const FbxArray<FbxNode*>& pCameraArray);
void GetCameraAnimatedParameters(FbxNode* pNode,
FbxTime& pTime,
FbxAnimLayer* pAnimLayer);
bool IsProducerCamera(FbxScene* pScene, FbxCamera* pCamera);
static double gsOrthoCameraScale = 178.0;
void SetCamera(FbxScene* pScene,
FbxTime& pTime,
FbxAnimLayer* pAnimLayer,
const FbxArray<FbxNode*>& pCameraArray,
int pWindowWidth, int pWindowHeight)
{
FbxCamera* lCamera = GetCurrentCamera(pScene, pTime, pAnimLayer, pCameraArray);
if( lCamera == NULL)
return;
FbxNode* lCameraNode = lCamera ? lCamera->GetNode() : NULL;
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
{
FbxAMatrix lGlobalRotation;
FbxVector4 lRotationVector(GetGlobalPosition(lCameraNode, pTime).GetR());
lGlobalRotation.SetR(lRotationVector);
FbxVector4 lInterestPosition(lCamera->InterestPosition.Get());
FbxVector4 lCameraGlobalPosition(GetGlobalPosition(lCameraNode, pTime).GetT());
double lLength = (FbxVector4(lInterestPosition - lCameraGlobalPosition).Length());
lRotationVector = FbxVector4(1.0,0,0);
lCenter = lGlobalRotation.MultT(lRotationVector);
lCenter *= lLength;
lCenter += lEye;
lRotationVector = FbxVector4(0,1.0,0);
lUp = lGlobalRotation.MultT(lRotationVector);
}
}
lForward = lCenter - lEye;
lForward.Normalize();
lRight = lForward.CrossProduct(lUp);
lRight.Normalize();
lUp = lRight.CrossProduct(lForward);
lUp.Normalize();
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();
FbxVector4 lCameraScaling = GetGlobalPosition(lCameraNode, pTime).GetS();
static const int FORWARD_SCALE = 2;
static const int RIGHT_SCALE = 0;
static const int UP_SCALE = 1;
lNearPlane *= lCameraScaling[ FORWARD_SCALE];
lFarPlane *= lCameraScaling[ FORWARD_SCALE];
if (lCamera && lCamera->ProjectionType.Get() == FbxCamera::ePerspective)
{
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;
}
double lFilmHeight = lCamera->GetApertureHeight();
double lFilmWidth = lCamera->GetApertureWidth() * lCamera->GetSqueezeRatio();
double lApertureRatio = lFilmHeight / lFilmWidth;
lAspectRatio = 1 / lAspectRatio;
FbxCamera::EGateFit lCameraGateFit = lCamera->GateFit.Get();
switch( lCameraGateFit )
{
case FbxCamera::eFitFill:
if( lApertureRatio > lAspectRatio)
{
lFilmHeight = lFilmWidth * lAspectRatio;
lCamera->SetApertureHeight( lFilmHeight);
lApertureRatio = lFilmHeight / lFilmWidth;
}
else if( lApertureRatio < lAspectRatio)
{
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;
}
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();
lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio);
}
else if (lCamera->GetApertureMode() == FbxCamera::eFocalLength)
{
lFieldOfViewX = lCamera->ComputeFieldOfView(lCamera->FocalLength.Get());
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;
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);
}
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);
glViewport( lViewPortPosX, lViewPortPosY, lViewPortSizeX, lViewPortSizeY);
}
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);
}
}
FbxCamera* GetCurrentCamera(FbxScene* pScene,
FbxTime& pTime,
FbxAnimLayer* pAnimLayer,
const FbxArray<FbxNode*>& pCameraArray)
{
FbxGlobalSettings& lGlobalSettings = pScene->GetGlobalSettings();
FbxGlobalCameraSettings& lGlobalCameraSettings = pScene->GlobalCameraSettings();
FbxString lCurrentCameraName = lGlobalSettings.GetDefaultCamera();
if (lGlobalCameraSettings.GetCameraProducerPerspective() == NULL &&
lGlobalCameraSettings.GetCameraProducerBottom() == NULL &&
lGlobalCameraSettings.GetCameraProducerTop() == NULL &&
lGlobalCameraSettings.GetCameraProducerFront() == NULL &&
lGlobalCameraSettings.GetCameraProducerBack() == NULL &&
lGlobalCameraSettings.GetCameraProducerRight() == NULL &&
lGlobalCameraSettings.GetCameraProducerLeft() == NULL)
{
lGlobalCameraSettings.CreateProducerCameras();
}
if (lCurrentCameraName.Compare(FBXSDK_CAMERA_PERSPECTIVE) == 0)
{
return lGlobalCameraSettings.GetCameraProducerPerspective();
}
else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_BOTTOM) == 0)
{
return lGlobalCameraSettings.GetCameraProducerBottom();
}
else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_TOP) == 0)
{
return lGlobalCameraSettings.GetCameraProducerTop();
}
else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_FRONT) == 0)
{
return lGlobalCameraSettings.GetCameraProducerFront();
}
else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_BACK) == 0)
{
return lGlobalCameraSettings.GetCameraProducerBack();
}
else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_RIGHT) == 0)
{
return lGlobalCameraSettings.GetCameraProducerRight();
}
else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_LEFT) == 0)
{
return lGlobalCameraSettings.GetCameraProducerLeft();
}
else if (lCurrentCameraName.Compare(FBXSDK_CAMERA_SWITCHER) == 0)
{
FbxCameraSwitcher* lCameraSwitcher = pScene->GlobalCameraSettings().GetCameraSwitcher();
FbxAnimCurve* lCurve = NULL;
if (lCameraSwitcher)
{
lCurve = lCameraSwitcher->CameraIndex.GetCurve(pAnimLayer);
int lCameraIndex = lCurve ? int(lCurve->Evaluate(pTime)) - 1 : 0;
if (lCameraIndex >= 0 && lCameraIndex < pCameraArray.GetCount())
{
FbxNode* lNode = pCameraArray[lCameraIndex];
GetCameraAnimatedParameters(lNode, pTime, pAnimLayer);
return (FbxCamera*) lNode->GetNodeAttribute();
}
}
}
else
{
int i;
FbxNode* lNode = NULL;
for (i = 0; i < pCameraArray.GetCount(); i++)
{
if (lCurrentCameraName.Compare(pCameraArray[i]->GetName()) == 0)
{
lNode = pCameraArray[i];
break;
}
}
if (lNode)
{
GetCameraAnimatedParameters(lNode, pTime, pAnimLayer);
return (FbxCamera*) lNode->GetNodeAttribute();
}
}
return lGlobalCameraSettings.GetCameraProducerPerspective();
}
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);
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();
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);
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);
lCamera->FocalLength.Set( lFocalLength);
lCamera->FieldOfView.Set( lCamera->ComputeFieldOfView( lFocalLength));
}
}
bool IsProducerCamera(FbxScene* pScene, FbxCamera* pCamera)
{
FbxGlobalCameraSettings& lGlobalCameraSettings = pScene->GlobalCameraSettings();
if (pCamera == lGlobalCameraSettings.GetCameraProducerPerspective())
return true;
if (pCamera == lGlobalCameraSettings.GetCameraProducerTop())
return true;
if (pCamera == lGlobalCameraSettings.GetCameraProducerBottom())
return true;
if (pCamera == lGlobalCameraSettings.GetCameraProducerFront())
return true;
if (pCamera == lGlobalCameraSettings.GetCameraProducerBack())
return true;
if (pCamera == lGlobalCameraSettings.GetCameraProducerRight())
return true;
if (pCamera == lGlobalCameraSettings.GetCameraProducerLeft())
return true;
return false;
}
FbxCamera* GetCurrentCamera(FbxScene* pScene)
{
FbxCamera* lRet = NULL;
FbxString lCurrentCameraName;
FbxGlobalCameraSettings& lGlobalCameraSettings = pScene->GlobalCameraSettings();
FbxGlobalSettings& lGlobalSettings = pScene->GetGlobalSettings();
lCurrentCameraName = lGlobalSettings.GetDefaultCamera();
if (lCurrentCameraName == FBXSDK_CAMERA_PERSPECTIVE)
{
lRet = lGlobalCameraSettings.GetCameraProducerPerspective();
}
else if (lCurrentCameraName == FBXSDK_CAMERA_TOP)
{
lRet = lGlobalCameraSettings.GetCameraProducerTop();
}
else if (lCurrentCameraName == FBXSDK_CAMERA_BOTTOM)
{
lRet = lGlobalCameraSettings.GetCameraProducerBottom();
}
else if (lCurrentCameraName == FBXSDK_CAMERA_FRONT)
{
lRet = lGlobalCameraSettings.GetCameraProducerFront();
}
else if (lCurrentCameraName == FBXSDK_CAMERA_BACK)
{
lRet = lGlobalCameraSettings.GetCameraProducerBack();
}
else if (lCurrentCameraName == FBXSDK_CAMERA_RIGHT)
{
lRet = lGlobalCameraSettings.GetCameraProducerRight();
}
else if (lCurrentCameraName == FBXSDK_CAMERA_LEFT)
{
lRet = lGlobalCameraSettings.GetCameraProducerLeft();
}
else
{
FbxNode* lCameraNode = pScene->FindNodeByName( lCurrentCameraName);
if( lCameraNode)
{
lRet = lCameraNode->GetCamera();
}
}
return lRet;
}
double TransformAperture( double pAperture, double pTransform)
{
double lTransformAperture = ( pAperture + pTransform);
if( lTransformAperture < 0.25)
{
lTransformAperture = 0.25;
}
if( lTransformAperture > 179.0)
{
lTransformAperture = 179.0;
}
return lTransformAperture;
}
void UpdatePerspCameraAttributes( FbxCamera* pCamera, double pNewApertureW, double pNewApertureH)
{
if( pCamera == NULL || FbxAnimUtilities::IsAnimated( pCamera))
return;
double lApertureWidthOrig = pCamera->GetApertureWidth();
double lApertureHeightOrig = pCamera->GetApertureHeight();
if (pCamera->GetApertureMode() == FbxCamera::eFocalLength) {
double lFLOrig = pCamera->FocalLength.Get();
double lFOVOrig = pCamera->ComputeFieldOfView(lFLOrig);
pCamera->SetApertureWidth( pNewApertureW );
pCamera->SetApertureHeight(pNewApertureH );
double lFLNew = pCamera->ComputeFocalLength(lFOVOrig);
double lFOVNew = pCamera->ComputeFieldOfView(lFLNew);
pCamera->FocalLength.Set(lFLNew);
pCamera->FieldOfView.Set(lFOVNew);
} else if (pCamera->GetApertureMode() == FbxCamera::eVertical
|| pCamera->GetApertureMode() == FbxCamera::eHorizontal) {
double lFOVOrig = pCamera->FieldOfView.Get();
double lFLOrig = pCamera->ComputeFocalLength(lFOVOrig);
pCamera->SetApertureWidth(pNewApertureW );
pCamera->SetApertureHeight(pNewApertureH );
double lFOVNew = pCamera->ComputeFieldOfView(lFLOrig);
double lFLNew = pCamera->ComputeFocalLength(lFOVNew);
pCamera->FieldOfView.Set(lFOVNew);
pCamera->FocalLength.Set(lFLNew);
} else if (pCamera->GetApertureMode() == FbxCamera::eHorizAndVert) {
double lFOVOrigX = pCamera->FieldOfViewX.Get();
double lFLOrig = pCamera->ComputeFocalLength(lFOVOrigX);
pCamera->SetApertureWidth(pNewApertureW );
pCamera->SetApertureHeight(pNewApertureH );
double lFOVNewX = pCamera->ComputeFieldOfView(lFLOrig);
double lFOVNewY = pCamera->ComputeFieldOfView(lFLOrig);
double lFLNew = pCamera->ComputeFocalLength(lFOVNewX);
pCamera->FieldOfViewY.Set(lFOVNewX);
pCamera->FieldOfViewY.Set(lFOVNewY);
pCamera->FocalLength.Set(lFLNew);
}
pCamera->SetApertureWidth(lApertureWidthOrig);
pCamera->SetApertureHeight(lApertureHeightOrig);
}
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 / 400.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;
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
{
FbxAMatrix lGlobalRotation;
FbxVector4 lRotationVector( lCameraNode->LclRotation.Get());
lGlobalRotation.SetR(lRotationVector);
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);
}
}
void CameraOrbit(FbxScene* pScene, FbxVector4 lOrigCamPos, double OrigRoll, int dX, int dY)
{
FbxCamera* lCamera = GetCurrentCamera(pScene);
if (!lCamera) return;
FbxGlobalCameraSettings& lGlobalCameraSettings = pScene->GlobalCameraSettings();
if (lCamera != lGlobalCameraSettings.GetCameraProducerPerspective()) return;
if (lCamera->LockMode.Get()) return;
if (dX == 0 && dY == 0) return;
FbxVector4 lRotationVector, lNewPosition, lCurPosition;
FbxAMatrix lRotation;
FbxVector4 lCenter = lCamera->InterestPosition.Get();
FbxVector4 lPosition = lCamera->Position.Get();
lCurPosition = lPosition-lCenter;
lNewPosition = lOrigCamPos-lCenter;
int rotX;
if (lNewPosition[2] == 0) {
rotX = 90;
} else {
rotX = (int) (atan((double)lNewPosition[0]/(double)lNewPosition[2]) * FBXSDK_180_DIV_PI);
}
bool bRoll = (((int)OrigRoll % 360) != 0);
if ( (lNewPosition[2] < 0 && !bRoll)
|| (lNewPosition[2] > 0 && bRoll) ) {
dY = -dY;
}
if (bRoll) dX = -dX;
lRotationVector[1] = -rotX;
lRotation.SetR(lRotationVector);
lNewPosition = lRotation.MultT(lNewPosition);
lRotationVector[1] = 0;
lRotationVector[0] = dY;
lRotation.SetR(lRotationVector);
lNewPosition = lRotation.MultT(lNewPosition);
lRotationVector[0] = 0;
lRotationVector[1] = rotX;
lRotation.SetR(lRotationVector);
lNewPosition = lRotation.MultT(lNewPosition);
lRotationVector[1] = -dX;
lRotation.SetR(lRotationVector);
lNewPosition = lRotation.MultT(lNewPosition);
if ( lNewPosition[0]*lCurPosition[0] < 0
&& lNewPosition[2]*lCurPosition[2] < 0) {
double lRoll = lCamera->Roll.Get();
lRoll = 180.0-lRoll;
lCamera->Roll.Set(lRoll);
}
lNewPosition = lNewPosition + lCenter;
lCamera->Position.Set(lNewPosition);
}
void CameraPan(FbxScene* pScene, FbxVector4 lOrigCamPos, FbxVector4 lOrigCamCenter, double OrigRoll, int dX, int dY) {
FbxCamera* lCamera = GetCurrentCamera(pScene);
if (!lCamera) return;
if (!IsProducerCamera(pScene, lCamera)) return;
if (lCamera->LockMode.Get()) return;
if (dX == 0 && dY == 0) return;
FbxGlobalCameraSettings& lGlobalCameraSettings = pScene->GlobalCameraSettings();
FbxVector4 lRotationXV, lRotationYV, lTranslationV;
FbxAMatrix lRotationX, lRotationY, lRotationXInverse, lRotationYInverse, lTranslation;
FbxVector4 lNewPosition = lOrigCamPos;
FbxVector4 lNewCenter = lOrigCamCenter;
if (lCamera == lGlobalCameraSettings.GetCameraProducerTop()) {
lTranslationV[0] = -dX;
lTranslationV[1] = 0;
lTranslationV[2] = dY;
} else if (lCamera == lGlobalCameraSettings.GetCameraProducerBottom()) {
lTranslationV[0] = dX;
lTranslationV[1] = 0;
lTranslationV[2] = dY;
} else if (lCamera == lGlobalCameraSettings.GetCameraProducerFront()) {
lTranslationV[0] = -dX;
lTranslationV[1] = -dY;
lTranslationV[2] = 0;
} else if (lCamera == lGlobalCameraSettings.GetCameraProducerBack()) {
lTranslationV[0] = dX;
lTranslationV[1] = -dY;
lTranslationV[2] = 0;
} else if (lCamera == lGlobalCameraSettings.GetCameraProducerRight()) {
lTranslationV[0] = 0;
lTranslationV[1] = -dY;
lTranslationV[2] = dX;
} else if (lCamera == lGlobalCameraSettings.GetCameraProducerLeft()) {
lTranslationV[0] = 0;
lTranslationV[1] = -dY;
lTranslationV[2] = -dX;
} else {
bool bRoll = (((int)OrigRoll % 360) != 0);
if (bRoll) {
dX = -dX;
dY = -dY;
}
double aZ, aY;
FbxVector4 lDist = lNewPosition - lNewCenter;
double dist = (double)(lDist[0]*lDist[0]+lDist[1]*lDist[1]+lDist[2]*lDist[2]);
if (lDist[2] == 0) {
aZ = 90.0;
} else {
aZ = (atan((double)lDist[0]/(double)lDist[2]) * FBXSDK_180_DIV_PI);
}
if (lNewPosition[2] < lNewCenter[2]) aZ += 180;
if (dist > 0.001) {
aY = (asin(sqrt((double)(lDist[1]*lDist[1])/ dist)) * FBXSDK_180_DIV_PI);
} else {
aY = 0;
}
if (lNewPosition[1] < lNewCenter[1]) aY = -aY;
lTranslationV[0] = -dX;
lTranslationV[1] = -dY;
lTranslationV[2] = 0;
lRotationYV[0] = 0;
lRotationYV[1] = -aZ;
lRotationYV[2] = 0;
lRotationY.SetR(lRotationYV);
lRotationXV[0] = aY;
lRotationXV[1] = 0;
lRotationXV[2] = 0;
lRotationX.SetR(lRotationXV);
lTranslation.SetT(lTranslationV);
lRotationYInverse = lRotationY.Inverse();
lRotationXInverse = lRotationX.Inverse();
lTranslation = lRotationYInverse * lRotationXInverse * lTranslation * lRotationY * lRotationX;
lTranslationV = lTranslation.GetT();
}
lNewPosition += lTranslationV;
lNewCenter += lTranslationV;
lCamera->Position.Set(lNewPosition);
lCamera->InterestPosition.Set(lNewCenter);
}