コード例 #1
0
	StaticModel * ModelLoader::LoadModel(VulkanBase* vulkanBase, std::string filename)
	{
		// Check if the model already is loaded
		if (mModelMap.find(filename) != mModelMap.end())
			return mModelMap[filename];

		StaticModel* model = nullptr;
		Assimp::Importer importer;

		// Load scene from the file.
		const aiScene* scene = importer.ReadFile(filename, aiProcess_FlipWindingOrder | aiProcess_Triangulate | aiProcess_PreTransformVertices | aiProcess_CalcTangentSpace | aiProcess_GenSmoothNormals | aiProcess_JoinIdenticalVertices);

		if (scene != nullptr)
		{
			model = new StaticModel;

			// Loop over all meshes
			for (int meshId = 0; meshId < scene->mNumMeshes; meshId++)
			{
				aiMesh* assimpMesh = scene->mMeshes[meshId];

				// Get the diffuse color
				aiColor3D color(0.f, 0.f, 0.f);
				scene->mMaterials[assimpMesh->mMaterialIndex]->Get(AI_MATKEY_COLOR_DIFFUSE, color);

				Mesh mesh;

				// Load vertices
				for (int vertexId = 0; vertexId < assimpMesh->mNumVertices; vertexId++)
				{
					aiVector3D v = assimpMesh->mVertices[vertexId];
					aiVector3D n = assimpMesh->mNormals[vertexId];
					aiVector3D t = aiVector3D(0, 0, 0);

					if (assimpMesh->HasTextureCoords(0))
						t = assimpMesh->mTextureCoords[0][vertexId];

					n = n.Normalize();
					Vertex vertex(v.x, v.y, v.z, n.x, n.y, n.z, 0, 0, 0, t.x, t.y, color.r, color.g, color.b);

					mesh.vertices.push_back(vertex);
				}

				// Load indices
				for (int faceId = 0; faceId < assimpMesh->mNumFaces; faceId++)
				{
					for (int indexId = 0; indexId < assimpMesh->mFaces[faceId].mNumIndices; indexId++)
						mesh.indices.push_back(assimpMesh->mFaces[faceId].mIndices[indexId]);
				}

				model->AddMesh(mesh);
			}

			// Add the model to the model map
			model->BuildBuffers(vulkanBase);		// Build the models buffers here
			mModelMap[filename] = model;
		}
		else {
			// Loading of model failed
			assert(scene);
		}

		return model;
	}
