Sign in to follow this  
Migi0027

Getting maximum and minimum vertex position

Recommended Posts

Now this may sound really simple, but somehow it's been bugging me for now, here's the code (explanation at the end):

 

void UMesh::GenerateBoundingBox(vector<MESH_STRUCT> &vertices)
{
	float maxx = 0, maxy = 0, maxz = 0;
	float minx = 0, miny = 0, minz = 0;

	FOREACH(vertices.size())
	{
		if (maxx < vertices[i].X || i == 0)
			maxx = vertices[i].X;

		if (maxy < vertices[i].Y || i == 0)
			maxy = vertices[i].Y;

		if (maxz < vertices[i].Z || i == 0)
			maxz = vertices[i].Z;

		if (minx > vertices[i].X || i == 0)
			minx = vertices[i].X;

		if (miny > vertices[i].Y || i == 0)
			miny = vertices[i].Y;

		if (minz > vertices[i].Z || i == 0)
			minz = vertices[i].Z;
	}

	// Set params
	BoundingBox.omx = BoundingBox.maxx = maxx;
	BoundingBox.omy = BoundingBox.maxy = maxy;
	BoundingBox.omz = BoundingBox.maxz = maxz;
	BoundingBox.ommx = BoundingBox.minx = minx;
	BoundingBox.ommy = BoundingBox.miny = miny;
	BoundingBox.ommz = BoundingBox.minz = minz;

	AdaptBoundingBox();
}

void UMesh::AdaptBoundingBox()
{
	BoundingBox.maxx = BoundingBox.omx;
	BoundingBox.maxy = BoundingBox.omy;
	BoundingBox.maxz = BoundingBox.omz;
	BoundingBox.minx = BoundingBox.ommx;
	BoundingBox.miny = BoundingBox.ommy;
	BoundingBox.minz = BoundingBox.ommz;

	// Apply Scaling
	BoundingBox.maxx *= scalation.x;
	BoundingBox.maxy *= scalation.y;
	BoundingBox.maxz *= scalation.z;
	BoundingBox.minx *= scalation.x;
	BoundingBox.miny *= scalation.y;
	BoundingBox.minz *= scalation.z;

	// Calculate size
	BoundingBox.sizex = BoundingBox.maxx - BoundingBox.minx;
	BoundingBox.sizey = BoundingBox.maxy - BoundingBox.miny;
	BoundingBox.sizez = BoundingBox.maxz - BoundingBox.minz;
}

 

