示例#1
0
JNIEXPORT jfloatArray JNICALL Java_de_tesis_dynaware_javafx_graphics_importers_fbx_JFbxLib_getMeshVertices(JNIEnv *env, jobject obj, jint attributeIndex) {

	// Check FBX file has been opened.
	if (!isOpen()) { throwFileClosedException(env); }

	// Check attribute index bounds for safety.
	if (!checkAttributeBounds(attributeIndex)) { throwArrayOutOfBoundsException(env); }

	// Check attribute type for safety.
	if (!isValidType(attributeIndex, FbxNodeAttribute::EType::eMesh)) { return NULL; }

	FbxMesh* mesh = (FbxMesh*)currentNode->GetNodeAttributeByIndex(attributeIndex);

	FbxVector4 *controlPoints    = mesh->GetControlPoints();
	const int controlPointsCount = mesh->GetControlPointsCount();

	jfloatArray vertices = env->NewFloatArray(3*controlPointsCount);

	// Check memory could be allocated.
	if (vertices == NULL) {	throwOutOfMemoryError(env); }

	for (int i=0; i<controlPointsCount; i++)	{
		jfloat vertex[3];

		vertex[0] = controlPoints[i][0];
		vertex[1] = controlPoints[i][1];
		vertex[2] = controlPoints[i][2];

		env->SetFloatArrayRegion(vertices, 3*i, 3, vertex);
	}

	return vertices;
}
示例#2
0
void FBXImporter::ReadUVs(FBXMeshData* fbxMeshData, int controlPointIndex, int index, int textureUVIndex, int uvLayer)
{
	FbxMesh* mesh = fbxMeshData->mMesh;
	vector<XMFLOAT2>& uvs = fbxMeshData->mUVs;

	if (uvLayer >= 2 || mesh->GetElementUVCount() <= uvLayer)
	{
		return;
	}

	FbxGeometryElementUV* vertexUV = mesh->GetElementUV(0);

	switch (vertexUV->GetMappingMode())
	{
	case FbxGeometryElement::eByControlPoint:
		switch (vertexUV->GetReferenceMode())
		{
		case FbxGeometryElement::eDirect:
		{
			XMFLOAT2 uv;
			FbxVector2 fbxUV = vertexUV->GetDirectArray().GetAt(controlPointIndex);
			uv.x = static_cast<float>(fbxUV[0]);
			uv.y = static_cast<float>(fbxUV[1]);
			uvs.push_back(uv);
		}
			break;
		case FbxGeometryElement::eIndexToDirect:
		{
			int id = vertexUV->GetIndexArray().GetAt(controlPointIndex);
			FbxVector2 fbxUV = vertexUV->GetDirectArray().GetAt(id);
			XMFLOAT2 uv;
			uv.x = static_cast<float>(fbxUV[0]);
			uv.y = static_cast<float>(fbxUV[1]);
			uvs.push_back(uv);
		}

		break;
		default:
			break;
		}

	case FbxGeometryElement::eByPolygonVertex:
		switch (vertexUV->GetReferenceMode())
		{
		case FbxGeometryElement::eDirect:
		case FbxGeometryElement::eIndexToDirect:
#if USE_RIGHT_HAND
			uvs[index].x = static_cast<float>(vertexUV->GetDirectArray().GetAt(textureUVIndex)[0]);
#else
			uvs[index].x = 1.0f - static_cast<float>(vertexUV->GetDirectArray().GetAt(textureUVIndex)[0]);
#endif
			uvs[index].y = 1.0f - static_cast<float>(vertexUV->GetDirectArray().GetAt(textureUVIndex)[1]);
			break;
		default:
			break;
		}
		break;
	}
}
示例#3
0
FbxMesh* GenerateLOD::CreateNewMesh(FbxVector4 *pControlPoints, FbxMesh *pMesh, FbxScene *pScene)
{
	// ********************************************************************************* //
	// Following is Create new Mesh
	FbxMesh *newMesh = FbxMesh::Create(pScene, "newMesh");
	newMesh->InitControlPoints((*ControlP).size());

	int count = 0;
	std::unordered_map<int, int> RemainPoints;
	for (std::unordered_map<int, Point>::iterator it = (*ControlP).begin(); it != (*ControlP).end(); ++it) {
		newMesh->SetControlPointAt(pControlPoints[it->first], count);
		RemainPoints[it->first] = count;
		++count;
	}

	FbxGeometryElementUV *newElementUV = newMesh->CreateElementUV("DiffuseUV");
	if (!newElementUV) {
		MessageBox(NULL, "CreateElementUV Error!", "�ב�¾", 0);
		//exit(0);
	}

	newElementUV->SetMappingMode(FbxLayerElement::eByPolygonVertex);
	newElementUV->SetReferenceMode(FbxLayerElement::eIndexToDirect);

	//# copy oldElementUV.DirectArray() into newElementUV.DirectArray()
	FbxGeometryElementUV *oldElementUV = pMesh->GetElementUV(0);
	int length = oldElementUV->GetDirectArray().GetCount();
	for (int i = 0; i < length; ++i)
		newElementUV->GetDirectArray().Add(oldElementUV->GetDirectArray()[i]);

	//# Now we have set the UVs as eIndexToDirect reference and
	//# in eByPolygonVertex mapping mode, we must Set the size of the index array.
	int PolygonCount = (*Triangles).size();
	newElementUV->GetIndexArray().SetCount(3 * PolygonCount);

	//# Add new triangles to pMesh
	int newPolygonIndex = 0;
	for (std::unordered_map<int, Face>::iterator it = (*Triangles).begin(); it != (*Triangles).end(); ++it) {
		newMesh->BeginPolygon(-1, -1, -1, false);

		newMesh->AddPolygon(RemainPoints[it->second.points[0]], it->second.uvs[0]);
		newElementUV->GetIndexArray().SetAt(newPolygonIndex * 3 + 0, it->second.uvs[0]);

		newMesh->AddPolygon(RemainPoints[it->second.points[1]], it->second.uvs[1]);
		newElementUV->GetIndexArray().SetAt(newPolygonIndex * 3 + 1, it->second.uvs[1]);

		newMesh->AddPolygon(RemainPoints[it->second.points[2]], it->second.uvs[2]);
		newElementUV->GetIndexArray().SetAt(newPolygonIndex * 3 + 2, it->second.uvs[2]);

		newMesh->EndPolygon();
		newPolygonIndex += 1;
	}

	//# Automatically generate edge data for the mesh.
	newMesh->BuildMeshEdgeArray();

	return newMesh;
}
示例#4
0
    // Bake node attributes and materials under this node recursively.
    // Currently only mesh, light and material.
    void LoadCacheRecursive(SceneContext* pSceneCtx, FbxNode * pNode, FbxAnimLayer * pAnimLayer, bool pSupportVBO)
    {
        // Bake material and hook as user data.
        const int lMaterialCount = pNode->GetMaterialCount();
        for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
        {
            FbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex);
            if (lMaterial && !lMaterial->GetUserDataPtr())
            {
                FbxAutoPtr<MaterialCache> lMaterialCache(new MaterialCache);
                if (lMaterialCache->Initialize(lMaterial))
                {
                    lMaterial->SetUserDataPtr(lMaterialCache.Release());
                }
            }
        }

        FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();
        if (lNodeAttribute)
        {
            // Bake mesh as VBO(vertex buffer object) into GPU.
            if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh)
            {
                FbxMesh * lMesh = pNode->GetMesh();
                if (pSupportVBO && lMesh && !lMesh->GetUserDataPtr())
                {
                    FbxAutoPtr<VBOMesh> lMeshCache(new VBOMesh);
                    if (lMeshCache->Initialize(pSceneCtx, lMesh))
                    {
                        lMesh->SetUserDataPtr(lMeshCache.Release());
                    }
                }
            }
            // Bake light properties.
            else if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight)
            {
                FbxLight * lLight = pNode->GetLight();
                if (lLight && !lLight->GetUserDataPtr())
                {
                    FbxAutoPtr<LightCache> lLightCache(new LightCache);
                    if (lLightCache->Initialize(lLight, pAnimLayer))
                    {
                        lLight->SetUserDataPtr(lLightCache.Release());
                    }
                }
            }
        }

        const int lChildCount = pNode->GetChildCount();
        for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
        {
            LoadCacheRecursive(pSceneCtx, pNode->GetChild(lChildIndex), pAnimLayer, pSupportVBO);
        }
    }
