Mesh Quality. Is there any way to reduce it?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
MarcusD
Posts: 16
Joined: Sat Nov 27, 2010 12:57 pm
Location: South Yorkshire, UK

Mesh Quality. Is there any way to reduce it?

Post by MarcusD »

Hi everyone,

I'm fairly new to working with Irrlicht, have already got a terrain up and running, camera, lights, models etc.. It's basically a vehicle driving around a terrain atm. I've been trying deperately to increase the FPS as it is very low (~250) and I feel it should be much higher than that as there really is not much happening yet other than a terrain and a vehicle.

A large part of the problem seemed to be revealed to me when I was messing with camera modes, you know, followcam, cockpitcam etc.. When I implemented cockpit cam, I simply placed the camera at the same position as the vehicle facing front, when in this mode, the vehicle itself is not drawn (i set the node to invisible) and the FPS shot up to the 2000 area. Obviously drawing the vehicle is taking a vast amount of time and cpu. I figured that maybe this is because the mesh used to render the vehicle is far too detailed for what I need (the vehicle is only small on the screen and the 3d object file I am using has a lot of vertices) I'm not 100% up on how it all works yet, but, isn't a mesh composed of lots of squares, divided up into 2 right angle triangles? Wouldn't it be possible to reduce the vertices by simply skipping every other one? If it is, it is beyond my ability to do so at this point, I couldn't find anything in the engine or example code to lower the quality of a mesh, so any advice or help would be much appreciated.

Thanks
Marc
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

can show any screenshots? maybe we can know more about your problem. 250fps to me is quite decent/fast. and by the way how many poly your vehicle has?
MarcusD
Posts: 16
Joined: Sat Nov 27, 2010 12:57 pm
Location: South Yorkshire, UK

Post by MarcusD »

Well, for what is actually happening (1 terrain and 1 vehicle object), 250 isn't really that good. I've seen demos of similar things that exceed 2000 on my system. Plus in the finished product there may have to be several vehicles to render in one scene. If rendering just 1 causes a reduction from 2000fps to 250fps then think what 10 vehicles would would do? The whole thing would look like a powerpoint slide show. I'm not sure how to find out the number of polygons yet, but the obj file for the vehicle has 5270 vertices, if that is any use.

I did try this:

Code: Select all

SAnimatedMesh* newQuality(IAnimatedMesh* amesh, s32 qual)
{
	SAnimatedMesh* smesh;
	smesh=new SAnimatedMesh();
	smesh->Type=amesh->getMeshType();
	IMesh* mesh;
	for(s32 i=0; i<amesh->getFrameCount(); i++)
	{
		mesh=amesh->getMesh(i, qual);
		smesh->addMesh(mesh);
	}
	return smesh;
}
But it had no effect, the documentation does say that the quality parameter of getMesh() is usually ignored.
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

This will not work with an OBJ.

1- That command is for an animated mesh and OBJ is for a static mesh.
2- I don't know what format would have LOD (never saw infos about this, but the model would have different LOD models already done inside the mesh, they are NOT generated)

Checked on the API since I did not know IRRlicht could load LOD models:
http://irrlicht.sourceforge.net/docu/cl ... 7b96f3a0ca

For the "LOD" here what it's says:
Level of detail. 0 is the lowest, 255 the highest level of detail. Most meshes will ignore the detail
I saw that you mentionned around 5000+ vertices but that is not the tris count... A command from the video driver could give you the total tris count, but is not accurate because it will give you all the polygons (tris) for the scene but should give you an idea (hidind the terrain should give you an approximate number of tris for the vehicle):
http://irrlicht.sourceforge.net/docu/cl ... db489a57a3

You could try to implement VBO hinting to your mesh. So it would not be sent to the GPU each frame. You would also need to use the "setDirty" command when you move your mesh.

If you plan to have many vehicles, then a good idea would be that you find an artist that would take the current vehicle mesh, and use a technique like baking onto a lower geometry for differents LOD (level of detail).

You would have then to decide to "change" the mesh based on distance, or choose the lower geometry. Having 2-3 LOD would surely suffice if you need a lot of vehicle. (player would have the more details and the other very less)
MarcusD
Posts: 16
Joined: Sat Nov 27, 2010 12:57 pm
Location: South Yorkshire, UK

