Sprint 4 — Full bridge scene (Girder×5 + DeckSlab + Bearing×10 + Abutment×2)
viewer/bridge_scene.rs: BridgeScene compositor - 5× PSC-I Girder (2500mm c/c) - DeckSlab (12000mm, 220mm thick, top of girders) - 10× Elastomeric Bearing (5 per abutment end) - 2× ReverseT Abutment (start & end) - sweep::merge_meshes로 단일 메시 합성 - scene_extents()로 카메라 자동 배치 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
//! - Add selection highlight.
|
||||
|
||||
pub mod camera;
|
||||
pub mod bridge_scene;
|
||||
|
||||
use std::sync::Arc;
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
@@ -31,6 +32,7 @@ use cimery_kernel::OcctKernel;
|
||||
use cimery_kernel::PureRustKernel;
|
||||
use cimery_kernel::GeomKernel;
|
||||
use camera::Camera;
|
||||
use glam;
|
||||
|
||||
// ─── Vertex ───────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -139,23 +141,14 @@ impl RenderState {
|
||||
// ── Depth texture ─────────────────────────────────────────────────────
|
||||
let depth_view = Self::make_depth_view(&device, &surface_config);
|
||||
|
||||
// ── Test girder mesh via StubKernel ───────────────────────────────────
|
||||
// Sprint 3: replace StubKernel with OcctKernel when OCCT compiles.
|
||||
let test_ir = GirderIR {
|
||||
id: FeatureId::new(),
|
||||
station_start: 0.0,
|
||||
station_end: 40.0,
|
||||
offset_from_alignment: 0.0,
|
||||
section_type: SectionType::PscI,
|
||||
section: SectionParams::PscI(PscISectionParams::kds_standard()),
|
||||
count: 1,
|
||||
spacing: 0.0,
|
||||
material: MaterialGrade::C50,
|
||||
};
|
||||
// ── Full bridge scene (Sprint 4) ──────────────────────────────────────
|
||||
// Girder + DeckSlab + Bearing + Abutment
|
||||
#[cfg(feature = "occt")]
|
||||
let mesh = OcctKernel.girder_mesh(&test_ir).expect("OcctKernel mesh");
|
||||
let mesh = bridge_scene::build_bridge_scene(&OcctKernel)
|
||||
.expect("OcctKernel bridge scene");
|
||||
#[cfg(not(feature = "occt"))]
|
||||
let mesh = PureRustKernel.girder_mesh(&test_ir).expect("PureRustKernel mesh");
|
||||
let mesh = bridge_scene::build_bridge_scene(&PureRustKernel)
|
||||
.expect("PureRustKernel bridge scene");
|
||||
|
||||
let verts: Vec<Vertex> = mesh.vertices.iter().zip(mesh.normals.iter())
|
||||
.map(|(p, n)| Vertex { position: *p, normal: *n })
|
||||
@@ -174,7 +167,23 @@ impl RenderState {
|
||||
let num_indices = mesh.indices.len() as u32;
|
||||
|
||||
// ── Camera ────────────────────────────────────────────────────────────
|
||||
let mut camera = Camera::default_for_girder(mesh.aabb().1[2]); // span from AABB
|
||||
// Camera for full bridge scene
|
||||
let (mn, mx) = bridge_scene::scene_extents();
|
||||
let cx = (mn[0] + mx[0]) * 0.5;
|
||||
let cy = (mn[1] + mx[1]) * 0.5;
|
||||
let cz = (mn[2] + mx[2]) * 0.5;
|
||||
let span = (mx[2] - mn[2]).max(mx[0] - mn[0]);
|
||||
let mut camera = Camera {
|
||||
target: glam::Vec3::new(cx, cy, cz),
|
||||
radius: span * 1.2,
|
||||
yaw: std::f32::consts::FRAC_PI_4,
|
||||
pitch: 0.30,
|
||||
fov_y: 60.0_f32.to_radians(),
|
||||
aspect: 16.0 / 9.0,
|
||||
znear: 10.0,
|
||||
zfar: 10_000_000.0,
|
||||
};
|
||||
let _ = mesh.aabb(); // keep aabb call for future use
|
||||
camera.resize(surface_config.width, surface_config.height);
|
||||
|
||||
let camera_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
@@ -384,9 +393,9 @@ impl ApplicationHandler for CimeryApp {
|
||||
fn resumed(&mut self, event_loop: &ActiveEventLoop) {
|
||||
let attrs = Window::default_attributes()
|
||||
.with_title(if cfg!(feature = "occt") {
|
||||
"cimery viewer [Sprint 3 — OcctKernel B-rep]"
|
||||
"cimery viewer [Sprint 4 — Full Bridge / OcctKernel]"
|
||||
} else {
|
||||
"cimery viewer [Sprint 2 — PSC-I PureRustKernel]"
|
||||
"cimery viewer [Sprint 4 — Full Bridge / PureRustKernel]"
|
||||
})
|
||||
.with_inner_size(winit::dpi::LogicalSize::new(1280u32, 720u32));
|
||||
let window = Arc::new(
|
||||
|
||||
Reference in New Issue
Block a user