PDA

View Full Version : Question



Krispies
10-15-2010, 02:31 PM
Hi, I'm really struggling to create a bounding box around my object. I've read websites but the guidance on implementing it isn't shown and I've tried countless times to do it myself so I will show my current working.

My Shape information:


GLfloat normals[] = {0,0,1, 0,0,1, 0,0,1, 0,0,1, // v0-v1-v2-v3
1,0,0, 1,0,0, 1,0,0, 1,0,0, // v0-v3-v4-v5
0,1,0, 0,1,0, 0,1,0, 0,1,0, // v0-v5-v6-v1
-1,0,0, -1,0,0, -1,0,0, -1,0,0, // v1-v6-v7-v2
0,-1,0, 0,-1,0, 0,-1,0, 0,-1,0, // v7-v4-v3-v2
0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1}; // v4-v7-v6-v5


GLfloat vertices[] = {1,1,1, -4,1,1, -4,-1,1, 1,-1,1, // v0-v1-v2-v3
1,1,1, 1,-1,1, 1,-1,-1, 1,1,-1, // v0-v3-v4-v5
1,1,1, 1,1,-1, -4,1,-1, -4,1,1, // v0-v5-v6-v1
-4,1,1, -4,1,-1, -4,-1,-1, -4,-1,1, // v1-v6-v7-v2
-4,-1,-1, 1,-1,-1, 1,-1,1, -4,-1,1, // v7-v4-v3-v2
1,-1,-1, -4,-1,-1, -4,1,-1, 1,1,-1}; // v4-v7-v6-v5


GLfloat colors[] = {1,1,1, 1,1,0, 1,0,0, 1,0,1, // v0-v1-v2-v3
1,1,1, 1,0,1, 0,0,1, 0,1,1, // v0-v3-v4-v5
1,1,1, 0,1,1, 0,1,0, 1,1,0, // v0-v5-v6-v1
1,1,0, 0,1,0, 0,0,0, 1,0,0, // v1-v6-v7-v2
0,0,0, 0,0,1, 1,0,1, 1,0,0, // v7-v4-v3-v2
0,0,1, 0,0,0, 0,1,0, 0,1,1}; // v4-v7-v6-v5

void OBJECT(int x, int y, int z){
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glNormalPointer(GL_FLOAT, 0, normals);
glColorPointer(3, GL_FLOAT, 0, colors);
glVertexPointer(3, GL_FLOAT, 0, vertices);

glPushMatrix();
glTranslatef(x, y, z); // Position Holder
glDrawArrays(GL_QUADS, 0, 24);
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}


Ok to use a bounding box around my object I'm understanding that I use a Min/Max value and wrap it around my object(poor understanding I know)

What I've tried / Doesn't work

struct Vector3
{

float x;
float y;
float z;

};
struct BoundingBox
{

Vector3 Max;
Vector3 Min;

}OBJECT;

I've inserted this into the draw function for the OBJECT so I can see myself the box being drawn but none of this works because I'm not really understanding fully.

glBegin(GL_LINES);
glColor3f(255,0,0);
glVertex3f(aabb.m_xMin, aabb.m_yMin, aabb.m_zMin);
glVertex3f(aabb.m_xMin, aabb.m_yMin, aabb.m_zMax);

glVertex3f(aabb.m_xMax, aabb.m_yMin, aabb.m_zMin);
glVertex3f(aabb.m_xMax, aabb.m_yMin, aabb.m_zMax);

glVertex3f(aabb.m_xMin, aabb.m_yMax, aabb.m_zMin);
glVertex3f(aabb.m_xMin, aabb.m_yMax, aabb.m_zMax);

glEnd();





I know this is a complete mess but I'm just reading different bits of how to do it without ever seeing a full solution that will help me define my own bounding box.


Can anyone aid me to understand / or how to implement a bounding box for my object array please ~



Regards.

carsten neumann
10-16-2010, 04:04 AM
What I've tried / Doesn't work

In what way does this not work? Is anything drawn at all? Is it the wrong size (i.e. the box does not enclose your object)?


Ok to use a bounding box around my object I'm understanding that I use a Min/Max value and wrap it around my object

yes, this gives an axis aligned bounding box. The x,y,z values of Min/Max are the minimum/maximum over all vertices.

