reNode* reFBXAsset::importNode(FbxNode* fbxNode, reNode* parent) { reNode* node = new reNode; node->name(fbxNode->GetName()); FbxMatrix mat = fbxNode->EvaluateGlobalTransform(FbxTime(0)); FbxNode *fbxParent = fbxNode->GetParent(); if (!fbxParent) { node->transform (reTransform(fromFBXMatrix(mat))); } else { FbxMatrix pmat = fbxParent->EvaluateGlobalTransform(FbxTime(0)); node->transform(reTransform(fromFBXMatrix(pmat.Inverse()) * fromFBXMatrix(mat))); } if (fbxNode->GetNodeAttribute() ) { FbxNodeAttribute::EType attrType = (fbxNode->GetNodeAttribute()->GetAttributeType()); switch (attrType) { case FbxNodeAttribute::eMesh: reMesh* mesh = importMesh(fbxNode); node->renderables->add(mesh); break; } } for(int i = 0; i < fbxNode->GetChildCount(); i++) { reNode* child = importNode(fbxNode->GetChild(i), node); node->children->add(child); } return node; };
void LoaderFbxMesh::parseTransformMatrix(FbxCluster* cluster, FbxMesh* mesh, FbxPose* fbxPose, LoaderFbxMeshDesc* meshDesc, int index) { FbxCluster::ELinkMode clusterMode = cluster->GetLinkMode(); FbxAMatrix globalPosition = getGlobalPosition(mesh->GetNode(), FbxTime(0), fbxPose, &globalPosition); globalPosition *= getGeometry(mesh->GetNode()); FbxAMatrix fbxMatrix; // if(clusterMode == FbxCluster::eAdditive && cluster->GetAssociateModel()) // fbxMatrix = parseTransformMatrixAssociateModel(cluster, mesh, fbxPose, globalPosition); // else // fbxMatrix = parseTransformMatrixOther(cluster, mesh, fbxPose, globalPosition); fbxMatrix = parseTransformMatrix_debug(cluster, mesh, fbxPose, globalPosition); // fbxMatrix = convertToLeftHanded(fbxMatrix); Float4x4 offsetMatrix = translateMatrixToFloat4x4(fbxMatrix); meshDesc->setOffsetMatrix(index, offsetMatrix); }
//----------------------------------------------------------------------------------- static void ImportMotions(SceneImport* import, FbxScene* scene, Matrix4x4& matrixStackTop, std::map<int, FbxNode*>& map, float framerate) { int animationCount = scene->GetSrcObjectCount<FbxAnimStack>(); if (animationCount == 0) { return; } if (import->skeletons.size() == 0) { return; } //Timing information for animation in this scene. How fast is the framerate in this file? FbxGlobalSettings& settings = scene->GetGlobalSettings(); FbxTime::EMode timeMode = settings.GetTimeMode(); double sceneFramerate; if (timeMode == FbxTime::eCustom) { sceneFramerate = settings.GetCustomFrameRate(); } else { sceneFramerate = FbxTime::GetFrameRate(timeMode); } //Only supporting one skeleton for now, update when needed. uint32_t skeletonCount = import->skeletons.size(); Skeleton* skeleton= import->skeletons.at(0); ASSERT_OR_DIE(skeletonCount == 1, "Had multiple skeletons, we only support 1!"); //Time between frames FbxTime advance; advance.SetSecondDouble((double)(1.0f / framerate)); for (int animIndex = 0; animIndex < animationCount; ++animIndex) { //Import Motions FbxAnimStack* anim = scene->GetSrcObject<FbxAnimStack>(); if (nullptr == anim) { continue; } FbxTime startTime = anim->LocalStart; FbxTime endTime = anim->LocalStop; FbxTime duration = endTime - startTime; scene->SetCurrentAnimationStack(anim); const char* motionName = anim->GetName(); float timeSpan = duration.GetSecondDouble(); AnimationMotion* motion = new AnimationMotion(motionName, timeSpan, framerate, skeleton); int jointCount = skeleton->GetJointCount(); for (int jointIndex = 0; jointIndex < jointCount; ++jointIndex) { FbxNode* node = map[jointIndex]; //Extracting world position //local, you would need to grab parent as well Matrix4x4* boneKeyframes = motion->GetJointKeyframes(jointIndex); FbxTime evalTime = FbxTime(0); for (uint32_t frameIndex = 0; frameIndex < motion->m_frameCount; ++frameIndex) { Matrix4x4* boneKeyframe = boneKeyframes + frameIndex; Matrix4x4 boneTransform = GetNodeWorldTransformAtTime(node, evalTime, matrixStackTop); double seconds = evalTime.GetSecondDouble(); seconds = seconds; *boneKeyframe = boneTransform; evalTime += advance; } } import->motions.push_back(motion); } }