1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136 | //import { ActiveEvents, ColliderDesc, RigidBody, RigidBodyDesc, World } from '@dimforge/rapier3d-compat'
import { Euler, Matrix4, Object3D, PerspectiveCamera, Quaternion, Scene, Vector3, WebGLRenderer } from 'three'
import AnimationController from './AnimationController'
import FollowCam from './FollowCam'
import Keyboard from './Keyboard'
export default class Player {
scene: Scene
//world: World
//body: RigidBody
animationController?: AnimationController
vector = new Vector3()
inputVelocity = new Vector3()
euler = new Euler()
quaternion = new Quaternion()
followTarget = new Object3D() //new Mesh(new SphereGeometry(0.1), new MeshNormalMaterial())
grounded = true
rotationMatrix = new Matrix4()
targetQuaternion = new Quaternion()
followCam: FollowCam
keyboard: Keyboard
wait = false
constructor(
scene: Scene,
camera: PerspectiveCamera,
renderer: WebGLRenderer
//world: World,
//position: [number, number, number] = [0, 0, 0]
) {
this.scene = scene
//this.world = world
this.keyboard = new Keyboard(renderer)
this.followCam = new FollowCam(this.scene, camera, renderer)
scene.add(this.followTarget) // the followCam will lerp towards this object3Ds world position.
// this.body = world.createRigidBody(
// RigidBodyDesc.dynamic()
// .setTranslation(...position)
// .enabledRotations(false, false, false)
// .setLinearDamping(4)
// .setCanSleep(false)
// )
// const shape = ColliderDesc.capsule(0.5, 0.15)
// .setTranslation(0, 0.645, 0)
// .setMass(1)
// .setFriction(0)
// .setActiveEvents(ActiveEvents.COLLISION_EVENTS)
// world.createCollider(shape, this.body)
}
async init() {
this.animationController = new AnimationController(this.scene, this.keyboard)
await this.animationController.init()
}
// setGrounded() {
// this.body.setLinearDamping(4)
// this.grounded = true
// setTimeout(() => (this.wait = false), 250)
// }
update(delta: number) {
// this.inputVelocity.set(0, 0, 0)
// if (this.grounded) {
// if (this.keyboard.keyMap['KeyW']) {
// this.inputVelocity.z = -1
// }
// if (this.keyboard.keyMap['KeyS']) {
// this.inputVelocity.z = 1
// }
// if (this.keyboard.keyMap['KeyA']) {
// this.inputVelocity.x = -1
// }
// if (this.keyboard.keyMap['KeyD']) {
// this.inputVelocity.x = 1
// }
// this.inputVelocity.setLength(delta * (this.animationController?.speed || 1)) // limit horizontal movement based on walking or running speed
// if (!this.wait && this.keyboard.keyMap['Space']) {
// this.wait = true
// this.body.setLinearDamping(0)
// if (this.keyboard.keyMap['ShiftLeft']) {
// this.inputVelocity.multiplyScalar(15) // if running, add more boost
// } else {
// this.inputVelocity.multiplyScalar(10)
// }
// this.inputVelocity.y = 5 // give jumping some height
// this.grounded = false
// }
// }
// // apply the followCam yaw to inputVelocity so the capsule moves forward based on cameras forward direction
// this.euler.y = this.followCam.yaw.rotation.y
// this.quaternion.setFromEuler(this.euler)
// this.inputVelocity.applyQuaternion(this.quaternion)
// // now move the capsule body based on inputVelocity
// this.body.applyImpulse(this.inputVelocity, true)
// // The followCam will lerp towards the followTarget position.
// this.followTarget.position.copy(this.body.translation()) // Copy the capsules position to followTarget
// this.followTarget.getWorldPosition(this.vector) // Put followTargets new world position into a vector
// this.followCam.pivot.position.lerp(this.vector, delta * 10) // lerp the followCam pivot towards the vector
// // Eve model also lerps towards the capsules position, but independently of the followCam
// this.animationController?.model?.position.lerp(this.vector, delta * 20)
// // Also turn Eve to face the direction of travel.
// // First, construct a rotation matrix based on the direction from the followTarget to Eve
// this.rotationMatrix.lookAt(
// this.followTarget.position,
// this.animationController?.model?.position as Vector3,
// this.animationController?.model?.up as Vector3
// )
// this.targetQuaternion.setFromRotationMatrix(this.rotationMatrix) // creating a quaternion to rotate Eve, since eulers can suffer from gimbal lock
// // Next, get the distance from the Eve model to the followTarget
//const distance = this.animationController?.model?.position.distanceTo(this.followTarget.position)
// // If distance is higher than some espilon, and Eves quaternion isn't the same as the targetQuaternion, then rotate towards the targetQuaternion.
// if ((distance as number) > 0.0001 && !this.animationController?.model?.quaternion.equals(this.targetQuaternion)) {
// this.targetQuaternion.z = 0 // so that it rotates around the Y axis
// this.targetQuaternion.x = 0 // so that it rotates around the Y axis
// this.targetQuaternion.normalize() // always normalise quaternions before use.
// this.animationController?.model?.quaternion.rotateTowards(this.targetQuaternion, delta * 20)
// }
// update which animationAction Eve should be playing
this.animationController?.update(delta)
}
}
|