Factory function to create Gem-Portal Shimmer Key in your world.
export function createAsset(THREE, options = {}) {
const group = new THREE.Group();
group.name = 'Gem-Portal Shimmer Key';
const length = Math.max(0.7, Math.min(1.4, Number(options.length ?? 1)));
const thickness = Math.max(0.75, Math.min(1.35, Number(options.thickness ?? 1)));
const gemColor = options.gemColor || '#53E8FF';
const accentColor = options.accentColor || '#C99CFF';
const haloAlpha = Math.max(0.15, Math.min(0.85, Number(options.haloAlpha ?? 0.55)));
const showSparkles = options.showSparkles !== false;
const darkMetal = new THREE.MeshStandardMaterial({ color: '#181A29', roughness: 0.48, metalness: 0.32 });
const edgeMetal = new THREE.MeshStandardMaterial({ color: '#282F4B', roughness: 0.42, metalness: 0.38 });
const gemMat = new THREE.MeshStandardMaterial({ color: gemColor, emissive: new THREE.Color(gemColor), emissiveIntensity: 0.45, roughness: 0.28, metalness: 0.08 });
const haloMat = new THREE.MeshStandardMaterial({ color: accentColor, emissive: new THREE.Color(accentColor), emissiveIntensity: 0.35, roughness: 0.35, metalness: 0.05, transparent: true, opacity: haloAlpha });
const glowMat = new THREE.MeshStandardMaterial({ color: '#FFFFFF', emissive: new THREE.Color(gemColor), emissiveIntensity: 0.55, roughness: 0.5, metalness: 0, transparent: true, opacity: 0.78 });
function box(partId, name, size, position, material) {
const mesh = new THREE.Mesh(new THREE.BoxGeometry(size[0], size[1], size[2]), material);
mesh.position.set(position[0], position[1], position[2]);
mesh.name = name;
mesh.userData.partId = partId;
return mesh;
}
const swayPivot = new THREE.Group();
swayPivot.name = 'local-sway-pivot';
swayPivot.userData.partId = 'local-sway-pivot';
group.add(swayPivot);
const haloLoop = new THREE.Group();
haloLoop.name = 'halo-loop';
haloLoop.userData.partId = 'halo-loop';
haloLoop.add(box('halo-loop-top', 'halo loop top bar', [0.78 * thickness, 0.12 * thickness, 0.2 * thickness], [0, 1.02 * length, 0], haloMat));
haloLoop.add(box('halo-loop-left', 'halo loop left bar', [0.12 * thickness, 0.5 * thickness, 0.2 * thickness], [-0.33 * thickness, 0.78 * length, 0], haloMat));
haloLoop.add(box('halo-loop-right', 'halo loop right bar', [0.12 * thickness, 0.5 * thickness, 0.2 * thickness], [0.33 * thickness, 0.78 * length, 0], haloMat));
haloLoop.add(box('halo-loop-bottom', 'halo loop bottom bar', [0.52 * thickness, 0.12 * thickness, 0.2 * thickness], [0, 0.54 * length, 0], haloMat));
swayPivot.add(haloLoop);
const shaft = box('main-shaft', 'main shaft', [0.18 * thickness, 1.18 * length, 0.22 * thickness], [0, -0.05 * length, 0], darkMetal);
swayPivot.add(shaft);
const spineHighlight = box('shaft-highlight', 'thin cyan shaft highlight', [0.06 * thickness, 0.9 * length, 0.235 * thickness], [0.065 * thickness, 0.01 * length, 0.012 * thickness], gemMat);
swayPivot.add(spineHighlight);
const gemCore = box('gem-core', 'square portal gem', [0.28 * thickness, 0.28 * thickness, 0.28 * thickness], [0, 0.38 * length, 0.08 * thickness], gemMat);
gemCore.rotation.z = Math.PI / 4;
swayPivot.add(gemCore);
const nodule = new THREE.Group();
nodule.name = 'nodule';
nodule.userData.partId = 'nodule';
nodule.add(box('nodule-base', 'lower sync nodule', [0.38 * thickness, 0.18 * thickness, 0.22 * thickness], [0, -0.78 * length, 0], edgeMetal));
nodule.add(box('nodule-tooth-left', 'left key tooth', [0.18 * thickness, 0.2 * thickness, 0.22 * thickness], [-0.18 * thickness, -0.94 * length, 0], edgeMetal));
nodule.add(box('nodule-tooth-right', 'right key tooth', [0.18 * thickness, 0.12 * thickness, 0.22 * thickness], [0.19 * thickness, -0.91 * length, 0], edgeMetal));
swayPivot.add(nodule);
if (showSparkles) {
const sparklets = new THREE.Group();
sparklets.name = 'sparklets';
sparklets.userData.partId = 'sparklets';
const points = [[-0.52, 0.28, 0.04], [0.5, -0.18, 0.04], [0.42, 0.78, 0.04]];
for (let i = 0; i < points.length; i++) {
const p = points[i];
const s = box('sparklet-' + (i + 1), 'tiny shimmer chip ' + (i + 1), [0.1 * thickness, 0.1 * thickness, 0.08 * thickness], [p[0] * thickness, p[1] * length, p[2]], glowMat);
s.rotation.z = Math.PI / 4;
sparklets.add(s);
}
swayPivot.add(sparklets);
}
const shadowFoot = box('soft-shadow-foot', 'small grounding shadow', [0.72 * thickness, 0.04, 0.26 * thickness], [0, -1.12 * length, -0.08 * thickness], new THREE.MeshStandardMaterial({ color: '#10121C', roughness: 0.8, metalness: 0, transparent: true, opacity: 0.35 }));
group.add(shadowFoot);
group.userData.selection = { id: 'gem-portal-shimmer-key', kind: 'asset', label: 'Gem-Portal Shimmer Key' };
return group;
}