Spaces:
Sleeping
Sleeping
Commit Β·
b75c304
1
Parent(s): a1cf96b
feat(ui): Detailed 3D upgrades - typed geometries, glowing tubes, dynamic camera tracking
Browse files- static/viz3d.html +26 -11
static/viz3d.html
CHANGED
|
@@ -269,6 +269,7 @@ scene.add(grid);
|
|
| 269 |
// ββ Orbit controls (manual) βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 270 |
let sph = { theta: 0, phi: 1.1, r: 24 };
|
| 271 |
let orbitAuto = false, dragging = false, lastX = 0, lastY = 0;
|
|
|
|
| 272 |
|
| 273 |
canvas.addEventListener('mousedown', e => { dragging = true; lastX = e.clientX; lastY = e.clientY; });
|
| 274 |
window.addEventListener('mouseup', () => { dragging = false; });
|
|
@@ -287,11 +288,11 @@ function updateCamera() {
|
|
| 287 |
if (orbitAuto) sph.theta += 0.004;
|
| 288 |
const sin_p = Math.sin(sph.phi);
|
| 289 |
camera.position.set(
|
| 290 |
-
sph.r * sin_p * Math.sin(sph.theta),
|
| 291 |
-
sph.r * Math.cos(sph.phi),
|
| 292 |
-
sph.r * sin_p * Math.cos(sph.theta)
|
| 293 |
);
|
| 294 |
-
camera.lookAt(
|
| 295 |
}
|
| 296 |
|
| 297 |
// ββ Scene state βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -338,14 +339,19 @@ function buildScene(data) {
|
|
| 338 |
f.type === 'spec' ? COLS.spec : COLS.src;
|
| 339 |
const col = new THREE.Color(baseColor);
|
| 340 |
|
| 341 |
-
//
|
| 342 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 343 |
const mat = new THREE.MeshPhongMaterial({
|
| 344 |
color: col, emissive: col.clone().multiplyScalar(0.25),
|
| 345 |
-
shininess:
|
| 346 |
});
|
| 347 |
const mesh = new THREE.Mesh(geo, mat);
|
| 348 |
mesh.position.copy(pos);
|
|
|
|
| 349 |
mesh.userData = { file: f, basePos: pos.clone() };
|
| 350 |
scene.add(mesh);
|
| 351 |
|
|
@@ -458,11 +464,16 @@ function applyStep(idx) {
|
|
| 458 |
}
|
| 459 |
}
|
| 460 |
|
| 461 |
-
// Draw path
|
| 462 |
if (pathPts.length >= 2) {
|
| 463 |
-
|
| 464 |
-
const
|
| 465 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
scene.add(line); pathLines.push(line);
|
| 467 |
}
|
| 468 |
|
|
@@ -576,7 +587,11 @@ function updateLabel(s, m) { document.getElementById('step-label').textContent =
|
|
| 576 |
function animate() {
|
| 577 |
requestAnimationFrame(animate);
|
| 578 |
frame++;
|
|
|
|
|
|
|
|
|
|
| 579 |
updateCamera();
|
|
|
|
| 580 |
// Pulsing & moving agent (seamless flow)
|
| 581 |
if (agentMesh) {
|
| 582 |
agentMesh.position.lerp(targetAgentPos, 0.08); // Smooth transition
|
|
|
|
| 269 |
// ββ Orbit controls (manual) βββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 270 |
let sph = { theta: 0, phi: 1.1, r: 24 };
|
| 271 |
let orbitAuto = false, dragging = false, lastX = 0, lastY = 0;
|
| 272 |
+
let lookTarget = new THREE.Vector3(0,0,0);
|
| 273 |
|
| 274 |
canvas.addEventListener('mousedown', e => { dragging = true; lastX = e.clientX; lastY = e.clientY; });
|
| 275 |
window.addEventListener('mouseup', () => { dragging = false; });
|
|
|
|
| 288 |
if (orbitAuto) sph.theta += 0.004;
|
| 289 |
const sin_p = Math.sin(sph.phi);
|
| 290 |
camera.position.set(
|
| 291 |
+
sph.r * sin_p * Math.sin(sph.theta) + lookTarget.x,
|
| 292 |
+
sph.r * Math.cos(sph.phi) + (lookTarget.y * 0.3),
|
| 293 |
+
sph.r * sin_p * Math.cos(sph.theta) + lookTarget.z
|
| 294 |
);
|
| 295 |
+
camera.lookAt(lookTarget);
|
| 296 |
}
|
| 297 |
|
| 298 |
// ββ Scene state βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
| 339 |
f.type === 'spec' ? COLS.spec : COLS.src;
|
| 340 |
const col = new THREE.Color(baseColor);
|
| 341 |
|
| 342 |
+
// Diverse Geometries
|
| 343 |
+
let geo;
|
| 344 |
+
if (f.type === 'test') { geo = new THREE.CylinderGeometry(0.5, 0.5, 0.8, 6); } // Hex prism
|
| 345 |
+
else if (f.type === 'spec') { geo = new THREE.OctahedronGeometry(0.65); } // Diamond
|
| 346 |
+
else { geo = new THREE.BoxGeometry(0.85, 0.85, 0.85); } // Code block Cube
|
| 347 |
+
|
| 348 |
const mat = new THREE.MeshPhongMaterial({
|
| 349 |
color: col, emissive: col.clone().multiplyScalar(0.25),
|
| 350 |
+
shininess: 90, transparent: true, opacity: 0.85, flatShading: true
|
| 351 |
});
|
| 352 |
const mesh = new THREE.Mesh(geo, mat);
|
| 353 |
mesh.position.copy(pos);
|
| 354 |
+
if (f.type !== 'src') { mesh.rotation.x = 0.2; mesh.rotation.z = Math.random() * 0.5; }
|
| 355 |
mesh.userData = { file: f, basePos: pos.clone() };
|
| 356 |
scene.add(mesh);
|
| 357 |
|
|
|
|
| 464 |
}
|
| 465 |
}
|
| 466 |
|
| 467 |
+
// Draw precision tube path
|
| 468 |
if (pathPts.length >= 2) {
|
| 469 |
+
// Add an exact curve mapping
|
| 470 |
+
const curve = new THREE.CatmullRomCurve3(pathPts);
|
| 471 |
+
const geo = new THREE.TubeGeometry(curve, pathPts.length * 8, 0.045, 8, false);
|
| 472 |
+
const mat = new THREE.MeshPhongMaterial({
|
| 473 |
+
color: COLS.path, emissive: COLS.path, emissiveIntensity: 0.6,
|
| 474 |
+
transparent: true, opacity: 0.8
|
| 475 |
+
});
|
| 476 |
+
const line = new THREE.Mesh(geo, mat);
|
| 477 |
scene.add(line); pathLines.push(line);
|
| 478 |
}
|
| 479 |
|
|
|
|
| 587 |
function animate() {
|
| 588 |
requestAnimationFrame(animate);
|
| 589 |
frame++;
|
| 590 |
+
|
| 591 |
+
// Dynamic camera focal tracking
|
| 592 |
+
lookTarget.lerp(targetAgentPos, 0.03);
|
| 593 |
updateCamera();
|
| 594 |
+
|
| 595 |
// Pulsing & moving agent (seamless flow)
|
| 596 |
if (agentMesh) {
|
| 597 |
agentMesh.position.lerp(targetAgentPos, 0.08); // Smooth transition
|