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;
}
Ejemplo n.º 2
0
        KFbxXMatrix FilmboxNode::GetWorldTransform( int frame ) const
        {
            KFbxXMatrix value;
            value.SetIdentity();

            if( m_node )
            {
                KFbxScene*         scene     = m_node->GetScene();
                KFbxAnimEvaluator* evaluator = scene->GetEvaluator();
                
                KTime frame_time;

                if( frame == 0xFFFFFFFF )
                {
                    frame_time = KTIME_INFINITE;
                }
                else
                {
                    frame_time.SetTime( 0, 0, 0, frame );
                }

                value = evaluator->GetNodeGlobalTransform( m_node, frame_time );

                if( m_type == MCE::FBX::SceneObjectType::CAMERA )
                {
                    KFbxNode* fbx_target_node = m_node->GetTarget();

                    if( fbx_target_node )
                    {
                        // For target cameras we need to manually replace the rotation to point towards the target
                        KFbxVector4 camera_position = value.GetT();

                        MCE::FBX::FilmboxNode mce_target_node( fbx_target_node );

                        KFbxXMatrix target_transform = mce_target_node.GetWorldTransform( frame );
                        KFbxVector4 target_position  = target_transform.GetT();

                        KFbxVector4 up_vector( 0.0, 1.0, 0.0, 0.0 );

                        KFbxVector4 look_axis = -( target_position - camera_position );
                        look_axis.Normalize();

                        KFbxVector4 right_axis = up_vector.CrossProduct( look_axis );
                        KFbxVector4 up_axis    = look_axis.CrossProduct( right_axis );

                        KFbxMatrix rotation_matrix;
                        rotation_matrix.SetRow( 0, right_axis );
                        rotation_matrix.SetRow( 1, up_axis );
                        rotation_matrix.SetRow( 2, look_axis );
                        rotation_matrix.SetRow( 3, KFbxVector4( 0.0, 0.0, 0.0, 1.0 ) );

                        KFbxQuaternion camera_rotation;
                        double determinant;
                        rotation_matrix.GetElements( KFbxVector4(), camera_rotation, KFbxVector4(), KFbxVector4(), determinant );

                        KFbxVector4 camera_scale( 1.0, 1.0, 1.0, 0.0 );
                        value.SetTQS( camera_position, camera_rotation, camera_scale );
                    }
                    else
                    {
                        // Even though the SDK docs say that GetNodeGlobalTransform takes all transforms into account
                        // For cameras it appears that you have to manually apply post-rotation
                        KFbxVector4 post_rotation = m_node->GetPostRotation( KFbxNode::eSOURCE_SET );

                        KFbxXMatrix fbx_to_mce_camera;
                        fbx_to_mce_camera.SetR( post_rotation );

                        value *= fbx_to_mce_camera;
                    }
                }
            }

            return value;
        }