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 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.
-
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/max-values 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/max-values 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.