示例#5
0
void FBXImporter::ProcessMesh(FbxNodeAttribute* nodeAttribute)
{
	FbxMesh* mesh = (FbxMesh*)nodeAttribute;
	
	// 网格是否三角化的?如果不是先将其转为三角化的。
	// 注意:一步其实应该在建模软件导出的时候进行。
	if (!mesh->IsTriangleMesh())
	{
		FbxGeometryConverter converter(mSDKManager);

		// #1
		// For FBX SDK 2015.1
		nodeAttribute = converter.Triangulate(nodeAttribute, true, false);
		// For FBX SDK 2013.3
		//converter.TriangulateInPlace(nodeAttribute->GetNode());

		mesh = (FbxMesh*)nodeAttribute;
	}

	FBXMeshData* fbxMeshData = new FBXMeshData();
	fbxMeshData->mMesh = mesh;
	mFBXMeshDatas.push_back(fbxMeshData);

	Log("TriangleCount:%d\n", mesh->GetPolygonCount());
	Log("VertexCount:%d\n", mesh->GetControlPointsCount());
	Log("IndexCount:%d\n", mesh->GetPolygonVertexCount());
	Log("Layer:%d\n", mesh->GetLayerCount());
	Log("DeformerCount:%d\n", mesh->GetDeformerCount());
	Log("MaterialCount%d\n", mesh->GetNode()->GetMaterialCount());
	Log("\n");
}
void CFBXLoader::SetupNode(FbxNode* pNode, std::string parentName)
{
	if(!pNode)
		return ;

	FBX_MESH_NODE meshNode;

	meshNode.name = pNode->GetName();
	meshNode.parentName = parentName;

	ZeroMemory( &meshNode.elements, sizeof(MESH_ELEMENTS) );

	FbxMesh* lMesh = pNode->GetMesh();	

	if(lMesh)
	{
		const int lVertexCount = lMesh->GetControlPointsCount();

		if (lVertexCount>0)
		{
			// 頂点があるならノードにコピー
			CopyVertexData(lMesh, &meshNode);
		}
	}

	// マテリアル
	const int lMaterialCount = pNode->GetMaterialCount();
	for(int i=0;i<lMaterialCount;i++)
	{
		FbxSurfaceMaterial* mat = pNode->GetMaterial(i);
		if(!mat)
			continue;

		FBX_MATERIAL_NODE destMat;
		CopyMatrialData(mat, &destMat);

		meshNode.m_materialArray.push_back(destMat);
	}

	//
	ComputeNodeMatrix(pNode, &meshNode);

	m_meshNodeArray.push_back(meshNode);

	const int lCount = pNode->GetChildCount();
	for (int i = 0; i < lCount; i++)
	{
		SetupNode(pNode->GetChild(i), meshNode.name);
	}
}
示例#7
0
void fbxLoader2::computeMesh(FbxNode* pNode, FbxTime& pTime, FbxAnimLayer* pAnimLayer, FbxAMatrix& pGlobalPosition, FbxPose* pPose, int frame)
{
    FbxMesh* lMesh = pNode->GetMesh();
    const int lVertexCount = lMesh->GetControlPointsCount();

    // No vertex to draw.
    if (lVertexCount == 0)
    {
        return;
    }

    // If it has some defomer connection, update the vertices position
    const bool lHasVertexCache = lMesh->GetDeformerCount(FbxDeformer::eVertexCache) &&
        (static_cast<FbxVertexCacheDeformer*>(lMesh->GetDeformer(0, FbxDeformer::eVertexCache)))->IsActive();
    const bool lHasShape = lMesh->GetShapeCount() > 0;
    const bool lHasSkin = lMesh->GetDeformerCount(FbxDeformer::eSkin) > 0;
    const bool lHasDeformation = lHasVertexCache || lHasShape || lHasSkin;

    if (lHasDeformation)
    {
        //we need to get the number of clusters
        const int lSkinCount = lMesh->GetDeformerCount(FbxDeformer::eSkin);
        int lClusterCount = 0;
        for (int lSkinIndex = 0; lSkinIndex < lSkinCount; ++lSkinIndex)
        {
            lClusterCount += ((FbxSkin *)(lMesh->GetDeformer(lSkinIndex, FbxDeformer::eSkin)))->GetClusterCount();
        }
        if (lClusterCount)
        {
            // Deform the vertex array with the skin deformer.
            ComputeSkinDeformation(pGlobalPosition, lMesh, pTime, pPose, frame);
        }
    }
}
示例#8
0
		void FbxLoader::ProcessControlPoints(FbxNode* node, Node& meshNode)
		{
			FbxMesh* currMesh = node->GetMesh();
			if(!currMesh)
				return;

			const int ctrlPointCount = currMesh->GetControlPointsCount();
			meshNode.controlPoints.resize(ctrlPointCount);

			for(int i = 0; i < ctrlPointCount; i++) {
				FbxVector4 p = currMesh->GetControlPointAt(i);
				auto& cp = meshNode.controlPoints[i];
				cp.position = { (float)p[0], (float)p[1], (float)p[2] };
			}
		}
