Jump to content
  • Advertisement
Sign in to follow this  
Migi0027

DX11 C++ DX11 - Assimp - Mesh not Loading properly...

This topic is 2049 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys!

 

I've recently implemented Assimp with DirectX 11, now when I load a mesh with no submeshes, everything is fine. But when a mesh has submeshes, it pretty much get's a bad result.

 

Here's how I load my mesh using Assimp:

 

Struct FMESH_DATA:

struct FMESH_DATA
{
	Group<Group<MESH_STRUCT>> meshData;
	Group<Group<DWORD>> indices;
	
	Group<CE_ANIMATIONKEY> Keys;

	Group<std::string> textures;
};

 

 

 

A function called GetData of the namespace AssimpIntegration:

FMESH_DATA AssimpIntegration::GetData(string &pFile, bool convLeftHanded, int maxSM)
{
	// Create an instance of the Importer class
	Assimp::Importer importer;
	// And have it read the given file with some example postprocessing
	// Usually - if speed is not the most important aspect for you - you'll 
	// propably to request more postprocessing than we do in this example.

	int cls = 0x0;
	if (convLeftHanded)
		cls = aiProcess_ConvertToLeftHanded;

	const aiScene* scene = importer.ReadFile( pFile, aiProcess_GenNormals | aiProcess_FindInstances | aiProcess_CalcTangentSpace | cls );
  
	// If the import failed, report it
	if (!scene)
	{
		char* error = (char*)importer.GetErrorString();
		CE_ERROR(error, "Assimp Error");
	}

	// Now we can access the file's contents. 
	Group<MESH_STRUCT> Vertices;
	Group<DWORD> indices;

	//////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////PROCESS MESH///////////////////////////////////////////
	//////////////////////////////////////////////////////////////////////////////////////////

	FMESH_DATA data;

	if (scene->HasAnimations())
	{
		aiAnimation *anim = scene->mAnimations[0];

		FOREACH(anim->mChannels[0]->mNumPositionKeys)
		{
			aiVector3D position = anim->mChannels[0]->mPositionKeys.mValue;

			CE_ANIMATIONKEY key;
			key.position = D3DXVECTOR3(position.x, position.y, position.z);

			data.Keys.push_back(key);
		}
	}

	D3DXVECTOR3 norms;
	float tanx, tany, tanz;
	float bitanx, bitany, bitanz;

	FOREACH (scene->mNumMeshes)
	{
		if (i >= maxSM)
			continue;

		aiMesh *mesh = scene->mMeshes;
		Vertices.group.clear();
		indices.group.clear();

		if (mesh->HasPositions())
		{
			for (int v = 0; v != mesh->mNumVertices; v++)
			{
				norms = D3DXVECTOR3(0,0,0);
				if (mesh->HasNormals())
					norms =  D3DXVECTOR3(mesh->mNormals[v].x,mesh->mNormals[v].y,mesh->mNormals[v].z);
				
				tanx = tany = tanz = 0;
				bitanx = bitany = bitanz = 0;

				if (mesh->HasTangentsAndBitangents())
				{
					tanx = mesh->mTangents[v].x; tany = mesh->mTangents[v].y; tanz = mesh->mTangents[v].z;
					bitanx = mesh->mBitangents[v].x; bitany = mesh->mBitangents[v].y; bitanz = mesh->mBitangents[v].z;
				}

				Vertices.push_back(MESH_STRUCT(
					mesh->mVertices[v].x,
					mesh->mVertices[v].y,
					mesh->mVertices[v].z,
					norms,
					0,
					0,
					tanx, // TANGENTS
					tany,
					tanz
				));

				if (mesh->HasTextureCoords(0))
				{
					Vertices.back().U = mesh->mTextureCoords[0][v].x;
					Vertices.back().V = mesh->mTextureCoords[0][v].y;
				}
			}

			for (int f = 0; f != mesh->mNumFaces; f++)
			{
				for (int index = 0; index != mesh->mFaces[f].mNumIndices; index++)
				{
					indices.push_back(mesh->mFaces[f].mIndices[index]);
				}
			}
		}

		data.meshData.push_back(Vertices);
		data.indices.push_back(indices);

		// Set the required textures
		const aiMaterial* pMaterial = scene->mMaterials[mesh->mMaterialIndex];

		if (pMaterial->GetTextureCount(aiTextureType_DIFFUSE) > 0) {
			aiString Path;

			if (pMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &Path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) {
				std::string FullPath = Path.data;

				if (FullPath.find("\\") != string::npos)
					FullPath = FullPath.substr(FullPath.find_last_of("\\")+1, FullPath.length() - (FullPath.length() - FullPath.find_last_of("\\")-1));
				else if (FullPath.find("/") != string::npos)
					FullPath = FullPath.substr(FullPath.find_last_of("//")+1, FullPath.length() - (FullPath.length() - FullPath.find_last_of("//")-1));

				string rFile = pFile;

				if (pFile.find("\\") != string::npos)
					rFile = pFile.substr(0, pFile.find_last_of("\\")+1);
				else
					rFile = pFile.substr(0, pFile.find_last_of("/")+1);

				FullPath = rFile + FullPath;

				data.textures.push_back(FullPath);
			}
		}
	}

	return data;
}

 

 