Post by MarcusD »

Thanks for the replies guys, some useful info there.

I analized the MeshBuffers of the Mesh totaling the IndexCount of each one which yielded a total of 24093. since i assume 3 indices represent a triangle, the mesh has 8031 triangles.

I did further analysis of the mesh buffers and couldn't understand the results. I assumed that every triangle MUST share 2 of its points with another 3 triangles. This doesn't seem to be the case however, some triangles only connected with 2 others, some with just 1, the divide was pretty even. I even detected 3 orphaned trianges and 6 identical triangles in one of the meshbuffers. I'm starting to think the model I am using is poorly designed, which is why I'm having trouble?

This was annoying because I figured that a triangle joined to its 3 neighbors forms a larger triangle, which would have been ideal to reduce the polygon count.

perhaps i made a mistake in my analizing code

Code: Select all

void analize(IAnimatedMesh* amesh)
{
	SMesh* smesh;
	S3DVertex* verts;
	u16* inds;
	s32 tris;
	for(s32 i=0; i<amesh->getFrameCount(); i++)
	{
		tris=0;
		smesh=(SMesh*)amesh->getMesh(i);
		for(s32 j=0; j<smesh->getMeshBufferCount(); j++)
		{
			IMeshBuffer* mb=smesh->getMeshBuffer(j);
			E_VERTEX_TYPE vtype = mb->getVertexType();		
			verts=(S3DVertex*)mb->getVertices();
			inds=mb->getIndices();			
			s32 vCount=mb->getVertexCount();
			s32 iCount=mb->getIndexCount();
			u16* newInds=new u16[iCount];
			s32 m=0;
			for(s32 k=0; k<iCount; k+=3)
			{
				tris++;
				u16 a1=inds[k];
				u16 b1=inds[k+1];
				u16 c1=inds[k+2];
				if(a1==b1 || a1==c1 || b1==c1)
				{
					printf("WTF, 2 points in the triangle are the same making it a line.\r\n");
					continue;
				}
				bool ok=true;
				s32 alikeCount=0;
				for(s32 l=0; l<iCount; l+=3)
				{
					if(l==k) continue;
					u16 a2=inds[l];
					u16 b2=inds[l+1];
					u16 c2=inds[l+2];
					s32 alike=0;
					if(a1==a2 || a1==b2 || a1==c2) alike++;
					if(b1==a2 || b1==b2 || b1==c2) alike++;
					if(c1==a2 || c1==b2 || c1==c2) alike++;
					if(alike>2)
					{
						printf("WTF, Identical Triangle in this meshbuffer\r\n");
						ok=false;
						break;
					}
					if(alike==2)
						alikeCount++;
				}
				if(alikeCount==0 && ok)
				{
					printf("WTF, orphaned triangle in this meshbuffer\r\n");
					continue;
				}
				if(alikeCount!=3)
				{
					printf("WTF, The triangle does not connect to 3 others, it connects to %d\r\n",alikeCount);
					continue;
				}
				if(ok)
				{
					newInds[m++]=a1;
					newInds[m++]=b1;
					newInds[m++]=c1;
				}
			}
			switch(vtype)
			{
				case EVT_STANDARD: default:
				{
					CMeshBuffer<S3DVertex>* cmb=new CMeshBuffer<S3DVertex>();
					cmb->append(verts,vCount,newInds,m);
					smesh->MeshBuffers[j]=cmb;
					break;
				}
				case EVT_2TCOORDS:
				{
					CMeshBuffer<S3DVertex2TCoords>* cmb=new CMeshBuffer<S3DVertex2TCoords>();
					cmb->append(verts,vCount,newInds,m);
					smesh->MeshBuffers[j]=cmb;
					break;
				}
				case EVT_TANGENTS:
				{
					CMeshBuffer<S3DVertexTangents>* cmb=new CMeshBuffer<S3DVertexTangents>();
					cmb->append(verts,vCount,newInds,m);
					smesh->MeshBuffers[j]=cmb;
					break;
				}
			}
		}
		printf("Total Triangles=%d in frame %d\r\n",tris,i);
	}
}
Post Reply