示例#9
0
文件: Scene.cpp 项目: linuxaged/m3d
void LoadMeshes(FbxNode* pFbxNode, packed_freelist<Mesh>& sceneMeshes)
{
    // Material
    const uint32_t materialCount = pFbxNode->GetMaterialCount();
    for (uint32_t i = 0; i < materialCount; ++i) {
        FbxSurfaceMaterial* pFbxMaterial = pFbxNode->GetMaterial(i);
        if (pFbxMaterial && !pFbxMaterial->GetUserDataPtr()) {
            FbxAutoPtr<Material> pMaterial(new Material);
            if (pMaterial->init(pFbxMaterial)) {
                pFbxMaterial->SetUserDataPtr(pMaterial.Release());
            }
        }
    }

    FbxNodeAttribute* nodeAttribute = pFbxNode->GetNodeAttribute();
    if (nodeAttribute) {
        // Mesh
        if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) {
            FbxMesh* pFbxMesh = pFbxNode->GetMesh();
            if (pFbxMesh && !pFbxMesh->GetUserDataPtr()) {
                Mesh mesh;
                if (mesh.init(pFbxMesh)) {
                    sceneMeshes.insert(mesh);
                }
                // TODO:
                FbxAutoPtr<Mesh> pMesh(new Mesh);
                if (pMesh->init(pFbxMesh)) {
                    pFbxMesh->SetUserDataPtr(pMesh.Release());
                }
            }
        }
        // Light
        else if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight) {
            FbxLight* pFbxLight = pFbxNode->GetLight();
            if (pFbxLight && !pFbxLight->GetUserDataPtr()) {
                FbxAutoPtr<Light> pLight(new Light);
                if (pLight->init(pFbxLight)) {
                    pFbxLight->SetUserDataPtr(pLight.Release());
                }
            }
        }
    }

    const int childCount = pFbxNode->GetChildCount();
    for (int i = 0; i < childCount; ++i) {
        LoadMeshes(pFbxNode->GetChild(i), sceneMeshes);
    }
}
示例#10
0
    // Unload the cache and release the memory under this node recursively.
    void UnloadCacheRecursive(FbxNode * pNode)
    {
        // Unload the material cache
        const int lMaterialCount = pNode->GetMaterialCount();
        for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
        {
            FbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex);
            if (lMaterial && lMaterial->GetUserDataPtr())
            {
                MaterialCache * lMaterialCache = static_cast<MaterialCache *>(lMaterial->GetUserDataPtr());
                lMaterial->SetUserDataPtr(NULL);
                delete lMaterialCache;
            }
        }

        FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();
        if (lNodeAttribute)
        {
            // Unload the mesh cache
            if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh)
            {
                FbxMesh * lMesh = pNode->GetMesh();
                if (lMesh && lMesh->GetUserDataPtr())
                {
                    VBOMesh * lMeshCache = static_cast<VBOMesh *>(lMesh->GetUserDataPtr());
                    lMesh->SetUserDataPtr(NULL);
                    delete lMeshCache;
                }
            }
            // Unload the light cache
            else if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight)
            {
                FbxLight * lLight = pNode->GetLight();
                if (lLight && lLight->GetUserDataPtr())
                {
                    LightCache * lLightCache = static_cast<LightCache *>(lLight->GetUserDataPtr());
                    lLight->SetUserDataPtr(NULL);
                    delete lLightCache;
                }
            }
        }

        const int lChildCount = pNode->GetChildCount();
        for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
        {
            UnloadCacheRecursive(pNode->GetChild(lChildIndex));
        }
    }