In my Mesh class:

// Get the buffer from assimp loader
	FMESH_DATA data = AssimpIntegration::GetData(filename, convLeftHanded, maxSM);
	fMeshData = data;

	FOREACH(data.Keys.size())
	{
		fMeshData.Keys.position.x *= scalation.x;
		fMeshData.Keys.position.y *= scalation.y;
		fMeshData.Keys.position.z *= scalation.z;
	}

	assimploadName = filename;

	vector<MESH_STRUCT> combinedVertices;

	for (int i = 0; i != data.meshData.size(); i++)
	{
		if (i != NULL)
			SubMeshes.push_back(SubMesh());

		// Prepare the data
		if (i == NULL) // Not an instance
		{
			Vertices = new MESH_STRUCT[data.meshData.size()];
			Indices = new DWORD[data.indices.size()];

			Vertices = data.meshData.ToArray();
			Indices = data.indices.ToArray();
		}
		else
		{
			SubMeshes.back().Vertices = new MESH_STRUCT[data.meshData.size()];
			SubMeshes.back().Indices = new DWORD[data.indices.size()];

			SubMeshes.back().Vertices = data.meshData.ToArray();
			SubMeshes.back().Indices = data.indices.ToArray();
		}

		//combinedVertices.insert( combinedVertices.end(), data.meshData.group.begin(), data.meshData.group.end() );
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
		D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc;
		D3D11_SUBRESOURCE_DATA vertexData, indexData;

		// Set up the description of the static vertex buffer.
		vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
		vertexBufferDesc.ByteWidth = sizeof(MESH_STRUCT) * data.meshData.size();
		vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
		vertexBufferDesc.CPUAccessFlags = 0;
		vertexBufferDesc.MiscFlags = 0;
		vertexBufferDesc.StructureByteStride = 0;

		// Give the subresource structure a pointer to the vertex data.
		
		if (i == NULL)
			vertexData.pSysMem = Vertices;
		else
			vertexData.pSysMem = SubMeshes[SubMeshes.size()-1].Vertices;

		vertexData.SysMemPitch = 0;
		vertexData.SysMemSlicePitch = 0;

		if (i == NULL) // Not an instance
			dev->CreateBuffer(&vertexBufferDesc, &vertexData, &UMeshVBuffer);
		else
			dev->CreateBuffer(&vertexBufferDesc, &vertexData, &SubMeshes.back().SMVBuffer);

		// Set up the description of the static index buffer.
		indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
		indexBufferDesc.ByteWidth = sizeof(DWORD) * data.indices.size();
		indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
		indexBufferDesc.CPUAccessFlags = 0;
		indexBufferDesc.MiscFlags = 0;
		indexBufferDesc.StructureByteStride = 0;

		// Give the subresource structure a pointer to the index data.
		
		if (i == NULL)
			indexData.pSysMem = Indices;
		else
			indexData.pSysMem = SubMeshes[SubMeshes.size()-1].Indices;

		indexData.SysMemPitch = 0;
		indexData.SysMemSlicePitch = 0;

		if (i == NULL) // Not an instance
			dev->CreateBuffer(&indexBufferDesc, &indexData, &UMeshIBuffer);
		else
			dev->CreateBuffer(&indexBufferDesc, &indexData, &SubMeshes.back().SMIBuffer);
		
		/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		if (i != NULL)
		{
			SubMeshes.back().passes.RecieveShadows = passes.RecieveShadows;
			SubMeshes.back().passes.CastShadows = passes.CastShadows;
			SubMeshes.back().passes.Diffuse = passes.Diffuse;
			SubMeshes.back().passes.Lighting = passes.Lighting;
			SubMeshes.back().passes.doubleSided = passes.doubleSided;
			SubMeshes.back().passes.texture_repeat = passes.texture_repeat;
			SubMeshes.back().passes.Wind = passes.Wind;
			SubMeshes.back().passes.GlobalMaterial.AmbientColor = passes.GlobalMaterial.AmbientColor;
		}
		
		if (i == NULL) {
			IndexCount = data.indices.size();
			VertexCount = data.meshData.size();
	    } else {
			SubMeshes.back().indexCount = data.indices.size();
			SubMeshes.back().vertexCount = data.meshData.size();
		}

		// Animations

		TextureHolder = new TextureObject[data.textures.size()];

		// PrepareTextures if any
		if (TEXTURESTATE)
		{
			if (data.textures.size() == data.meshData.size())
			{
				TextureHolder.CreateTexture(dev, data.textures.c_str());

				if (i == NULL) {
					passes.base = &TextureHolder; 
					passes.Texture = true;}
				else {
					SubMeshes.back().passes.base = &TextureHolder; 
					SubMeshes.back().passes.Texture = true;}
			}
		}
	}

	GenerateBoundingBox(combinedVertices);

 

 

One example of a mesh with submeshes:

 

33tjnrr.png

 

Look at the middle of the well...

 

Now what on earth is going on? blink.png

Share this post


Link to post
Share on other sites
Advertisement

Ok, it seems that I've fixed it.

 

I needed to pass aiProcess_Triangulate as an extra post processing flag to assimp!

 

But thanks for anyone thinking about this! wink.png

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!