· 6 years ago · Apr 26, 2020, 06:04 AM
1/**
2 * @author mrdoob / http://mrdoob.com/
3 * @author Mugen87 / https://github.com/Mugen87
4 */
5
6THREE.CannonPointerLockControls = function ( camera, domElement, cannonBody ) {
7 var eyeYPos = 2; // eyes are 2 meters above the ground
8 var velocityFactor = 0.2;
9 var jumpVelocity = 20;
10 var scope = this;
11
12 this.domElement = domElement || document.body;
13 this.isLocked = false;
14
15 camera.rotation.set( 0, 0, 0 );
16
17 var pitchObject = new THREE.Object3D();
18 pitchObject.add( camera );
19
20 var yawObject = new THREE.Object3D();
21 yawObject.position.y = 2;
22 yawObject.add( pitchObject );
23
24 var quat = new THREE.Quaternion();
25
26 var moveForward = false;
27 var moveBackward = false;
28 var moveLeft = false;
29 var moveRight = false;
30
31 var canJump = false;
32
33 var contactNormal = new CANNON.Vec3(); // Normal in the contact, pointing *out* of whatever the player touched
34 var upAxis = new CANNON.Vec3(0,1,0);
35 cannonBody.addEventListener( 'collide', function(e) {
36 var contact = e.contact;
37
38 // contact.bi and contact.bj are the colliding bodies, and contact.ni is the collision normal.
39 // We do not yet know which one is which! Let's check.
40 if( contact.bi.id == cannonBody.id ) // bi is the player body, flip the contact normal
41 contact.ni.negate( contactNormal );
42 else
43 contactNormal.copy( contact.ni ); // bi is something else. Keep the normal as it is
44
45 // If contactNormal.dot(upAxis) is between 0 and 1, we know that the contact normal is somewhat in the up direction.
46 if( contactNormal.dot( upAxis ) > 0.5 ) // Use a "good" threshold value between 0 and 1 here!
47 canJump = true;
48 });
49
50 var velocity = cannonBody.velocity;
51 var PI_2 = Math.PI / 2;
52
53 function onMouseMove( event ) {
54
55 if ( scope.isLocked === false ) return;
56
57 var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
58 var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
59
60 yawObject.rotation.y -= movementX * 0.002;
61 pitchObject.rotation.x -= movementY * 0.002;
62
63 pitchObject.rotation.x = Math.max( - PI_2, Math.min( PI_2, pitchObject.rotation.x ) );
64
65 }
66
67 function onKeyDown( event ) {
68
69 switch ( event.keyCode ) {
70
71 case 38: // up
72 case 87: // w
73 moveForward = true;
74 break;
75
76 case 37: // left
77 case 65: // a
78 moveLeft = true; break;
79
80 case 40: // down
81 case 83: // s
82 moveBackward = true;
83 break;
84
85 case 39: // right
86 case 68: // d
87 moveRight = true;
88 break;
89
90 case 32: // space
91 if ( canJump === true ){
92 velocity.y = jumpVelocity;
93 }
94 canJump = false;
95 break;
96 }
97
98 }
99
100 function onKeyUp( event ) {
101
102 switch( event.keyCode ) {
103
104 case 38: // up
105 case 87: // w
106 moveForward = false;
107 break;
108
109 case 37: // left
110 case 65: // a
111 moveLeft = false;
112 break;
113
114 case 40: // down
115 case 83: // a
116 moveBackward = false;
117 break;
118
119 case 39: // right
120 case 68: // d
121 moveRight = false;
122 break;
123
124 }
125
126 }
127
128 function onPointerlockChange() {
129
130 if ( document.pointerLockElement === scope.domElement ) {
131
132 scope.dispatchEvent( { type: 'lock' } );
133
134 scope.isLocked = true;
135
136 } else {
137
138 scope.dispatchEvent( { type: 'unlock' } );
139
140 scope.isLocked = false;
141
142 }
143
144 }
145
146 function onPointerlockError() {
147
148 console.error( 'THREE.PointerLockControls: Unable to use Pointer Lock API' );
149
150 }
151
152 this.connect = function () {
153
154 document.addEventListener( 'mousemove', onMouseMove, false );
155 document.addEventListener( 'keydown', onKeyDown, false );
156 document.addEventListener( 'keyup', onKeyUp, false );
157 document.addEventListener( 'pointerlockchange', onPointerlockChange, false );
158 document.addEventListener( 'pointerlockerror', onPointerlockError, false );
159
160 };
161
162 this.disconnect = function () {
163
164 document.removeEventListener( 'mousemove', onMouseMove, false );
165 document.removeEventListener( 'keydown', onKeyDown, false );
166 document.removeEventListener( 'keyup', onKeyUp, false );
167 document.removeEventListener( 'pointerlockchange', onPointerlockChange, false );
168 document.removeEventListener( 'pointerlockerror', onPointerlockError, false );
169
170 };
171
172 this.dispose = function () {
173
174 this.disconnect();
175
176 };
177
178 this.getObject = function () {
179
180 return yawObject;
181
182 };
183
184 this.getDirection = function () {
185
186 // assumes the camera itself is not rotated
187
188 var direction = new THREE.Vector3( 0, 0, - 1 );
189 var rotation = new THREE.Euler( 0, 0, 0, 'YXZ' );
190
191 return function ( v ) {
192 quat.multiplyVector3( v );
193
194 rotation.set( pitchObject.rotation.x, yawObject.rotation.y, 0 );
195
196 v.copy( direction ).applyEuler( rotation );
197
198 return v;
199
200 };
201
202 }();
203
204 this.lock = function () {
205
206 this.domElement.requestPointerLock();
207
208 };
209
210 this.unlock = function () {
211
212 document.exitPointerLock();
213
214 };
215
216 // Moves the camera to the Cannon.js object position and adds velocity to the object if the run key is down
217 var inputVelocity = new THREE.Vector3();
218 var euler = new THREE.Euler();
219 this.update = function ( delta ) {
220
221 if ( scope.isLocked === false ) return;
222
223 delta *= 0.1;
224
225 inputVelocity.set( 0,0,0 );
226
227 if ( moveForward ){
228 inputVelocity.z = -velocityFactor * delta;
229 console.log( 'moveForward', inputVelocity );
230 }
231 if ( moveBackward ){
232 inputVelocity.z = velocityFactor * delta;
233 console.log( 'moveBackward', inputVelocity );
234 }
235
236 if ( moveLeft ){
237 inputVelocity.x = -velocityFactor * delta;
238 console.log( 'moveLeft', inputVelocity );
239 }
240 if ( moveRight ){
241 inputVelocity.x = velocityFactor * delta;
242 console.log( 'moveRight', inputVelocity );
243 }
244
245 // Convert velocity to world coordinates
246 euler.x = pitchObject.rotation.x;
247 euler.y = yawObject.rotation.y;
248 euler.order = 'XYZ';
249 quat.setFromEuler( euler );
250 inputVelocity.applyQuaternion( quat );
251
252 // Add to the object
253 velocity.x += inputVelocity.x;
254 velocity.z += inputVelocity.z;
255
256 yawObject.position.copy( cannonBody.position );
257 console.log ( yawObject.position );
258 };
259
260 this.connect();
261
262};
263
264THREE.CannonPointerLockControls.prototype = Object.create( THREE.EventDispatcher.prototype );
265THREE.CannonPointerLockControls.prototype.constructor = THREE.CannonPointerLockControls;