[gemini] Implement ArchonAssembler with primitive shapes (#530) #536
19
app.js
19
app.js
@@ -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
213
archon_assembler.js
Normal 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 };
|
||||
Reference in New Issue
Block a user