Пример #1
0
// 指定されているメッシュに含まれる三角形を取得.
IZ_UINT AssimpImporter::GetTriangles(std::vector<STri>& tvTriList)
{
    IZ_ASSERT(m_curMeshIdx < m_scene->mNumMeshes);

    auto mesh = m_scene->mMeshes[m_curMeshIdx];
    IZ_ASSERT(mesh->HasFaces());

    tvTriList.reserve(mesh->mNumFaces);

    for (IZ_UINT i = 0; i < mesh->mNumFaces; i++) {
        const auto& face = mesh->mFaces[i];

        // Check if this is a triangle.
        IZ_ASSERT(face.mNumIndices == 3);

        // NOTE
        // 全頂点を通じた一意のインデックスを指定する.

        STri tri;
        tri.vtx[0] = face.mIndices[0] + m_VtxPos;
        tri.vtx[1] = face.mIndices[1] + m_VtxPos;
        tri.vtx[2] = face.mIndices[2] + m_VtxPos;

        tvTriList.push_back(tri);
    }

    // NOTE
    // 三角形を構成する頂点に影響を与える(スキニングする)関節インデックスについては外部で処理するので、ここでは何もしない.

    m_VtxPos += mesh->mNumVertices;

    IZ_UINT ret = mesh->mNumVertices;
    
    return ret;
}
Пример #2
0
MeshPtr AssimpMeshIO::load(const std::string &mesh_name, const std::string &file_name, unsigned int mesh_index, const BufferManagerPtr &buffer_manager, const VaoManagerPtr &vao_manager)
{
	auto scene = importer->ReadFile(file_name, aiProcessPreset_TargetRealtime_MaxQuality | aiProcess_ConvertToLeftHanded);

	if (scene == nullptr)
	{
		throw clan::Exception(clan::string_format("Unable to locate (%1) for (%2)", file_name, mesh_name));
	}

	if (scene->mNumMeshes <= mesh_index)
		throw clan::Exception(clan::string_format("The mesh index (%1) was out of bounds for mesh %2.", mesh_index, mesh_name));

	auto scene_mesh = scene->mMeshes[mesh_index];

	unsigned int stride = 0;
	std::vector<Core::VertexAttribute> interleaved_spec;
	Core::VaoLayout vao_layout;
	Core::RenderCommand render_command;

	// vectors to store bounds position and size in.
	glm::vec3 mesh_bounds_pos = glm::vec3(0);
	glm::vec3 mesh_bounds_size = glm::vec3(0);

	if (scene_mesh->HasPositions() && scene_mesh->mNumVertices > 0)
	{
		mesh_bounds_pos = glm::vec3(scene_mesh->mVertices[0].x, scene_mesh->mVertices[0].y, scene_mesh->mVertices[0].z);
		mesh_bounds_size = mesh_bounds_pos;
	}

	//
	// Set up vertices
	//

	// Set up the interleaved vertex attributes
	if (scene_mesh->HasPositions())
	{
		stride += sizeof(glm::vec3);
		interleaved_spec.push_back(Core::VaoArg<glm::vec3>(Core::ShaderConstants::Position));
	}

	if (scene_mesh->HasNormals())
	{
		stride += sizeof(glm::vec3);
		interleaved_spec.push_back(Core::VaoArg<glm::vec3>(Core::ShaderConstants::Normal));
	}

	if (scene_mesh->HasTextureCoords(0))
	{
		stride += sizeof(glm::vec2);
		interleaved_spec.push_back(Core::VaoArg<glm::vec2>(Core::ShaderConstants::TexCoord));
	}

	if (scene_mesh->HasTangentsAndBitangents())
	{
		stride += 2*sizeof(glm::vec3);
		interleaved_spec.push_back(Core::VaoArg<glm::vec3>(Core::ShaderConstants::Tangent));
		interleaved_spec.push_back(Core::VaoArg<glm::vec3>(Core::ShaderConstants::Bitangent));
	}

	std::vector<float> vertices;
	vertices.reserve(scene_mesh->mNumVertices * stride / sizeof(float)); // This is how many floats we have

	for (unsigned int i = 0; i < scene_mesh->mNumVertices; i++) {
		// This may be made into a lambda for BuffeOperations::unsafe_upload
		if (scene_mesh->HasPositions())
		{
			auto position = scene_mesh->mVertices[i];
			vertices.push_back(position.x);
			vertices.push_back(position.y);
			vertices.push_back(position.z);

			// check for new min-max component in vertex, and update bounds.
			check_if_new_min_or_max_vertex(glm::vec3(position.x, position.y, position.z),
			                               mesh_bounds_pos, mesh_bounds_size);
		}

		if (scene_mesh->HasNormals())
		{
			auto normal = scene_mesh->mNormals[i];
			vertices.push_back(normal.x);
			vertices.push_back(normal.y);
			vertices.push_back(normal.z);
		}

		if (scene_mesh->HasTextureCoords(0))
		{
			auto texcoord = scene_mesh->mTextureCoords[0][i];
			vertices.push_back(texcoord.x);
			vertices.push_back(texcoord.y);
		}

		if (scene_mesh->HasTangentsAndBitangents())
		{
			auto tangent = scene_mesh->mTangents[i];
			vertices.push_back(tangent.x);
			vertices.push_back(tangent.y);
			vertices.push_back(tangent.z);

			auto bitangent = scene_mesh->mBitangents[i];
			vertices.push_back(bitangent.x);
			vertices.push_back(bitangent.y);
			vertices.push_back(bitangent.z);
		}
	}

	auto vertex_allocation = buffer_manager->allocate(vertices.size()*stride, stride);
	vertex_allocation.upload(vertices);

	vao_layout
		.for_buffer(vertex_allocation)
			.use_as(GL_ARRAY_BUFFER)
				.bind_interleaved(0, 0, interleaved_spec);
	
	render_command.set_draw_mode(GL_TRIANGLES);
	render_command.set_vertices(vertex_allocation, scene_mesh->mNumVertices, stride);

	//
	// Set up indices
	//

	if (scene_mesh->HasFaces()) {
		std::vector<unsigned int> indices;

		for (unsigned int i = 0; i < scene_mesh->mNumFaces; i++) {
			auto face = scene_mesh->mFaces[i];
			for (unsigned int j = 0; j < face.mNumIndices; j++) {
				indices.push_back(face.mIndices[j]);
			}
		}

		auto index_allocation = buffer_manager->allocate_and_upload(indices);

		vao_layout
			.for_buffer(index_allocation)
				.use_as(GL_ELEMENT_ARRAY_BUFFER);

		render_command.set_indices(index_allocation, indices);
	}

	// Ensure that mesh_bounds_size is the distance from mesh_bounds_pos to upper-right-back-corner of the bounds
	mesh_bounds_size = glm::vec3(
	                             mesh_bounds_size.x - mesh_bounds_pos.x,
	                             mesh_bounds_size.y - mesh_bounds_pos.y,
	                             mesh_bounds_size.z - mesh_bounds_pos.z
	                            );

	return std::make_shared<Mesh>(render_command, vao_layout, vao_manager, mesh_name, mesh_bounds_pos, mesh_bounds_size);
}