Factory function to create Cat Face Bomb Boss in your world.
export function createAsset(THREE, options = {}) {
const group = new THREE.Group();
group.name = 'Cat Face Bomb Boss';
group.userData.selection = { id: 'cat_bomb_boss', kind: 'asset', label: 'Cat Face Bomb Boss' };
const shellColor = options.shellColor || '#202331';
const maskColor = options.maskColor || '#fff4dc';
const coreColor = options.coreColor || '#19d6c8';
const warningColor = options.warningColor || '#ffd447';
const dangerPink = options.dangerPink || '#ff6aa2';
const showSpikeBand = options.showSpikeBand !== false;
const shellMat = new THREE.MeshStandardMaterial({ color: shellColor, roughness: 0.72, metalness: 0.08 });
const maskMat = new THREE.MeshStandardMaterial({ color: maskColor, roughness: 0.62, metalness: 0.02 });
const coreMat = new THREE.MeshStandardMaterial({ color: coreColor, roughness: 0.36, metalness: 0.1, emissive: new THREE.Color(coreColor), emissiveIntensity: 0.35 });
const warningMat = new THREE.MeshStandardMaterial({ color: warningColor, roughness: 0.5, metalness: 0.05 });
const dangerMat = new THREE.MeshStandardMaterial({ color: dangerPink, roughness: 0.45, metalness: 0.05 });
const metalMat = new THREE.MeshStandardMaterial({ color: '#8f98a3', roughness: 0.38, metalness: 0.48 });
const darkLineMat = new THREE.MeshStandardMaterial({ color: '#11131d', roughness: 0.6, metalness: 0.04 });
function tag(obj, partId, label) {
obj.userData.partId = partId;
obj.userData.selection = { id: partId, kind: 'part', label };
return obj;
}
const shell = tag(new THREE.Group(), 'outerShell', 'Outer Shell');
shell.name = 'outerShell';
group.add(shell);
const body = new THREE.Mesh(new THREE.SphereGeometry(2.45, 12, 8), shellMat);
body.name = 'outerShell_body';
body.scale.set(1.08, 1.0, 1.16);
body.position.set(0, 2.95, 0);
shell.add(body);
const topCap = new THREE.Mesh(new THREE.BoxGeometry(1.25, 0.42, 1.25), metalMat);
topCap.name = 'outerShell_top_cap';
topCap.position.set(0, 5.44, 0);
shell.add(topCap);
const faceMask = tag(new THREE.Group(), 'faceMask', 'Cat Face Mask');
faceMask.name = 'faceMask';
faceMask.position.set(0, 3.18, -2.72);
group.add(faceMask);
const maskBase = new THREE.Mesh(new THREE.BoxGeometry(3.38, 2.44, 0.34), maskMat);
maskBase.name = 'faceMask_plate';
faceMask.add(maskBase);
const leftEar = new THREE.Mesh(new THREE.BoxGeometry(0.82, 0.98, 0.36), maskMat);
leftEar.name = 'faceMask_left_ear';
leftEar.position.set(-1.16, 1.44, 0);
leftEar.rotation.z = -0.45;
faceMask.add(leftEar);
const rightEar = leftEar.clone();
rightEar.name = 'faceMask_right_ear';
rightEar.position.x = 1.16;
rightEar.rotation.z = 0.45;
faceMask.add(rightEar);
const leftBrow = new THREE.Mesh(new THREE.BoxGeometry(0.86, 0.16, 0.12), dangerMat);
leftBrow.name = 'faceMask_left_red_lightning_brow';
leftBrow.position.set(-0.72, 0.48, -0.22);
leftBrow.rotation.z = -0.24;
faceMask.add(leftBrow);
const rightBrow = leftBrow.clone();
rightBrow.name = 'faceMask_right_red_lightning_brow';
rightBrow.position.x = 0.72;
rightBrow.rotation.z = 0.24;
faceMask.add(rightBrow);
const leftEye = new THREE.Mesh(new THREE.BoxGeometry(0.46, 0.22, 0.14), darkLineMat);
leftEye.name = 'faceMask_left_eye';
leftEye.position.set(-0.72, 0.12, -0.25);
faceMask.add(leftEye);
const rightEye = leftEye.clone();
rightEye.name = 'faceMask_right_eye';
rightEye.position.x = 0.72;
faceMask.add(rightEye);
const mouthEdge = new THREE.Mesh(new THREE.BoxGeometry(1.16, 0.16, 0.14), dangerMat);
mouthEdge.name = 'faceMask_red_lightning_mouth_edge';
mouthEdge.position.set(0, -0.62, -0.25);
faceMask.add(mouthEdge);
const nose = new THREE.Mesh(new THREE.BoxGeometry(0.28, 0.24, 0.16), dangerMat);
nose.name = 'faceMask_pink_danger_nose';
nose.position.set(0, -0.16, -0.28);
faceMask.add(nose);
const coreRing = tag(new THREE.Group(), 'coreRing', 'Teal Core Ring');
coreRing.name = 'coreRing';
coreRing.position.set(0, 2.06, -2.9);
group.add(coreRing);
const ringOuter = new THREE.Mesh(new THREE.CylinderGeometry(0.78, 0.78, 0.24, 12), metalMat);
ringOuter.name = 'coreRing_metal_ring';
ringOuter.rotation.x = Math.PI / 2;
coreRing.add(ringOuter);
const ringCore = new THREE.Mesh(new THREE.BoxGeometry(0.88, 0.88, 0.18), coreMat);
ringCore.name = 'coreRing_glowing_core';
ringCore.position.set(0, 0, -0.12);
coreRing.add(ringCore);
const spikeBand = tag(new THREE.Group(), 'spikeBand', 'Spike Band');
spikeBand.name = 'spikeBand';
spikeBand.visible = showSpikeBand;
spikeBand.position.set(0, 3.0, 0);
group.add(spikeBand);
for (let i = 0; i < 12; i++) {
const angle = (i / 12) * Math.PI * 2;
const spike = new THREE.Mesh(new THREE.BoxGeometry(0.34, 0.62, 0.72), warningMat);
spike.name = 'spikeBand_warning_spike_' + i;
spike.position.set(Math.sin(angle) * 2.78, 0, Math.cos(angle) * 2.96);
spike.rotation.y = angle;
spikeBand.add(spike);
}
const ribGroup = tag(new THREE.Group(), 'metalRibs', 'Side Metal Ribs');
ribGroup.name = 'metalRibs';
group.add(ribGroup);
[-1, 1].forEach((side) => {
for (let i = 0; i < 3; i++) {
const rib = new THREE.Mesh(new THREE.BoxGeometry(0.22, 3.2, 0.34), metalMat);
rib.name = (side < 0 ? 'left' : 'right') + '_metal_rib_' + i;
rib.position.set(side * 2.68, 2.95, -0.84 + i * 0.84);
rib.rotation.z = side * 0.09;
ribGroup.add(rib);
}
});
const underRim = tag(new THREE.Group(), 'underRim', 'Under Rim');
underRim.name = 'underRim';
underRim.position.set(0, 0.72, 0);
group.add(underRim);
const rim = new THREE.Mesh(new THREE.CylinderGeometry(2.08, 2.32, 0.42, 12), metalMat);
rim.name = 'underRim_metal_rim';
underRim.add(rim);
for (let i = 0; i < 4; i++) {
const foot = new THREE.Mesh(new THREE.BoxGeometry(0.62, 0.42, 0.62), shellMat);
foot.name = 'underRim_stub_foot_' + i;
foot.position.set((i < 2 ? -1 : 1) * 1.08, -0.42, (i % 2 === 0 ? -1 : 1) * 1.34);
underRim.add(foot);
}
const warningBolt = new THREE.Mesh(new THREE.BoxGeometry(0.28, 0.92, 0.18), warningMat);
warningBolt.name = 'outerShell_front_yellow_warning_point';
warningBolt.position.set(0, 4.28, -2.58);
warningBolt.rotation.z = 0.32;
shell.add(warningBolt);
return group;
}