forked from 1b-agent/fieldcraft-upstream
mcp, cli, ui: camera target, fit and fov in screenshots, snapshot --camera and ui.camera; screenshot section (#467)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UhhZMBTviDQxZvwnyP89fo
This commit is contained in:
1 parent
1f183e04ea
commit
19c0538dd8
9 files changed
+145
-39
No files matched your search
@@ -327,11 +327,8 @@ pub fn handle(app: &mut ModelApp, ctx: &egui::Context, req: &ControlRequest) ->
|
||||
}
|
||||
ok(json!(app.cam))
|
||||
}
|
||||
"ui.camera" => match fieldcraft_engine::view::orientation(p) {
|
||||
Ok(o) => {
|
||||
app.cam.orient(&o);
|
||||
ok(json!(app.cam))
|
||||
}
|
||||
"ui.camera" => match fieldcraft_engine::view::camera(p).map_err(|e| e.to_string()).and_then(|a| app.aim_camera(&a)) {
|
||||
Ok(()) => ok(json!(app.cam)),
|
||||
Err(e) => err(e),
|
||||
},
|
||||
"ui.start" => {
|
||||
@@ -748,6 +745,13 @@ mod tests {
|
||||
}
|
||||
assert_eq!(app.cam.distance, 250.0);
|
||||
assert_eq!(call(&mut app, "ui.camera", json!({"yaw": -1e12, "pitch": 1e300, "distance": 1e300}))["ok"], true);
|
||||
// Aimed at a point it looks at it; at the model's centre of mass, framed (#467).
|
||||
let r = call(&mut app, "ui.camera", json!({"yaw": 30, "pitch": 20, "target": [1, 2, 3], "distance": 40}));
|
||||
assert_eq!((app.cam.target, app.cam.distance), (fieldcraft_render::Vec3::new(1.0, 2.0, 3.0), 40.0), "{r}");
|
||||
let r = call(&mut app, "ui.camera", json!({"yaw": 30, "pitch": 20, "target": {"center_of": "mass"}, "fit": true}));
|
||||
assert_eq!(r["ok"], true, "{r}");
|
||||
assert!(app.cam.target.dist(fieldcraft_render::Vec3::new(1.0, 2.0, 3.0)) > 1.0 && app.cam.distance < 1e8, "{r}");
|
||||
assert_eq!(call(&mut app, "ui.camera", json!({"yaw": 0, "pitch": 0, "target": {"bodies": ["Nope"]}}))["ok"], false);
|
||||
assert!(app.cam.is_valid() && app.cam.pitch < std::f64::consts::FRAC_PI_2);
|
||||
assert_eq!(call(&mut app, "ui.inspect", json!({}))["result"]["model"]["elements"], 64 + 162);
|
||||
assert_eq!(call(&mut app, "ui.screenshot", json!({})), json!({"screenshot": true}));
|
||||
|
||||
@@ -1894,6 +1894,16 @@ impl ModelApp {
|
||||
self.fit_view();
|
||||
}
|
||||
|
||||
/// Aim the camera as `aim` says ([`fieldcraft_engine::view::camera`], the control channel's
|
||||
/// `ui.camera`): turned, and with a target moved to look at it from the view's free part, as
|
||||
/// a standard view moves it. A framing still waiting is dropped.
|
||||
pub fn aim_camera(&mut self, aim: &fieldcraft_engine::view::Aim) -> Result<(), String> {
|
||||
let (aspect, _) = self.free_part();
|
||||
self.cam = fieldcraft_engine::view::aim(&self.session, aim, self.cam, aspect).map_err(|e| e.to_string())?;
|
||||
self.reframe = None;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Do the framing asked for ([`framing::Reframe`]) once there is something to frame; the
|
||||
/// viewport calls it when it knows its size and its overlays, before drawing.
|
||||
pub(crate) fn apply_reframe(&mut self) {
|
||||
|
||||
Reference in new issue
Block a user