コード例 #1
0
ファイル: MeshModel.cpp プロジェクト: hongyunL/OpenGL
/* 首先,已知顶点位置坐标v0 v1 v2 v3…和法向量n0 n1 n2 n3…。
* (上述vi 和 ni都是数组,长度为3,表示一个三维向量)
* 因此,指定3个序号,比如0,1,2代表v0v1v2即可指定一个三角形3个顶点的位置;
* 又指定3个序号,比如0,2,4代表n0n2n4即可指定一个三角形3个顶点的法向量。
* 把刚才指定的序号结合在一起,即0,1,2,0,2,4,即可描述一个三角形面的位置和方向 
*/
void MeshModel::LoadMeshDataFrom3DE(
	unsigned vertexNum,
	int face_indicies[][6], unsigned faceIndiciesLength,
	float vertices[][3], unsigned verticesLength,
	float normals[][3], unsigned normalsLength,
	float colorR, float colorG, float colorB)
{
	std::vector<float> vecVertex;
	std::vector<float> vecNormal;
	std::vector<float> vecColor;

	for (unsigned i = 0; i<faceIndiciesLength / sizeof(face_indicies[0]); i++)
	{
		for (unsigned j = 0; j<3; j++)
		{
			int vi = face_indicies[i][j];
			int ni = face_indicies[i][j + 3];//Normal index
			vecVertex.push_back(vertices[vi][0]);
			vecVertex.push_back(vertices[vi][1]);
			vecVertex.push_back(vertices[vi][2]);
			vecNormal.push_back(normals[ni][0]);
			vecNormal.push_back(normals[ni][1]);
			vecNormal.push_back(normals[ni][2]);
			vecColor.push_back(colorR);
			vecColor.push_back(colorG);
			vecColor.push_back(colorB);
		}
	}

	LoadColor(vecColor.data(), vecColor.size()*sizeof(float), GL_FLOAT, 3);
	LoadVertex(vecVertex.data(), vecVertex.size()*sizeof(float), GL_FLOAT, 3);
	LoadNormal(vecNormal.data(), vecNormal.size()*sizeof(float), GL_FLOAT);
}
コード例 #2
0
ファイル: MeshModel.cpp プロジェクト: hongyunL/OpenGL
void MeshModel::LoadMeshDataWithTexFrom3DE(
	unsigned vertexNum,
	int face_indicies[][9], unsigned faceIndiciesLength,
	float vertices[][3], unsigned verticesLength,
	float normals[][3], unsigned normalsLength,
	std::string fileName,
	float textures[][2], unsigned texturesLength)
{
	std::vector<float> vecVertex;
	std::vector<float> vecNormal;
	std::vector<float> vecTexture;

	for (unsigned i = 0; i<faceIndiciesLength / sizeof(face_indicies[0]); i++)
	{
		for (unsigned j = 0; j<3; j++)
		{
			int vi = face_indicies[i][j];     //顶点坐标的序号
			int ni = face_indicies[i][j + 3]; //法向量的序号
			int ti = face_indicies[i][j + 6]; //纹理坐标的序号
			vecVertex.push_back(vertices[vi][0]);
			vecVertex.push_back(vertices[vi][1]);
			vecVertex.push_back(vertices[vi][2]);
			vecNormal.push_back(normals[ni][0]);
			vecNormal.push_back(normals[ni][1]);
			vecNormal.push_back(normals[ni][2]);
			vecTexture.push_back(textures[ti][0]);
			vecTexture.push_back(textures[ti][1]);
		}
	}

	LoadVertex(vecVertex.data(), vecVertex.size()*sizeof(float), GL_FLOAT, 3);
	LoadNormal(vecNormal.data(), vecNormal.size()*sizeof(float), GL_FLOAT);
	LoadTexture(fileName, vecTexture.data(), vecTexture.size()*sizeof(float), GL_FLOAT, 2);
}
コード例 #3
0
	std::shared_ptr<Mesh> FBXConverter::LoadMesh(FbxMesh* fbxMesh)
	{
		assert(fbxMesh->GetLayerCount() > 0);

		auto node = fbxMesh->GetNode();
		auto layer = fbxMesh->GetLayer(0);

		if (layer->GetNormals() == nullptr)
		{
			fbxMesh->GenerateNormals(true);
		}

		auto uvs = layer->GetUVs();
		auto vcolors = layer->GetVertexColors();
		auto normals = layer->GetNormals();
		auto binormals = layer->GetBinormals();
		auto materials = layer->GetMaterials();

		auto controlPoints = fbxMesh->GetControlPoints();
		auto controlPointsCount = fbxMesh->GetControlPointsCount();

		auto polygonCount = fbxMesh->GetPolygonCount();

		std::vector<FbxFace> faces;

		// Load weights
		std::vector<BoneConnector> bcs_temp;
		std::vector<Vertex> vs_temp;
		LoadSkin(fbxMesh, bcs_temp, vs_temp);

		// generate face vertex
		int32_t vertexID = 0;
		for (int32_t polygonIndex = 0; polygonIndex < polygonCount; polygonIndex++)
		{
			int polygonPointCount = fbxMesh->GetPolygonSize(polygonIndex);

			FbxFace face;

			for (int32_t polygonPointIndex = 0; polygonPointIndex < polygonPointCount; polygonPointIndex++)
			{
				auto ctrlPointIndex = fbxMesh->GetPolygonVertex(polygonIndex, polygonPointIndex);

				Vertex v;

				v.Position = LoadPosition(fbxMesh, ctrlPointIndex);
				
				v.Weights = vs_temp[ctrlPointIndex].Weights;

				if (normals != nullptr)
				{
					v.Normal = LoadNormal(normals, vertexID, ctrlPointIndex);
				}
		
				if (uvs != nullptr)
				{
					v.UV = LoadUV(fbxMesh, uvs, vertexID, ctrlPointIndex, polygonIndex, polygonPointIndex);
				}
				else
				{
					// Auto generated
					v.UV[0] = v.Position[0] + v.Position[2];
					v.UV[1] = v.Position[1];
				}

				if (vcolors != nullptr)
				{
					v.VertexColor = LoadVertexColor(fbxMesh, vcolors, vertexID, ctrlPointIndex, polygonIndex, polygonPointIndex);
				}

				face.Vertecies.push_back(v);
				vertexID++;
			}

			faces.push_back(face);
		}



		// 面の表裏入れ替え
		for (auto& face : faces)
		{
			std::reverse(face.Vertecies.begin(), face.Vertecies.end());
		}

		// メッシュで使用可能な形式に変換
	
		// 頂点変換テーブル作成
		int32_t vInd = 0;
		std::map<Vertex, int32_t> v2ind;
		std::map<int32_t, Vertex> ind2v;

		for (auto& face : faces)
		{
			for (int32_t vi = 0; vi < (int32_t)face.Vertecies.size(); vi++)
			{
				auto vertex = face.Vertecies[vi];

				auto it = v2ind.find(vertex);
				if (it == v2ind.end())
				{
					v2ind[vertex] = vInd;
					ind2v[vInd] = vertex;
					vInd++;
				}
			}
		}

		// 設定
		auto mesh = std::make_shared<Mesh>();
		mesh->Name = node->GetName();
		mesh->BoneConnectors = bcs_temp;

		mesh->Vertexes.resize(vInd);
		for (auto& iv : ind2v)
		{
			mesh->Vertexes[iv.first] = iv.second;
		}

		for (auto& face : faces)
		{
			if (face.Vertecies.size() < 3) continue;

			if (face.Vertecies.size() == 3)
			{
				Face f;
				f.Index[0] = v2ind[face.Vertecies[0]];
				f.Index[1] = v2ind[face.Vertecies[1]];
				f.Index[2] = v2ind[face.Vertecies[2]];
				mesh->Faces.push_back(f);
			}
			
			if (face.Vertecies.size() == 4)
			{
				Face f0;
				f0.Index[0] = v2ind[face.Vertecies[0]];
				f0.Index[1] = v2ind[face.Vertecies[1]];
				f0.Index[2] = v2ind[face.Vertecies[2]];
				mesh->Faces.push_back(f0);

				Face f1;
				f1.Index[0] = v2ind[face.Vertecies[0]];
				f1.Index[1] = v2ind[face.Vertecies[2]];
				f1.Index[2] = v2ind[face.Vertecies[3]];
				mesh->Faces.push_back(f1);
			}
		}

		// Binormal,Tangent計算
		std::map<int32_t, VertexNormals> vInd2Normals;

		for (const auto& face : mesh->Faces)
		{
			FbxVector4 binormal, tangent;
			CalcTangentSpace(
				mesh->Vertexes[face.Index[0]],
				mesh->Vertexes[face.Index[1]],
				mesh->Vertexes[face.Index[2]],
				binormal,
				tangent);

			for (auto i = 0; i < 3; i++)
			{
				vInd2Normals[face.Index[i]].Binormal += binormal;
				vInd2Normals[face.Index[i]].Tangent += tangent;
				vInd2Normals[face.Index[i]].Count += 1;
			}
		}

		for (auto& vn : vInd2Normals)
		{
			vn.second.Binormal /= vn.second.Count;
			vn.second.Tangent /= vn.second.Count;
		}

		for (auto& vn : vInd2Normals)
		{
			mesh->Vertexes[vn.first].Binormal = vn.second.Binormal;
			mesh->Vertexes[vn.first].Tangent = vn.second.Tangent;

			// 適当な値を代入する
			if (mesh->Vertexes[vn.first].Binormal.Length() == 0.0f)
			{
				if (mesh->Vertexes[vn.first].Normal != FbxVector4(1, 0, 0))
				{
					mesh->Vertexes[vn.first].Binormal = FbxVector4(1, 0, 0);
					mesh->Vertexes[vn.first].Tangent = FbxVector4(0, 1, 0);
				}
				else
				{
					mesh->Vertexes[vn.first].Binormal = FbxVector4(0, 1, 0);
					mesh->Vertexes[vn.first].Tangent = FbxVector4(1, 0, 0);
				}
			}
		}

		return mesh;
	}