{ "buildGorillaCharacter": "function buildGorillaCharacter(materials) {\n const geos = getCharacterGeometry('gorilla');\n const group = new THREE.Group();\n const parts = {};\n parts.body = addPart(group, geos.body, materials.primary, 0, 0.72, 0, 'body');\n parts.chest = addPart(group, geos.chest, materials.secondary, 0, 0.67, 0.34, 'chest');\n parts.head = addPart(group, geos.head, materials.primary, 0, 1.38, 0.08, 'head');\n addPart(group, geos.brow, materials.primary, 0, 1.5, 0.28, 'brow');\n addPart(group, geos.muzzle, materials.secondary, 0, 1.24, 0.34, 'muzzle');\n addPart(group, geos.eye, materials.eye, -0.14, 1.33, 0.38, 'eye_l');\n addPart(group, geos.eye, materials.eye, 0.14, 1.33, 0.38, 'eye_r');\n parts.armL = addPart(group, geos.arm, materials.primary, -0.62, 0.48, 0.04, 'arm_l');\n parts.armR = addPart(group, geos.arm, materials.primary, 0.62, 0.48, 0.04, 'arm_r');\n parts.legL = addPart(group, geos.leg, materials.primary, -0.22, 0.18, 0, 'leg_l');\n parts.legR = addPart(group, geos.leg, materials.primary, 0.22, 0.18, 0, 'leg_r');\n group.userData.parts = parts;\n return group;\n}", "buildPandaCharacter": "function buildPandaCharacter(materials) {\n const geos = getCharacterGeometry('panda');\n const group = new THREE.Group();\n const parts = {};\n parts.body = addPart(group, geos.body, materials.primary, 0, 0.72, 0, 'body');\n addPart(group, geos.belly, materials.secondary, 0, 0.66, 0.34, 'belly');\n parts.head = addPart(group, geos.head, materials.primary, 0, 1.36, 0.08, 'head');\n addPart(group, geos.ear, materials.secondary, -0.26, 1.68, 0.02, 'ear_l');\n addPart(group, geos.ear, materials.secondary, 0.26, 1.68, 0.02, 'ear_r');\n addPart(group, geos.snout, materials.secondary, 0, 1.24, 0.34, 'snout');\n addPart(group, geos.eye, materials.secondary, -0.16, 1.34, 0.36, 'eye_l');\n addPart(group, geos.eye, materials.secondary, 0.16, 1.34, 0.36, 'eye_r');\n parts.armL = addPart(group, geos.arm, materials.secondary, -0.52, 0.56, 0.02, 'arm_l');\n parts.armR = addPart(group, geos.arm, materials.secondary, 0.52, 0.56, 0.02, 'arm_r');\n parts.legL = addPart(group, geos.leg, materials.secondary, -0.2, 0.16, 0, 'leg_l');\n parts.legR = addPart(group, geos.leg, materials.secondary, 0.2, 0.16, 0, 'leg_r');\n parts.scarf = addPart(group, geos.scarf, materials.accent, 0, 1.02, 0.2, 'scarf');\n parts.scarfTail = addPart(group, geos.scarfTail, materials.accent, 0.22, 0.86, 0.22, 'scarf_tail');\n group.userData.parts = parts;\n return group;\n}", "buildChameleonCharacter": "function buildChameleonCharacter(materials) {\n const geos = getCharacterGeometry('chameleon');\n const group = new THREE.Group();\n const parts = {};\n parts.body = addPart(group, geos.body, materials.primary, 0, 0.62, 0, 'body');\n addPart(group, geos.belly, materials.secondary, 0, 0.58, 0.24, 'belly');\n parts.head = addPart(group, geos.head, materials.primary, 0, 1.12, 0.14, 'head');\n addPart(group, geos.crest, materials.accent, 0, 1.34, 0.06, 'crest');\n addPart(group, geos.eye, materials.eye, -0.12, 1.18, 0.28, 'eye_l');\n addPart(group, geos.eye, materials.eye, 0.12, 1.18, 0.28, 'eye_r');\n parts.armL = addPart(group, geos.arm, materials.primary, -0.42, 0.54, 0.06, 'arm_l');\n parts.armR = addPart(group, geos.arm, materials.primary, 0.42, 0.54, 0.06, 'arm_r');\n parts.legL = addPart(group, geos.leg, materials.primary, -0.16, 0.2, 0.06, 'leg_l');\n parts.legR = addPart(group, geos.leg, materials.primary, 0.16, 0.2, 0.06, 'leg_r');\n parts.tailBase = addPart(group, geos.tailBase, materials.secondary, 0, 0.64, -0.34, 'tail_base');\n parts.tailTip = addPart(group, geos.tailTip, materials.accent, 0, 0.64, -0.68, 'tail_tip');\n group.userData.parts = parts;\n return group;\n}", "buildBisonCharacter": "function buildBisonCharacter(materials) {\n const geos = getCharacterGeometry('bison');\n const group = new THREE.Group();\n const parts = {};\n parts.body = addPart(group, geos.body, materials.primary, 0, 0.72, 0, 'body');\n parts.hump = addPart(group, geos.hump, materials.secondary, 0, 1.0, -0.1, 'hump');\n parts.head = addPart(group, geos.head, materials.secondary, 0, 1.2, 0.26, 'head');\n addPart(group, geos.muzzle, materials.accent, 0, 1.08, 0.48, 'muzzle');\n addPart(group, geos.eye, materials.eye, -0.14, 1.22, 0.42, 'eye_l');\n addPart(group, geos.eye, materials.eye, 0.14, 1.22, 0.42, 'eye_r');\n addPart(group, geos.horn, materials.accent, -0.22, 1.42, 0.24, 'horn_l', { rotation: { x: 0, y: 0, z: 0.4 } });\n addPart(group, geos.horn, materials.accent, 0.22, 1.42, 0.24, 'horn_r', { rotation: { x: 0, y: 0, z: -0.4 } });\n parts.armL = addPart(group, geos.arm, materials.primary, -0.46, 0.48, 0.08, 'arm_l');\n parts.armR = addPart(group, geos.arm, materials.primary, 0.46, 0.48, 0.08, 'arm_r');\n parts.legL = addPart(group, geos.leg, materials.primary, -0.22, 0.2, 0.04, 'leg_l');\n parts.legR = addPart(group, geos.leg, materials.primary, 0.22, 0.2, 0.04, 'leg_r');\n parts.beard = addPart(group, geos.beard, materials.dark, 0, 0.92, 0.42, 'beard');\n group.userData.parts = parts;\n return group;\n}", "buildSongoku": "function buildSongoku() {\n const group = new THREE.Group();\n\n // Legs\n const legGeo = new THREE.BoxGeometry(0.22, 0.42, 0.24);\n const legMat = createMaterial(PALETTE.martial_blue);\n const legL = new THREE.Mesh(legGeo, legMat);\n legL.position.set(-0.18, 0.21, 0);\n group.add(legL);\n const legR = new THREE.Mesh(legGeo, legMat);\n legR.position.set(0.18, 0.21, 0);\n group.add(legR);\n\n // Body (GI) \u2014 with procedural gi texture\n const bodyGeo = new THREE.BoxGeometry(1.0, 0.88, 0.62);\n const bodyMat = createMaterial(PALETTE.gi_orange);\n const giTex = makeSongokuGiTexture();\n bodyMat.map = giTex;\n bodyMat.map.wrapS = THREE.RepeatWrapping;\n bodyMat.map.wrapT = THREE.RepeatWrapping;\n const body = new THREE.Mesh(bodyGeo, bodyMat);\n body.position.set(0, 0.86, 0);\n group.add(body);\n\n // Arms\n const armGeo = new THREE.BoxGeometry(0.16, 0.52, 0.18);\n const armMat = createMaterial(PALETTE.gi_orange);\n const armL = new THREE.Mesh(armGeo, armMat);\n armL.position.set(-0.58, 0.92, 0);\n group.add(armL);\n const armR = new THREE.Mesh(armGeo, armMat);\n armR.position.set(0.58, 0.92, 0);\n group.add(armR);\n\n // Wrists\n const wristGeo = new THREE.BoxGeometry(0.18, 0.12, 0.20);\n const wristMat = createMaterial(PALETTE.martial_blue);\n const wristL = new THREE.Mesh(wristGeo, wristMat);\n wristL.position.set(-0.58, 0.62, 0);\n group.add(wristL);\n const wristR = new THREE.Mesh(wristGeo, wristMat);\n wristR.position.set(0.58, 0.62, 0);\n group.add(wristR);\n\n // Head\n const headGeo = new THREE.BoxGeometry(0.68, 0.52, 0.56);\n const headMat = createMaterial(PALETTE.skin_tan);\n const head = new THREE.Mesh(headGeo, headMat);\n head.position.set(0, 1.60, 0.04);\n group.add(head);\n\n // Hair main \u2014 with procedural hair texture\n const hairMainGeo = new THREE.BoxGeometry(0.76, 0.34, 0.60);\n const hairMat = createMaterial(PALETTE.dark_black);\n const hairTex = makeSongokuHairTexture();\n hairMat.map = hairTex;\n hairMat.map.wrapS = THREE.RepeatWrapping;\n hairMat.map.wrapT = THREE.RepeatWrapping;\n const hairMain = new THREE.Mesh(hairMainGeo, hairMat);\n hairMain.position.set(0, 1.97, -0.02);\n group.add(hairMain);\n\n // Hair spikes\n const hairSpikeGeo = new THREE.BoxGeometry(0.22, 0.28, 0.18);\n const hairSpikeL = new THREE.Mesh(hairSpikeGeo, hairMat);\n hairSpikeL.position.set(-0.24, 2.24, -0.08);\n group.add(hairSpikeL);\n const hairSpikeR = new THREE.Mesh(hairSpikeGeo, hairMat);\n hairSpikeR.position.set(0.24, 2.20, -0.04);\n group.add(hairSpikeR);\n\n // Eyes\n const eyeGeo = new THREE.BoxGeometry(0.09, 0.09, 0.08);\n const eyeMat = createMaterial(PALETTE.black);\n const eyeL = new THREE.Mesh(eyeGeo, eyeMat);\n eyeL.position.set(-0.14, 1.62, 0.28);\n group.add(eyeL);\n const eyeR = new THREE.Mesh(eyeGeo, eyeMat);\n eyeR.position.set(0.14, 1.62, 0.28);\n group.add(eyeR);\n\n return group;\n}", "buildFallenLog": "function buildFallenLog() {\n const group = new THREE.Group();\n\n // Main body\n const bodyGeo = new THREE.BoxGeometry(2.2, 0.48, 0.62);\n const bodyMat = createMaterial(PALETTE.brown_dark);\n const body = new THREE.Mesh(bodyGeo, bodyMat);\n body.position.set(0, 0.24, 0);\n group.add(body);\n\n // End caps\n const capGeo = new THREE.BoxGeometry(0.18, 0.40, 0.54);\n const capMat = createMaterial(PALETTE.brown_darker);\n const capL = new THREE.Mesh(capGeo, capMat);\n capL.position.set(-1.01, 0.24, 0);\n group.add(capL);\n const capR = new THREE.Mesh(capGeo, capMat);\n capR.position.set(1.01, 0.24, 0);\n group.add(capR);\n\n return group;\n}", "buildSaiyanPod": "function buildSaiyanPod() {\n const group = new THREE.Group();\n\n // Body lower\n const bodyLowerGeo = new THREE.BoxGeometry(1.0, 0.52, 0.90);\n const bodyMat = createMaterial(PALETTE.purple_dark);\n const bodyLower = new THREE.Mesh(bodyLowerGeo, bodyMat);\n bodyLower.position.set(0, 0.76, 0);\n group.add(bodyLower);\n\n // Body upper\n const bodyUpperGeo = new THREE.BoxGeometry(0.82, 0.34, 0.74);\n const bodyUpperMat = createMaterial(PALETTE.purple_mid);\n const bodyUpper = new THREE.Mesh(bodyUpperGeo, bodyUpperMat);\n bodyUpper.position.set(0, 1.19, 0);\n group.add(bodyUpper);\n\n // Fins\n const finGeo = new THREE.BoxGeometry(0.14, 0.30, 0.42);\n const finMat = createMaterial(PALETTE.purple_mid);\n const finL = new THREE.Mesh(finGeo, finMat);\n finL.position.set(-0.57, 0.88, 0);\n group.add(finL);\n const finR = new THREE.Mesh(finGeo, finMat);\n finR.position.set(0.57, 0.88, 0);\n group.add(finR);\n\n // Window front\n const windowGeo = new THREE.BoxGeometry(0.42, 0.24, 0.12);\n const windowMat = createMaterial(PALETTE.threat_red_violet);\n const window = new THREE.Mesh(windowGeo, windowMat);\n window.position.set(0, 0.96, 0.51);\n group.add(window);\n\n return group;\n}", "buildDragonBall": "function buildDragonBall() {\n const group = new THREE.Group();\n\n // Orb bottom\n const orbBottomGeo = new THREE.BoxGeometry(0.34, 0.12, 0.34);\n const orbMat = createMaterial(PALETTE.gold_bright);\n const orbBottom = new THREE.Mesh(orbBottomGeo, orbMat);\n orbBottom.position.set(0, 0.06, 0);\n group.add(orbBottom);\n\n // Orb middle\n const orbMiddleGeo = new THREE.BoxGeometry(0.42, 0.28, 0.42);\n const orbMiddle = new THREE.Mesh(orbMiddleGeo, orbMat);\n orbMiddle.position.set(0, 0.26, 0);\n group.add(orbMiddle);\n\n // Orb top\n const orbTopGeo = new THREE.BoxGeometry(0.34, 0.12, 0.34);\n const orbTop = new THREE.Mesh(orbTopGeo, orbMat);\n orbTop.position.set(0, 0.46, 0);\n group.add(orbTop);\n\n // Star marking\n const starGeo = new THREE.PlaneGeometry(0.12, 0.12);\n const starMat = createMaterial(PALETTE.threat_red_violet);\n const star = new THREE.Mesh(starGeo, starMat);\n star.position.set(0, 0.26, 0.211);\n star.rotation.z = Math.PI / 4;\n group.add(star);\n\n return group;\n}", "buildWastelandTile": "function buildWastelandTile() {\n const group = new THREE.Group();\n\n // Base tile\n const baseTex = makeWastelandTileTexture();\n const baseGeo = new THREE.BoxGeometry(1.0, 0.20, 1.0);\n const baseMat = createMaterial(PALETTE.stone_tan);\n baseMat.map = baseTex;\n baseMat.map.wrapS = THREE.RepeatWrapping;\n baseMat.map.wrapT = THREE.RepeatWrapping;\n const base = new THREE.Mesh(baseGeo, baseMat);\n base.position.set(0, 0.10, 0);\n group.add(base);\n\n // Highlight top slab\n const highlightGeo = new THREE.BoxGeometry(0.96, 0.10, 0.96);\n const highlightMat = createMaterial(PALETTE.warm_sand);\n const highlight = new THREE.Mesh(highlightGeo, highlightMat);\n highlight.position.set(0, 0.25, 0);\n group.add(highlight);\n\n return group;\n}", "buildTournamentWall": "function buildTournamentWall() {\n const group = new THREE.Group();\n\n // Wall body\n const wallTex = makeTournamentWallTexture();\n const wallGeo = new THREE.BoxGeometry(4.0, 1.60, 0.50);\n const wallMat = createMaterial(PALETTE.warm_sand);\n wallMat.map = wallTex;\n wallMat.map.wrapS = THREE.RepeatWrapping;\n wallMat.map.wrapT = THREE.RepeatWrapping;\n const wall = new THREE.Mesh(wallGeo, wallMat);\n wall.position.set(0, 0.80, -14.00);\n group.add(wall);\n\n // Roof cap\n const roofGeo = new THREE.BoxGeometry(4.2, 0.14, 0.70);\n const roofMat = createMaterial(PALETTE.brown_dark);\n const roof = new THREE.Mesh(roofGeo, roofMat);\n roof.position.set(0, 1.67, -14.00);\n group.add(roof);\n\n return group;\n}", "buildStoneMarker": "function buildStoneMarker() {\n const group = new THREE.Group();\n\n // Base\n const baseTex = makeStoneMarkerTexture();\n const baseGeo = new THREE.BoxGeometry(0.52, 0.34, 0.52);\n const baseMat = createMaterial(PALETTE.stone_tan);\n baseMat.map = baseTex;\n baseMat.map.wrapS = THREE.RepeatWrapping;\n baseMat.map.wrapT = THREE.RepeatWrapping;\n const base = new THREE.Mesh(baseGeo, baseMat);\n base.position.set(3.50, 0.17, 0);\n group.add(base);\n\n // Top\n const topGeo = new THREE.BoxGeometry(0.34, 0.42, 0.34);\n const topMat = createMaterial(PALETTE.brown_dark);\n const top = new THREE.Mesh(topGeo, topMat);\n top.position.set(3.50, 0.55, 0);\n group.add(top);\n\n return group;\n}", "buildKiOrb": "function buildKiOrb() {\n const group = new THREE.Group();\n\n // Core\n const coreTex = makeKiOrbTexture();\n const coreGeo = new THREE.BoxGeometry(0.28, 0.28, 0.28);\n const coreMat = createMaterial(PALETTE.sky_blue);\n coreMat.map = coreTex;\n coreMat.map.wrapS = THREE.RepeatWrapping;\n coreMat.map.wrapT = THREE.RepeatWrapping;\n const core = new THREE.Mesh(coreGeo, coreMat);\n core.position.set(0, 0.14, 0);\n group.add(core);\n\n // Glow shell\n const glowGeo = new THREE.BoxGeometry(0.40, 0.40, 0.40);\n const glowMat = createMaterial(PALETTE.martial_blue);\n const glow = new THREE.Mesh(glowGeo, glowMat);\n glow.position.set(0, 0.14, 0);\n group.add(glow);\n\n return group;\n}", "buildDistantButte": "function buildDistantButte() {\n const group = new THREE.Group();\n\n // Base\n const baseTex = makeDistantButteTexture();\n const baseGeo = new THREE.BoxGeometry(4.8, 1.6, 3.6);\n const baseMat = createMaterial(PALETTE.brown_dark);\n baseMat.map = baseTex;\n baseMat.map.wrapS = THREE.RepeatWrapping;\n baseMat.map.wrapT = THREE.RepeatWrapping;\n const base = new THREE.Mesh(baseGeo, baseMat);\n base.position.set(0, 0.80, -30.00);\n group.add(base);\n\n // Mid layer\n const midGeo = new THREE.BoxGeometry(4.1, 1.2, 3.0);\n const midMat = createMaterial(PALETTE.stone_tan);\n const mid = new THREE.Mesh(midGeo, midMat);\n mid.position.set(0.10, 2.20, -30.10);\n group.add(mid);\n\n // Top layer\n const topGeo = new THREE.BoxGeometry(3.3, 0.9, 2.4);\n const top = new THREE.Mesh(topGeo, midMat);\n top.position.set(-0.06, 3.25, -29.95);\n group.add(top);\n\n // Sun cap\n const capGeo = new THREE.BoxGeometry(2.7, 0.14, 1.9);\n const capMat = createMaterial(PALETTE.warm_sand);\n const cap = new THREE.Mesh(capGeo, capMat);\n cap.position.set(-0.02, 3.77, -29.88);\n group.add(cap);\n\n return group;\n}", "buildShowcase": "function buildShowcase() {\n // Hero on pedestal\n if (gameState.hero) {\n scene.remove(gameState.hero);\n }\n gameState.hero = buildSongoku();\n gameState.hero.position.set(0, 1.8, 0);\n scene.add(gameState.hero);\n\n // Pedestal\n const pedestalGeo = new THREE.BoxGeometry(1.8, 0.18, 1.8);\n const pedestalMat = createMaterial(PALETTE.stone_tan);\n const pedestal = new THREE.Mesh(pedestalGeo, pedestalMat);\n pedestal.position.set(0, 0.09, 0);\n pedestal.name = 'pedestal';\n scene.add(pedestal);\n\n // Set showcase camera\n camera.position.copy(CAMERA_SHOWCASE.position);\n camera.lookAt(CAMERA_SHOWCASE.lookAt);\n\n // Reset game state\n gameState.score = 0;\n gameState.distance = 0;\n gameState.scrollSpeed = SCROLL.initial;\n gameState.elapsedTime = 0;\n gameState.heroVelocityY = 0;\n gameState.heroLane = 0;\n gameState.obstacles = [];\n gameState.collectibles = [];\n gameState.spawnTimer = 0;\n\n updateHUD();\n}", "buildRaticate": "function buildRaticate(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.70,0.50,0.80,'#c8a87a',0,0.25,0);p(0.58,0.28,0.30,'#c8a87a',0,0.42,-0.28);\n p(0.48,0.28,0.58,'#f5f0e8',0,0.22,0.30);p(0.58,0.48,0.52,'#c8a87a',0,0.62,0.22);\n p(0.40,0.18,0.26,'#c8a87a',0,0.52,0.48);\n p(0.09,0.22,0.06,'#f8f8f8',-0.07,0.54,0.61);p(0.09,0.22,0.06,'#f8f8f8',0.07,0.54,0.61);\n p(0.14,0.13,0.05,'#f8f8f8',-0.17,0.71,0.46);p(0.08,0.08,0.04,'#1a1a1a',-0.17,0.71,0.49);\n p(0.14,0.13,0.05,'#f8f8f8',0.17,0.71,0.46);p(0.08,0.08,0.04,'#1a1a1a',0.17,0.71,0.49);\n p(0.12,0.24,0.08,'#c8a87a',-0.26,0.87,0.18);p(0.08,0.16,0.05,'#e8c8b0',-0.26,0.87,0.21);\n p(0.12,0.24,0.08,'#c8a87a',0.26,0.87,0.18);p(0.08,0.16,0.05,'#e8c8b0',0.26,0.87,0.21);\n p(0.18,0.02,0.02,'#1a1a1a',-0.27,0.59,0.56);p(0.18,0.02,0.02,'#1a1a1a',-0.27,0.54,0.56);\n p(0.18,0.02,0.02,'#1a1a1a',0.27,0.59,0.56);p(0.18,0.02,0.02,'#1a1a1a',0.27,0.54,0.56);\n p(0.14,0.30,0.14,'#c8a87a',-0.32,0.08,0.24);p(0.14,0.30,0.14,'#c8a87a',0.32,0.08,0.24);\n p(0.16,0.32,0.16,'#c8a87a',-0.30,0.08,-0.22);p(0.16,0.32,0.16,'#c8a87a',0.30,0.08,-0.22);\n p(0.10,0.10,0.30,'#c8a87a',0,0.20,-0.55);p(0.08,0.08,0.22,'#c8a87a',0,0.30,-0.74);p(0.06,0.06,0.16,'#c8a87a',0,0.38,-0.88);\n return g;\n}", "buildPersian": "function buildPersian(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.58,0.40,0.88,'#c8c8d4',0,0.20,0);p(0.38,0.24,0.68,'#e8e8f0',0,0.18,0.10);\n p(0.28,0.22,0.26,'#c8c8d4',0,0.43,0.36);p(0.58,0.50,0.48,'#c8c8d4',0,0.68,0.28);\n p(0.20,0.28,0.26,'#c8c8d4',-0.30,0.64,0.26);p(0.20,0.28,0.26,'#c8c8d4',0.30,0.64,0.26);\n p(0.26,0.14,0.20,'#d8d8e4',0,0.60,0.50);p(0.12,0.12,0.06,'#e05050',0,0.75,0.52);\n p(0.14,0.08,0.06,'#1a1a1a',-0.17,0.75,0.51);p(0.06,0.05,0.04,'#f8f8f8',-0.17,0.76,0.54);\n p(0.14,0.08,0.06,'#1a1a1a',0.17,0.75,0.51);p(0.06,0.05,0.04,'#f8f8f8',0.17,0.76,0.54);\n p(0.11,0.20,0.08,'#c8c8d4',-0.25,0.94,0.26);p(0.07,0.13,0.05,'#e8a8a8',-0.25,0.94,0.29);\n p(0.11,0.20,0.08,'#c8c8d4',0.25,0.94,0.26);p(0.07,0.13,0.05,'#e8a8a8',0.25,0.94,0.29);\n p(0.22,0.02,0.02,'#1a1a1a',-0.32,0.64,0.50);p(0.22,0.02,0.02,'#1a1a1a',-0.32,0.60,0.50);\n p(0.22,0.02,0.02,'#1a1a1a',0.32,0.64,0.50);p(0.22,0.02,0.02,'#1a1a1a',0.32,0.60,0.50);\n p(0.13,0.32,0.13,'#c8c8d4',-0.24,0.13,0.32);p(0.13,0.32,0.13,'#c8c8d4',0.24,0.13,0.32);\n p(0.15,0.34,0.15,'#c8c8d4',-0.22,0.13,-0.28);p(0.15,0.34,0.15,'#c8c8d4',0.22,0.13,-0.28);\n p(0.08,0.08,0.26,'#c8c8d4',0,0.18,-0.56);p(0.08,0.18,0.10,'#c8c8d4',0,0.28,-0.70);p(0.10,0.14,0.08,'#c8c8d4',0,0.36,-0.76);\n return g;\n}", "buildTauros": "function buildTauros(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.88,0.56,0.96,'#8b6914',0,0.30,-0.08);p(0.76,0.42,0.28,'#8b6914',0,0.36,0.32);\n p(0.44,0.34,0.34,'#8b6914',0,0.56,0.48);p(0.68,0.52,0.50,'#8b6914',0,0.80,0.46);\n p(0.48,0.28,0.26,'#d0b860',0,0.70,0.72);p(0.22,0.06,0.06,'#c8c8c8',0,0.66,0.88);\n p(0.09,0.08,0.05,'#1a1a1a',-0.13,0.70,0.86);p(0.09,0.08,0.05,'#1a1a1a',0.13,0.70,0.86);\n p(0.13,0.13,0.06,'#1a1a1a',-0.29,0.92,0.68);p(0.13,0.13,0.06,'#1a1a1a',0.29,0.92,0.68);\n p(0.14,0.12,0.12,'#d0b860',-0.32,1.06,0.42);p(0.08,0.08,0.26,'#d0b860',-0.36,1.14,0.24);\n p(0.14,0.12,0.12,'#d0b860',0.32,1.06,0.42);p(0.08,0.08,0.26,'#d0b860',0.36,1.14,0.24);\n p(0.20,0.28,0.20,'#8b6914',-0.33,0.14,0.30);p(0.20,0.10,0.22,'#1a1a1a',-0.33,-0.14,0.30);\n p(0.20,0.28,0.20,'#8b6914',0.33,0.14,0.30);p(0.20,0.10,0.22,'#1a1a1a',0.33,-0.14,0.30);\n p(0.22,0.30,0.22,'#8b6914',-0.31,0.14,-0.34);p(0.22,0.10,0.24,'#1a1a1a',-0.31,-0.14,-0.34);\n p(0.22,0.30,0.22,'#8b6914',0.31,0.14,-0.34);p(0.22,0.10,0.24,'#1a1a1a',0.31,-0.14,-0.34);\n p(0.06,0.06,0.34,'#8b6914',-0.11,0.23,-0.60);p(0.06,0.06,0.34,'#8b6914',0,0.28,-0.60);p(0.06,0.06,0.34,'#8b6914',0.11,0.23,-0.60);\n p(0.20,0.16,0.08,'#1a1a1a',0,0.30,-0.80);\n return g;\n}", "buildSnorlax": "function buildSnorlax(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.42,0.14,0.46,'#6080a0',-0.40,0.07,0.08);p(0.42,0.14,0.46,'#6080a0',0.40,0.07,0.08);\n p(0.36,0.40,0.32,'#6080a0',-0.38,0.34,0.06);p(0.36,0.40,0.32,'#6080a0',0.38,0.34,0.06);\n p(1.36,0.68,1.08,'#6080a0',0,0.72,0);p(1.16,0.56,0.94,'#6080a0',0,1.22,0);\n p(0.88,0.84,0.28,'#e8d8b0',0,0.82,0.50);p(0.70,0.42,0.22,'#e8d8b0',0,1.30,0.44);\n p(0.28,0.38,0.26,'#6080a0',-0.74,1.14,0.08);p(0.24,0.30,0.24,'#6080a0',-0.76,0.80,0.10);\n p(0.30,0.22,0.28,'#6080a0',-0.78,0.62,0.08);p(0.10,0.10,0.14,'#6080a0',-0.86,0.57,0.14);p(0.10,0.10,0.14,'#6080a0',-0.70,0.57,0.14);\n p(0.28,0.38,0.26,'#6080a0',0.74,1.14,0.08);p(0.24,0.30,0.24,'#6080a0',0.76,0.80,0.10);\n p(0.30,0.22,0.28,'#6080a0',0.78,0.62,0.08);p(0.10,0.10,0.14,'#6080a0',0.86,0.57,0.14);p(0.10,0.10,0.14,'#6080a0',0.70,0.57,0.14);\n p(0.54,0.22,0.50,'#6080a0',0,1.60,0.02);p(0.98,0.70,0.76,'#6080a0',0,1.94,0);\n p(0.78,0.26,0.58,'#6080a0',0,2.26,0);\n p(0.34,0.28,0.28,'#8098b0',-0.48,1.86,0.26);p(0.34,0.28,0.28,'#8098b0',0.48,1.86,0.26);\n p(0.28,0.07,0.07,'#1a1a1a',-0.28,2.04,0.36);p(0.28,0.07,0.07,'#1a1a1a',0.28,2.04,0.36);\n p(0.34,0.07,0.07,'#1a1a1a',0,1.86,0.38);\n p(0.17,0.26,0.13,'#8098b0',-0.50,2.20,-0.02);p(0.17,0.26,0.13,'#8098b0',0.50,2.20,-0.02);\n return g;\n}", "buildGraveler": "function buildGraveler(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(1.00,0.90,0.90,'#808080',0,0.46,0);p(0.84,0.28,0.74,'#808080',0,0.93,0);\n p(0.22,0.60,0.60,'#606060',-0.56,0.46,0);p(0.22,0.60,0.60,'#606060',0.56,0.46,0);\n p(0.18,0.14,0.16,'#404040',-0.42,0.78,-0.22);p(0.14,0.12,0.14,'#404040',-0.30,0.86,0.28);\n p(0.18,0.14,0.16,'#404040',0.42,0.78,-0.22);p(0.14,0.12,0.14,'#404040',0.30,0.86,0.28);\n p(0.18,0.16,0.06,'#f0f0f0',-0.22,0.64,0.44);p(0.10,0.10,0.05,'#e83030',-0.22,0.64,0.47);\n p(0.18,0.16,0.06,'#f0f0f0',0.22,0.64,0.44);p(0.10,0.10,0.05,'#e83030',0.22,0.64,0.47);\n p(0.22,0.08,0.06,'#404040',-0.22,0.74,0.44);p(0.22,0.08,0.06,'#404040',0.22,0.74,0.44);\n p(0.20,0.14,0.18,'#808080',-0.62,0.70,0.16);p(0.22,0.18,0.20,'#404040',-0.88,0.52,0.22);\n p(0.20,0.14,0.18,'#808080',0.62,0.70,0.16);p(0.22,0.18,0.20,'#404040',0.88,0.52,0.22);\n p(0.20,0.12,0.18,'#808080',-0.58,0.28,0.18);p(0.22,0.16,0.20,'#404040',-0.84,0.10,0.24);\n p(0.20,0.12,0.18,'#808080',0.58,0.28,0.18);p(0.22,0.16,0.20,'#404040',0.84,0.10,0.24);\n p(0.26,0.22,0.28,'#808080',-0.28,0.08,0.04);p(0.26,0.22,0.28,'#808080',0.28,0.08,0.04);\n return g;\n}", "buildOnix": "function buildOnix(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n const sc=[1.0,0.88,0.76,0.64,0.52],zs=[0,-1.8,-3.6,-5.4,-7.2];\n for(let i=0;i<5;i++){\n const s=sc[i],z=zs[i];\n p(0.90*s,0.70*s,1.20*s,'#909090',0,0.37*s,z);\n p(0.22*s,0.22*s,0.22*s,'#707070',-0.42*s,0.52*s,z);p(0.22*s,0.22*s,0.22*s,'#707070',0.42*s,0.52*s,z);\n p(0.18*s,0.30*s,0.18*s,'#505050',0,0.80*s,z);\n p(0.14*s,0.12*s,0.14*s,'#707070',-0.30*s,0.66*s,z+0.20*s);p(0.14*s,0.12*s,0.14*s,'#707070',0.30*s,0.66*s,z-0.20*s);\n }\n p(0.12,0.12,0.06,'#e8e060',-0.22,0.54,0.58);p(0.12,0.12,0.06,'#e8e060',0.22,0.54,0.58);\n return g;\n}", "buildZubat": "function buildZubat(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.48,0.46,0.36,'#9060c0',0,0.24,0);p(0.36,0.20,0.26,'#7040b0',0,0.06,0.04);\n p(0.10,0.24,0.08,'#9060c0',-0.20,0.52,0);p(0.06,0.16,0.05,'#d090f8',-0.20,0.52,0.03);\n p(0.10,0.24,0.08,'#9060c0',0.20,0.52,0);p(0.06,0.16,0.05,'#d090f8',0.20,0.52,0.03);\n p(0.40,0.14,0.10,'#e83060',0,0.14,0.20);p(0.30,0.08,0.06,'#1a1a1a',0,0.14,0.24);\n p(0.06,0.10,0.06,'#f8f8f8',-0.08,0.09,0.22);p(0.06,0.10,0.06,'#f8f8f8',0.08,0.09,0.22);\n p(0.26,0.10,0.52,'#7040b0',-0.34,0.30,0);p(0.44,0.08,0.60,'#7040b0',-0.70,0.24,0);p(0.36,0.06,0.44,'#604090',-1.04,0.18,0);\n p(0.26,0.10,0.52,'#7040b0',0.34,0.30,0);p(0.44,0.08,0.60,'#7040b0',0.70,0.24,0);p(0.36,0.06,0.44,'#604090',1.04,0.18,0);\n p(0.08,0.06,0.46,'#8050b0',-0.54,0.28,-0.06);p(0.08,0.06,0.40,'#8050b0',-0.88,0.22,-0.04);\n p(0.08,0.06,0.46,'#8050b0',0.54,0.28,-0.06);p(0.08,0.06,0.40,'#8050b0',0.88,0.22,-0.04);\n p(0.16,0.08,0.08,'#1a1a1a',-0.18,0.02,0.04);p(0.16,0.08,0.08,'#1a1a1a',0.18,0.02,0.04);\n p(0.06,0.04,0.12,'#1a1a1a',-0.22,0.00,0.10);p(0.06,0.04,0.12,'#1a1a1a',0.22,0.00,0.10);\n return g;\n}", "buildGolbat": "function buildGolbat(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.60,0.50,0.42,'#7040b0',0,0.26,0);p(0.44,0.18,0.30,'#5a3090',0,0.06,0);\n p(0.60,0.44,0.44,'#7040b0',0,0.60,0);\n p(0.72,0.30,0.12,'#e83060',0,0.52,0.24);p(0.64,0.22,0.08,'#1a1a1a',0,0.52,0.28);\n p(0.08,0.16,0.07,'#f8f8f8',-0.22,0.60,0.30);p(0.08,0.16,0.07,'#f8f8f8',0.22,0.60,0.30);\n p(0.08,0.12,0.07,'#f8f8f8',-0.14,0.43,0.30);p(0.08,0.12,0.07,'#f8f8f8',0.14,0.43,0.30);\n p(0.30,0.08,0.08,'#e83060',0,0.49,0.32);\n p(0.12,0.26,0.08,'#7040b0',-0.26,0.82,0);p(0.12,0.26,0.08,'#7040b0',0.26,0.82,0);\n p(0.12,0.10,0.05,'#e83060',-0.20,0.70,0.21);p(0.12,0.10,0.05,'#e83060',0.20,0.70,0.21);\n p(0.30,0.10,0.64,'#8050c0',-0.42,0.34,0);p(0.54,0.08,0.74,'#6040a0',-0.84,0.26,0);p(0.42,0.06,0.56,'#5030a0',-1.18,0.18,0);\n p(0.30,0.10,0.64,'#8050c0',0.42,0.34,0);p(0.54,0.08,0.74,'#6040a0',0.84,0.26,0);p(0.42,0.06,0.56,'#5030a0',1.18,0.18,0);\n p(0.08,0.06,0.62,'#9060c0',-0.66,0.30,-0.05);p(0.08,0.06,0.62,'#9060c0',0.66,0.30,-0.05);\n p(0.06,0.04,0.14,'#1a1a1a',-0.20,0.00,0.11);p(0.06,0.04,0.14,'#1a1a1a',0.20,0.00,0.11);\n return g;\n}", "buildPidgey": "function buildPidgey(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.44,0.42,0.60,'#c09060',0,0.22,0);p(0.30,0.30,0.44,'#e8d8b0',0,0.20,0.20);\n p(0.44,0.40,0.40,'#c09060',0,0.56,0.14);p(0.36,0.16,0.32,'#a07040',0,0.74,0.10);\n p(0.08,0.14,0.06,'#1a1a1a',0,0.88,0.06);\n p(0.10,0.08,0.22,'#e8c040',0,0.54,0.38);p(0.08,0.06,0.18,'#1a1a1a',0,0.49,0.38);\n p(0.10,0.10,0.05,'#1a1a1a',-0.16,0.62,0.34);p(0.05,0.05,0.04,'#f8f8f8',-0.16,0.63,0.37);\n p(0.10,0.10,0.05,'#1a1a1a',0.16,0.62,0.34);p(0.05,0.05,0.04,'#f8f8f8',0.16,0.63,0.37);\n p(0.08,0.32,0.56,'#a07040',-0.30,0.26,0);p(0.06,0.22,0.42,'#906030',-0.46,0.20,-0.18);\n p(0.08,0.32,0.56,'#a07040',0.30,0.26,0);p(0.06,0.22,0.42,'#906030',0.46,0.20,-0.18);\n p(0.24,0.14,0.26,'#a07040',0,0.22,-0.38);\n p(0.08,0.10,0.18,'#906030',-0.10,0.20,-0.52);p(0.08,0.10,0.18,'#906030',0.10,0.20,-0.52);\n p(0.08,0.22,0.08,'#e8c040',-0.12,0.04,0.20);p(0.08,0.22,0.08,'#e8c040',0.12,0.04,0.20);\n p(0.14,0.04,0.08,'#e8c040',-0.18,0.00,0.26);p(0.14,0.04,0.08,'#e8c040',0.06,0.00,0.24);\n p(0.14,0.04,0.08,'#e8c040',0.18,0.00,0.26);p(0.14,0.04,0.08,'#e8c040',-0.06,0.00,0.24);\n return g;\n}", "buildFearow": "function buildFearow(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.54,0.48,0.72,'#c06030',0,0.24,0);p(0.36,0.30,0.52,'#e8d0a0',0,0.22,0.18);\n p(0.24,0.40,0.22,'#c06030',0,0.58,0.22);p(0.40,0.36,0.36,'#c06030',0,0.78,0.18);\n p(0.08,0.08,0.54,'#f0c040',0,0.78,0.50);p(0.06,0.06,0.46,'#1a1a1a',0,0.74,0.50);\n p(0.12,0.22,0.10,'#c06030',0,0.96,0.14);p(0.08,0.14,0.06,'#e8d0a0',0.04,1.08,0.12);\n p(0.10,0.10,0.05,'#1a1a1a',-0.16,0.82,0.36);p(0.14,0.14,0.04,'#f0d080',-0.16,0.82,0.34);\n p(0.10,0.10,0.05,'#1a1a1a',0.16,0.82,0.36);p(0.14,0.14,0.04,'#f0d080',0.16,0.82,0.34);\n p(0.10,0.38,0.68,'#c06030',-0.36,0.28,-0.02);p(0.08,0.28,0.54,'#a04820',-0.60,0.22,-0.12);p(0.06,0.18,0.38,'#804010',-0.78,0.16,-0.22);\n p(0.10,0.38,0.68,'#c06030',0.36,0.28,-0.02);p(0.08,0.28,0.54,'#a04820',0.60,0.22,-0.12);p(0.06,0.18,0.38,'#804010',0.78,0.16,-0.22);\n p(0.06,0.06,0.44,'#904020',-0.46,0.14,-0.20);p(0.06,0.06,0.44,'#904020',0.46,0.14,-0.20);\n p(0.28,0.16,0.32,'#c06030',0,0.22,-0.48);\n p(0.08,0.10,0.24,'#a04820',-0.12,0.20,-0.62);p(0.08,0.10,0.24,'#a04820',0.12,0.20,-0.62);\n p(0.08,0.24,0.08,'#f0c040',-0.12,0.04,0.28);p(0.08,0.24,0.08,'#f0c040',0.12,0.04,0.28);\n p(0.24,0.06,0.18,'#f0c040',0,0.01,0.32);\n return g;\n}", "buildBeedrill": "function buildBeedrill(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.26,0.46,0.30,'#f8d840',0,0.36,0);p(0.28,0.10,0.32,'#1a1a1a',0,0.52,0);\n p(0.22,0.64,0.22,'#f8d840',0,0.34,-0.38);\n p(0.24,0.10,0.24,'#1a1a1a',0,0.18,-0.36);p(0.24,0.10,0.24,'#1a1a1a',0,0.44,-0.44);\n p(0.14,0.18,0.14,'#f8d840',0,0.10,-0.60);p(0.06,0.06,0.22,'#1a1a1a',0,0.06,-0.74);\n p(0.30,0.28,0.28,'#f8d840',0,0.68,0.12);\n p(0.14,0.18,0.08,'#e83060',-0.12,0.70,0.24);p(0.06,0.07,0.05,'#f8f8f8',-0.12,0.72,0.27);\n p(0.14,0.18,0.08,'#e83060',0.12,0.70,0.24);p(0.06,0.07,0.05,'#f8f8f8',0.12,0.72,0.27);\n p(0.04,0.04,0.22,'#1a1a1a',-0.10,0.86,0.10);p(0.04,0.04,0.22,'#1a1a1a',0.10,0.86,0.10);\n p(0.08,0.08,0.54,'#1a1a1a',-0.28,0.52,0.22);p(0.06,0.06,0.10,'#f0f080',-0.28,0.52,0.50);\n p(0.08,0.08,0.54,'#1a1a1a',0.28,0.52,0.22);p(0.06,0.06,0.10,'#f0f080',0.28,0.52,0.50);\n p(0.06,0.28,0.52,'#f0f0f8',-0.32,0.52,-0.10);p(0.04,0.20,0.40,'#d8e8f8',-0.52,0.48,-0.14);\n p(0.06,0.28,0.52,'#f0f0f8',0.32,0.52,-0.10);p(0.04,0.20,0.40,'#d8e8f8',0.52,0.48,-0.14);\n p(0.06,0.22,0.42,'#f0f0f8',-0.28,0.30,-0.12);p(0.06,0.22,0.42,'#f0f0f8',0.28,0.30,-0.12);\n p(0.08,0.08,0.16,'#1a1a1a',-0.20,0.42,0.08);p(0.08,0.08,0.16,'#1a1a1a',0.20,0.42,0.08);\n return g;\n}", "buildButterfree": "function buildButterfree(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.22,0.60,0.20,'#f0f0f8',0,0.36,0);p(0.20,0.24,0.18,'#d0d0e0',0,0.60,0);\n p(0.14,0.22,0.14,'#d0d0e8',0,0.10,-0.14);p(0.28,0.28,0.26,'#f0f0f8',0,0.80,0.04);\n p(0.12,0.16,0.08,'#e83060',-0.10,0.82,0.16);p(0.12,0.16,0.08,'#e83060',0.10,0.82,0.16);\n p(0.04,0.04,0.26,'#1a1a1a',-0.08,0.98,0.06);p(0.08,0.08,0.06,'#9060c0',-0.10,1.10,0.06);\n p(0.04,0.04,0.26,'#1a1a1a',0.08,0.98,0.06);p(0.08,0.08,0.06,'#9060c0',0.10,1.10,0.06);\n p(0.06,0.58,0.74,'#f8f8ff',-0.40,0.56,-0.06);p(0.04,0.44,0.58,'#d8d0f8',-0.64,0.52,-0.12);\n p(0.04,0.30,0.38,'#9060c0',-0.54,0.64,-0.08);p(0.04,0.12,0.12,'#9060c0',-0.46,0.72,-0.04);\n p(0.06,0.58,0.74,'#f8f8ff',0.40,0.56,-0.06);p(0.04,0.44,0.58,'#d8d0f8',0.64,0.52,-0.12);\n p(0.04,0.30,0.38,'#9060c0',0.54,0.64,-0.08);p(0.04,0.12,0.12,'#9060c0',0.46,0.72,-0.04);\n p(0.06,0.42,0.58,'#f0f0ff',-0.34,0.18,-0.04);p(0.04,0.30,0.44,'#d8d0f8',-0.54,0.14,-0.10);p(0.04,0.22,0.28,'#9060c0',-0.44,0.22,-0.06);\n p(0.06,0.42,0.58,'#f0f0ff',0.34,0.18,-0.04);p(0.04,0.30,0.44,'#d8d0f8',0.54,0.14,-0.10);p(0.04,0.22,0.28,'#9060c0',0.44,0.22,-0.06);\n p(0.18,0.06,0.08,'#1a1a1a',-0.12,0.04,0.08);p(0.18,0.06,0.08,'#1a1a1a',0.12,0.04,0.08);\n return g;\n}", "buildVoltorb": "function buildVoltorb(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.72,0.36,0.72,'#e83030',0,0.52,0);p(0.44,0.42,0.52,'#e83030',-0.32,0.44,0);p(0.44,0.42,0.52,'#e83030',0.32,0.44,0);\n p(0.52,0.38,0.36,'#e83030',0,0.44,0.32);p(0.50,0.30,0.28,'#e83030',0,0.46,-0.28);\n p(0.54,0.14,0.54,'#e83030',0,0.64,0);p(0.38,0.10,0.38,'#e83030',0,0.72,0);\n p(0.80,0.08,0.76,'#1a1a1a',0,0.30,0);p(0.46,0.08,0.58,'#1a1a1a',-0.30,0.30,0);p(0.46,0.08,0.58,'#1a1a1a',0.30,0.30,0);\n p(0.72,0.36,0.72,'#f8f8f8',0,0.10,0);p(0.44,0.38,0.52,'#f0f0f0',-0.32,0.14,0);p(0.44,0.38,0.52,'#f0f0f0',0.32,0.14,0);\n p(0.52,0.32,0.36,'#f0f0f0',0,0.12,0.30);p(0.38,0.08,0.38,'#f0f0f0',0,0.04,0);\n p(0.16,0.14,0.06,'#f8f8f8',-0.20,0.42,0.35);p(0.10,0.09,0.04,'#1a1a1a',-0.20,0.42,0.38);\n p(0.16,0.14,0.06,'#f8f8f8',0.20,0.42,0.35);p(0.10,0.09,0.04,'#1a1a1a',0.20,0.42,0.38);\n p(0.18,0.08,0.05,'#1a1a1a',-0.20,0.52,0.35);p(0.18,0.08,0.05,'#1a1a1a',0.20,0.52,0.35);\n p(0.24,0.08,0.05,'#1a1a1a',0,0.30,0.37);\n return g;\n}", "buildElectrode": "function buildElectrode(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.90,0.44,0.90,'#f8f8f8',0,0.60,0);p(0.54,0.52,0.64,'#f0f0f0',-0.38,0.52,0);p(0.54,0.52,0.64,'#f0f0f0',0.38,0.52,0);\n p(0.64,0.46,0.44,'#f0f0f0',0,0.52,0.38);p(0.62,0.36,0.34,'#f0f0f0',0,0.54,-0.34);\n p(0.68,0.18,0.68,'#f8f8f8',0,0.82,0);p(0.48,0.12,0.48,'#f8f8f8',0,0.92,0);\n p(0.96,0.10,0.92,'#1a1a1a',0,0.36,0);p(0.58,0.10,0.72,'#1a1a1a',-0.36,0.36,0);p(0.58,0.10,0.72,'#1a1a1a',0.36,0.36,0);\n p(0.90,0.44,0.90,'#e83030',0,0.14,0);p(0.54,0.48,0.64,'#e83030',-0.38,0.20,0);p(0.54,0.48,0.64,'#e83030',0.38,0.20,0);\n p(0.64,0.40,0.44,'#e83030',0,0.16,0.36);p(0.48,0.10,0.48,'#e83030',0,0.06,0);\n p(0.20,0.16,0.06,'#1a1a1a',-0.24,0.50,0.44);p(0.12,0.10,0.04,'#f8f8f8',-0.24,0.50,0.47);\n p(0.20,0.16,0.06,'#1a1a1a',0.24,0.50,0.44);p(0.12,0.10,0.04,'#f8f8f8',0.24,0.50,0.47);\n p(0.22,0.09,0.05,'#1a1a1a',-0.24,0.62,0.44);p(0.22,0.09,0.05,'#1a1a1a',0.24,0.62,0.44);\n p(0.30,0.09,0.05,'#1a1a1a',0,0.36,0.46);\n return g;\n}", "buildJigglypuff": "function buildJigglypuff(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.80,0.70,0.80,'#ffb0c8',0,0.38,0);p(0.56,0.52,0.60,'#ffb0c8',-0.34,0.34,0);p(0.56,0.52,0.60,'#ffb0c8',0.34,0.34,0);\n p(0.64,0.56,0.64,'#ffb0c8',0,0.38,0.32);p(0.60,0.42,0.50,'#ffb0c8',0,0.38,-0.28);\n p(0.64,0.22,0.62,'#ffb0c8',0,0.68,0);p(0.46,0.14,0.44,'#ffb0c8',0,0.78,0);\n p(0.14,0.14,0.06,'#f0f0ff',-0.22,0.48,0.40);p(0.28,0.28,0.08,'#6898f8',-0.22,0.48,0.42);p(0.10,0.10,0.05,'#1a1a1a',-0.22,0.48,0.45);\n p(0.14,0.14,0.06,'#f0f0ff',0.22,0.48,0.40);p(0.28,0.28,0.08,'#6898f8',0.22,0.48,0.42);p(0.10,0.10,0.05,'#1a1a1a',0.22,0.48,0.45);\n p(0.28,0.06,0.05,'#e05878',0,0.36,0.41);\n p(0.08,0.12,0.06,'#ffb0c8',-0.28,0.74,0.06);p(0.06,0.08,0.05,'#e890b0',0,0.82,0.06);\n p(0.26,0.24,0.14,'#ffb0c8',-0.44,0.26,0.12);p(0.14,0.10,0.10,'#ffb0c8',-0.54,0.14,0.14);\n p(0.26,0.24,0.14,'#ffb0c8',0.44,0.26,0.12);p(0.14,0.10,0.10,'#ffb0c8',0.54,0.14,0.14);\n p(0.22,0.18,0.22,'#ffb0c8',-0.24,0.04,0.08);p(0.22,0.18,0.22,'#ffb0c8',0.24,0.04,0.08);\n p(0.10,0.06,0.14,'#ffb0c8',-0.28,0.00,0.16);p(0.10,0.06,0.14,'#ffb0c8',0.22,0.00,0.16);\n return g;\n}", "buildAbra": "function buildAbra(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),tmat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.48,0.44,0.54,'#e8c840',0,0.24,0);p(0.34,0.28,0.40,'#c0a030',0,0.24,0.14);\n p(0.36,0.36,0.38,'#e8c840',0,0.60,0.10);p(0.28,0.20,0.26,'#e8c840',0,0.52,0.32);\n p(0.22,0.08,0.06,'#1a1a1a',-0.10,0.64,0.26);p(0.22,0.08,0.06,'#1a1a1a',0.10,0.64,0.26);\n p(0.10,0.22,0.08,'#e8c840',-0.18,0.82,0.06);p(0.06,0.14,0.06,'#c0a030',-0.18,0.82,0.09);\n p(0.10,0.22,0.08,'#e8c840',0.18,0.82,0.06);p(0.06,0.14,0.06,'#c0a030',0.18,0.82,0.09);\n p(0.40,0.36,0.36,'#c0a030',0,0.06,0);\n p(0.16,0.26,0.14,'#e8c840',-0.28,0.40,0.04);p(0.14,0.22,0.12,'#c0a030',-0.38,0.24,0.08);\n p(0.16,0.26,0.14,'#e8c840',0.28,0.40,0.04);p(0.14,0.22,0.12,'#c0a030',0.38,0.24,0.08);\n p(0.12,0.10,0.16,'#c0a030',-0.42,0.16,0.14);p(0.12,0.10,0.16,'#c0a030',0.42,0.16,0.14);\n p(0.10,0.06,0.06,'#c0a030',-0.48,0.14,0.18);p(0.10,0.06,0.06,'#c0a030',0.48,0.14,0.18);\n p(0.30,0.10,0.22,'#c0a030',-0.08,0.08,-0.22);p(0.26,0.10,0.22,'#c0a030',0.08,0.08,-0.22);\n p(0.28,0.08,0.06,'#c0a030',0,0.48,0.02);\n p(0.06,0.28,0.06,'#e8c840',0,0.54,-0.26);p(0.06,0.14,0.14,'#c0a030',0,0.42,-0.34);\n return g;\n}", "buildAlakazam": "function buildAlakazam(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),tmat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.36,0.60,0.30,'#e8c840',0,0.32,0);p(0.26,0.34,0.22,'#c0a030',0,0.32,0.12);\n p(0.44,0.44,0.40,'#e8c840',0,0.76,0.04);p(0.22,0.14,0.20,'#c0a030',0,0.62,0.24);\n p(0.36,0.08,0.06,'#d0b050',-0.02,0.64,0.24);p(0.36,0.08,0.06,'#d0b050',0.02,0.60,0.24);\n p(0.10,0.10,0.06,'#1a1a1a',-0.14,0.80,0.20);p(0.10,0.10,0.06,'#1a1a1a',0.14,0.80,0.20);\n p(0.10,0.28,0.08,'#e8c840',-0.22,0.96,0.02);p(0.10,0.28,0.08,'#e8c840',0.22,0.96,0.02);\n p(0.26,0.48,0.14,'#e8c840',-0.32,0.36,0.04);p(0.20,0.38,0.12,'#c0a030',-0.44,0.22,0.06);\n p(0.26,0.48,0.14,'#e8c840',0.32,0.36,0.04);p(0.20,0.38,0.12,'#c0a030',0.44,0.22,0.06);\n p(0.06,0.06,0.46,'#d0b050',-0.52,0.14,0.20);p(0.04,0.04,0.06,'#f0d880',-0.52,0.14,0.44);\n p(0.06,0.06,0.46,'#d0b050',0.52,0.14,0.20);p(0.04,0.04,0.06,'#f0d880',0.52,0.14,0.44);\n p(0.20,0.44,0.20,'#e8c840',-0.14,0.10,0.02);p(0.20,0.44,0.20,'#e8c840',0.14,0.10,0.02);\n p(0.24,0.10,0.28,'#c0a030',-0.14,0.00,0.06);p(0.24,0.10,0.28,'#c0a030',0.14,0.00,0.06);\n p(0.08,0.30,0.08,'#c0a030',0,0.14,-0.20);p(0.12,0.08,0.14,'#c0a030',0,0.04,-0.28);\n return g;\n}", "buildGengar": "function buildGengar(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),tmat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.82,0.70,0.78,'#7850a0',0,0.38,0);p(0.60,0.52,0.60,'#604080',-0.38,0.30,0);p(0.60,0.52,0.60,'#604080',0.38,0.30,0);\n p(0.66,0.54,0.64,'#7850a0',0,0.38,0.30);p(0.58,0.44,0.52,'#7850a0',0,0.40,-0.28);\n p(0.74,0.40,0.70,'#7850a0',0,0.78,0);\n p(0.18,0.26,0.08,'#604080',-0.36,1.02,-0.08);p(0.18,0.26,0.08,'#604080',0.36,1.02,-0.08);\n p(0.12,0.20,0.08,'#604080',-0.20,1.10,-0.04);p(0.12,0.20,0.08,'#604080',0.20,1.10,-0.04);\n p(0.22,0.18,0.08,'#e83060',-0.20,0.80,0.34);p(0.14,0.10,0.05,'#1a1a1a',-0.20,0.80,0.38);\n p(0.22,0.18,0.08,'#e83060',0.20,0.80,0.34);p(0.14,0.10,0.05,'#1a1a1a',0.20,0.80,0.38);\n p(0.54,0.18,0.08,'#f8f8f8',0,0.62,0.38);p(0.44,0.10,0.06,'#1a1a1a',0,0.62,0.40);\n p(0.06,0.14,0.06,'#f8f8f8',-0.18,0.56,0.38);p(0.06,0.14,0.06,'#f8f8f8',-0.06,0.56,0.38);\n p(0.06,0.14,0.06,'#f8f8f8',0.06,0.56,0.38);p(0.06,0.14,0.06,'#f8f8f8',0.18,0.56,0.38);\n p(0.30,0.26,0.22,'#7850a0',-0.54,0.34,0.12);p(0.22,0.20,0.18,'#604080',-0.66,0.20,0.14);\n p(0.30,0.26,0.22,'#7850a0',0.54,0.34,0.12);p(0.22,0.20,0.18,'#604080',0.66,0.20,0.14);\n p(0.14,0.10,0.08,'#604080',-0.72,0.14,0.20);p(0.14,0.10,0.08,'#604080',0.72,0.14,0.20);\n p(0.60,0.22,0.56,'#604080',0,0.06,0);\n return g;\n}", "buildDoduo": "function buildDoduo(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.60,0.42,0.52,'#c8a840',0,0.22,0);p(0.44,0.24,0.38,'#e8c860',0,0.20,0.14);\n p(0.12,0.54,0.12,'#c8a840',-0.14,0.62,0.04);p(0.12,0.54,0.12,'#c8a840',0.14,0.62,0.04);\n p(0.36,0.34,0.32,'#c8a840',-0.14,0.96,0.04);p(0.36,0.34,0.32,'#c8a840',0.14,0.96,0.04);\n p(0.10,0.08,0.22,'#e84820',-0.14,0.96,0.22);p(0.10,0.08,0.22,'#e84820',0.14,0.96,0.22);\n p(0.10,0.10,0.05,'#1a1a1a',-0.22,1.02,0.18);p(0.10,0.10,0.05,'#1a1a1a',-0.06,1.02,0.18);\n p(0.10,0.10,0.05,'#1a1a1a',0.06,1.02,0.18);p(0.10,0.10,0.05,'#1a1a1a',0.22,1.02,0.18);\n p(0.10,0.16,0.08,'#c8a840',-0.22,1.10,0.02);p(0.10,0.16,0.08,'#c8a840',0.22,1.10,0.02);\n p(0.20,0.16,0.18,'#c8a840',-0.16,0.08,0.06);p(0.20,0.16,0.18,'#c8a840',0.16,0.08,0.06);\n p(0.08,0.28,0.08,'#e84820',-0.18,0.00,0.08);p(0.08,0.28,0.08,'#e84820',0.18,0.00,0.08);\n p(0.22,0.06,0.14,'#e84820',-0.18,-0.02,0.14);p(0.22,0.06,0.14,'#e84820',0.18,-0.02,0.14);\n p(0.08,0.06,0.10,'#e84820',-0.24,-0.02,0.12);p(0.08,0.06,0.10,'#e84820',0.22,-0.02,0.12);\n p(0.26,0.20,0.24,'#c8a840',0,0.40,-0.28);p(0.08,0.14,0.08,'#e8c860',0,0.28,-0.34);\n return g;\n}", "buildRapidash": "function buildRapidash(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.52,0.48,0.88,'#f8f8f8',0,0.42,0);p(0.38,0.34,0.70,'#f0f0f0',0,0.40,0.10);\n p(0.32,0.40,0.30,'#f8f8f8',0,0.70,0.36);p(0.26,0.42,0.28,'#f8f8f8',0,0.88,0.52);\n p(0.36,0.34,0.34,'#f8f8f8',0,1.04,0.60);p(0.18,0.10,0.26,'#f8f8f8',0,0.96,0.78);\n p(0.06,0.06,0.20,'#f0f080',0,1.06,0.90);\n p(0.10,0.10,0.05,'#1a1a1a',-0.14,1.10,0.74);p(0.10,0.10,0.05,'#1a1a1a',0.14,1.10,0.74);\n p(0.06,0.24,0.06,'#f89020',0,0.88,0.36);p(0.10,0.36,0.10,'#f89020',0,1.02,0.26);\n p(0.14,0.48,0.10,'#f89020',-0.10,1.00,0.20);p(0.14,0.48,0.10,'#f89020',0.10,1.00,0.20);\n p(0.10,0.30,0.08,'#f8d840',-0.06,1.08,0.22);p(0.10,0.30,0.08,'#f8d840',0.06,1.08,0.22);\n p(0.16,0.42,0.16,'#f8f8f8',-0.18,0.16,0.28);p(0.12,0.34,0.12,'#f0f0f0',-0.18,-0.04,0.28);p(0.16,0.10,0.20,'#f0f0f0',-0.18,-0.16,0.28);\n p(0.16,0.42,0.16,'#f8f8f8',0.18,0.16,0.28);p(0.12,0.34,0.12,'#f0f0f0',0.18,-0.04,0.28);p(0.16,0.10,0.20,'#f0f0f0',0.18,-0.16,0.28);\n p(0.16,0.42,0.16,'#f8f8f8',-0.18,0.16,-0.36);p(0.12,0.34,0.12,'#f0f0f0',-0.18,-0.04,-0.36);p(0.16,0.10,0.20,'#f0f0f0',-0.18,-0.16,-0.36);\n p(0.16,0.42,0.16,'#f8f8f8',0.18,0.16,-0.36);p(0.12,0.34,0.12,'#f0f0f0',0.18,-0.04,-0.36);p(0.16,0.10,0.20,'#f0f0f0',0.18,-0.16,-0.36);\n p(0.08,0.10,0.24,'#f89020',0,0.42,-0.52);p(0.10,0.18,0.12,'#f8d840',0,0.54,-0.62);p(0.08,0.26,0.08,'#f89020',0,0.64,-0.58);\n return g;\n}", "buildHaunter": "function buildHaunter(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),tmat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.66,0.60,0.62,'#9060b8',0,0.40,0);p(0.48,0.44,0.48,'#7040a0',-0.32,0.32,0);p(0.48,0.44,0.48,'#7040a0',0.32,0.32,0);\n p(0.56,0.50,0.54,'#9060b8',0,0.40,0.24);p(0.52,0.42,0.46,'#7040a0',0,0.38,-0.22);\n p(0.62,0.48,0.60,'#9060b8',0,0.76,0);\n p(0.16,0.24,0.08,'#7040a0',-0.34,1.00,-0.04);p(0.16,0.24,0.08,'#7040a0',0.34,1.00,-0.04);\n p(0.22,0.20,0.08,'#e83060',-0.18,0.78,0.30);p(0.12,0.12,0.05,'#1a1a1a',-0.18,0.78,0.34);\n p(0.22,0.20,0.08,'#e83060',0.18,0.78,0.30);p(0.12,0.12,0.05,'#1a1a1a',0.18,0.78,0.34);\n p(0.40,0.14,0.08,'#f8f8f8',0,0.62,0.32);\n p(0.06,0.12,0.06,'#f8f8f8',-0.12,0.56,0.34);p(0.06,0.12,0.06,'#f8f8f8',0.12,0.56,0.34);\n p(0.26,0.24,0.22,'#c080ff',-0.72,0.56,0.16);p(0.08,0.18,0.08,'#c080ff',-0.82,0.46,0.20);p(0.08,0.18,0.08,'#c080ff',-0.72,0.44,0.22);\n p(0.26,0.24,0.22,'#c080ff',0.72,0.56,0.16);p(0.08,0.18,0.08,'#c080ff',0.82,0.46,0.20);p(0.08,0.18,0.08,'#c080ff',0.72,0.44,0.22);\n p(0.52,0.18,0.48,'#7040a0',0,0.06,0);\n p(0.12,0.16,0.10,'#7040a0',-0.18,0.00,-0.08);p(0.12,0.16,0.10,'#7040a0',0,0.00,-0.10);p(0.12,0.16,0.10,'#7040a0',0.18,0.00,-0.08);\n return g;\n}", "buildCaterpie": "function buildCaterpie(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.38,0.34,0.34,'#60c040',0,0.18,0.30);p(0.26,0.22,0.24,'#78d858',0,0.18,0.30);\n p(0.10,0.10,0.05,'#1a1a1a',-0.12,0.24,0.45);p(0.10,0.10,0.05,'#1a1a1a',0.12,0.24,0.45);\n p(0.04,0.04,0.14,'#e83030',0,0.32,0.40);p(0.06,0.08,0.06,'#e83030',0,0.40,0.44);\n p(0.40,0.36,0.32,'#60c040',0,0.19,0);p(0.28,0.14,0.26,'#f8f840',0,0.10,0.02);\n p(0.06,0.06,0.08,'#60c040',-0.20,0.06,0.04);p(0.06,0.06,0.08,'#60c040',0.20,0.06,0.04);\n p(0.38,0.34,0.30,'#60c040',0,0.18,-0.32);p(0.26,0.12,0.24,'#f8f840',0,0.10,-0.30);\n p(0.06,0.06,0.08,'#60c040',-0.20,0.06,-0.30);p(0.06,0.06,0.08,'#60c040',0.20,0.06,-0.30);\n p(0.34,0.30,0.28,'#60c040',0,0.16,-0.62);p(0.24,0.10,0.22,'#f8f840',0,0.10,-0.60);\n p(0.06,0.06,0.08,'#60c040',-0.18,0.06,-0.60);p(0.06,0.06,0.08,'#60c040',0.18,0.06,-0.60);\n p(0.30,0.26,0.22,'#60c040',0,0.14,-0.88);p(0.08,0.18,0.06,'#e83030',0,0.28,-0.96);\n p(0.06,0.06,0.08,'#78d858',-0.18,0.06,0.30);p(0.06,0.06,0.08,'#78d858',0.18,0.06,0.30);\n p(0.06,0.06,0.08,'#78d858',-0.18,0.06,-0.62);p(0.06,0.06,0.08,'#78d858',0.18,0.06,-0.62);\n return g;\n}", "buildMagnemite": "function buildMagnemite(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.56,0.52,0.50,'#a0a8b8',0,0.40,0);p(0.40,0.36,0.36,'#b8c0d0',0,0.40,0.12);\n p(0.14,0.14,0.06,'#f0f0f0',0,0.40,0.25);p(0.10,0.10,0.04,'#1a1a1a',0,0.40,0.28);\n p(0.08,0.08,0.06,'#e8d840',-0.10,0.46,0.24);p(0.08,0.08,0.06,'#e8d840',0.10,0.46,0.24);\n p(0.08,0.08,0.06,'#e8d840',-0.10,0.34,0.24);p(0.08,0.08,0.06,'#e8d840',0.10,0.34,0.24);\n p(0.38,0.12,0.12,'#808898',-0.44,0.40,0);p(0.14,0.22,0.14,'#e83030',-0.64,0.48,0);p(0.14,0.22,0.14,'#f8f8f8',-0.64,0.32,0);\n p(0.38,0.12,0.12,'#808898',0.44,0.40,0);p(0.14,0.22,0.14,'#e83030',0.64,0.48,0);p(0.14,0.22,0.14,'#f8f8f8',0.64,0.32,0);\n p(0.06,0.06,0.04,'#c0c8d8',-0.20,0.54,0.24);p(0.06,0.06,0.04,'#c0c8d8',0.20,0.54,0.24);\n p(0.06,0.06,0.04,'#c0c8d8',-0.20,0.26,0.24);p(0.06,0.06,0.04,'#c0c8d8',0.20,0.26,0.24);\n p(0.06,0.06,0.04,'#c0c8d8',-0.26,0.40,0.24);p(0.06,0.06,0.04,'#c0c8d8',0.26,0.40,0.24);\n p(0.30,0.08,0.08,'#808898',0,0.40,-0.26);\n p(0.04,0.04,0.18,'#e8d840',0,0.50,-0.28);p(0.04,0.04,0.18,'#e8d840',0,0.30,-0.28);\n p(0.12,0.04,0.04,'#808898',-0.44,0.50,0);p(0.12,0.04,0.04,'#808898',0.44,0.50,0);\n p(0.18,0.18,0.04,'#c0c8d8',0,0.40,0.14);\n return g;\n}", "buildGeodude": "function buildGeodude(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.64,0.58,0.62,'#c8a870',0,0.32,0);p(0.48,0.42,0.48,'#b89050',-0.28,0.28,0.10);p(0.48,0.42,0.48,'#b89050',0.28,0.28,0.10);\n p(0.52,0.44,0.50,'#c8a870',0,0.32,0.22);p(0.46,0.36,0.44,'#b89050',0,0.30,-0.20);\n p(0.46,0.22,0.44,'#c8a870',0,0.58,0);\n p(0.14,0.14,0.06,'#f0f0e8',-0.14,0.42,0.30);p(0.08,0.09,0.04,'#1a1a1a',-0.14,0.42,0.33);\n p(0.14,0.14,0.06,'#f0f0e8',0.14,0.42,0.30);p(0.08,0.09,0.04,'#1a1a1a',0.14,0.42,0.33);\n p(0.22,0.08,0.06,'#604020',-0.14,0.54,0.30);p(0.22,0.08,0.06,'#604020',0.14,0.54,0.30);\n p(0.28,0.06,0.05,'#604020',0,0.30,0.33);\n p(0.16,0.14,0.14,'#a08050',-0.34,0.48,-0.12);p(0.12,0.10,0.10,'#604020',-0.28,0.56,0.14);\n p(0.16,0.14,0.14,'#a08050',0.34,0.48,-0.12);p(0.12,0.10,0.10,'#604020',0.28,0.56,0.14);\n p(0.20,0.16,0.18,'#c8a870',-0.46,0.28,0.12);p(0.24,0.20,0.22,'#a08050',-0.64,0.18,0.16);\n p(0.08,0.08,0.10,'#604020',-0.72,0.12,0.20);p(0.08,0.08,0.10,'#604020',-0.60,0.10,0.22);\n p(0.20,0.16,0.18,'#c8a870',0.46,0.28,0.12);p(0.24,0.20,0.22,'#a08050',0.64,0.18,0.16);\n p(0.08,0.08,0.10,'#604020',0.72,0.12,0.20);p(0.08,0.08,0.10,'#604020',0.60,0.10,0.22);\n return g;\n}", "buildHero_dragon_ball_no_complete": "function buildHero_dragon_ball_no_complete(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(1.00,0.78,1.18,'#e67e22',0,0.39,0);\n p(0.56,0.56,0.12,'#f3d9b1',0,0.36,0.53);\n p(0.34,0.20,0.24,'#e67e22',0,0.76,0.42);\n p(0.72,0.52,0.66,'#e67e22',0,1.06,0.70);\n p(0.46,0.24,0.26,'#e67e22',0,0.98,1.10);\n p(0.10,0.16,0.14,'#f3d9b1',-0.20,1.38,0.56);\n p(0.10,0.16,0.14,'#f3d9b1',0.20,1.38,0.56);\n const wGeo=geo(0.14,0.78,0.92);\n const wMatL=new THREE.MeshToonMaterial({color:'#2aa6a4',flatShading:true});\n const wMatR=new THREE.MeshToonMaterial({color:'#2aa6a4',flatShading:true});\n const wL=new THREE.Mesh(wGeo,wMatL); wL.position.set(-0.57,0.82,-0.02); wL.castShadow=true; g.add(wL);\n const wR=new THREE.Mesh(wGeo,wMatR); wR.position.set(0.57,0.82,-0.02); wR.castShadow=true; g.add(wR);\n p(0.24,0.28,0.28,'#e67e22',-0.24,0.14,0.12);\n p(0.24,0.28,0.28,'#e67e22',0.24,0.14,0.12);\n p(0.24,0.24,0.68,'#e67e22',0,0.30,-0.90);\n p(0.18,0.18,0.18,'#f4c542',0,0.34,-1.32);\n return g;\n}", "buildCollectible": "function buildCollectible(){\n const g=new THREE.Group();\n const gem=new THREE.Mesh(geo(0.42,0.42,0.42),mat('#f4c542'));\n gem.position.set(0,0.21,0); gem.castShadow=true; g.add(gem);\n const star=new THREE.Mesh(geo(0.18,0.18,0.10),mat('#8c3b2a'));\n star.position.set(0,0.21,0.21); star.castShadow=true; g.add(star);\n const glow=new THREE.PointLight('#f4c542',0.8,5,2);\n glow.position.set(0,0.2,0.2); g.add(glow);\n return g;\n}", "buildPlatformTile": "function buildPlatformTile(){\n const g=new THREE.Group();\n const tile=new THREE.Mesh(geo(6.0,0.12,TILE.depth),mat('#d8c7a1'));\n tile.position.set(0,0.06,0); tile.receiveShadow=true; g.add(tile);\n const border=new THREE.Mesh(geo(5.7,0.02,TILE.depth-0.18),mat('#caa56a'));\n border.position.set(0,0.13,0); g.add(border);\n return g;\n}", "buildDecoA": "function buildDecoA(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.34,0.18,0.20,'#1a1a1a',0,0.09,0);p(0.62,0.52,0.34,'#caa56a',0,0.44,0);\n p(0.40,0.36,0.34,'#f3d9b1',0,0.88,0.04);p(0.24,0.22,0.12,'#f2f2f0',0,0.76,0.21);\n p(0.05,0.05,0.08,'#1a1a1a',-0.08,0.90,0.20);p(0.05,0.05,0.08,'#1a1a1a',0.08,0.90,0.20);\n return g;\n}", "buildDecoB": "function buildDecoB(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.46,0.24,0.24,'#8c3b2a',0,0.12,0);p(0.92,0.66,0.46,'#8c3b2a',0,0.57,0);\n p(0.52,0.38,0.36,'#caa56a',0,1.07,0.06);\n p(0.12,0.14,0.12,'#f3d9b1',-0.26,1.24,0.02);p(0.12,0.14,0.12,'#f3d9b1',0.26,1.24,0.02);\n return g;\n}", "buildDecoC": "function buildDecoC(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.12,0.26,0.12,'#5e2418',-0.08,0.13,0);p(0.12,0.26,0.12,'#5e2418',0.08,0.13,0);\n p(0.42,0.42,0.24,'#2aa6a4',0,0.47,0);p(0.30,0.28,0.24,'#f3d9b1',0,0.82,0.02);\n p(0.32,0.12,0.26,'#5e2418',0,0.96,0.02);p(0.10,0.16,0.12,'#5e2418',-0.15,0.84,0.10);\n return g;\n}", "buildBackgroundProp": "function buildBackgroundProp(){\n const g=new THREE.Group();\n function p(w,h,d,c,x,y,z){const m=new THREE.Mesh(geo(w,h,d),mat(c));m.position.set(x,y,z);m.castShadow=true;g.add(m);}\n p(0.34,0.28,0.18,'#5e2418',0,0.14,0);p(0.52,0.50,0.26,'#caa56a',0,0.53,0);\n p(0.66,0.16,0.16,'#caa56a',0,0.54,0.12);p(0.32,0.30,0.28,'#f3d9b1',0,0.93,0.02);\n p(0.34,0.12,0.30,'#5e2418',0,1.08,0.02);\n return g;\n}", "buildStaticWorld": "function buildStaticWorld(){\n bgGroup=new THREE.Group(); scene.add(bgGroup);\n const groundMat=mat('#e6d29a');\n const sideGeo=geo(8,0.2,60);\n const lG=new THREE.Mesh(sideGeo,groundMat); lG.position.set(-7.5,-0.24,-18); bgGroup.add(lG);\n const rG=new THREE.Mesh(sideGeo,groundMat); rG.position.set(7.5,-0.24,-18); bgGroup.add(rG);\n for(let i=0;i<4;i++){\n const prop=buildBackgroundProp(); prop.scale.setScalar(1.6);\n prop.position.set(i%2===0?-6.0:6.0,0,-12-i*8); bgGroup.add(prop);\n }\n}", "buildHero_jungle": "function buildHero_jungle() {\n const g = new THREE.Group();\n g.name = 'hero';\n addPart(g, geos.heroBody, materials.heroDark, 0, 0.69, 0, 'body');\n addPart(g, geos.heroChest, materials.heroChest, 0, 0.64, 0.33, 'chest_plate');\n addPart(g, geos.heroHead, materials.heroDark, 0, 1.35, 0.10, 'head');\n addPart(g, geos.heroBrow, materials.heroDark, 0, 1.46, 0.31, 'brow');\n addPart(g, geos.heroMuzzle, materials.heroChest, 0, 1.24, 0.34, 'muzzle');\n addPart(g, geos.eye, materials.black, -0.14, 1.33, 0.37, 'eye_l');\n addPart(g, geos.eye, materials.black, 0.14, 1.33, 0.37, 'eye_r');\n addPart(g, geos.arm, materials.heroDark, -0.62, 0.49, 0.05, 'arm_l');\n addPart(g, geos.arm, materials.heroDark, 0.62, 0.49, 0.05, 'arm_r');\n addPart(g, geos.leg, materials.heroDark, -0.22, 0.17, 0, 'leg_l');\n addPart(g, geos.leg, materials.heroDark, 0.22, 0.17, 0, 'leg_r');\n\n g.position.set(0, PHYSICS.playerGroundY, SPAWN.heroZ);\n g.userData = { hitTimer: 0, hitFlash: 0, collectTimer: 0 };\n return g;\n}", "buildObstacleGround": "function buildObstacleGround() {\n const g = new THREE.Group();\n g.name = 'obstacle_ground';\n addPart(g, geos.logBody, materials.earth, 0, 0.18, 0, 'log_body');\n addPart(g, geos.logCap, materials.bark, -0.64, 0.18, 0, 'end_cap_l');\n addPart(g, geos.logCap, materials.bark, 0.64, 0.18, 0, 'end_cap_r');\n g.userData = { bobAmp: 0.08, bobPhase: Math.random() * Math.PI * 2, baseY: 0 };\n return g;\n}", "buildObstacleAerial": "function buildObstacleAerial() {\n const g = new THREE.Group();\n g.name = 'obstacle_aerial';\n addPart(g, geos.toucanBody, materials.heroDark, 0, 0.21, 0, 'body');\n addPart(g, geos.toucanHead, materials.heroDark, 0, 0.48, 0.20, 'head');\n addPart(g, geos.toucanBeakBase, materials.fruitOrange, 0, 0.48, 0.6, 'beak_base');\n addPart(g, geos.toucanBeakTip, materials.fruitGold, 0, 0.5, 0.95, 'beak_tip');\n addPart(g, geos.toucanWing, materials.fruitGold, -0.56, 0.24, 0, 'wing_l');\n addPart(g, geos.toucanWing, materials.fruitGold, 0.56, 0.24, 0, 'wing_r');\n addPart(g, geos.toucanEye, materials.black, -0.1, 0.52, 0.34, 'eye_l');\n addPart(g, geos.toucanEye, materials.black, 0.1, 0.52, 0.34, 'eye_r');\n g.userData = { bobAmp: 0.10, bobPhase: Math.random() * Math.PI * 2, baseY: 0, wingFlip: Math.random() * 10 };\n return g;\n}", "buildBackgroundWall": "function buildBackgroundWall(x, z, scaleY) {\n const mesh = new THREE.Mesh(geos.backgroundBlock, materials.moss);\n mesh.position.set(x, 0.9 * scaleY, z);\n mesh.scale.y = scaleY;\n return mesh;\n}", "buildCanopy": "function buildCanopy(z, y) {\n const mesh = new THREE.Mesh(geos.canopyBlock, materials.moss);\n mesh.position.set(0, y, z);\n return mesh;\n}", "buildHero_pokemon": "function buildHero_pokemon() {\n const hero = new THREE.Group();\n\n // Body\n const bodyGeom = buildSphere(0.38, 8, 6);\n const body = new THREE.Mesh(bodyGeom, MAT_BODY);\n body.position.set(0, 0.4, 0);\n body.castShadow = true;\n hero.add(body);\n\n // Belly patch\n const bellyGeom = buildSphere(0.22, 6, 5);\n const belly = new THREE.Mesh(bellyGeom, MAT_BELLY);\n belly.position.set(0, 0.34, 0.3);\n belly.scale.set(1, 0.7, 0.4);\n hero.add(belly);\n\n // Bulb on back\n const bulbGeom = buildSphere(0.22, 6, 5);\n const bulb = new THREE.Mesh(bulbGeom, MAT_BULB);\n bulb.position.set(0, 0.72, -0.2);\n hero.add(bulb);\n\n // Bulb inner (lighter)\n const bulbInnerGeom = buildSphere(0.12, 5, 4);\n const bulbInner = new THREE.Mesh(bulbInnerGeom, MAT_BELLY);\n bulbInner.position.set(0, 0.85, -0.14);\n hero.add(bulbInner);\n\n // Eyes\n const eyeGeom = buildSphere(0.07, 5, 4);\n const eyeL = new THREE.Mesh(eyeGeom, MAT_EYE);\n const eyeR = eyeL.clone();\n eyeL.position.set(-0.18, 0.52, 0.32);\n eyeR.position.set( 0.18, 0.52, 0.32);\n hero.add(eyeL, eyeR);\n\n // Legs (4)\n const legGeom = buildBox(0.15, 0.22, 0.18);\n const legPositions = [\n [-0.22, 0.12, 0.16], [ 0.22, 0.12, 0.16],\n [-0.20, 0.12,-0.12], [ 0.20, 0.12,-0.12],\n ];\n legPositions.forEach(p => {\n const leg = new THREE.Mesh(legGeom, MAT_BODY);\n leg.position.set(...p);\n leg.castShadow = true;\n hero.add(leg);\n });\n\n return hero;\n}", "buildHero_wreck_it": "function buildHero_wreck_it() {\n const group = new THREE.Group();\n group.add(makePart(GEO.g026_052_028, MAT.brown, -0.22, 0.26, 0, false)); // leg_l\n group.add(makePart(GEO.g026_052_028, MAT.brown, 0.22, 0.26, 0, false)); // leg_r\n group.add(makePart(GEO.g100_092_062, MAT.red, 0, 0.98, 0, false)); // torso\n group.add(makePart(GEO.g014_076_008, MAT.brown, -0.20, 1.06, 0.27, false)); // overall_strap_l\n group.add(makePart(GEO.g014_076_008, MAT.brown, 0.20, 1.06, 0.27, false)); // overall_strap_r\n group.add(makePart(GEO.g022_052_022, MAT.red, -0.61, 0.96, 0.02, false)); // arm_l\n group.add(makePart(GEO.g022_052_022, MAT.red, 0.61, 0.96, 0.02, false)); // arm_r\n group.add(makePart(GEO.g034_028_034, MAT.skin, -0.61, 0.74, 0.23, true)); // fist_l\n group.add(makePart(GEO.g034_028_034, MAT.skin, 0.61, 0.74, 0.23, true)); // fist_r\n group.add(makePart(GEO.g070_054_056, MAT.skin, 0, 1.75, 0.05, false)); // head\n group.add(makePart(GEO.g076_018_038, MAT.darkBrown, 0, 2.11, 0.02, false)); // hair_main\n group.add(makePart(GEO.g020_016_018, MAT.darkBrown, -0.24, 2.19, 0.10, false)); // hair_lump_l\n group.add(makePart(GEO.g016_012_016, MAT.darkBrown, 0.22, 2.17, -0.02, false)); // hair_lump_r\n return group;\n}", "buildCandyCastleTower": "function buildCandyCastleTower() {\n const group = new THREE.Group();\n group.add(makePart(GEO.g110_140_110, MAT.blue, 0, 0.70, 0, false)); // tower_base\n group.add(makePart(GEO.g072_062_072, MAT.pink, 0, 1.71, 0, false)); // tower_mid\n group.add(makePart(GEO.g040_026_040, MAT.cream, 0, 2.15, 0, true)); // tower_cap\n return group;\n}", "buildLollipopPost": "function buildLollipopPost() {\n const group = new THREE.Group();\n group.add(makePart(GEO.g014_180_014, MAT.brown, 0, 0.90, 0, false)); // pole\n group.add(makePart(GEO.g062_062_012, MAT.pink, 0, 1.74, 0, true)); // sign_face\n group.add(makePart(GEO.g046_010_013, MAT.cream, 0, 1.74, 0.01, false)); // stripe_h\n group.add(makePart(GEO.g010_046_013, MAT.cream, 0, 1.74, 0.01, false)); // stripe_v\n return group;\n}", "buildArcadeBeacon": "function buildArcadeBeacon() {\n const group = new THREE.Group();\n group.add(makePart(GEO.g046_046_046, MAT.blue, 0, 1.60, 0, true)); // beacon_body\n group.add(makePart(GEO.g062_010_062, MAT.gold, 0, 1.93, 0, false)); // halo\n return group;\n}", "buildDistantSugarHills": "function buildDistantSugarHills() {\n const group = new THREE.Group();\n group.add(makePart(GEO.g800_160_220, MAT.blue, 0, 0.80, -22, false)); // hill_back\n group.add(makePart(GEO.g640_120_200, MAT.pink, -1.20, 0.60, -20, false)); // hill_mid\n group.add(makePart(GEO.g520_096_180, MAT.cream, 1.60, 0.48, -18, false)); // hill_front\n return group;\n}", "buildFruitCollectible": "function buildFruitCollectible() {\n const group = new THREE.Group();\n addPart(group, WORLD_GEOMETRY.fruitBase, WORLD_MATERIALS.accent, 0, 0.12, 0, 'fruit_base');\n addPart(group, WORLD_GEOMETRY.fruitMid, WORLD_MATERIALS.accent, 0, 0.31, 0, 'fruit_mid');\n addPart(group, WORLD_GEOMETRY.fruitTop, WORLD_MATERIALS.obstacleAlt, 0, 0.46, 0, 'fruit_top');\n addPart(group, WORLD_GEOMETRY.bananaStem, WORLD_MATERIALS.decorMain, 0, 0.64, 0, 'fruit_stem');\n group.userData.type = 'fruit';\n return group;\n}", "buildCheckpointBanana": "function buildCheckpointBanana() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.36, 0.16, 0.22), WORLD_MATERIALS.checkpoint, -0.18, 0.3, 0, 'banana_l', { rotation: { z: -0.25 } });\n addPart(group, new THREE.BoxGeometry(0.36, 0.16, 0.22), WORLD_MATERIALS.checkpoint, 0.18, 0.3, 0, 'banana_r', { rotation: { z: 0.25 } });\n addPart(group, WORLD_GEOMETRY.bananaStem, WORLD_MATERIALS.decorMain, 0, 0.54, 0, 'banana_stem');\n addPart(group, WORLD_GEOMETRY.pedestalMini, WORLD_MATERIALS.emissive, 0, 0.02, 0, 'banana_glow');\n group.userData.type = 'checkpoint';\n return group;\n}", "buildToucanGlider": "function buildToucanGlider() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(1.0, 0.42, 0.6), WORLD_MATERIALS.obstacleMain, 0, 0.2, 0, 'body');\n addPart(group, new THREE.BoxGeometry(0.44, 0.34, 0.34), WORLD_MATERIALS.obstacleMain, 0, 0.46, 0.2, 'head');\n addPart(group, new THREE.BoxGeometry(0.24, 0.18, 0.44), WORLD_MATERIALS.obstacleAlt, 0, 0.44, 0.6, 'beak');\n addPart(group, new THREE.BoxGeometry(0.14, 0.12, 0.92), WORLD_MATERIALS.accent, -0.56, 0.26, 0, 'wing_l');\n addPart(group, new THREE.BoxGeometry(0.14, 0.12, 0.92), WORLD_MATERIALS.accent, 0.56, 0.26, 0, 'wing_r');\n group.userData.animKind = 'fly';\n group.userData.baseY = 1.8;\n group.userData.collisionHalf = COLLISION.aerialObstacleHalf;\n return group;\n}", "buildBambooSpikes": "function buildBambooSpikes() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(1.2, 0.18, 0.6), WORLD_MATERIALS.obstacleAlt, 0, 0.09, 0, 'base');\n addPart(group, new THREE.BoxGeometry(0.18, 0.72, 0.18), WORLD_MATERIALS.obstacleMain, -0.28, 0.42, 0, 'spike_l');\n addPart(group, new THREE.BoxGeometry(0.18, 0.86, 0.18), WORLD_MATERIALS.obstacleMain, 0, 0.49, 0, 'spike_m');\n addPart(group, new THREE.BoxGeometry(0.18, 0.68, 0.18), WORLD_MATERIALS.obstacleMain, 0.28, 0.38, 0, 'spike_r');\n group.userData.animKind = 'still';\n group.userData.baseY = 0;\n group.userData.collisionHalf = COLLISION.groundObstacleHalf;\n return group;\n}", "buildBambooBundle": "function buildBambooBundle() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(1.1, 0.62, 0.62), WORLD_MATERIALS.obstacleMain, 0, 0.31, 0, 'bundle');\n addPart(group, new THREE.BoxGeometry(1.2, 0.08, 0.08), WORLD_MATERIALS.accent, 0, 0.22, 0.24, 'band_1');\n addPart(group, new THREE.BoxGeometry(1.2, 0.08, 0.08), WORLD_MATERIALS.accent, 0, 0.4, -0.24, 'band_2');\n group.userData.animKind = 'roll';\n group.userData.baseY = 1.1;\n group.userData.collisionHalf = COLLISION.aerialObstacleHalf;\n return group;\n}", "buildStoneWall": "function buildStoneWall(options) {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(1.2, 1.0, 0.44), WORLD_MATERIALS.obstacleMain, 0, 0.5, 0, 'wall');\n addPart(group, new THREE.BoxGeometry(1.28, 0.18, 0.48), WORLD_MATERIALS.obstacleAlt, 0, 0.96, 0, 'cap');\n if (options && options.wallOfHonor) {\n addPart(group, new THREE.BoxGeometry(0.14, 0.14, 0.08), WORLD_MATERIALS.accent, -0.18, 0.55, 0.24, 'honor_l');\n addPart(group, new THREE.BoxGeometry(0.14, 0.14, 0.08), WORLD_MATERIALS.accent, 0.18, 0.55, 0.24, 'honor_r');\n }\n group.userData.animKind = 'still';\n group.userData.baseY = 0;\n group.userData.collisionHalf = COLLISION.groundObstacleHalf;\n return group;\n}", "buildDragonKite": "function buildDragonKite() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(1.1, 0.16, 0.82), WORLD_MATERIALS.obstacleAlt, 0, 0.1, 0, 'wing');\n addPart(group, new THREE.BoxGeometry(0.34, 0.22, 0.28), WORLD_MATERIALS.obstacleMain, 0, 0.18, 0.1, 'head');\n addPart(group, new THREE.BoxGeometry(0.12, 0.12, 0.9), WORLD_MATERIALS.accent, 0, 0.02, -0.48, 'tail');\n group.userData.animKind = 'glide';\n group.userData.baseY = 1.8;\n group.userData.collisionHalf = COLLISION.aerialObstacleHalf;\n return group;\n}", "buildDumpster": "function buildDumpster() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(1.1, 0.82, 0.72), WORLD_MATERIALS.obstacleMain, 0, 0.41, 0, 'bin');\n addPart(group, new THREE.BoxGeometry(1.12, 0.12, 0.76), WORLD_MATERIALS.obstacleAlt, 0, 0.86, -0.02, 'lid');\n group.userData.animKind = 'still';\n group.userData.baseY = 0;\n group.userData.collisionHalf = COLLISION.groundObstacleHalf;\n return group;\n}", "buildTaxi": "function buildTaxi() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(1.14, 0.52, 0.72), WORLD_MATERIALS.obstacleAlt, 0, 0.26, 0, 'body');\n addPart(group, new THREE.BoxGeometry(0.66, 0.26, 0.56), WORLD_MATERIALS.neutral, 0, 0.56, -0.02, 'roof');\n addPart(group, new THREE.BoxGeometry(0.18, 0.18, 0.18), WORLD_MATERIALS.dark, -0.34, 0.05, 0.22, 'wheel_lf');\n addPart(group, new THREE.BoxGeometry(0.18, 0.18, 0.18), WORLD_MATERIALS.dark, 0.34, 0.05, 0.22, 'wheel_rf');\n addPart(group, new THREE.BoxGeometry(0.18, 0.18, 0.18), WORLD_MATERIALS.dark, -0.34, 0.05, -0.22, 'wheel_lr');\n addPart(group, new THREE.BoxGeometry(0.18, 0.18, 0.18), WORLD_MATERIALS.dark, 0.34, 0.05, -0.22, 'wheel_rr');\n group.userData.animKind = 'hover_roll';\n group.userData.baseY = 1.25;\n group.userData.collisionHalf = COLLISION.aerialObstacleHalf;\n return group;\n}", "buildSkullRock": "function buildSkullRock() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(1.04, 0.84, 0.76), WORLD_MATERIALS.obstacleMain, 0, 0.42, 0, 'skull');\n addPart(group, new THREE.BoxGeometry(0.18, 0.18, 0.12), WORLD_MATERIALS.dark, -0.18, 0.52, 0.28, 'eye_l');\n addPart(group, new THREE.BoxGeometry(0.18, 0.18, 0.12), WORLD_MATERIALS.dark, 0.18, 0.52, 0.28, 'eye_r');\n addPart(group, new THREE.BoxGeometry(0.14, 0.18, 0.1), WORLD_MATERIALS.dark, 0, 0.34, 0.3, 'nose');\n group.userData.animKind = 'still';\n group.userData.baseY = 0;\n group.userData.collisionHalf = COLLISION.groundObstacleHalf;\n return group;\n}", "buildVulture": "function buildVulture() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.72, 0.32, 0.46), WORLD_MATERIALS.obstacleMain, 0, 0.18, 0, 'body');\n addPart(group, new THREE.BoxGeometry(0.28, 0.22, 0.22), WORLD_MATERIALS.obstacleMain, 0, 0.42, 0.18, 'head');\n addPart(group, new THREE.BoxGeometry(0.16, 0.08, 0.2), WORLD_MATERIALS.accent, 0, 0.36, 0.34, 'beak');\n addPart(group, new THREE.BoxGeometry(0.12, 0.08, 0.9), WORLD_MATERIALS.obstacleAlt, -0.46, 0.22, 0, 'wing_l');\n addPart(group, new THREE.BoxGeometry(0.12, 0.08, 0.9), WORLD_MATERIALS.obstacleAlt, 0.46, 0.22, 0, 'wing_r');\n group.userData.animKind = 'vulture';\n group.userData.baseY = 1.9;\n group.userData.collisionHalf = COLLISION.aerialObstacleHalf;\n return group;\n}", "buildMonkeyLookout": "function buildMonkeyLookout() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.9, 0.1, 0.2), WORLD_MATERIALS.obstacleMain, 0, 0.42, 0, 'branch');\n addPart(group, new THREE.BoxGeometry(0.34, 0.3, 0.28), WORLD_MATERIALS.neutral, 0, 0.72, 0, 'body');\n addPart(group, new THREE.BoxGeometry(0.24, 0.22, 0.22), WORLD_MATERIALS.neutral, 0.08, 0.98, 0.06, 'head');\n addPart(group, new THREE.BoxGeometry(0.1, 0.24, 0.1), WORLD_MATERIALS.obstacleMain, -0.18, 0.68, 0.04, 'arm_l');\n addPart(group, new THREE.BoxGeometry(0.1, 0.28, 0.1), WORLD_MATERIALS.obstacleMain, 0.18, 0.62, 0.08, 'arm_r');\n addPart(group, new THREE.BoxGeometry(0.1, 0.1, 0.48), WORLD_MATERIALS.obstacleMain, -0.22, 0.58, -0.18, 'tail');\n group.userData.animKind = 'watcher';\n return group;\n}", "buildParrotHover": "function buildParrotHover() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.38, 0.34, 0.3), WORLD_MATERIALS.obstacleAlt, 0, 0.82, 0.06, 'body');\n addPart(group, new THREE.BoxGeometry(0.26, 0.24, 0.24), WORLD_MATERIALS.obstacleAlt, 0, 1.06, 0.14, 'head');\n addPart(group, new THREE.BoxGeometry(0.12, 0.1, 0.2), WORLD_MATERIALS.accent, 0, 1.0, 0.34, 'beak');\n addPart(group, new THREE.BoxGeometry(0.12, 0.14, 0.58), WORLD_MATERIALS.accent, -0.24, 0.84, 0.08, 'wing_l');\n addPart(group, new THREE.BoxGeometry(0.12, 0.14, 0.58), WORLD_MATERIALS.accent, 0.24, 0.84, 0.08, 'wing_r');\n group.userData.animKind = 'hover';\n return group;\n}", "buildLemurWatcher": "function buildLemurWatcher() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.3, 0.34, 0.24), WORLD_MATERIALS.decorAlt, 0, 0.72, 0, 'body');\n addPart(group, new THREE.BoxGeometry(0.24, 0.22, 0.22), WORLD_MATERIALS.decorMain, 0, 0.98, 0.04, 'head');\n addPart(group, new THREE.BoxGeometry(0.1, 0.62, 0.1), WORLD_MATERIALS.decorMain, 0.18, 0.42, -0.08, 'tail');\n group.userData.animKind = 'watcher';\n return group;\n}", "buildElephantBackdrop": "function buildElephantBackdrop() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(1.2, 0.72, 0.72), WORLD_MATERIALS.decorAlt, 0, 0.52, 0, 'body');\n addPart(group, new THREE.BoxGeometry(0.46, 0.42, 0.42), WORLD_MATERIALS.decorAlt, 0.48, 0.6, 0.02, 'head');\n addPart(group, new THREE.BoxGeometry(0.16, 0.42, 0.16), WORLD_MATERIALS.decorMain, 0.58, 0.26, 0.18, 'trunk');\n group.userData.animKind = 'slow';\n return group;\n}", "buildBambooStalk": "function buildBambooStalk() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.2, 1.8, 0.2), WORLD_MATERIALS.decorMain, 0, 0.9, 0, 'stalk');\n addPart(group, new THREE.BoxGeometry(0.5, 0.1, 0.24), WORLD_MATERIALS.groundAccent, -0.22, 1.45, 0, 'leaf_l', { rotation: { z: 0.35 } });\n addPart(group, new THREE.BoxGeometry(0.5, 0.1, 0.24), WORLD_MATERIALS.groundAccent, 0.22, 1.3, 0, 'leaf_r', { rotation: { z: -0.35 } });\n group.userData.animKind = 'sway';\n return group;\n}", "buildFireflyCluster": "function buildFireflyCluster() {\n const group = new THREE.Group();\n for (let i = 0; i < 3; i++) {\n const lightOrb = addPart(group, new THREE.BoxGeometry(0.06, 0.06, 0.06), WORLD_MATERIALS.emissive, randRange(-0.2, 0.2), randRange(0.8, 1.3), randRange(-0.2, 0.2), 'orb_' + i);\n const point = new THREE.PointLight(0xffeb88, 0.25, 3, 2);\n point.position.copy(lightOrb.position);\n group.add(point);\n }\n group.userData.animKind = 'fireflies';\n return group;\n}", "buildGuardTower": "function buildGuardTower() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.8, 1.8, 0.8), WORLD_MATERIALS.decorMain, 0, 0.9, 0, 'tower');\n addPart(group, new THREE.BoxGeometry(1.0, 0.16, 1.0), WORLD_MATERIALS.obstacleAlt, 0, 1.74, 0, 'roof');\n group.userData.animKind = 'slow';\n return group;\n}", "buildLanternPost": "function buildLanternPost() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.12, 1.8, 0.12), WORLD_MATERIALS.decorMain, 0, 0.9, 0, 'post');\n addPart(group, new THREE.BoxGeometry(0.38, 0.38, 0.38), WORLD_MATERIALS.emissive, 0, 1.54, 0, 'lantern');\n group.userData.animKind = 'lantern';\n return group;\n}", "buildNeonSign": "function buildNeonSign() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.18, 1.4, 0.18), WORLD_MATERIALS.decorMain, 0, 0.7, 0, 'post');\n addPart(group, new THREE.BoxGeometry(0.92, 0.34, 0.14), WORLD_MATERIALS.sign, 0.44, 1.18, 0, 'panel');\n group.userData.animKind = 'neon';\n return group;\n}", "buildHydrant": "function buildHydrant() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.26, 0.44, 0.26), WORLD_MATERIALS.obstacleAlt, 0, 0.22, 0, 'body');\n addPart(group, new THREE.BoxGeometry(0.46, 0.14, 0.14), WORLD_MATERIALS.obstacleAlt, 0, 0.3, 0, 'crossbar');\n group.userData.animKind = 'still';\n return group;\n}", "buildStreetlamp": "function buildStreetlamp() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.12, 1.9, 0.12), WORLD_MATERIALS.decorMain, 0, 0.95, 0, 'pole');\n addPart(group, new THREE.BoxGeometry(0.52, 0.08, 0.08), WORLD_MATERIALS.decorMain, 0.18, 1.72, 0, 'arm');\n addPart(group, new THREE.BoxGeometry(0.22, 0.3, 0.22), WORLD_MATERIALS.emissive, 0.42, 1.5, 0, 'lamp');\n group.userData.animKind = 'lamp';\n return group;\n}", "buildCactus": "function buildCactus() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.34, 1.1, 0.34), WORLD_MATERIALS.decorMain, 0, 0.55, 0, 'stem');\n addPart(group, new THREE.BoxGeometry(0.18, 0.52, 0.18), WORLD_MATERIALS.decorMain, -0.22, 0.68, 0, 'arm_l');\n addPart(group, new THREE.BoxGeometry(0.18, 0.46, 0.18), WORLD_MATERIALS.decorMain, 0.22, 0.56, 0, 'arm_r');\n group.userData.animKind = 'slow';\n return group;\n}", "buildBones": "function buildBones() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.6, 0.12, 0.12), WORLD_MATERIALS.decorAlt, -0.14, 0.06, 0, 'bone_l', { rotation: { z: 0.35 } });\n addPart(group, new THREE.BoxGeometry(0.6, 0.12, 0.12), WORLD_MATERIALS.decorAlt, 0.14, 0.06, 0, 'bone_r', { rotation: { z: -0.35 } });\n group.userData.animKind = 'still';\n return group;\n}", "buildDustDevil": "function buildDustDevil() {\n const group = new THREE.Group();\n addPart(group, new THREE.BoxGeometry(0.18, 1.2, 0.18), WORLD_MATERIALS.groundAccent, 0, 0.6, 0, 'core');\n addPart(group, new THREE.BoxGeometry(0.44, 0.08, 0.44), WORLD_MATERIALS.obstacleAlt, 0, 0.22, 0, 'ring_1');\n addPart(group, new THREE.BoxGeometry(0.62, 0.08, 0.62), WORLD_MATERIALS.obstacleAlt, 0, 0.64, 0, 'ring_2');\n addPart(group, new THREE.BoxGeometry(0.78, 0.08, 0.78), WORLD_MATERIALS.obstacleAlt, 0, 1.0, 0, 'ring_3');\n group.userData.animKind = 'dust_devil';\n return group;\n}", "buildBiomeObstacle": "function buildBiomeObstacle(biome, type, options) {\n const key = type === 'ground' ? biome.obstacleKinds.ground : biome.obstacleKinds.aerial;\n const builder = OBSTACLE_BUILDERS[key];\n if (!builder) return buildFallenLog();\n const obstacle = builder(options || {});\n obstacle.name = key;\n obstacle.userData.type = type;\n return obstacle;\n}", "buildBiomeDecor": "function buildBiomeDecor(kind) {\n const builder = DECOR_BUILDERS[kind] || buildMonkeyLookout;\n const decor = builder();\n decor.name = kind;\n return decor;\n}", "buildSelectionScene": "function buildSelectionScene() {\n clearGroup(selectionGroup);\n selectionDisplays.length = 0;\n applyBiomeMaterials(getBiome(0));\n scene.background.setHex(getBiome(0).background);\n scene.fog.color.setHex(getBiome(0).fog);\n scene.fog.near = 18;\n scene.fog.far = 52;\n for (let i = 0; i < SELECT_LAYOUT.length; i++) {\n const layout = SELECT_LAYOUT[i];\n const display = createSelectionDisplay(layout.key);\n display.position.set(layout.x, 0, layout.z);\n selectionGroup.add(display);\n selectionDisplays.push(display);\n }\n camera.position.set(CAMERA.select.x, CAMERA.select.y, CAMERA.select.z);\n tempCameraLook.set(CAMERA.select.lookAt.x, CAMERA.select.lookAt.y, CAMERA.select.lookAt.z);\n camera.lookAt(tempCameraLook);\n}", "buildPatternForBiome": "function buildPatternForBiome() {\n const base = JSON.parse(JSON.stringify(pickOne(PATTERN_LIBRARY)));\n const used = {};\n for (let i = 0; i < base.obstacles.length; i++) {\n if (base.obstacles[i].lane === null) {\n let lane = randInt(0, 2);\n while (used[lane]) lane = randInt(0, 2);\n used[lane] = true;\n base.obstacles[i].lane = lane;\n }\n }\n for (let i = 0; i < base.fruits.length; i++) {\n if (base.fruits[i].lane === null) base.fruits[i].lane = randInt(0, 2);\n }\n\n if (currentBiome.specialHazard === 'bamboo_wall' && totalRunTime > 8 && Math.random() < 0.18) {\n const lane = randInt(0, 1);\n base.obstacles.push({ type: 'ground', lane, zOffset: -1.1 });\n base.obstacles.push({ type: 'aerial', lane: lane + 1, zOffset: -2.2 });\n }\n if (currentBiome.specialHazard === 'double_step' && totalRunTime > 12 && Math.random() < 0.2) {\n const lane = randInt(0, 2);\n base.obstacles.push({ type: 'ground', lane, zOffset: -1.25 });\n }\n if (bananaHoardTimer > 0) {\n const extra = [];\n for (let i = 0; i < base.fruits.length; i++) {\n extra.push({ lane: clamp(base.fruits[i].lane - 1, 0, 2), zOffset: base.fruits[i].zOffset - 0.4 });\n extra.push({ lane: clamp(base.fruits[i].lane + 1, 0, 2), zOffset: base.fruits[i].zOffset - 0.8 });\n }\n base.fruits = base.fruits.concat(extra);\n }\n return base;\n}" }