示例#11
0
void fbxLoader2::setBindPoseCluster(FbxNode *node)
{
	if( node->GetNodeAttribute())
	{
		switch(node->GetNodeAttribute()->GetAttributeType())
		{
		case FbxNodeAttribute::eMesh: 
			FbxMesh *mesh = node->GetMesh();

			for (int j = 0; j<mesh->GetDeformerCount(); j++)
			{
				FbxSkin *skin = (FbxSkin*) mesh->GetDeformer(j,FbxDeformer::eSkin);
				int clusters = skin->GetClusterCount();
				for(int k = 0; k<clusters; k++)
				{
					FbxCluster* cluster = skin->GetCluster(k);
					FbxNode* boneLink = cluster->GetLink();

					if(boneLink)
					{
						std::string nameLink = boneLink->GetName();
						FbxAMatrix translationM;
						FbxAMatrix invert;
						cluster->GetTransformLinkMatrix(translationM);
						cluster->GetTransformMatrix(invert);

						translationM = translationM * invert.Inverse();

						D3DXMATRIX mat = D3DXMATRIX((float)translationM.mData[0].mData[0], (float)translationM.mData[0].mData[1], (float)translationM.mData[0].mData[2], (float)translationM.mData[3].mData[0],
													(float)translationM.mData[1].mData[0], (float)translationM.mData[1].mData[1], (float)translationM.mData[1].mData[2], (float)translationM.mData[3].mData[1],
													(float)translationM.mData[2].mData[0], (float)translationM.mData[2].mData[1], (float)translationM.mData[2].mData[2], (float)translationM.mData[3].mData[2],
													0,0,0,1);

						skeleton->GetBone(skeleton->GetBoneByName(nameLink))->SetTransformation(mat);
					}
				}
			}
			break;
		}
	}
	for (int i = 0; i<node->GetChildCount(); i++)
	{
		FbxNode* child = node->GetChild(i);
		setBindPoseCluster(child);
	}
}
示例#12
0
//===============================================================================================================================
void FBXLoader::AssociateMaterialToMesh(FbxNode* inNode)
{
	FbxLayerElementArrayTemplate<int>* materialIndices;
	FbxGeometryElement::EMappingMode materialMappingMode = FbxGeometryElement::eNone;
	FbxMesh* mesh = inNode->GetMesh();
	
	if (mesh->GetElementMaterial())
	{
		materialIndices = &(mesh->GetElementMaterial()->GetIndexArray());
		materialMappingMode = mesh->GetElementMaterial()->GetMappingMode();
		
		FBXSubsets* subset = mSubsets[iCurrentSubset];
		
		if (materialIndices)
		{
			switch (materialMappingMode)
			{
				case FbxGeometryElement::eByPolygon:
				{
					if (materialIndices->GetCount() == subset->mPolygonCount)
					{
						for (uint32 i = 0; i < subset->mPolygonCount; ++i)
						{
							uint32 materialIndex = materialIndices->GetAt(i);
							//subset->mTriangles[i].materialIndex = materialIndex;
							subset->mMaterialIndex = materialIndex;
						}
					}
				}
				break;
				case FbxGeometryElement::eAllSame:
				{
					uint32 materialIndex = materialIndices->GetAt(0);
					for (uint32 i = 0; i < subset->mPolygonCount; ++i)
					{
						//subset->mTriangles[i].materialIndex = materialIndex;
						subset->mMaterialIndex = materialIndex;
					}
				}
				break;
				default: throw std::exception("Invalid mapping mode for material\n");
			}
		}
	}
}
示例#13
0
//===============================================================================================================================
void FBXLoader::LoadControlPoints(FbxNode* node)
{
	FbxMesh* mesh = node->GetMesh();
	uint32 controlPointCount = mesh->GetControlPointsCount();
	
	for (uint32 i = 0; i < controlPointCount; ++i)
	{
		ZShadeSandboxMesh::PhysicalPoint* currCtrlPoint = new ZShadeSandboxMesh::PhysicalPoint();
		
		XMFLOAT3 position;
		position.x = static_cast<float>(mesh->GetControlPointAt(i).mData[0]);
		position.y = static_cast<float>(mesh->GetControlPointAt(i).mData[1]);
		position.z = static_cast<float>(mesh->GetControlPointAt(i).mData[2]);
		currCtrlPoint->position = position;
		
		mControlPoints[i] = currCtrlPoint;
	}
}
示例#14
0
// Load Fbx File
void GenerateLOD::LoadFbx()
{
	FbxManager *fbxManager = FbxManager::Create();

	//Create an IOSetting
	FbxIOSettings *ios = FbxIOSettings::Create(fbxManager, IOSROOT);
	fbxManager->SetIOSettings(ios);

	//Create an impoter
	FbxImporter *lImporter = FbxImporter::Create(fbxManager, "myImporter");
	std::string tmp = std::string(".\\LODs\\") + srcFbxName;
	bool lImporterStatus = lImporter->Initialize(tmp.c_str(), -1, fbxManager->GetIOSettings());
	if (!lImporterStatus) {
		MessageBox(NULL, "No Scuh File in .\\LODs\\ directory !", "Warning", 0);
		return;
	}

	FbxScene *fbxScene = FbxScene::Create(fbxManager, "myScene");
	lImporter->Import(fbxScene);

	FbxNode *rootNode = fbxScene->GetRootNode();
	if (rootNode != NULL) {
		for (int i = 0; i < rootNode->GetChildCount(); ++i) {
			FbxNode *node = rootNode->GetChild(i);
			FbxNodeAttribute *Att = node->GetNodeAttribute();
			if (Att != NULL && Att->GetAttributeType() == FbxNodeAttribute::eMesh) {
				FbxMesh *lMesh = (FbxMesh *)(Att);
				//FbxMesh *lMesh = dynamic_cast<FbxMesh *>(Att);
				if (!lMesh->IsTriangleMesh()) {
					FbxGeometryConverter converter = FbxGeometryConverter(fbxManager);
					FbxNodeAttribute *Attr = converter.Triangulate(lMesh, true);
					lMesh = (FbxMesh *)(Attr);
				}

				//Following is the SImplification
				Reduction_EdgesCollapse_UV(node, lMesh, fbxManager, fbxScene);

			}
		}
	}

	//MessageBox(NULL, "Export Succeed!", "Export", 0);
	fbxManager->Destroy();
}
示例#15
0
void FBXExporter::ProcessMesh(FbxNode* inNode)
{
	FbxMesh* currMesh = inNode->GetMesh();

	mTriangleCount = currMesh->GetPolygonCount();
	int vertexCounter = 0;
	mTriangles.reserve(mTriangleCount);

	//per triangle
	for (unsigned int i = 0; i < mTriangleCount; ++i)
	{
		XMFLOAT3 normal[3];
		XMFLOAT3 binormal[3];
		XMFLOAT2 UV[3][2];
		Triangle currTriangle;
		mTriangles.push_back(currTriangle);
		
		//per vertex
		for (unsigned int j = 0; j < 3; ++j)
		{
			int ctrlPointIndex = currMesh->GetPolygonVertex(i, j);
			CtrlPoint* currCtrlPoint = mControlPoints[ctrlPointIndex];


			PNTIWVertex temp;
			temp.mPosition = currCtrlPoint->mPosition;
			temp.mNormal = normal[j];
			temp.mUV = UV[j][0];

			mVertices.push_back(temp);
			mTriangles.back().mIndices.push_back(vertexCounter);
			++vertexCounter;
		}
	}

	// Now mControlPoints has served its purpose
	// We can free its memory
	for(auto itr = mControlPoints.begin(); itr != mControlPoints.end(); ++itr)
	{
		delete itr->second;
	}
	mControlPoints.clear();
}
示例#16
0
	void FbxUtil::LoadMesh(const SceneNode::Ptr &ntNode, FbxNode* fbxNode)
	{
		FbxMesh* fbxMesh = static_cast<FbxMesh*>(fbxNode->GetNodeAttribute());

		// first, we test if ther's already a mesh asset exits with this name.
		Mesh::Ptr mesh = EntityUtil::Instance()->FindEntity<Mesh>(fbxMesh->GetName());
		
		if (mesh == nullptr)
		{
			// if not, we read the mesh data.
			mesh = CreateMesh(fbxMesh);
			EntityUtil::Instance()->AddEntity(mesh);
		}

		// attach mesh component to node.
		ntNode->AddComponent(MeshRender::Create(nullptr, mesh));

		LoadMaterial(ntNode, fbxNode);
	}
