void LoadVertices(const aiMesh &inMesh, std::vector<Vertex> &convertedVertices, BoundingSphere &inBoundingSphere)
{
	for (unsigned int i = 0; i < inMesh.mNumVertices; ++i)
	{
		Vertex newVertex;

		float vertexLength = inMesh.mVertices[i].Length();
		if (vertexLength > inBoundingSphere.mRadius)
		{
			inBoundingSphere.mRadius = vertexLength;
		}

		newVertex.LoadAiVector3D(newVertex.Pos, inMesh.mVertices[i]);
		if (inMesh.HasNormals())
		{
			newVertex.LoadAiVector3D(newVertex.Normal, inMesh.mNormals[i]);
		}
		if (inMesh.HasTextureCoords(0))
		{
			newVertex.LoadAiVector3D(newVertex.Tex0, inMesh.mTextureCoords[0][i]);
			newVertex.Tex0.y = 1.0 - newVertex.Tex0.y;
		}
		if (inMesh.HasTangentsAndBitangents())
		{
			newVertex.LoadAiVector3D(newVertex.Tangent, inMesh.mTangents[i]);
			//newVertex.Tangent.z = -newVertex.Tangent.z;
			newVertex.LoadAiVector3D(newVertex.Bitangent, inMesh.mBitangents[i]);
		}

		convertedVertices.push_back(newVertex);
	}
}
Example #2
0
void ResourceManager::cpQuadFaces(const aiMesh &aimesh, Mesh3D &mesh)
{
    unsigned count = 0;
    for (unsigned i(0); i < aimesh.mNumFaces; ++i)
    {
        const aiFace &face = aimesh.mFaces[i];
        int vi[4];
        int ti[4];
        for (unsigned j(0); j < 4; ++j)
        {
            aiVector3D p = aimesh.mVertices[face.mIndices[j]];
            aiVector3D n = aimesh.mNormals[face.mIndices[j]];
            aiVector3D t = aimesh.mTextureCoords[0][face.mIndices[j]];

            mesh.vertices_.push_back(Vec3(p.x, p.z, p.y));

            if (aimesh.HasNormals())
                mesh.vertexNormals_.push_back(Vec3(n.x, n.z, n.y));

            mesh.texCoords_.push_back(Vec2(t.x, t.y));
            vi[j] = count;
            ti[j] = count;
            count++;
        }
        mesh.faces_.push_back(TriFace(vi, ti));
    }
}
Example #3
0
    Mesh::Mesh(Model& model, aiMesh& mesh)
        : mModel(model), mMaterial(nullptr), mName(mesh.mName.C_Str()), mVertices(), mNormals(), mTangents(), mBiNormals(), mTextureCoordinates(), mVertexColors(),
		  mFaceCount(0), mIndices()
    {
		mMaterial = mModel.Materials().at(mesh.mMaterialIndex);

        // Vertices
        mVertices.reserve(mesh.mNumVertices);
        for (UINT i = 0; i < mesh.mNumVertices; i++)
        {
            mVertices.push_back(XMFLOAT3(reinterpret_cast<const float*>(&mesh.mVertices[i])));			
        }

        // Normals
        if (mesh.HasNormals())
        {
            mNormals.reserve(mesh.mNumVertices);
            for (UINT i = 0; i < mesh.mNumVertices; i++)
            {
                mNormals.push_back(XMFLOAT3(reinterpret_cast<const float*>(&mesh.mNormals[i])));
            }
        }

        // Tangents and Binormals
        if (mesh.HasTangentsAndBitangents())
        {
            mTangents.reserve(mesh.mNumVertices);
            mBiNormals.reserve(mesh.mNumVertices);
            for (UINT i = 0; i < mesh.mNumVertices; i++)
            {
                mTangents.push_back(XMFLOAT3(reinterpret_cast<const float*>(&mesh.mTangents[i])));
                mBiNormals.push_back(XMFLOAT3(reinterpret_cast<const float*>(&mesh.mBitangents[i])));
            }
        }

        // Texture Coordinates
        UINT uvChannelCount = mesh.GetNumUVChannels();
        for (UINT i = 0; i < uvChannelCount; i++)
        {
            std::vector<XMFLOAT3>* textureCoordinates = new std::vector<XMFLOAT3>();
            textureCoordinates->reserve(mesh.mNumVertices);
            mTextureCoordinates.push_back(textureCoordinates);

            aiVector3D* aiTextureCoordinates = mesh.mTextureCoords[i];
            for (UINT j = 0; j < mesh.mNumVertices; j++)
            {
                textureCoordinates->push_back(XMFLOAT3(reinterpret_cast<const float*>(&aiTextureCoordinates[j])));
            }
        }

        // Vertex Colors
        UINT colorChannelCount = mesh.GetNumColorChannels();
        for (UINT i = 0; i < colorChannelCount; i++)
        {
            std::vector<XMFLOAT4>* vertexColors = new std::vector<XMFLOAT4>();
            vertexColors->reserve(mesh.mNumVertices);
            mVertexColors.push_back(vertexColors);

            aiColor4D* aiVertexColors = mesh.mColors[i];
            for (UINT j = 0; j < mesh.mNumVertices; j++)
            {
                vertexColors->push_back(XMFLOAT4(reinterpret_cast<const float*>(&aiVertexColors[j])));
            }
        }

        // Faces (note: could pre-reserve if we limit primitive types)
        if (mesh.HasFaces())
        {
            mFaceCount = mesh.mNumFaces;
            for (UINT i = 0; i < mFaceCount; i++)
            {
                aiFace* face = &mesh.mFaces[i];
            
                for (UINT j = 0; j < face->mNumIndices; j++)
                {		
                    mIndices.push_back(face->mIndices[j]);
                }
            }
        }
    }
