import { createElement } from "../../../lib/skeleton/index.js"; import { qs } from "../../../lib/dom.js"; import * as THREE from "../../../lib/vendor/three/three.module.js"; export default function(render, { camera, controls, mesh, $menubar, $toolbar, is2D }) { if (mesh.children.length <= 1) return; $menubar.add(buttonLayers({ $toolbar })); render(createChild( document.createDocumentFragment(), mesh, 0, { camera, controls, is2D } )); } function buttonLayers({ $toolbar }) { const $button = createElement(`layers`); $button.onclick = () => $toolbar.classList.toggle("open"); return $button; } function createChild($fragment, mesh, child = 0, opts) { if (["Bone"].indexOf(mesh.type) >= 0) return; buildDOM($fragment, mesh, child, opts); if (mesh.children.length > 0 && child < 4) { for (let i=0; i
${name(child)} `); qs($label, "input").onchange = () => child.visible = !child.visible; $label.onclick = async(e) => { if (is2D()) return; else if (e.target.nodeName === "INPUT" || e.target.classList.contains("component_checkbox")) return; e.preventDefault(); e.stopPropagation(); getRootObject(child).traverse((c) => { if (!c.material) return; c.material.opacity = c.id === child.id || c.parent.id === child.id ? 1 : 0.2; c.material.depthWrite = c.material.opacity === 1; }); await flyTo({ mesh: child, camera, controls }); }; $fragment.appendChild($label); } async function flyTo({ mesh, camera, controls }) { const box = new THREE.Box3().setFromObject(mesh); const size = box.getSize(new THREE.Vector3()); const targetLookAt = box.getCenter(new THREE.Vector3()); const targetDistance = Math.max(size.x, size.y, size.z) * 1.1; const targetPosition = targetLookAt.clone().add(new THREE.Vector3(targetDistance, targetDistance, targetDistance)); const [startPosition, startLookAt] = [camera.position.clone(), controls.target.clone()]; const startTime = performance.now(); return new Promise((resolve) => (function animate() { const t = Math.min((performance.now() - startTime) / 500, 1); camera.position.lerpVectors(startPosition, targetPosition, t); controls.target.lerpVectors(startLookAt, targetLookAt, t); controls.update(); t < 1 ? requestAnimationFrame(animate) : resolve(); })()); } function getRootObject(mesh) { if (mesh.type === "Scene" || mesh.parent.type === "Scene") return mesh; return getRootObject(mesh.parent); } function name(mesh) { if (mesh.name) return mesh.name; else if (mesh.isGroup && mesh.uuid) return `group: ${mesh.uuid}`; else if (mesh.uuid) return mesh.uuid; return "N/A"; }