std::string readFbxAnimation(KFbxNode* pNode,
    KFbxScene& fbxScene,
    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimManager,
    const char* targetName)
{
    std::string result;
    for (int i = 0; i < fbxScene.GetSrcObjectCount(FBX_TYPE(KFbxAnimStack)); ++i)
    {
        KFbxAnimStack* pAnimStack = KFbxCast<KFbxAnimStack>(fbxScene.GetSrcObject(FBX_TYPE(KFbxAnimStack), i));

        int nbAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(KFbxAnimLayer));

        const char* pTakeName = pAnimStack->GetName();

        if (!pTakeName || !*pTakeName)
            continue;

        for (int j = 0; j < nbAnimLayers; j++)
        {
            KFbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(KFbxAnimLayer), j);

            if (osgAnimation::Animation* pAnimation = readFbxAnimation(
                pNode, pAnimLayer, pTakeName, targetName, pAnimManager))
            {
                result = targetName;
            }
        }
    }
    return result;
}
Example #2
0
void readAnimation(KFbxNode* pNode, KFbxScene& fbxScene, const std::string& targetName,
    osg::ref_ptr<osgAnimation::AnimationManagerBase>& pAnimationManager,
    KFbxMesh* pMesh, int nBlendShape, int nBlendShapeChannel, int nShape)
{
    for (int i = 0; i < fbxScene.GetSrcObjectCount(FBX_TYPE(KFbxAnimStack)); ++i)
    {
        KFbxAnimStack* pAnimStack = KFbxCast<KFbxAnimStack>(fbxScene.GetSrcObject(FBX_TYPE(KFbxAnimStack), i));

        int nbAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(KFbxAnimLayer));

        const char* pTakeName = pAnimStack->GetName();

        if (!pTakeName || !*pTakeName)
            continue;

        for (int j = 0; j < nbAnimLayers; j++)
        {
            KFbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(KFbxAnimLayer), j);

            KFbxAnimCurve* pCurve = pMesh->GetShapeChannel(nBlendShape, nBlendShapeChannel, pAnimLayer, false);

            if (!pCurve)
            {
                continue;
            }

            int nKeys = pCurve->KeyGetCount();
            if (!nKeys)
            {
                continue;
            }

            osgAnimation::FloatLinearChannel* pChannel = new osgAnimation::FloatLinearChannel;
            std::vector<osgAnimation::TemplateKeyframe<float> >& keyFrameCntr = *pChannel->getOrCreateSampler()->getOrCreateKeyframeContainer();

            for (int k = 0; k < nKeys; ++k)
            {
                KFbxAnimCurveKey key = pCurve->KeyGet(k);
                double fTime = key.GetTime().GetSecondDouble();
                float fValue = static_cast<float>(key.GetValue() * 0.01);
                keyFrameCntr.push_back(osgAnimation::FloatKeyframe(fTime,fValue));
            }

            pChannel->setTargetName(targetName);
            std::stringstream ss;
            ss << nShape;
            pChannel->setName(ss.str());
            addChannel(pChannel, pAnimationManager, pTakeName);
        }
    }
}
void FBXModel::load(const GraphicsDevice& device, const std::string& filename, unsigned keyframes)
{
	if (effect.resource == 0)
		effect = Effect::createFromFile<FBXEffect>(device, Config::getValue(ConfigKeys::fbxEffectPath));

	defaultTexture = Texture::createFromFile(device, defaultTexturePath);
	
	vertexDeclaration = device.createVertexDeclaration(FBXInstance::vertexElements);

	KFbxSdkManager* sdkManager = KFbxSdkManager::Create();
	KFbxIOSettings* ios = KFbxIOSettings::Create(sdkManager, IOSROOT);
	sdkManager->SetIOSettings(ios);

	// Create an importer using our sdk manager.
	KFbxImporter* importer = KFbxImporter::Create(sdkManager, "");

	importer->Initialize(filename.c_str(), -1, sdkManager->GetIOSettings());

	// Create a new scene so it can be populated by the imported file.
	KFbxScene* scene = KFbxScene::Create(sdkManager, "");

	// Import the contents of the file into the scene.
	importer->Import(scene);

	KFbxNode* rootBone = 0;
	KFbxNode* rootNode = scene->GetRootNode();

	KFbxAnimStack* animStack = KFbxCast<KFbxAnimStack>(scene->GetSrcObject(FBX_TYPE(KFbxAnimStack), 0));
	KFbxAnimLayer* animLayer = 0;

	if (animStack)
	{
		animLayer = animStack->GetMember(FBX_TYPE(KFbxAnimLayer), 0);
		scene->GetEvaluator()->SetContext(animStack);
	}

	loadBones(rootNode, &rootBone, animLayer);
	loadMeshes(rootNode, device, KFbxGeometryConverter(sdkManager));

	if (animLayer)
	{
		for (unsigned i = 0; i <= keyframes; ++i)
			boneMatricesMap[i] = traverseBones(i, rootBone, Matrix::identity, MatrixCollection(bones.size()));
	}

	sdkManager->Destroy();

	loaded = true;
}
Example #4
0
// -- Actions ----------------------------------------------------------------
void Scene::setAnimation(int index)
{
    LOG_INFO( "Scene::setAnimation("<< index <<")");

    int numAnimStacks = animationNames.GetCount();
    if (!numAnimStacks || index >= numAnimStacks) {
        return;
    }

    // select the base layer from the animation stack
    KFbxAnimStack* currentAnimationStack = fbxScene->FindMember(FBX_TYPE(KFbxAnimStack), animationNames[index]->Buffer());
    if (currentAnimationStack == NULL) {
        // this is a problem. The anim stack should be found in the scene!
        LOG_INFO( "The anim stack should be found in the scene!\n");
        return;
    }

    // we assume that the first animation layer connected to the animation stack is the base layer
    // (this is the assumption made in the FBXSDK)
    currentAnimationLayer = currentAnimationStack->GetMember(FBX_TYPE(KFbxAnimLayer), 0);
    fbxScene->GetEvaluator()->SetContext(currentAnimationStack);

    KFbxTakeInfo* lCurrentTakeInfo = fbxScene->GetTakeInfo(*(animationNames[index]));
    if (lCurrentTakeInfo) {
        start = lCurrentTakeInfo->mLocalTimeSpan.GetStart();
        stop = lCurrentTakeInfo->mLocalTimeSpan.GetStop();

        printf("Scene::initAnimStack $1 start %f stop %f \n", start.GetSecondDouble(), stop.GetSecondDouble());

    } else {
        // Take the time line value
        KTimeSpan lTimeLineTimeSpan;
        fbxScene->GetGlobalSettings().GetTimelineDefaultTimeSpan(lTimeLineTimeSpan);

        start = lTimeLineTimeSpan.GetStart();
        stop  = lTimeLineTimeSpan.GetStop();

        printf("Scene::initAnimStack $2 start %f stop %f \n", start.GetSecondDouble(), stop.GetSecondDouble());
    }

    currentTime = start;
}