From d40c9bf997cf7bc0c5de25de9baa8c95975f68eb Mon Sep 17 00:00:00 2001 From: Alexander Whitestone Date: Tue, 24 Mar 2026 00:07:35 -0400 Subject: [PATCH] feat: add Timmy avatar as floating geometric form near terminal hub - Add dual-layer icosahedron (core + wireframe shell) at position (1.6, 0.4, 0) - Core rotates on X/Y axes with bobbing float animation - Shell counter-rotates for holographic depth effect - Both layers pulse opacity using sine wave - Colors use new NEXUS.colors.avatarCore/avatarGlow palette entries Fixes #128 --- app.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/app.js b/app.js index 5a028f6..3d66a79 100644 --- a/app.js +++ b/app.js @@ -9,6 +9,8 @@ const NEXUS = { constellationLine: 0x334488, constellationFade: 0x112244, accent: 0x4488ff, + avatarCore: 0x66aaff, + avatarGlow: 0x2255cc, } }; @@ -112,6 +114,31 @@ function buildConstellationLines() { const constellationLines = buildConstellationLines(); scene.add(constellationLines); +// === TIMMY AVATAR === +// A floating icosahedron representing Timmy's presence near the terminal hub. +const avatarGeo = new THREE.IcosahedronGeometry(0.55, 1); +const avatarMat = new THREE.MeshBasicMaterial({ + color: NEXUS.colors.avatarCore, + wireframe: true, + transparent: true, + opacity: 0.85, +}); +const timmyAvatar = new THREE.Mesh(avatarGeo, avatarMat); +timmyAvatar.position.set(1.6, 0.4, 0); +scene.add(timmyAvatar); + +// Outer shell — slightly larger wireframe for holographic depth +const avatarShellGeo = new THREE.IcosahedronGeometry(0.8, 1); +const avatarShellMat = new THREE.MeshBasicMaterial({ + color: NEXUS.colors.avatarGlow, + wireframe: true, + transparent: true, + opacity: 0.25, +}); +const timmyShell = new THREE.Mesh(avatarShellGeo, avatarShellMat); +timmyShell.position.copy(timmyAvatar.position); +scene.add(timmyShell); + // === MOUSE-DRIVEN ROTATION === let mouseX = 0; let mouseY = 0; @@ -182,6 +209,17 @@ function animate() { // Subtle pulse on constellation opacity constellationLines.material.opacity = 0.12 + Math.sin(elapsed * 0.5) * 0.06; + // Timmy avatar — float, rotate, and pulse + const floatY = Math.sin(elapsed * 0.8) * 0.12; + timmyAvatar.position.y = 0.4 + floatY; + timmyShell.position.y = timmyAvatar.position.y; + timmyAvatar.rotation.y = elapsed * 0.6; + timmyAvatar.rotation.x = elapsed * 0.3; + timmyShell.rotation.y = -elapsed * 0.4; + timmyShell.rotation.x = elapsed * 0.2; + timmyAvatar.material.opacity = 0.7 + Math.sin(elapsed * 1.2) * 0.15; + timmyShell.material.opacity = 0.15 + Math.sin(elapsed * 0.9 + 1) * 0.1; + renderer.render(scene, camera); } -- 2.43.0