◇
loading geometry…
Generic
1RU placeholder
MDL-0331
here was a sink fed by model_url; the
// column is CHECK-constrained to https:// and admin-set, which made it low
// risk and not no risk. Reading an attribute has no such edge.
const canvas = document.getElementById("glbCanvas");
const SRC = canvas.dataset.src;
const holder = document.getElementById("glbView");
const fallback = document.getElementById("glbFallback");
const status = document.getElementById("glbStatus");
// Any failure leaves the glyph exactly as it was.
const fail = (why) => { canvas.style.display = "none"; status.textContent = why; };
try {
const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true });
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
renderer.setSize(holder.clientWidth, holder.clientHeight, false);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, holder.clientWidth / holder.clientHeight, 0.01, 1000);
scene.add(new THREE.HemisphereLight(0xbfd4ff, 0x0a0a12, 2.2));
const key = new THREE.DirectionalLight(0xffffff, 2.0); key.position.set(2, 3, 2); scene.add(key);
const rim = new THREE.DirectionalLight(0x00ff88, 0.7); rim.position.set(-2, 1, -2); scene.add(rim);
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true; controls.enablePan = false;
new GLTFLoader().load(SRC, (gltf) => {
const root = gltf.scene;
// This ghost carries no materials and no normals (trimesh export), so
// both are supplied here. Without computed normals the lighting is flat
// and the shape reads as a silhouette.
root.traverse((o) => {
if (!o.isMesh) return;
if (!o.geometry.attributes.normal) o.geometry.computeVertexNormals();
o.material = new THREE.MeshStandardMaterial({ color: 0x8a94a6, metalness: 0.15, roughness: 0.65 });
});
// Frame whatever arrived rather than assuming a scale: a 1RU panel and a
// 40RU rack are three orders of magnitude apart in bounding box.
const box = new THREE.Box3().setFromObject(root);
const size = box.getSize(new THREE.Vector3());
const centre = box.getCenter(new THREE.Vector3());
const maxDim = Math.max(size.x, size.y, size.z) || 1;
const dist = (maxDim / 2) / Math.tan((camera.fov * Math.PI / 180) / 2);
root.position.sub(centre);
scene.add(root);
camera.position.set(dist * 0.9, dist * 0.55, dist * 1.15);
camera.near = dist / 100; camera.far = dist * 100; camera.updateProjectionMatrix();
controls.target.set(0, 0, 0); controls.update();
canvas.style.display = "block";
fallback.style.display = "none";
status.textContent = "GLB · drag to rotate";
}, undefined, () => fail("geometry unavailable"));
addEventListener("resize", () => {
renderer.setSize(holder.clientWidth, holder.clientHeight, false);
camera.aspect = holder.clientWidth / holder.clientHeight;
camera.updateProjectionMatrix();
});
(function loop() { requestAnimationFrame(loop); controls.update(); renderer.render(scene, camera); })();
} catch (e) {
fail("3D preview unavailable");
}
MDL-0331 ·
Ethernet Switch
Nominal specification for a rack-mounted Ethernet switch. Derived from 45 catalogued products across 13 brands, 42 of which record a rack height and all of them 1RU. Not a manufacturer product and not modelled on one.
Properties
GLB
Untextured
No Normals
File not yet available for download.