three-player-controller 0.1.9 → 0.2.1

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/dist/index.mjs CHANGED
@@ -1,10 +1,11 @@
1
1
  // src/playerController.ts
2
2
  import * as THREE from "three";
3
- import { MeshBVH, MeshBVHHelper } from "three-mesh-bvh";
3
+ import { acceleratedRaycast, MeshBVH, MeshBVHHelper } from "three-mesh-bvh";
4
4
  import { RoundedBoxGeometry } from "three/examples/jsm/geometries/RoundedBoxGeometry.js";
5
5
  import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader.js";
6
6
  import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
7
7
  import * as BufferGeometryUtils from "three/examples/jsm/utils/BufferGeometryUtils.js";
8
+ THREE.Mesh.prototype.raycast = acceleratedRaycast;
8
9
  var controllerInstance = null;
9
10
  var clock = new THREE.Clock();
10
11
  var PlayerController = class {
@@ -68,8 +69,14 @@ var PlayerController = class {
68
69
  this.DIR_UP = new THREE.Vector3(0, 1, 0);
69
70
  this._personToCam = new THREE.Vector3();
70
71
  this._originTmp = new THREE.Vector3();
71
- this._raycaster = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3(0, -1, 0));
72
- this._raycasterPersonToCam = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3());
72
+ this._raycaster = new THREE.Raycaster(
73
+ new THREE.Vector3(),
74
+ new THREE.Vector3(0, -1, 0)
75
+ );
76
+ this._raycasterPersonToCam = new THREE.Raycaster(
77
+ new THREE.Vector3(),
78
+ new THREE.Vector3()
79
+ );
73
80
  // 键盘按下事件
74
81
  this._boundOnKeydown = async (e) => {
75
82
  if (e.ctrlKey && (e.code === "KeyW" || e.code === "KeyA" || e.code === "KeyS" || e.code === "KeyD")) {
@@ -111,12 +118,7 @@ var PlayerController = class {
111
118
  break;
112
119
  case "KeyF":
113
120
  this.isFlying = !this.isFlying;
114
- this._maxCamDistance = this.isFlying ? this.orginMaxCamDistance * 2 : this.orginMaxCamDistance;
115
- if (!this.isFlying && !this.playerIsOnGround) {
116
- this.playPersonAnimationByName("jumping");
117
- } else {
118
- this.setAnimationByPressed();
119
- }
121
+ this.setAnimationByPressed();
120
122
  break;
121
123
  }
122
124
  };
@@ -196,6 +198,8 @@ var PlayerController = class {
196
198
  this.playPersonAnimationByName("walking_backward");
197
199
  return;
198
200
  }
201
+ } else {
202
+ this.playPersonAnimationByName("jumping");
199
203
  }
200
204
  };
201
205
  // 鼠标移动事件
@@ -205,7 +209,11 @@ var PlayerController = class {
205
209
  const yaw = -e.movementX * 1e-4 * this.mouseSensity;
206
210
  const pitch = -e.movementY * 1e-4 * this.mouseSensity;
207
211
  this.player.rotateY(yaw);
208
- this.camera.rotation.x = THREE.MathUtils.clamp(this.camera.rotation.x + pitch, -1.3, 1.4);
212
+ this.camera.rotation.x = THREE.MathUtils.clamp(
213
+ this.camera.rotation.x + pitch,
214
+ -1.3,
215
+ 1.4
216
+ );
209
217
  } else {
210
218
  const sensitivity = 1e-4 * this.mouseSensity;
211
219
  const deltaX = -e.movementX * sensitivity;
@@ -221,12 +229,17 @@ var PlayerController = class {
221
229
  const newX = distance * Math.sin(phi) * Math.sin(theta);
222
230
  const newY = distance * Math.cos(phi);
223
231
  const newZ = distance * Math.sin(phi) * Math.cos(theta);
224
- this.camera.position.set(target.x + newX, target.y + newY, target.z + newZ);
232
+ this.camera.position.set(
233
+ target.x + newX,
234
+ target.y + newY,
235
+ target.z + newZ
236
+ );
225
237
  this.camera.lookAt(target);
226
238
  }
227
239
  };
228
240
  this._mouseClick = (e) => {
229
- if (document.pointerLockElement !== document.body) document.body.requestPointerLock();
241
+ if (document.pointerLockElement !== document.body)
242
+ document.body.requestPointerLock();
230
243
  };
231
244
  this._raycaster.firstHitOnly = true;
232
245
  this._raycasterPersonToCam.firstHitOnly = true;
