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 @@

๐Ÿ—๏ธ ๋ถ€์žฌ ๊ตฌ์„ฑ

-
-
๊ฐ€์‹œ์„ค4 52๊ฐœ
-
h-pile2 244๊ฐœ
-
ํ† ๋ฅ˜ํŒ 240๊ฐœ
-
H-PILE 26๊ฐœ
-
์Šคํ„ฐ๋Ÿฟ 26๊ฐœ
+
+ + + + +
+
@@ -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);