forked from 1b-agent/opencadstudio-upstream
fix(scene): correct view_world_aabb space + guard initial render
Two bugs in the new frustum culler that left the GUI rendering nothing on file open: 1. `cam.target` is already in **local** f32 space — `fit_to_bounds` populates it from local wire coords — so subtracting `world_offset` again pushed the view rect to the negated centroid, with the actual geometry far outside. 2. The first call to `entity_wires()` after open comes from `fit_all()` itself, while `camera_generation` is still 0 and the camera is at its default origin. Culling against that rect discarded every wire → fit_all saw an empty list → camera never moved → the user-visible render stayed empty forever. `view_world_aabb` now returns `None` until `camera_generation > 0` (letting fit_all collect a real extent), then derives the view rect directly from `cam.target` in local space. Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
1 parent
78cbb5570e
commit
8d5ecdef51
1 file changed
+12
-5
+12
-5
@@ -343,16 +343,23 @@ impl Scene {
|
||||
// top-level paper canvas is small enough not to need it.
|
||||
return None;
|
||||
}
|
||||
// Until the first explicit camera move (typically `fit_all()` after
|
||||
// file open), the camera sits at the default origin while geometry
|
||||
// lives at large local offsets — culling against the default rect
|
||||
// would discard everything and starve fit_all of points to fit to.
|
||||
if self.camera_generation == 0 {
|
||||
return None;
|
||||
}
|
||||
let cam = self.camera.borrow();
|
||||
let aspect = self.last_render_aspect.get().max(0.01);
|
||||
let h = cam.ortho_size();
|
||||
let w = h * aspect;
|
||||
// Generous margin: in 3D / perspective the projection actually covers
|
||||
// more than the orthographic-equivalent rect, and pan inertia briefly
|
||||
// moves geometry past the visible edge before camera_generation bumps.
|
||||
let margin = 1.25_f32;
|
||||
let cx = (cam.target.x - self.world_offset[0] as f32) as f32;
|
||||
let cy = (cam.target.y - self.world_offset[1] as f32) as f32;
|
||||
// `cam.target` is in the same local f32 space as emitted wire points
|
||||
// (fit_to_bounds populates it from local wire coords). No further
|
||||
// `world_offset` subtraction is needed.
|
||||
let cx = cam.target.x;
|
||||
let cy = cam.target.y;
|
||||
Some([
|
||||
cx - w * margin,
|
||||
cy - h * margin,
|
||||
|
||||
Reference in new issue
Block a user