diff --git a/out/viewer-correct.html b/out/viewer-correct.html
index f4852ae..5dcc12a 100644
--- a/out/viewer-correct.html
+++ b/out/viewer-correct.html
@@ -191,13 +191,39 @@
๐๏ธ ๋ถ์ฌ ๊ตฌ์ฑ
-
@@ -338,12 +364,23 @@
const DISPLAY_SCALE = 0.01;
+ // ๋ถ์ฌ ๊ทธ๋ฃน ์ถ์ (์จ์คํ ์ ์ด์ฉ)
+ const memberGroups = {
+ '๊ฐ์์ค4': [],
+ 'h-pile2': [],
+ 'ํ ๋ฅํ': [],
+ 'H-PILE': [],
+ '์คํฐ๋ฟ': []
+ };
+
// ์ํ ๋ถ์ฌ (ํ
์คํธ์ฉ)
const testGeo = new THREE.BoxGeometry(4, 4, 80);
const testMat = new THREE.MeshStandardMaterial({ color: 0x7ed321, roughness: 0.7, emissive: 0x2d5a2d });
const testMesh = new THREE.Mesh(testGeo, testMat);
testMesh.position.set(0, -2554, 100);
+ testMesh.userData.groupName = 'h-pile2';
scene.add(testMesh);
+ memberGroups['h-pile2'].push(testMesh);
console.log('โ ์ํ ๋ถ์ฌ ์ถ๊ฐ๋จ');
// ๊ทธ๋ฆฌ๋ & ์ถ
@@ -426,7 +463,14 @@
const mesh = new THREE.Mesh(geometry, getMaterial(type));
mesh.position.set(position.x, position.y, position.z + 10);
+ mesh.userData = { blockType, type, spec, volume, groupName: blockType };
scene.add(mesh);
+
+ // ๋ถ์ฌ ๊ทธ๋ฃน์ ์ถ๊ฐ
+ if (memberGroups[blockType]) {
+ memberGroups[blockType].push(mesh);
+ }
+
count++;
if (count <= 3 || count % 100 === 0) {
@@ -447,6 +491,80 @@
document.getElementById('loadingMsg').innerHTML = 'โ ๋ก๋ ์คํจ
' + err.message;
});
+ // ๋ถ์ฌ ํ ๊ธ ๊ธฐ๋ฅ
+ const checkboxes = {
+ '๊ฐ์์ค4': document.getElementById('cb-gasiseol4'),
+ 'h-pile2': document.getElementById('cb-hpile2'),
+ 'ํ ๋ฅํ': document.getElementById('cb-tolyupan'),
+ 'H-PILE': document.getElementById('cb-hpile'),
+ '์คํฐ๋ฟ': document.getElementById('cb-strut')
+ };
+
+ Object.entries(checkboxes).forEach(([name, checkbox]) => {
+ checkbox.addEventListener('change', (e) => {
+ const isVisible = e.target.checked;
+ memberGroups[name].forEach(mesh => {
+ mesh.visible = isVisible;
+ });
+ console.log(`${name}: ${isVisible ? 'ํ์' : '์จ๊น'}`);
+ });
+ });
+
+ // ์คํ ๊ธฐ๋ฅ
+ document.getElementById('btnZoomFit').addEventListener('click', () => {
+ // ํ์ฑํ๋ ๋ถ์ฌ๋ค์ ๊ฒฝ๊ณ ๊ณ์ฐ
+ let minX = Infinity, maxX = -Infinity;
+ let minY = Infinity, maxY = -Infinity;
+ let minZ = Infinity, maxZ = -Infinity;
+ let hasVisible = false;
+
+ Object.entries(memberGroups).forEach(([name, meshes]) => {
+ if (checkboxes[name].checked) {
+ meshes.forEach(mesh => {
+ if (mesh.geometry.boundingBox === null) {
+ mesh.geometry.computeBoundingBox();
+ }
+ const box = mesh.geometry.boundingBox;
+ const pos = mesh.position;
+
+ minX = Math.min(minX, pos.x + box.min.x);
+ maxX = Math.max(maxX, pos.x + box.max.x);
+ minY = Math.min(minY, pos.y + box.min.y);
+ maxY = Math.max(maxY, pos.y + box.max.y);
+ minZ = Math.min(minZ, pos.z + box.min.z);
+ maxZ = Math.max(maxZ, pos.z + box.max.z);
+ hasVisible = true;
+ });
+ }
+ });
+
+ if (!hasVisible) {
+ console.log('ํ์๋ ๋ถ์ฌ๊ฐ ์์ต๋๋ค');
+ return;
+ }
+
+ // ๊ฒฝ๊ณ์ ์ค์ฌ๊ณผ ํฌ๊ธฐ ๊ณ์ฐ
+ const center = new THREE.Vector3(
+ (minX + maxX) / 2,
+ (minY + maxY) / 2,
+ (minZ + maxZ) / 2
+ );
+
+ const size = new THREE.Vector3(
+ maxX - minX,
+ maxY - minY,
+ maxZ - minZ
+ );
+
+ const maxDim = Math.max(size.x, size.y, size.z);
+ const fov = camera.fov * (Math.PI / 180);
+ let cameraZ = Math.abs(maxDim / 2 / Math.tan(fov / 2));
+
+ camera.position.set(center.x, center.y, center.z + cameraZ * 1.5);
+ camera.lookAt(center);
+ console.log('โ ์คํ ์๋ฃ');
+ });
+
// ๋ ๋๋ง
function animate() {
requestAnimationFrame(animate);