//ジオメトリ情報を持って来ます。 FbxAMatrix GetGeometry(FbxNode* pNode) { const FbxVector4 lT = pNode->GetGeometricTranslation(FbxNode::eSourcePivot); const FbxVector4 lR = pNode->GetGeometricRotation(FbxNode::eSourcePivot); const FbxVector4 lS = pNode->GetGeometricScaling(FbxNode::eSourcePivot); return FbxAMatrix(lT, lR, lS); }
// Get the geometry offset to a node. It is never inherited by the children. FbxAMatrix GetRotaionPivot(FbxNode* pNode) { const FbxVector4 lT = pNode->GetRotationPivot(FbxNode::eSourcePivot);// (FbxNode::eSourcePivot); const FbxVector4 lR(0,0,0,1); const FbxVector4 lS(1,1,1,1); return FbxAMatrix(lT, lR, lS); }
FbxAMatrix Utilities::GetGeometryTransformation(FbxNode* inNode) { if (!inNode) { throw std::exception("Null for mesh geometry"); } const FbxVector4 lT = inNode->GetGeometricTranslation(FbxNode::eSourcePivot); const FbxVector4 lR = inNode->GetGeometricRotation(FbxNode::eSourcePivot); const FbxVector4 lS = inNode->GetGeometricScaling(FbxNode::eSourcePivot); return FbxAMatrix(lT, lR, lS); }
void FbxLoader::ProcessBoneAndAnimation(FbxNode* node, Node& meshNode) { auto currMesh = node->GetMesh(); if(!currMesh) return; FbxVector4 lT = node->GetGeometricTranslation(FbxNode::eSourcePivot); FbxVector4 lR = node->GetGeometricRotation(FbxNode::eSourcePivot); FbxVector4 lS = node->GetGeometricScaling(FbxNode::eSourcePivot); FbxAMatrix geometryTransform = FbxAMatrix(lT, lR, lS); FbxSkin* skin = nullptr; const int deformerCnt = currMesh->GetDeformerCount(); for(int deformerIndex = 0; deformerIndex < deformerCnt; ++deformerIndex) { skin = (FbxSkin*)(currMesh->GetDeformer(deformerIndex, FbxDeformer::eSkin)); if(skin) break; } if(!skin) return; meshNode.useSkinnedMesh = true; const size_t nClusters = skin->GetClusterCount(); if(nClusters < 1) return; for(auto& clip : animationClips) clip.second->transformCurves.resize(nClusters); meshNode.bones.resize(nClusters); const int animCount = scene->GetSrcObjectCount<FbxAnimStack>(); float time = 0; for(int ci = 0; ci < nClusters; ++ci) { FbxCluster* cluster = skin->GetCluster(ci); auto elink = cluster->GetLinkMode(); std::string boneName = cluster->GetLink()->GetName(); FbxAMatrix transformMatrix, transformLinkMatrix, globalBindposeInverse; cluster->GetTransformMatrix(transformMatrix); cluster->GetTransformLinkMatrix(transformLinkMatrix); globalBindposeInverse = transformLinkMatrix.Inverse() * geometryTransform * transformMatrix; FbxNode* boneNode = cluster->GetLink(); Bone& bone = meshNode.bones[ci]; bone.name = boneName; bone.index = ci; auto T = globalBindposeInverse.GetT() * factor; if(axismode == eLeftHanded) { auto R = globalBindposeInverse.GetR(); T[0] *= -1; R[1] *= -1; R[2] *= -1; globalBindposeInverse.SetR(R); } globalBindposeInverse.SetT(T); ConvertMatrix(bone.bindPoseInverse, globalBindposeInverse); const int nCtrl = cluster->GetControlPointIndicesCount(); for(int ctrlIndex = 0; ctrlIndex < nCtrl; ++ctrlIndex) { BlendWeightPair pair; pair.boneIndex = ci; pair.weight = (float)cluster->GetControlPointWeights()[ctrlIndex]; meshNode.controlPoints[cluster->GetControlPointIndices()[ctrlIndex]].blendWeigths.push_back(pair); } FbxAMatrix preRot; auto preR = boneNode->GetPreRotation(FbxNode::eSourcePivot); preRot.SetR(preR); for(int ai = 0; ai < animCount; ++ai) { auto animStack = scene->GetSrcObject<FbxAnimStack>(ai); scene->SetCurrentAnimationStack(animStack); std::string animName = animStack->GetName(); auto& clip = animationClips[animName]; auto& transformCurve = clip->transformCurves[ci]; transformCurve.boneName = boneName; transformCurve.begin = 0; auto animLayer = animStack->GetMember<FbxAnimLayer>(0); FbxAnimCurve* fbxTCurves[3]; FbxAnimCurve* fbxRCurves[3]; FbxAnimCurve* fbxSCurves[3]; fbxTCurves[0] = boneNode->LclTranslation.GetCurve(animLayer, "X"); if(!fbxTCurves[0]) continue; fbxTCurves[1] = boneNode->LclTranslation.GetCurve(animLayer, "Y"); fbxTCurves[2] = boneNode->LclTranslation.GetCurve(animLayer, "Z"); fbxRCurves[0] = boneNode->LclRotation.GetCurve(animLayer, "X"); fbxRCurves[1] = boneNode->LclRotation.GetCurve(animLayer, "Y"); fbxRCurves[2] = boneNode->LclRotation.GetCurve(animLayer, "Z"); fbxSCurves[0] = boneNode->LclScaling.GetCurve(animLayer, "X"); fbxSCurves[1] = boneNode->LclScaling.GetCurve(animLayer, "Y"); fbxSCurves[2] = boneNode->LclScaling.GetCurve(animLayer, "Z"); // set & apply filter FbxAnimCurveFilterKeyReducer keyReducer; keyReducer.SetKeySync(false); keyReducer.Apply(fbxTCurves, 3); keyReducer.Apply(fbxSCurves, 3); keyReducer.SetKeySync(true); keyReducer.Apply(fbxRCurves, 3); FbxAnimCurveFilterUnroll unroll; unroll.SetForceAutoTangents(true); unroll.Apply(fbxRCurves, 3); FbxAnimCurveFilterTSS tss; FbxTime tt; tt.SetSecondDouble(-fbxTCurves[0]->KeyGetTime(0).GetSecondDouble()); tss.SetShift(tt); tss.Apply(fbxTCurves, 3); tss.Apply(fbxRCurves, 3); tss.Apply(fbxSCurves, 3); // // process curves if(fbxTCurves[0]->KeyGetCount() > 0) { ProcessAnimCurveT(fbxTCurves, transformCurve); ProcessAnimCurveS(fbxSCurves, transformCurve); ProcessAnimCurveR(fbxRCurves, transformCurve, preRot); //clamping by reduced keyframes clip->startTime = 0; clip->lengthInSeconds = transformCurve.end; clip->lengthInFrames = (int)(1.5f + (transformCurve.end / (1 / 30.0f))); } } // animations loop } // cluster loop }
FbxModelData* FBXLoader::loadModel( const char* aFile ) { FBX_LOG("FBXLoader Creating ModelData..."); myLoadingModel = new FbxModelData; FBX_LOG("Success!"); FBX_LOG("FBXLoader Creating TextureData..."); myLoadingModel->myTextureData = new TextureData(); FBX_LOG("Success!"); FBX_LOG("FBXLoader Loading Scene..."); auto scene = LoadScene(aFile); FBX_LOG("Successfully loaded scene!"); FBX_LOG("FBXLoader Loading Textures..."); //TextureData const int lTextureCount = scene->GetTextureCount(); for (int lTextureIndex = 0; lTextureIndex < lTextureCount; ++lTextureIndex) { FbxTexture * lTexture = scene->GetTexture(lTextureIndex); FbxFileTexture * lFileTexture = reinterpret_cast<FbxFileTexture*>(lTexture); if (lFileTexture && !lFileTexture->GetUserDataPtr()) { const FbxString lFileName = lFileTexture->GetFileName(); unsigned int lTextureObject = 0; lTextureObject; bool lStatus = false; lStatus; const FbxString lAbsFbxFileName = FbxPathUtils::Resolve(aFile); const FbxString lAbsFolderName = FbxPathUtils::GetFolderName(lAbsFbxFileName); const FbxString lTextureFileName = lAbsFolderName + "\\" + lFileTexture->GetRelativeFileName();// FbxPathUtils::GetFileName(lFileName); const FbxString lResolvedFileName = lAbsFolderName + "\\" + FbxPathUtils::GetFileName(lFileName);// lFileTexture->GetRelativeFileName();;// FbxPathUtils::Bind(lAbsFolderName, lTextureFileName); TextureInfo info; info.myFileName = lResolvedFileName; //info.myFileName += "\\"; info.myFileName = lFileTexture->GetRelativeFileName(); myLoadingModel->myTextureData->myTextures.push_back(info); lFileTexture->SetFileName(lResolvedFileName); } } FBX_LOG("Success!"); FBX_LOG("FBXLoader Loading Animations..."); FbxArray<FbxString*> animationNames; FbxArray<FbxPose*> poses; scene->FillAnimStackNameArray(animationNames); scene->FillPoseArray(poses); FbxAnimStack * lCurrentAnimationStack = nullptr; FbxAnimLayer* lCurrentAnimLayer = nullptr; if(animationNames.GetCount() > 0) { lCurrentAnimationStack = scene->FindMember<FbxAnimStack>(animationNames[0]->Buffer()); if (lCurrentAnimationStack != NULL) { lCurrentAnimLayer = lCurrentAnimationStack->GetMember<FbxAnimLayer>(); } } //lCurrentAnimLayer->IsR myLoadingModel->myAnimation = new AnimationData(); FbxPose* pose = nullptr; if(poses.GetCount() > 0) { pose = poses[0]; } LoadAnimation(*myLoadingModel->myAnimation,scene->GetRootNode(),FbxAMatrix(),pose, lCurrentAnimLayer,-1); LoadNodeRecursive(myLoadingModel, *myLoadingModel->myAnimation, scene->GetRootNode(), FbxAMatrix(), pose, lCurrentAnimLayer, -1); FBX_LOG("Success!"); return myLoadingModel; }