@@ -235,6 +248,7 @@ var PlayerController = class {
235
248
  async init(opts, callback) {
236
249
  this.scene = opts.scene;
237
250
  this.camera = opts.camera;
251
+ this.camera.rotation.order = "YXZ";
238
252
  this.controls = opts.controls;
239
253
  this.playerModel = opts.playerModel;
240
254
  this.initPos = opts.initPos ? opts.initPos : new THREE.Vector3(0, 0, 0);
@@ -243,7 +257,8 @@ var PlayerController = class {
243
257
  this.visualizeDepth = 0 * s;
244
258
  this.gravity = opts.playerModel.gravity ? opts.playerModel.gravity * s : -2400 * s;
245
259
  this.jumpHeight = opts.playerModel.jumpHeight ? opts.playerModel.jumpHeight * s : 800 * s;
246
- this.playerSpeed = opts.playerModel.speed ? opts.playerModel.speed * s : 400 * s;
260
+ this.originPlayerSpeed = opts.playerModel.speed ? opts.playerModel.speed * s : 400 * s;
261
+ this.playerSpeed = this.originPlayerSpeed;
247
262
  this._camCollisionLerp = 0.18;
248
263
  this._camEpsilon = 35 * s;
249
264
  this._minCamDistance = opts.minCamDistance ? opts.minCamDistance * s : 100 * s;
@@ -265,15 +280,25 @@ var PlayerController = class {
265
280
  this.isFirstPerson = !this.isFirstPerson;
266
281
  if (this.isFirstPerson) {
267
282
  this.player.attach(this.camera);
268
- this.camera.position.set(0, 40 * this.playerModel.scale, 30 * this.playerModel.scale);
283
+ this.camera.position.set(
284
+ 0,
285
+ 40 * this.playerModel.scale,
286
+ 30 * this.playerModel.scale
287
+ );
269
288
  this.camera.rotation.set(0, Math.PI, 0);
270
289
  document.body.requestPointerLock();
271
290
  } else {
272
291
  this.scene.attach(this.camera);
273
292
  const worldPos = this.player.position.clone();
274
- const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(this.player.quaternion);
293
+ const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(
294
+ this.player.quaternion
295
+ );
275
296
  const angle = Math.atan2(dir.z, dir.x);
276
- const offset = new THREE.Vector3(Math.cos(angle) * 400 * this.playerModel.scale, 200 * this.playerModel.scale, Math.sin(angle) * 400 * this.playerModel.scale);
297
+ const offset = new THREE.Vector3(
298
+ Math.cos(angle) * 400 * this.playerModel.scale,
299
+ 200 * this.playerModel.scale,
300
+ Math.sin(angle) * 400 * this.playerModel.scale
301
+ );
277
302
  this.camera.position.copy(worldPos).add(offset);
278
303
  this.controls.target.copy(worldPos);
279
304
  document.body.requestPointerLock();
@@ -282,12 +307,22 @@ var PlayerController = class {
282
307
  // 摄像机/控制器设置
283
308
  setCameraPos() {
284
309
  if (this.isFirstPerson) {
285
- this.camera.position.set(0, 40 * this.playerModel.scale, 30 * this.playerModel.scale);
310
+ this.camera.position.set(
311
+ 0,
312
+ 40 * this.playerModel.scale,
313
+ 30 * this.playerModel.scale
314
+ );
286
315
  } else {
287
316
  const worldPos = this.player.position.clone();
288
- const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(this.player.quaternion);
317
+ const dir = new THREE.Vector3(0, 0, -1).applyQuaternion(
318
+ this.player.quaternion
319
+ );
289
320
  const angle = Math.atan2(dir.z, dir.x);
290
- const offset = new THREE.Vector3(Math.cos(angle) * 400 * this.playerModel.scale, 200 * this.playerModel.scale, Math.sin(angle) * 400 * this.playerModel.scale);
321
+ const offset = new THREE.Vector3(
322
+ Math.cos(angle) * 400 * this.playerModel.scale,
323
+ 200 * this.playerModel.scale,
324
+ Math.sin(angle) * 400 * this.playerModel.scale
325
+ );
291
326
  this.camera.position.copy(worldPos).add(offset);
292
327
  }
293
328
  this.camera.updateProjectionMatrix();
@@ -314,7 +349,9 @@ var PlayerController = class {
314
349
  // 初始化加载器
315
350
  async initLoader() {
316
351
  const dracoLoader = new DRACOLoader();
317
- dracoLoader.setDecoderPath("https://unpkg.com/three@0.180.0/examples/jsm/libs/draco/gltf/");
352
+ dracoLoader.setDecoderPath(
353
+ "https://unpkg.com/three@0.180.0/examples/jsm/libs/draco/gltf/"
354
+ );
318
355
  dracoLoader.setDecoderConfig({ type: "js" });
319
356
  this.loader.setDRACOLoader(dracoLoader);
320
357
  }
@@ -330,7 +367,11 @@ var PlayerController = class {
330
367
  this.person.traverse((child) => {
331
368
  if (child.isMesh) {
332
369
  child.castShadow = true;
333
- child.receiveShadow = true;
370
+ const mat = child.material;
371
+ if (!mat) return;
372
+ const mats = Array.isArray(mat) ? mat : [mat];
373
+ mats.forEach((m) => {
374
+ });
334
375
  }
335
376
  });
336
377
  this.player.add(this.person);
@@ -342,9 +383,18 @@ var PlayerController = class {
342
383
  const regs = [
343
384
  [this.playerModel.idleAnim, "idle"],
344
385
  [this.playerModel.walkAnim, "walking"],
345
- [this.playerModel.leftWalkAnim || this.playerModel.walkAnim, "left_walking"],
346
- [this.playerModel.rightWalkAnim || this.playerModel.walkAnim, "right_walking"],
347
- [this.playerModel.backwardAnim || this.playerModel.walkAnim, "walking_backward"],
386
+ [
387
+ this.playerModel.leftWalkAnim || this.playerModel.walkAnim,
388
+ "left_walking"
389
+ ],
390
+ [
391
+ this.playerModel.rightWalkAnim || this.playerModel.walkAnim,
392
+ "right_walking"
393
+ ],
394
+ [
395
+ this.playerModel.backwardAnim || this.playerModel.walkAnim,
396
+ "walking_backward"
397
+ ],
348
398
  [this.playerModel.jumpAnim, "jumping"],
349
399
  [this.playerModel.runAnim, "running"],
350
400
  [this.playerModel.flyIdleAnim || this.playerModel.idleAnim, "flyidle"],
@@ -433,11 +483,17 @@ var PlayerController = class {
433
483
  material.depthWrite = false;
434
484
  const r = this.playerRadius * this.playerModel.scale;
435
485
  const h = this.playerHeight * this.playerModel.scale;
436
- this.player = new THREE.Mesh(new RoundedBoxGeometry(r * 2, h, r * 2, 1, 75), material);
486
+ this.player = new THREE.Mesh(
487
+ new RoundedBoxGeometry(r * 2, h, r * 2, 1, 75),
488
+ material
489
+ );
437
490
  this.player.geometry.translate(0, -h * 0.25, 0);
438
491
  this.player.capsuleInfo = {
439
492
  radius: r,
440
- segment: new THREE.Line3(new THREE.Vector3(), new THREE.Vector3(0, -h * 0.5, 0))
493
+ segment: new THREE.Line3(
494
+ new THREE.Vector3(),
495
+ new THREE.Vector3(0, -h * 0.5, 0)
496
+ )
441
497
  };
442
498
  this.player.name = "capsule";
443
499
  this.scene.add(this.player);
@@ -447,7 +503,9 @@ var PlayerController = class {
447
503
  getAngleWithYAxis(normal) {
448
504
  const yAxis = { x: 0, y: 1, z: 0 };
449
505
  const dotProduct = normal.x * yAxis.x + normal.y * yAxis.y + normal.z * yAxis.z;
450
- const normalMagnitude = Math.sqrt(normal.x * normal.x + normal.y * normal.y + normal.z * normal.z);
506
+ const normalMagnitude = Math.sqrt(
507
+ normal.x * normal.x + normal.y * normal.y + normal.z * normal.z
508
+ );
451
509
  const yAxisMagnitude = 1;
452
510
  const cosTheta = dotProduct / (normalMagnitude * yAxisMagnitude);
453
511
  return Math.acos(cosTheta);
@@ -456,7 +514,8 @@ var PlayerController = class {
456
514
  async update(delta = clock.getDelta()) {
457
515
  if (!this.isupdate || !this.player || !this.collider) return;
458
516
  delta = Math.min(delta, 1 / 30);
459
- if (!this.isFlying) this.player.position.addScaledVector(this.playerVelocity, delta);
517
+ if (!this.isFlying)
518
+ this.player.position.addScaledVector(this.playerVelocity, delta);
460
519
  this.updateMixers(delta);
461
520
  this.camera.getWorldDirection(this.camDir);
462
521
  let angle = Math.atan2(this.camDir.z, this.camDir.x) + Math.PI / 2;
@@ -477,16 +536,26 @@ var PlayerController = class {
477
536
  }
478
537
  }
479
538
  if (this.isFlying && this.fwdPressed) {
480
- this.playerSpeed = this.shiftPressed ? 4e3 * this.playerModel.scale : 3e3 * this.playerModel.scale;
539
+ this.playerSpeed = this.shiftPressed ? this.originPlayerSpeed * 12 : this.originPlayerSpeed * 7;
481
540
  } else {
482
- this.playerSpeed = this.shiftPressed ? 900 * this.playerModel.scale : 400 * this.playerModel.scale;
541
+ this.playerSpeed = this.shiftPressed ? this.originPlayerSpeed * 2 : this.originPlayerSpeed;
483
542
  }
484
543
  this.moveDir.normalize().applyAxisAngle(this.upVector, angle);
485
- this.player.position.addScaledVector(this.moveDir, this.playerSpeed * delta);
544
+ this.player.position.addScaledVector(
545
+ this.moveDir,
546
+ this.playerSpeed * delta
547
+ );
486
548
  let playerDistanceFromGround = Infinity;
487
- this._originTmp.set(this.player.position.x, this.player.position.y, this.player.position.z);
549
+ this._originTmp.set(
550
+ this.player.position.x,
551
+ this.player.position.y,
552
+ this.player.position.z
553
+ );
488
554
  this._raycaster.ray.origin.copy(this._originTmp);
489
- const intersects = this._raycaster.intersectObject(this.collider, false);
555
+ const intersects = this._raycaster.intersectObject(
556
+ this.collider,
557
+ false
558
+ );
490
559
  if (intersects.length > 0) {
491
560
  playerDistanceFromGround = this.player.position.y - intersects[0].point.y;
492
561
  const normal = intersects[0].normal;
@@ -494,7 +563,6 @@ var PlayerController = class {
494
563
  const maxH = this.playerHeight * this.playerModel.scale * 0.9;
495
564
  const h = this.playerHeight * this.playerModel.scale * 0.75;
496
565
  const minH = this.playerHeight * this.playerModel.scale * 0.7;
497
- console.log(angle2, playerDistanceFromGround, maxH, h, minH);
498
566
  if (this.isFlying) {
499
567
  } else {
500
568
  if (playerDistanceFromGround > maxH) {
@@ -515,7 +583,11 @@ var PlayerController = class {
515
583
  this.playerIsOnGround = true;
516
584
  } else if (playerDistanceFromGround < minH) {
517
585
  this.playerVelocity.set(0, 0, 0);
518
- this.player.position.set(this.player.position.x, intersects[0].point.y + h, this.player.position.z);
586
+ this.player.position.set(
587
+ this.player.position.x,
588
+ intersects[0].point.y + h,
589
+ this.player.position.z
590
+ );
519
591
  this.playerIsOnGround = true;
520
592
  }
521
593
  }
@@ -538,7 +610,11 @@ var PlayerController = class {
538
610
  intersectsTriangle: (tri) => {
539
611
  const triPoint = this.tempVector;
540
612
  const capsulePoint = this.tempVector2;
541
- const distance = tri.closestPointToSegment(this.tempSegment, triPoint, capsulePoint);
613
+ const distance = tri.closestPointToSegment(
614
+ this.tempSegment,
615
+ triPoint,
616
+ capsulePoint
617
+ );
542
618
  if (distance < capsuleInfo.radius) {
543
619
  const depth = capsuleInfo.radius - distance;
544
620
  const direction = capsulePoint.sub(triPoint).normalize();
@@ -548,7 +624,10 @@ var PlayerController = class {
548
624
  }
549
625
  });
550
626
  const newPosition = this.tempVector.copy(this.tempSegment.start).applyMatrix4(this.collider.matrixWorld);
551
- const deltaVector = this.tempVector2.subVectors(newPosition, this.player.position);
627
+ const deltaVector = this.tempVector2.subVectors(
628
+ newPosition,
629
+ this.player.position
630
+ );
552
631
  const offset = Math.max(0, deltaVector.length() - 1e-5);
553
632
  deltaVector.normalize().multiplyScalar(offset);
554
633
  this.player.position.add(deltaVector);
@@ -589,15 +668,24 @@ var PlayerController = class {
589
668
  const desiredDist = this._personToCam.length();
590
669
  this._raycasterPersonToCam.set(origin, direction);
591
670
  this._raycasterPersonToCam.far = desiredDist;
592
- const intersects2 = this._raycasterPersonToCam.intersectObject(this.collider, false);
671
+ const intersects2 = this._raycasterPersonToCam.intersectObject(
672
+ this.collider,
673
+ false
674
+ );
593
675
  if (intersects2.length > 0) {
594
676
  const hit = intersects2[0];
595
- const safeDist = Math.max(hit.distance - this._camEpsilon, this._minCamDistance);
677
+ const safeDist = Math.max(
678
+ hit.distance - this._camEpsilon,
679
+ this._minCamDistance
680
+ );
596
681
  const targetCamPos = origin.clone().add(direction.clone().multiplyScalar(safeDist));
597
682
  this.camera.position.lerp(targetCamPos, this._camCollisionLerp);
598
683
  } else {
599
684
  this._raycasterPersonToCam.far = this._maxCamDistance;
600
- const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(this.collider, false);
685
+ const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(
686
+ this.collider,
687
+ false
688
+ );
601
689
  let safeDist = this._maxCamDistance;
602
690
  if (intersectsMaxDis.length) {
603
691
  const hitMax = intersectsMaxDis[0];
@@ -608,15 +696,34 @@ var PlayerController = class {
608
696
  }
609
697
  }
610
698
  if (this.player.position.y < this.boundingBoxMinY - 1) {
611
- this._originTmp.set(this.player.position.x, 1e4, this.player.position.z);
699
+ this._originTmp.set(
700
+ this.player.position.x,
701
+ 1e4,
702
+ this.player.position.z
703
+ );
612
704
  this._raycaster.ray.origin.copy(this._originTmp);
613
- const intersects2 = this._raycaster.intersectObject(this.collider, false);
705
+ const intersects2 = this._raycaster.intersectObject(
706
+ this.collider,
707
+ false
708
+ );
614
709
  if (intersects2.length > 0) {
615
710
  console.log("\u73A9\u5BB6\u4E3Abug\u610F\u5916\u6389\u843D");
616
- this.reset(new THREE.Vector3(this.player.position.x, intersects2[0].point.y + 5, this.player.position.z));
711
+ this.reset(
712
+ new THREE.Vector3(
713
+ this.player.position.x,
714
+ intersects2[0].point.y + 5,
715
+ this.player.position.z
716
+ )
717
+ );
617
718
  } else {
618
719
  console.log("\u73A9\u5BB6\u6B63\u5E38\u6389\u843D");
619
- this.reset(new THREE.Vector3(this.player.position.x, this.player.position.y + 15, this.player.position.z));
720
+ this.reset(
721
+ new THREE.Vector3(
722
+ this.player.position.x,
723
+ this.player.position.y + 15,
724
+ this.player.position.z
725
+ )
726
+ );
620
727
  }
621
728
  }
622
729
  }
@@ -720,7 +827,8 @@ var PlayerController = class {
720
827
  attrMap.set(name, { itemSize, arrayCtor: ctor, examples: 1 });
721
828
  } else {
722
829
  const m = attrMap.get(name);
723
- if (m.itemSize !== itemSize || m.arrayCtor !== ctor) attrConflict.add(name);
830
+ if (m.itemSize !== itemSize || m.arrayCtor !== ctor)
831
+ attrConflict.add(name);
724
832
  else m.examples++;
725
833
  }
726
834
  }
@@ -741,7 +849,10 @@ var PlayerController = class {
741
849
  const meta = attrMap.get(name);
742
850
  const len = count * meta.itemSize;
743
851
  const array = new meta.arrayCtor(len);
744
- g.setAttribute(name, new THREE.BufferAttribute(array, meta.itemSize));
852
+ g.setAttribute(
853
+ name,
854
+ new THREE.BufferAttribute(array, meta.itemSize)
855
+ );
745
856
  }
746
857
  }
747
858
  }
@@ -761,7 +872,9 @@ var PlayerController = class {
761
872
  console.error("\u5408\u5E76\u51E0\u4F55\u5931\u8D25");
762
873
  return;
763
874
  }
764
- merged.boundsTree = new MeshBVH(merged);
875
+ merged.boundsTree = new MeshBVH(merged, {
876
+ maxDepth: 100
877
+ });
765
878
  this.collider = new THREE.Mesh(
766
879
  merged,
767
880
  new THREE.MeshBasicMaterial({