fix(view): 교대만 그려진 상태에서 정면·측면·평면 버튼이 동작하도록 함
- 원인: 교대를 고르면 교각 장면이 없어서 setView가 바로 반환. 정면 버튼이 아무 동작도 하지 않았음 - 교대만 보일 때는 교대 그룹의 좌표계(+x = 교대축, +z = 전면)에서 카메라 방향을 잡고, 보이는 교대 전체를 맞춤 - 테스트 640건 통과, 타입 검사·빌드 통과. 브라우저 시각 확인은 미실시 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
686d87bad9
commit
d3440e9158
1 file changed
+32
-2
+32
-2
@@ -479,9 +479,12 @@ function setView(kind: ViewKind): void {
|
||||
$('views-toggle').textContent = `${VIEWS.find((v) => v.kind === kind)?.label ?? ''} ▾`;
|
||||
setMenuOpen('views', false);
|
||||
const scene = allPiers ? allPiers.view : state.scene;
|
||||
if (!scene) return;
|
||||
const pier = activePier();
|
||||
if (!pier?.model) return;
|
||||
if (!scene || !pier?.model) {
|
||||
// No pier is drawn (an abutment is selected in ②): the views follow the abutment's own frame (2026-11-03).
|
||||
abutView(kind);
|
||||
return;
|
||||
}
|
||||
const framed = viewPosition(scene, kind, pier.model);
|
||||
// Keep the chosen view direction but fit every model (piers and abutments) in the window (2026-11-03).
|
||||
const fitted = fitToModels(framed.position, framed.target);
|
||||
@@ -490,6 +493,33 @@ function setView(kind: ViewKind): void {
|
||||
controls.update();
|
||||
}
|
||||
|
||||
/** Camera for the drawn abutments alone: the directions come from the abutment group (local +x = 교대축 IP1→IP3, +z = 전면). */
|
||||
function abutView(kind: ViewKind): void {
|
||||
const shown = abutGroups.filter((g) => g.visible);
|
||||
if (shown.length === 0) return;
|
||||
const box = new THREE.Box3();
|
||||
for (const g of shown) {
|
||||
g.updateWorldMatrix(true, true);
|
||||
box.expandByObject(g);
|
||||
}
|
||||
const sphere = box.getBoundingSphere(new THREE.Sphere());
|
||||
const ref = shown[0];
|
||||
const axisX = new THREE.Vector3(1, 0, 0).transformDirection(ref.matrixWorld);
|
||||
const front = new THREE.Vector3(0, 0, 1).transformDirection(ref.matrixWorld);
|
||||
const lift = new THREE.Vector3(0, 0.15, 0);
|
||||
const dirs: Record<ViewKind, THREE.Vector3> = {
|
||||
iso: new THREE.Vector3(1, 0.7, 1).normalize(),
|
||||
front: front.clone().add(lift).normalize(),
|
||||
side: axisX.clone().add(lift).normalize(),
|
||||
top: new THREE.Vector3(0, 1, 0.001).normalize(),
|
||||
};
|
||||
const target = sphere.center.clone();
|
||||
const dist = sphere.radius * 2.6;
|
||||
camera.position.copy(target.clone().add(dirs[kind].multiplyScalar(dist)));
|
||||
controls.target.copy(target);
|
||||
controls.update();
|
||||
}
|
||||
|
||||
/** Bounding sphere of everything drawn (the piers or the all-piers view, plus the abutments) fitted to the camera. */
|
||||
function fitToModels(position: THREE.Vector3, target: THREE.Vector3): { position: THREE.Vector3; target: THREE.Vector3 } {
|
||||
const box = new THREE.Box3();
|
||||
|
||||
Reference in new issue
Block a user