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); }
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; }
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(); }
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); } }