214 lines
8.5 KiB
JavaScript
214 lines
8.5 KiB
JavaScript
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 };
|