import type { MachineAssetDefinition, MachineMetadata } from '../../types/viewer'; import { FOUR_STROKE_ENGINE_METADATA, createFourStrokeEngineAsset } from '../procedural/fourStrokeEngine'; const ASSET_BASE_URL = import.meta.env.VITE_MECHANICA_ASSET_BASE_URL?.replace(/\/$/, '') ?? '/assets/machines'; export const DEFAULT_DRACO_DECODER_PATH = '/draco/'; export const DEFAULT_KTX2_TRANSCODER_PATH = '/basis/'; export const MACHINE_ASSET_REGISTRY: Record = { [FOUR_STROKE_ENGINE_METADATA.id]: { id: FOUR_STROKE_ENGINE_METADATA.id, kind: 'procedural', metadata: FOUR_STROKE_ENGINE_METADATA, create: createFourStrokeEngineAsset } }; const MACHINE_ID_ALIASES: Record = { 'four-stroke-engine': FOUR_STROKE_ENGINE_METADATA.id, 'four-stroke-petrol': FOUR_STROKE_ENGINE_METADATA.id, 'petrol-engine': FOUR_STROKE_ENGINE_METADATA.id, 'gasoline-engine': FOUR_STROKE_ENGINE_METADATA.id, 'otto-cycle-engine': FOUR_STROKE_ENGINE_METADATA.id }; export function canonicalMachineId(machineId: string): string { const normalised = machineId .trim() .toLowerCase() .replace(/[_\s]+/g, '-') .replace(/[^a-z0-9-]/g, ''); return MACHINE_ID_ALIASES[normalised] ?? normalised; } export function registerMachineAsset(definition: MachineAssetDefinition): void { MACHINE_ASSET_REGISTRY[canonicalMachineId(definition.id)] = { ...definition, id: canonicalMachineId(definition.id) }; } export function getMachineAssetDefinition( machineId: string | null | undefined ): MachineAssetDefinition | undefined { if (!machineId) { return undefined; } return MACHINE_ASSET_REGISTRY[canonicalMachineId(machineId)]; } export function listMachineAssetDefinitions(): MachineAssetDefinition[] { return Object.values(MACHINE_ASSET_REGISTRY); } export function isMachineAssetSupported(machineId: string | null | undefined): boolean { return Boolean(getMachineAssetDefinition(machineId)); } export function createGltfMachineAssetDefinition( metadata: MachineMetadata, options: { fileName?: string; url?: string; dracoPath?: string | boolean; ktx2TranscoderPath?: string; meshopt?: boolean; partNameMap?: Record; preload?: boolean; } = {} ): MachineAssetDefinition { const id = canonicalMachineId(metadata.id); const fileName = options.fileName ?? 'model.glb'; return { id, kind: 'gltf', metadata: { ...metadata, id }, url: options.url ?? `${ASSET_BASE_URL}/${id}/${fileName}`, dracoPath: options.dracoPath, ktx2TranscoderPath: options.ktx2TranscoderPath, meshopt: options.meshopt, preload: options.preload, partNameMap: options.partNameMap }; } export const SUPPORTED_VIEWER_MACHINE_IDS = Object.keys(MACHINE_ASSET_REGISTRY);