-
Notifications
You must be signed in to change notification settings - Fork 923
Removed bounding_box calls with magic numbers #770
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -2929,14 +2932,13 @@ | |||
|
|||
virtual bool bounding_box(double time0, double time1, aabb& output_box) const override { | |||
output_box = bbox; | |||
return hasbox; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks wrong to me. In the constructor, we compute the bbox of the rotated object and store it in this->bbox
. Here we compute the original (unrotated) geometry bbox and return that instead, clobbering the computed bbox.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about:
virtual bool bounding_box(double time0, double time1, aabb& output_box) const override {
aabb unrotated_box;
if (ptr->bounding_box(time0, time1, unrotated_box) {
output_box = bbox;
return true;
}
else {
return false;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see what's going on. The rotated object is constructed with a given rotation angle, so is constant ever after. The rotated object, however, may be time-varying.
Given this, we can't compute the bounding box of the child object in the constructor, since we have no time parameters at construction. Even if we did, there's no point, because the bounding_box
method takes some (possibly different) time parameters. So we need to recompute the bounding box on every call.
Thus:
- Remove the
bbox
member from the class in addition to thehasbox
flag. They're both unusable. - We have code in the constructor that computes the bounding box of the rotated child object's box. That code no longer has any use in the constructor, so move that into the
rotate_y::bounding_box()
method. - You'll thus need access to the rotation angle, so you'll have to store that in a member variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The end result will be that the body of rotate_y::bounding_box()
will end up looking a lot like what the constructor currently looks like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this is pretty much the way that the translate
class operates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ugh.
Wait.
There's a discrepancy here. Like, a big one.
A ray has a specific time value. So a hit result samples the object over time. However, bounding_box()
methods take a range of times. Thus, they must yield the bounds of the object over that range, as opposed to a tight bounds for a specific instance in time.
That range of time is the range of time values for the entire rendering, and is thus invariant. Therefore, we should know the time range at object construction, and can safely cache the result. So rotate_y
is actually the way that things should be, except that it hard-coded the time range.
translate
incorrectly recomputes the bounding box over and over for every query — the time range is always the same, and therefore the result should just have been cached at construction and returned.
But that means that logically, every hittable should take the time range as parameters to their constructor. Which would be a major change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this change is screwed, and should be lumped in with the other bounding-box work slated for v4.0.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's another possible (major) design approach, which is that instead of every hittable taking a time range in the constructor, they have a set_time_range()
method. For most simple primitives, a no-op. For time-varying primitives, this sets the time range, which will be used by bounding_box()
. For hittables that contain children, they proxy the set_time_range()
call to each child, and possibly compute and cache their bounding box. (The bounding box could be memoized in the bounding_box()
method, but no point doing that on each call; bounding_box()
might be called many times, while set_time_range()
should be called only once.
Just a thought.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clarifying the comment above, just prior to scene render, you'd call set_time_interval()
(better name than set_time_range()
) on the root of the scene, to set up the scene graph once prior to rendering, after the scene time interval is known. Prior to rendering the second frame, you'd call set_time_interval()
with arguments for the second frame.
We should consider changing the Uhh.
|
Ok, we're going to rethink this for v4.0.0 instead. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This turns out to be a larger issue than a small patch change. Deferring to v4.0.0.
See #799 |
Resolves #749