{"version":3,"sources":["../src/playerController.ts","../src/utils/mobileControls.ts","../src/systems/AnimationSystem.ts","../src/systems/CameraSystem.ts","../src/systems/InputSystem.ts","../src/systems/VehicleSystem.ts","../src/utils/vehicleLoader.ts","../src/utils/pathPlanner.ts","../src/utils/vehicleController.ts","../src/utils/capsuleCollision.ts"],"sourcesContent":["import * as THREE from \"three\";\r\nimport { MeshBVH, BVHHelper, acceleratedRaycast } from \"three-mesh-bvh\";\r\nimport type { GLTF } from \"three/examples/jsm/Addons.js\";\r\nimport { OrbitControls } from \"three/examples/jsm/controls/OrbitControls.js\";\r\nimport { RoundedBoxGeometry } from \"three/examples/jsm/geometries/RoundedBoxGeometry.js\";\r\nimport { DRACOLoader } from \"three/examples/jsm/loaders/DRACOLoader.js\";\r\nimport { GLTFLoader } from \"three/examples/jsm/loaders/GLTFLoader.js\";\r\nimport * as BufferGeometryUtils from \"three/examples/jsm/utils/BufferGeometryUtils.js\";\r\n\r\nimport { MobileControls } from \"./utils/mobileControls\";\r\nimport type { PlayerControllerOptions, PlayerModelOptions, VehicleInstance, VehicleOptions, DynamicColliderEntry, KeyMap } from \"./types\";\r\nimport { AnimationSystem } from \"./systems/AnimationSystem\";\r\nimport { CameraSystem } from \"./systems/CameraSystem\";\r\nimport { InputSystem } from \"./systems/InputSystem\";\r\nimport { VehicleSystem } from \"./systems/VehicleSystem\";\r\nimport { applyCapsuleCollision, createCollisionTemps, type CollisionTemps } from \"./utils/capsuleCollision\";\r\n\r\nTHREE.Mesh.prototype.raycast = acceleratedRaycast;\r\n\r\nconst clock = new THREE.Clock();\r\n\r\nfunction isMobileDevice() {\r\n    return /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent);\r\n}\r\n\r\nexport class playerController {\r\n\r\n    // ==================== 场景引用 ====================\r\n    loader: GLTFLoader = new GLTFLoader(); // GLTF加载器\r\n    scene!: THREE.Scene; // 三维场景\r\n    camera!: THREE.PerspectiveCamera; // 透视相机\r\n    controls!: OrbitControls; // 轨道控制器\r\n\r\n    // ==================== 玩家配置 ====================\r\n    playerModelConfig!: PlayerModelOptions; // 模型配置项\r\n    private initPos: THREE.Vector3 = new THREE.Vector3(0, 0, 0); // 初始出生位置\r\n    gravity = -2400; // 重力加速度\r\n    jumpHeight = 600; // 跳跃初速度\r\n    playerSpeed = 300; // 行走速度\r\n    playerFlySpeed = 2100; // 飞行速度\r\n    private curPlayerSpeed = 0; // 当前实际速度\r\n    enableOverShoulderView = false; // 越肩视角开关\r\n    private isShowMobileControls = true; // 显示移动端控件\r\n\r\n    // ==================== 玩家胶囊体 ====================\r\n    private playerCapsuleRadius = 30; // 胶囊体半径\r\n    private playerCapsuleRadiusRatio = 1; // 半径缩放比\r\n    private playerCapsuleHeight = 180; // 胶囊体高度\r\n    isFirstPerson = false; // 第一人称状态\r\n\r\n    // ==================== 运行状态 ====================\r\n    controllerMode: 0 | 1 = 0; // 0步行 1载具\r\n    playerIsOnGround = false; // 是否在地面\r\n    isupdate = true; // 帧更新开关\r\n    timeScale = 1; // 时间缩放系数\r\n    isFlying = false; // 飞行状态\r\n    isChangeControllerTransitionTimer: any = null; // 模式切换计时器\r\n    enableToward = true; // 启用朝向输入\r\n\r\n    // ==================== 玩家物体 ====================\r\n    playerCapsule!: THREE.Mesh & { capsuleInfo?: any }; // 玩家碰撞胶囊\r\n    playerModel: THREE.Object3D | null = null; // 模型根节点\r\n    playerModelHead: THREE.Object3D | null = null; // 头骨节点\r\n\r\n    // ==================== 碰撞体 ====================\r\n    collider: THREE.Mesh | null = null; // 静态碰撞体\r\n    private visualizer: BVHHelper | null = null; // BVH可视化\r\n    collected: THREE.BufferGeometry[] = []; // 静态几何收集\r\n    private dynamicColliders: DynamicColliderEntry[] = []; // 动态碰撞体列表\r\n    activeDynamicCollider: DynamicColliderEntry | null = null; // 当前站立的动态碰撞体\r\n\r\n    // ==================== 碰撞阈值 ====================\r\n    private readonly slopeAngleThreshold = 50; // 斜坡阈值（度）\r\n    private readonly maxStepHeight = 40; // 可跨越台阶/立面高度阈值\r\n\r\n    // ==================== 移动端 ====================\r\n    mobileControls: MobileControls | null = null; // 移动端控件\r\n    private isNearVehicle = false; // 靠近车辆\r\n    private nearCheckLocal = new THREE.Vector3(); // 近距检测局部坐标\r\n    private nearCheckWorld = new THREE.Vector3(); // 近距检测世界坐标\r\n\r\n    // ==================== 调试 ====================\r\n    private displayPlayer = false; // 显示玩家碰撞体\r\n    private displayCollider = false; // 显示场景碰撞体\r\n    private displayVisualizer = false; // 显示BVH辅助\r\n\r\n    // ==================== 方向常量 & 复用向量 ====================\r\n    private rotationSpeed = 10; // 朝向旋转速度\r\n    upVector = new THREE.Vector3(0, 1, 0); // 世界上方向\r\n    private DIR_FWD = new THREE.Vector3(0, 0, -1); // 前\r\n    private DIR_BKD = new THREE.Vector3(0, 0, 1); // 后\r\n    private DIR_LFT = new THREE.Vector3(-1, 0, 0); // 左\r\n    private DIR_RGT = new THREE.Vector3(1, 0, 0); // 右\r\n\r\n    playerAcceleration = 30; // XZ 加速响应速度\r\n    playerDeceleration = 30; // XZ 减速响应速度\r\n    private decelBase = 300; // 减速基准速度\r\n    playerVelocity = new THREE.Vector3(); // 玩家速度\r\n    private camDir = new THREE.Vector3(); // 相机方向缓存\r\n    private moveDir = new THREE.Vector3(); // 移动方向缓存\r\n    private xzDir = new THREE.Vector3(); // 步进方向缓存\r\n    targetQuat = new THREE.Quaternion(); // 目标四元数\r\n    targetMat = new THREE.Matrix4(); // 目标变换矩阵\r\n    private staticTemps: CollisionTemps = createCollisionTemps(); // 静态碰撞临时对象\r\n    private dynTemps: CollisionTemps = createCollisionTemps();    // 动态碰撞临时对象\r\n    private groundRaycaster = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3(0, -1, 0)); // 地面检测射线\r\n\r\n    // ==================== 事件回调 ====================\r\n    onAnimationChange?: (name: string, action: THREE.AnimationAction) => void; // 动画切换回调\r\n    onBeforeViewChange?: (isFirstPerson: boolean) => void; // 视角切换前回调\r\n    onViewChange?: (isFirstPerson: boolean) => void; // 视角切换后回调\r\n    onGroundChange?: (onGround: boolean) => void; // 落地状态回调\r\n    onVehicleEnter?: (vehicle: VehicleInstance) => void; // 上车回调\r\n    onVehicleExit?: (vehicle: VehicleInstance) => void; // 下车回调\r\n    onTowardChange?: (dx: number, dy: number, speed: number) => void; // 朝向变化回调\r\n\r\n    // ==================== 子系统 ====================\r\n    animation = new AnimationSystem(this); // 动画系统\r\n    cam = new CameraSystem(this); // 相机系统\r\n    input = new InputSystem(this); // 输入系统\r\n    vehicle = new VehicleSystem(this); // 载具系统\r\n\r\n    constructor() {\r\n        (this.groundRaycaster as any).firstHitOnly = true;\r\n    }\r\n\r\n    // ==================== 初始化 ====================\r\n\r\n    // 主初始化入口\r\n    async init(opts: PlayerControllerOptions, callback?: () => void) {\r\n        const m = opts.playerModelConfig;\r\n        const s = m.scale ?? 1;\r\n\r\n        this.scene = opts.scene;\r\n        this.camera = opts.camera;\r\n        this.camera.rotation.order = \"YXZ\";\r\n        this.controls = opts.controls;\r\n\r\n        this.playerModelConfig = m;\r\n        this.initPos = opts.initPos ? opts.initPos.clone() : this.initPos;\r\n\r\n        // 应用玩家参数\r\n        const pm = this.playerModelConfig;\r\n        this.gravity = (pm.gravity ?? this.gravity) * s;\r\n        this.jumpHeight = (pm.jumpHeight ?? this.jumpHeight) * s;\r\n        this.playerSpeed = (pm.speed ?? this.playerSpeed) * s;\r\n        this.playerFlySpeed = (pm.flySpeed ?? this.playerFlySpeed) * s;\r\n        this.curPlayerSpeed = this.playerSpeed;\r\n        this.playerCapsuleRadiusRatio = pm.capsuleRadiusRatio ?? this.playerCapsuleRadiusRatio;\r\n        this.playerAcceleration = pm.acceleration ?? this.playerAcceleration;\r\n        this.playerDeceleration = pm.deceleration ?? this.playerDeceleration;\r\n        this.decelBase = this.playerSpeed;\r\n\r\n        // 应用相机参数\r\n        this.cam.sensitivity = opts.mouseSensitivity ?? this.cam.sensitivity;\r\n        this.cam.mouseMode = opts.thirdMouseMode ?? this.cam.mouseMode;\r\n        this.cam.enableSpringCamera = opts.enableSpringCamera ?? this.cam.enableSpringCamera;\r\n        this.cam.springCameraTime = opts.springCameraTime ?? this.cam.springCameraTime;\r\n        this.cam.zoomEnabled = opts.enableZoom ?? this.cam.zoomEnabled;\r\n        this.cam.minDist = (opts.minCamDistance ?? this.cam.minDist) * s;\r\n        this.cam.maxDist = (opts.maxCamDistance ?? this.cam.maxDist) * s;\r\n        this.cam.lookAtHeightRatio = opts.camLookAtHeightRatio ?? this.cam.lookAtHeightRatio;\r\n        this.cam.originMaxDist = this.cam.maxDist;\r\n        this.cam.epsilon = this.cam.epsilon * s;\r\n\r\n        this.isShowMobileControls = (opts.isShowMobileControls ?? this.isShowMobileControls) && isMobileDevice();\r\n        this.enableOverShoulderView = opts.enableOverShoulderView ?? this.enableOverShoulderView;\r\n        this.isFirstPerson = opts.isFirstPerson ?? this.isFirstPerson;\r\n        this.timeScale = opts.timeScale ?? this.timeScale;\r\n\r\n        // 自定义键位\r\n        if (opts.keyMap) this.input.buildKeyMap(opts.keyMap);\r\n\r\n        // 初始化移动端控件\r\n        if (this.isShowMobileControls) {\r\n            this.mobileControls = new MobileControls(i => this.input.setInput(i), this.controls);\r\n            await this.mobileControls.init(opts.mobileControls);\r\n        }\r\n\r\n        await this.initLoader();\r\n        this.buildStaticCollider(opts.staticCollider);\r\n        await this.loadPlayerModelGLB();\r\n\r\n        // 初始化时注册动态碰撞体\r\n        if (opts.dynamicCollider) {\r\n            const list = Array.isArray(opts.dynamicCollider) ? opts.dynamicCollider : [opts.dynamicCollider];\r\n            for (const obj of list) this.addDynamicCollider(obj);\r\n        }\r\n\r\n        this.input.bindEvents();\r\n        this.cam.setCamPos();\r\n        this.cam.initControls();\r\n        this.cam.setOverShoulder(this.isFirstPerson ? false : this.enableOverShoulderView);\r\n        callback?.();\r\n    }\r\n\r\n    // 初始化加载器\r\n    private async initLoader() {\r\n        const dracoLoader = new DRACOLoader();\r\n        dracoLoader.setDecoderPath(\"https://unpkg.com/three@0.182.0/examples/jsm/libs/draco/gltf/\");\r\n        this.loader.setDRACOLoader(dracoLoader);\r\n    }\r\n\r\n    // ==================== 玩家模型 ====================\r\n\r\n    // 加载模型与动画\r\n    private async loadPlayerModelGLB() {\r\n        try {\r\n            const gltf = await this.loader.loadAsync(this.playerModelConfig.url) as GLTF;\r\n            this.playerModel = gltf.scene;\r\n\r\n            // 初始化动画混合器\r\n            this.animation.mixer = new THREE.AnimationMixer(this.playerModel);\r\n            const animations = gltf.animations ?? [];\r\n            this.animation.clips = animations;\r\n            this.animation.actions = new Map();\r\n\r\n            // 构建动作映射表\r\n            const mc = this.playerModelConfig;\r\n            const isThreePartJump = Array.isArray(mc.jumpAnim);\r\n            this.animation.hasThreePartJump = isThreePartJump;\r\n            const mappings: [string, string][] = [\r\n                [mc.idleAnim, \"idle\"],\r\n                [mc.walkAnim, \"walking\"],\r\n                [mc.leftWalkAnim || mc.walkAnim, \"left_walking\"],\r\n                [mc.rightWalkAnim || mc.walkAnim, \"right_walking\"],\r\n                [mc.backwardAnim || mc.walkAnim, \"walking_backward\"],\r\n                ...(isThreePartJump\r\n                    ? [] as [string, string][]\r\n                    : [[mc.jumpAnim as string, \"jumping\"]] as [string, string][]),\r\n                [mc.runAnim, \"running\"],\r\n                [mc.flyIdleAnim || mc.idleAnim, \"flyidle\"],\r\n                [mc.flyAnim || mc.idleAnim, \"flying\"],\r\n                [mc.flyHoverForwardAnim || mc.flyAnim || mc.idleAnim, \"flyHoverForward\"],\r\n                [mc.flyHoverBackAnim || mc.flyIdleAnim || mc.idleAnim, \"flyHoverBack\"],\r\n                [mc.flyHoverLeftAnim || mc.flyIdleAnim || mc.idleAnim, \"flyHoverLeft\"],\r\n                [mc.flyHoverRightAnim || mc.flyIdleAnim || mc.idleAnim, \"flyHoverRight\"],\r\n                [mc.flyHoverUpAnim || mc.flyIdleAnim || mc.idleAnim, \"flyHoverUp\"],\r\n                [mc.flyHoverDownAnim || mc.flyIdleAnim || mc.idleAnim, \"flyHoverDown\"],\r\n                [mc.enterCarAnim || mc.idleAnim, \"enterCar\"],\r\n                [mc.exitCarAnim || mc.idleAnim, \"exitCar\"],\r\n            ];\r\n\r\n            for (const [clipName, actionName] of mappings) {\r\n                const clip = animations.find(a => a.name === clipName);\r\n                if (!clip) continue;\r\n                const action = this.animation.mixer.clipAction(clip);\r\n                if (actionName === \"jumping\") {\r\n                    action.setLoop(THREE.LoopOnce, 1);\r\n                    action.clampWhenFinished = true;\r\n                    action.setEffectiveTimeScale(1.2);\r\n                } else {\r\n                    action.setLoop(THREE.LoopRepeat, Infinity);\r\n                    action.setEffectiveTimeScale(1);\r\n                }\r\n                action.enabled = true;\r\n                action.setEffectiveWeight(0);\r\n                this.animation.actions.set(actionName, action);\r\n            }\r\n\r\n            // 注册三段跳跃动画\r\n            if (isThreePartJump) {\r\n                const [startClip, loopClip, endClip] = mc.jumpAnim as [string, string, string];\r\n                const jumpDefs: [string, string, number, boolean][] = [\r\n                    [startClip, \"jumpStart\", THREE.LoopOnce, true],\r\n                    [loopClip, \"jumpLoop\", THREE.LoopRepeat, false],\r\n                    [endClip, \"jumpEnd\", THREE.LoopOnce, true],\r\n                ];\r\n                for (const [clipName, key, loop, clamp] of jumpDefs) {\r\n                    const clip = animations.find(a => a.name === clipName);\r\n                    if (!clip) { console.warn(`找不到跳跃动画 clip: \"${clipName}\"`); continue; }\r\n                    const action = this.animation.mixer!.clipAction(clip);\r\n                    action.setLoop(loop as THREE.AnimationActionLoopStyles, loop === THREE.LoopOnce ? 1 : Infinity);\r\n                    action.clampWhenFinished = clamp;\r\n                    action.setEffectiveTimeScale(key === \"jumpStart\" ? 1.2 : 1);\r\n                    action.enabled = true;\r\n                    action.setEffectiveWeight(0);\r\n                    this.animation.actions.set(key, action);\r\n                }\r\n            }\r\n\r\n            // 注册默认动作组\r\n            const defaultSet = new Map<string, THREE.AnimationAction>();\r\n            for (const key of [\"idle\", \"walking\", \"walking_backward\", \"running\", \"jumping\", \"flyidle\", \"flying\"]) {\r\n                const action = this.animation.actions.get(key);\r\n                if (action) defaultSet.set(key, action);\r\n            }\r\n            this.animation.sets.set(\"default\", defaultSet);\r\n\r\n            this.animation.actions.get(\"idle\")?.setEffectiveWeight(1);\r\n            this.animation.actions.get(\"idle\")?.play();\r\n            this.animation.state = this.animation.actions.get(\"idle\")!;\r\n\r\n            // 监听动画完成事件\r\n            this.animation.mixerCb = (ev: any) => {\r\n                const done: THREE.AnimationAction = ev.action;\r\n                const resolveGroundAnim = () => {\r\n                    if (this.input.fwd) { this.animation.playByName(this.input.shift ? \"running\" : \"walking\"); return; }\r\n                    if (this.input.bkd) { this.animation.playByName(\"walking_backward\"); return; }\r\n                    if (this.input.rgt || this.input.lft) { this.animation.playByName(\"walking\"); return; }\r\n                    this.animation.playByName(\"idle\");\r\n                };\r\n                if (done === this.animation.actions?.get(\"jumping\")) { resolveGroundAnim(); return; }\r\n                if (done === this.animation.actions?.get(\"jumpStart\")) { this.animation.playByName(\"jumpLoop\"); return; }\r\n                if (done === this.animation.actions?.get(\"jumpEnd\")) { resolveGroundAnim(); return; }\r\n                if (done === this.animation.actions?.get(\"enterCar\")) this.vehicle.onEnterAnimFinished();\r\n            };\r\n            this.animation.mixer.addEventListener(\"finished\", this.animation.mixerCb);\r\n\r\n            this.animation.mixer.update(0);\r\n            this.playerModel.updateMatrixWorld(true);\r\n\r\n            // 计算胶囊体尺寸\r\n            const { size } = this.getBbox(this.playerModel);\r\n            const modelScale = this.playerCapsuleHeight / size.y;\r\n\r\n            const s = this.playerModelConfig.scale;\r\n            const r = this.playerCapsuleRadius * s * this.playerCapsuleRadiusRatio;\r\n            const h = this.playerCapsuleHeight * s;\r\n\r\n            // 创建胶囊体网格\r\n            this.playerCapsule = new THREE.Mesh(\r\n                new RoundedBoxGeometry(r * 2, h, r * 2, 1, 75),\r\n                new THREE.MeshStandardMaterial({\r\n                    color: new THREE.Color(1, 0, 0),\r\n                    shadowSide: THREE.DoubleSide,\r\n                    depthTest: false,\r\n                    wireframe: true,\r\n                    depthWrite: false,\r\n                }),\r\n            );\r\n            const segmentLength = h - 2 * r;\r\n            this.playerCapsule.geometry.translate(0, -segmentLength / 2, 0);\r\n            this.playerCapsule.capsuleInfo = {\r\n                radius: r,\r\n                segment: new THREE.Line3(new THREE.Vector3(), new THREE.Vector3(0, -segmentLength, 0)),\r\n            };\r\n            this.playerCapsule.name = \"capsule\";\r\n            (this.playerCapsule.material as THREE.Material).visible = this.displayPlayer;\r\n            this.scene.add(this.playerCapsule);\r\n            this.reset();\r\n            this.playerCapsule.rotateY(this.playerModelConfig.rotateY ?? 0);\r\n\r\n            // 挂载模型到胶囊\r\n            this.playerModel.scale.multiplyScalar(modelScale * s);\r\n            this.playerModel.position.set(0, -segmentLength - r, 0);\r\n            this.playerModel.traverse((child: any) => {\r\n                if (child.name === this.playerModelConfig?.headBoneName) this.playerModelHead = child;\r\n            });\r\n            this.playerCapsule.add(this.playerModel);\r\n            this.reset();\r\n        } catch (e) {\r\n            console.error(\"加载玩家模型失败:\", e);\r\n        }\r\n    }\r\n\r\n    // 切换玩家模型\r\n    async switchPlayerModel(newPlayerModel: PlayerModelOptions) {\r\n        // 保存当前状态\r\n        const savedPos = this.playerCapsule.position.clone();\r\n        const savedQuat = this.playerCapsule.quaternion.clone();\r\n        const wasFirstPerson = this.isFirstPerson;\r\n\r\n        if (wasFirstPerson) this.scene.attach(this.camera);\r\n        if (this.playerCapsule) this.scene.remove(this.playerCapsule);\r\n        if (this.playerModel) { this.playerCapsule.remove(this.playerModel); this.playerModel = null; this.playerModelHead = null; }\r\n\r\n        // 清除旧动画资源\r\n        const anim = this.animation;\r\n        if (anim.mixer) {\r\n            if (anim.mixerCb) { anim.mixer.removeEventListener(\"finished\", anim.mixerCb); anim.mixerCb = undefined; }\r\n            anim.mixer.stopAllAction();\r\n            anim.mixer.uncacheRoot(anim.mixer.getRoot());\r\n            anim.mixer = undefined;\r\n            anim.actions = undefined;\r\n        }\r\n\r\n        // 更新比例相关参数\r\n        const ratio = newPlayerModel.scale / this.playerModelConfig.scale;\r\n        this.playerModelConfig = { ...this.playerModelConfig, ...newPlayerModel };\r\n\r\n        this.gravity *= ratio;\r\n        this.jumpHeight *= ratio;\r\n        this.playerSpeed *= ratio;\r\n        this.playerFlySpeed *= ratio;\r\n        this.curPlayerSpeed *= ratio;\r\n        this.cam.epsilon *= ratio;\r\n        this.cam.minDist *= ratio;\r\n        this.cam.maxDist *= ratio;\r\n        this.cam.originMaxDist *= ratio;\r\n\r\n        await this.loadPlayerModelGLB();\r\n        this.playerCapsule.position.copy(savedPos);\r\n        this.playerCapsule.quaternion.copy(savedQuat);\r\n        if (wasFirstPerson) this.cam.setFirstPerson();\r\n        this.setDebug(this.displayCollider);\r\n    }\r\n\r\n    // ==================== 碰撞体构建和查询 ====================\r\n\r\n    // 获取包围盒\r\n    private getBbox(object: THREE.Object3D) {\r\n        const bbox = new THREE.Box3().setFromObject(object);\r\n        const center = new THREE.Vector3();\r\n        const size = new THREE.Vector3();\r\n        bbox.getCenter(center);\r\n        bbox.getSize(size);\r\n        return { bbox, center, size };\r\n    }\r\n\r\n    // 补全必要属性\r\n    private ensureAttributesMinimal(geom: THREE.BufferGeometry): THREE.BufferGeometry | null {\r\n        if (!geom.attributes.position) return null;\r\n        if (!geom.attributes.normal) geom.computeVertexNormals();\r\n        if (!geom.attributes.uv) {\r\n            const count = geom.attributes.position.count;\r\n            geom.setAttribute(\"uv\", new THREE.BufferAttribute(new Float32Array(count * 2), 2));\r\n        }\r\n        return geom;\r\n    }\r\n\r\n    // 统一属性格式\r\n    private unifiedAttribute(collected: THREE.BufferGeometry[]) {\r\n        type AttrMeta = { itemSize: number; arrayCtor: any; examples: number; normalized: boolean };\r\n        const attrMap = new Map<string, AttrMeta>();\r\n        const attrConflict = new Set<string>();\r\n        const required = new Set([\"position\", \"normal\", \"uv\"]);\r\n\r\n        // 清除非必要属性\r\n        for (const g of collected)\r\n            for (const name of Object.keys(g.attributes))\r\n                if (!required.has(name)) g.deleteAttribute(name);\r\n\r\n        // 统计属性元信息\r\n        for (const g of collected) {\r\n            for (const name of Object.keys(g.attributes)) {\r\n                const attr = g.attributes[name] as THREE.BufferAttribute;\r\n                const ctor = (attr.array as any).constructor;\r\n                if (!attrMap.has(name)) {\r\n                    attrMap.set(name, { itemSize: attr.itemSize, arrayCtor: ctor, examples: 1, normalized: attr.normalized });\r\n                } else {\r\n                    const m = attrMap.get(name)!;\r\n                    if (m.itemSize !== attr.itemSize || m.arrayCtor !== ctor || m.normalized !== attr.normalized) attrConflict.add(name);\r\n                    else m.examples++;\r\n                }\r\n            }\r\n        }\r\n\r\n        // 移除冲突属性\r\n        for (const name of attrConflict) {\r\n            for (const g of collected) if (g.attributes[name]) g.deleteAttribute(name);\r\n            attrMap.delete(name);\r\n        }\r\n\r\n        // 补全缺失属性\r\n        for (const [name, meta] of attrMap) {\r\n            for (const g of collected) {\r\n                if (!g.attributes[name]) {\r\n                    const count = g.attributes.position.count;\r\n                    g.setAttribute(name, new THREE.BufferAttribute(new meta.arrayCtor(count * meta.itemSize), meta.itemSize, meta.normalized));\r\n                }\r\n            }\r\n        }\r\n        return collected;\r\n    }\r\n\r\n    // 构建静态碰撞体\r\n    buildStaticCollider(sources?: THREE.Object3D | THREE.Object3D[]) {\r\n        this.collected = [];\r\n        if (this.collider) { this.scene.remove(this.collider); this.collider = null; }\r\n\r\n        const collectMesh = (mesh: THREE.Mesh | THREE.LineSegments) => {\r\n            try {\r\n                let geom = mesh.geometry.clone();\r\n                geom.applyMatrix4(mesh.matrixWorld);\r\n                if (geom.index) geom = geom.toNonIndexed();\r\n                const safe = this.ensureAttributesMinimal(geom);\r\n                if (safe) this.collected.push(safe);\r\n            } catch (e) {\r\n                console.warn(\"处理网格时出错：\", mesh, e);\r\n            }\r\n        };\r\n\r\n        // 收集碰撞网格：传入则用指定对象，否则遍历整个场景\r\n        if (sources) {\r\n            const list = Array.isArray(sources) ? sources : [sources];\r\n            for (const obj of list) {\r\n                obj.updateMatrixWorld(true);\r\n                obj.traverse(c => {\r\n                    const a = c as any;\r\n                    if ((a.isMesh || a.isLineSegments) && a.geometry && c.name !== \"capsule\") collectMesh(a);\r\n                });\r\n            }\r\n        } else {\r\n            this.scene.traverse(c => {\r\n                const m = c as THREE.Mesh;\r\n                if (m?.isMesh && m.geometry && c.name !== \"capsule\") collectMesh(m);\r\n            });\r\n        }\r\n\r\n        if (!this.collected.length) return;\r\n        this.collected = this.unifiedAttribute(this.collected);\r\n\r\n        // 合并并构建BVH\r\n        const merged = BufferGeometryUtils.mergeGeometries(this.collected, false);\r\n        if (!merged) { console.error(\"合并几何失败\"); return; }\r\n        (merged as any).boundsTree = new MeshBVH(merged, { maxDepth: 100 });\r\n        this.collider = new THREE.Mesh(merged, new THREE.MeshBasicMaterial({ opacity: 0.5, transparent: true, wireframe: true, depthTest: true, side: THREE.DoubleSide }));\r\n        this.collider.layers.enable(1);\r\n\r\n        if (this.displayCollider) this.scene.add(this.collider);\r\n        if (this.displayVisualizer) {\r\n            if (this.visualizer) this.scene.remove(this.visualizer);\r\n            this.visualizer = new BVHHelper(this.collider, 10);\r\n            this.scene.add(this.visualizer);\r\n        }\r\n    }\r\n\r\n    // 注册动态碰撞体\r\n    addDynamicCollider(source: THREE.Object3D) {\r\n        if (this.dynamicColliders.find(e => e.source === source)) return;\r\n        source.updateMatrixWorld(true);\r\n\r\n        // 收集网格，几何保留在 source 本地空间\r\n        const collected: THREE.BufferGeometry[] = [];\r\n        const invSource = new THREE.Matrix4().copy(source.matrixWorld).invert();\r\n        source.traverse(c => {\r\n            const m = c as THREE.Mesh;\r\n            if (!m?.isMesh || !m.geometry || c.name === \"capsule\") return;\r\n            try {\r\n                let geom = (m.geometry as THREE.BufferGeometry).clone();\r\n                geom.applyMatrix4(new THREE.Matrix4().multiplyMatrices(invSource, m.matrixWorld));\r\n                if (geom.index) geom = geom.toNonIndexed();\r\n                const safe = this.ensureAttributesMinimal(geom);\r\n                if (safe) collected.push(safe);\r\n            } catch (e) { console.warn(\"处理动态网格出错：\", m, e); }\r\n        });\r\n\r\n        if (!collected.length) return;\r\n        const unified = this.unifiedAttribute(collected);\r\n        const merged = BufferGeometryUtils.mergeGeometries(unified, false);\r\n        if (!merged) { console.error(\"合并动态几何失败\"); return; }\r\n        (merged as any).boundsTree = new MeshBVH(merged);\r\n\r\n        const mesh = new THREE.Mesh(merged, new THREE.MeshBasicMaterial({ opacity: 0.5, transparent: true, wireframe: true, depthTest: true, side: THREE.DoubleSide }));\r\n        mesh.matrixAutoUpdate = false;\r\n        mesh.matrix.copy(source.matrixWorld);\r\n        mesh.updateMatrixWorld(true);\r\n\r\n        this.dynamicColliders.push({ source, mesh, prevWorldMatrix: new THREE.Matrix4().copy(source.matrixWorld), deltaPos: new THREE.Vector3(), deltaRotY: 0 });\r\n        if (this.displayCollider) this.scene.add(mesh);\r\n    }\r\n\r\n    // 注销动态碰撞体\r\n    removeDynamicCollider(source: THREE.Object3D) {\r\n        const idx = this.dynamicColliders.findIndex(e => e.source === source);\r\n        if (idx === -1) return;\r\n        const entry = this.dynamicColliders[idx];\r\n        this.scene.remove(entry.mesh);\r\n        entry.mesh.geometry.dispose();\r\n        (entry.mesh.material as THREE.Material).dispose();\r\n        if (this.activeDynamicCollider === entry) this.activeDynamicCollider = null;\r\n        this.dynamicColliders.splice(idx, 1);\r\n    }\r\n\r\n    // 清除所有动态碰撞体\r\n    clearDynamicColliders() {\r\n        for (const entry of this.dynamicColliders) {\r\n            this.scene.remove(entry.mesh);\r\n            entry.mesh.geometry.dispose();\r\n            (entry.mesh.material as THREE.Material).dispose();\r\n        }\r\n        this.dynamicColliders = [];\r\n        this.activeDynamicCollider = null;\r\n    }\r\n\r\n    // 更新动态碰撞体\r\n    private updateDynamicColliders() {\r\n        if (!this.playerCapsule) return;\r\n        const playerWorldPos = this.playerCapsule.position.clone();\r\n\r\n        for (const entry of this.dynamicColliders) {\r\n            // 将玩家位置变换到平台上一帧本地空间\r\n            const prevInv = new THREE.Matrix4().copy(entry.prevWorldMatrix).invert();\r\n            const playerInLocal = playerWorldPos.clone().applyMatrix4(prevInv);\r\n\r\n            // 更新 mesh 跟随 source\r\n            entry.source.updateMatrixWorld(true);\r\n            entry.mesh.matrix.copy(entry.source.matrixWorld);\r\n            entry.mesh.updateMatrixWorld(true);\r\n\r\n            // 变换回新世界空间，得到含旋转的完整位移\r\n            const playerInNewWorld = playerInLocal.clone().applyMatrix4(entry.source.matrixWorld);\r\n            entry.deltaPos.subVectors(playerInNewWorld, playerWorldPos);\r\n\r\n            // 计算平台本帧 Y 轴旋转增量\r\n            const prevEuler = new THREE.Euler().setFromRotationMatrix(entry.prevWorldMatrix, \"YXZ\");\r\n            const curEuler = new THREE.Euler().setFromRotationMatrix(entry.source.matrixWorld, \"YXZ\");\r\n            entry.deltaRotY = curEuler.y - prevEuler.y;\r\n\r\n            // 保存当前矩阵供下帧使用\r\n            entry.prevWorldMatrix.copy(entry.source.matrixWorld);\r\n        }\r\n    }\r\n\r\n    // 判断是否跳过三角面碰撞\r\n    private shouldSkipTriCollision(tri: any, dir: THREE.Vector3): boolean {\r\n        const normal = tri.getNormal(new THREE.Vector3());\r\n        const normalYAangle = normal.angleTo(this.upVector) * 180 / Math.PI;\r\n        // 小于 slopeAngleThreshold° 斜坡，不处理碰撞\r\n        if (normalYAangle < this.slopeAngleThreshold) return true;\r\n        // 忽略立面阈值高度以下的碰撞\r\n        if (normalYAangle > 80 && normalYAangle < 100) {\r\n            const triHeight = Math.max(tri.a.y, tri.b.y, tri.c.y) - Math.min(tri.a.y, tri.b.y, tri.c.y); // 三角面y高度\r\n            if (triHeight < this.maxStepHeight * this.playerModelConfig.scale) return true; // 阈值高度\r\n            // else {\r\n            //     // console.log('被挡住：', '当前三角面高度', triHeight, \"阈值\", this.maxStepHeight * this.playerModelConfig.scale);\r\n            // }\r\n        }\r\n        // console.log('碰撞三角面法线与世界上方向夹角：', normalYAangle.toFixed(2), '°');\r\n        // console.log('碰撞三角面：', tri, \"推开方向向量：\", dir);\r\n        return false;\r\n    }\r\n\r\n    // ==================== 主循环 ====================\r\n\r\n    // 主循环\r\n    async update(delta = clock.getDelta()) {\r\n        if (!this.isupdate || !this.playerCapsule || !this.collider) return;\r\n        delta = Math.min(delta, 1 / 40) * this.timeScale;\r\n        if (this.controllerMode === 1) {\r\n            this.vehicle.updateVehicle(delta);\r\n        } else {\r\n            this.updatePlayer(delta);\r\n            if (this.isChangeControllerTransitionTimer) this.vehicle.updateInertia(delta);\r\n        }\r\n    }\r\n\r\n    // 玩家帧更新\r\n    updatePlayer(delta: number) {\r\n        // 更新动态碰撞体位置与增量\r\n        this.updateDynamicColliders();\r\n\r\n        const v = this.vehicle;\r\n        if (v.isMovingToBoarding) v.updateMoveTo(delta);\r\n\r\n        // 上车关门计时\r\n        if (v.isBoardingAnim) {\r\n            const action = this.animation.actions?.get(\"enterCar\");\r\n            if (action) {\r\n                const duration = action.getClip().duration;\r\n                const remaining = ((duration - action.time) / action.getEffectiveTimeScale()) * 1000;\r\n                if (!v.doorClosed && remaining <= 500) { v.doorClosed = true; v.openDoor(false); }\r\n                if (action.time >= duration) {\r\n                    v.isBoardingAnim = false;\r\n                    v.doorClosed = false;\r\n                    v.onEnterAnimFinished();\r\n                    return;\r\n                }\r\n            }\r\n        }\r\n\r\n        // 下车关门计时\r\n        if (v.isExitAnim) {\r\n            const action = this.animation.actions?.get(\"exitCar\");\r\n            if (action) {\r\n                const duration = action.getClip().duration;\r\n                const remaining = ((duration - action.time) / action.getEffectiveTimeScale()) * 1000;\r\n                if (!v.exitDoorClosed && remaining <= 500) { v.exitDoorClosed = true; v.openDoor(false); }\r\n                if (action.time >= duration) { v.isExitAnim = false; v.exitDoorClosed = false; this.onVehicleExit?.(v.active!); }\r\n            }\r\n        }\r\n\r\n        // 车辆模式下退出\r\n        if (this.controllerMode === 1) {\r\n            // 更新动画\r\n            this.animation.updateMixers(delta);\r\n            return;\r\n        }\r\n\r\n        // 计算移动方向\r\n        this.camera.getWorldDirection(this.camDir);\r\n        const angle = 2 * Math.PI - (Math.atan2(this.camDir.z, this.camDir.x) + Math.PI / 2);\r\n\r\n        // 按键移动方向\r\n        this.moveDir.set(0, 0, 0);\r\n        if (this.input.fwd) this.moveDir.add(this.DIR_FWD);\r\n        if (this.input.bkd) this.moveDir.add(this.DIR_BKD);\r\n        if (this.input.lft) this.moveDir.add(this.DIR_LFT);\r\n        if (this.input.rgt) this.moveDir.add(this.DIR_RGT);\r\n        if (this.isFlying) {\r\n            if (this.input.fwd) this.moveDir.copy(this.camDir);\r\n            if (this.input.space) this.moveDir.y += 1;\r\n            this.curPlayerSpeed = this.input.shift ? this.playerFlySpeed * 2 : this.playerFlySpeed;\r\n        } else {\r\n            this.curPlayerSpeed = this.input.shift ? this.playerSpeed * 2 : this.playerSpeed;\r\n        }\r\n\r\n        this.moveDir.normalize(); // 归一化方向向量\r\n        if (!this.isFlying || !this.input.fwd) this.moveDir.applyAxisAngle(this.upVector, angle); // 应用相机角度\r\n\r\n        // 速度驱动\r\n        const accelStep = this.playerAcceleration * this.decelBase * delta; // 加速步长\r\n        const decelStep = this.playerDeceleration * this.decelBase * delta; // 减速步长\r\n        const targetX = this.moveDir.x * this.curPlayerSpeed; // 目标速度X\r\n        const targetZ = this.moveDir.z * this.curPlayerSpeed; // 目标速度Z\r\n        const diffX = targetX - this.playerVelocity.x; // 速度差X\r\n        const diffZ = targetZ - this.playerVelocity.z; // 速度差Z\r\n        // XZ 作为整体2D向量限幅\r\n        const hasXZInput = this.moveDir.x !== 0 || this.moveDir.z !== 0;\r\n        const xzDiffLen = Math.hypot(diffX, diffZ);\r\n        if (xzDiffLen > 0) {\r\n            const xzApplied = Math.min(xzDiffLen, hasXZInput ? accelStep : decelStep);\r\n            this.playerVelocity.x += (diffX / xzDiffLen) * xzApplied;\r\n            this.playerVelocity.z += (diffZ / xzDiffLen) * xzApplied;\r\n        }\r\n        if (this.isFlying) {\r\n            const targetY = this.moveDir.y * this.curPlayerSpeed;\r\n            const diffY = targetY - this.playerVelocity.y;\r\n            this.playerVelocity.y += Math.sign(diffY) * Math.min(Math.abs(diffY), this.moveDir.y !== 0 ? accelStep : decelStep);\r\n        }\r\n\r\n        // 地面检测\r\n        const s = this.playerModelConfig.scale;\r\n        this.groundRaycaster.ray.origin.copy(this.playerCapsule.position);\r\n        const staticHits = this.groundRaycaster.intersectObject(this.collider!, false);\r\n\r\n        // 同时检测动态碰撞体，取最高地面点\r\n        let bestHit: THREE.Intersection | undefined = staticHits[0];\r\n        let hitEntry: DynamicColliderEntry | null = null;\r\n        for (const entry of this.dynamicColliders) {\r\n            const dynHits = this.groundRaycaster.intersectObject(entry.mesh, false);\r\n            if (dynHits.length > 0 && (!bestHit || dynHits[0].point.y > bestHit.point.y)) {\r\n                bestHit = dynHits[0];\r\n                hitEntry = entry;\r\n            }\r\n        }\r\n        // 更新当前动态碰撞体\r\n        this.activeDynamicCollider = hitEntry;\r\n\r\n        if (!this.isFlying) {\r\n            if (bestHit) {\r\n                const capsuleInfo = this.playerCapsule.capsuleInfo;\r\n                const snapH = parseFloat((-capsuleInfo.segment.end.y + capsuleInfo.radius).toFixed(6));\r\n                const maxH = parseFloat((snapH * 1.2).toFixed(6));\r\n                const snapY = bestHit.point.y + snapH;\r\n                const dist = parseFloat((this.playerCapsule.position.y - bestHit.point.y).toFixed(6));\r\n                if (dist > maxH) {\r\n                    this.applyGravity(delta);\r\n                } else if (this.playerVelocity.y <= 0) {\r\n                    if (this.playerIsOnGround) {\r\n                        // 已在地面：直接跟随地形（斜坡、动态平台）\r\n                        this.snapToGround(snapY);\r\n                    } else {\r\n                        // 从空中落下：只有本帧速度能到达落点才 snap，否则继续应用重力\r\n                        const predictedY = this.playerCapsule.position.y + this.playerVelocity.y * delta;\r\n                        if (predictedY <= snapY) {\r\n                            this.snapToGround(snapY);\r\n                        } else {\r\n                            this.applyGravity(delta);\r\n                        }\r\n                    }\r\n                }\r\n            } else {\r\n                this.applyGravity(delta);\r\n            }\r\n            // 应用重力速度\r\n            this.playerCapsule.position.y += this.playerVelocity.y * delta;\r\n        }\r\n\r\n        // 分步碰撞移动\r\n        const capsuleInfo = this.playerCapsule.capsuleInfo;\r\n        const xzSpeed = Math.hypot(this.playerVelocity.x, this.playerVelocity.z);\r\n        const totalDist = this.isFlying ? this.playerVelocity.length() * delta : xzSpeed * delta;\r\n        this.xzDir.set(this.playerVelocity.x, this.isFlying ? this.playerVelocity.y : 0, this.playerVelocity.z).normalize();\r\n        const maxStep = capsuleInfo.radius * 0.8;\r\n        const steps = Math.ceil(totalDist / maxStep) || 1;\r\n        const stepDist = totalDist / steps;\r\n        for (let i = 0; i < steps; i++) {\r\n            this.playerCapsule.position.addScaledVector(this.xzDir, stepDist);\r\n            this.playerCapsule.updateMatrixWorld();\r\n\r\n            if (!v.isMovingToBoarding) {\r\n                // 静态碰撞检测\r\n                applyCapsuleCollision(\r\n                    this.playerCapsule,\r\n                    capsuleInfo,\r\n                    this.collider!,\r\n                    this.staticTemps,\r\n                    (tri: any, dir: THREE.Vector3) => !this.isFlying && this.playerIsOnGround && this.shouldSkipTriCollision(tri, dir),\r\n                );\r\n\r\n                // 动态碰撞检测\r\n                for (const dynEntry of this.dynamicColliders) {\r\n                    this.playerCapsule.updateMatrixWorld();\r\n                    applyCapsuleCollision(\r\n                        this.playerCapsule,\r\n                        capsuleInfo,\r\n                        dynEntry.mesh,\r\n                        this.dynTemps,\r\n                        (tri: any, dir: THREE.Vector3) => !this.isFlying && this.playerIsOnGround && this.shouldSkipTriCollision(tri, dir),\r\n                    );\r\n                }\r\n            }\r\n        }\r\n\r\n        // 动态平台带动玩家\r\n        if (this.activeDynamicCollider && this.playerIsOnGround && !this.isFlying) {\r\n            this.playerCapsule.position.add(this.activeDynamicCollider.deltaPos);\r\n            if (this.activeDynamicCollider.deltaRotY !== 0) {\r\n                this.playerCapsule.rotateY(this.activeDynamicCollider.deltaRotY);\r\n            }\r\n        }\r\n\r\n        // 玩家朝向\r\n        if (!this.isFirstPerson) {\r\n            const camDirFlat = this.camDir.clone().setY(0).normalize().negate();\r\n            const moveDirFlat = this.moveDir.clone().normalize().negate();\r\n\r\n            if (!this.isFlying) {\r\n                if (this.cam.mouseMode === 4 || this.cam.mouseMode === 5) {\r\n                    // mode 4/5: 胶囊朝向始终与相机水平朝向一致，鼠标旋转即驱动人物转向\r\n                    this.targetMat.lookAt(this.playerCapsule.position, this.playerCapsule.position.clone().add(camDirFlat), this.playerCapsule.up);\r\n                    this.playerCapsule.quaternion.copy(this.targetQuat.setFromRotationMatrix(this.targetMat));\r\n                } else if (this.cam.mouseMode === 0 || this.cam.mouseMode === 2) {\r\n                    const lookTarget = this.playerCapsule.position.clone().add(moveDirFlat.lengthSq() > 0 ? moveDirFlat : camDirFlat);\r\n                    this.targetMat.lookAt(this.playerCapsule.position, lookTarget, this.playerCapsule.up);\r\n                    this.playerCapsule.quaternion.slerp(this.targetQuat.setFromRotationMatrix(this.targetMat), Math.min(1, this.rotationSpeed * delta));\r\n                } else if (moveDirFlat.lengthSq() > 0) {\r\n                    this.targetMat.lookAt(this.playerCapsule.position, this.playerCapsule.position.clone().add(moveDirFlat), this.playerCapsule.up);\r\n                    this.playerCapsule.quaternion.slerp(this.targetQuat.setFromRotationMatrix(this.targetMat), Math.min(1, this.rotationSpeed * delta));\r\n                }\r\n            } else {\r\n                const lookTarget = this.playerCapsule.position.clone().add(this.input.fwd ? moveDirFlat : camDirFlat);\r\n                this.targetMat.lookAt(this.playerCapsule.position, lookTarget, this.playerCapsule.up);\r\n                this.playerCapsule.quaternion.slerp(this.targetQuat.setFromRotationMatrix(this.targetMat), Math.min(1, this.rotationSpeed * delta));\r\n            }\r\n        }\r\n\r\n        // 第三人称相机跟随\r\n        if (!this.isFirstPerson) {\r\n            const lookTarget = this.cam.applySpringToTarget(delta);\r\n            this.camera.position.sub(this.controls.target);\r\n            this.camera.position.add(lookTarget);\r\n            this.controls.target.copy(lookTarget);\r\n            this.controls.update();\r\n\r\n            if (!this.cam.zoomEnabled) {\r\n                this.cam.updateWithRaycast(\r\n                    this.controls.target,\r\n                    this.cam.playerToCam.subVectors(this.camera.position, this.controls.target).length(),\r\n                    this.cam.maxDist,\r\n                );\r\n            }\r\n        }\r\n\r\n        // 移动端车辆按钮检测\r\n        if (this.isShowMobileControls && this.vehicle.list.length) {\r\n            let near = false;\r\n            for (const veh of this.vehicle.list) {\r\n                this.nearCheckLocal.copy(veh.boardingPoint).multiplyScalar(veh.scale);\r\n                veh.vehicleGroup.localToWorld(this.nearCheckWorld.copy(this.nearCheckLocal));\r\n                if (this.playerCapsule.position.distanceTo(this.nearCheckWorld) < 800 * this.playerModelConfig.scale) { near = true; break; }\r\n            }\r\n            if (near !== this.isNearVehicle) {\r\n                this.isNearVehicle = near;\r\n                this.mobileControls?.syncVehicleBtn(near);\r\n            }\r\n        }\r\n\r\n        // 设置动画\r\n        this.animation.setAnimationByPressed();\r\n        // 更新动画混合器\r\n        this.animation.updateMixers(delta);\r\n    }\r\n\r\n    // ==================== 内部辅助 ====================\r\n\r\n    // 同步 debug 可见性\r\n    syncDebugVisibility() {\r\n        if (!this.playerCapsule) return;\r\n        const dbg = this.displayCollider;\r\n        const isVehicle = this.controllerMode === 1;\r\n\r\n        // 静态碰撞体：两种模式下都显示\r\n        if (this.collider) {\r\n            if (dbg) { if (!this.scene.children.includes(this.collider)) this.scene.add(this.collider); }\r\n            else this.scene.remove(this.collider);\r\n        }\r\n\r\n        // 玩家胶囊线框：步行模式才显示\r\n        (this.playerCapsule.material as THREE.Material).visible = dbg && !isVehicle;\r\n\r\n        // 动态碰撞体线框：步行模式才显示\r\n        for (const entry of this.dynamicColliders) {\r\n            if (dbg && !isVehicle) { if (!this.scene.children.includes(entry.mesh)) this.scene.add(entry.mesh); }\r\n            else this.scene.remove(entry.mesh);\r\n        }\r\n\r\n        // Rapier 物理调试：车辆模式才开启\r\n        this.vehicle.params.debug.showPhysicsBox = dbg && isVehicle;\r\n        for (const v of this.vehicle.list) {\r\n            if (!v.physicsBoxMesh) continue;\r\n            if (dbg && isVehicle) { if (!v.vehicleGroup.children.includes(v.physicsBoxMesh)) v.vehicleGroup.add(v.physicsBoxMesh); }\r\n            else v.vehicleGroup.remove(v.physicsBoxMesh);\r\n        }\r\n    }\r\n\r\n    // 设置落地状态\r\n    setOnGround(val: boolean) {\r\n        if (this.playerIsOnGround === val) return;\r\n        this.playerIsOnGround = val;\r\n        this.onGroundChange?.(val);\r\n        if (val) this.animation.onLand();\r\n        else this.animation.onBecomeAirborne();\r\n    }\r\n\r\n    // 应用重力\r\n    private applyGravity(delta: number) {\r\n        this.playerVelocity.y += delta * this.gravity;\r\n        this.setOnGround(false);\r\n    }\r\n\r\n    // 吸附到地面\r\n    private snapToGround(groundY: number) {\r\n        this.playerVelocity.y = 0;\r\n        this.playerCapsule.position.y = groundY;\r\n        this.setOnGround(true);\r\n    }\r\n\r\n    // 动态修改缩放\r\n    setPlayerScale(newScale: number) {\r\n        if (newScale <= 0) return;\r\n        const ratio = newScale / this.playerModelConfig.scale;\r\n        this.playerModelConfig.scale = newScale;\r\n\r\n        // 更新比例相关参数\r\n        this.gravity *= ratio;\r\n        this.jumpHeight *= ratio;\r\n        this.playerSpeed *= ratio;\r\n        this.playerFlySpeed *= ratio;\r\n        this.curPlayerSpeed *= ratio;\r\n        this.cam.epsilon *= ratio;\r\n        this.cam.minDist *= ratio;\r\n        this.controls.minDistance *= ratio;\r\n        this.cam.maxDist *= ratio;\r\n        this.cam.originMaxDist *= ratio;\r\n\r\n        if (this.isFirstPerson) this.scene.attach(this.camera);\r\n        this.playerCapsule?.scale.multiplyScalar(ratio);\r\n        if (this.playerCapsule?.capsuleInfo) {\r\n            this.playerCapsule.capsuleInfo.radius *= ratio;\r\n            this.playerCapsule.capsuleInfo.segment.end.y *= ratio;\r\n        }\r\n        if (this.isFirstPerson) this.cam.setFirstPerson();\r\n    }\r\n\r\n    // 重置玩家位置\r\n    reset(position?: THREE.Vector3) {\r\n        if (!this.playerCapsule) return;\r\n        this.playerVelocity.set(0, 0, 0);\r\n        this.playerCapsule.position.copy(position ?? this.initPos);\r\n    }\r\n\r\n    // ==================== API ====================\r\n\r\n    // 获取当前位置\r\n    getPosition() { return this.playerCapsule?.position; }\r\n    // 获取速度\r\n    getVelocity() { return this.playerVelocity.clone(); }\r\n    // 获取第一人称状态\r\n    getIsFirstPerson() { return this.isFirstPerson; }\r\n    // 获取飞行状态\r\n    getIsFlying() { return this.isFlying; }\r\n    // 获取落地状态\r\n    getIsOnGround() { return this.playerIsOnGround; }\r\n    // 获取控制器模式\r\n    getControllerMode() { return this.controllerMode; }\r\n    // 获取玩家模型\r\n    getPlayerModel() { return this.playerModel; }\r\n    // 获取胶囊体\r\n    getPlayerCapsule() { return this.playerCapsule; }\r\n    // 获取当前载具\r\n    getActiveVehicle() { return this.vehicle.active; }\r\n    // 获取所有载具\r\n    getAllVehicles() { return this.vehicle.list; }\r\n    // 获取碰撞体\r\n    getCollider() { return this.collider; }\r\n    // 获取当前站立的动态碰撞体\r\n    getActiveDynamicCollider() { return this.activeDynamicCollider; }\r\n\r\n    // 设置鼠标灵敏度\r\n    setMouseSensitivity(value: number) {\r\n        this.cam.sensitivity = value;\r\n        this.controls.rotateSpeed = value * 0.05;\r\n    }\r\n\r\n    // --- 玩家参数 ---\r\n    // 设置重力\r\n    setGravity(gravity: number) { this.gravity = gravity * this.playerModelConfig.scale; }\r\n    // 设置跳跃高度\r\n    setJumpHeight(jumpHeight: number) { this.jumpHeight = jumpHeight * this.playerModelConfig.scale; }\r\n    // 设置行走速度\r\n    setPlayerSpeed(speed: number) { this.playerSpeed = speed * this.playerModelConfig.scale; this.curPlayerSpeed = this.playerSpeed; }\r\n    // 设置飞行速度\r\n    setPlayerFlySpeed(flySpeed: number) { this.playerFlySpeed = flySpeed * this.playerModelConfig.scale; }\r\n    // 设置朝向开关\r\n    setEnableToward(v: boolean) { this.enableToward = v; }\r\n\r\n    // --- 相机参数 ---\r\n    // 设置相机最近距\r\n    setMinCamDistance(dist: number) { this.cam.minDist = dist * this.playerModelConfig.scale; }\r\n    // 设置相机最远距\r\n    setMaxCamDistance(dist: number) { this.cam.maxDist = dist * this.playerModelConfig.scale; this.cam.originMaxDist = this.cam.maxDist; }\r\n    // 设置相机看向点高度比例\r\n    setCamLookAtHeightRatio(ratio: number) { this.cam.lookAtHeightRatio = ratio; }\r\n    // 设置鼠标模式\r\n    setThirdMouseMode(mode: 0 | 1 | 2 | 3 | 4 | 5) { this.cam.mouseMode = mode; this.cam.setPointerLock(); }\r\n    // 设置缩放开关\r\n    setEnableZoom(enable: boolean) { this.cam.zoomEnabled = enable; this.controls.enableZoom = enable; }\r\n\r\n    // --- 调试 ---\r\n    // 切换调试显示\r\n    setDebug(debug: boolean) {\r\n        this.displayCollider = debug;\r\n        this.syncDebugVisibility();\r\n    }\r\n\r\n    // --- 动画 ---\r\n    // 按名播放动画\r\n    playPlayerAnimationByName(name: string, fade?: number) { this.animation.playByName(name, fade); }\r\n    // 注册自定义动画\r\n    registerAnimation(key: string, clipName: string, opts?: Parameters<AnimationSystem[\"register\"]>[2]) { this.animation.register(key, clipName, opts); }\r\n    // 播放已注册动画\r\n    playAnimation(key: string, opts?: Parameters<AnimationSystem[\"play\"]>[1]) { this.animation.play(key, opts); }\r\n    // 注册移动动作组\r\n    registerLocomotionSet(setName: string, map: Parameters<AnimationSystem[\"registerLocomotionSet\"]>[1]) { this.animation.registerLocomotionSet(setName, map); }\r\n    // 切换移动动作组\r\n    switchLocomotionSet(setName: string, fade?: number) { this.animation.switchLocomotionSet(setName, fade); }\r\n    // 获取当前动画名\r\n    getCurrentPlayerAnimationName() { return this.animation.getCurrentName(); }\r\n    // 获取当前移动动作组名\r\n    getCurrentLocomotionSet() { return this.animation.currentLocomotionSet; }\r\n\r\n    // --- 相机 ---\r\n    // 切换视角模式\r\n    changeView() { this.cam.changeView(); }\r\n    // 设置第一人称\r\n    setFirstPersonCamera(v = 0) { this.cam.setFirstPerson(v); }\r\n    // 设置越肩视角\r\n    setOverShoulderView(v: boolean) { this.cam.setOverShoulder(v); }\r\n    // 屏幕中心检测\r\n    getCenterScreenRaycastHit() { return this.cam.getCenterHit(); }\r\n\r\n    // --- 输入 ---\r\n    // 设置输入状态\r\n    setInput(input: Parameters<InputSystem[\"setInput\"]>[0]) { this.input.setInput(input); }\r\n    // 运行时自定义键位\r\n    setKeyMap(map?: KeyMap) { this.input.buildKeyMap(map); }\r\n    // 绑定输入事件\r\n    onAllEvent() { this.input.bindEvents(); }\r\n    // 解绑输入事件\r\n    offAllEvent() { this.input.unbindEvents(); }\r\n\r\n    // --- 载具 ---\r\n    // 加载车辆模型\r\n    loadVehicleModel(opts: VehicleOptions) { return this.vehicle.load(opts); }\r\n\r\n    // --- 销毁 ---\r\n    destroy() {\r\n        this.input.unbindEvents();\r\n\r\n        // 清除玩家对象\r\n        if (this.playerCapsule) { this.playerCapsule.remove(this.camera); this.scene.remove(this.playerCapsule); }\r\n        (this.playerCapsule as any) = null;\r\n        if (this.playerModel) { this.scene.remove(this.playerModel); this.playerModel = null; }\r\n\r\n        // 清除碰撞体和相机\r\n        this.cam.resetControls();\r\n        if (this.visualizer) { this.scene.remove(this.visualizer); this.visualizer = null; }\r\n        if (this.collider) { this.scene.remove(this.collider); this.collider = null; }\r\n        this.mobileControls?.destroy();\r\n        this.mobileControls = null;\r\n\r\n        // 清除动态碰撞体\r\n        this.clearDynamicColliders();\r\n\r\n        // 清除所有车辆\r\n        for (const v of this.vehicle.list) { this.scene.remove(v.vehicleGroup); v.pathPlanner?.dispose(); v.vehicleController?.destroy?.(); }\r\n        this.vehicle.list = [];\r\n        this.vehicle.active = null;\r\n    }\r\n}","import type { OrbitControls } from \"three/examples/jsm/controls/OrbitControls.js\";\r\nimport breakIconModule from \"../../assets/imgs/break.png\";\r\nimport flyIconModule from \"../../assets/imgs/fly.png\";\r\nimport jumpIconModule from \"../../assets/imgs/jump.png\";\r\nimport vehicleIconModule from \"../../assets/imgs/vehicle.png\";\r\nimport viewIconModule from \"../../assets/imgs/view.png\";\r\n\r\ntype SetInputFn = (input: Partial<{\r\n    moveX: 1 | 0 | -1;\r\n    moveY: 1 | 0 | -1;\r\n    lookDeltaX: number;\r\n    lookDeltaY: number;\r\n    jump: boolean;\r\n    shift: boolean;\r\n    toggleView: boolean;\r\n    toggleFly: boolean;\r\n    toggleVehicle: boolean;\r\n}>) => void;\r\n\r\nclass VirtualJoystick {\r\n    private baseEl: HTMLDivElement;\r\n    private stickEl: HTMLDivElement;\r\n    private pointerId: number | null = null;\r\n    private center = { x: 0, y: 0 };\r\n    private radius: number;\r\n    private onMove: (data: { vector: { x: number; y: number }; distance: number }) => void;\r\n    private onEnd: () => void;\r\n\r\n    constructor(\r\n        zone: HTMLDivElement,\r\n        size: number,\r\n        onMove: (data: { vector: { x: number; y: number }; distance: number }) => void,\r\n        onEnd: () => void,\r\n    ) {\r\n        this.radius = size / 2;\r\n        this.onMove = onMove;\r\n        this.onEnd = onEnd;\r\n\r\n        // 外环\r\n        this.baseEl = document.createElement(\"div\");\r\n        Object.assign(this.baseEl.style, {\r\n            position: \"absolute\",\r\n            left: \"50%\",\r\n            bottom: \"50%\",\r\n            transform: \"translate(-50%, 50%)\",\r\n            width: `${size}px`,\r\n            height: `${size}px`,\r\n            borderRadius: \"50%\",\r\n            border: \"2px solid rgba(0,0,0,0.5)\",\r\n            backgroundColor: \"rgba(0,0,0,0.2)\",\r\n            boxSizing: \"border-box\",\r\n            pointerEvents: \"none\",\r\n        });\r\n        zone.appendChild(this.baseEl);\r\n\r\n        // 内点\r\n        const stickSize = size * 0.2;\r\n        this.stickEl = document.createElement(\"div\");\r\n        Object.assign(this.stickEl.style, {\r\n            position: \"absolute\",\r\n            left: \"50%\",\r\n            top: \"50%\",\r\n            transform: \"translate(-50%, -50%)\",\r\n            width: `${stickSize}px`,\r\n            height: `${stickSize}px`,\r\n            borderRadius: \"50%\",\r\n            backgroundColor: \"rgba(255,255,255,0.7)\",\r\n            pointerEvents: \"none\",\r\n        });\r\n        this.baseEl.appendChild(this.stickEl);\r\n\r\n        zone.addEventListener(\"pointerdown\", this.onPointerDown, { passive: false });\r\n        zone.addEventListener(\"pointermove\", this.onPointerMove, { passive: false });\r\n        zone.addEventListener(\"pointerup\", this.onPointerUp, { passive: false });\r\n        zone.addEventListener(\"pointercancel\", this.onPointerUp, { passive: false });\r\n    }\r\n\r\n    private onPointerDown = (e: PointerEvent) => {\r\n        if (this.pointerId !== null) return;\r\n        this.pointerId = e.pointerId;\r\n        const rect = this.baseEl.parentElement!.getBoundingClientRect();\r\n        this.center = { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };\r\n        this.baseEl.parentElement!.setPointerCapture(e.pointerId);\r\n        e.preventDefault();\r\n        this.updateStick(e.clientX, e.clientY);\r\n    };\r\n\r\n    private onPointerMove = (e: PointerEvent) => {\r\n        if (e.pointerId !== this.pointerId) return;\r\n        e.preventDefault();\r\n        this.updateStick(e.clientX, e.clientY);\r\n    };\r\n\r\n    private onPointerUp = (e: PointerEvent) => {\r\n        if (e.pointerId !== this.pointerId) return;\r\n        this.pointerId = null;\r\n        this.stickEl.style.transform = \"translate(-50%, -50%)\";\r\n        this.onEnd();\r\n    };\r\n\r\n    private updateStick(clientX: number, clientY: number) {\r\n        const dx = clientX - this.center.x;\r\n        const dy = clientY - this.center.y;\r\n        const dist = Math.sqrt(dx * dx + dy * dy);\r\n        const clampedDist = Math.min(dist, this.radius);\r\n        const angle = Math.atan2(dy, dx);\r\n        const ox = Math.cos(angle) * clampedDist;\r\n        const oy = Math.sin(angle) * clampedDist;\r\n\r\n        this.stickEl.style.transform = `translate(calc(-50% + ${ox}px), calc(-50% + ${oy}px))`;\r\n\r\n        // 归一化向量，y 轴取反\r\n        const scale = dist > 0 ? clampedDist / this.radius / dist : 0;\r\n        this.onMove({ vector: { x: dx * scale, y: -dy * scale }, distance: clampedDist });\r\n    }\r\n\r\n    destroy() {\r\n        const zone = this.baseEl.parentElement;\r\n        if (zone) {\r\n            zone.removeEventListener(\"pointerdown\", this.onPointerDown);\r\n            zone.removeEventListener(\"pointermove\", this.onPointerMove);\r\n            zone.removeEventListener(\"pointerup\", this.onPointerUp);\r\n            zone.removeEventListener(\"pointercancel\", this.onPointerUp);\r\n        }\r\n        this.baseEl.remove();\r\n    }\r\n}\r\n\r\nexport class MobileControls {\r\n    setInput: SetInputFn;\r\n    controls: OrbitControls;\r\n\r\n    // 摇杆状态\r\n    joystick: VirtualJoystick | null = null;\r\n    prevJoyState = { dirX: 0, dirY: 0, shift: false };\r\n\r\n    // DOM 元素\r\n    joystickZoneEl: HTMLDivElement | null = null;\r\n    lookAreaEl: HTMLDivElement | null = null;\r\n    jumpBtnEl: HTMLButtonElement | null = null;\r\n    flyBtnEl: HTMLButtonElement | null = null;\r\n    viewBtnEl: HTMLButtonElement | null = null;\r\n    vehicleBtnEl: HTMLButtonElement | null = null;\r\n\r\n    // 触摸状态\r\n    lookPointerId: number | null = null;\r\n    isLookDown = false;\r\n    lastTouchX = 0;\r\n    lastTouchY = 0;\r\n\r\n    constructor(setInput: SetInputFn, controls: OrbitControls) {\r\n        this.setInput = setInput;\r\n        this.controls = controls;\r\n    }\r\n\r\n    // 初始化移动端控制\r\n    async init(opts?: { joystick?: boolean; jump?: boolean; fly?: boolean; view?: boolean; vehicle?: boolean }) {\r\n        const showJoystick = opts?.joystick ?? true;\r\n        const showJump = opts?.jump ?? true;\r\n        const showFly = opts?.fly ?? true;\r\n        const showView = opts?.view ?? true;\r\n        const showVehicle = opts?.vehicle ?? true;\r\n\r\n        this.controls.maxPolarAngle = Math.PI * (300 / 360);\r\n        this.controls.touches = { ONE: null as any, TWO: null as any };\r\n\r\n        const JOY_SIZE = 120;\r\n        const container = document.body;\r\n\r\n        // 创建摇杆区域\r\n        if (showJoystick) {\r\n            this.joystickZoneEl = document.createElement(\"div\");\r\n            this.joystickZoneEl.id = \"joy-zone\";\r\n            Object.assign(this.joystickZoneEl.style, {\r\n                position: \"absolute\",\r\n                left: \"16px\",\r\n                bottom: \"16px\",\r\n                width: `${JOY_SIZE + 40}px`,\r\n                height: `${JOY_SIZE + 40}px`,\r\n                touchAction: \"none\",\r\n                zIndex: \"999\",\r\n                pointerEvents: \"auto\",\r\n                WebkitUserSelect: \"none\",\r\n                userSelect: \"none\",\r\n            });\r\n            container.appendChild(this.joystickZoneEl);\r\n            this.blockTouch(this.joystickZoneEl);\r\n\r\n            // 初始化自定义摇杆\r\n            this.joystick = new VirtualJoystick(\r\n                this.joystickZoneEl,\r\n                JOY_SIZE,\r\n                (data) => {\r\n                    const rawX = data.vector?.x ?? 0;\r\n                    const rawY = data.vector?.y ?? 0;\r\n                    const distance = data.distance ?? 0;\r\n                    const deadzone = 0.2;\r\n                    const dirX = rawX > deadzone ? 1 : rawX < -deadzone ? -1 : 0;\r\n                    const dirY = rawY > deadzone ? 1 : rawY < -deadzone ? -1 : 0;\r\n                    const isSprinting = distance >= JOY_SIZE / 2;\r\n                    const prev = this.prevJoyState;\r\n                    if (dirX === prev.dirX && dirY === prev.dirY && isSprinting === prev.shift) return;\r\n                    this.prevJoyState = { dirX, dirY, shift: isSprinting };\r\n                    this.setInput({ moveX: dirX as any, moveY: dirY as any, shift: isSprinting });\r\n                },\r\n                () => {\r\n                    const prev = this.prevJoyState;\r\n                    if (prev.dirX !== 0 || prev.dirY !== 0 || prev.shift) {\r\n                        this.prevJoyState = { dirX: 0, dirY: 0, shift: false };\r\n                        this.setInput({ moveX: 0, moveY: 0, shift: false });\r\n                    }\r\n                },\r\n            );\r\n        }\r\n\r\n        // 创建视角区域\r\n        this.lookAreaEl = document.createElement(\"div\");\r\n        Object.assign(this.lookAreaEl.style, {\r\n            position: \"absolute\",\r\n            right: \"0\",\r\n            bottom: \"0\",\r\n            width: \"50%\",\r\n            height: \"100%\",\r\n            zIndex: \"998\",\r\n            touchAction: \"none\",\r\n            WebkitUserSelect: \"none\",\r\n            userSelect: \"none\",\r\n        });\r\n        container.appendChild(this.lookAreaEl);\r\n        this.blockTouch(this.lookAreaEl);\r\n\r\n        // 绑定视角触摸事件\r\n        this.lookAreaEl.addEventListener(\"pointerdown\", this.onPointerDown, { passive: false });\r\n        this.lookAreaEl.addEventListener(\"pointermove\", this.onPointerMove, { passive: false });\r\n        this.lookAreaEl.addEventListener(\"pointerup\", this.onPointerUp, { passive: false });\r\n        this.lookAreaEl.addEventListener(\"pointercancel\", this.onPointerUp, { passive: false });\r\n\r\n        // 创建操作按钮\r\n        if (showJump) {\r\n            this.jumpBtnEl = this.createBtn(container, 14, 14, jumpIconModule);\r\n            this.jumpBtnEl.addEventListener(\"touchstart\", (e) => { e.preventDefault(); this.setInput({ jump: true }); }, { passive: false });\r\n            this.jumpBtnEl.addEventListener(\"touchend\", (e) => { e.preventDefault(); this.setInput({ jump: false }); }, { passive: false });\r\n            this.jumpBtnEl.addEventListener(\"touchcancel\", (e) => { e.preventDefault(); this.setInput({ jump: false }); }, { passive: false });\r\n        }\r\n        if (showFly) {\r\n            this.flyBtnEl = this.createBtn(container, 14, 14 + 80, flyIconModule);\r\n            this.flyBtnEl.addEventListener(\"touchstart\", (e) => { e.preventDefault(); this.setInput({ toggleFly: true }); }, { passive: false });\r\n        }\r\n        if (showView) {\r\n            this.viewBtnEl = this.createBtn(container, 14, 14 + 200, viewIconModule);\r\n            this.viewBtnEl.addEventListener(\"touchstart\", (e) => { e.preventDefault(); this.setInput({ toggleView: true }); }, { passive: false });\r\n        }\r\n        if (showVehicle) {\r\n            this.vehicleBtnEl = this.createBtn(container, 14 + 100, 14 + 120, vehicleIconModule);\r\n            this.vehicleBtnEl.style.display = \"none\";\r\n            this.vehicleBtnEl.addEventListener(\"touchstart\", (e) => { e.preventDefault(); this.setInput({ toggleVehicle: true }); }, { passive: false });\r\n        }\r\n    }\r\n\r\n    // 销毁移动端控制\r\n    destroy() {\r\n        try {\r\n            this.joystick?.destroy();\r\n            this.joystick = null;\r\n\r\n            if (this.lookAreaEl) {\r\n                this.lookAreaEl.removeEventListener(\"pointerdown\", this.onPointerDown);\r\n                this.lookAreaEl.removeEventListener(\"pointermove\", this.onPointerMove);\r\n                this.lookAreaEl.removeEventListener(\"pointerup\", this.onPointerUp);\r\n                this.lookAreaEl.removeEventListener(\"pointercancel\", this.onPointerUp);\r\n            }\r\n\r\n            // 移除所有 DOM 元素\r\n            [this.joystickZoneEl, this.lookAreaEl, this.jumpBtnEl, this.flyBtnEl, this.viewBtnEl, this.vehicleBtnEl]\r\n                .forEach(el => el?.parentElement?.removeChild(el));\r\n\r\n            this.joystickZoneEl = this.lookAreaEl = this.jumpBtnEl =\r\n                this.flyBtnEl = this.viewBtnEl = this.vehicleBtnEl = null;\r\n        } catch (e) {\r\n            console.warn(\"销毁移动端控制时出错：\", e);\r\n        }\r\n    }\r\n\r\n    // 同步车辆按钮显隐\r\n    syncVehicleBtn(show: boolean) {\r\n        if (this.vehicleBtnEl) this.vehicleBtnEl.style.display = show ? \"block\" : \"none\";\r\n    }\r\n\r\n    // 同步控制模式按钮\r\n    syncControllerModeBtn(mode: 0 | 1) {\r\n        if (!this.flyBtnEl || !this.jumpBtnEl) return;\r\n        if (mode === 0) {\r\n            this.flyBtnEl.style.display = \"block\";\r\n            this.jumpBtnEl.style.backgroundImage = `linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5)),url(\"${jumpIconModule}\")`;\r\n        } else {\r\n            this.flyBtnEl.style.display = \"none\";\r\n            this.jumpBtnEl.style.backgroundImage = `url(${breakIconModule})`;\r\n        }\r\n    }\r\n\r\n    // 触摸按下\r\n    private onPointerDown = (e: PointerEvent) => {\r\n        if (e.pointerType !== \"touch\") return;\r\n        this.isLookDown = true;\r\n        this.lookPointerId = e.pointerId;\r\n        this.lastTouchX = e.clientX;\r\n        this.lastTouchY = e.clientY;\r\n        this.lookAreaEl?.setPointerCapture?.(e.pointerId);\r\n        e.preventDefault();\r\n    };\r\n\r\n    // 触摸移动\r\n    private onPointerMove = (e: PointerEvent) => {\r\n        if (!this.isLookDown || e.pointerId !== this.lookPointerId) return;\r\n        const dx = e.clientX - this.lastTouchX;\r\n        const dy = e.clientY - this.lastTouchY;\r\n        this.lastTouchX = e.clientX;\r\n        this.lastTouchY = e.clientY;\r\n        this.setInput({ lookDeltaX: dx, lookDeltaY: dy });\r\n        e.preventDefault();\r\n    };\r\n\r\n    // 触摸抬起\r\n    private onPointerUp = (e: PointerEvent) => {\r\n        if (e.pointerId !== this.lookPointerId) return;\r\n        this.isLookDown = false;\r\n        this.lookPointerId = null;\r\n        this.lookAreaEl?.releasePointerCapture?.(e.pointerId);\r\n    };\r\n\r\n    // 阻止默认触摸\r\n    private blockTouch(el: HTMLElement) {\r\n        [\"touchstart\", \"touchmove\", \"touchend\", \"touchcancel\"].forEach(name => {\r\n            el.addEventListener(name, e => e.preventDefault(), { passive: false });\r\n        });\r\n    }\r\n\r\n    // 创建圆形按钮\r\n    private createBtn(container: HTMLElement, rightPx: number, bottomPx: number, bgUrl: string): HTMLButtonElement {\r\n        const btn = document.createElement(\"button\");\r\n        Object.assign(btn.style, {\r\n            position: \"absolute\",\r\n            right: `${rightPx}px`,\r\n            bottom: `${bottomPx}px`,\r\n            width: \"56px\",\r\n            height: \"56px\",\r\n            zIndex: \"1000\",\r\n            borderRadius: \"50%\",\r\n            border: \"2px solid black\",\r\n            padding: \"20px\",\r\n            opacity: \"0.95\",\r\n            touchAction: \"none\",\r\n            fontSize: \"14px\",\r\n            userSelect: \"none\",\r\n            overflow: \"hidden\",\r\n            boxSizing: \"border-box\",\r\n            backgroundColor: \"transparent\",\r\n            backgroundRepeat: \"no-repeat, no-repeat\",\r\n            backgroundPosition: \"center center, center center\",\r\n            backgroundSize: \"80% 80%, 100% 100%\",\r\n            backgroundImage: `url(\"${bgUrl}\"),linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5))`,\r\n        });\r\n        container.appendChild(btn);\r\n        [\"touchstart\", \"touchend\", \"touchcancel\"].forEach(name => {\r\n            btn.addEventListener(name, e => e.preventDefault(), { passive: false });\r\n        });\r\n        return btn;\r\n    }\r\n}\r\n","import * as THREE from \"three\";\r\nimport type { playerController } from \"../playerController\";\r\n\r\nexport class AnimationSystem {\r\n    private ctrl: playerController; // 主控制器引用\r\n\r\n    mixer?: THREE.AnimationMixer; // 动画混合器\r\n    mixerCb?: (ev: any) => void; // 完成事件回调\r\n    actions?: Map<string, THREE.AnimationAction>; // 动作映射表\r\n    state!: THREE.AnimationAction; // 当前播放状态\r\n    sets = new Map<string, Map<string, THREE.AnimationAction>>(); // 动作集合组\r\n    currentLocomotionSet: string | null = null; // 当前激活的动作集合名\r\n    recheckTimer: any = null; // 延迟重检定时器\r\n    clips: THREE.AnimationClip[] = []; // 原始动画片段\r\n    hasThreePartJump = false; // 是否使用三段跳跃动画\r\n    isOverrideAnimationPlaying = false; // 动画锁，用于防止覆盖型动画被移动动画打断\r\n    private overrideInputSnapshot: Record<string, any> | null = null; // 覆盖动画播放时的输入快照，用于检测打断\r\n\r\n    constructor(ctrl: playerController) {\r\n        this.ctrl = ctrl;\r\n    }\r\n\r\n    // 按名切换动画\r\n    playByName(name: string, fade = 0.18) {\r\n        if (!this.actions) return;\r\n        const next = this.actions.get(name);\r\n        // 如果动画不存在，或已在播放，则忽略\r\n        if (!next || this.state === next) return;\r\n\r\n        const prev = this.state;\r\n        next.reset();\r\n        next.setEffectiveWeight(1);\r\n\r\n        // 上下车动画特殊处理：根据配置的上下车时间调整动画速度\r\n        if (name === \"enterCar\" || name === \"exitCar\") {\r\n            const duration = next.getClip().duration;\r\n            const enterTime = this.ctrl.vehicle.active?.enterVehicleTime ?? 1.5;\r\n            next.setEffectiveTimeScale(duration / enterTime);\r\n            next.setLoop(THREE.LoopOnce, 1);\r\n            next.clampWhenFinished = true;\r\n        }\r\n\r\n        next.play();\r\n        // 平滑过渡动画\r\n        if (prev && prev !== next) { prev.fadeOut(fade); next.fadeIn(fade); }\r\n        else next.fadeIn(fade);\r\n\r\n        this.state = next;\r\n        this.ctrl.onAnimationChange?.(name, next);\r\n    }\r\n\r\n    // 注册自定义动画\r\n    register(key: string, clipName: string, opts?: {\r\n        loop?: boolean;\r\n        timeScale?: number;\r\n        duration?: number;\r\n        clampWhenFinished?: boolean;\r\n        onFinished?: () => void;\r\n    }) {\r\n        if (!this.mixer || !this.actions) return;\r\n        const clip = this.clips.find(c => c.name === clipName);\r\n        if (!clip) { console.warn(`找不到 \"${clipName}\" 动画`); return; }\r\n\r\n        const action = this.mixer.clipAction(clip);\r\n        // duration 优先于 timeScale，如果指定了 duration，则据此计算 timeScale\r\n        const timeScale = opts?.duration ? clip.duration / opts.duration : (opts?.timeScale ?? 1);\r\n        action.setLoop(opts?.loop === false ? THREE.LoopOnce : THREE.LoopRepeat, Infinity);\r\n        action.clampWhenFinished = opts?.clampWhenFinished ?? false;\r\n        action.setEffectiveTimeScale(timeScale);\r\n        action.enabled = true;\r\n        action.setEffectiveWeight(0);\r\n        this.actions.set(key, action);\r\n\r\n        // 如果有 onFinished 回调，则监听动画完成事件\r\n        if (opts?.onFinished) {\r\n            this.mixer.addEventListener(\"finished\", (ev: any) => {\r\n                if (ev.action === action) opts.onFinished!();\r\n            });\r\n        }\r\n    }\r\n\r\n    // 注册移动动作组\r\n    registerLocomotionSet(setName: string, map: Partial<Record<\"idle\" | \"walking\" | \"walking_backward\" | \"running\" | \"jumping\" | \"flyidle\" | \"flying\", string>>) {\r\n        if (!this.mixer) return;\r\n        const set = new Map<string, THREE.AnimationAction>();\r\n        for (const [key, clipName] of Object.entries(map) as [string, string][]) {\r\n            const clip = this.clips.find(c => c.name === clipName);\r\n            if (!clip) { console.warn(`registerLocomotionSet: 找不到 \"${clipName}\"`); continue; }\r\n            const action = this.mixer.clipAction(clip);\r\n            // 跳跃动画特殊处理：只播放一次\r\n            if (key === \"jumping\") {\r\n                action.setLoop(THREE.LoopOnce, 1);\r\n                action.clampWhenFinished = true;\r\n                action.setEffectiveTimeScale(1.2);\r\n            } else {\r\n                action.setLoop(THREE.LoopRepeat, Infinity);\r\n                action.setEffectiveTimeScale(1);\r\n            }\r\n            action.enabled = true;\r\n            action.setEffectiveWeight(0);\r\n            set.set(key, action);\r\n        }\r\n        this.sets.set(setName, set);\r\n    }\r\n\r\n    // 切换移动动作组\r\n    switchLocomotionSet(setName: string, fade = 0.18) {\r\n        if (!this.actions) return;\r\n        const set = this.sets.get(setName);\r\n        if (!set) { console.warn(`switchLocomotionSet: 未找到集合 \"${setName}\"`); return; }\r\n        this.currentLocomotionSet = setName;\r\n        for (const [key, newAction] of set.entries()) {\r\n            const oldAction = this.actions.get(key);\r\n            if (oldAction === newAction) continue;\r\n            // 将旧动作淡出\r\n            if (oldAction) oldAction.fadeOut(fade);\r\n            // 替换当前动作表中的动作为新集合中的动作\r\n            this.actions.set(key, newAction);\r\n            // 如果正在播放的动画被替换，则立即切换到新动画\r\n            if (this.state === oldAction) {\r\n                newAction.reset();\r\n                newAction.setEffectiveWeight(1);\r\n                newAction.fadeIn(fade);\r\n                newAction.play();\r\n                this.state = newAction;\r\n                this.ctrl.onAnimationChange?.(key, newAction);\r\n            }\r\n        }\r\n    }\r\n\r\n    // 播放已注册动画\r\n    play(key: string, opts?: { fade?: number; force?: boolean; returnToPrev?: boolean }) {\r\n        if (!this.actions) return;\r\n        const action = this.actions.get(key);\r\n        if (!action) { console.warn(`playAnimation: \"${key}\" 未注册`); return; }\r\n\r\n        // 如果是播放一次的动画，则设置动画锁\r\n        if (action.loop === THREE.LoopOnce) {\r\n            // 设置动画锁\r\n            this.isOverrideAnimationPlaying = true;\r\n\r\n            // 记录当前完整输入状态快照\r\n            this.overrideInputSnapshot = { ...this.ctrl.input };\r\n\r\n            // 设置动画播放完毕后的自动解锁\r\n            const onFinish = (e: any) => {\r\n                if (e.action === action) {\r\n                    // 仅当锁仍然激活时才解锁\r\n                    if (this.isOverrideAnimationPlaying && this.overrideInputSnapshot) {\r\n                        this.isOverrideAnimationPlaying = false;\r\n                        this.overrideInputSnapshot = null;\r\n                    }\r\n                    this.mixer!.removeEventListener('finished', onFinish);\r\n                }\r\n            };\r\n            this.mixer!.addEventListener('finished', onFinish);\r\n        }\r\n\r\n        if (opts?.force) action.reset();\r\n\r\n        // 记录初始动画状态以便返回\r\n        const prevState = opts?.returnToPrev ? this.state : null;\r\n        // 播放目标动画\r\n        this.playByName(key, opts?.fade ?? 0.18);\r\n\r\n        // 如果设置 returnToPrev，则在动画播放完毕后返回之前的动画状态\r\n        if (opts?.returnToPrev && prevState && this.mixer) {\r\n            // 存储当前动画状态\r\n            const action = this.actions.get(key)!;\r\n            const fade = opts?.fade ?? 0.18;\r\n            // 定义一个一次性的事件处理器\r\n            const handler = (ev: any) => {\r\n                if (ev.action === action && this.state === action) {\r\n                    this.mixer!.removeEventListener(\"finished\", handler);\r\n                    const cur = this.state;\r\n                    // 停止当前动画\r\n                    cur.stop();\r\n                    // 重置前一个状态\r\n                    prevState.reset();\r\n                    // 将权重设置为1并播放前一个状态动画\r\n                    prevState.setEffectiveWeight(1);\r\n                    prevState.play();\r\n                    // 更新状态\r\n                    this.state = prevState;\r\n                    this.ctrl.onAnimationChange?.(prevState.getClip().name, prevState);\r\n                }\r\n            };\r\n            // 监听动画完成事件\r\n            this.mixer.addEventListener(\"finished\", handler);\r\n        }\r\n    }\r\n\r\n    // 触发跳跃动画（统一入口）\r\n    startJump(inAir = false) {\r\n        // 根据是否配置了三段跳跃，播放不同动画\r\n        if (this.hasThreePartJump) {\r\n            this.playByName(inAir ? \"jumpLoop\" : \"jumpStart\");\r\n        } else {\r\n            this.playByName(\"jumping\");\r\n        }\r\n    }\r\n\r\n    // 离地时触发 jumpLoop（三段模式专用）\r\n    onBecomeAirborne() {\r\n        if (!this.hasThreePartJump) return;\r\n        const s = this.state;\r\n        const a = this.actions;\r\n        // 如果当前已经在跳跃动画中，则不打断\r\n        if (s === a?.get(\"jumpStart\") || s === a?.get(\"jumpLoop\") || s === a?.get(\"jumpEnd\")) return;\r\n        this.playByName(\"jumpLoop\");\r\n    }\r\n\r\n    // 落地时触发 jumpEnd（三段模式专用）\r\n    onLand() {\r\n        if (!this.hasThreePartJump) return;\r\n        const s = this.state;\r\n        const a = this.actions;\r\n        // 只有在起跳或跳跃循环中才触发落地\r\n        if (s === a?.get(\"jumpStart\") || s === a?.get(\"jumpLoop\")) {\r\n            this.playByName(\"jumpEnd\");\r\n        }\r\n    }\r\n\r\n    // 是否处于任意跳跃动画中（用于防止在跳跃动画播放时重复起跳）\r\n    isJumping(): boolean {\r\n        const s = this.state;\r\n        const a = this.actions;\r\n        if (!a) return false;\r\n        return s === a.get(\"jumping\") || s === a.get(\"jumpStart\") ||\r\n            s === a.get(\"jumpLoop\") || s === a.get(\"jumpEnd\");\r\n    }\r\n\r\n    // 获取当前动画名\r\n    getCurrentName(): string | null {\r\n        return this.state?.getClip()?.name ?? null;\r\n    }\r\n\r\n    // 更新所有混合器\r\n    updateMixers(delta: number) {\r\n        this.mixer?.update(delta);\r\n        for (const v of this.ctrl.vehicle.list) v.vehicleMixer?.update(delta);\r\n    }\r\n\r\n    // 按键状态触发动画\r\n    setAnimationByPressed() {\r\n        // 检查并处理覆盖动画中断逻辑\r\n        if (this.isOverrideAnimationPlaying) {\r\n            const currentInput = this.ctrl.input as Record<string, any>;\r\n            const snapshot = this.overrideInputSnapshot;\r\n            let inputChanged = false;\r\n\r\n            if (snapshot) {\r\n                // 遍历快照中的所有键，与当前输入状态进行比较\r\n                for (const key in snapshot) {\r\n                    if (snapshot[key] !== currentInput[key]) {\r\n                        inputChanged = true;\r\n                        break; // 不匹配，中断\r\n                    }\r\n                }\r\n            }\r\n\r\n            // 如果输入状态发生变化，则解除动画锁，并继续执行后续的移动动画逻辑\r\n            if (inputChanged) {\r\n                this.isOverrideAnimationPlaying = false;\r\n                this.overrideInputSnapshot = null;\r\n            } else {\r\n                // 如果输入状态未变，则保持覆盖动画，不执行移动动画\r\n                return;\r\n            }\r\n        }\r\n\r\n        // 恢复相机距离\r\n        this.ctrl.cam.maxDist = this.ctrl.cam.originMaxDist;\r\n\r\n        const v = this.ctrl.vehicle;\r\n        // 上下车流程中：有移动键输入才允许打断，否则不干预\r\n        if (v.isMovingToBoarding || v.isBoardingAnim || v.isExitAnim) {\r\n            const { fwd, bkd, lft, rgt } = this.ctrl.input;\r\n            if (!fwd && !bkd && !lft && !rgt) return;\r\n        }\r\n\r\n        // 取消上下车过程\r\n        v.cancelBoarding();\r\n        if (v.isExitAnim) { v.isExitAnim = false; v.exitDoorClosed = false; }\r\n        if (v.isBoardingAnim) { v.isBoardingAnim = false; v.doorClosed = false; }\r\n        if (v.doorTimer) { clearTimeout(v.doorTimer); v.doorTimer = null; }\r\n\r\n        const { fwd, bkd, lft, rgt, shift, space } = this.ctrl.input;\r\n\r\n        // 飞行状态下的动画逻辑\r\n        if (this.ctrl.isFlying) {\r\n            if (fwd) {\r\n                if (shift) {\r\n                    this.playByName(\"flying\");\r\n                    // 加速飞行时，拉远相机\r\n                    if (!this.ctrl.cam.enableSpringCamera) this.ctrl.cam.maxDist = this.ctrl.cam.originMaxDist * 2;\r\n                } else {\r\n                    this.playByName(\"flyHoverForward\");\r\n                }\r\n                return;\r\n            }\r\n            if (bkd) { this.playByName(\"flyHoverBack\"); return; }\r\n            if (lft) { this.playByName(\"flyHoverLeft\"); return; }\r\n            if (rgt) { this.playByName(\"flyHoverRight\"); return; }\r\n            if (space) { this.playByName(\"flyHoverUp\"); return; }\r\n            // 无任何操作时，播放悬停动画\r\n            this.playByName(\"flyidle\");\r\n            return;\r\n        }\r\n\r\n        // 地面状态下的动画逻辑\r\n        if (this.ctrl.playerIsOnGround) {\r\n            // 如果是三段跳的落地动画，则等待其播放完毕\r\n            if (this.hasThreePartJump && this.state === this.actions?.get(\"jumpEnd\")) return;\r\n            // 无方向键输入，播放站立动画\r\n            if (!fwd && !bkd && !lft && !rgt) { this.playByName(\"idle\"); return; }\r\n            // 向前走或跑\r\n            if (fwd) { this.playByName(shift ? \"running\" : \"walking\"); return; }\r\n            // 第三人称下，左、右、后退也播放走/跑动画（模型会自动转向）\r\n            if (!this.ctrl.isFirstPerson && (lft || rgt || bkd)) {\r\n                this.playByName(shift ? \"running\" : \"walking\"); return;\r\n            }\r\n            // 第一人称下的平移和后退\r\n            if (lft) { this.playByName(\"left_walking\"); return; }\r\n            if (rgt) { this.playByName(\"right_walking\"); return; }\r\n            if (bkd) { this.playByName(\"walking_backward\"); return; }\r\n        }\r\n    }\r\n}","import * as THREE from \"three\";\r\nimport type { playerController } from \"../playerController\";\r\n\r\nexport class CameraSystem {\r\n    private ctrl: playerController; // 主控制器引用\r\n\r\n    collisionLerp = 0.18; // 碰撞插值速度\r\n    epsilon = 35; // 安全距离偏移\r\n    minDist = 100; // 最小相机距离\r\n    maxDist = 440; // 最大相机距离\r\n    originMaxDist = 440; // 初始最大距离\r\n    sensitivity = 5; // 鼠标灵敏度\r\n    mouseMode: 0 | 1 | 2 | 3 | 4 | 5 = 1; // 鼠标控制模式\r\n    zoomEnabled = false; // 是否允许缩放\r\n    lookAtHeightRatio = 0.8; // 第三人称看向点高度比例（0=底部，1=顶部）\r\n\r\n    private lookAtPoint = new THREE.Vector3(); // 预分配的看向点向量\r\n\r\n    enableSpringCamera = false;\r\n    springCameraTime = 0.15;\r\n    private _springVelocity = new THREE.Vector3();\r\n    private _springResult = new THREE.Vector3();\r\n\r\n    raycaster = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3()); // 相机碰撞射线\r\n    centerRay = new THREE.Raycaster(); // 屏幕中心射线\r\n    centerMouse = new THREE.Vector2(); // 屏幕中心坐标\r\n    playerToCam = new THREE.Vector3(); // 玩家到相机向量\r\n\r\n    constructor(ctrl: playerController) {\r\n        this.ctrl = ctrl;\r\n        (this.raycaster as any).firstHitOnly = true;\r\n    }\r\n\r\n    // 弹簧阻尼插值，返回本帧的看向点；enableSpringCamera 关闭时直接返回看向点\r\n    applySpringToTarget(delta: number): THREE.Vector3 {\r\n        const dest = this.getLookAtPoint();\r\n        if (!this.enableSpringCamera) return dest;\r\n        const cur = this.ctrl.controls.target;\r\n        const v = this._springVelocity;\r\n        const out = this._springResult;\r\n        const smoothTime = Math.max(0.0001, this.springCameraTime);\r\n        const omega = 2 / smoothTime;\r\n        const x = omega * delta;\r\n        const exp = 1 / (1 + x + 0.48 * x * x + 0.235 * x * x * x);\r\n        const axes = ['x', 'y', 'z'] as const;\r\n        for (const a of axes) {\r\n            const change = cur[a] - dest[a];\r\n            const temp = (v[a] + omega * change) * delta;\r\n            v[a] = (v[a] - omega * temp) * exp;\r\n            let o = dest[a] + (change + temp) * exp;\r\n            if ((dest[a] - cur[a] > 0) === (o > dest[a])) {\r\n                o = dest[a];\r\n                v[a] = 0;\r\n            }\r\n            out[a] = o;\r\n        }\r\n        return out;\r\n    }\r\n\r\n    // 第三人称相机看向点\r\n    getLookAtPoint(): THREE.Vector3 {\r\n        const capsuleInfo = this.ctrl.playerCapsule.capsuleInfo;\r\n        const r = capsuleInfo.radius;\r\n        const totalH = -capsuleInfo.segment.end.y + 2 * r;\r\n        const y = this.ctrl.playerCapsule.position.y + r - totalH * (1 - this.lookAtHeightRatio);\r\n        return this.lookAtPoint.copy(this.ctrl.playerCapsule.position).setY(y);\r\n    }\r\n\r\n    // 设置越肩视角\r\n    setOverShoulder(enable: boolean) {\r\n        if (!enable || this.ctrl.controllerMode === 1) { this.ctrl.camera.clearViewOffset(); return; }\r\n        const w = window.innerWidth;\r\n        const h = window.innerHeight;\r\n        this.ctrl.camera.setViewOffset(w, h, w * 0.2, 0, w, h);\r\n    }\r\n\r\n    // 切换视角模式\r\n    changeView() {\r\n        this.ctrl.onBeforeViewChange?.(this.ctrl.isFirstPerson);\r\n        this.ctrl.isFirstPerson = !this.ctrl.isFirstPerson;\r\n        if (this.ctrl.isFirstPerson) {\r\n            // 切到第一人称，先对齐胶囊体朝向\r\n            const playerFwd = new THREE.Vector3(0, 0, 1).applyQuaternion(this.ctrl.playerCapsule.quaternion);\r\n            const flatDir = new THREE.Vector3(playerFwd.x, 0, playerFwd.z).normalize();\r\n            if (flatDir.lengthSq() > 0.001) {\r\n                const yAngle = Math.atan2(flatDir.x, flatDir.z);\r\n                this.ctrl.playerCapsule.rotation.set(0, yAngle, 0);\r\n            }\r\n            this.setFirstPerson();\r\n            this.setOverShoulder(false);\r\n        } else {\r\n            // 切到第三人称，放置相机到玩家背后\r\n            this.ctrl.controls.enabled = true;\r\n            this.ctrl.scene.attach(this.ctrl.camera);\r\n            const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(this.ctrl.playerCapsule.quaternion);\r\n            const angle = Math.atan2(dir.z, dir.x);\r\n            const s = this.ctrl.playerModelConfig.scale;\r\n            const rawOffset = new THREE.Vector3(Math.cos(angle) * 400 * s, 200 * s, Math.sin(angle) * 400 * s);\r\n            this.ctrl.controls.target.copy(this.getLookAtPoint());\r\n            this.ctrl.camera.position.copy(this.ctrl.controls.target).add(rawOffset.normalize().multiplyScalar(this.maxDist));\r\n            this.ctrl.controls.enableZoom = this.zoomEnabled;\r\n            this.setOverShoulder(this.ctrl.enableOverShoulderView);\r\n        }\r\n        this.setPointerLock();\r\n        this.ctrl.onViewChange?.(this.ctrl.isFirstPerson);\r\n    }\r\n\r\n    // 进入第一人称\r\n    setFirstPerson(vertAngle = 0) {\r\n        this.ctrl.controls.enabled = false;\r\n        const s = this.ctrl.playerModelConfig.scale;\r\n        const sharedOffset = this.ctrl.playerModelConfig.firstPersonCameraOffset;\r\n        // 有头骨节点挂到头骨，否则挂到胶囊体\r\n        if (this.ctrl.playerModelHead) {\r\n            const [x, y, z] = sharedOffset ?? [0, 10, 20];\r\n            this.ctrl.playerModelHead.attach(this.ctrl.camera);\r\n            this.ctrl.camera.position.set(x, y, z);\r\n        } else {\r\n            const [x, y, z] = sharedOffset ?? [0, 40, 30];\r\n            this.ctrl.playerCapsule.attach(this.ctrl.camera);\r\n            this.ctrl.camera.position.set(x * s, y * s, z * s);\r\n        }\r\n        this.ctrl.camera.rotation.set(\r\n            THREE.MathUtils.clamp(vertAngle, -1.1, 1.4),\r\n            Math.PI,\r\n            0,\r\n        );\r\n        this.ctrl.controls.enableZoom = false;\r\n    }\r\n\r\n    // 指针锁定控制\r\n    setPointerLock() {\r\n        if (!document.body.requestPointerLock) return;\r\n        if (((this.mouseMode === 0 || this.mouseMode === 1 || this.mouseMode === 5) && !this.ctrl.isFirstPerson) || this.ctrl.isFirstPerson) {\r\n            document.body.requestPointerLock();\r\n        } else {\r\n            document.exitPointerLock();\r\n        }\r\n    }\r\n\r\n    // 初始相机位置\r\n    setCamPos() {\r\n        requestAnimationFrame(() => {\r\n            if (!this.ctrl.isFirstPerson) {\r\n                const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(this.ctrl.playerCapsule.quaternion);\r\n                const angle = Math.atan2(dir.z, dir.x);\r\n                const s = this.ctrl.playerModelConfig.scale;\r\n                const rawOffset = new THREE.Vector3(Math.cos(angle) * 400 * s, 200 * s, Math.sin(angle) * 400 * s);\r\n                this.ctrl.controls.target.copy(this.getLookAtPoint());\r\n                this.ctrl.camera.position.copy(this.ctrl.controls.target).add(rawOffset.normalize().multiplyScalar(this.maxDist));\r\n                this.ctrl.controls.enableZoom = this.zoomEnabled;\r\n            } else {\r\n                this.setFirstPerson();\r\n            }\r\n            this.ctrl.camera.updateProjectionMatrix();\r\n        });\r\n    }\r\n\r\n    // 初始化轨道控制\r\n    initControls() {\r\n        this.ctrl.controls.enableZoom = this.zoomEnabled;\r\n        this.ctrl.controls.rotateSpeed = this.sensitivity * 0.05;\r\n        this.ctrl.controls.maxPolarAngle = Math.PI;\r\n        this.ctrl.controls.mouseButtons = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\r\n        // 防止相机轨道半径归零穿越目标点\r\n        this.ctrl.controls.minDistance = this.minDist;\r\n    }\r\n\r\n    // 重置轨道控制\r\n    resetControls() {\r\n        if (!this.ctrl.controls) return;\r\n        this.ctrl.controls.enabled = true;\r\n        this.ctrl.controls.enablePan = true;\r\n        this.ctrl.controls.maxPolarAngle = Math.PI / 2;\r\n        this.ctrl.controls.rotateSpeed = 1;\r\n        this.ctrl.controls.enableZoom = true;\r\n        this.ctrl.controls.mouseButtons = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\r\n    }\r\n\r\n    // 处理鼠标朝向\r\n    setToward(dx: number, dy: number, speed: number) {\r\n        this.ctrl.onTowardChange?.(dx, dy, speed);\r\n        if (!this.ctrl.enableToward || (this.ctrl.controllerMode === 0 && this.ctrl.isFirstPerson && this.ctrl.vehicle.isMovingToBoarding)) return;\r\n        const sens = this.sensitivity;\r\n        if (this.ctrl.controllerMode === 0) {\r\n            // 步行第一人称\r\n            if (this.ctrl.isFirstPerson) {\r\n                this.ctrl.playerCapsule.rotateY(-dx * speed * sens);\r\n                this.ctrl.camera.rotation.x = THREE.MathUtils.clamp(\r\n                    this.ctrl.camera.rotation.x + (-dy * speed * sens),\r\n                    -Math.PI * (60 / 180), Math.PI * (80 / 180),\r\n                );\r\n            } else {\r\n                // 步行第三人称\r\n                this.orbit(this.getLookAtPoint(), -dx * speed * sens, -dy * speed * sens);\r\n            }\r\n        } else {\r\n            const v = this.ctrl.vehicle.active;\r\n            if (!v) return;\r\n            // 载具第一人称\r\n            if (this.ctrl.isFirstPerson) {\r\n                this.ctrl.camera.rotation.y = THREE.MathUtils.clamp(this.ctrl.camera.rotation.y + (-dx * speed * sens), Math.PI * (3 / 4), Math.PI * (5 / 4));\r\n                this.ctrl.camera.rotation.x = THREE.MathUtils.clamp(this.ctrl.camera.rotation.x + (-dy * speed * sens), 0, Math.PI * (1 / 3));\r\n            } else {\r\n                // 载具第三人称\r\n                this.orbit(v.vehicleGroup.position, -dx * speed * sens, -dy * speed * sens);\r\n            }\r\n        }\r\n    }\r\n\r\n    // 手动轨道旋转\r\n    private orbit(target: THREE.Vector3, deltaX: number, deltaY: number) {\r\n        const distance = this.ctrl.camera.position.distanceTo(target);\r\n        const cur = this.ctrl.camera.position.clone().sub(target);\r\n        let theta = Math.atan2(cur.x, cur.z) + deltaX;\r\n        let phi = Math.acos(THREE.MathUtils.clamp(cur.y / distance, -1, 1)) + deltaY;\r\n        // 限制仰角避免万向节死锁\r\n        phi = Math.max(0.1, Math.min(Math.PI - 0.1, phi));\r\n        this.ctrl.camera.position.set(\r\n            target.x + distance * Math.sin(phi) * Math.sin(theta),\r\n            target.y + distance * Math.cos(phi),\r\n            target.z + distance * Math.sin(phi) * Math.cos(theta),\r\n        );\r\n        this.ctrl.camera.lookAt(target);\r\n    }\r\n\r\n    // 射线防穿墙\r\n    updateWithRaycast(origin: THREE.Vector3, desiredDist: number, maxDist: number) {\r\n        this.playerToCam.subVectors(this.ctrl.camera.position, origin);\r\n        const direction = this.playerToCam.clone().normalize();\r\n        this.raycaster.set(origin, direction);\r\n        this.raycaster.far = desiredDist;\r\n\r\n        const hits = this.raycaster.intersectObject(this.ctrl.collider!, false);\r\n        // 有遮挡：贴近安全距离\r\n        if (hits.length > 0) {\r\n            const safeDist = Math.max(hits[0].distance - this.epsilon, this.minDist);\r\n            this.ctrl.camera.position.lerp(origin.clone().add(direction.multiplyScalar(safeDist)), this.collisionLerp);\r\n        } else {\r\n            // 无遮挡：尝试拉到最大距离\r\n            this.raycaster.far = maxDist;\r\n            const maxHits = this.raycaster.intersectObject(this.ctrl.collider!, false);\r\n            const safeDist = maxHits.length > 0 ? Math.min(maxDist, maxHits[0].distance - this.epsilon) : maxDist;\r\n            this.ctrl.camera.position.lerp(origin.clone().add(direction.multiplyScalar(safeDist)), this.collisionLerp);\r\n        }\r\n    }\r\n\r\n    // 屏幕中心检测\r\n    getCenterHit(): THREE.Intersection | undefined {\r\n        this.ctrl.camera.updateMatrixWorld();\r\n        this.centerRay.setFromCamera(this.centerMouse, this.ctrl.camera);\r\n        this.centerRay.layers.set(1);\r\n        this.centerRay.layers.enable(2);\r\n\r\n        const checkTargets = this.ctrl.collider ? [this.ctrl.collider, ...this.ctrl.scene.children] : this.ctrl.scene.children;\r\n        const hits = this.centerRay.intersectObjects(checkTargets, true);\r\n        hits.sort((a, b) => a.distance - b.distance);\r\n        if (hits[0]) return hits[0];\r\n\r\n        // 无命中返回1000距离的虚拟点\r\n        const fallbackPoint = this.centerRay.ray.at(1000, new THREE.Vector3());\r\n        return {\r\n            distance: 1000, point: fallbackPoint, object: this.ctrl.camera,\r\n            uv: null as any, normal: null as any, face: null as any,\r\n            faceIndex: null as any, instanceId: undefined,\r\n        } as THREE.Intersection;\r\n    }\r\n}\r\n","import type { playerController } from \"../playerController\";\r\nimport type { KeyAction, KeyMap } from \"../types\";\r\n\r\n// 默认键位表（动作 -> KeyboardEvent.code 列表）\r\nconst defaultKeyMap: Record<KeyAction, string[]> = {\r\n    forward: [\"KeyW\", \"ArrowUp\"],\r\n    backward: [\"KeyS\", \"ArrowDown\"],\r\n    left: [\"KeyA\", \"ArrowLeft\"],\r\n    right: [\"KeyD\", \"ArrowRight\"],\r\n    sprint: [\"ShiftLeft\", \"ShiftRight\"],\r\n    jump: [\"Space\"],\r\n    toggleView: [\"KeyV\"],\r\n    toggleFly: [\"KeyF\"],\r\n    toggleVehicle: [\"KeyE\"],\r\n};\r\n\r\nexport class InputSystem {\r\n    private ctrl: playerController; // 主控制器引用\r\n\r\n    fwd = false; // 前进键\r\n    bkd = false; // 后退键\r\n    lft = false; // 左移键\r\n    rgt = false; // 右移键\r\n    space = false; // 跳跃键\r\n    shift = false; // 加速键\r\n\r\n    private boundKeydown = async (e: KeyboardEvent) => this.onKeydown(e); // 键盘按下绑定\r\n    private boundKeyup = (e: KeyboardEvent) => this.onKeyup(e); // 键盘抬起绑定\r\n    private boundMouseMove = (e: MouseEvent) => this.onMouseMove(e); // 鼠标移动绑定\r\n    private boundMouseClick = () => this.ctrl.cam.setPointerLock(); // 鼠标点击绑定\r\n    private boundBlur = () => this.resetKeys(); // 页面失焦时重置按键状态\r\n\r\n    private codeToAction = new Map<string, KeyAction>(); // 键码 -> 动作 反查表\r\n\r\n    constructor(ctrl: playerController) {\r\n        this.ctrl = ctrl;\r\n        this.buildKeyMap();\r\n    }\r\n\r\n    // 构建键码：动作 反查表：未传的动作用默认键，传 string/数组则覆盖，传 null 则禁用\r\n    buildKeyMap(userMap?: KeyMap) {\r\n        this.codeToAction.clear();  // 清空旧表\r\n        for (const action of Object.keys(defaultKeyMap) as KeyAction[]) {\r\n            let codes: string[];\r\n            if (userMap && action in userMap) {\r\n                const v = userMap[action];\r\n                if (v == null) continue; // null：禁用该动作\r\n                codes = Array.isArray(v) ? v : [v]; // 覆盖默认键\r\n            } else {\r\n                codes = defaultKeyMap[action];  // 未传：用默认键\r\n            }\r\n            for (const code of codes) this.codeToAction.set(code, action);\r\n        }\r\n    }\r\n\r\n    // 程序化输入接口\r\n    setInput(input: Partial<{\r\n        moveX: 1 | 0 | -1; moveY: 1 | 0 | -1;\r\n        lookDeltaX: number; lookDeltaY: number;\r\n        jump: boolean; shift: boolean;\r\n        toggleView: boolean; toggleFly: boolean; toggleVehicle: boolean;\r\n    }>) {\r\n        const c = this.ctrl;\r\n\r\n        // 移动方向\r\n        if (typeof input.moveX === \"number\") { this.applyAction(\"left\", input.moveX === -1); this.applyAction(\"right\", input.moveX === 1); }\r\n        if (typeof input.moveY === \"number\") { this.applyAction(\"forward\", input.moveY === 1); this.applyAction(\"backward\", input.moveY === -1); }\r\n\r\n        // 视角朝向\r\n        if (typeof input.lookDeltaX === \"number\" && typeof input.lookDeltaY === \"number\") {\r\n            c.cam.setToward(input.lookDeltaX, input.lookDeltaY, 0.002);\r\n        }\r\n\r\n        // 持续状态\r\n        if (typeof input.jump === \"boolean\") this.applyAction(\"jump\", input.jump);\r\n        if (typeof input.shift === \"boolean\") this.applyAction(\"sprint\", input.shift);\r\n\r\n        // 触发式切换\r\n        if (input.toggleView) this.applyAction(\"toggleView\", true);\r\n        if (input.toggleFly) this.applyAction(\"toggleFly\", true);\r\n        if (input.toggleVehicle) this.applyAction(\"toggleVehicle\", true);\r\n    }\r\n\r\n    // 绑定输入事件\r\n    bindEvents() {\r\n        this.ctrl.isupdate = true;\r\n        this.ctrl.cam.setPointerLock();\r\n        window.addEventListener(\"keydown\", this.boundKeydown);\r\n        window.addEventListener(\"keyup\", this.boundKeyup);\r\n        window.addEventListener(\"mousemove\", this.boundMouseMove);\r\n        window.addEventListener(\"click\", this.boundMouseClick);\r\n        window.addEventListener(\"blur\", this.boundBlur);\r\n    }\r\n\r\n    // 解绑输入事件\r\n    unbindEvents() {\r\n        this.ctrl.isupdate = false;\r\n        document.exitPointerLock();\r\n        window.removeEventListener(\"keydown\", this.boundKeydown);\r\n        window.removeEventListener(\"keyup\", this.boundKeyup);\r\n        window.removeEventListener(\"mousemove\", this.boundMouseMove);\r\n        window.removeEventListener(\"click\", this.boundMouseClick);\r\n        window.removeEventListener(\"blur\", this.boundBlur);\r\n    }\r\n\r\n    // 重置所有按键状态\r\n    private resetKeys() {\r\n        const c = this.ctrl;\r\n        this.fwd = false;\r\n        this.bkd = false;\r\n        this.lft = false;\r\n        this.rgt = false;\r\n        this.space = false;\r\n        this.shift = false;\r\n        c.controls.mouseButtons = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\r\n        c.animation.setAnimationByPressed();\r\n    }\r\n\r\n    // 统一动作派发\r\n    private applyAction(action: KeyAction, pressed: boolean) {\r\n        const c = this.ctrl;\r\n        switch (action) {\r\n            // 前进\r\n            case \"forward\": this.fwd = pressed; c.animation.setAnimationByPressed(); break;\r\n            // 后退\r\n            case \"backward\": this.bkd = pressed; c.animation.setAnimationByPressed(); break;\r\n            // 左移\r\n            case \"left\": this.lft = pressed; c.animation.setAnimationByPressed(); break;\r\n            // 右移\r\n            case \"right\": this.rgt = pressed; c.animation.setAnimationByPressed(); break;\r\n            // 冲刺\r\n            case \"sprint\":\r\n                this.shift = pressed;\r\n                c.animation.setAnimationByPressed();\r\n                // 切换轨道拖拽键位\r\n                c.controls.mouseButtons = pressed\r\n                    ? { LEFT: 2, MIDDLE: 1, RIGHT: 0 }\r\n                    : { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\r\n                break;\r\n            // 跳跃\r\n            case \"jump\":\r\n                if (pressed) {\r\n                    c.vehicle.cancelBoarding(); // 取消载具模式下的下车\r\n                    this.space = true;\r\n                    if (c.controllerMode === 1) return; // 载具模式不跳跃\r\n                    if (c.isFlying) { c.animation.setAnimationByPressed(); return; } // 飞行中仅切动画\r\n                    if (!c.playerIsOnGround) return; // 不在地面不能跳\r\n                    if (c.animation.isJumping()) return;  // 跳跃中不重复触发\r\n                    c.animation.startJump();\r\n                    c.playerVelocity.y = c.jumpHeight;\r\n                    c.setOnGround(false); // 跳跃后设置为不在地面\r\n                } else {\r\n                    this.space = false;\r\n                    if (c.isFlying) c.animation.setAnimationByPressed();\r\n                }\r\n                break;\r\n            // 切换第一 / 第三人称视角\r\n            case \"toggleView\":\r\n                if (pressed) c.cam.changeView();\r\n                break;\r\n            // 切换飞行模式\r\n            case \"toggleFly\":\r\n                if (pressed && c.controllerMode === 0) {\r\n                    c.isFlying = !c.isFlying;\r\n                    if (c.isFlying) c.playerVelocity.set(0, 0, 0);\r\n                    c.animation.setAnimationByPressed();\r\n                    if (!c.isFlying && !c.playerIsOnGround) c.animation.startJump(true); \r\n                }\r\n                break;\r\n            // 上 / 下车\r\n            case \"toggleVehicle\":\r\n                if (pressed) {\r\n                    if (c.isFlying) return;\r\n                    if (c.controllerMode === 0) c.vehicle.enter(); else c.vehicle.exit();\r\n                }\r\n                break;\r\n        }\r\n    }\r\n\r\n    // 键盘按下处理\r\n    private onKeydown(e: KeyboardEvent) {\r\n        const action = this.codeToAction.get(e.code);\r\n        if (action) this.applyAction(action, true);\r\n    }\r\n\r\n    // 键盘抬起处理\r\n    private onKeyup(e: KeyboardEvent) {\r\n        const action = this.codeToAction.get(e.code);\r\n        if (action) this.applyAction(action, false);\r\n    }\r\n\r\n    // 鼠标移动处理\r\n    private onMouseMove(e: MouseEvent) {\r\n        if (document.pointerLockElement === document.body) {\r\n            this.ctrl.cam.setToward(e.movementX, e.movementY, 0.0001);\r\n        }\r\n    }\r\n}\r\n","import * as THREE from \"three\";\r\nimport type { World } from \"@dimforge/rapier3d-compat\";\r\nimport type { playerController } from \"../playerController\";\r\nimport { loadVehicleModel as loadVehicleModelUtil } from \"../utils/vehicleLoader\";\r\nimport type { VehicleInstance, VehicleOptions } from \"../types\";\r\n\r\nexport class VehicleSystem {\r\n    private ctrl: playerController; // 主控制器引用\r\n\r\n    list: VehicleInstance[] = []; // 车辆实例列表\r\n    active: VehicleInstance | null = null; // 当前乘坐车辆\r\n    maxCount = 6; // 最大车辆数量\r\n    RAPIER: any = null; // 物理引擎模块\r\n    world: World | null = null; // 物理世界实例\r\n    params = {\r\n        debug: { showPhysicsBox: false }, // 调试显示\r\n        chassis: { linearDamping: 0.5, angularDamping: 0.5 }, // 车身阻尼\r\n        model: { rotation: -Math.PI / 2 }, // 模型旋转\r\n        power: { accelerateForce: 50, brakeForce: 200, maxSpeed: 10000 }, // 动力参数\r\n        steering: { maxSteerAngle: Math.PI / 4, steerSpeed: 0.5, steerReturnSpeed: 1 }, // 转向参数\r\n        followVehicleDirection: true, // 相机跟随方向\r\n    };\r\n\r\n    steerQuat = new THREE.Quaternion(); // 转向四元数\r\n    rotQuat = new THREE.Quaternion(); // 旋转四元数\r\n    camBehindDir = new THREE.Vector3(0, 0, 1); // 相机跟随方向\r\n\r\n    // ==================== 上车流程状态 ====================\r\n    isMovingToBoarding = false; // 正在走向上车点\r\n    waypoints: THREE.Vector3[] = []; // 路径节点列表\r\n    waypointIdx = 0; // 当前路径节点\r\n    targetDir: THREE.Vector3 | null = null; // 目标朝向\r\n    moveSpeed = 300; // 自动移动速度\r\n    rotSpeed = 10; // 自动旋转速度\r\n    boardingPoint: THREE.Vector3 | null = null; // 上车位置\r\n    isBoardingAnim = false; // 上车动画中\r\n    doorClosed = false; // 上车门已关\r\n    isExitAnim = false; // 下车动画中\r\n    exitDoorClosed = false; // 下车门已关\r\n    doorTimer: any = null; // 开关门定时器\r\n    flip180 = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI); // 180度翻转\r\n\r\n    constructor(ctrl: playerController) {\r\n        this.ctrl = ctrl;\r\n    }\r\n\r\n    // 初始化物理引擎\r\n    async initRapier() {\r\n        if (this.RAPIER) return;\r\n        this.RAPIER = await import(\"@dimforge/rapier3d-compat\");\r\n        await this.RAPIER.init();\r\n\r\n        this.world = new this.RAPIER.World(new this.RAPIER.Vector3(0, -9.81, 0)) as World;\r\n        (this.world as any).maxCcdSubsteps = 2;\r\n\r\n        // 构建三角网格碰撞体\r\n        const addTrimesh = (RAPIER: any, world: any, geom: THREE.BufferGeometry) => {\r\n            let g = geom.index ? geom.clone().toNonIndexed() : geom.clone();\r\n            const pos = g.attributes.position;\r\n            const count = pos.count;\r\n            const verts = new Float32Array(count * 3);\r\n            const tmp = new THREE.Vector3();\r\n            for (let i = 0; i < count; i++) {\r\n                tmp.fromBufferAttribute(pos, i);\r\n                verts[i * 3] = tmp.x; verts[i * 3 + 1] = tmp.y; verts[i * 3 + 2] = tmp.z;\r\n            }\r\n            const indices = count > 65535 ? new Uint32Array(count) : new Uint16Array(count);\r\n            for (let i = 0; i < count; i++) indices[i] = i;\r\n\r\n            const body = world.createRigidBody(RAPIER.RigidBodyDesc.fixed());\r\n            world.createCollider(\r\n                RAPIER.ColliderDesc.trimesh(verts, indices).setRestitution(0).setFriction(0.8),\r\n                body,\r\n            );\r\n        };\r\n\r\n        for (const g of this.ctrl.collected) addTrimesh(this.RAPIER, this.world, g);\r\n\r\n        // 添加地面刚体\r\n        const groundBody = this.world.createRigidBody(this.RAPIER.RigidBodyDesc.fixed());\r\n        groundBody.userData = { outOfBounds: true };\r\n\r\n    }\r\n\r\n    // 加载车辆模型\r\n    async load(opts: VehicleOptions) {\r\n        try {\r\n            if (!this.ctrl.playerModelConfig.enterCarAnim) {\r\n                return console.warn(\"未配置上车动画，不执行车辆相关逻辑\");\r\n            }\r\n            await this.initRapier();\r\n            if (!this.world) return;\r\n\r\n            const instance = await loadVehicleModelUtil(opts, {\r\n                loader: this.ctrl.loader,\r\n                scene: this.ctrl.scene,\r\n                world: this.world,\r\n                RAPIER: this.RAPIER,\r\n                vehicleParams: this.params,\r\n                vehicleLength: this.maxCount,\r\n                playerScale: this.ctrl.playerModelConfig.scale,\r\n            });\r\n\r\n            this.list.push(instance);\r\n            this.ctrl.addDynamicCollider(instance.vehicleGroup);\r\n            this.setTransition();\r\n        } catch (e) {\r\n            console.error(\"加载车辆模型失败:\", e);\r\n        }\r\n    }\r\n\r\n    // 控制车门开关\r\n    openDoor(isOpen = true) {\r\n        const v = this.active;\r\n        if (!v?.vehicleActions) return;\r\n        const next = v.vehicleActions.get(\"openDoor\");\r\n        if (!next) return;\r\n\r\n        const duration = next.getClip().duration;\r\n        next.reset();\r\n        next.setEffectiveWeight(1);\r\n\r\n        // 正向播放开门，反向播放关门\r\n        if (isOpen) {\r\n            next.setEffectiveTimeScale(duration * 2);\r\n            next.time = 0;\r\n            v.vehiclIsOpenDoor = true;\r\n        } else {\r\n            next.setEffectiveTimeScale(-duration * 2);\r\n            next.time = duration;\r\n            v.vehiclIsOpenDoor = false;\r\n        }\r\n\r\n        next.setLoop(THREE.LoopOnce, 1);\r\n        next.clampWhenFinished = true;\r\n        next.play();\r\n    }\r\n\r\n    // 触发上车流程\r\n    enter() {\r\n        if (!this.list.length || this.isMovingToBoarding) return;\r\n\r\n        // 查找最近可上车的车辆\r\n        let nearest: VehicleInstance | null = null;\r\n        let nearestDist = Infinity;\r\n        let nearBoardingPoint: THREE.Vector3 | null = null;\r\n\r\n        for (const v of this.list) {\r\n            const boardingLocal = v.boardingPoint.clone().multiplyScalar(v.scale);\r\n            const boardingWorld = v.vehicleGroup.localToWorld(boardingLocal);\r\n            const dist = this.ctrl.playerCapsule.position.distanceTo(boardingWorld);\r\n            if (dist < 800 * this.ctrl.playerModelConfig.scale && dist < nearestDist) {\r\n                nearestDist = dist;\r\n                nearest = v;\r\n                nearBoardingPoint = boardingWorld;\r\n            }\r\n        }\r\n\r\n        if (!nearest || !nearBoardingPoint) return;\r\n        this.active = nearest;\r\n        const v = nearest;\r\n\r\n        // 车辆移动中不允许上车\r\n        const vel = v.chassisBody.linvel();\r\n        if (Math.sqrt(vel.x ** 2 + vel.z ** 2) > 0.1) return;\r\n\r\n        // 规划路径并开始移动\r\n        this.boardingPoint = nearBoardingPoint;\r\n        this.waypoints = v.pathPlanner.findPath(this.ctrl.playerCapsule.position.clone(), nearBoardingPoint);\r\n        this.waypointIdx = 0;\r\n        this.targetDir = new THREE.Vector3(0, 0, 1).applyQuaternion(v.vehicleGroup.quaternion).normalize();\r\n        this.isMovingToBoarding = true;\r\n        this.ctrl.animation.playByName(\"walking\");\r\n    }\r\n\r\n    // 自动走向上车点\r\n    updateMoveTo(delta: number) {\r\n        const c = this.ctrl;\r\n        if (!this.isMovingToBoarding || !this.targetDir || !this.waypoints.length) return;\r\n\r\n        // 所有路径点已走完，进入对齐阶段\r\n        if (this.waypointIdx >= this.waypoints.length) {\r\n            this.finalizeBoarding(delta);\r\n            return;\r\n        }\r\n\r\n        const waypoint = this.waypoints[this.waypointIdx];\r\n        const currentPos = c.playerCapsule.position.clone();\r\n        const isLast = this.waypointIdx === this.waypoints.length - 1;\r\n        const threshold = isLast ? 0 : 10 * c.playerModelConfig.scale;\r\n        const horizDist = new THREE.Vector2(waypoint.x - currentPos.x, waypoint.z - currentPos.z).length();\r\n\r\n        // 移动并旋转朝向路径点\r\n        if (horizDist > threshold) {\r\n            const moveDir = new THREE.Vector3(waypoint.x - currentPos.x, 0, waypoint.z - currentPos.z).normalize();\r\n            c.playerCapsule.position.add(moveDir.clone().multiplyScalar(Math.min(this.moveSpeed * c.playerModelConfig.scale * delta, horizDist)));\r\n            c.targetMat.lookAt(c.playerCapsule.position, c.playerCapsule.position.clone().add(moveDir), c.playerCapsule.up);\r\n            c.targetQuat.setFromRotationMatrix(c.targetMat).multiply(this.flip180);\r\n            c.playerCapsule.quaternion.slerp(c.targetQuat, Math.min(1, this.rotSpeed * delta));\r\n        } else {\r\n            this.waypointIdx++;\r\n        }\r\n    }\r\n\r\n    // 完成上车对齐\r\n    finalizeBoarding(delta: number) {\r\n        const c = this.ctrl;\r\n        const v = this.active;\r\n        if (!this.targetDir || !v || !this.isMovingToBoarding) return;\r\n\r\n        // 旋转至与车辆同向\r\n        const currentDir = new THREE.Vector3(0, 0, -1).applyQuaternion(c.playerCapsule.quaternion).normalize();\r\n        if (currentDir.angleTo(this.targetDir) > 0.01) {\r\n            const lookTarget = c.playerCapsule.position.clone().add(this.targetDir);\r\n            c.targetMat.lookAt(c.playerCapsule.position, lookTarget, c.playerCapsule.up);\r\n            c.targetQuat.setFromRotationMatrix(c.targetMat);\r\n            c.playerCapsule.quaternion.slerp(c.targetQuat, Math.min(1, this.rotSpeed * delta));\r\n        } else {\r\n            // 对齐完成，触发上车动画\r\n            this.waypoints = [];\r\n            this.waypointIdx = 0;\r\n            this.targetDir = null;\r\n            v.pathPlanner?.clearVisualization();\r\n\r\n            c.animation.playByName(\"enterCar\");\r\n            this.isBoardingAnim = true;\r\n            this.doorClosed = false;\r\n            if (!v.vehiclIsOpenDoor) this.openDoor();\r\n            c.playerCapsule.rotation.copy(v.vehicleGroup.rotation);\r\n            c.playerCapsule.quaternion.multiply(this.flip180);\r\n        }\r\n    }\r\n\r\n    // 上车动画结束\r\n    onEnterAnimFinished() {\r\n        const c = this.ctrl;\r\n        const v = this.active;\r\n        if (!v || !this.isMovingToBoarding) return;\r\n        c.playerCapsule.updateMatrixWorld(true);\r\n        const offsetY = this.boardingPoint!.y - c.playerCapsule.position.y;\r\n\r\n        // 挂载到车辆并设置座位偏移\r\n        c.controllerMode = 1;\r\n        c.mobileControls?.syncControllerModeBtn(1);\r\n        c.cam.setOverShoulder(false);\r\n        v.vehicleGroup.attach(c.playerCapsule);\r\n        c.playerCapsule.position.add(v.seatOffset.clone().multiplyScalar(v.scale).add(new THREE.Vector3(0, offsetY, 0)));\r\n        this.isMovingToBoarding = false;\r\n        c.syncDebugVisibility();\r\n        c.onVehicleEnter?.(v);\r\n    }\r\n\r\n    // 触发下车流程\r\n    exit() {\r\n        const c = this.ctrl;\r\n        const v = this.active;\r\n        if (!v) return;\r\n\r\n        this.isMovingToBoarding = false;\r\n        this.waypoints = [];\r\n        this.waypointIdx = 0;\r\n        this.targetDir = null;\r\n\r\n        // 静止才播放下车动画\r\n        const vel = v.chassisBody.linvel();\r\n        if (Math.sqrt(vel.x ** 2 + vel.z ** 2) < 0.1) {\r\n            c.animation.playByName(\"exitCar\");\r\n            this.isExitAnim = true;\r\n            this.exitDoorClosed = false;\r\n        } else {\r\n            c.animation.playByName(\"idle\");\r\n        }\r\n\r\n        this.openDoor(true);\r\n        c.controllerMode = 0;\r\n        c.mobileControls?.syncControllerModeBtn(0);\r\n        c.cam.setOverShoulder(c.enableOverShoulderView);\r\n        c.scene.attach(c.playerCapsule);\r\n        if (c.isFirstPerson) c.cam.setFirstPerson();\r\n        c.syncDebugVisibility();\r\n        this.setTransition();\r\n    }\r\n\r\n    // 取消上车流程\r\n    cancelBoarding() {\r\n        this.isMovingToBoarding = false;\r\n        this.waypoints = [];\r\n        this.waypointIdx = 0;\r\n        this.targetDir = null;\r\n    }\r\n\r\n    // 更新车辆驾驶\r\n    updateVehicle(delta: number) {\r\n        const c = this.ctrl;\r\n        const v = this.active;\r\n        if (!v || !this.world) return;\r\n        const { vehicleController, chassisBody, vehicleGroup } = v;\r\n\r\n        // 坡度补偿\r\n        const rotation = chassisBody.rotation();\r\n        const quat = new THREE.Quaternion(rotation.x, rotation.y, rotation.z, rotation.w);\r\n        const forward = new THREE.Vector3(1, 0, 0).applyQuaternion(quat);\r\n        const slopeAngle = Math.asin(forward.y);\r\n        const factor = (slopeAngle < -0.05 && c.input.fwd) ? -Math.sin(slopeAngle) * 10 : 1;\r\n\r\n        // 驱动力\r\n        const accelerateForce = this.params.power.accelerateForce * v.speedMultiplier;\r\n        const maxSpeed = this.params.power.maxSpeed * v.speedMultiplier;\r\n        const engineForce = (Number(c.input.fwd) - Number(c.input.bkd)) * accelerateForce * factor;\r\n        for (let i = 0; i < 4; i++) vehicleController.setWheelEngineForce(i, engineForce);\r\n\r\n        // 制动\r\n        const wheelBrake = Number(c.input.space) * this.params.power.brakeForce * delta;\r\n        for (let i = 0; i < 4; i++) vehicleController.setWheelBrake(i, wheelBrake);\r\n\r\n        // 转向\r\n        const currentSteering = vehicleController.wheelSteering(0) || 0;\r\n        const steerDir = Number(c.input.lft) - Number(c.input.rgt);\r\n        const steerSpeed = steerDir === 0 ? this.params.steering.steerReturnSpeed : this.params.steering.steerSpeed;\r\n        const steering = THREE.MathUtils.lerp(currentSteering, this.params.steering.maxSteerAngle * steerDir, 1 - Math.pow(1 - steerSpeed, delta));\r\n        vehicleController.setWheelSteering(0, steering);\r\n        vehicleController.setWheelSteering(1, steering);\r\n\r\n        // 漂移摩擦\r\n        const driftFriction = ((c.input.rgt || c.input.lft) && c.input.shift) ? 0.5 : 2;\r\n        vehicleController.setWheelSideFrictionStiffness(2, driftFriction);\r\n        vehicleController.setWheelSideFrictionStiffness(3, driftFriction);\r\n\r\n        this.updateInertia(delta);\r\n\r\n        // 相机跟随\r\n        if (!c.isFirstPerson) {\r\n            const lookTarget = vehicleGroup.position.clone();\r\n            c.camera.position.sub(c.controls.target);\r\n            c.controls.target.copy(lookTarget);\r\n            c.camera.position.add(lookTarget);\r\n            c.controls.update();\r\n\r\n            const velocity = chassisBody.linvel();\r\n            const currentSpeed = new THREE.Vector3(velocity.x, velocity.y, velocity.z).length();\r\n            const speedRatio = Math.min(currentSpeed / maxSpeed, 1);\r\n            const baseDist = v.size.l * 0.8;\r\n            const maxDist = v.size.l * 5;\r\n            const desiredDist = THREE.MathUtils.lerp(baseDist, maxDist, speedRatio);\r\n\r\n            c.cam.playerToCam.subVectors(c.camera.position, vehicleGroup.position);\r\n            const direction = c.cam.playerToCam.clone().normalize();\r\n            c.cam.raycaster.set(vehicleGroup.position, direction);\r\n            c.cam.raycaster.far = desiredDist;\r\n\r\n            const hits = c.cam.raycaster.intersectObject(c.collider!, false);\r\n            if (hits.length > 0) {\r\n                const safeDist = Math.max(hits[0].distance - c.cam.epsilon, baseDist);\r\n                c.camera.position.lerp(vehicleGroup.position.clone().add(direction.clone().multiplyScalar(safeDist)), c.cam.collisionLerp);\r\n            } else {\r\n                c.cam.raycaster.far = maxDist;\r\n                const maxHits = c.cam.raycaster.intersectObject(c.collider!, false);\r\n                const safeDist = maxHits.length > 0 ? Math.min(desiredDist, maxHits[0].distance - c.cam.epsilon) : desiredDist;\r\n                c.camera.position.lerp(vehicleGroup.position.clone().add(direction.clone().multiplyScalar(safeDist)), c.cam.collisionLerp);\r\n            }\r\n\r\n            if ((c.input.fwd || c.input.bkd) && this.params.followVehicleDirection) {\r\n                const vel = chassisBody.linvel();\r\n                const velVec = new THREE.Vector3(vel.x, vel.y, vel.z);\r\n                if (velVec.length() > 0.3) {\r\n                    this.camBehindDir.lerp(velVec.normalize().negate(), c.cam.collisionLerp).normalize();\r\n                    const targetCamPos = lookTarget.clone()\r\n                        .add(this.camBehindDir.clone().multiplyScalar(desiredDist))\r\n                        .add(new THREE.Vector3(0, v.size.h, 0));\r\n                    c.camera.position.lerp(targetCamPos, c.cam.collisionLerp);\r\n                    c.controls.update();\r\n                }\r\n            }\r\n        }\r\n\r\n        // 翻车自动复位\r\n        const vehicleUp = c.upVector.clone().applyQuaternion(vehicleGroup.quaternion);\r\n        if (vehicleUp.angleTo(c.upVector) > Math.PI / 2) {\r\n            const size = new THREE.Vector3();\r\n            v.vehicleBBox?.getSize(size);\r\n            const t = chassisBody.translation();\r\n            chassisBody.setTranslation(new this.RAPIER.Vector3(t.x, t.y + size.y, t.z), true);\r\n            chassisBody.setRotation(new this.RAPIER.Quaternion(0, 0, 0, 1), true);\r\n            chassisBody.setLinvel(new this.RAPIER.Vector3(0, 0, 0), true);\r\n            chassisBody.setAngvel(new this.RAPIER.Vector3(0, 0, 0), true);\r\n        }\r\n    }\r\n\r\n    // 步进物理世界\r\n    updateInertia(delta: number) {\r\n        if (!this.world) return;\r\n        this.world.timestep = delta;\r\n        this.world.step();\r\n\r\n        for (const v of this.list) {\r\n            const { vehicleController, chassisBody, vehicleGroup, updateWheelVisuals } = v;\r\n            vehicleController.updateVehicle(delta);\r\n            if (chassisBody.isSleeping()) continue;\r\n\r\n            // 限制最大速度\r\n            const vel = chassisBody.linvel();\r\n            const speed = new THREE.Vector3(vel.x, vel.y, vel.z).length();\r\n            const max = this.params.power.maxSpeed * v.speedMultiplier;\r\n            if (speed > max) {\r\n                const s = max / speed;\r\n                chassisBody.setLinvel(new this.RAPIER.Vector3(vel.x * s, vel.y * s, vel.z * s), true);\r\n            }\r\n\r\n            // 同步视觉位置\r\n            const t = chassisBody.translation();\r\n            const r = chassisBody.rotation();\r\n            vehicleGroup.position.set(t.x, t.y, t.z);\r\n            vehicleGroup.quaternion.set(r.x, r.y, r.z, r.w);\r\n            updateWheelVisuals?.();\r\n        }\r\n    }\r\n\r\n    // 等待车辆停稳后清除速度\r\n    setTransition() {\r\n        if (this.ctrl.isChangeControllerTransitionTimer) {\r\n            clearTimeout(this.ctrl.isChangeControllerTransitionTimer);\r\n            this.ctrl.isChangeControllerTransitionTimer = null;\r\n        }\r\n        this.ctrl.isChangeControllerTransitionTimer = setTimeout(() => {\r\n            this.ctrl.isChangeControllerTransitionTimer = null;\r\n            this.list.forEach(v => this.clearVelocity(v));\r\n        }, 3000);\r\n    }\r\n\r\n    // 清除车辆速度\r\n    private clearVelocity(v: VehicleInstance) {\r\n        if (!v || !this.world || !this.RAPIER) return;\r\n        const { chassisBody, vehicleController } = v;\r\n        const ZERO = new this.RAPIER.Vector3(0, 0, 0);\r\n        chassisBody.setLinvel(ZERO, true);\r\n        chassisBody.setAngvel(ZERO, true);\r\n        for (let i = 0; i < 4; i++) { vehicleController.setWheelEngineForce(i, 0); vehicleController.setWheelBrake(i, 1e6); }\r\n        vehicleController.updateVehicle(1 / 60);\r\n        this.world.timestep = 1 / 60;\r\n        this.world.step();\r\n        chassisBody.setLinvel(ZERO, true);\r\n        chassisBody.setAngvel(ZERO, true);\r\n        for (let i = 0; i < 4; i++) vehicleController.setWheelBrake(i, 0);\r\n    }\r\n}\r\n","import * as THREE from \"three\";\r\nimport type { GLTFLoader } from \"three/examples/jsm/loaders/GLTFLoader.js\";\r\nimport { PathPlanner, type ObstacleChecker } from \"./pathPlanner\";\r\nimport { createVehicleController } from \"./vehicleController\";\r\nimport type { VehicleOptions, VehicleInstance } from \"../types\";\r\n\r\nexport type VehicleLoaderContext = {\r\n    loader: GLTFLoader;\r\n    scene: THREE.Scene;\r\n    world: any;\r\n    RAPIER: any;\r\n    vehicleParams: {\r\n        debug: { showPhysicsBox: boolean };\r\n        chassis: { linearDamping: number; angularDamping: number };\r\n        model: { rotation: number };\r\n        power: { accelerateForce: number; brakeForce: number; maxSpeed: number };\r\n        steering: { maxSteerAngle: number; steerSpeed: number; steerReturnSpeed: number };\r\n        followVehicleDirection: boolean;\r\n    };\r\n    vehicleLength: number;\r\n    playerScale: number;\r\n};\r\n\r\n// ==================== 工具函数 ====================\r\n\r\n// 获取包围盒\r\nfunction getBbox(object: THREE.Object3D) {\r\n    const bbox = new THREE.Box3().setFromObject(object);\r\n    const center = new THREE.Vector3();\r\n    const size = new THREE.Vector3();\r\n    bbox.getCenter(center);\r\n    bbox.getSize(size);\r\n    return { bbox, center, size };\r\n}\r\n\r\n// 创建障碍物检测器\r\nfunction createObstacleChecker(\r\n    vehicleGroup: THREE.Group,\r\n    bbox: THREE.Box3,\r\n    scale: number,\r\n    playerScale: number,\r\n): ObstacleChecker {\r\n    return {\r\n        // 射线检测路径是否被车辆遮挡\r\n        isBlocked(start: THREE.Vector3, end: THREE.Vector3): boolean {\r\n            const vehiclePos = vehicleGroup.position;\r\n            const vehicleQuat = vehicleGroup.quaternion;\r\n            const center = new THREE.Vector3();\r\n            const size = new THREE.Vector3();\r\n            bbox.getCenter(center);\r\n            bbox.getSize(size);\r\n            center.applyQuaternion(vehicleQuat).add(vehiclePos);\r\n\r\n            // 构建旋转后的包围盒角点\r\n            const halfSize = size.clone().multiplyScalar(0.5 * scale);\r\n            const corners: THREE.Vector3[] = [];\r\n            for (let x = -1; x <= 1; x += 2)\r\n                for (let y = -1; y <= 1; y += 2)\r\n                    for (let z = -1; z <= 1; z += 2)\r\n                        corners.push(\r\n                            new THREE.Vector3(halfSize.x * x, halfSize.y * y, halfSize.z * z)\r\n                                .applyQuaternion(vehicleQuat)\r\n                                .add(center),\r\n                        );\r\n\r\n            // 扩展包围盒并做射线检测\r\n            const expandedBBox = new THREE.Box3();\r\n            corners.forEach(c => expandedBBox.expandByPoint(c));\r\n            expandedBBox.expandByScalar(100 * playerScale);\r\n\r\n            const direction = new THREE.Vector3().subVectors(end, start);\r\n            const length = direction.length();\r\n            const ray = new THREE.Ray(start, direction.normalize());\r\n            const intersects = ray.intersectBox(expandedBBox, new THREE.Vector3());\r\n            return intersects !== null && start.distanceTo(intersects) < length;\r\n        },\r\n\r\n        // 生成绕行导航节点\r\n        getNavigationNodes(start: THREE.Vector3, _goal: THREE.Vector3): THREE.Vector3[] {\r\n            const nodes = [] as THREE.Vector3[];\r\n            const vehiclePos = vehicleGroup.position;\r\n            const vehicleQuat = vehicleGroup.quaternion;\r\n            const bboxSize = new THREE.Vector3();\r\n            bbox.getSize(bboxSize);\r\n\r\n            const fwd = new THREE.Vector3(0, 0, 1).applyQuaternion(vehicleQuat);\r\n            const right = new THREE.Vector3(1, 0, 0).applyQuaternion(vehicleQuat);\r\n            const halfLen = (bboxSize.z / 2) * scale;\r\n            const halfWidth = (bboxSize.x / 2) * scale;\r\n            const groundY = start.y;\r\n\r\n            // 两个距离层级各生成四个角点\r\n            for (const margin of [300 * playerScale, 500 * playerScale]) {\r\n                nodes.push(vehiclePos.clone().add(fwd.clone().multiplyScalar(halfLen + margin)).add(right.clone().multiplyScalar(-halfWidth - margin)).setY(groundY));\r\n                nodes.push(vehiclePos.clone().add(fwd.clone().multiplyScalar(halfLen + margin)).add(right.clone().multiplyScalar(halfWidth + margin)).setY(groundY));\r\n                nodes.push(vehiclePos.clone().add(fwd.clone().multiplyScalar(-halfLen - margin)).add(right.clone().multiplyScalar(-halfWidth - margin)).setY(groundY));\r\n                nodes.push(vehiclePos.clone().add(fwd.clone().multiplyScalar(-halfLen - margin)).add(right.clone().multiplyScalar(halfWidth + margin)).setY(groundY));\r\n            }\r\n            return nodes;\r\n        },\r\n    };\r\n}\r\n\r\n// ==================== 主函数 ====================\r\n\r\n// 加载车辆模型\r\nexport async function loadVehicleModel(\r\n    opts: VehicleOptions,\r\n    ctx: VehicleLoaderContext,\r\n): Promise<VehicleInstance> {\r\n    const { loader, scene, world, RAPIER, vehicleParams, vehicleLength, playerScale } = ctx;\r\n\r\n    const scale = opts.scale ?? 1;\r\n    const chassisRatio = opts.chassisRatio ?? 0.2;\r\n    const suspensionRestLengthRatio = opts.suspensionRestLengthRatio ?? 0.2;\r\n    const speedMultiplier = opts.speedMultiplier ?? 1;\r\n\r\n    // 更新车辆物理参数\r\n    vehicleParams.power.accelerateForce = 50 * scale;\r\n    vehicleParams.power.brakeForce = 200 * scale;\r\n    vehicleParams.power.maxSpeed = 10000 * scale;\r\n    vehicleParams.followVehicleDirection = opts.followVehicleDirection ?? true;\r\n\r\n    const vehicleModel = await loader.loadAsync(opts.url);\r\n\r\n    // 计算模型缩放比\r\n    const { size: originalSize } = getBbox(vehicleModel.scene);\r\n    const modelScale = vehicleLength / Math.max(originalSize.x, originalSize.y, originalSize.z);\r\n\r\n    // 绑定开门动画\r\n    const vehicleMixer = new THREE.AnimationMixer(vehicleModel.scene);\r\n    const vehicleActions = new Map<string, THREE.AnimationAction>();\r\n    const animations = vehicleModel.animations ?? [];\r\n    const openDoorClip = animations.find(a => a.name === (opts.animations?.openDoorAnim ?? \"\"));\r\n    if (openDoorClip) {\r\n        const action = vehicleMixer.clipAction(openDoorClip);\r\n        action.setLoop(THREE.LoopOnce, 1);\r\n        action.clampWhenFinished = true;\r\n        action.setEffectiveTimeScale(openDoorClip.duration);\r\n        action.enabled = true;\r\n        action.setEffectiveWeight(0);\r\n        vehicleActions.set(\"openDoor\", action);\r\n    }\r\n\r\n    // 查找轮子节点\r\n    const wheelObjects: THREE.Object3D[] = [];\r\n    for (const name of opts.wheelsNames) {\r\n        let found = false;\r\n        vehicleModel.scene.traverse(child => {\r\n            if (child.name === name && !found) { wheelObjects.push(child); found = true; }\r\n        });\r\n        if (!found) console.warn(`未找到轮子: ${name}`);\r\n    }\r\n\r\n    // 临时挂载获取世界坐标\r\n    const tempGroup = new THREE.Group();\r\n    scene.add(tempGroup);\r\n    vehicleModel.scene.scale.multiplyScalar(modelScale * scale);\r\n    vehicleModel.scene.rotateY(vehicleParams.model.rotation);\r\n    const { size, bbox, center } = getBbox(vehicleModel.scene);\r\n    vehicleModel.scene.position.set(-center.x, -center.y, -center.z);\r\n    tempGroup.add(vehicleModel.scene);\r\n    tempGroup.updateMatrixWorld(true);\r\n\r\n    // 收集轮子世界变换信息\r\n    let wheelRadius = 0, wheelWidth = 0, suspensionRestLength = 0, chassisHeight = 0, wheelSizeInit = false;\r\n    const wheelsInfo: any[] = [];\r\n\r\n    for (const wheel of wheelObjects) {\r\n        const worldPos = new THREE.Vector3();\r\n        const worldQuat = new THREE.Quaternion();\r\n        const worldScale = new THREE.Vector3();\r\n        wheel.getWorldPosition(worldPos);\r\n        wheel.getWorldQuaternion(worldQuat);\r\n        wheel.getWorldScale(worldScale);\r\n\r\n        // 只计算一次轮子尺寸\r\n        if (!wheelSizeInit) {\r\n            const { size: ws } = getBbox(wheel);\r\n            wheelRadius = Number((Math.max(ws.x, ws.y, ws.z) / 2).toFixed(2));\r\n            wheelWidth = Number(Math.min(ws.x, ws.y, ws.z).toFixed(2));\r\n            suspensionRestLength = Number((wheelRadius * 2 * suspensionRestLengthRatio).toFixed(2));\r\n            chassisHeight = Number((wheelRadius * 2 * chassisRatio).toFixed(2));\r\n            wheelSizeInit = true;\r\n        }\r\n\r\n        wheelsInfo.push({ axleCs: new THREE.Vector3(0, 0, -1), position: worldPos, quaternion: worldQuat, scale: worldScale, radius: wheelRadius, width: wheelWidth, suspensionRestLength, object: wheel });\r\n    }\r\n\r\n    tempGroup.remove(vehicleModel.scene);\r\n    scene.remove(tempGroup);\r\n\r\n    // 创建车辆根节点\r\n    const vehicleGroup = new THREE.Group();\r\n    scene.add(vehicleGroup);\r\n    vehicleGroup.add(vehicleModel.scene);\r\n    vehicleGroup.updateMatrixWorld(true);\r\n\r\n    // 轮子包装组（独立旋转）\r\n    const wheelWrappers: THREE.Group[] = [];\r\n    for (let i = 0; i < wheelsInfo.length; i++) {\r\n        const wheel = wheelsInfo[i];\r\n        const wheelWrapper = new THREE.Group();\r\n        wheelWrapper.position.copy(vehicleGroup.worldToLocal(wheel.position.clone()));\r\n\r\n        const wheelObj = wheel.object;\r\n        wheelObj.parent?.remove(wheelObj);\r\n        wheelObj.position.set(0, 0, 0);\r\n        wheelObj.quaternion.copy(wheel.quaternion);\r\n        wheelObj.scale.copy(wheel.scale);\r\n        wheelObj.updateMatrixWorld();\r\n\r\n        wheelWrapper.add(wheelObj);\r\n        vehicleGroup.add(wheelWrapper);\r\n        wheelWrappers.push(wheelWrapper);\r\n    }\r\n\r\n    // 创建车身物理碰撞体\r\n    const halfExtents = size.clone().multiplyScalar(0.5);\r\n    halfExtents.y -= chassisHeight / 2;\r\n    vehicleModel.scene.position.y -= chassisHeight / 2;\r\n    halfExtents.x *= 0.95;\r\n    halfExtents.z *= 0.95;\r\n\r\n    const chassisBody = world.createRigidBody(\r\n        RAPIER.RigidBodyDesc.dynamic()\r\n            .setTranslation(opts.position.x, opts.position.y, opts.position.z)\r\n            .setLinearDamping(vehicleParams.chassis.linearDamping)\r\n            .setAngularDamping(vehicleParams.chassis.angularDamping)\r\n            .setCanSleep(true)\r\n            .setAdditionalMass(10),\r\n    );\r\n    world.createCollider(RAPIER.ColliderDesc.cuboid(halfExtents.x, halfExtents.y, halfExtents.z), chassisBody);\r\n\r\n    // 物理调试盒\r\n    const physicsBoxMesh = new THREE.Mesh(\r\n        new THREE.BoxGeometry(halfExtents.x * 2, halfExtents.y * 2, halfExtents.z * 2),\r\n        new THREE.MeshBasicMaterial({ color: 0xffffff, wireframe: true, transparent: true, opacity: 0.3 }),\r\n    );\r\n    if (vehicleParams.debug.showPhysicsBox) vehicleGroup.add(physicsBoxMesh);\r\n\r\n    vehicleGroup.position.copy(opts.position);\r\n    vehicleGroup.updateMatrixWorld(true);\r\n\r\n    const { vehicle, updateWheelVisuals } = createVehicleController(world, chassisBody, wheelWrappers, wheelsInfo);\r\n\r\n    return {\r\n        vehicleGroup,\r\n        chassisBody,\r\n        vehicleController: vehicle,\r\n        updateWheelVisuals,\r\n        vehicleMixer,\r\n        vehicleActions,\r\n        vehiclIsOpenDoor: false,\r\n        vehicleBBox: bbox.clone(),\r\n        pathPlanner: new PathPlanner(\r\n            createObstacleChecker(vehicleGroup, bbox, scale, playerScale),\r\n            { debugEnabled: false, scene, scale: playerScale },\r\n        ),\r\n        scale,\r\n        boardingPoint: opts.boardingPoint,\r\n        seatOffset: opts.seatOffset ?? new THREE.Vector3(),\r\n        enterVehicleTime: 1.5,\r\n        chassisRatio,\r\n        suspensionRestLengthRatio,\r\n        size: { l: Math.max(size.x, size.z), w: Math.min(size.x, size.z), h: size.y },\r\n        speedMultiplier,\r\n        physicsBoxMesh,\r\n    };\r\n}","import * as THREE from \"three\";\r\n\r\n// ==================== 路径节点 ====================\r\n\r\n// A* 路径节点\r\nclass PathNode {\r\n    position: THREE.Vector3;\r\n    g: number = Infinity; // 实际代价\r\n    h: number = 0;        // 估计代价\r\n    f: number = Infinity; // f = g + h\r\n    parent: PathNode | null = null;\r\n\r\n    constructor(position: THREE.Vector3) {\r\n        this.position = position.clone();\r\n    }\r\n\r\n    // 判断节点相等\r\n    equals(other: PathNode): boolean {\r\n        return this.position.distanceTo(other.position) < 0.01;\r\n    }\r\n}\r\n\r\n// ==================== 优先队列 ====================\r\n\r\n// A* 开放列表用优先队列\r\nclass PriorityQueue<T> {\r\n    elements: Array<{ priority: number; item: T }> = [];\r\n\r\n    // 入队并排序\r\n    enqueue(item: T, priority: number) {\r\n        this.elements.push({ priority, item });\r\n        this.elements.sort((a, b) => a.priority - b.priority);\r\n    }\r\n\r\n    // 出队最小优先级\r\n    dequeue(): T | undefined {\r\n        return this.elements.shift()?.item;\r\n    }\r\n\r\n    isEmpty(): boolean {\r\n        return this.elements.length === 0;\r\n    }\r\n\r\n    contains(item: T, compareFn: (a: T, b: T) => boolean): boolean {\r\n        return this.elements.some((e) => compareFn(e.item, item));\r\n    }\r\n\r\n    // 更新节点优先级\r\n    update(item: T, newPriority: number, compareFn: (a: T, b: T) => boolean) {\r\n        const index = this.elements.findIndex((e) => compareFn(e.item, item));\r\n        if (index !== -1) {\r\n            this.elements[index].priority = newPriority;\r\n            this.elements.sort((a, b) => a.priority - b.priority);\r\n        }\r\n    }\r\n}\r\n\r\n// ==================== 接口定义 ====================\r\n\r\n// 障碍物检测接口\r\nexport interface ObstacleChecker {\r\n    // 检查两点间是否被障碍物阻挡\r\n    isBlocked(start: THREE.Vector3, end: THREE.Vector3): boolean;\r\n    // 获取障碍物周围导航节点\r\n    getNavigationNodes(start: THREE.Vector3, goal: THREE.Vector3): THREE.Vector3[];\r\n}\r\n\r\n// 路径规划器配置\r\nexport interface PathPlannerConfig {\r\n    debugEnabled?: boolean; // 路径可视化开关\r\n    scene?: THREE.Scene; // 用于可视化的场景\r\n    scale?: number;      // 缩放系数\r\n}\r\n\r\n// ==================== 路径规划器 ====================\r\n\r\n// A* 路径规划器\r\nexport class PathPlanner {\r\n    obstacleChecker: ObstacleChecker;\r\n    config: PathPlannerConfig;\r\n    debugLines: THREE.Line[] = [];\r\n    debugPoints: THREE.Mesh[] = [];\r\n\r\n    constructor(obstacleChecker: ObstacleChecker, config: PathPlannerConfig = {}) {\r\n        this.obstacleChecker = obstacleChecker;\r\n        this.config = { debugEnabled: false, scale: 1, ...config };\r\n    }\r\n\r\n    // 启发式距离\r\n    private heuristic(a: THREE.Vector3, b: THREE.Vector3): number {\r\n        return a.distanceTo(b);\r\n    }\r\n\r\n    // A* 寻路主入口\r\n    findPath(start: THREE.Vector3, goal: THREE.Vector3): THREE.Vector3[] {\r\n        // 直线可达则直接返回\r\n        if (!this.obstacleChecker.isBlocked(start, goal)) return [goal];\r\n\r\n        // 生成候选导航节点\r\n        const navigationPoints = this.obstacleChecker.getNavigationNodes(start, goal);\r\n        const allNodes = [new PathNode(start), new PathNode(goal), ...navigationPoints.map((p) => new PathNode(p))];\r\n\r\n        if (allNodes.length < 2) {\r\n            console.warn(\"导航节点不足，返回直线路径\");\r\n            return [goal];\r\n        }\r\n\r\n        const startNode = allNodes[0];\r\n        const goalNode = allNodes[1];\r\n\r\n        // 初始化起点代价\r\n        startNode.g = 0;\r\n        startNode.h = this.heuristic(startNode.position, goalNode.position);\r\n        startNode.f = startNode.h;\r\n\r\n        const openList = new PriorityQueue<PathNode>();\r\n        const closedSet = new Set<PathNode>();\r\n        const nodeEquals = (a: PathNode, b: PathNode) => a.equals(b);\r\n        openList.enqueue(startNode, startNode.f);\r\n\r\n        // A* 主循环\r\n        while (!openList.isEmpty()) {\r\n            const current = openList.dequeue();\r\n            if (!current) break;\r\n\r\n            // 到达目标，重建路径\r\n            if (current.equals(goalNode)) {\r\n                const path = this.reconstructPath(current);\r\n                if (this.config.debugEnabled) this.visualizePath([start, ...path]);\r\n                return path;\r\n            }\r\n\r\n            closedSet.add(current);\r\n\r\n            // 遍历所有邻居节点\r\n            for (const neighbor of allNodes) {\r\n                if (closedSet.has(neighbor)) continue;\r\n                if (this.obstacleChecker.isBlocked(current.position, neighbor.position)) continue;\r\n\r\n                const tentativeG = current.g + current.position.distanceTo(neighbor.position);\r\n                if (tentativeG < neighbor.g) {\r\n                    neighbor.parent = current;\r\n                    neighbor.g = tentativeG;\r\n                    neighbor.h = this.heuristic(neighbor.position, goalNode.position);\r\n                    neighbor.f = neighbor.g + neighbor.h;\r\n\r\n                    if (openList.contains(neighbor, nodeEquals)) openList.update(neighbor, neighbor.f, nodeEquals);\r\n                    else openList.enqueue(neighbor, neighbor.f);\r\n                }\r\n            }\r\n        }\r\n\r\n        console.warn(\"A* 未找到路径，使用直线路径\");\r\n        return [goal];\r\n    }\r\n\r\n    // 重建路径\r\n    private reconstructPath(endNode: PathNode): THREE.Vector3[] {\r\n        const path: THREE.Vector3[] = [];\r\n        let current: PathNode | null = endNode;\r\n        while (current !== null) {\r\n            path.unshift(current.position.clone());\r\n            current = current.parent;\r\n        }\r\n        // 移除起点，再平滑\r\n        if (path.length > 0) path.shift();\r\n        return this.smoothPath(path);\r\n    }\r\n\r\n    // 路径平滑优化\r\n    private smoothPath(path: THREE.Vector3[]): THREE.Vector3[] {\r\n        if (path.length <= 2) return path;\r\n        const smoothed: THREE.Vector3[] = [path[0]];\r\n        let current = 0;\r\n        while (current < path.length - 1) {\r\n            // 尽量跳过中间节点\r\n            let farthest = current + 1;\r\n            for (let i = path.length - 1; i > current + 1; i--) {\r\n                if (!this.obstacleChecker.isBlocked(path[current], path[i])) { farthest = i; break; }\r\n            }\r\n            smoothed.push(path[farthest]);\r\n            current = farthest;\r\n        }\r\n        return smoothed;\r\n    }\r\n\r\n    // 可视化路径\r\n    private visualizePath(path: THREE.Vector3[]) {\r\n        if (!this.config.scene || !this.config.debugEnabled) return;\r\n        this.clearVisualization();\r\n        const scale = this.config.scale || 1;\r\n\r\n        // 绘制路径连线\r\n        if (path.length > 1) {\r\n            const geometry = new THREE.BufferGeometry().setFromPoints(path.map(p => p.clone()));\r\n            const line = new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: 0x00ff00, linewidth: 3 }));\r\n            this.config.scene.add(line);\r\n            this.debugLines.push(line);\r\n        }\r\n\r\n        // 绘制路径节点球体\r\n        path.forEach((point, index) => {\r\n            const sphere = new THREE.Mesh(\r\n                new THREE.SphereGeometry(20 * scale),\r\n                new THREE.MeshBasicMaterial({ color: index === path.length - 1 ? 0xff0000 : 0x00ff00 }),\r\n            );\r\n            sphere.position.copy(point);\r\n            this.config.scene!.add(sphere);\r\n            this.debugPoints.push(sphere);\r\n        });\r\n    }\r\n\r\n    // 清除路径可视化\r\n    clearVisualization() {\r\n        if (!this.config.scene) return;\r\n        this.debugLines.forEach(line => {\r\n            this.config.scene!.remove(line);\r\n            line.geometry.dispose();\r\n            (line.material as THREE.Material).dispose();\r\n        });\r\n        this.debugLines = [];\r\n        this.debugPoints.forEach(point => {\r\n            this.config.scene!.remove(point);\r\n            point.geometry.dispose();\r\n            (point.material as THREE.Material).dispose();\r\n        });\r\n        this.debugPoints = [];\r\n    }\r\n\r\n    // 更新配置\r\n    updateConfig(config: Partial<PathPlannerConfig>) {\r\n        this.config = { ...this.config, ...config };\r\n    }\r\n\r\n    // 销毁规划器\r\n    dispose() {\r\n        this.clearVisualization();\r\n    }\r\n}","import type { World } from \"@dimforge/rapier3d-compat\";\r\nimport * as THREE from \"three\";\r\n\r\nexport type WheelInfo = {\r\n    axleCs: THREE.Vector3;\r\n    suspensionRestLength: number;\r\n    position: THREE.Vector3;\r\n    radius: number;\r\n};\r\n\r\n// 创建车辆控制器\r\nexport function createVehicleController(\r\n    world: World,\r\n    chassisBody: any,\r\n    wheels: (THREE.Object3D | null)[],\r\n    wheelsInfo: WheelInfo[],\r\n) {\r\n    if (!world || !chassisBody) return { vehicle: null, updateWheelVisuals: () => {} };\r\n\r\n    const vehicle = world.createVehicleController(chassisBody);\r\n    const suspensionDirection = new THREE.Vector3(0, -1, 0);\r\n\r\n    // 注册每个轮子的物理参数\r\n    wheelsInfo.forEach((wheel, index) => {\r\n        vehicle.addWheel(wheel.position, suspensionDirection, wheel.axleCs, wheel.suspensionRestLength, wheel.radius);\r\n        vehicle.setWheelChassisConnectionPointCs(index, wheel.position); // 连接点\r\n        vehicle.setWheelDirectionCs(index, suspensionDirection); // 悬挂方向\r\n        vehicle.setWheelAxleCs(index, wheel.axleCs); // 轮轴方向\r\n        vehicle.setWheelSuspensionRestLength(index, wheel.suspensionRestLength); // 静止长度\r\n        vehicle.setWheelRadius(index, wheel.radius); // 轮胎半径\r\n        vehicle.setWheelMaxSuspensionTravel(index, wheel.suspensionRestLength); // 最大行程\r\n        vehicle.setWheelSuspensionStiffness(index, 250); // 悬挂刚度\r\n        vehicle.setWheelSuspensionCompression(index, 6); // 压缩阻尼\r\n        vehicle.setWheelSuspensionRelaxation(index, 6); // 回弹阻尼\r\n        vehicle.setWheelMaxSuspensionForce(index, 10000); // 最大作用力\r\n        vehicle.setWheelBrake(index, 0); // 制动\r\n        vehicle.setWheelSteering(index, 0); // 转向角\r\n        vehicle.setWheelEngineForce(index, 0); // 驱动力\r\n        vehicle.setWheelFrictionSlip(index, 20); // 纵向抓地\r\n        vehicle.setWheelSideFrictionStiffness(index, 2); // 侧向摩擦\r\n    });\r\n\r\n    const up = new THREE.Vector3(0, 1, 0);\r\n    const wheelSteeringQuat = new THREE.Quaternion();\r\n    const wheelRotationQuat = new THREE.Quaternion();\r\n\r\n    // 同步轮子视觉旋转\r\n    function updateWheelVisuals() {\r\n        for (const [index, wheelObj] of wheels.entries()) {\r\n            if (!wheelObj) continue;\r\n            try {\r\n                const wheelAxleCs = vehicle.wheelAxleCs(index) ?? new THREE.Vector3(1, 0, 0);\r\n                const connection = vehicle.wheelChassisConnectionPointCs(index)?.y ?? 0;\r\n                const suspension = vehicle.wheelSuspensionLength(index) ?? 0;\r\n                const steering = vehicle.wheelSteering(index) ?? 0;\r\n                const rotationRad = vehicle.wheelRotation(index) ?? 0;\r\n\r\n                // 悬挂压缩偏移\r\n                wheelObj.position.y = connection - suspension;\r\n                // 转向 * 自转\r\n                wheelSteeringQuat.setFromAxisAngle(up, steering);\r\n                wheelRotationQuat.setFromAxisAngle(wheelAxleCs, rotationRad);\r\n                wheelObj.quaternion.copy(wheelSteeringQuat).multiply(wheelRotationQuat);\r\n            } catch (e) {}\r\n        }\r\n    }\r\n\r\n    // 销毁车辆控制器\r\n    function destroy() {\r\n        try { world.removeVehicleController(vehicle); } catch { }\r\n    }\r\n\r\n    return { vehicle, updateWheelVisuals, destroy };\r\n}\r\n","import * as THREE from \"three\";\r\n\r\n// 胶囊碰撞所需的临时对象\r\nexport interface CollisionTemps {\r\n    invMat: THREE.Matrix4;    // 碰撞体世界矩阵的逆矩阵\r\n    localSeg: THREE.Line3;    // 胶囊段在碰撞体本地空间的副本\r\n    localBox: THREE.Box3;     // 胶囊段在碰撞体本地空间的包围盒\r\n    closestSeg: THREE.Vector3; // 胶囊段最近点\r\n    closestTri: THREE.Vector3; // 三角面最近点\r\n}\r\n\r\n// 创建一组预分配的临时对象\r\nexport function createCollisionTemps(): CollisionTemps {\r\n    return {\r\n        invMat: new THREE.Matrix4(),\r\n        localSeg: new THREE.Line3(),\r\n        localBox: new THREE.Box3(),\r\n        closestSeg: new THREE.Vector3(),\r\n        closestTri: new THREE.Vector3(),\r\n    };\r\n}\r\n\r\n/**\r\n * 将胶囊与单个网格做 BVH 碰撞检测\r\n * @param capsule       胶囊所在的 Object3D（位置会被直接修改）\r\n * @param capsuleInfo   胶囊描述：局部空间线段 + 半径\r\n * @param collider      目标碰撞网格\r\n * @param temps         预分配临时对象\r\n * @param skipTri       可选：返回 true 则跳过该三角面\r\n */\r\nexport function applyCapsuleCollision(\r\n    capsule: THREE.Object3D,\r\n    capsuleInfo: { segment: THREE.Line3; radius: number },\r\n    collider: THREE.Mesh,\r\n    temps: CollisionTemps,\r\n    skipTri?: (tri: any, dir: THREE.Vector3) => boolean,\r\n): void {\r\n    // 胶囊段变换到碰撞体本地空间\r\n    temps.invMat.copy(collider.matrixWorld).invert();\r\n    temps.localSeg.start.copy(capsuleInfo.segment.start).applyMatrix4(capsule.matrixWorld).applyMatrix4(temps.invMat);\r\n    temps.localSeg.end.copy(capsuleInfo.segment.end).applyMatrix4(capsule.matrixWorld).applyMatrix4(temps.invMat);\r\n\r\n    // 构建本地包围盒\r\n    temps.localBox.makeEmpty();\r\n    temps.localBox.expandByPoint(temps.localSeg.start).expandByPoint(temps.localSeg.end);\r\n    temps.localBox.expandByScalar(capsuleInfo.radius);\r\n\r\n    // 碰撞查询\r\n    (collider.geometry as any)?.boundsTree?.shapecast({\r\n        intersectsBounds: (box: THREE.Box3) => box.intersectsBox(temps.localBox),\r\n        intersectsTriangle: (tri: any) => {\r\n            // 初步筛选\r\n            const distance = tri.closestPointToSegment(temps.localSeg, temps.closestSeg, temps.closestTri);\r\n            if (distance >= capsuleInfo.radius) return;\r\n\r\n            // 二次筛选\r\n            const dir = temps.closestTri.clone().sub(temps.closestSeg).normalize();\r\n            if (skipTri?.(tri, dir)) return;\r\n\r\n            // 推开胶囊段\r\n            temps.localSeg.start.addScaledVector(dir, capsuleInfo.radius - distance);\r\n            temps.localSeg.end.addScaledVector(dir, capsuleInfo.radius - distance);\r\n        },\r\n    });\r\n\r\n    // 应用碰撞修正\r\n    const newPos = temps.closestSeg.copy(temps.localSeg.start).applyMatrix4(collider.matrixWorld);\r\n    const delta = temps.closestTri.subVectors(newPos, capsule.position);\r\n    const offset = Math.max(0, delta.length() - 1e-5);\r\n    capsule.position.add(delta.normalize().multiplyScalar(offset));\r\n}"],"mappings":"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","names":["THREE","action","fwd","bkd","lft","rgt","THREE","THREE","THREE","THREE","THREE","v","THREE","capsuleInfo"]}