feat(view): ③ rebar view at 50% for members, ground and blinding; deeper rebar colour

On ③ the members, the ground and the blinding concrete are drawn at half opacity without depth writes, so the bars show
through. Outside ③ each part returns to its own opacity. Rebar colours are shaded to 0.8 and slightly glossier so they
read through the members. Approved 2026-10-23.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-23 09:24:53 +09:00
1 parent e0e220f35c
commit 398fa997e2
4 files changed
+52 -3

No files matched your search

+5 -2
View File
@@ -33,6 +33,9 @@ const OTHER_COLOR = 0x8c8c8c;
const MEMBER_COLORS: Record<RebarMemberKey, number> = { bearing: 0xe69f00, coping: 0x0072b2, column: 0x009e73, footing: 0xcc79a7, other: OTHER_COLOR };
const MEMBER_LABELS: Record<RebarMemberKey, string> = { bearing: '받침블럭', coping: '코핑', column: '기둥', footing: '확대기초', other: '기타' };
const hex = (v: number) => `#${v.toString(16).padStart(6, '0')}`;
/** Rebar is drawn a little deeper than the 6.7 colours so it reads through the half-transparent members (승인 2026-10-23). */
const REBAR_SHADE = 0.8;
const rebarColor = (v: number) => new THREE.Color(v).multiplyScalar(REBAR_SHADE);
const COLOR = {
coping: 0xb4531f,
@@ -66,7 +69,7 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
geo.applyQuaternion(new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 1, 0), dir.normalize()));
geo.translate((a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2);
geo.applyMatrix4(Ms[k]);
const mat = new THREE.MeshStandardMaterial({ color, roughness: 0.6, metalness: 0.1 });
const mat = new THREE.MeshStandardMaterial({ color: rebarColor(color), roughness: 0.45, metalness: 0.1 });
const mesh = new THREE.Mesh(geo, mat);
mesh.userData = { name, roleColor: color, dMm, member: memberOfBar(name) };
group.add(mesh);
@@ -459,7 +462,7 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
};
const setColorMode = (mode: RebarColorMode) => {
for (const meshes of byName.values()) {
for (const mesh of meshes) (mesh.material as THREE.MeshStandardMaterial).color.setHex(colorOf(mesh, mode));
for (const mesh of meshes) (mesh.material as THREE.MeshStandardMaterial).color.copy(rebarColor(colorOf(mesh, mode)));
}
};
const legend = (mode: RebarColorMode) => {
+19
View File
@@ -87,6 +87,7 @@ export function buildPierScene(m: PierModel): PierScene {
side: THREE.DoubleSide,
clippingPlanes,
});
material.userData.baseOpacity = opacity;
parts[part].add(new THREE.Mesh(geometry, material));
};
@@ -146,6 +147,24 @@ export function buildPierScene(m: PierModel): PierScene {
return { root, parts, size };
}
/** ③ rebar view: members and the ground at half opacity so the bars show through (승인 2026-10-23). */
const REBAR_VIEW_ALPHA = 0.5;
/** Turns the ③ rebar view on or off. Off restores each part's own opacity. Depth writes stop while on, so bars behind a member stay visible. */
export function setRebarView(scene: PierScene, on: boolean): void {
for (const group of Object.values(scene.parts)) {
group.traverse((o) => {
if (!(o instanceof THREE.Mesh)) return;
const mat = o.material as THREE.MeshStandardMaterial;
const base = mat.userData.baseOpacity as number;
mat.opacity = on ? REBAR_VIEW_ALPHA : base;
mat.transparent = on || base < 1;
mat.depthWrite = !on;
mat.needsUpdate = true;
});
}
}
export type ViewKind = 'iso' | 'front' | 'side' | 'top';
/** Camera position for one of the four view presets, looking at the centre of the model. */