three-player-controller 0.1.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,28 +1,29 @@
1
1
  # three-player-controller
2
2
 
3
- A lightweight third-person / first-person player controller, ready to use out of the box, based on three.js and three-mesh-bvh. It implements capsule-based character collision, BVH collision detection, character animations, first/third-person switching, and camera obstacle avoidance. This repository contains the library source code and example demos.
3
+ 轻量的第三人称 / 第一人称玩家控制器,开箱即用,基于 three.js three-mesh-bvh 实现人物胶囊体碰撞、BVH 碰撞检测、人物动画、第一/三人称切换与相机避障。此仓库包含库源码、example 演示。
4
4
 
5
- # Installation
5
+ # 安装
6
6
 
7
7
  npm install three-player-controller
8
8
 
9
- # Demo
9
+ # 示例
10
10
 
11
11
  [Player Controller](https://hh-hang.github.io/three-player-controller/)
12
12
 
13
- ### Controls
13
+ ### 控制
14
14
 
15
- ![Controls](https://github.com/hh-hang/three-player-controller/blob/master/example/public/gif/1.gif)
15
+ ![控制演示](https://github.com/hh-hang/three-player-controller/blob/master/example/public/gif/1.gif)
16
16
 
17
- ### fly
17
+ ### 飞行
18
18
 
19
- ![fly](https://github.com/hh-hang/three-player-controller/blob/master/example/public/gif/3.gif)
19
+ ![飞行](https://github.com/hh-hang/three-player-controller/blob/master/example/public/gif/3.gif)
20
20
 
21
- ### Third-person camera obstacle avoidance
21
+ ### 3DTiles 漫游
22
22
 
23
- ![Third-person camera obstacle avoidance](https://github.com/hh-hang/three-player-controller/blob/master/example/public/gif/2.gif)
23
+ ![3DTiles 漫游](https://github.com/hh-hang/three-player-controller/blob/master/example/public/gif/4.gif)
24
24
 
25
- # Usage
25
+
26
+ # 使用
26
27
 
27
28
  ```js
28
29
  import * as THREE from "three";
@@ -30,27 +31,27 @@ import { playerController } from "three-player-controller";
30
31
 
31
32
  const player = playerController();
32
33
 
33
- // Initialize the player controller
34
+ // 初始化玩家控制器
34
35
  player.init({
35
- scene, // three.js scene
36
- camera, // three.js camera
37
- controls, // three.js controls
36
+ scene, // three.js 场景
37
+ camera, // three.js 相机
38
+ controls, // three.js 控制器
38
39
  playerModel: {
39
- url: "./glb/person.glb", // model path
40
- scale: 0.001, // model scale
41
- idleAnim: "Idle_2", // idle animation name
42
- walkAnim: "Walking_11", // walk animation name
43
- runAnim: "Running_9", // run animation name
44
- jumpAnim: "Jump_3", // jump animation name
40
+ url: "./glb/person.glb", // 模型路径
41
+ scale: 0.001, // 模型缩放
42
+ idleAnim: "Idle_2", // 默认 Idle 动画名字
43
+ walkAnim: "Walking_11", // 默认 Walk 动画名字
44
+ runAnim: "Running_9", // 默认 Run 动画名字
45
+ jumpAnim: "Jump_3", // 默认 Jump 动画名字
45
46
  },
46
- initPos: pos, // initial position
47
+ initPos: pos, // 初始位置
47
48
  });
48
49
 
49
- // Call in the render loop
50
+ // 渲染循环调用
50
51
  player.update();
51
52
  ```
52
53
 
53
- # Thanks
54
+ # 感谢
54
55
 
55
56
  [three-mesh-bvh](https://github.com/gkjohnson/three-mesh-bvh)
56
57
 
package/dist/index.d.mts CHANGED
@@ -24,6 +24,8 @@ declare function playerController(): {
24
24
  };
25
25
  initPos?: THREE.Vector3;
26
26
  mouseSensity?: number;
27
+ minCamDistance?: number;
28
+ maxCamDistance?: number;
27
29
  }, callback?: () => void) => Promise<void>;
28
30
  changeView: () => void;
29
31
  createBVH: (url?: string) => Promise<void>;
package/dist/index.d.ts CHANGED
@@ -24,6 +24,8 @@ declare function playerController(): {
24
24
  };
25
25
  initPos?: THREE.Vector3;
26
26
  mouseSensity?: number;
27
+ minCamDistance?: number;
28
+ maxCamDistance?: number;
27
29
  }, callback?: () => void) => Promise<void>;
28
30
  changeView: () => void;
29
31
  createBVH: (url?: string) => Promise<void>;
package/dist/index.js CHANGED
@@ -42,6 +42,7 @@ var import_RoundedBoxGeometry = require("three/examples/jsm/geometries/RoundedBo
42
42
  var import_DRACOLoader = require("three/examples/jsm/loaders/DRACOLoader.js");
43
43
  var import_GLTFLoader = require("three/examples/jsm/loaders/GLTFLoader.js");
44
44
  var BufferGeometryUtils = __toESM(require("three/examples/jsm/utils/BufferGeometryUtils.js"));
45
+ THREE.Mesh.prototype.raycast = import_three_mesh_bvh.acceleratedRaycast;
45
46
  var controllerInstance = null;
46
47
  var clock = new THREE.Clock();
47
48
  var PlayerController = class {
@@ -81,6 +82,7 @@ var PlayerController = class {
81
82
  // 摄像机最小距离
82
83
  this._maxCamDistance = 4.4;
83
84
  // 摄像机最大距离
85
+ this.orginMaxCamDistance = 4.4;
84
86
  // 物理/运动
85
87
  this.playerVelocity = new THREE.Vector3();
86
88
  // 玩家速度向量
@@ -101,11 +103,17 @@ var PlayerController = class {
101
103
  this.DIR_BKD = new THREE.Vector3(0, 0, 1);
102
104
  this.DIR_LFT = new THREE.Vector3(-1, 0, 0);
103
105
  this.DIR_RGT = new THREE.Vector3(1, 0, 0);
104
- this.DIR_Y = new THREE.Vector3(0, 1, 0);
106
+ this.DIR_UP = new THREE.Vector3(0, 1, 0);
105
107
  this._personToCam = new THREE.Vector3();
106
108
  this._originTmp = new THREE.Vector3();
107
- this._raycaster = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3(0, -1, 0));
108
- this._raycasterPersonToCam = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3());
109
+ this._raycaster = new THREE.Raycaster(
110
+ new THREE.Vector3(),
111
+ new THREE.Vector3(0, -1, 0)
112
+ );
113
+ this._raycasterPersonToCam = new THREE.Raycaster(
114
+ new THREE.Vector3(),
115
+ new THREE.Vector3()
116
+ );
109
117
  // 键盘按下事件
110
118
  this._boundOnKeydown = async (e) => {
111
119
  if (e.ctrlKey && (e.code === "KeyW" || e.code === "KeyA" || e.code === "KeyS" || e.code === "KeyD")) {
@@ -133,8 +141,8 @@ var PlayerController = class {
133
141
  this.setAnimationByPressed();
134
142
  break;
135
143
  case "Space":
136
- if (!this.playerIsOnGround || this.isFlying) return;
137
144
  this.spacePressed = true;
145
+ if (!this.playerIsOnGround || this.isFlying) return;
138
146
  this.playPersonAnimationByName("jumping");
139
147
  this.playerVelocity.y = this.jumpHeight;
140
148
  this.playerIsOnGround = false;
@@ -175,6 +183,7 @@ var PlayerController = class {
175
183
  this.setAnimationByPressed();
176
184
  break;
177
185
  case "Space":
186
+ this.spacePressed = false;
178
187
  break;
179
188
  case "ControlLeft":
180
189
  this.ctPressed = false;
@@ -183,14 +192,14 @@ var PlayerController = class {
183
192
  };
184
193
  // 根据按键设置人物动画
185
194
  this.setAnimationByPressed = () => {
186
- this._maxCamDistance = 440 * this.playerModel.scale;
195
+ this._maxCamDistance = this.orginMaxCamDistance;
187
196
  if (this.isFlying) {
188
197
  if (!this.fwdPressed) {
189
198
  this.playPersonAnimationByName("flyidle");
190
199
  return;
191
200
  }
192
201
  this.playPersonAnimationByName("flying");
193
- this._maxCamDistance = 700 * this.playerModel.scale;
202
+ this._maxCamDistance = this.orginMaxCamDistance * 2;
194
203
  return;
195
204
  }
196
205
  if (this.playerIsOnGround) {
@@ -237,7 +246,11 @@ var PlayerController = class {
237
246
  const yaw = -e.movementX * 1e-4 * this.mouseSensity;
238
247
  const pitch = -e.movementY * 1e-4 * this.mouseSensity;
239
248
  this.player.rotateY(yaw);
240
- this.camera.rotation.x = THREE.MathUtils.clamp(this.camera.rotation.x + pitch, -1.3, 1.4);
249
+ this.camera.rotation.x = THREE.MathUtils.clamp(
250
+ this.camera.rotation.x + pitch,
251
+ -1.3,
252
+ 1.4
253
+ );
241
254
  } else {
242
255
  const sensitivity = 1e-4 * this.mouseSensity;
243
256
  const deltaX = -e.movementX * sensitivity;
@@ -253,12 +266,17 @@ var PlayerController = class {
253
266
  const newX = distance * Math.sin(phi) * Math.sin(theta);
254
267
  const newY = distance * Math.cos(phi);
255
268
  const newZ = distance * Math.sin(phi) * Math.cos(theta);
256
- this.camera.position.set(target.x + newX, target.y + newY, target.z + newZ);
269
+ this.camera.position.set(
270
+ target.x + newX,
271
+ target.y + newY,
272
+ target.z + newZ
273
+ );
257
274
  this.camera.lookAt(target);
258
275
  }
259
276
  };
260
277
  this._mouseClick = (e) => {
261
- if (document.pointerLockElement !== document.body) document.body.requestPointerLock();
278
+ if (document.pointerLockElement !== document.body)
279
+ document.body.requestPointerLock();
262
280
  };
263
281
  this._raycaster.firstHitOnly = true;
264
282
  this._raycasterPersonToCam.firstHitOnly = true;
@@ -278,8 +296,9 @@ var PlayerController = class {
278
296
  this.playerSpeed = opts.playerModel.speed ? opts.playerModel.speed * s : 400 * s;
279
297
  this._camCollisionLerp = 0.18;
280
298
  this._camEpsilon = 35 * s;
281
- this._minCamDistance = 100 * s;
282
- this._maxCamDistance = 440 * s;
299
+ this._minCamDistance = opts.minCamDistance ? opts.minCamDistance * s : 100 * s;
300
+ this._maxCamDistance = opts.maxCamDistance ? opts.maxCamDistance * s : 440 * s;
301
+ this.orginMaxCamDistance = this._maxCamDistance;
283
302
  await this.createBVH();
284
303
  this.createPlayer();
285
304
  await this.loadPersonGLB();
@@ -296,15 +315,25 @@ var PlayerController = class {
296
315
  this.isFirstPerson = !this.isFirstPerson;
297
316
  if (this.isFirstPerson) {
298
317
  this.player.attach(this.camera);
299
- this.camera.position.set(0, 40 * this.playerModel.scale, 30 * this.playerModel.scale);
318
+ this.camera.position.set(
319
+ 0,
320
+ 40 * this.playerModel.scale,
321
+ 30 * this.playerModel.scale
322
+ );
300
323
  this.camera.rotation.set(0, Math.PI, 0);
301
324
  document.body.requestPointerLock();
302
325
  } else {
303
326
  this.scene.attach(this.camera);
304
327
  const worldPos = this.player.position.clone();
305
- const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(this.player.quaternion);
328
+ const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(
329
+ this.player.quaternion
330
+ );
306
331
  const angle = Math.atan2(dir.z, dir.x);
307
- const offset = new THREE.Vector3(Math.cos(angle) * 400 * this.playerModel.scale, 200 * this.playerModel.scale, Math.sin(angle) * 400 * this.playerModel.scale);
332
+ const offset = new THREE.Vector3(
333
+ Math.cos(angle) * 400 * this.playerModel.scale,
334
+ 200 * this.playerModel.scale,
335
+ Math.sin(angle) * 400 * this.playerModel.scale
336
+ );
308
337
  this.camera.position.copy(worldPos).add(offset);
309
338
  this.controls.target.copy(worldPos);
310
339
  document.body.requestPointerLock();
@@ -313,12 +342,22 @@ var PlayerController = class {
313
342
  // 摄像机/控制器设置
314
343
  setCameraPos() {
315
344
  if (this.isFirstPerson) {
316
- this.camera.position.set(0, 40 * this.playerModel.scale, 30 * this.playerModel.scale);
345
+ this.camera.position.set(
346
+ 0,
347
+ 40 * this.playerModel.scale,
348
+ 30 * this.playerModel.scale
349
+ );
317
350
  } else {
318
351
  const worldPos = this.player.position.clone();
319
- const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(this.player.quaternion);
352
+ const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(
353
+ this.player.quaternion
354
+ );
320
355
  const angle = Math.atan2(dir.z, dir.x);
321
- const offset = new THREE.Vector3(Math.cos(angle) * 400 * this.playerModel.scale, 200 * this.playerModel.scale, Math.sin(angle) * 400 * this.playerModel.scale);
356
+ const offset = new THREE.Vector3(
357
+ Math.cos(angle) * 400 * this.playerModel.scale,
358
+ 200 * this.playerModel.scale,
359
+ Math.sin(angle) * 400 * this.playerModel.scale
360
+ );
322
361
  this.camera.position.copy(worldPos).add(offset);
323
362
  }
324
363
  this.camera.updateProjectionMatrix();
@@ -330,6 +369,7 @@ var PlayerController = class {
330
369
  }
331
370
  // 重置控制器
332
371
  resetControls() {
372
+ if (!this.controls) return;
333
373
  this.controls.enabled = true;
334
374
  this.controls.enablePan = true;
335
375
  this.controls.maxPolarAngle = Math.PI / 2;
@@ -344,7 +384,9 @@ var PlayerController = class {
344
384
  // 初始化加载器
345
385
  async initLoader() {
346
386
  const dracoLoader = new import_DRACOLoader.DRACOLoader();
347
- dracoLoader.setDecoderPath("https://unpkg.com/three@0.180.0/examples/jsm/libs/draco/gltf/");
387
+ dracoLoader.setDecoderPath(
388
+ "https://unpkg.com/three@0.180.0/examples/jsm/libs/draco/gltf/"
389
+ );
348
390
  dracoLoader.setDecoderConfig({ type: "js" });
349
391
  this.loader.setDRACOLoader(dracoLoader);
350
392
  }
@@ -360,21 +402,34 @@ var PlayerController = class {
360
402
  this.person.traverse((child) => {
361
403
  if (child.isMesh) {
362
404
  child.castShadow = true;
405
+ const mat = child.material;
406
+ if (!mat) return;
407
+ const mats = Array.isArray(mat) ? mat : [mat];
408
+ mats.forEach((m) => {
409
+ });
363
410
  }
364
411
  });
365
412
  this.player.add(this.person);
366
413
  this.reset();
367
414
  this.personMixer = new THREE.AnimationMixer(this.person);
368
415
  const animations = gltf.animations ?? [];
369
- console.log("animations", animations);
370
416
  this.personActions = /* @__PURE__ */ new Map();
371
417
  const findClip = (name) => animations.find((a) => a.name === name);
372
418
  const regs = [
373
419
  [this.playerModel.idleAnim, "idle"],
374
420
  [this.playerModel.walkAnim, "walking"],
375
- [this.playerModel.leftWalkAnim || this.playerModel.walkAnim, "left_walking"],
376
- [this.playerModel.rightWalkAnim || this.playerModel.walkAnim, "right_walking"],
377
- [this.playerModel.backwardAnim || this.playerModel.walkAnim, "walking_backward"],
421
+ [
422
+ this.playerModel.leftWalkAnim || this.playerModel.walkAnim,
423
+ "left_walking"
424
+ ],
425
+ [
426
+ this.playerModel.rightWalkAnim || this.playerModel.walkAnim,
427
+ "right_walking"
428
+ ],
429
+ [
430
+ this.playerModel.backwardAnim || this.playerModel.walkAnim,
431
+ "walking_backward"
432
+ ],
378
433
  [this.playerModel.jumpAnim, "jumping"],
379
434
  [this.playerModel.runAnim, "running"],
380
435
  [this.playerModel.flyIdleAnim || this.playerModel.idleAnim, "flyidle"],
@@ -463,20 +518,29 @@ var PlayerController = class {
463
518
  material.depthWrite = false;
464
519
  const r = this.playerRadius * this.playerModel.scale;
465
520
  const h = this.playerHeight * this.playerModel.scale;
466
- this.player = new THREE.Mesh(new import_RoundedBoxGeometry.RoundedBoxGeometry(r * 2, h, r * 2, 1, 75), material);
521
+ this.player = new THREE.Mesh(
522
+ new import_RoundedBoxGeometry.RoundedBoxGeometry(r * 2, h, r * 2, 1, 75),
523
+ material
524
+ );
467
525
  this.player.geometry.translate(0, -h * 0.25, 0);
468
526
  this.player.capsuleInfo = {
469
527
  radius: r,
470
- segment: new THREE.Line3(new THREE.Vector3(), new THREE.Vector3(0, -h * 0.5, 0))
528
+ segment: new THREE.Line3(
529
+ new THREE.Vector3(),
530
+ new THREE.Vector3(0, -h * 0.5, 0)
531
+ )
471
532
  };
472
533
  this.player.name = "capsule";
473
534
  this.scene.add(this.player);
474
535
  this.reset();
475
536
  }
537
+ // 获取法线与Y轴的夹角
476
538
  getAngleWithYAxis(normal) {
477
539
  const yAxis = { x: 0, y: 1, z: 0 };
478
540
  const dotProduct = normal.x * yAxis.x + normal.y * yAxis.y + normal.z * yAxis.z;
479
- const normalMagnitude = Math.sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z);
541
+ const normalMagnitude = Math.sqrt(
542
+ normal.x * normal.x + normal.y * normal.y + normal.z * normal.z
543
+ );
480
544
  const yAxisMagnitude = 1;
481
545
  const cosTheta = dotProduct / (normalMagnitude * yAxisMagnitude);
482
546
  return Math.acos(cosTheta);
@@ -484,8 +548,9 @@ var PlayerController = class {
484
548
  // 每帧更新
485
549
  async update(delta = clock.getDelta()) {
486
550
  if (!this.isupdate || !this.player || !this.collider) return;
487
- delta = Math.min(delta, 1 / 60);
488
- if (!this.isFlying) this.player.position.addScaledVector(this.playerVelocity, delta);
551
+ delta = Math.min(delta, 1 / 30);
552
+ if (!this.isFlying)
553
+ this.player.position.addScaledVector(this.playerVelocity, delta);
489
554
  this.updateMixers(delta);
490
555
  this.camera.getWorldDirection(this.camDir);
491
556
  let angle = Math.atan2(this.camDir.z, this.camDir.x) + Math.PI / 2;
@@ -495,8 +560,15 @@ var PlayerController = class {
495
560
  if (this.bkdPressed) this.moveDir.add(this.DIR_BKD);
496
561
  if (this.lftPressed) this.moveDir.add(this.DIR_LFT);
497
562
  if (this.rgtPressed) this.moveDir.add(this.DIR_RGT);
498
- if (this.isFlying && this.fwdPressed) {
499
- this.moveDir.y = this.camDir.y;
563
+ if (this.isFlying) {
564
+ if (this.fwdPressed) {
565
+ this.moveDir.y = this.camDir.y;
566
+ } else {
567
+ this.moveDir.y = 0;
568
+ }
569
+ if (this.spacePressed) {
570
+ this.moveDir.add(this.DIR_UP);
571
+ }
500
572
  }
501
573
  if (this.isFlying && this.fwdPressed) {
502
574
  this.playerSpeed = this.shiftPressed ? 4e3 * this.playerModel.scale : 3e3 * this.playerModel.scale;
@@ -504,11 +576,21 @@ var PlayerController = class {
504
576
  this.playerSpeed = this.shiftPressed ? 900 * this.playerModel.scale : 400 * this.playerModel.scale;
505
577
  }
506
578
  this.moveDir.normalize().applyAxisAngle(this.upVector, angle);
507
- this.player.position.addScaledVector(this.moveDir, this.playerSpeed * delta);
579
+ this.player.position.addScaledVector(
580
+ this.moveDir,
581
+ this.playerSpeed * delta
582
+ );
508
583
  let playerDistanceFromGround = Infinity;
509
- this._originTmp.set(this.player.position.x, this.player.position.y, this.player.position.z);
584
+ this._originTmp.set(
585
+ this.player.position.x,
586
+ this.player.position.y,
587
+ this.player.position.z
588
+ );
510
589
  this._raycaster.ray.origin.copy(this._originTmp);
511
- const intersects = this._raycaster.intersectObject(this.collider, false);
590
+ const intersects = this._raycaster.intersectObject(
591
+ this.collider,
592
+ false
593
+ );
512
594
  if (intersects.length > 0) {
513
595
  playerDistanceFromGround = this.player.position.y - intersects[0].point.y;
514
596
  const normal = intersects[0].normal;
@@ -536,7 +618,11 @@ var PlayerController = class {
536
618
  this.playerIsOnGround = true;
537
619
  } else if (playerDistanceFromGround < minH) {
538
620
  this.playerVelocity.set(0, 0, 0);
539
- this.player.position.set(this.player.position.x, intersects[0].point.y + h, this.player.position.z);
621
+ this.player.position.set(
622
+ this.player.position.x,
623
+ intersects[0].point.y + h,
624
+ this.player.position.z
625
+ );
540
626
  this.playerIsOnGround = true;
541
627
  }
542
628
  }
@@ -559,7 +645,11 @@ var PlayerController = class {
559
645
  intersectsTriangle: (tri) => {
560
646
  const triPoint = this.tempVector;
561
647
  const capsulePoint = this.tempVector2;
562
- const distance = tri.closestPointToSegment(this.tempSegment, triPoint, capsulePoint);
648
+ const distance = tri.closestPointToSegment(
649
+ this.tempSegment,
650
+ triPoint,
651
+ capsulePoint
652
+ );
563
653
  if (distance < capsuleInfo.radius) {
564
654
  const depth = capsuleInfo.radius - distance;
565
655
  const direction = capsulePoint.sub(triPoint).normalize();
@@ -569,11 +659,14 @@ var PlayerController = class {
569
659
  }
570
660
  });
571
661
  const newPosition = this.tempVector.copy(this.tempSegment.start).applyMatrix4(this.collider.matrixWorld);
572
- const deltaVector = this.tempVector2.subVectors(newPosition, this.player.position);
662
+ const deltaVector = this.tempVector2.subVectors(
663
+ newPosition,
664
+ this.player.position
665
+ );
573
666
  const offset = Math.max(0, deltaVector.length() - 1e-5);
574
667
  deltaVector.normalize().multiplyScalar(offset);
575
668
  this.player.position.add(deltaVector);
576
- if (!this.isFirstPerson && this.moveDir.lengthSq() > 0) {
669
+ if (!this.isFirstPerson && this.moveDir.lengthSq() > 0 && !this.isFlying) {
577
670
  this.camDir.y = 0;
578
671
  this.camDir.normalize();
579
672
  this.camDir.negate();
@@ -585,6 +678,18 @@ var PlayerController = class {
585
678
  const alpha = Math.min(1, this.rotationSpeed * delta);
586
679
  this.player.quaternion.slerp(this.targetQuat, alpha);
587
680
  }
681
+ if (this.isFlying) {
682
+ this.camDir.y = 0;
683
+ this.camDir.normalize();
684
+ this.camDir.negate();
685
+ this.moveDir.normalize();
686
+ this.moveDir.negate();
687
+ const lookTarget = this.player.position.clone().add(this.fwdPressed ? this.moveDir : this.camDir);
688
+ this.targetMat.lookAt(this.player.position, lookTarget, this.player.up);
689
+ this.targetQuat.setFromRotationMatrix(this.targetMat);
690
+ const alpha = Math.min(1, this.rotationSpeed * delta);
691
+ this.player.quaternion.slerp(this.targetQuat, alpha);
692
+ }
588
693
  if (!this.isFirstPerson) {
589
694
  const lookTarget = this.player.position.clone();
590
695
  lookTarget.y += 30 * this.playerModel.scale;
@@ -598,15 +703,24 @@ var PlayerController = class {
598
703
  const desiredDist = this._personToCam.length();
599
704
  this._raycasterPersonToCam.set(origin, direction);
600
705
  this._raycasterPersonToCam.far = desiredDist;
601
- const intersects2 = this._raycasterPersonToCam.intersectObject(this.collider, false);
706
+ const intersects2 = this._raycasterPersonToCam.intersectObject(
707
+ this.collider,
708
+ false
709
+ );
602
710
  if (intersects2.length > 0) {
603
711
  const hit = intersects2[0];
604
- const safeDist = Math.max(hit.distance - this._camEpsilon, this._minCamDistance);
712
+ const safeDist = Math.max(
713
+ hit.distance - this._camEpsilon,
714
+ this._minCamDistance
715
+ );
605
716
  const targetCamPos = origin.clone().add(direction.clone().multiplyScalar(safeDist));
606
717
  this.camera.position.lerp(targetCamPos, this._camCollisionLerp);
607
718
  } else {
608
719
  this._raycasterPersonToCam.far = this._maxCamDistance;
609
- const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(this.collider, false);
720
+ const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(
721
+ this.collider,
722
+ false
723
+ );
610
724
  let safeDist = this._maxCamDistance;
611
725
  if (intersectsMaxDis.length) {
612
726
  const hitMax = intersectsMaxDis[0];
@@ -617,15 +731,34 @@ var PlayerController = class {
617
731
  }
618
732
  }
619
733
  if (this.player.position.y < this.boundingBoxMinY - 1) {
620
- this._originTmp.set(this.player.position.x, 1e4, this.player.position.z);
734
+ this._originTmp.set(
735
+ this.player.position.x,
736
+ 1e4,
737
+ this.player.position.z
738
+ );
621
739
  this._raycaster.ray.origin.copy(this._originTmp);
622
- const intersects2 = this._raycaster.intersectObject(this.collider, false);
740
+ const intersects2 = this._raycaster.intersectObject(
741
+ this.collider,
742
+ false
743
+ );
623
744
  if (intersects2.length > 0) {
624
745
  console.log("\u73A9\u5BB6\u4E3Abug\u610F\u5916\u6389\u843D");
625
- this.reset(new THREE.Vector3(this.player.position.x, intersects2[0].point.y + 5, this.player.position.z));
746
+ this.reset(
747
+ new THREE.Vector3(
748
+ this.player.position.x,
749
+ intersects2[0].point.y + 5,
750
+ this.player.position.z
751
+ )
752
+ );
626
753
  } else {
627
754
  console.log("\u73A9\u5BB6\u6B63\u5E38\u6389\u843D");
628
- this.reset(new THREE.Vector3(this.player.position.x, this.player.position.y + 15, this.player.position.z));
755
+ this.reset(
756
+ new THREE.Vector3(
757
+ this.player.position.x,
758
+ this.player.position.y + 15,
759
+ this.player.position.z
760
+ )
761
+ );
629
762
  }
630
763
  }
631
764
  }
@@ -729,7 +862,8 @@ var PlayerController = class {
729
862
  attrMap.set(name, { itemSize, arrayCtor: ctor, examples: 1 });
730
863
  } else {
731
864
  const m = attrMap.get(name);
732
- if (m.itemSize !== itemSize || m.arrayCtor !== ctor) attrConflict.add(name);
865
+ if (m.itemSize !== itemSize || m.arrayCtor !== ctor)
866
+ attrConflict.add(name);
733
867
  else m.examples++;
734
868
  }
735
869
  }
@@ -750,7 +884,10 @@ var PlayerController = class {
750
884
  const meta = attrMap.get(name);
751
885
  const len = count * meta.itemSize;
752
886
  const array = new meta.arrayCtor(len);
753
- g.setAttribute(name, new THREE.BufferAttribute(array, meta.itemSize));
887
+ g.setAttribute(
888
+ name,
889
+ new THREE.BufferAttribute(array, meta.itemSize)
890
+ );
754
891
  }
755
892
  }
756
893
  }