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);
        }
    }
}
Beispiel #2
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");
}
Beispiel #3
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;
}
// メッシュ情報処理(再帰関数)
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);
	}
}
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);
	}
}
Beispiel #6
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] };
			}
		}
Beispiel #7
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;
	}
}
Beispiel #8
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);
  }
}
Beispiel #9
0
MeshData* FBXImporter::GetMeshInfo()
{
	mMeshData = new MeshData();

	int indicesIndexOffset = 0;		// 记录当前mesh在整个ib中的索引位移。
	int verticesIndexOffset = 0;	// 记录当前mesh在整个vb中的顶点位移。

	for (int meshIndex = 0; meshIndex < mFBXMeshDatas.size(); meshIndex++)
	{
		FbxMesh* mesh = mFBXMeshDatas[meshIndex]->mMesh;
		FBXMeshData* fbxMeshData = mFBXMeshDatas[meshIndex];
		fbxMeshData->mVerticesCount = mesh->GetControlPointsCount();
		fbxMeshData->mIndicesCount = mesh->GetPolygonVertexCount();
		fbxMeshData->mTrianglesCount = mesh->GetPolygonCount();

		// 获取3dsmax中的全局变换矩阵,稍后可以在DX中还原。
		FbxMatrix gloableTransform = mesh->GetNode()->EvaluateGlobalTransform();

		FbxAMatrix matrixGeo;
		matrixGeo.SetIdentity();

		const FbxVector4 lT = mesh->GetNode()->GetGeometricTranslation(FbxNode::eSourcePivot);
		const FbxVector4 lR = mesh->GetNode()->GetGeometricRotation(FbxNode::eSourcePivot);
		const FbxVector4 lS = mesh->GetNode()->GetGeometricScaling(FbxNode::eSourcePivot);

		matrixGeo.SetT(lT);
		matrixGeo.SetR(lR);
		matrixGeo.SetS(lS);

		FbxAMatrix matrixL2W;
		matrixL2W.SetIdentity();

		matrixL2W = mesh->GetNode()->EvaluateGlobalTransform();

		matrixL2W *= matrixGeo;

		XMMATRIX globalTransform = XMLoadFloat4x4(&fbxMeshData->globalTransform);
		FbxMatrixToXMMATRIX(globalTransform, matrixL2W);
		XMStoreFloat4x4(&fbxMeshData->globalTransform, globalTransform);

		// 读取顶点。
		ReadVertices(fbxMeshData);
		// 读取索引。
		ReadIndices(fbxMeshData);

		// 先读取网格对应的材质索引信息,以便优化稍后纹理读取。
		// 一个网格可能只对应一个materialId,也可能对应多个materialId(3dsmax里的Multi/Sub-Object材质)。
		// 如果只对应一个材质,简单的读取就行,不过普遍情况可能是为了优化渲染合并mesh从而拥有多材质。
		// 这个函数调用完毕我们会得到materialId和拥有这个materialId的三角形列表(三角形编号列表),保存在vector<MaterialIdOffset>的容器中。
		//struct Material
		//{
		//	Material() {}
		//	Material(int id, string diffuse, string normalMap)
		//		: materialId(id),
		//		diffuseTextureFile(diffuse),
		//		normalMapTextureFile(normalMap)
		//	{}
		//
		//	int materialId;
		//	string diffuseTextureFile;
		//	string normalMapTextureFile;
		//};
		// struct MaterialIdOffset
		//{
		//	MaterialIdOffset()
		//		: polygonCount(0)
		//	{}
		//	int polygonCount;
		//	Material material;
		//};
		ConnectMaterialsToMesh(mesh, fbxMeshData->mTrianglesCount);

		// 根据ConnectMaterialsToMesh得到的信息读取材质纹理信息,同样存入vector<MaterialIdOffset>容器。
		LoadMaterials(fbxMeshData);

		int triangleCount = mesh->GetPolygonCount();
		int controlPointIndex = 0;
		int normalIndex = 0;
		fbxMeshData->mUVs.resize(fbxMeshData->mIndicesCount, XMFLOAT2(-1.0f, -1.0f));

		// Extract normals and uvs from FbxMesh.
		for (int i = 0; i < triangleCount; i++)
		{
			int polygonSize = mesh->GetPolygonSize(i);

			for (int j = 0; j < polygonSize; j++)
			{ 
				controlPointIndex = mesh->GetPolygonVertex(i, j);

				ReadNormals(fbxMeshData, controlPointIndex, normalIndex);

				// 有纹理我们才读取uv,tangent以及binormal。
				if (fbxMeshData->hasDiffuseTexture())
				{
					ReadUVs(fbxMeshData, controlPointIndex, normalIndex, mesh->GetTextureUVIndex(i, j), 0);
					ReadTangents(fbxMeshData, controlPointIndex, normalIndex);
					ReadBinormals(fbxMeshData, controlPointIndex, normalIndex);
				}

				normalIndex++;
			}
		}

		SplitVertexByNormal(fbxMeshData);

		if (fbxMeshData->hasDiffuseTexture())
		{
			SplitVertexByUV(fbxMeshData);
		}
		else
		{
			fbxMeshData->mUVs.resize(fbxMeshData->mVerticesCount);
		}

		if (fbxMeshData->hasNormalMapTexture())
		{
			SplitVertexByTangent(fbxMeshData);
			SplitVertexByBinormal(fbxMeshData);
		}
		else
		{
			fbxMeshData->mTangents.resize(fbxMeshData->mVerticesCount);
			fbxMeshData->mBinormals.resize(fbxMeshData->mVerticesCount);
		}

		// 如果.fbx包含一个以上的mesh,需要计算当前FBXMeshData的索引在全局索引中的位置。
		for (int i = 0; i < fbxMeshData->mIndicesCount; i++)
		{
			fbxMeshData->mIndices[i] = fbxMeshData->mIndices[i] + verticesIndexOffset;
		}

		mMeshData->verticesCount += fbxMeshData->mVerticesCount;
		mMeshData->indicesCount += fbxMeshData->mIndicesCount;
		mMeshData->meshesCount++;

		// 多材质的情况。
		// 根据之前填充的materialIdOffsets容器保存的materialId和三角形的对应关系,
		// 计算每个RenderPackage渲染所需的索引数量和索引起始位置(偏移)。
		if (isByPolygon && fbxMeshData->hasDiffuseTexture())
		{
			vector<MaterialIdOffset> materialIdOffsets = mMeshData->materialIdOffsets;

			for (int i = 0; i < materialIdOffsets.size(); i++)
			{
				RenderPackage renderPacakge;
				renderPacakge.globalTransform = fbxMeshData->globalTransform;
				renderPacakge.indicesCount = materialIdOffsets[i].polygonCount * 3;
	
				if (i == 0)
				{
					renderPacakge.indicesOffset = indicesIndexOffset;
				}
				else
				{
					renderPacakge.indicesOffset += indicesIndexOffset;
				}

				renderPacakge.material = materialIdOffsets[i].material;

				mMeshData->renderPackages.push_back(renderPacakge);

				indicesIndexOffset += renderPacakge.indicesCount;
			}
		}
		else
		// 单一材质的情况。
		{
			RenderPackage renderPackage;
			renderPackage.indicesCount = fbxMeshData->mIndicesCount;
			renderPackage.indicesOffset = indicesIndexOffset;
			renderPackage.material = fbxMeshData->mMaterial;
			renderPackage.globalTransform = fbxMeshData->globalTransform;

			mMeshData->renderPackages.push_back(renderPackage);

			indicesIndexOffset += fbxMeshData->mIndices.size();
		}

		verticesIndexOffset += fbxMeshData->mVertices.size();

		// 将当前mesh的数据追加到全局数据容器。
		Merge(mMeshData->vertices, fbxMeshData->mVertices);
		Merge(mMeshData->indices, fbxMeshData->mIndices);
		Merge(mMeshData->normals, fbxMeshData->mNormals);
		Merge(mMeshData->uvs, fbxMeshData->mUVs);
		Merge(mMeshData->tangents, fbxMeshData->mTangents);
		Merge(mMeshData->binormals, fbxMeshData->mBinormals);

		mMeshData->materialIdOffsets.clear();
	}

	clear();

	return mMeshData;
}
void MeshImporter::LoadNodeMesh(FbxNode* node, ID3D11Device3* device,
	ID3D11DeviceContext3* context)
{
	unsigned int numPolygons = 0;
	unsigned int numVertices = 0;
	unsigned int numIndices = 0;
	unsigned int numPolygonVert = 0;

	if (node->GetNodeAttribute() != NULL &&
		node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh)
	{
		//PrintNode(node);

		// Create meshes
		FbxMesh* fbxMesh = node->GetMesh();
		numPolygons = fbxMesh->GetPolygonCount();
		numIndices = fbxMesh->GetPolygonVertexCount();
		numVertices = fbxMesh->GetControlPointsCount();

		// Do not use indexed drawing method
		numVertices = numIndices;

		vector<Vertex> vertices(numVertices);
		vector<unsigned int> indices(numIndices);

		numPolygonVert = 3;
		//assert(numPolygonVert == 3);

		FbxVector4* controlPoints = fbxMesh->GetControlPoints();

		int* indices_array = fbxMesh->GetPolygonVertices();

		// Need to be changed for optimization
		for (unsigned int i = 0; i < numIndices; i++)
		{
			indices[i] = indices_array[i];

			vertices[i].pos.x = (float)fbxMesh->GetControlPointAt(indices[i]).mData[0] / 10000.0f;
			vertices[i].pos.y = (float)fbxMesh->GetControlPointAt(indices[i]).mData[1] / 10000.0f;
			vertices[i].pos.z = (float)fbxMesh->GetControlPointAt(indices[i]).mData[2] / 10000.0f;
		}

		// For indexed drawing
		/*for (unsigned int i = 0; i < numVertices; i++)
		{
		vertices[i].pos.x = (float)controlPoints[i].mData[0];// / 25.0f;
		vertices[i].pos.y = (float)controlPoints[i].mData[1];// / 25.0f;
		vertices[i].pos.z = (float)controlPoints[i].mData[2];// / 25.0f;
		}*/

		LoadUV(fbxMesh, &vertices[0], &indices[0]);

		// Set to be clockwise, must be done after reading uvs and normals
		for (auto it = vertices.begin(); it != vertices.end(); it += 3)
		{
			std::swap(*it, *(it + 2));
		}

		//OutputDebugStringA(("\n number of polygons: " + to_string(numPolygons) + " \n").c_str());
		//OutputDebugStringA(("\n number of indices: " + to_string(numIndices) + " \n").c_str());
		//OutputDebugStringA(("\n number of vertices: " + to_string(vertices.size()) + " \n").c_str());

		ModelObj::MeshEntry mesh;
		mesh.vertices = vertices;
		mesh.indices = indices;
		mesh.numVertices = numVertices;
		mesh.numIndices = numIndices;

		LoadMaterials(node, &mesh, device, context);

		model->entries.push_back(mesh);
	}

	for (int i = 0; i < node->GetChildCount(); i++)
	{
		LoadNodeMesh(node->GetChild(i), device, context);
	}
}
	HRESULT FBXLoader::loadFBXFile(char* filePath, VertexBuffer** vBuf, IndexBuffer** iBuf, Renderer* renderer, bool centerShift)
	{
		if (g_pFbxSdkManager == nullptr)
		{
			g_pFbxSdkManager = FbxManager::Create();

			FbxIOSettings* pIOsettings = FbxIOSettings::Create(g_pFbxSdkManager, IOSROOT);
			g_pFbxSdkManager->SetIOSettings(pIOsettings);
		}

		this->shiftCenter = centerShift;

		FbxImporter* pImporter = FbxImporter::Create(g_pFbxSdkManager, "");
		FbxScene* pFbxScene = FbxScene::Create(g_pFbxSdkManager, "");

		bool bSuccess = pImporter->Initialize(filePath, -1, g_pFbxSdkManager->GetIOSettings());
		if (!bSuccess) return E_FAIL;

		bSuccess = pImporter->Import(pFbxScene);
		if (!bSuccess) return E_FAIL;

		FbxAxisSystem sceneAxisSystem = pFbxScene->GetGlobalSettings().GetAxisSystem();
		FbxAxisSystem DirectXAxisSystem(FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eLeftHanded);

		if (sceneAxisSystem != DirectXAxisSystem)
		{
			DirectXAxisSystem.ConvertScene(pFbxScene);
		}

		pImporter->Destroy();

		FbxNode* pFbxRootNode = pFbxScene->GetRootNode();

		if (pFbxRootNode)
		{
			// Check if the getChildCount is > 1  TODO
			int test = pFbxRootNode->GetChildCount();

			for (int i = 0; i < pFbxRootNode->GetChildCount(); i++)
			{
				FbxNode* pFbxChildNode = pFbxRootNode->GetChild(i);

				if (pFbxChildNode->GetNodeAttribute() == NULL)
					continue;

				FbxNodeAttribute::EType AttributeType = pFbxChildNode->GetNodeAttribute()->GetAttributeType();

				if (AttributeType != FbxNodeAttribute::eMesh)
					continue;

				FbxMesh* pMesh = (FbxMesh*)pFbxChildNode->GetNodeAttribute();

				int numControlPoints = pMesh->GetControlPointsCount();
				bool initial = true;
				float xMin, yMin, zMin;
				float xMax, yMax, zMax;
				float xIn, yIn, zIn;

				float xCenter, yCenter, zCenter;

				if (this->shiftCenter){

					for (int c = 0; c < numControlPoints; c++) {
						xIn = (float)pMesh->GetControlPointAt(c).mData[0];
						yIn = (float)pMesh->GetControlPointAt(c).mData[1];
						zIn = (float)pMesh->GetControlPointAt(c).mData[2];

						if (initial) {
							xMin = xIn;
							yMin = yIn;
							zMin = zIn;

							xMax = xIn;
							yMax = yIn;
							zMax = zIn;

							initial = false;
						}
						else {
							if (xIn < xMin) {
								xMin = xIn;
							}

							if (yIn < yMin) {
								yMin = yIn;
							}

							if (zIn < zMin) {
								zMin = zIn;
							}

							if (xIn > xMax) {
								xMax = xIn;
							}

							if (yIn > yMax) {
								yMax = yIn;
							}

							if (zIn > zMax) {
								zMax = zIn;
							}
						}
					}
					xCenter = (xMin + xMax) / 2.0f;
					yCenter = (yMin + yMax) / 2.0f;
					zCenter = (zMin + zMax) / 2.0f;
				}
				else {
					xCenter = 0;
					yCenter = 0;
					zCenter = 0;
				}

				FbxVector4* pVertices = pMesh->GetControlPoints();
				int vertexCount = pMesh->GetPolygonVertexCount();

				//Vertex vertex;
				Vertex* vertexArray = new Vertex[vertexCount];
				//Vertex vertexArray[2592];


				int numIndices = vertexCount;
				unsigned int* indexArray = new unsigned int[numIndices];


				FbxVector4 fbxNorm(0, 0, 0, 0);
				FbxVector2 fbxUV(0, 0);
				bool isMapped;

				int vertexIndex = 0;

				// Loop iterates through the polygons and fills the vertex and index arrays for the buffers
				for (int j = 0; j < pMesh->GetPolygonCount(); j++)
				{
					int iNumVertices = pMesh->GetPolygonSize(j);

					assert(iNumVertices == 3);

					//1st vertex
					int controlIndex = pMesh->GetPolygonVertex(j, 2);
					pMesh->GetPolygonVertexUV(j, 2, "map1", fbxUV, isMapped);
					pMesh->GetPolygonVertexNormal(j, 2, fbxNorm);

					vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter;
					vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter;
					vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter;

					vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0];
					vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1];

					vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0];
					vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1];
					vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2];

					indexArray[vertexIndex] = vertexIndex;
					vertexIndex++;

					//2nd vertex
					controlIndex = pMesh->GetPolygonVertex(j, 1);
					pMesh->GetPolygonVertexUV(j, 1, "map1", fbxUV, isMapped);
					pMesh->GetPolygonVertexNormal(j, 1, fbxNorm);

					vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter;
					vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter;
					vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter;

					vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0];
					vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1];

					vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0];
					vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1];
					vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2];

					indexArray[vertexIndex] = vertexIndex;
					vertexIndex++;

					//3rd vertex
					controlIndex = pMesh->GetPolygonVertex(j, 0);
					pMesh->GetPolygonVertexUV(j, 0, "map1", fbxUV, isMapped);
					pMesh->GetPolygonVertexNormal(j, 0, fbxNorm);

					vertexArray[vertexIndex].point[0] = (float)pVertices[controlIndex].mData[0] - xCenter;
					vertexArray[vertexIndex].point[1] = (float)pVertices[controlIndex].mData[1] - yCenter;
					vertexArray[vertexIndex].point[2] = -(float)pVertices[controlIndex].mData[2] - zCenter;

					vertexArray[vertexIndex].texCoord[0] = (float)fbxUV[0];
					vertexArray[vertexIndex].texCoord[1] = 1.0f - (float)fbxUV[1];

					vertexArray[vertexIndex].normal[0] = (float)fbxNorm[0];
					vertexArray[vertexIndex].normal[1] = (float)fbxNorm[1];
					vertexArray[vertexIndex].normal[2] = -(float)fbxNorm[2];

					indexArray[vertexIndex] = vertexIndex;
					vertexIndex++;
				}

				// Generate vertex and index buffers from the vertex and index arrays
				*vBuf = renderer->createVertexBuffer(vertexArray, vertexCount);
				*iBuf = renderer->createIndexBuffer(indexArray, numIndices);

				delete[] vertexArray;
				delete[] indexArray;
			}
		}
		return S_OK;
	}