I'm not sure what you want to draw with the GL_LINES, it will only show you three of the 24 edges of the box, but it still should give you an idea if your bounding box is actually containing your object.

Krispies
10-16-2010, 05:28 AM
[quote]In what way does this not work? Is anything drawn at all? Is it the wrong size (i.e. the box does not enclose your object)?

I'm having trouble creating the bounding box itself, I was attempting to use the vertice array values to draw the bounding box so it would be a tight fit but I havent had any success in doing so.

I was drawing the Lines to display the boundingbox once I had it figured out but it doesn't seem to want to use the vertices I already supplied to draw my object.


I've exhausted all attempts to figure out how to draw it around my object which is why I came here to get some guidance. The guides I tried to find only give code snippets and don't really show how they've achieved the bounding box around a certain object in the way I have drawn mine with vertice array.

carsten neumann
10-16-2010, 06:56 AM
I'm having trouble creating the bounding box itself, I was attempting to use the vertice array values to draw the bounding box so it would be a tight fit but I havent had any success in doing so.

If you are trying to use some of the existing vertices of object to draw the bounding box, this can not work, because in general the bounding box corners do not coincide with any vertices of the object. Calculating the bounding box corners can be done with a loop over all vertices:



Vec3f min( Inf, Inf, Inf);
Vec3f max(-Inf, -Inf, -Inf);

for(std::size_t i = 0; i < vertices.size(); ++i)
{
min.x = (vertices[i].x < min.x) ? vertices[i].x : min.x;
min.y = (vertices[i].y < min.y) ? vertices[i].y : min.y;
min.z = (vertices[i].z < min.z) ? vertices[i].z : min.z;

max.x = (vertices[i].x > max.x) ? vertices[i].x : max.x;
max.y = (vertices[i].y > max.y) ? vertices[i].y : max.y;
max.z = (vertices[i].z > max.z) ? vertices[i].z : max.z;
}


From these two points you can calculate all six corners of the bounding box. If you make your vertex array 6 elements larger than your object needs, you can store the corners of the bounding box there and use them if you want to visualize it or just ignore them if you only want to draw your object.

Krispies
10-18-2010, 03:29 PM
Hi, thankyou for the reply's so far,I've been busy at work and haven't had much time to reply.

I believe I'm close to implementing my bounding box, but I'm having trouble with the method you suggested above.

I will post the code I have so far so you can see where I am going wrong possibly?.



GLfloat vertices[] = {1,1,1, -4,1,1, -4,-1,1, 1,-1,1, // v0-v1-v2-v3
1,1,1, 1,-1,1, 1,-1,-1, 1,1,-1, // v0-v3-v4-v5
1,1,1, 1,1,-1, -4,1,-1, -4,1,1, // v0-v5-v6-v1
-4,1,1, -4,1,-1, -4,-1,-1, -4,-1,1, // v1-v6-v7-v2
-4,-1,-1, 1,-1,-1, 1,-1,1, -4,-1,1, // v7-v4-v3-v2
1,-1,-1, -4,-1,-1, -4,1,-1, 1,1,-1}; // v4-v7-v6-v5





struct BoundingBox
{
CVector4 min; .
CVector4 max;
};



BoundingBox Box;


void BoundingBox()
{

Box.min.x = 0.0f;
Box.max.x = 0.0f;
Box.min.z = 0.0f;
Box.max.z = 0.0f;
Box.min.y = 0.0f;
Box.max.y = 0.0f;

for(int i = 0; i < 73; i++)
{
if(vertices[i].x < Box.min.x) Box.min.x = vertices[i].x;
if(vertices[i].x > Box.max.x) Box.max.x = vertices[i].x;

if(vertices[i].y < Box.min.y) Box.min.y = vertices[i].y;
if(vertices[i].y > Box.max.y) Box.max.y = vertices[i].y;

if(vertices[i].z < Box.min.z) Box.min.z = vertices[i].z;
if(vertices[i].z > Box.max.z) Box.max.z = vertices[i].z;
}
}


I'm trying to read the vertices array I have but it doesn't like it one bit, I'd rather not re-design my object, is there anyway to use the vertice array I defined?

mhagain
10-19-2010, 03:04 AM
That code is more or less OK, but you need to set your initial min to a really really large positive number and your initial max to a really really large negative number. Large enough so that every vertex in the object is going to be lower than the initial min and higher than the initial max. The correct values should then just fall out of it.

