[gemini] Implement ArchonAssembler with primitive shapes (#530) #536

Merged
gemini merged 1 commits from gemini/issue-530 into main 2026-03-25 18:07:32 +00:00
2 changed files with 232 additions and 0 deletions

19
app.js
View File

@@ -3,6 +3,7 @@ import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
import { SMAAPass } from 'three/addons/postprocessing/SMAAPass.js';
import { ArchonAssembler } from './archon_assembler.js';
// ═══════════════════════════════════════════
// NEXUS v2.0 — WebSocket Bridge to Timmy
@@ -47,6 +48,7 @@ let frameCount = 0, lastFPSTime = 0, fps = 0;
let chatOpen = true;
let loadProgress = 0;
let performanceTier = 'high';
let archonAssembler;
// ═══ COMMIT HEATMAP ═══
let heatmapMesh = null, heatmapMat = null, heatmapTexture = null;
@@ -210,6 +212,23 @@ async function init() {
createDualBrainPanel();
updateLoad(90);
// Test Archon Assembler
const testManifest = {
head: true,
torso: true,
arms: true,
legs: true,
hands: true,
eyes: true,
mouth: true,
wings: true,
aura: true,
crown: true,
};
archonAssembler = new ArchonAssembler(scene, testManifest);
archonAssembler.assemble();
archonAssembler.spawn(new THREE.Vector3(0, 0, -15));
composer = new EffectComposer(renderer);
composer.addPass(new RenderPass(scene, camera));
composer.addPass(new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 0.6, 0.4, 0.85));

213
archon_assembler.js Normal file
View File

@@ -0,0 +1,213 @@
import * as THREE from 'three';
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
import { SMAAPass } from 'three/addons/postprocessing/SMAAPass.js';
// Assuming NEXUS colors are available or passed in
const NEXUS = {
colors: {
primary: 0x4af0c0,
secondary: 0x7b5cff,
bg: 0x050510,
panelBg: 0x0a0f28,
nebula1: 0x1a0a3e,
nebula2: 0x0a1a3e,
gold: 0xffd700,
danger: 0xff4466,
gridLine: 0x1a2a4a,
}
};
class ArchonAssembler {
constructor(scene, manifest) {
this.scene = scene;
this.manifest = manifest;
this.avatarGroup = new THREE.Group();
this.scene.add(this.avatarGroup);
this.parts = {}; // To store references to individual parts
}
_createMaterial(color) {
// Use a material consistent with the wireframe_glow aesthetic
// This will likely be a basic material or shader material that interacts with UnrealBloomPass
return new THREE.MeshBasicMaterial({
color: color,
wireframe: true,
transparent: true,
opacity: 0.8,
// These properties might be needed if not handled by post-processing
// blending: THREE.AdditiveBlending,
// emissive: color,
// emissiveIntensity: 1.5,
});
}
assemble() {
// Clear existing parts if any
while(this.avatarGroup.children.length > 0){
this.avatarGroup.remove(this.avatarGroup.children[0]);
}
this.parts = {};
// Head (SphereGeometry)
if (this.manifest.head) {
const headGeometry = new THREE.SphereGeometry(0.5, 32, 32);
const headMaterial = this._createMaterial(NEXUS.colors.primary);
const head = new THREE.Mesh(headGeometry, headMaterial);
head.position.y = 2; // Example position
this.avatarGroup.add(head);
this.parts.head = head;
}
// Torso (BoxGeometry)
if (this.manifest.torso) {
const torsoGeometry = new THREE.BoxGeometry(1, 1.5, 0.75);
const torsoMaterial = this._createMaterial(NEXUS.colors.secondary);
const torso = new THREE.Mesh(torsoGeometry, torsoMaterial);
torso.position.y = 1; // Example position
this.avatarGroup.add(torso);
this.parts.torso = torso;
}
// Arms (CylinderGeometry) - simple example, will need left/right
if (this.manifest.arms) {
const armGeometry = new THREE.CylinderGeometry(0.15, 0.15, 1, 16);
const armMaterial = this._createMaterial(NEXUS.colors.gold);
const armLeft = new THREE.Mesh(armGeometry, armMaterial);
armLeft.position.set(-0.6, 1.5, 0); // Left arm
armLeft.rotation.z = Math.PI / 2; // Horizontal
this.avatarGroup.add(armLeft);
this.parts.armLeft = armLeft;
const armRight = new THREE.Mesh(armGeometry, armMaterial);
armRight.position.set(0.6, 1.5, 0); // Right arm
armRight.rotation.z = -Math.PI / 2; // Horizontal
this.avatarGroup.add(armRight);
this.parts.armRight = armRight;
}
// Legs (CylinderGeometry) - simple example, will need left/right
if (this.manifest.legs) {
const legGeometry = new THREE.CylinderGeometry(0.2, 0.2, 1.2, 16);
const legMaterial = this._createMaterial(NEXUS.colors.nebula1);
const legLeft = new THREE.Mesh(legGeometry, legMaterial);
legLeft.position.set(-0.3, 0.5, 0); // Left leg
this.avatarGroup.add(legLeft);
this.parts.legLeft = legLeft;
const legRight = new THREE.Mesh(legGeometry, legMaterial);
legRight.position.set(0.3, 0.5, 0); // Right leg
this.avatarGroup.add(legRight);
this.parts.legRight = legRight;
}
// Hands/Fingers (small SphereGeometry clusters) - Placeholder
if (this.manifest.hands) {
const handGeometry = new THREE.SphereGeometry(0.2, 16, 16);
const handMaterial = this._createMaterial(NEXUS.colors.gold);
const handLeft = new THREE.Mesh(handGeometry, handMaterial);
handLeft.position.set(-1.1, 1.5, 0);
this.avatarGroup.add(handLeft);
this.parts.handLeft = handLeft;
const handRight = new THREE.Mesh(handGeometry, handMaterial);
handRight.position.set(1.1, 1.5, 0);
this.avatarGroup.add(handRight);
this.parts.handRight = handRight;
}
// Eyes (emissive small spheres on head) - Placeholder
if (this.manifest.eyes) {
const eyeGeometry = new THREE.SphereGeometry(0.08, 16, 16);
const eyeMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff, emissive: 0xffffff, emissiveIntensity: 2 }); // Emissive for glow
const eyeLeft = new THREE.Mesh(eyeGeometry, eyeMaterial);
eyeLeft.position.set(-0.2, 2.1, 0.45); // Adjust position relative to head
this.avatarGroup.add(eyeLeft);
this.parts.eyeLeft = eyeLeft;
const eyeRight = new THREE.Mesh(eyeGeometry, eyeMaterial);
eyeRight.position.set(0.2, 2.1, 0.45); // Adjust position relative to head
this.avatarGroup.add(eyeRight);
this.parts.eyeRight = eyeRight;
}
// Mouth (torus segment on head) - Placeholder
if (this.manifest.mouth) {
const mouthGeometry = new THREE.TorusGeometry(0.15, 0.03, 8, 16, Math.PI); // Half torus
const mouthMaterial = this._createMaterial(NEXUS.colors.primary);
const mouth = new THREE.Mesh(mouthGeometry, mouthMaterial);
mouth.position.set(0, 1.8, 0.5); // Adjust position relative to head
mouth.rotation.x = Math.PI / 2;
this.avatarGroup.add(mouth);
this.parts.mouth = mouth;
}
// Wings (PlaneGeometry with wireframe) - Placeholder
if (this.manifest.wings) {
const wingGeometry = new THREE.PlaneGeometry(2, 1.5);
const wingMaterial = this._createMaterial(NEXUS.colors.nebula2);
const wingLeft = new THREE.Mesh(wingGeometry, wingMaterial);
wingLeft.position.set(-1.2, 2, -0.2);
wingLeft.rotation.y = Math.PI / 2;
this.avatarGroup.add(wingLeft);
this.parts.wingLeft = wingLeft;
const wingRight = new THREE.Mesh(wingGeometry, wingMaterial);
wingRight.position.set(1.2, 2, -0.2);
wingRight.rotation.y = -Math.PI / 2;
this.avatarGroup.add(wingRight);
this.parts.wingRight = wingRight;
}
// Aura (transparent SphereGeometry around body) - Placeholder
if (this.manifest.aura) {
const auraGeometry = new THREE.SphereGeometry(2, 32, 32);
const auraMaterial = new THREE.MeshBasicMaterial({
color: NEXUS.colors.primary,
transparent: true,
opacity: 0.1,
side: THREE.BackSide, // Render inside out
blending: THREE.AdditiveBlending,
});
const aura = new THREE.Mesh(auraGeometry, auraMaterial);
aura.position.y = 1.5;
this.avatarGroup.add(aura);
this.parts.aura = aura;
}
// Crown (TorusGeometry above head) - Placeholder
if (this.manifest.crown) {
const crownGeometry = new THREE.TorusGeometry(0.6, 0.05, 8, 32);
const crownMaterial = this._createMaterial(NEXUS.colors.gold);
const crown = new THREE.Mesh(crownGeometry, crownMaterial);
crown.position.y = 2.6;
this.avatarGroup.add(crown);
this.parts.crown = crown;
}
}
spawn(position) {
this.avatarGroup.position.copy(position);
this.avatarGroup.visible = true; // Make the group visible
// TODO: Implement materialization animation
console.log("Archon spawned at", position);
}
remove() {
this.avatarGroup.visible = false; // Hide the group
// TODO: Implement de-materialization animation
console.log("Archon removed");
}
updateManifest(newManifest) {
this.manifest = newManifest;
this.assemble(); // Re-assemble with new parts
console.log("Archon manifest updated");
}
}
export { ArchonAssembler };