Beispiel #12
0
bool FillData(ModelData* someData,FbxNode* aNode, AnimationData* aAnimation)
{
	FbxMesh* mesh = aNode->GetMesh();
	if (mesh == nullptr || !aNode)
		return false;

	const int lPolygonCount = mesh->GetPolygonCount();

	// Count the polygon count of each material
	FbxLayerElementArrayTemplate<int>* lMaterialIndice = NULL;
	FbxGeometryElement::EMappingMode lMaterialMappingMode = FbxGeometryElement::eNone;
	if (mesh->GetElementMaterial())
	{
		lMaterialIndice = &mesh->GetElementMaterial()->GetIndexArray();
		lMaterialMappingMode = mesh->GetElementMaterial()->GetMappingMode();
		if (lMaterialIndice && lMaterialMappingMode == FbxGeometryElement::eByPolygon)
		{
			FBX_ASSERT(lMaterialIndice->GetCount() == lPolygonCount);
			if (lMaterialIndice->GetCount() == lPolygonCount)
			{
				// Count the faces of each material
				for (int lPolygonIndex = 0; lPolygonIndex < lPolygonCount; ++lPolygonIndex)
				{
					const int lMaterialIndex = lMaterialIndice->GetAt(lPolygonIndex);
					lMaterialIndex;
					/*if (someData->mSubMeshes[lMaterialIndex] == NULL)
					{
						someData->mSubMeshes[lMaterialIndex] = new ModelData::SubMesh;
					}
					someData->mSubMeshes[lMaterialIndex]->TriangleCount += 1;*/
				}

				// Make sure we have no "holes" (NULL) in the mSubMeshes table. This can happen
				// if, in the loop above, we resized the mSubMeshes by more than one slot.
					
				/*for (int i = 0; i < someData->mSubMeshes.Count(); i++)
				{
					if (someData->mSubMeshes[i] == NULL)
						someData->mSubMeshes[i] = new ModelData::SubMesh;
				}*/

				// Record the offset (how many vertex)
				const int lMaterialCount = someData->mSubMeshes.Size();
				lMaterialCount;
				int lOffset = 0;
				/*for (int lIndex = 0; lIndex < lMaterialCount; ++lIndex)
				{
					someData->mSubMeshes[lIndex]->IndexOffset = lOffset;
					lOffset += someData->mSubMeshes[lIndex]->TriangleCount * 3;
					// This will be used as counter in the following procedures, reset to zero
					someData->mSubMeshes[lIndex]->TriangleCount = 0;
				}*/
				FBX_ASSERT(lOffset == lPolygonCount * 3);
			}
		}
	}

	// All faces will use the same material.
	if (someData->mSubMeshes.Size() == 0)
	{
		if (someData->mSubMeshes.GetCapacity() == 0)
		{
			someData->mSubMeshes.Init(1);
		}
		someData->mSubMeshes.RemoveAll();
		someData->mSubMeshes.AddEmptyObject();
		someData->mSubMeshes[0] = new ModelData::SubMesh();
	}

		

	bool hasNormalMap = false;

	const int lMaterialCount = aNode->GetMaterialCount();
	for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
	{
		FbxSurfaceMaterial * lMaterial = aNode->GetMaterial(lMaterialIndex);
		if (lMaterial && !lMaterial->GetUserDataPtr())
		{
			TextureInfo diffuseInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sDiffuse,FbxSurfaceMaterial::sDiffuseFactor,diffuseInfo.myFileName);
			diffuseInfo.myType = DIFFUSE;
			if(diffuseInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(diffuseInfo);
			}

			TextureInfo normalInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sNormalMap,FbxSurfaceMaterial::sBumpFactor,normalInfo.myFileName);
			hasNormalMap = normalInfo.myFileName.empty() == false;
			normalInfo.myType = NORMALMAP;
			if(normalInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(normalInfo);
				hasNormalMap = true;
			}

			TextureInfo roughnessInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sSpecular,FbxSurfaceMaterial::sSpecularFactor,roughnessInfo.myFileName);
			roughnessInfo.myType = ROUGHNESS;
			if(roughnessInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(roughnessInfo);
			}

			TextureInfo substanceInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sReflection,FbxSurfaceMaterial::sReflectionFactor,substanceInfo.myFileName);
			substanceInfo.myType = SUBSTANCE;
			if(substanceInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(substanceInfo);
			}

			TextureInfo ambientInfo;
			GetMaterialProperty(lMaterial, FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor, ambientInfo.myFileName);
			ambientInfo.myType = AO;
			if (substanceInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(ambientInfo);
			}
		}
	}

	// Congregate all the data of a mesh to be cached in VBOs.
	// If normal or UV is by polygon vertex, record all vertex attributes by polygon vertex.'
		
	someData->mHasNormal = mesh->GetElementNormalCount() > 0;
	someData->mHasUV = mesh->GetElementUVCount() > 0;
	someData->myHasBiNormal = mesh->GetElementBinormalCount() > 0;

	FbxSkin * lSkinDeformer = (FbxSkin *)mesh->GetDeformer(0, FbxDeformer::eSkin);
	someData->myHasSkinweights = lSkinDeformer != nullptr;

	if(hasNormalMap && someData->myHasBiNormal == false)
	{
		mesh->GenerateTangentsDataForAllUVSets();
		someData->myHasBiNormal = mesh->GetElementBinormalCount() > 0;
	}
	someData->myHasTangents = mesh->GetElementTangentCount() > 0;
		
	FbxGeometryElement::EMappingMode lNormalMappingMode = FbxGeometryElement::eNone;
	FbxGeometryElement::EMappingMode lUVMappingMode = FbxGeometryElement::eNone;
	if (someData->mHasNormal)
	{
		lNormalMappingMode = mesh->GetElementNormal(0)->GetMappingMode();
		if (lNormalMappingMode == FbxGeometryElement::eNone)
		{
			someData->mHasNormal = false;
		}
		if (someData->mHasNormal && lNormalMappingMode != FbxGeometryElement::eByControlPoint)
		{
			someData->mAllByControlPoint = false;
		}
	}
	if (someData->mHasUV)
	{
		lUVMappingMode = mesh->GetElementUV(0)->GetMappingMode();
		if (lUVMappingMode == FbxGeometryElement::eNone)
		{
			someData->mHasUV = false;
		}
		if (someData->mHasUV && lUVMappingMode != FbxGeometryElement::eByControlPoint)
		{
			someData->mAllByControlPoint = false;
		}
	}

	// Allocate the array memory, by control point or by polygon vertex.
	int lPolygonVertexCount = mesh->GetControlPointsCount();
	//if (!someData->my)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_POS;
		newLayout.mySize = VERTEX_STRIDE;
		newLayout.myOffset = 0;
		someData->myLayout.Add(newLayout);
		lPolygonVertexCount = lPolygonCount * TRIANGLE_VERTEX_COUNT;
	}
	int stride = VERTEX_STRIDE;
	size_t size = lPolygonVertexCount * VERTEX_STRIDE;
	//float * lVertices = new float[lPolygonVertexCount * VERTEX_STRIDE];
	unsigned int * lIndices = new unsigned int[lPolygonCount * TRIANGLE_VERTEX_COUNT];
	someData->myIndexCount = lPolygonCount * TRIANGLE_VERTEX_COUNT;
	//float * lNormals = NULL;
	if (someData->mHasNormal)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_NORMAL;
		newLayout.mySize = NORMAL_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += NORMAL_STRIDE;
		size += lPolygonVertexCount * NORMAL_STRIDE;
		//lNormals = new float[lPolygonVertexCount * NORMAL_STRIDE];
	}
	//float * lUVs = NULL;
	FbxStringList lUVNames;
	mesh->GetUVSetNames(lUVNames);
	const char * lUVName = NULL;
	if (someData->mHasUV && lUVNames.GetCount())
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_UV;
		newLayout.mySize = UV_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += UV_STRIDE;
		size += lPolygonVertexCount * UV_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
		lUVName = lUVNames[0];
	}

	if (someData->myHasBiNormal)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_BINORMAL;
		newLayout.mySize = BINORMAL_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += BINORMAL_STRIDE;
		size += lPolygonVertexCount * BINORMAL_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
	}

	if (someData->myHasTangents)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_TANGENT;
		newLayout.mySize = TANGENT_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += TANGENT_STRIDE;
		size += lPolygonVertexCount * TANGENT_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
	}

	if (someData->myHasSkinweights)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_SKINWEIGHTS;
		newLayout.mySize = SKINWEIGHT_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += SKINWEIGHT_STRIDE;
		size += lPolygonVertexCount * SKINWEIGHT_STRIDE;

		newLayout.myType = ModelData::VERTEX_BONEID;
		newLayout.mySize = BONEID_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += BONEID_STRIDE;
		size += lPolygonVertexCount * BONEID_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
	}

	float * lVertices = new float[size];

	FbxAMatrix globalPos;
	FbxVector4* weights = nullptr;
	FbxVectorTemplate4<int>* bones = nullptr;
	FbxTime time = static_cast<FbxTime>(0.0f);
	if(someData->myHasSkinweights)
	{
		weights = new FbxVector4[mesh->GetControlPointsCount()];
		bones = new FbxVectorTemplate4<int>[mesh->GetControlPointsCount()];
		ComputeLinearDeformation(globalPos,mesh,weights,bones,aAnimation);
	}

	const FbxGeometryElementBinormal * lBiNormalElement = NULL;
	const FbxGeometryElementTangent * lTangentElement = NULL;

	if (someData->myHasBiNormal)
	{
		lBiNormalElement = mesh->GetElementBinormal(0);
	}
	if (someData->myHasTangents)
	{
		lTangentElement = mesh->GetElementTangent(0);
	}

	// Populate the array with vertex attribute, if by control point.
	const FbxVector4 * lControlPoints = mesh->GetControlPoints();
	FbxVector4 lCurrentVertex;
	FbxVector4 lCurrentNormal;
	FbxVector4 lCurrentBiNormal;
	FbxVector4 lCurrentTangent;
	FbxVector2 lCurrentUV;
	if (someData->mAllByControlPoint)
	{
		const FbxGeometryElementNormal * lNormalElement = NULL;
		const FbxGeometryElementUV * lUVElement = NULL;
		if (someData->mHasNormal)
		{
			lNormalElement = mesh->GetElementNormal(0);
		}
		if (someData->mHasUV)
		{
			lUVElement = mesh->GetElementUV(0);
		}

		for (int lIndex = 0; lIndex < lPolygonVertexCount; ++lIndex)
		{
			int currentIndex = lIndex * stride;
			int addedSize = VERTEX_STRIDE;
			// Save the vertex position.
			lCurrentVertex = lControlPoints[lIndex];
				
			CU::Vector4f position(static_cast<float>(lCurrentVertex[0]),
					static_cast<float>(lCurrentVertex[1]),
					static_cast<float>(lCurrentVertex[2]),
					1);

			CU::Matrix44f fixMatrix;
			fixMatrix = CU::Matrix44<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1,0,0));
			position = position*fixMatrix;

			lVertices[currentIndex] = position.x;
			lVertices[currentIndex + 1] = position.y;
			lVertices[currentIndex + 2] = position.z;
			lVertices[currentIndex + 3] = 1;


			// Save the normal.
			if (someData->mHasNormal)
			{
				int lNormalIndex = lIndex;
				if (lNormalElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
				{
					lNormalIndex = lNormalElement->GetIndexArray().GetAt(lIndex);
				}
				lCurrentNormal = lNormalElement->GetDirectArray().GetAt(lNormalIndex);

				CU::Vector3f normal( static_cast<float>(lCurrentNormal[0]), static_cast<float>(lCurrentNormal[1]), static_cast<float>(lCurrentNormal[2]));
				normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));

				lVertices[currentIndex + addedSize] = normal.x;
				lVertices[currentIndex + addedSize + 1] = normal.y;
				lVertices[currentIndex + addedSize + 2] = normal.z;
				lVertices[currentIndex + addedSize + 3] = 0;
				addedSize += NORMAL_STRIDE;
			}

			// Save the UV.
			if (someData->mHasUV)
			{
				int lUVIndex = lIndex;
				if (lUVElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
				{
					lUVIndex = lUVElement->GetIndexArray().GetAt(lIndex);
				}
				lCurrentUV = lUVElement->GetDirectArray().GetAt(lUVIndex);
				lVertices[currentIndex + addedSize] = static_cast<float>(lCurrentUV[0]);
				lVertices[currentIndex + addedSize + 1] = static_cast<float>(lCurrentUV[1])*-1.0f;
				addedSize += 2;
			}

			if (someData->myHasBiNormal)
				{
					int lBinormIndexIndex = lIndex;
					if (lBiNormalElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lBiNormalElement->GetIndexArray().GetAt(lIndex);
					}

					lCurrentBiNormal = lBiNormalElement->GetDirectArray().GetAt(lBinormIndexIndex);
					//mesh->GetElementBinormal(lPolygonIndex, lVerticeIndex, lCurrentNormal);
					//lCurrentNormal = lCurrentNormal
					CU::Vector3f normal( static_cast<float>(lCurrentBiNormal[0]), static_cast<float>(lCurrentBiNormal[1]), static_cast<float>(lCurrentBiNormal[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += BINORMAL_STRIDE;
				}

				if (someData->myHasTangents)
				{
					int lBinormIndexIndex = lIndex;
					if (lTangentElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lTangentElement->GetIndexArray().GetAt(lIndex);
					}

					lCurrentTangent = lTangentElement->GetDirectArray().GetAt(lBinormIndexIndex);

					//lCurrentNormal = lCurrentNormal
					CU::Vector3f normal( static_cast<float>(lCurrentTangent[0]), static_cast<float>(lCurrentTangent[1]), static_cast<float>(lCurrentTangent[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += TANGENT_STRIDE;
				}

				if(someData->myHasSkinweights)
				{
					FbxVector4 currentWeights = weights[lIndex];
					//currentWeights.Normalize();

					lVertices[currentIndex + addedSize] = static_cast<float>(currentWeights[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(currentWeights[1]);
					lVertices[currentIndex + addedSize + 2] = static_cast<float>(currentWeights[2]);
					lVertices[currentIndex + addedSize + 3] = static_cast<float>(currentWeights[3]);
					addedSize += SKINWEIGHT_STRIDE;

					FbxVectorTemplate4<int> currentBones = bones[lIndex];

					lVertices[currentIndex + addedSize] = static_cast<float>(currentBones[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(currentBones[1]);
					lVertices[currentIndex + addedSize + 2] = static_cast<float>(currentBones[2]);
					lVertices[currentIndex + addedSize + 3] = static_cast<float>(currentBones[3]);
					addedSize += BONEID_STRIDE;
				}
		}

	}

	int lVertexCount = 0;
	for (int lPolygonIndex = 0; lPolygonIndex < lPolygonCount; ++lPolygonIndex)
	{
		// The material for current face.
		int lMaterialIndex = 0;
		if (lMaterialIndice && lMaterialMappingMode == FbxGeometryElement::eByPolygon)
		{
			lMaterialIndex = lMaterialIndice->GetAt(lPolygonIndex);
		}

		// Where should I save the vertex attribute index, according to the material
		const int lIndexOffset = someData->mSubMeshes[lMaterialIndex]->IndexOffset +
			someData->mSubMeshes[lMaterialIndex]->TriangleCount * 3;
		for (int lVerticeIndex = TRIANGLE_VERTEX_COUNT-1; lVerticeIndex > -1; --lVerticeIndex)
		{
			const int lControlPointIndex = mesh->GetPolygonVertex(lPolygonIndex, lVerticeIndex);
				
			int vertexIndex = lIndexOffset + (TRIANGLE_VERTEX_COUNT-1) - lVerticeIndex;
			if (someData->mAllByControlPoint)
			{
				lIndices[vertexIndex] = static_cast<unsigned int>(lControlPointIndex);
			}
			// Populate the array with vertex attribute, if by polygon vertex.
			else
			{
				lIndices[vertexIndex] = static_cast<unsigned int>(lVertexCount);

				lCurrentVertex = lControlPoints[lControlPointIndex];
				int addedSize = VERTEX_STRIDE;
				int currentIndex = lVertexCount * stride;

				CU::Vector4f position(static_cast<float>(lCurrentVertex[0]),
					static_cast<float>(lCurrentVertex[1]),
					static_cast<float>(lCurrentVertex[2]),
					1);

				//fixMatrix
				CU::Matrix44f fixMatrix;
				fixMatrix = CU::Matrix44<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
				position = position*fixMatrix;

				lVertices[currentIndex] = position.x;
				lVertices[currentIndex + 1] = position.y;
				lVertices[currentIndex + 2] = position.z;
				lVertices[currentIndex + 3] = 0;

				if (someData->mHasNormal)
				{
					mesh->GetPolygonVertexNormal(lPolygonIndex, lVerticeIndex, lCurrentNormal);
					CU::Vector3f normal( static_cast<float>(lCurrentNormal[0]), static_cast<float>(lCurrentNormal[1]), static_cast<float>(lCurrentNormal[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);

					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += NORMAL_STRIDE;
				}

				if (someData->mHasUV)
				{
					bool lUnmappedUV;
					mesh->GetPolygonVertexUV(lPolygonIndex, lVerticeIndex, lUVName, lCurrentUV, lUnmappedUV);
					lVertices[currentIndex + addedSize] = static_cast<float>(lCurrentUV[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(lCurrentUV[1])*-1.0f;
					addedSize += UV_STRIDE;
				}
					
				if (someData->myHasBiNormal)
				{
					int lBinormIndexIndex = lVerticeIndex;
					if (lBiNormalElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lBiNormalElement->GetIndexArray().GetAt(lVerticeIndex);
					}

					lCurrentBiNormal = lBiNormalElement->GetDirectArray().GetAt(lBinormIndexIndex);

					CU::Vector3f normal( static_cast<float>(lCurrentBiNormal[0]), static_cast<float>(lCurrentBiNormal[1]), static_cast<float>(lCurrentBiNormal[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += BINORMAL_STRIDE;
				}

				if (someData->myHasTangents)
				{
					int lBinormIndexIndex = lVerticeIndex;
					if (lTangentElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lTangentElement->GetIndexArray().GetAt(lVerticeIndex);
					}

					lCurrentTangent = lTangentElement->GetDirectArray().GetAt(lBinormIndexIndex);

					mesh->GetPolygonVertexNormal(lPolygonIndex, lVerticeIndex, lCurrentNormal);

					CU::Vector3f normal( static_cast<float>(lCurrentTangent[0]), static_cast<float>(lCurrentTangent[1]), static_cast<float>(lCurrentTangent[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += TANGENT_STRIDE;
				}

				if(someData->myHasSkinweights)
				{
					FbxVector4 currentWeights = weights[lControlPointIndex];
					FbxVectorTemplate4<int> currentBones = bones[lControlPointIndex];
					for(int l = 0;l < 4;++l)
					{
						if(currentBones[l] == -1)
						{
							currentWeights[l] = 0.0f;
						}
					}
					currentWeights.Normalize();

					lVertices[currentIndex + addedSize] = static_cast<float>(currentWeights[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(currentWeights[1]);
					lVertices[currentIndex + addedSize + 2] = static_cast<float>(currentWeights[2]);
					lVertices[currentIndex + addedSize + 3] = static_cast<float>(currentWeights[3]);
					addedSize += SKINWEIGHT_STRIDE;

						

					lVertices[currentIndex + addedSize] = *(float*)&currentBones[0];
					lVertices[currentIndex + addedSize + 1] = *(float*)&currentBones[1];
					lVertices[currentIndex + addedSize + 2] = *(float*)&currentBones[2];
					lVertices[currentIndex + addedSize + 3] = *(float*)&currentBones[3];
					addedSize += BONEID_STRIDE;
				}
			}
			++lVertexCount;
		}
		someData->mSubMeshes[lMaterialIndex]->TriangleCount += 1;
	}

	someData->myVertexCount = lVertexCount;
	someData->myVertexStride = stride;

	someData->myVertexBuffer = lVertices;
	someData->myIndicies = lIndices;

	if(weights)
	{
		delete [] weights;
		delete [] bones;
	}

	return true;
}
Beispiel #13
0
void fbxLoader2::processMesh(FbxNode* node)
{
	FbxMesh* mesh = node->GetMesh();

	this->readAnimationWeigths(mesh);

	if(mesh!=NULL && mesh->IsTriangleMesh())
	{
		for (int i = 0; i<mesh->GetControlPointsCount(); i++)
		{
			readVertex(mesh, i, &vertex[i]);
			vertexArray[i].position = D3DXVECTOR3(vertex[i]);
		}

		int a = mesh->GetPolygonVertexCount();

		for (int i = 0; i<mesh->GetPolygonVertexCount(); i++)
		{
			readUV(mesh, i, 0, &uv[i]);
			readNormal(mesh, i, &normal[i]);
			indices[i].indice = mesh->GetPolygonVertices()[i];
			indices[i].normal1 = normal[i];
			indices[i].uv1 = uv[i];
			indicesMeshCount++;
		}
	}

	//vertexLists.push_back(vertexArray);
	indiceLists.push_back(indices);

	FbxAnimStack* pAnimStack = FbxCast<FbxAnimStack>(scene->GetSrcObject(FBX_TYPE(FbxAnimStack)));
	int numAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(FbxAnimLayer));

	this->setBindPoseCluster(node);

	for (int i = 0; i < numAnimLayers; i++)
	{
		FbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(FbxAnimLayer), i);
		FbxAnimCurve* animCv = this->findSkeletonRootBone(scene->GetRootNode())->GetChild(0)->LclTranslation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);

		if (animCv)
		{
			FbxTimeSpan animationLength;
			int p = animCv->KeyGetCount();
			animCv->GetTimeInterval(animationLength);

			for(int j = 0; j<animationStructure->GetFramesNumber();j++)
			{
				FbxTime timeKey = animCv->KeyGet(j).mTime;
				//FbxTime interval = (duration/p)*j + animationLength.GetStart();

				//int intervalVal = (duration.GetSecondCount()/p)*j + animationLength.GetStart().GetSecondCount();
				const FbxTime pTime = animCv->KeyGet(j).mTime;


				FbxAMatrix pGlobalPos = GetGlobalPosition(node, pTime, scene->GetPose(j));

				ComputeSkinDeformation(pGlobalPos, mesh, timeKey, scene->GetPose(j), j);
			}
		}
	}

	for(int i = 0; i<node->GetChildCount(); i++)
	{
		processMesh(node->GetChild(i));
	}
}
Beispiel #14
0
Model* FbxModelLoader::LoadModel(const char* fileName)
{
	Model* model = nullptr;

	if (!m_importer->Initialize(fileName, -1, m_manager->GetIOSettings()))
	{
		return nullptr;
	}

	FbxScene* lScene = FbxScene::Create(m_manager, "myscene");
	m_importer->Import(lScene);


	FbxNode* lRootNode = lScene->GetRootNode();

	if (lRootNode)
	{
		if (lRootNode->GetChildCount() > 0)
		{
			FbxNode* lNode = lRootNode->GetChild(0);

			FbxMesh* lMesh = lNode->GetMesh();

			

			if (!lMesh)
				return nullptr;

			
			std::ofstream file;

			file.open("DataFromFbxVector.txt");
			char* buffer = new char[1024];

			sprintf_s(buffer, 1024, "Number of children in Root: %d\n\n\n\n", lRootNode->GetChildCount());

			file << buffer;

			if (lMesh->IsTriangleMesh())
				file << "It's a triangle mesh!";
			else
				file << "It's NOT a triangle mesh!";

			


			FbxVector4* vertexArray = lMesh->GetControlPoints();

			for (int i = 0; i < lMesh->GetControlPointsCount(); i++)
			{
				sprintf(buffer, "(%f, %f, %f)\n", vertexArray[i].mData[0], vertexArray[i].mData[1], vertexArray[i].mData[2]);
				file << buffer;
			}

			delete buffer;

			file.close();

			Polygon* polygons = new Polygon[lMesh->GetPolygonCount()];

			int polygonCount = lMesh->GetPolygonCount();

			int index = 0;

			buffer = new char[1024];
			file.open("DataFromPolygons.txt");

			for (int i = 0; i < lMesh->GetPolygonCount(); i++)
			{
				

				index = lMesh->GetPolygonVertex(i, 0);

				sprintf(buffer, "\n\nPolygon #%d\nPolygon Vertex Index #%d: ", i, index);
				file << buffer;

				polygons[i].vertex1.x = (float)vertexArray[index].mData[0];
				polygons[i].vertex1.y = (float)vertexArray[index].mData[1];
				polygons[i].vertex1.z = (float)vertexArray[index].mData[2];

				sprintf(buffer, "(%f, %f, %f)\n", polygons[i].vertex1.x, polygons[i].vertex1.y, polygons[i].vertex1.z);
				file << buffer;


				
				index = lMesh->GetPolygonVertex(i, 1);
				sprintf(buffer, "Polygon Vertex Index #%d: ", index);
				file << buffer;

				polygons[i].vertex2.x = (float)vertexArray[index].mData[0];
				polygons[i].vertex2.y = (float)vertexArray[index].mData[1];
				polygons[i].vertex2.z = (float)vertexArray[index].mData[2];
				sprintf(buffer, "(%f, %f, %f)\n", polygons[i].vertex2.x, polygons[i].vertex2.y, polygons[i].vertex2.z);
				file << buffer;
				
				index = lMesh->GetPolygonVertex(i, 2);
				sprintf(buffer, "Polygon Vertex Index #%d: ", index);
				file << buffer;

				polygons[i].vertex3.x = (float)vertexArray[index].mData[0];
				polygons[i].vertex3.y = (float)vertexArray[index].mData[1];
				polygons[i].vertex3.z = (float)vertexArray[index].mData[2];
				sprintf(buffer, "(%f, %f, %f)\n", polygons[i].vertex3.x, polygons[i].vertex3.y, polygons[i].vertex3.z);
				file << buffer;
			}

			file.close();
			delete buffer;


			model = new Model();
			model->Vertices = new DirectX::XMFLOAT3[polygonCount * 3];
			model->NumVertices = polygonCount * 3;

			file.open("DataFromPolygonToModelTransfer.txt");
			buffer = new char[1024];

			for (int i = 0; i < lMesh->GetPolygonCount() * 3; i += 3)
			{
				model->Vertices[i] = polygons[i/3].vertex1;
				model->Vertices[i+1] = polygons[i/3].vertex2;
				model->Vertices[i+2] = polygons[i/3].vertex3;
			
				sprintf_s(buffer, 1024, "Polygon #%d:\n(%f, %f, %f)\n(%f, %f, %f)\n(%f, %f, %f)\n\n"
					, i / 3
					, model->Vertices[i].x, model->Vertices[i].y, model->Vertices[i].z
					, model->Vertices[i+1].x, model->Vertices[i+1].y, model->Vertices[i+1].z
					, model->Vertices[i+2].x, model->Vertices[i+2].y, model->Vertices[i+2].z);
			
				file << buffer;
			}

			delete buffer;
			file.close();


			// delete [] polygons;
		}
		else
			return nullptr;
	}
	else
		return nullptr;



	return model;
}
Beispiel #15
0
	void importFBXNode(
		FbxNode *node, 
		vector<Vector3> &vertices, 
		vector<Color> &colors, 
		vector<Vector2> &uvs, 
		vector<Vector3> &normals,
		vector<uint32> &elements) {

		FbxNode *childNode = 0;
		int numKids = node->GetChildCount();
		for ( int i=0 ; i<numKids ; i++)
		{
			childNode = node->GetChild(i);
			FbxMesh *mesh = childNode->GetMesh();

			if ( mesh != NULL )
			{
				auto offset = node->GetGeometricTranslation(FbxNode::eSourcePivot);

				//================= Get Vertices ====================================
				int baseline = vertices.size();
				int numVerts = mesh->GetControlPointsCount();

				for ( int j=0; j<numVerts; j++)
				{
					FbxVector4 vert = mesh->GetControlPointAt(j);
					vertices.push_back(
						Vector3(vert.mData[0], vert.mData[1], vert.mData[2])
						/*+ Vector3(offset.mData[0], offset.mData[1], offset.mData[2])*/);
					colors.push_back(Vector3(1, 1, 1));
					uvs.push_back(Vector2(0, 0));
				}

				//================= Get Indices ====================================
				int numIndices=mesh->GetPolygonVertexCount();
				int *indicesRaw = mesh->GetPolygonVertices();
				for (int j = 0; j < numIndices; j++) {
					elements.push_back(indicesRaw[j] + baseline);
				}

				int cnt = 0;
				int polygonCount = mesh->GetPolygonCount();
				for (int j = 0; j < polygonCount; ++j) {

					FbxLayerElementArrayTemplate<FbxVector2>* uvVertices= 0;
					mesh->GetTextureUV(&uvVertices, FbxLayerElement::eTextureDiffuse);

					for (int k = 0; k < mesh->GetPolygonSize(j); ++k) {

						FbxVector2 uv = (*uvVertices)[mesh->GetTextureUVIndex(j, k)];

						uvs[indicesRaw[cnt] + baseline].x = uv[0];
						uvs[indicesRaw[cnt] + baseline].y = uv[1];
						cnt++;
					}
				}
			}

			importFBXNode(childNode, vertices, colors, uvs, normals, elements);
		}
	}
void MeshImporter::LoadNodeMesh(FbxNode* node, ID3D11Device3* device,
	ID3D11DeviceContext3* context)
{
	unsigned int numPolygons = 0;
	unsigned int numVertices = 0;
	unsigned int numIndices = 0;
	unsigned int numPolygonVert = 0;

	if (node->GetNodeAttribute() != NULL &&
		node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eMesh)
	{
		//PrintNode(node);
		
		// Create meshes
		FbxMesh* fbxMesh = node->GetMesh();
		
		numPolygons = fbxMesh->GetPolygonCount();
		numIndices = fbxMesh->GetPolygonVertexCount();
		numVertices = fbxMesh->GetControlPointsCount();
		
		// Do not use indexed drawing method
		numVertices = numIndices;

		vector<Vertex> vertices(numVertices);
		vector<unsigned int> indices(numIndices);

		numPolygonVert = 3;
		//assert(numPolygonVert == 3);

		FbxVector4* controlPoints = fbxMesh->GetControlPoints();

		int* indices_array = fbxMesh->GetPolygonVertices();

		// Need to be changed for optimization
		for (unsigned int i = 0; i < numIndices; i++)
		{
			indices[i] = indices_array[i];

			vertices[i].pos.x = (float)fbxMesh->GetControlPointAt(indices[i]).mData[0];// / 1000.0f;
			vertices[i].pos.y = (float)fbxMesh->GetControlPointAt(indices[i]).mData[1];// / 1000.0f;
			vertices[i].pos.z = (float)fbxMesh->GetControlPointAt(indices[i]).mData[2];// / 1000.0f;
		}

		// For indexed drawing
		/*for (unsigned int i = 0; i < numVertices; i++)
		{
			vertices[i].pos.x = (float)controlPoints[i].mData[0];
			vertices[i].pos.y = (float)controlPoints[i].mData[1];
			vertices[i].pos.z = (float)controlPoints[i].mData[2];
		}*/

		LoadUV(fbxMesh, &vertices[0], &indices[0]);

		//OutputDebugStringA(("\n number of polygons: " + to_string(numPolygons) + " \n").c_str());
		//OutputDebugStringA(("\n number of indices: " + to_string(numIndices) + " \n").c_str());
		//OutputDebugStringA(("\n number of vertices: " + to_string(vertices.size()) + " \n").c_str());

		// Read mesh base transform matrix
		FbxAMatrix fbxGlobalMeshBaseMatrix = node->EvaluateGlobalTransform().Inverse().Transpose();
		XMFLOAT4X4 globalMeshBaseMatrix;

		for (int r = 0; r < 4; r++)
		{
			//PrintTab("Global mesh base mat: " + to_string(fbxGlobalMeshBaseMatrix.mData[r][0]));

			for (int c = 0; c < 4; c++)
			{
				globalMeshBaseMatrix.m[r][c] = (float)fbxGlobalMeshBaseMatrix.mData[r][c];
			}
		}

		// To be considered when importing Maya fbx model
		//FbxAMatrix geoMatrix = GetTransformMatrix(node);

		//ConvertFbxAMatrixToDXMatrix(&globalMeshBaseMatrix, fbxGlobalMeshBaseMatrix);

		MeshEntry mesh;
		mesh.vertices = vertices;
		mesh.indices = indices;
		mesh.numVertices = numVertices;
		mesh.numIndices = numIndices;
		mesh.fbxNode = node;
		mesh.globalMeshBaseMatrix = globalMeshBaseMatrix;

		// Load materials and textures
		LoadMaterials(node, &mesh, device, context);

		// Load weights
		LoadWeight(fbxMesh, &mesh);

		// Set to be clockwise, must be done after reading uvs, normals, weights and etc
		for (auto it = mesh.vertices.begin(); it != mesh.vertices.end(); it += 3)
		{
			swap(*it, *(it + 2));
		}

		model->entries.push_back(mesh);
	}

	int numChild = node->GetChildCount();

	for (int i = 0; i < numChild; i++)
	{
		LoadNodeMesh(node->GetChild(i), device, context);
	}
}
Beispiel #17
0
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);
}
Beispiel #18
0
	void FbxLoader::LoadAttribute(FbxNodeAttribute* pAttribute)
	{
		if (pAttribute->GetAttributeType() == FbxNodeAttribute::eMesh)
		{
			FbxMesh* pMesh = (FbxMesh*)pAttribute;

			FbxVector4* IControlPoints = pMesh->GetControlPoints();
			m_vertexCount = pMesh->GetControlPointsCount();
			m_vertexBuffer = new float[m_vertexCount * 4];
			for (int i = 0; i < m_vertexCount * 4; i+=4)
			{
				m_vertexBuffer[i]     = (float)IControlPoints[i / 4].mData[0];
				m_vertexBuffer[i + 1] = (float)IControlPoints[i / 4].mData[1];
				m_vertexBuffer[i + 2] = (float)IControlPoints[i / 4].mData[2];
				m_vertexBuffer[i + 3] = 1.0f;// IControlPoints[i / 4].mData[3];
			}

			int* pIndices = pMesh->GetPolygonVertices();
			m_indexCount = pMesh->GetPolygonVertexCount();
			m_indexBuffer = new uint32[m_indexCount];
			for (int i = 0; i < m_indexCount; ++i)
			{
				m_indexBuffer[i] = pIndices[i];
			}

			FbxLayer* pLayer = pMesh->GetLayer(0);
			if (pLayer != NULL)
			{
				FbxLayerElementNormal* pNormal = pLayer->GetNormals();
				m_normalCount = pNormal->mDirectArray->GetCount();
				m_normalBuffer = new float[m_normalCount * 3];
				for (int i = 0; i < m_normalCount * 3; i+=3)
				{
					m_normalBuffer[i]     = (float)(*pNormal->mDirectArray)[i / 3][0];
					m_normalBuffer[i + 1] = (float)(*pNormal->mDirectArray)[i / 3][1];
					m_normalBuffer[i + 2] = (float)(*pNormal->mDirectArray)[i / 3][2];
					//m_normalBuffer[i + 3] = (*pNormal->mDirectArray)[i / 4][3];
				}

				FbxLayerElementUV* pUV = pLayer->GetUVs();
				if (pUV->GetMappingMode() == FbxLayerElement::eByPolygonVertex)
				{
					if (pUV->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						m_uvCount = pUV->mIndexArray->GetCount();
						m_uvBuffer = new float[m_uvCount * 2];
						for (int i = 0; i < m_uvCount * 2; i+=2)
						{
							m_uvBuffer[i] = (float)(*pUV->mDirectArray)[(*pUV->mIndexArray)[i / 2]][0];
							m_uvBuffer[i + 1] = (float)(*pUV->mDirectArray)[(*pUV->mIndexArray)[i / 2]][1];
						}
					}
					else
					{
						m_uvCount = pUV->mDirectArray->GetCount();
						m_uvBuffer = new float[m_uvCount * 2];
						for (int i = 0; i < m_uvCount * 2; i += 2)
						{
							m_uvBuffer[i] = (float)(*pUV->mDirectArray)[i / 2][0];
							m_uvBuffer[i + 1] = (float)(*pUV->mDirectArray)[i / 2][1];
						}
					}
				}
				else
				{
					if (pUV->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						m_uvCount = pUV->mIndexArray->GetCount();
						m_uvBuffer = new float[m_uvCount * 2];
						for (int i = 0; i < m_uvCount * 2; i+=2)
						{
							m_uvBuffer[i] = (float)(*pUV->mDirectArray)[(*pUV->mIndexArray)[i / 2]][0];
							m_uvBuffer[i + 1] = (float)(*pUV->mDirectArray)[(*pUV->mIndexArray)[i / 2]][1];
						}
					}
					else
					{
						m_uvCount = pUV->mDirectArray->GetCount();
						m_uvBuffer = new float[m_uvCount * 2];
						for (int i = 0; i < m_uvCount * 2; i+=2)
						{
							m_uvBuffer[i] = (float)(*pUV->mDirectArray)[i / 2][0];
							m_uvBuffer[i + 1] = (float)(*pUV->mDirectArray)[i / 2][1];
						}
					}
				}
			}
		}
	}