Krispies
10-19-2010, 08:51 AM
GLfloat vertices[] + if(vertices[i].x < Box.min.x) Box.min.x = vertices[i].x;

It wont accept reading the values from the vertices array I specified, which is what I'm having trouble with. The code is logically ok and would work for a object drawn differently, but I want it to use my vertex array. I'm not sure if I'm making any sense here as I'm not advanced as most people here, so terminology is lacking.

Basically: All the values I specified in GLfloat vertices[] I want to use those values to find the Min/Max value for my AABB.
I have shown my code above and what I previously tried in the posts before. Any modifications or a way to resolve my issue would be grateful as when I go to compile it reads; "left of '.x' must have class/struct/union type is 'GLfloat'"

mhagain
10-19-2010, 09:08 AM
OK, I should have looked at your code closer...

Using "vertices[i].x" here is definitely wrong. vertices is of type GLfloat, not CVector4 so you can't address it that way at all. That code as you've given it shouldn't compile so you should get the error you're getting.

Using 73 in your for loop is also wrong, and will go down in flames. Arrays in C (and descendent languages or languages that share the same syntax) are 0-based, so a 72 element array will have elements addressable by the indexes 0 to 71. Your for loop should be 72, not 73. This way it will stop when it gets to index 71, and won't attempt to read beyond the end of your array.

You need to try something like:
GLfloat *v = vertices;
Box.min.x = Box.min.y = Box.min.z = 99999999;
Box.max.x = Box.max.y = Box.max.z = -99999999;

for (int i = 0; i < 72; i += 3, v += 3)
{
if (v[0] < Box.min.x) Box.min.x = v[0];
if (v[1] < Box.min.y) Box.min.y = v[1];
if (v[2] < Box.min.z) Box.min.z = v[2];

if (v[0] > Box.max.x) Box.max.x = v[0];
if (v[1] > Box.max.y) Box.max.y = v[1];
if (v[2] > Box.max.z) Box.max.z = v[2];
}

You would probably be better off not hard-coding 72 in here as well. If you ever add or remove vertexes from your array you'll need to go jumping around elsewhere in your code looking for the number 72, figure if the 72 refers to the number of vertexes or to something else, and change it if necessary. Use something like this instead:
int NumVertices = sizeof (vertices) / (sizeof (GLfloat) * 3);

Krispies
10-19-2010, 09:58 AM
Mhagain, I am in your debt! :D - I understand what I was doing wrong and have worked my AABB's thanks to your explanation above^. Thankyou for the recommendation/code example it has been of great help.

[Resolved]

MaxH
10-19-2010, 11:45 AM
A slightly different way to initialize which I prefer ....



Box.min.x = Box.min.x = v[0];
Box.min.y = Box.max.y = v[1];
Box.min.z = Box.max.z = v[2];

for (int i = 1; i < 72; i += 3, v += 3)
{
if (v[0] < Box.min.x) Box.min.x = v[0];
if (v[1] < Box.min.y) Box.min.y = v[1];
if (v[2] < Box.min.z) Box.min.z = v[2];

if (v[0] > Box.max.x) Box.max.x = v[0];
if (v[1] > Box.max.y) Box.max.y = v[1];
if (v[2] > Box.max.z) Box.max.z = v[2];
}

[/QUOTE]

Krispies
10-24-2010, 01:43 PM
Sorry to bump this topic up again, but since it contains the previous answers it may help with the answer I'm looking for.

Since im trying to do this in 3D, I now need to translate my AABB accordingly to the current position of the cuboids I have defined.

The Problem is, I don't know where to start on "how to", since I know the Box.max/min.x,y,z's are stored using the Array values, but translating and updating them(according to current coboid position) for collision is proving quite difficult. When debugging the values shown are the values given in the vertex array and not updating relative to the position of the cuboid.

I know the correct collision check formula to check if one point is inside the other, so that's not the issue.

I have one static Cuboid thats defined in a certain location using the push/translate/pop, and one dynamic cuboid which is translated by the values(for current position etc) used to move the cameras values(3rd person basically).

To place the AABB's around the objects new position is quite puzzling, as I cannot obviously just use a translate function because it will alter it's current size if I used the current min/max values.

Any tutorial or document guidance or where I can find my solution would be welcomed. I have tried to translate the AABB to a different position with translatef function, but no such luck.