void FbxFileLoader::print_matrix( const FbxAMatrix& m ) const { std::cout.setf( std::ios_base::fixed, std::ios_base::floatfield ); std::cout.precision( 4 ); std::cout << "\tT : " << m.GetT()[ 0 ] << ", " << m.GetT()[ 1 ] << ", " << m.GetT()[ 2 ] << std::endl; std::cout << "\tR : " << m.GetR()[ 0 ] << ", " << m.GetR()[ 1 ] << ", " << m.GetR()[ 2 ] << std::endl; std::cout << "\tS : " << m.GetS()[ 0 ] << ", " << m.GetS()[ 1 ] << ", " << m.GetS()[ 2 ] << std::endl; }
FTransform FFbxDataConverter::ConvertTransform(FbxAMatrix Matrix) { FTransform Out; FQuat Rotation = ConvertRotToQuat(Matrix.GetQ()); FVector Origin = ConvertPos(Matrix.GetT()); FVector Scale = ConvertScale(Matrix.GetS()); Out.SetTranslation(Origin); Out.SetScale3D(Scale); Out.SetRotation(Rotation); return Out; }
// Deform the vertex array in classic linear way. void fbxLoader2::ComputeLinearDeformation(FbxAMatrix& pGlobalPosition, FbxMesh* pMesh, FbxTime& pTime, FbxPose* pPose, int frame) { // All the links must have the same link mode. FbxCluster::ELinkMode lClusterMode = ((FbxSkin*)pMesh->GetDeformer(0, FbxDeformer::eSkin))->GetCluster(0)->GetLinkMode(); int lVertexCount = pMesh->GetControlPointsCount(); FbxAMatrix* lClusterDeformation = new FbxAMatrix[lVertexCount]; memset(lClusterDeformation, 0, lVertexCount * sizeof(FbxAMatrix)); double* lClusterWeight = new double[lVertexCount]; memset(lClusterWeight, 0, lVertexCount * sizeof(double)); if (lClusterMode == FbxCluster::eAdditive) { for (int i = 0; i < lVertexCount; ++i) { lClusterDeformation[i].SetIdentity(); } } // For all skins and all clusters, accumulate their deformation and weight // on each vertices and store them in lClusterDeformation and lClusterWeight. int lSkinCount = pMesh->GetDeformerCount(FbxDeformer::eSkin); for ( int lSkinIndex=0; lSkinIndex<lSkinCount; ++lSkinIndex) { FbxSkin * lSkinDeformer = (FbxSkin *)pMesh->GetDeformer(lSkinIndex, FbxDeformer::eSkin); int lClusterCount = lSkinDeformer->GetClusterCount(); for ( int lClusterIndex=0; lClusterIndex<lClusterCount; ++lClusterIndex) { FbxCluster* lCluster = lSkinDeformer->GetCluster(lClusterIndex); if (!lCluster->GetLink()) continue; FbxAMatrix lVertexTransformMatrix; ComputeClusterDeformation(pGlobalPosition, pMesh, lCluster, lVertexTransformMatrix, pTime, pPose, frame); //lVertexTransformMatrix.Transpose(); FbxAMatrix identityM; identityM.SetIdentity(); FbxVector4 rotation = lVertexTransformMatrix.GetROnly(); FbxVector4 translation = lVertexTransformMatrix.GetT(); FbxVector4 scaling = lVertexTransformMatrix.GetS(); //rotation = FbxVector4(rotation.mData[0], rotation.mData[1], rotation.mData[2], rotation.mData[3]); //translation = FbxVector4 (translation.mData[0], translation.mData[1], translation.mData[2], translation.mData[3]); //scaling = FbxVector4 (scaling.mData[0], scaling.mData[1], scaling.mData[2], scaling.mData[3]); //lVertexTransformMatrix = FbxAMatrix(translation, rotation, scaling); //lVertexTransformMatrix = FbxAMatrix(translation, rotation, scaling); identityM = lVertexTransformMatrix * identityM; D3DXMATRIX convert = D3DXMATRIX(1,0,0,0, 0,0,1,0, 0,1,0,0, 0,0,0,1); D3DXMATRIX setMatrix = D3DXMATRIX( (float)identityM.mData[0].mData[0], (float)identityM.mData[1].mData[0], (float)identityM.mData[2].mData[0], (float)identityM.mData[3].mData[0], (float)identityM.mData[0].mData[1], (float)identityM.mData[1].mData[1], (float)identityM.mData[2].mData[1], (float)identityM.mData[3].mData[1], (float)identityM.mData[0].mData[2], (float)identityM.mData[1].mData[2], (float)identityM.mData[2].mData[2], (float)identityM.mData[3].mData[2], (float)identityM.mData[0].mData[3], (float)identityM.mData[1].mData[3], (float)identityM.mData[2].mData[3],1); //setMatrix *=0.5f; setMatrix = D3DXMATRIX( (float)identityM.mData[0].mData[0], (float)identityM.mData[1].mData[0], (float)identityM.mData[2].mData[0], (float)identityM.mData[3].mData[0], (float)identityM.mData[0].mData[1], (float)identityM.mData[1].mData[1], (float)identityM.mData[2].mData[1], (float)identityM.mData[3].mData[1], //(float)identityM.mData[0].mData[2], (float)identityM.mData[1].mData[2], (float)identityM.mData[2].mData[2], (float)identityM.mData[3].mData[1], (float)identityM.mData[0].mData[2], (float)identityM.mData[1].mData[2], (float)identityM.mData[2].mData[2], (float)identityM.mData[3].mData[2], (float)identityM.mData[0].mData[3], (float)identityM.mData[1].mData[3], (float)identityM.mData[2].mData[3], 1); //setMatrix = setMatrix*convert; ///////// juz prawie dziala. sprawdz jeszcze te addytywne itp. /// generalnie dodaj to do włosów i dorzuć poprzednią macierz, żeby liczyć przesunięcia. //setMatrix /= 2.54f; //skala jedna jest w cm, druga w inchach, nieważne czy zmieniam system skali ręcznie... bzdurka fbxa std::string nametype = lCluster->GetLink()->GetName(); animationStructure->GetSkeleton(frame)->GetBone(animationStructure->GetSkeleton(frame)->GetBoneByName(lCluster->GetLink()->GetName()))->SetTransformation(setMatrix); }//lClusterCount } delete [] lClusterDeformation; delete [] lClusterWeight; }
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; }