示例#17
0
JNIEXPORT jintArray JNICALL Java_de_tesis_dynaware_javafx_graphics_importers_fbx_JFbxLib_getMeshFaceSmoothingGroups(JNIEnv *env, jobject obj, jint attributeIndex) {

	// Check FBX file has been opened.
	if (!isOpen()) { throwFileClosedException(env); }

	// Check attribute index bounds for safety.
	if (!checkAttributeBounds(attributeIndex)) { throwArrayOutOfBoundsException(env); }

	// Check attribute type for safety.
	if (!isValidType(attributeIndex, FbxNodeAttribute::EType::eMesh)) { return NULL; }

	FbxMesh* mesh = (FbxMesh*)currentNode->GetNodeAttributeByIndex(attributeIndex);

	FbxGeometryElementSmoothing* smoothingElement = mesh->GetElementSmoothing(0);

	// If smoothing is not defined explicitly, try to convert from normals. Convert edge-smoothing to face-smoothing.
	if (!smoothingElement || smoothingElement->GetMappingMode() == FbxGeometryElement::eByEdge) {

		FbxGeometryConverter geometryConverter(sdkManager);
		if (!smoothingElement) {
			geometryConverter.ComputeEdgeSmoothingFromNormals(mesh);
			smoothingElement = mesh->GetElementSmoothing(0);
		}
		if (smoothingElement->GetMappingMode() == FbxGeometryElement::eByEdge) {
			geometryConverter.ComputePolygonSmoothingFromEdgeSmoothing(mesh);
		}
	}

	const int polygonCount = mesh->GetPolygonCount();

	jintArray faceSmoothingGroups = env->NewIntArray(polygonCount);

	// Check memory could be allocated.
	if (faceSmoothingGroups == NULL) { throwOutOfMemoryError(env); }

	for (int i=0; i<polygonCount; i++) {
		jint iValue = smoothingElement->GetDirectArray().GetAt(i);
		env->SetIntArrayRegion(faceSmoothingGroups, i, 1, &iValue);
	}

	return faceSmoothingGroups;
}
示例#18
0
void FBXSceneEncoder::loadModel(FbxNode* fbxNode, Node* node)
{
    FbxMesh* fbxMesh = fbxNode->GetMesh();
    if (!fbxMesh)
    {
        return;
    }
    if (fbxMesh->IsTriangleMesh())
    {
        Mesh* mesh = loadMesh(fbxMesh);
        Model* model = new Model();
        model->setMesh(mesh);
        node->setModel(model);
        loadSkin(fbxMesh, model);
        if (model->getSkin())
        {
            node->resetTransformMatrix();
        }
    }
}
示例#19
0
void generateTangentsAndBinormals(FbxNode* fbxNode, const EncoderArguments& arguments)
{
    if (!fbxNode)
        return;
    const char* name = fbxNode->GetName();
    if (name && strlen(name) > 0)
    {
        FbxMesh* fbxMesh = fbxNode->GetMesh();
        if (fbxMesh && arguments.isGenerateTangentBinormalId(string(name)))
        {
            fbxMesh->GenerateTangentsDataForAllUVSets();
        }
    }
    // visit child nodes
    const int childCount = fbxNode->GetChildCount();
    for (int i = 0; i < childCount; ++i)
    {
        generateTangentsAndBinormals(fbxNode->GetChild(i), arguments);
    }
}
示例#20
0
FbxNode* ILDLMesh::CreateMesh( FbxScene* pScene, const char* pName )
{
    int nVerts  = (int)m_vertex_list.size();

    FbxMesh* lMesh = FbxMesh::Create(pScene,pName);
    lMesh->InitControlPoints( nVerts );
    FbxVector4* lControlPoints = lMesh->GetControlPoints();
    FbxGeometryElementNormal* lGeometryElementNormal= lMesh->CreateElementNormal();
    lGeometryElementNormal->SetMappingMode(FbxGeometryElement::eByControlPoint);
    lGeometryElementNormal->SetReferenceMode(FbxGeometryElement::eDirect);


    int vi = 0, glidx = 0;
    for( ILDLVertexIter i = m_vertex_list.begin();
        i !=  m_vertex_list.end(); ++i, vi++ )
    {
        ILDLVertexPtr vp = (*i);
        vp->m_glIdx = glidx;
        vec3 coords = vp->getCoords();
        lControlPoints[vi] = FbxVector4( coords[0], coords[1], coords[2] );
        vec3 normal = vp->getNormal();
        lGeometryElementNormal->GetDirectArray().Add( FbxVector4( normal[0], normal[1], normal[2] ) );
        glidx++;
    }

    for( ILDLFaceIter i = m_face_list.begin();
        i != m_face_list.end(); ++i )
    {
        ILDLFacePtr fp = *i;
        ILDLFaceVertexPtr fvp = fp->front();

        lMesh->BeginPolygon(-1, -1, -1, false);
        lMesh->AddPolygon( fvp->getVertexPtr()->m_glIdx );
        fvp = fvp->next();
        lMesh->AddPolygon( fvp->getVertexPtr()->m_glIdx );
        fvp = fvp->next();
        lMesh->AddPolygon( fvp->getVertexPtr()->m_glIdx );
        lMesh->EndPolygon ();
    }


    FbxNode* lNode = FbxNode::Create(pScene,pName);
    lNode->SetNodeAttribute(lMesh);

    return lNode;
}
示例#21
0
void FbxParser::ProcessMesh(FbxNode* pNode,std::vector<GS::BaseMesh*>& meshs)
{
	FbxMesh* lMesh = (FbxMesh*) pNode->GetNodeAttribute ();
	if (lMesh == NULL)
		return ; 
	int triangleCount = lMesh->GetPolygonCount();  
    int vertexCounter = 0;  
	if (triangleCount ==0)
		return ; 
	
	GS::BaseMesh* pMesh = new GS::BaseMesh();
	GS::double3 p0, p1, p2;
	int vertexId = 0;
	GS::VertexInfo v1, v2, v3;
	
	for(int i = 0 ; i < triangleCount ; ++i)  
    {
        int ctrlPointIndex = lMesh->GetPolygonVertex(i , 0);
		
		ReadVertex(lMesh, ctrlPointIndex, v1.pos);
		ReadColor(lMesh, ctrlPointIndex, vertexId, v1.color);
		ReadNormal(lMesh, ctrlPointIndex, vertexId++, v1.normal);
		
		// read the second vertex
		ctrlPointIndex = lMesh->GetPolygonVertex(i , 1);
	    ReadVertex(lMesh, ctrlPointIndex, v2.pos);
		ReadColor(lMesh, ctrlPointIndex, vertexId, v2.color);
		ReadNormal(lMesh, ctrlPointIndex, vertexId++, v2.normal);
		// read the third vertex
		ctrlPointIndex = lMesh->GetPolygonVertex(i , 2);
		ReadVertex(lMesh, ctrlPointIndex, v3.pos);
		ReadColor(lMesh, ctrlPointIndex, vertexId, v3.color);
		ReadNormal(lMesh, ctrlPointIndex, vertexId++, v3.normal);
		pMesh->Add(v1, v2, v3);
	}
	pMesh->GenID();
	//pMesh->GenSurface();
	pMesh->GenAABB(true);
	meshs.push_back(pMesh);
}
示例#22
0
reMesh* reFBXAsset::importMesh(FbxNode* fbxNode)
{
	qDebug() << "import mesh for" << fbxNode->GetName();
	reMesh* mesh = new reMesh;

	FbxMesh* fmesh = (FbxMesh*) fbxNode->GetNodeAttribute();
	FbxVector4* controlPoints = fmesh->GetControlPoints(); 

	for (int i=0; i<fmesh->GetPolygonCount(); i++) 
	{
		reFace* face = new reFace;
		for (int j=0; j<fmesh->GetPolygonSize(i); j++)
		{
			int vi = fmesh->GetPolygonVertex(i, j);
			reVertex vertex;
			vertex.pos = reVec3(controlPoints[vi][0], controlPoints[vi][1], controlPoints[vi][2]);
			FbxVector4 fNormal;
			fmesh->GetPolygonVertexNormal(i, j, fNormal);
			vertex.uv = getUV(fmesh, vi, i, j);
			vertex.normal = reVec3(fNormal[0], fNormal[1], fNormal[2]);
			face->vertices.push_back(vertex);	
		}
		reMaterial* mat =  getMaterial(fmesh, i, mesh->materialSet);
		mesh->addFace(face,mat ? mat->id: -1);
	}
	
	reMeshAsset* meshAsset = new reMeshAsset(meshes);
	meshAsset->mesh = mesh;
	meshes->children.push_back(meshAsset);
	meshAsset->setPath((dataDir().toStdString() + "/" + fbxNode->GetName() + ".mesh").c_str());
	mesh->save(dataDir().toStdString() + "/" + fbxNode->GetName() + ".mesh");
	return mesh;
}
示例#23
0
	std::shared_ptr<Mesh> FbxParser::CreateMesh(GameObjectPtr node, FbxNode * fbxNode)
	{
		Mesh::Ptr mesh = Mesh::Create(fbxNode->GetName());

		FbxMesh* fbxMesh = static_cast<FbxMesh*>(fbxNode->GetNodeAttribute());

		int polygonCount = fbxMesh->GetPolygonCount();
		int indicesCount = polygonCount * 3;
			
		mesh->Positions.Data.reserve(indicesCount * 3);
		mesh->Indices.Data.reserve(indicesCount);
		mesh->Colors.Data.reserve(indicesCount * 3);

		for (int i = 0; i < polygonCount; ++i) {
			ASSERT(fbxMesh->GetPolygonSize(i) <= 3,  "Error: triangulate %s", mesh->GetName());

			for (int jj = 0; jj < 3; ++jj) {
				int ctrPointIdx = fbxMesh->GetPolygonVertex(i, jj);
				// TODO 
				// Use Triangle Strip instead of triangle list
				auto position = fbxMesh->GetControlPointAt(ctrPointIdx);

				mesh->Positions.Data.push_back((double*)&position);

				int indices = i * 3 + jj;
				mesh->Indices.Data.push_back(indices);

				auto color = fbxMesh->GetElementVertexColor(ctrPointIdx);
				mesh->Colors.Data.push_back((double*)&color);
			}
		}
		mesh->UpdateBuffer();
		return mesh;
	}