void Material::createVertexBuffer(const aiMesh& aiMesh, VertexBuffer& vertexBuffer) const
{
	assert(aiMesh.HasPositions());
	assert(aiMesh.HasNormals());
	assert(aiMesh.HasTangentsAndBitangents());
	assert(aiMesh.HasTextureCoords(0));

	vertexBuffer.VertexCount = aiMesh.mNumVertices;
	const unsigned int vertexDataSize = vertexBuffer.VertexCount * 3;
	const unsigned int uvDataSize = vertexBuffer.VertexCount * aiMesh.mNumUVComponents[0];
	float* const positionData = new float[vertexDataSize];
	float* const normalData = new float[vertexDataSize];
	float* const tangentData = new float[vertexDataSize];
	float* const bitangentData = new float[vertexDataSize];
	float* const uvData = new float[uvDataSize];

	unsigned int index = 0, uvIndex = 0;
	for (unsigned int i=0; i < aiMesh.mNumVertices; ++i, index += 3, uvIndex += aiMesh.mNumUVComponents[0]) {
		positionData[index] = aiMesh.mVertices[i].x;
		positionData[index + 1] = aiMesh.mVertices[i].y;
		positionData[index + 2] = aiMesh.mVertices[i].z;

		normalData[index] = aiMesh.mNormals[i].x;
		normalData[index + 1] = aiMesh.mNormals[i].y;
		normalData[index + 2] = aiMesh.mNormals[i].z;

		tangentData[index] = aiMesh.mTangents[i].x;
		tangentData[index + 1] = aiMesh.mTangents[i].y;
		tangentData[index + 2] = aiMesh.mTangents[i].z;

		bitangentData[index] = aiMesh.mBitangents[i].x;
		bitangentData[index + 1] = aiMesh.mBitangents[i].y;
		bitangentData[index + 2] = aiMesh.mBitangents[i].z;

		uvData[uvIndex] = aiMesh.mTextureCoords[0][i].x;
		if (aiMesh.mNumUVComponents[0] > 1) {
			uvData[uvIndex + 1] = aiMesh.mTextureCoords[0][i].y;
			if (aiMesh.mNumUVComponents[0] > 2) {
				uvData[uvIndex + 2] = aiMesh.mTextureCoords[0][i].z;
			}
		}
	}

	vertexBuffer.VBOs.resize(5);
	glGenBuffers(5, &vertexBuffer.VBOs[0]);
	GLuint positionVBO = vertexBuffer.VBOs[0];
	glBindBuffer(GL_ARRAY_BUFFER, positionVBO);
	glBufferData(GL_ARRAY_BUFFER, vertexDataSize * sizeof(positionData[0]), positionData, GL_STATIC_DRAW);
	GLuint normalVBO = vertexBuffer.VBOs[1];
	glBindBuffer(GL_ARRAY_BUFFER, normalVBO);
	glBufferData(GL_ARRAY_BUFFER, vertexDataSize * sizeof(normalData[0]), normalData, GL_STATIC_DRAW);
	GLuint tangentVBO = vertexBuffer.VBOs[2];
	glBindBuffer(GL_ARRAY_BUFFER, tangentVBO);
	glBufferData(GL_ARRAY_BUFFER, vertexDataSize * sizeof(tangentData[0]), tangentData, GL_STATIC_DRAW);
	GLuint bitangentVBO = vertexBuffer.VBOs[2];
	glBindBuffer(GL_ARRAY_BUFFER, bitangentVBO);
	glBufferData(GL_ARRAY_BUFFER, vertexDataSize * sizeof(bitangentData[0]), bitangentData, GL_STATIC_DRAW);
	GLuint texCoordVBO = vertexBuffer.VBOs[3];
	glBindBuffer(GL_ARRAY_BUFFER, texCoordVBO);
	glBufferData(GL_ARRAY_BUFFER, uvDataSize * sizeof(uvData[0]), uvData, GL_STATIC_DRAW);

	glGenVertexArrays(1, &vertexBuffer.VAO);
	glBindVertexArray(vertexBuffer.VAO);
	for (unsigned int i=0; i < vertexBuffer.VBOs.size(); ++i) {
		glEnableVertexAttribArray(i);
	}
	glBindBuffer(GL_ARRAY_BUFFER, positionVBO);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);	
	glBindBuffer(GL_ARRAY_BUFFER, texCoordVBO);
	glVertexAttribPointer(1, aiMesh.mNumUVComponents[0], GL_FLOAT, GL_FALSE, 0, nullptr);
	glBindBuffer(GL_ARRAY_BUFFER, normalVBO);
	glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
	glBindBuffer(GL_ARRAY_BUFFER, tangentVBO);
	glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
	glBindBuffer(GL_ARRAY_BUFFER, bitangentVBO);
	glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

	delete[] positionData;
	delete[] normalData;
	delete[] tangentData;
	delete[] bitangentData;
	delete[] uvData;
}
	void bc_mesh_loader::convert_aimesh(game::bc_render_system& p_render_system,
		core::bc_content_loading_context& p_context,
		const aiScene& p_aiscene,
		const aiNode& p_ainode,
		const aiMesh& p_aimesh,
		game::bc_mesh_part_data& p_mesh,
		game::bc_render_state_ptr& p_mesh_render_state)
	{
		auto& l_device = p_render_system.get_device();
		core::bc_vector_movale< game::bc_vertex_pos_tex_nor_tan > l_vertices;
		core::bc_vector_movale< bcBYTE > l_indices;
		graphic::bc_graphic_resource_configure l_resource_configure;
		graphic::bc_buffer_ptr l_vertex_buffer;
		graphic::bc_buffer_ptr l_index_buffer;
		bcSIZE l_index_count = 0;
		graphic::bc_buffer_ptr l_cbuffer;
		game::bc_render_material_description l_material;

		bool l_need_32bit_indices = p_aimesh.mNumFaces * 3 > std::numeric_limits< bcUINT16 >::max();
		bool l_has_texcoord = p_aimesh.HasTextureCoords(0);
		bool l_has_normal = p_aimesh.HasNormals();
		bool l_has_tangent = p_aimesh.HasTangentsAndBitangents();

		l_vertices.reserve(p_aimesh.mNumVertices);
		l_indices.reserve(p_aimesh.mNumFaces * 3 * (l_need_32bit_indices ? static_cast< bcINT >(game::bc_index_type::i32bit) : static_cast< bcINT >(game::bc_index_type::i16bit)));

		for (bcUINT l_vertex = 0; l_vertex < p_aimesh.mNumVertices; ++l_vertex)
		{
			game::bc_vertex_pos_tex_nor_tan l_vertex_layout;
			auto* l_aivertex = &p_aimesh.mVertices[l_vertex];
			auto* l_aitexcoord = l_has_texcoord ? &p_aimesh.mTextureCoords[0][l_vertex] : nullptr;
			auto* l_ainoraml = l_has_normal ? &p_aimesh.mNormals[l_vertex] : nullptr;
			auto* l_aitangent = l_has_tangent ? &p_aimesh.mTangents[l_vertex] : nullptr;

			l_vertex_layout.m_position = core::bc_vector3f(l_aivertex->x, l_aivertex->y, l_aivertex->z);
			l_vertex_layout.m_texcoord = l_aitexcoord ? core::bc_vector2f(l_aitexcoord->x, l_aitexcoord->y) : core::bc_vector2f();
			l_vertex_layout.m_normal = l_ainoraml ? core::bc_vector3f(l_ainoraml->x, l_ainoraml->y, l_ainoraml->z) : core::bc_vector3f();
			l_vertex_layout.m_tangent = l_aitangent ? core::bc_vector3f(l_aitangent->x, l_aitangent->y, l_aitangent->z) : core::bc_vector3f();

			l_vertices.push_back(l_vertex_layout);
		}

		bcUINT16* l_16bit_indices = reinterpret_cast< bcUINT16* >(l_indices.data());
		bcUINT32* l_32bit_indices = reinterpret_cast< bcUINT32* >(l_indices.data());

		for (bcUINT l_face_index = 0; l_face_index < p_aimesh.mNumFaces; ++l_face_index)
		{
			for (bcBYTE l_index = 0; l_index < 3; ++l_index)
			{
				if (l_need_32bit_indices)
				{
					*l_32bit_indices = static_cast< bcUINT32 >(p_aimesh.mFaces[l_face_index].mIndices[l_index]);
					++l_32bit_indices;
				}
				else
				{
					*l_16bit_indices = static_cast< bcUINT16 >(p_aimesh.mFaces[l_face_index].mIndices[l_index]);
					++l_16bit_indices;
				}

				++l_index_count;
			}
		}

		auto l_vertex_buffer_config = l_resource_configure
			.as_resource()
			.as_buffer
			(
				l_vertices.size(),
				sizeof(game::bc_vertex_pos_tex_nor_tan),
				graphic::bc_resource_usage::gpu_r,
				graphic::bc_resource_view_type::none,
				false
			).as_vertex_buffer();
		auto l_index_buffer_config = l_resource_configure
			.as_resource()
			.as_buffer
			(
				l_index_count,
				l_need_32bit_indices ? static_cast< bcUINT32 >(game::bc_index_type::i32bit) : static_cast< bcUINT32 >(game::bc_index_type::i16bit),
				graphic::bc_resource_usage::gpu_r,
				graphic::bc_resource_view_type::none,
				false
			).as_index_buffer();
		auto l_vertex_buffer_data = graphic::bc_subresource_data(l_vertices.data(), 0, 0);
		auto l_index_buffer_data = graphic::bc_subresource_data(l_indices.data(), 0, 0);

		l_vertex_buffer = l_device.create_buffer(l_vertex_buffer_config, &l_vertex_buffer_data);
		l_index_buffer = l_device.create_buffer(l_index_buffer_config, &l_index_buffer_data);

		convert_aimaterial(p_context, *p_aiscene.mMaterials[p_aimesh.mMaterialIndex], l_material);

		auto l_material_name = core::bc_to_exclusive_string(core::bc_path(p_context.m_file->get_path().c_str()).get_filename()) + "." + p_aimesh.mName.C_Str();
		auto l_material_ptr = p_render_system.get_material_manager().store_material
		(
			p_context.get_allocator_alloc_type(),
			l_material_name.c_str(),
			std::move(l_material)
		);

		p_mesh.m_name = p_aimesh.mName.C_Str();
		p_mesh.m_material = std::move(l_material_ptr);
		p_mesh.m_vertices = std::move(l_vertices);
		p_mesh.m_indices = std::move(l_indices);
		p_mesh.m_vertex_buffer = std::move(l_vertex_buffer);
		p_mesh.m_index_buffer = std::move(l_index_buffer);
		p_mesh.m_bound_box = game::bc_extract_bound_box_from_points(physics::bc_bounded_strided_typed_data< core::bc_vector3f >
		(
			&p_mesh.m_vertices[0].m_position,
			sizeof(game::bc_vertex_pos_tex_nor_tan),
			p_mesh.m_vertices.size()
		));
		p_mesh_render_state = p_render_system.create_render_state
		(
			graphic::bc_primitive::trianglelist,
			p_mesh.m_vertex_buffer.get(),
			sizeof(game::bc_vertex_pos_tex_nor_tan),
			0,
			p_mesh.m_index_buffer.get(),
			l_need_32bit_indices ? game::bc_index_type::i32bit : game::bc_index_type::i16bit,
			l_index_count,
			0,
			{
				graphic::bc_resource_view_parameter(0, graphic::bc_shader_type::pixel, p_mesh.m_material->get_diffuse_map_view()),
				graphic::bc_resource_view_parameter(0, graphic::bc_shader_type::pixel, p_mesh.m_material->get_normal_map_view()),
				graphic::bc_resource_view_parameter(0, graphic::bc_shader_type::pixel, p_mesh.m_material->get_specular_map_view()),
			},
			{
				p_render_system.get_per_object_cbuffer(),
				graphic::bc_constant_buffer_parameter(1, graphic::bc_shader_type::pixel, p_mesh.m_material->get_parameters_cbuffer())
			}
		);
	}