three-player-controller 0.1.7 → 0.1.9
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 +28 -21
- package/dist/index.d.mts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +98 -76
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -76
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,50 +1,57 @@
|
|
|
1
1
|
# three-player-controller
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
轻量的第三人称 / 第一人称玩家控制器,开箱即用,基于 three.js 和 three-mesh-bvh 实现人物胶囊体碰撞、BVH 碰撞检测、人物动画、第一/三人称切换与相机避障。此仓库包含库源码、example 演示。
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# 安装
|
|
6
6
|
|
|
7
7
|
npm install three-player-controller
|
|
8
8
|
|
|
9
|
-
#
|
|
9
|
+
# 示例
|
|
10
10
|
|
|
11
11
|
[Player Controller](https://hh-hang.github.io/three-player-controller/)
|
|
12
12
|
|
|
13
|
-
###
|
|
13
|
+
### 控制
|
|
14
14
|
|
|
15
|
-

|
|
16
16
|
|
|
17
|
-
###
|
|
17
|
+
### 飞行
|
|
18
18
|
|
|
19
|
-

|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
### 3DTiles 漫游
|
|
22
|
+
|
|
23
|
+

|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# 使用
|
|
22
27
|
|
|
23
28
|
```js
|
|
24
29
|
import * as THREE from "three";
|
|
25
30
|
import { playerController } from "three-player-controller";
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
const player = playerController();
|
|
33
|
+
|
|
34
|
+
// 初始化玩家控制器
|
|
28
35
|
player.init({
|
|
29
|
-
scene, // three.js
|
|
30
|
-
camera, // three.js
|
|
31
|
-
controls, // three.js
|
|
36
|
+
scene, // three.js 场景
|
|
37
|
+
camera, // three.js 相机
|
|
38
|
+
controls, // three.js 控制器
|
|
32
39
|
playerModel: {
|
|
33
|
-
url: "./glb/person.glb", //
|
|
34
|
-
scale: 0.001, //
|
|
35
|
-
idleAnim: "Idle_2", //
|
|
36
|
-
walkAnim: "Walking_11", //
|
|
37
|
-
runAnim: "Running_9", //
|
|
38
|
-
jumpAnim: "Jump_3", //
|
|
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 动画名字
|
|
39
46
|
},
|
|
40
|
-
initPos: pos, //
|
|
47
|
+
initPos: pos, // 初始位置
|
|
41
48
|
});
|
|
42
49
|
|
|
43
|
-
//
|
|
50
|
+
// 渲染循环调用
|
|
44
51
|
player.update();
|
|
45
52
|
```
|
|
46
53
|
|
|
47
|
-
#
|
|
54
|
+
# 感谢
|
|
48
55
|
|
|
49
56
|
[three-mesh-bvh](https://github.com/gkjohnson/three-mesh-bvh)
|
|
50
57
|
|
package/dist/index.d.mts
CHANGED
|
@@ -15,14 +15,17 @@ declare function playerController(): {
|
|
|
15
15
|
leftWalkAnim?: string;
|
|
16
16
|
rightWalkAnim?: string;
|
|
17
17
|
backwardAnim?: string;
|
|
18
|
+
flyAnim?: string;
|
|
19
|
+
flyIdleAnim?: string;
|
|
18
20
|
scale: number;
|
|
19
21
|
gravity?: number;
|
|
20
22
|
jumpHeight?: number;
|
|
21
|
-
highJumpHeight?: number;
|
|
22
23
|
speed?: number;
|
|
23
24
|
};
|
|
24
25
|
initPos?: THREE.Vector3;
|
|
25
26
|
mouseSensity?: number;
|
|
27
|
+
minCamDistance?: number;
|
|
28
|
+
maxCamDistance?: number;
|
|
26
29
|
}, callback?: () => void) => Promise<void>;
|
|
27
30
|
changeView: () => void;
|
|
28
31
|
createBVH: (url?: string) => Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -15,14 +15,17 @@ declare function playerController(): {
|
|
|
15
15
|
leftWalkAnim?: string;
|
|
16
16
|
rightWalkAnim?: string;
|
|
17
17
|
backwardAnim?: string;
|
|
18
|
+
flyAnim?: string;
|
|
19
|
+
flyIdleAnim?: string;
|
|
18
20
|
scale: number;
|
|
19
21
|
gravity?: number;
|
|
20
22
|
jumpHeight?: number;
|
|
21
|
-
highJumpHeight?: number;
|
|
22
23
|
speed?: number;
|
|
23
24
|
};
|
|
24
25
|
initPos?: THREE.Vector3;
|
|
25
26
|
mouseSensity?: number;
|
|
27
|
+
minCamDistance?: number;
|
|
28
|
+
maxCamDistance?: number;
|
|
26
29
|
}, callback?: () => void) => Promise<void>;
|
|
27
30
|
changeView: () => void;
|
|
28
31
|
createBVH: (url?: string) => Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -63,6 +63,7 @@ var PlayerController = class {
|
|
|
63
63
|
// 状态开关
|
|
64
64
|
this.playerIsOnGround = false;
|
|
65
65
|
this.isupdate = true;
|
|
66
|
+
this.isFlying = false;
|
|
66
67
|
// 输入状态
|
|
67
68
|
this.fwdPressed = false;
|
|
68
69
|
this.bkdPressed = false;
|
|
@@ -71,8 +72,6 @@ var PlayerController = class {
|
|
|
71
72
|
this.spacePressed = false;
|
|
72
73
|
this.ctPressed = false;
|
|
73
74
|
this.shiftPressed = false;
|
|
74
|
-
this.sustainSpacePressed = false;
|
|
75
|
-
this.spaceLongPressTimer = null;
|
|
76
75
|
// 第三人称
|
|
77
76
|
this._camCollisionLerp = 0.18;
|
|
78
77
|
// 平滑系数
|
|
@@ -82,6 +81,7 @@ var PlayerController = class {
|
|
|
82
81
|
// 摄像机最小距离
|
|
83
82
|
this._maxCamDistance = 4.4;
|
|
84
83
|
// 摄像机最大距离
|
|
84
|
+
this.orginMaxCamDistance = 4.4;
|
|
85
85
|
// 物理/运动
|
|
86
86
|
this.playerVelocity = new THREE.Vector3();
|
|
87
87
|
// 玩家速度向量
|
|
@@ -102,6 +102,7 @@ var PlayerController = class {
|
|
|
102
102
|
this.DIR_BKD = new THREE.Vector3(0, 0, 1);
|
|
103
103
|
this.DIR_LFT = new THREE.Vector3(-1, 0, 0);
|
|
104
104
|
this.DIR_RGT = new THREE.Vector3(1, 0, 0);
|
|
105
|
+
this.DIR_UP = new THREE.Vector3(0, 1, 0);
|
|
105
106
|
this._personToCam = new THREE.Vector3();
|
|
106
107
|
this._originTmp = new THREE.Vector3();
|
|
107
108
|
this._raycaster = new THREE.Raycaster(new THREE.Vector3(), new THREE.Vector3(0, -1, 0));
|
|
@@ -133,12 +134,11 @@ var PlayerController = class {
|
|
|
133
134
|
this.setAnimationByPressed();
|
|
134
135
|
break;
|
|
135
136
|
case "Space":
|
|
136
|
-
|
|
137
|
-
if (!this.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
137
|
+
this.spacePressed = true;
|
|
138
|
+
if (!this.playerIsOnGround || this.isFlying) return;
|
|
139
|
+
this.playPersonAnimationByName("jumping");
|
|
140
|
+
this.playerVelocity.y = this.jumpHeight;
|
|
141
|
+
this.playerIsOnGround = false;
|
|
142
142
|
break;
|
|
143
143
|
case "ControlLeft":
|
|
144
144
|
this.ctPressed = true;
|
|
@@ -146,6 +146,15 @@ var PlayerController = class {
|
|
|
146
146
|
case "KeyV":
|
|
147
147
|
this.changeView();
|
|
148
148
|
break;
|
|
149
|
+
case "KeyF":
|
|
150
|
+
this.isFlying = !this.isFlying;
|
|
151
|
+
this._maxCamDistance = this.isFlying ? this.orginMaxCamDistance * 2 : this.orginMaxCamDistance;
|
|
152
|
+
if (!this.isFlying && !this.playerIsOnGround) {
|
|
153
|
+
this.playPersonAnimationByName("jumping");
|
|
154
|
+
} else {
|
|
155
|
+
this.setAnimationByPressed();
|
|
156
|
+
}
|
|
157
|
+
break;
|
|
149
158
|
}
|
|
150
159
|
};
|
|
151
160
|
// 键盘抬起事件
|
|
@@ -172,12 +181,7 @@ var PlayerController = class {
|
|
|
172
181
|
this.setAnimationByPressed();
|
|
173
182
|
break;
|
|
174
183
|
case "Space":
|
|
175
|
-
if (this.spaceLongPressTimer) {
|
|
176
|
-
clearTimeout(this.spaceLongPressTimer);
|
|
177
|
-
this.spaceLongPressTimer = null;
|
|
178
|
-
}
|
|
179
184
|
this.spacePressed = false;
|
|
180
|
-
this.sustainSpacePressed = false;
|
|
181
185
|
break;
|
|
182
186
|
case "ControlLeft":
|
|
183
187
|
this.ctPressed = false;
|
|
@@ -186,6 +190,16 @@ var PlayerController = class {
|
|
|
186
190
|
};
|
|
187
191
|
// 根据按键设置人物动画
|
|
188
192
|
this.setAnimationByPressed = () => {
|
|
193
|
+
this._maxCamDistance = this.orginMaxCamDistance;
|
|
194
|
+
if (this.isFlying) {
|
|
195
|
+
if (!this.fwdPressed) {
|
|
196
|
+
this.playPersonAnimationByName("flyidle");
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
this.playPersonAnimationByName("flying");
|
|
200
|
+
this._maxCamDistance = this.orginMaxCamDistance * 2;
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
189
203
|
if (this.playerIsOnGround) {
|
|
190
204
|
if (!this.fwdPressed && !this.bkdPressed && !this.lftPressed && !this.rgtPressed) {
|
|
191
205
|
this.playPersonAnimationByName("idle");
|
|
@@ -265,13 +279,13 @@ var PlayerController = class {
|
|
|
265
279
|
const s = this.playerModel.scale;
|
|
266
280
|
this.visualizeDepth = 0 * s;
|
|
267
281
|
this.gravity = opts.playerModel.gravity ? opts.playerModel.gravity * s : -2400 * s;
|
|
268
|
-
this.jumpHeight = opts.playerModel.jumpHeight ? opts.playerModel.jumpHeight * s :
|
|
269
|
-
this.highJumpHeight = opts.playerModel.highJumpHeight ? opts.playerModel.highJumpHeight * s : 1e3 * s;
|
|
282
|
+
this.jumpHeight = opts.playerModel.jumpHeight ? opts.playerModel.jumpHeight * s : 800 * s;
|
|
270
283
|
this.playerSpeed = opts.playerModel.speed ? opts.playerModel.speed * s : 400 * s;
|
|
271
284
|
this._camCollisionLerp = 0.18;
|
|
272
285
|
this._camEpsilon = 35 * s;
|
|
273
|
-
this._minCamDistance = 100 * s;
|
|
274
|
-
this._maxCamDistance = 440 * s;
|
|
286
|
+
this._minCamDistance = opts.minCamDistance ? opts.minCamDistance * s : 100 * s;
|
|
287
|
+
this._maxCamDistance = opts.maxCamDistance ? opts.maxCamDistance * s : 440 * s;
|
|
288
|
+
this.orginMaxCamDistance = this._maxCamDistance;
|
|
275
289
|
await this.createBVH();
|
|
276
290
|
this.createPlayer();
|
|
277
291
|
await this.loadPersonGLB();
|
|
@@ -318,10 +332,11 @@ var PlayerController = class {
|
|
|
318
332
|
// 设置控制器
|
|
319
333
|
setControls() {
|
|
320
334
|
this.controls.enabled = false;
|
|
321
|
-
this.controls.maxPolarAngle = Math.PI * (
|
|
335
|
+
this.controls.maxPolarAngle = Math.PI * (300 / 360);
|
|
322
336
|
}
|
|
323
337
|
// 重置控制器
|
|
324
338
|
resetControls() {
|
|
339
|
+
if (!this.controls) return;
|
|
325
340
|
this.controls.enabled = true;
|
|
326
341
|
this.controls.enablePan = true;
|
|
327
342
|
this.controls.maxPolarAngle = Math.PI / 2;
|
|
@@ -352,6 +367,7 @@ var PlayerController = class {
|
|
|
352
367
|
this.person.traverse((child) => {
|
|
353
368
|
if (child.isMesh) {
|
|
354
369
|
child.castShadow = true;
|
|
370
|
+
child.receiveShadow = true;
|
|
355
371
|
}
|
|
356
372
|
});
|
|
357
373
|
this.player.add(this.person);
|
|
@@ -367,7 +383,9 @@ var PlayerController = class {
|
|
|
367
383
|
[this.playerModel.rightWalkAnim || this.playerModel.walkAnim, "right_walking"],
|
|
368
384
|
[this.playerModel.backwardAnim || this.playerModel.walkAnim, "walking_backward"],
|
|
369
385
|
[this.playerModel.jumpAnim, "jumping"],
|
|
370
|
-
[this.playerModel.runAnim, "running"]
|
|
386
|
+
[this.playerModel.runAnim, "running"],
|
|
387
|
+
[this.playerModel.flyIdleAnim || this.playerModel.idleAnim, "flyidle"],
|
|
388
|
+
[this.playerModel.flyAnim || this.playerModel.idleAnim, "flying"]
|
|
371
389
|
];
|
|
372
390
|
for (const [key, clipName] of regs) {
|
|
373
391
|
const clip = findClip(key);
|
|
@@ -393,6 +411,8 @@ var PlayerController = class {
|
|
|
393
411
|
this.backwardAction = this.personActions.get("walking_backward");
|
|
394
412
|
this.jumpAction = this.personActions.get("jumping");
|
|
395
413
|
this.runAction = this.personActions.get("running");
|
|
414
|
+
this.flyidleAction = this.personActions.get("flyidle");
|
|
415
|
+
this.flyAction = this.personActions.get("flying");
|
|
396
416
|
this.idleAction.setEffectiveWeight(1);
|
|
397
417
|
this.idleAction.play();
|
|
398
418
|
this.actionState = this.idleAction;
|
|
@@ -460,6 +480,7 @@ var PlayerController = class {
|
|
|
460
480
|
this.scene.add(this.player);
|
|
461
481
|
this.reset();
|
|
462
482
|
}
|
|
483
|
+
// 获取法线与Y轴的夹角
|
|
463
484
|
getAngleWithYAxis(normal) {
|
|
464
485
|
const yAxis = { x: 0, y: 1, z: 0 };
|
|
465
486
|
const dotProduct = normal.x * yAxis.x + normal.y * yAxis.y + normal.z * yAxis.z;
|
|
@@ -470,10 +491,10 @@ var PlayerController = class {
|
|
|
470
491
|
}
|
|
471
492
|
// 每帧更新
|
|
472
493
|
async update(delta = clock.getDelta()) {
|
|
473
|
-
if (!this.isupdate || !this.player) return;
|
|
494
|
+
if (!this.isupdate || !this.player || !this.collider) return;
|
|
474
495
|
delta = Math.min(delta, 1 / 30);
|
|
496
|
+
if (!this.isFlying) this.player.position.addScaledVector(this.playerVelocity, delta);
|
|
475
497
|
this.updateMixers(delta);
|
|
476
|
-
if (!this.collider) return;
|
|
477
498
|
this.camera.getWorldDirection(this.camDir);
|
|
478
499
|
let angle = Math.atan2(this.camDir.z, this.camDir.x) + Math.PI / 2;
|
|
479
500
|
angle = 2 * Math.PI - angle;
|
|
@@ -482,31 +503,23 @@ var PlayerController = class {
|
|
|
482
503
|
if (this.bkdPressed) this.moveDir.add(this.DIR_BKD);
|
|
483
504
|
if (this.lftPressed) this.moveDir.add(this.DIR_LFT);
|
|
484
505
|
if (this.rgtPressed) this.moveDir.add(this.DIR_RGT);
|
|
485
|
-
if (this.
|
|
486
|
-
this.
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
this.
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
this.
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
if (this.sustainSpacePressed && this.playerIsOnGround) {
|
|
496
|
-
this.playPersonAnimationByName("jumping");
|
|
497
|
-
setTimeout(() => {
|
|
498
|
-
this.playerVelocity.y = this.highJumpHeight;
|
|
499
|
-
this.playerIsOnGround = false;
|
|
500
|
-
this.spacePressed = false;
|
|
501
|
-
this.player.position.addScaledVector(this.playerVelocity, delta);
|
|
502
|
-
this.player.updateMatrixWorld();
|
|
503
|
-
}, 200);
|
|
506
|
+
if (this.isFlying) {
|
|
507
|
+
if (this.fwdPressed) {
|
|
508
|
+
this.moveDir.y = this.camDir.y;
|
|
509
|
+
} else {
|
|
510
|
+
this.moveDir.y = 0;
|
|
511
|
+
}
|
|
512
|
+
if (this.spacePressed) {
|
|
513
|
+
this.moveDir.add(this.DIR_UP);
|
|
514
|
+
}
|
|
504
515
|
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
this.
|
|
516
|
+
if (this.isFlying && this.fwdPressed) {
|
|
517
|
+
this.playerSpeed = this.shiftPressed ? 4e3 * this.playerModel.scale : 3e3 * this.playerModel.scale;
|
|
518
|
+
} else {
|
|
519
|
+
this.playerSpeed = this.shiftPressed ? 900 * this.playerModel.scale : 400 * this.playerModel.scale;
|
|
509
520
|
}
|
|
521
|
+
this.moveDir.normalize().applyAxisAngle(this.upVector, angle);
|
|
522
|
+
this.player.position.addScaledVector(this.moveDir, this.playerSpeed * delta);
|
|
510
523
|
let playerDistanceFromGround = Infinity;
|
|
511
524
|
this._originTmp.set(this.player.position.x, this.player.position.y, this.player.position.z);
|
|
512
525
|
this._raycaster.ray.origin.copy(this._originTmp);
|
|
@@ -518,26 +531,30 @@ var PlayerController = class {
|
|
|
518
531
|
const maxH = this.playerHeight * this.playerModel.scale * 0.9;
|
|
519
532
|
const h = this.playerHeight * this.playerModel.scale * 0.75;
|
|
520
533
|
const minH = this.playerHeight * this.playerModel.scale * 0.7;
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
this.
|
|
534
|
+
console.log(angle2, playerDistanceFromGround, maxH, h, minH);
|
|
535
|
+
if (this.isFlying) {
|
|
536
|
+
} else {
|
|
537
|
+
if (playerDistanceFromGround > maxH) {
|
|
538
|
+
this.playerVelocity.y += delta * this.gravity;
|
|
539
|
+
this.player.position.addScaledVector(this.playerVelocity, delta);
|
|
540
|
+
this.playerIsOnGround = false;
|
|
541
|
+
} else if (playerDistanceFromGround > h && playerDistanceFromGround < maxH) {
|
|
542
|
+
if (angle2 >= 0 && angle2 < 5) {
|
|
543
|
+
this.playerVelocity.y += delta * this.gravity;
|
|
544
|
+
this.player.position.addScaledVector(this.playerVelocity, delta);
|
|
545
|
+
this.playerIsOnGround = true;
|
|
546
|
+
} else {
|
|
547
|
+
this.playerVelocity.set(0, 0, 0);
|
|
548
|
+
this.playerIsOnGround = true;
|
|
549
|
+
}
|
|
550
|
+
} else if (playerDistanceFromGround > minH && playerDistanceFromGround < h) {
|
|
528
551
|
this.playerVelocity.set(0, 0, 0);
|
|
529
552
|
this.playerIsOnGround = true;
|
|
530
|
-
} else {
|
|
553
|
+
} else if (playerDistanceFromGround < minH) {
|
|
531
554
|
this.playerVelocity.set(0, 0, 0);
|
|
555
|
+
this.player.position.set(this.player.position.x, intersects[0].point.y + h, this.player.position.z);
|
|
532
556
|
this.playerIsOnGround = true;
|
|
533
557
|
}
|
|
534
|
-
} else if (playerDistanceFromGround > minH && playerDistanceFromGround < h) {
|
|
535
|
-
this.playerVelocity.set(0, 0, 0);
|
|
536
|
-
this.playerIsOnGround = true;
|
|
537
|
-
} else if (playerDistanceFromGround < minH) {
|
|
538
|
-
this.playerVelocity.set(0, 0, 0);
|
|
539
|
-
this.player.position.set(this.player.position.x, intersects[0].point.y + h, this.player.position.z);
|
|
540
|
-
this.playerIsOnGround = true;
|
|
541
558
|
}
|
|
542
559
|
}
|
|
543
560
|
this.player.updateMatrixWorld();
|
|
@@ -569,13 +586,10 @@ var PlayerController = class {
|
|
|
569
586
|
});
|
|
570
587
|
const newPosition = this.tempVector.copy(this.tempSegment.start).applyMatrix4(this.collider.matrixWorld);
|
|
571
588
|
const deltaVector = this.tempVector2.subVectors(newPosition, this.player.position);
|
|
572
|
-
const
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
this.player.position.addScaledVector(n, offset);
|
|
577
|
-
}
|
|
578
|
-
if (!this.isFirstPerson && this.moveDir.lengthSq() > 0) {
|
|
589
|
+
const offset = Math.max(0, deltaVector.length() - 1e-5);
|
|
590
|
+
deltaVector.normalize().multiplyScalar(offset);
|
|
591
|
+
this.player.position.add(deltaVector);
|
|
592
|
+
if (!this.isFirstPerson && this.moveDir.lengthSq() > 0 && !this.isFlying) {
|
|
579
593
|
this.camDir.y = 0;
|
|
580
594
|
this.camDir.normalize();
|
|
581
595
|
this.camDir.negate();
|
|
@@ -587,6 +601,18 @@ var PlayerController = class {
|
|
|
587
601
|
const alpha = Math.min(1, this.rotationSpeed * delta);
|
|
588
602
|
this.player.quaternion.slerp(this.targetQuat, alpha);
|
|
589
603
|
}
|
|
604
|
+
if (this.isFlying) {
|
|
605
|
+
this.camDir.y = 0;
|
|
606
|
+
this.camDir.normalize();
|
|
607
|
+
this.camDir.negate();
|
|
608
|
+
this.moveDir.normalize();
|
|
609
|
+
this.moveDir.negate();
|
|
610
|
+
const lookTarget = this.player.position.clone().add(this.fwdPressed ? this.moveDir : this.camDir);
|
|
611
|
+
this.targetMat.lookAt(this.player.position, lookTarget, this.player.up);
|
|
612
|
+
this.targetQuat.setFromRotationMatrix(this.targetMat);
|
|
613
|
+
const alpha = Math.min(1, this.rotationSpeed * delta);
|
|
614
|
+
this.player.quaternion.slerp(this.targetQuat, alpha);
|
|
615
|
+
}
|
|
590
616
|
if (!this.isFirstPerson) {
|
|
591
617
|
const lookTarget = this.player.position.clone();
|
|
592
618
|
lookTarget.y += 30 * this.playerModel.scale;
|
|
@@ -607,18 +633,15 @@ var PlayerController = class {
|
|
|
607
633
|
const targetCamPos = origin.clone().add(direction.clone().multiplyScalar(safeDist));
|
|
608
634
|
this.camera.position.lerp(targetCamPos, this._camCollisionLerp);
|
|
609
635
|
} else {
|
|
610
|
-
const dis = this.player.position.distanceTo(this.camera.position);
|
|
611
636
|
this._raycasterPersonToCam.far = this._maxCamDistance;
|
|
612
637
|
const intersectsMaxDis = this._raycasterPersonToCam.intersectObject(this.collider, false);
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
safeDist = hitMax.distance - this._camEpsilon;
|
|
618
|
-
}
|
|
619
|
-
const targetCamPos = origin.clone().add(direction.clone().multiplyScalar(safeDist));
|
|
620
|
-
this.camera.position.lerp(targetCamPos, this._camCollisionLerp);
|
|
638
|
+
let safeDist = this._maxCamDistance;
|
|
639
|
+
if (intersectsMaxDis.length) {
|
|
640
|
+
const hitMax = intersectsMaxDis[0];
|
|
641
|
+
safeDist = hitMax.distance - this._camEpsilon;
|
|
621
642
|
}
|
|
643
|
+
const targetCamPos = origin.clone().add(direction.clone().multiplyScalar(safeDist));
|
|
644
|
+
this.camera.position.lerp(targetCamPos, this._camCollisionLerp);
|
|
622
645
|
}
|
|
623
646
|
}
|
|
624
647
|
if (this.player.position.y < this.boundingBoxMinY - 1) {
|
|
@@ -684,7 +707,6 @@ var PlayerController = class {
|
|
|
684
707
|
// 更新模型动画
|
|
685
708
|
updateMixers(delta) {
|
|
686
709
|
if (this.personMixer) this.personMixer.update(delta);
|
|
687
|
-
if (this.droneMixer) this.droneMixer.update(delta);
|
|
688
710
|
}
|
|
689
711
|
// BVH构建
|
|
690
712
|
async createBVH(meshUrl = "") {
|