import * as THREE from 'three'; import type { SceneResourceBag } from '@/scene/resources'; export function createRoad(resources: SceneResourceBag) { const group = new THREE.Group(); const roadGeometry = resources.own('geometry', new THREE.PlaneGeometry(18, 240)); const roadMaterial = resources.own('material', new THREE.MeshStandardMaterial({ color: 0x070b16, roughness: 0.88, metalness: 0.12, })); const road = new THREE.Mesh(roadGeometry, roadMaterial); road.rotation.x = -Math.PI / 2; road.position.z = -92; group.add(road); const edgeGeometry = resources.own('geometry', new THREE.BoxGeometry(0.12, 0.035, 240)); const edgeMaterial = resources.own('material', new THREE.MeshBasicMaterial({ color: 0x38dff2 })); for (const x of [-8.65, 8.65]) { const edge = new THREE.Mesh(edgeGeometry, edgeMaterial); edge.position.set(x, 0.035, -92); group.add(edge); } const markerGeometry = resources.own('geometry', new THREE.BoxGeometry(0.14, 0.025, 3.8)); const markerMaterial = resources.own('material', new THREE.MeshBasicMaterial({ color: 0xff9e68 })); const markers: Array<{ position: { z: number } }> = []; for (let index = 0; index < 22; index += 1) { const marker = new THREE.Mesh(markerGeometry, markerMaterial); marker.position.set(0, 0.045, 8 - index * 10); markers.push(marker); group.add(marker); } return { group, update(distance: number, speed: number) { const flow = distance * (5 + speed * 8); for (let index = 0; index < markers.length; index += 1) { const marker = markers[index]; if (!marker) continue; marker.position.z = 8 - modulo(index * 10 - flow, 220); } }, }; } function modulo(value: number, divisor: number): number { return ((value % divisor) + divisor) % divisor; }