Post by mrfresh3141 on Aug 12, 2023 19:11:49 GMT
There's something odd happening with the bounding box of some loaded obj files. The teapot and teddy are the main culprits. The dodecahedron is fine (amongst others).
The bounding box isn't big enough, so part of the object is cut off!
I'm getting the min and max x/y/z values from the incoming triangles (directly from the obj file).
I'm then transforming these using the object's transform (after multiplying by translate, scale, etc.). I'm doing this using the template in the bounding box bonus chapter (in order to account for rotations), I'm doing this once after the object's transform has been calculated.
So for an example, the teapot:
After loading (these appear correct after looking at the vector data in the obj file):
Minimum X, Y, Z : -3, 0, -2
Maximum X, Y, Z : 3.434, 3.15, 2
after a scale transform (of 0.7 in each axis) and translate (1.0 in z only)
Minimum x/y/z : -2.1, 0, -0.4
Maximum x/y/z : 2.4038, 2.205, 2.4
They are the correct values based on the post-transformed values (ie they are the min/max of the points after transform)... and I've tried calculating them with another tool and they appear to be the expected values.
So is the error somewhere else? I can't see anything obvious. The code looks broadly similar to other implementations.
If I remove the bounding box checks then it renders as expected with no bits missing.
The object that contains the triangle data from the obj file has a LocalIntersect() function that passes the ray to the bounds::intersects function unmodified (so after the base class intersects() function has transformed it using the inversetransform).
The bounding box intersecting code follows (and based on the cube code):
I think the bounding box intersection code is correct. I think the incoming min/max x/y/z are correct. I think the error is either in the transform of said x/y/z, or the ray being used in the bounding box intersect().
If you have any ideas I'd love to hear them.
Thanks!
The bounding box isn't big enough, so part of the object is cut off!
I'm getting the min and max x/y/z values from the incoming triangles (directly from the obj file).
I'm then transforming these using the object's transform (after multiplying by translate, scale, etc.). I'm doing this using the template in the bounding box bonus chapter (in order to account for rotations), I'm doing this once after the object's transform has been calculated.
So for an example, the teapot:
After loading (these appear correct after looking at the vector data in the obj file):
Minimum X, Y, Z : -3, 0, -2
Maximum X, Y, Z : 3.434, 3.15, 2
after a scale transform (of 0.7 in each axis) and translate (1.0 in z only)
Minimum x/y/z : -2.1, 0, -0.4
Maximum x/y/z : 2.4038, 2.205, 2.4
They are the correct values based on the post-transformed values (ie they are the min/max of the points after transform)... and I've tried calculating them with another tool and they appear to be the expected values.
So is the error somewhere else? I can't see anything obvious. The code looks broadly similar to other implementations.
If I remove the bounding box checks then it renders as expected with no bits missing.
The object that contains the triangle data from the obj file has a LocalIntersect() function that passes the ray to the bounds::intersects function unmodified (so after the base class intersects() function has transformed it using the inversetransform).
The bounding box intersecting code follows (and based on the cube code):
std::pair<double, double> BoundingBox::CheckAxis(double origin, double direction, double minx, double maxx)
{
auto tminNumerator = (minx - origin);
auto tmaxNumerator = (maxx - origin);
double tmin{ 0 }, tmax{ 0 };
if (std::abs(direction) >= epsilon)
{
tmin = tminNumerator / direction;
tmax = tmaxNumerator / direction;
}
else
{
tmin = tminNumerator * 9999999; // C++ builder gives invalid floating point operations if using INFINITY ¯\_(^-^)_/¯
tmax = tmaxNumerator * 9999999; //
}
if (tmin > tmax)
{
return { tmax, tmin };
}
return { tmin, tmax };
}
bool BoundingBox::Intersects(Ray& rt)
{
auto [xtmin, xtmax] = CheckAxis(rt.Origin.x, rt.Direction.x, Minimum.x, Maximum.x);
auto [ytmin, ytmax] = CheckAxis(rt.Origin.y, rt.Direction.y, Minimum.y, Maximum.y);
auto [ztmin, ztmax] = CheckAxis(rt.Origin.z, rt.Direction.z, Minimum.z, Maximum.z);
auto tmin = std::max(std::max(xtmin, ytmin), ztmin);
auto tmax = std::min(std::min(xtmax, ytmax), ztmax);
return tmax >= tmin;
}
I think the bounding box intersection code is correct. I think the incoming min/max x/y/z are correct. I think the error is either in the transform of said x/y/z, or the ray being used in the bounding box intersect().
If you have any ideas I'd love to hear them.
Thanks!