www.jpct.net
jPCT  a 3d engine for Java => Support => Topic started by: AGP on October 06, 2011, 09:08:16 pm

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;
}

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 xaxis. 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.

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

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

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?

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

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

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;
}

Looks fine to me at first glance.

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