UMesh is just a class. The GenerateBoundingBox gets all the vertices and then tries to get the max xyz, and the min xyz out of it. The BoundingBox.omx or .ommx is just backups for later use, omx = origional max x, ommx = origional minimum x (but it doesn't matter). From my results (i have a tree), the values are actually bigger than the mesh itself. The tree actually has submeshes so what I do is that I combine all the vertices into one vector. The AdaptBoundingBox is also used when scaling as the bounding box also then has to change when the mesh is scaled.

 

Now what on earth did I do wrong? biggrin.png

Share this post


Link to post
Share on other sites

You should first initialze min with some maximum float point value and max with minimum. and then do comparison in loop.

 

//float maxx = 0, maxy = 0, maxz = 0;
//float minx = 0, miny = 0, minz = 0;
float maxx = FLT_MIN, maxy = FLT_MIN, maxz = FLT_MIN;
float minx = FLT_MAX, miny = FLT_MAX, minz = FLT_MAX;
Edited by belfegor

Share this post


Link to post
Share on other sites

Well I changed it, but nothing really happened, same results:

 

float maxx = FLT_MIN, maxy = FLT_MIN, maxz = FLT_MIN;
	float minx = FLT_MAX, miny = FLT_MAX, minz = FLT_MAX;

	FOREACH(vertices.size())
	{
		if (maxx < vertices[i].X)
			maxx = vertices[i].X;

		if (maxy < vertices[i].Y)
			maxy = vertices[i].Y;

		if (maxz < vertices[i].Z)
			maxz = vertices[i].Z;

		if (minx > vertices[i].X)
			minx = vertices[i].X;

		if (miny > vertices[i].Y)
			miny = vertices[i].Y;

		if (minz > vertices[i].Z)
			minz = vertices[i].Z;
	}

Share this post


Link to post
Share on other sites

Wait a minute...

 

	FOREACH(vertices.size())

are you sure this is a working loop? Seems like a stupid question, but all you are passing is the size of the vertices, but I couldn't find any reference to this, is this some sort of compiler macro or something?

Share this post


Link to post
Share on other sites

Do you know that if you move your object you must also move BB min and max? Are you moving/moved your tree or is it at "origin"?

 

How are you visualiasing BBox? Post some more code.

Edited by belfegor

Share this post


Link to post
Share on other sites

When I use these values, I add the current position of the mesh:

 

// Can we see it?
if (ViewFrustum.CheckRectangle(mesh->position.x + (mesh->BoundingBox.sizex/2.0f), // the x center
						   mesh->position.y + (mesh->BoundingBox.sizey/2.0f),  // the y center
						   mesh->position.z + (mesh->BoundingBox.sizez/2.0f), // the z center
						   mesh->BoundingBox.sizex, // the x size
						   mesh->BoundingBox.sizey, // the y size
						   mesh->BoundingBox.sizez) == false) // the z size
{FontSystem.get(0)->_string = L"Tree Available: false";return;}
else
{FontSystem.get(0)->_string = L"Tree Available: true";}

 

The frustum culling is based on the rastertek tutorial: http://www.rastertek.com/dx11tut16.html

Share this post


Link to post
Share on other sites

From what i can see the size(s) variables should be half extent of a bbox , so

 

 

void UMesh::AdaptBoundingBox(){
...
//BoundingBox.sizex = BoundingBox.maxx - BoundingBox.minx;
//BoundingBox.sizey = BoundingBox.maxy - BoundingBox.miny;
//BoundingBox.sizez = BoundingBox.maxz - BoundingBox.minz;
BoundingBox.sizex = (BoundingBox.maxx - BoundingBox.minx) * 0.5;
BoundingBox.sizey = (BoundingBox.maxy - BoundingBox.miny) * 0.5f;
BoundingBox.sizez = (BoundingBox.maxz - BoundingBox.minz) * 0.5f;
}
 
 
float bbCenter[3];
bbCenter[0] = (mesh->BoundingBox.maxx + mesh->BoundingBox.minx) * 0.5; // x
bbCenter[1] = (mesh->BoundingBox.maxy + mesh->BoundingBox.miny) * 0.5f;// y
bbCenter[2] = (mesh->BoundingBox.maxz + mesh->BoundingBox.minz) * 0.5f; // z
 
if (ViewFrustum.CheckRectangle(mesh->position.x + (bbCenter[0]), // the x center
                         mesh->position.y + (bbCenter[1]), // the y center
                         mesh->position.z + (bbCenter[2]), // the z center
                         mesh->BoundingBox.sizex, // the x size
                         mesh->BoundingBox.sizey, // the y size
                         mesh->BoundingBox.sizez) == false) // the z size
...
Edited by belfegor

Share this post


Link to post
Share on other sites

These are the wrong way around:

 

		if (maxx < vertices[i].X)
			maxx = vertices[i].X;

		if (maxy < vertices[i].Y)
			maxy = vertices[i].Y;

		if (maxz < vertices[i].Z)
			maxz = vertices[i].Z;

		if (minx > vertices[i].X)
			minx = vertices[i].X;

		if (miny > vertices[i].Y)
			miny = vertices[i].Y;

		if (minz > vertices[i].Z)
			minz = vertices[i].Z;

 

When you init minx, for example, to FLT_MAX, you're never actually going to have vertices[i].x exceeding it.  You need to check minx < vertices[i].x and maxx > vertices[i].x, and likewise for y and z.

Share this post


Link to post
Share on other sites
No, it is okay that way. Well, almost, you are doing sort of "yoda conditions" which is kind of confusing. I had to lool at the code a few times go get it right. I'd suggest you rewrite these conditions to like

" if(vertices[i] > maxx)"

to increase readability and understandabity.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this