示例#24
0
/*
Extract Mesh objects by recursing the scene. They will initialise themselves.
*/
void SceneImporter::loadCacheRecursive(FbxNode * pNode)
{
	// Bake material and hook as user data.
	FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();
	if (lNodeAttribute)
	{
		if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh)
		{
			FbxMesh * lMesh = pNode->GetMesh();
			if (lMesh && !lMesh->GetUserDataPtr())
			{
				_meshes.push_back(std::auto_ptr<Mesh>(new Mesh(lMesh)));
			}
		}
	}

	const int lChildCount = pNode->GetChildCount();
	for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
	{
		loadCacheRecursive(pNode->GetChild(lChildIndex));
	}
}
示例#25
0
void Parser::bake_meshes_recursive(FbxNode * node, FbxAnimLayer * animation_layer)
{
  FbxPose * pose = NULL;
  FbxTime current_time;
  FbxAMatrix parent_global_position;

  FbxAMatrix global_position = get_global_position(node, current_time, pose, &parent_global_position);

  FbxNodeAttribute* node_attribute = node->GetNodeAttribute();

  if(node_attribute) {
    if(node_attribute->GetAttributeType() == FbxNodeAttribute::eMesh) {
      FbxMesh * mesh = node->GetMesh();
        
      FbxAMatrix geometry_offset = get_geometry(node);
      FbxAMatrix global_offset_position = global_position * geometry_offset;

      FbxVector4* control_points = mesh->GetControlPoints();
      bake_global_positions(control_points, mesh->GetControlPointsCount(), global_offset_position);

      if(mesh && !mesh->GetUserDataPtr()) {
        VBOMesh * mesh_cache = new VBOMesh;

        if(mesh_cache->initialize(mesh)) {
          bake_mesh_deformations(mesh, mesh_cache, current_time, animation_layer, global_offset_position, pose);

          meshes->push_back(mesh_cache);
        }
      }
    }
  }

  const int node_child_count = node->GetChildCount();

  for(int node_child_index = 0; node_child_index < node_child_count; ++node_child_index) {
    bake_meshes_recursive(node->GetChild(node_child_index), animation_layer);
  }
}
示例#26
0
JNIEXPORT jfloatArray JNICALL Java_de_tesis_dynaware_javafx_graphics_importers_fbx_JFbxLib_getMeshTexCoords(JNIEnv *env, jobject obj, jint attributeIndex) {

	// Check FBX file has been opened.
	if (!isOpen()) { throwFileClosedException(env); }

	// Check attribute index bounds for safety.
	if (!checkAttributeBounds(attributeIndex)) { throwArrayOutOfBoundsException(env); }

	// Check attribute type for safety.
	if (!isValidType(attributeIndex, FbxNodeAttribute::EType::eMesh)) { return NULL; }

	FbxMesh* mesh = (FbxMesh*)currentNode->GetNodeAttributeByIndex(attributeIndex);

	// Currently we only read from the first layer.
	FbxLayerElementUV *firstLayer = mesh->GetElementUV(0);

	if (firstLayer==NULL) {	return NULL; }

	const int uvCount = firstLayer->GetDirectArray().GetCount();

	jfloatArray texCoords = env->NewFloatArray(2*uvCount);
	if (texCoords == NULL) {
		return NULL;
	}

	for (int i=0; i<uvCount; i++) {
		jfloat uv[2];

		// Note that we invert the 'v' index to match the JavaFX (DirectX?) convention.
		uv[0] = firstLayer->GetDirectArray().GetAt(i)[0];
		uv[1] = 1-firstLayer->GetDirectArray().GetAt(i)[1];

		env->SetFloatArrayRegion(texCoords, 2*i, 2, uv);
	}

	return texCoords;
}
// メッシュ情報処理(再帰関数)
void GetMeshData(FbxNode *parent, VertexDataArray& outVertexData)
{
	// メッシュだけ処理
	int numKids = parent->GetChildCount();
	for(int i = 0; i < numKids; i++)
	{
		FbxNode *child = parent->GetChild(i);

		// メッシュを見つけたら
		if(child->GetMesh())
		{
			FbxMesh* pMesh = child->GetMesh();// static_cast<FbxMesh*>(child->GetNodeAttribute());
			printf("メッシュ発見\n");

			printf("名前:%s\n", pMesh->GetName());
			printf("ポリゴン数:%d\n", pMesh->GetPolygonCount());
			printf("マテリアル数:%d\n", pMesh->GetElementMaterialCount());

			printf("コントロールポイント数(頂点座標):%d\n", pMesh->GetControlPointsCount());
			printf("UV数:%d\n", pMesh->GetTextureUVCount());

			FbxArray<FbxVector4> normals;
			pMesh->GetPolygonVertexNormals(normals);
			printf("法線数:%d\n", normals.GetCount());

			// 頂点情報取得
			GetFBXVertexData(pMesh, outVertexData);
		}

		// マテリアル
		int numMat = child->GetMaterialCount();
		for(int j = 0; j < numMat; ++j)
		{
			FbxSurfaceMaterial* mat = child->GetMaterial(j);
			if(mat)
			{
				GetMatrialData(mat);
			}
		}

		if(numMat == 0)
		{
			printf("マテリアルなし\n");
		}

		child->GetChild(0);

		// 更に子を処理
		GetMeshData(child, outVertexData);
	}
}
示例#28
0
void FBXMesh::Builder::unloadCacheRecursive(FbxNode * pNode)
{
	// Unload the material cache
	const int lMaterialCount = pNode->GetMaterialCount();
	for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
	{
		FbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex);
		if (lMaterial && lMaterial->GetUserDataPtr())
		{
			FBXMaterialCache* lMaterialCache = static_cast<FBXMaterialCache*>(lMaterial->GetUserDataPtr());
			lMaterial->SetUserDataPtr(NULL);
			delete lMaterialCache;
		}
	}

	FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();
	if (lNodeAttribute)
	{
		// Unload the mesh cache
		if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh)
		{
			FbxMesh * lMesh = pNode->GetMesh();
			if (lMesh && lMesh->GetUserDataPtr())
			{

#ifndef USE_META_DATA
			VBOMesh * lMeshCache = static_cast<VBOMesh *>(lMesh->GetUserDataPtr());
			lMesh->SetUserDataPtr(NULL);
			delete lMeshCache;
#else
			FbxMetaData * fbxMetaData = static_cast<FbxMetaData*>(lMesh->GetUserDataPtr());
			lMesh->SetUserDataPtr(NULL);
			delete fbxMetaData;
#endif
			}
		}
		// Unload the light cache
		else if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight)
		{
			FbxLight * lLight = pNode->GetLight();
			if (lLight && lLight->GetUserDataPtr())
			{
				FBXLightCache* lLightCache = static_cast<FBXLightCache*>(lLight->GetUserDataPtr());
				lLight->SetUserDataPtr(NULL);
				delete lLightCache;
			}
		}
	}

	const int lChildCount = pNode->GetChildCount();
	for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
	{
		unloadCacheRecursive(pNode->GetChild(lChildIndex));
	}
}
示例#29
0
文件: FBXScene.cpp 项目: Malow/NDYGFX
void FBXScene::ProcessMesh(FbxNode* pNode)
{
	FbxMesh* pFBXMesh = pNode->GetMesh();
	if( !pFBXMesh )
		return;

	if ( pFBXMesh->GetPolygonVertexCount() != pFBXMesh->GetPolygonCount() * 3 )
	{
		FbxGeometryConverter GeometryConverter(pNode->GetFbxManager());
		if( !GeometryConverter.TriangulateInPlace( pNode ) )
		{
			return;
		}
		pFBXMesh = pNode->GetMesh();
	}

	pFBXMesh->InitNormals();
	pFBXMesh->ComputeVertexNormals(true); 
	pFBXMesh->GenerateTangentsDataForAllUVSets();

	int nVertexCount = pFBXMesh->GetControlPointsCount();
	if( nVertexCount <= 0 )
		return;

	std::vector<BoneWeights> boneWeights(nVertexCount);

	ProcessBoneWeights(pFBXMesh, boneWeights);
	
	Model* pModel = new Model(pNode->GetName(), m_Models.GetCount(), false);
	FbxVector4* aControlPoints = pFBXMesh->GetControlPoints();
	for( int pi = 0; pi < pFBXMesh->GetPolygonCount(); ++pi )	// Whole for-loop takes some time too, investigate further.
	{
		// Material
		Material* pMaterial = NULL;

		for( unsigned int pvi = 0; pvi < 3; ++pvi )
		{
			int nVertexIndex = pFBXMesh->GetPolygonVertex(pi, pvi);

			if( nVertexIndex < 0 || nVertexIndex >= nVertexCount )
				continue;

			// Material
			if( pMaterial == NULL )
				pMaterial = GetMaterialLinkedWithPolygon(pFBXMesh, 0, pi, 0, nVertexIndex);

			// Position
			FbxVector4 fbxPosition = aControlPoints[nVertexIndex];

			// Normals And Tangents
			FbxVector4 fbxNormal, fbxTangent;
			fbxNormal = GetNormal(pFBXMesh, 0, pi, pvi, nVertexIndex);
			fbxTangent = GetTangent(pFBXMesh, 0, pi, pvi, nVertexIndex);

			// Add Vertex
			pModel->AddVertex(pMaterial, FbxVector4ToBTHFBX_VEC3(fbxPosition),
										 FbxVector4ToBTHFBX_VEC3(fbxNormal),
										 FbxVector4ToBTHFBX_VEC3(fbxTangent),
										 GetTexCoord(pFBXMesh, 0, pi, pvi, nVertexIndex),
										 boneWeights[nVertexIndex]);

			// Update Bounding Box
			UpdateBoundingBoxDataFromVertex(FbxVector4ToBTHFBX_VEC3(fbxPosition));
		}
	}

	// Geometric Offset
	pModel->SetGeometricOffset2(GetGeometricOffset2(pNode));

	// Insert Model
	m_Models.Add(pModel->GetName(), pModel);
}
示例#30
0
void FBXConverter::processAnimations( FbxNode* node , std::vector<JointData> &skeleton , std::vector<VertexData> &verts , std::vector<IndexData> &indices )
{
	FbxMesh* theMesh = node->GetMesh();

	FbxAnimStack* animationStack = node->GetScene()->GetSrcObject<FbxAnimStack>();
	FbxAnimLayer* animationLayer = animationStack->GetMember<FbxAnimLayer>();
	std::vector<FbxTime> frames;
	for ( int curveNodeIndex = 0; curveNodeIndex < animationLayer->GetMemberCount(); ++curveNodeIndex )
	{
		FbxAnimCurveNode* currentCurve = animationLayer->GetMember<FbxAnimCurveNode>( curveNodeIndex );

		for ( unsigned int channelIndex = 0; channelIndex < currentCurve->GetChannelsCount(); ++channelIndex )
		{
			for ( int curve = 0; curve < currentCurve->GetCurveCount( channelIndex ); ++curve )
			{
				FbxAnimCurve* theCurveVictim = currentCurve->GetCurve( channelIndex , curve );
				for ( int keyIndex = 0; keyIndex < theCurveVictim->KeyGetCount(); ++keyIndex )
				{
					bool alreadyIn = false;
					for ( unsigned int frameIndex = 0; frameIndex < frames.size(); ++frameIndex )
					{
						if ( ( unsigned int ) frames[frameIndex].GetFrameCount() == ( unsigned int ) theCurveVictim->KeyGet( keyIndex ).GetTime().GetFrameCount() )
						{
							alreadyIn = true;
							//std::cout << frames[frameIndex].GetFrameCount() << " " << theCurveVictim->KeyGet( keyIndex ).GetTime().GetFrameCount() << " " << alreadyIn << std::endl;
							break;
						}
					}
					std::cout << theCurveVictim->KeyGet( keyIndex ).GetTime().GetFrameCount() << " " << alreadyIn << std::endl;
					if(!alreadyIn) frames.push_back(theCurveVictim->KeyGet( keyIndex ).GetTime());
				}
			}
		}
	}
	
	std::sort( frames.begin() , frames.end() , frameCompare );

	FbxAMatrix geoTransform( node->GetGeometricTranslation( FbxNode::eSourcePivot ) , node->GetGeometricRotation( FbxNode::eSourcePivot ) , node->GetGeometricScaling( FbxNode::eSourcePivot ) );


	for ( int i = 0; i < theMesh->GetDeformerCount(); ++i )
	{
		FbxSkin* theSkin = reinterpret_cast< FbxSkin* >( theMesh->GetDeformer( i , FbxDeformer::eSkin ) );
		if ( !theSkin ) continue;

		for ( int j = 0; j < theSkin->GetClusterCount(); ++j )
		{
			FbxCluster* cluster = theSkin->GetCluster( j );
			std::string jointName = cluster->GetLink()->GetName();
			int currentJointIndex = -1;
			for ( unsigned int k = 0; k < skeleton.size(); ++k )
			{
				if ( !skeleton[k].name.compare( jointName ) )
				{
					currentJointIndex = k;
					break;
				}
			}
			if ( currentJointIndex < 0 )
			{
				std::cout << "wrong bone" << std::endl;
				continue;
			}

			FbxAMatrix transformMatrix, transformLinkMatrix, offsetMatrix;
			cluster->GetTransformMatrix( transformMatrix );
			cluster->GetTransformLinkMatrix( transformLinkMatrix );
			//offsetMatrix = transformLinkMatrix.Inverse() * transformMatrix * geoTransform;

			FbxMatrix realMatrix( transformLinkMatrix.Inverse() * transformMatrix );
			
			for ( unsigned int row = 0; row < 4; ++row )
			{
				for ( unsigned int column = 0; column < 4; ++column )
				{
					skeleton[currentJointIndex].offsetMatrix[row][column] = (float)realMatrix.Get( row , column );
				}
			}

			for ( int k = 0; k < cluster->GetControlPointIndicesCount(); ++k )
			{
				BlendingIndexWeightPair weightPair;
				weightPair.blendingIndex = currentJointIndex;
				weightPair.blendingWeight = (float)cluster->GetControlPointWeights()[k];
				unsigned int controlPoint = cluster->GetControlPointIndices()[k];
				for ( unsigned int z = 0; z < indices.size(); ++z )
				{
					if ( indices[z].oldControlPoint == controlPoint )
					{
						if ( verts[indices[z].index].blendingInfo.size() > 4 )
						{
							std::cout << "Warning: vert has more than 4 bones connected, ignoring additional bone." << std::endl;
						}
						//else verts[indices[z].index].blendingInfo.push_back( weightPair );
						bool found = false;
						for ( unsigned int omg = 0; omg < verts[indices[z].index].blendingInfo.size(); ++omg )
						{
							if ( verts[indices[z].index].blendingInfo[omg].blendingIndex == weightPair.blendingIndex )
							{
								found = true;
								break;
							}
						}
						if ( !found ) verts[indices[z].index].blendingInfo.push_back( weightPair );
					}
				}
			}

			for ( unsigned int frameIndex = 0; frameIndex < frames.size(); ++frameIndex )
			{
				FbxVector4 translation = cluster->GetLink()->EvaluateLocalTranslation( frames[frameIndex] );
				FbxVector4 rotation = cluster->GetLink()->EvaluateLocalRotation( frames[frameIndex] );
				FbxVector4 scale = cluster->GetLink()->EvaluateLocalScaling( frames[frameIndex] );
				AnimationData animData;
				animData.frame = (int)frames[frameIndex].GetFrameCount();
				animData.translation = glm::vec3(translation[0],translation[1],translation[2]);
				animData.rotation = glm::angleAxis( glm::radians( (float)rotation[2] ), glm::vec3(0,0,1)) * glm::angleAxis(glm::radians((float) rotation[1]), glm::vec3(0,1,0)) * glm::angleAxis(glm::radians((float)rotation[0]), glm::vec3(1,0,0));
				animData.scale = glm::vec3(scale[0],scale[1],scale[2]);
				skeleton[currentJointIndex].animation.push_back( animData );
			}
		}
	}
}