World Space Bounds

Started by AGP, October 06, 2011, 09:08:16 PM

Previous topic - Next topic

AGP

Egon, do you agree with this code? Because if this is right, I have to find something to find wrong with my program. :- )


     public float[] getWorldSpaceBounds() {
float[] objectSpaceBounds = terrain.getMesh().getBoundingBox();
SimpleVector minimums = new SimpleVector(objectSpaceBounds[0], objectSpaceBounds[2], objectSpaceBounds[4]);
SimpleVector maximums = new SimpleVector(objectSpaceBounds[1], objectSpaceBounds[3], objectSpaceBounds[5]);
minimums.matMul(terrain.getWorldTransformation());
maximums.matMul(terrain.getWorldTransformation());
float[] worldSpaceBounds = new float[6];
worldSpaceBounds[0] = minimums.x;
worldSpaceBounds[2] = minimums.y;
worldSpaceBounds[4] = minimums.z;
worldSpaceBounds[1] = maximums.x;
worldSpaceBounds[3] = maximums.y;
worldSpaceBounds[5] = maximums.z;
return worldSpaceBounds;
     }

EgonOlsen

The logic seems to be flawed. As long as there's no rotation involved, it will work. But if, for example, the terrain rotates 45° around Y, your actual box will collapse to a plane with no depth on the x-axis. You have to create the bounding boxes vertices instead from the min/max values, rotate them and calculate a new bounding box from that that will represent your world space bounds.

AGP

Does that just mean apply the rotation just before calling matMul(getWorldTransformation())? Or is there something I'm missing?

EgonOlsen

No, matMul is the rotation. You just have to do that with all eight corners of the box and calculate the new min/max-values afterwards.

AGP

So it comes down to an iVertexController with which to get all the vertices, transform them with matMul, then test for the minimums and maximums?

EgonOlsen

No. You can simply create the needed vertices from the min/max-values that the getBoundingBox()-method returns. Just draw a quick sketch on paper and you'll see.

AGP

Now that you mention it I get it. Thanks a lot.

AGP

#7
I assume this one's right. If you say so, I will add it to the wiki's "code snippets" section, for future reference.

     public float[] getWorldSpaceBounds() {
float[] objectSpaceBounds = terrain.getMesh().getBoundingBox();
SimpleVector mins = new SimpleVector(objectSpaceBounds[0], objectSpaceBounds[2], objectSpaceBounds[4]);
SimpleVector maxs = new SimpleVector(objectSpaceBounds[1], objectSpaceBounds[3], objectSpaceBounds[5]);
SimpleVector[] p = new SimpleVector[8];
p[0] = new SimpleVector(mins.x, mins.y, maxs.z); p[1] = new SimpleVector(mins.x, mins.y, mins.z); p[2] = new SimpleVector(maxs.x, mins.y, mins.z);
p[3] = new SimpleVector(maxs.x, mins.y, maxs.z); p[4] = new SimpleVector(maxs.x, maxs.y, mins.z);
p[5] = new SimpleVector(maxs.x, maxs.y, maxs.z); p[6] = new SimpleVector(mins.x, maxs.y, mins.z); p[7] = new SimpleVector(mins.x, maxs.x, maxs.z);
float minX = Float.MAX_VALUE, minY = Float.MAX_VALUE, minZ = Float.MAX_VALUE, maxX = Float.MIN_VALUE, maxY = Float.MIN_VALUE, maxZ = Float.MIN_VALUE;
for (int i = 0; i < 8; i++) {
     p[i].matMul(terrain.getWorldTransformation());
     if (p[i].x < minX)
minX = p[i].x;
     if (p[i].y < minY)
minY = p[i].y;
     if (p[i].z < minZ)
minZ = p[i].z;
     if (p[i].x > maxX)
maxX = p[i].x;
     if (p[i].y > maxY)
maxY = p[i].y;
     if (p[i].z > maxZ)
maxZ = p[i].z;
}
float[] worldSpaceBounds = new float[6];
worldSpaceBounds[0] = minX;
worldSpaceBounds[2] = minY;
worldSpaceBounds[4] = minZ;
worldSpaceBounds[1] = maxX;
worldSpaceBounds[3] = maxY;
worldSpaceBounds[5] = maxZ;
return worldSpaceBounds;
     }

EgonOlsen

Looks fine to me at first glance.

AGP

Looks horrendous (maybe you could format it later), but it's on the wiki.