コード例 #2
0
ファイル: ModelImporter.cpp プロジェクト: simplerr/Devbox
//! Loads and returns a static model from a file.
StaticModel* ModelImporter::LoadStaticModel(string filename)
{
	// Is the model already loaded?
	if(mStaticModelMap.find(filename) != mStaticModelMap.end())
		return mStaticModelMap[filename];

	Assimp::Importer importer;
	mFilename =	filename;
	StaticModel* model = NULL;

	// Important! Makes sure that if the angle between two face normals is > 80 they are not smoothed together.
	// Since the angle between a cubes face normals is 90 the lighting looks very bad if we don't specify this.
	importer.SetPropertyFloat(AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE, 80.0f);	
	importer.SetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS, 1);
	importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE);

	// Load scene from the file.
	const aiScene* scene = importer.ReadFile(filename, 
		aiProcess_CalcTangentSpace		| 
		aiProcess_Triangulate			| 
		aiProcess_GenSmoothNormals		|
		aiProcess_SplitLargeMeshes		|
		aiProcess_ConvertToLeftHanded	|
		aiProcess_SortByPType);

	// Successfully loaded the scene.
	if(scene)
	{
		// Create the model that is getting filled out.
		model = new StaticModel();

		// Loop through all meshes.
		for(int i = 0; i < scene->mNumMeshes; i++)
		{
			aiMesh* assimpMesh = scene->mMeshes[i];
			vector<Vertex>	vertices;
			vector<UINT>	indices;

			// Add vertices to the vertex list.
			for(int i = 0; i < assimpMesh->mNumVertices; i++) 
			{
				aiVector3D v = assimpMesh->mVertices[i];
				aiVector3D n = assimpMesh->mNormals[i];
				aiVector3D t = aiVector3D(0, 0, 0);
				if(assimpMesh->HasTextureCoords(0))
					t = assimpMesh->mTextureCoords[0][i];

				n = n.Normalize();
				Vertex vertex(v.x, v.y, v.z, n.x, n.y, n.z, 0, 0, 0, t.x, t.y);
				vertices.push_back(vertex);
			}

			// Add indices to the index list.
			for(int i = 0; i < assimpMesh->mNumFaces; i++) 
				for(int j = 0; j < assimpMesh->mFaces[i].mNumIndices; j++) 
					indices.push_back(assimpMesh->mFaces[i].mIndices[j]);

			// Get the path to the texture in the directory.
			aiString path;
			aiMaterial* material = scene->mMaterials[assimpMesh->mMaterialIndex];
			material->Get(AI_MATKEY_TEXTURE_DIFFUSE(0), path);
			FindValidPath(&path);

			// Extract all the ambient, diffuse and specular colors.
			aiColor4D ambient, diffuse, specular;
			material->Get(AI_MATKEY_COLOR_AMBIENT, ambient);
			material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse);
			material->Get(AI_MATKEY_COLOR_SPECULAR, specular);

			// Create the mesh and its primitive.
			StaticMesh* mesh = new StaticMesh();
			Primitive* primitive = new Primitive(GlobalApp::GetD3DDevice(), vertices, indices);
			mesh->SetPrimitive(primitive);
			mesh->SetVertices(vertices);
			mesh->SetIndices(indices);
			mPrimtiveFactory->AddPrimitive(path.C_Str(), primitive);

			// Any texture?
			if(_stricmp(path.C_Str(), "") != 0)
				mesh->LoadTexture(path.C_Str());

			// Any normal map?
			aiString nmap;
			material->Get(AI_MATKEY_TEXTURE_HEIGHT(0), nmap);
			FindValidPath(&nmap);
			if(_stricmp(nmap.C_Str(), "") != 0)	
				mesh->SetNormalMap(GlobalApp::GetGraphics()->LoadTexture(nmap.C_Str()));

			// [NOTE] The material is set to white.
			mesh->SetMaterial(Material(Colors::White)); // Was  before [NOTE]

			model->SetFilename(filename);

			// Add the mesh to the model.
			model->AddMesh(mesh);
		}

		// Add to the model map and return it.
		mStaticModelMap[filename] = model;
		return mStaticModelMap[filename];
	}
	else {
		char buffer[246];
		sprintf(buffer, "Error loading model: %s", filename.c_str());
		MessageBox(0, buffer, "Error!", 0);
		mStaticModelMap[filename] = LoadStaticModel("models/box.obj");
		return mStaticModelMap[filename];
	}
}
コード例 #3
0
	StaticModel* ModelLoader::GenerateTerrain(VulkanBase* vulkanBase, std::string filename)
	{
		// Check if the model already is loaded
		if (mModelMap.find(filename) != mModelMap.end())
			return mModelMap[filename];

		// Load the terrain froma .tga file
		TextureData texture;
		LoadTGATextureData((char*)filename.c_str(), &texture);

		StaticModel* terrain = new StaticModel;
		Mesh mesh;

		int vertexCount = texture.width * texture.height;
		int triangleCount = (texture.width - 1) * (texture.height - 1) * 2;
		int x, z;

		mesh.vertices.resize(vertexCount);
		mesh.indices.resize(triangleCount * 3);

		printf("bpp %d\n", texture.bpp);
		for (x = 0; x < texture.width; x++)
			for (z = 0; z < texture.height; z++)
			{
				// Vertex array. You need to scale this properly
				float height = texture.imageData[(x + z * texture.width) * (texture.bpp / 8)] / 15.0f;

				vec3 pos = vec3(x / 1.0, height, z / 1.0);
				vec3 normal = vec3(0, 0, 0);
				vec2 uv = vec2(x / (float)texture.width, z / (float)texture.height);

				Vertex vertex = Vertex(pos, normal, uv, vec3(0, 0, 0), vec3(1.0, 1.0, 1.0));
				mesh.vertices[x + z * texture.width] = vertex;
			}

		// Normal vectors. You need to calculate these.
		for (x = 0; x < texture.width; x++)
		{
			for (z = 0; z < texture.height; z++)
			{
				vec3 p1, p2, p3;
				vec3 edge = { 0.0f, 0.0f, 0.0f };
				int i1;

				// p1 [x-1][z-1]
				if (x < 1 && z < 1)
					i1 = (x + 1 + (z + 1) * texture.width);
				else
					i1 = (x - 1 + (z - 1) * texture.width);

				// TODO: NOTE: HAX
				if (i1 < 0)
					i1 = 0;

				p1 = mesh.vertices[i1].Pos;

				// p1 [x-1][z] (if on the edge use [x+1] instead of [x-1])
				int i2;
				if (x < 1)
					i2 = (x + 1 + (z)* texture.width);
				else
					i2 = (x - 1 + (z)* texture.width);

				p2 = mesh.vertices[i2].Pos;

				// p1 [x][z-1]
				int i3;
				if (z < 1)
					i3 = (x + (z + 1) * texture.width);
				else
					i3 = (x + (z - 1) * texture.width);

				p3 = mesh.vertices[i3].Pos;

				vec3 e1 = p2 - p1;
				vec3 e2 = p3 - p1;
				vec3 normal = glm::cross(e2, e1);

				if (normal != vec3(0, 0, 0))
					int asda = 1;

				normal = glm::normalize(normal);

				//i = (x + 1 + (z + 1) * texture.width);
				mesh.vertices[i1].Normal += normal;
				mesh.vertices[i2].Normal += normal;
				mesh.vertices[i3].Normal += normal;

				// NOTE: Testing
				//mesh.vertices[i].Normal = vec3(0, 0, 0);
			}
		}

		for (x = 0; x < texture.width - 1; x++)
		{
			for (z = 0; z < texture.height - 1; z++)
			{
				// Triangle 1
				mesh.indices[(x + z * (texture.width - 1)) * 6 + 0] = x + z * texture.width;
				mesh.indices[(x + z * (texture.width - 1)) * 6 + 1] = x + (z + 1) * texture.width;
				mesh.indices[(x + z * (texture.width - 1)) * 6 + 2] = x + 1 + z * texture.width;
				// Triangle 2
				mesh.indices[(x + z * (texture.width - 1)) * 6 + 3] = x + 1 + z * texture.width;
				mesh.indices[(x + z * (texture.width - 1)) * 6 + 4] = x + (z + 1) * texture.width;
				mesh.indices[(x + z * (texture.width - 1)) * 6 + 5] = x + 1 + (z + 1) * texture.width;
			}
		}

		// Now loop through each vertex vector, and average out all the normals stored.
		for (int i = 0; i < mesh.vertices.size(); ++i)
		{
			mesh.vertices[i].Normal = glm::normalize(mesh.vertices[i].Normal);
		}

		terrain->AddMesh(mesh);
		terrain->BuildBuffers(vulkanBase);

		// Add to the map
		mModelMap[filename] = terrain;

		return terrain;
	}