Estoy jugando con Three.js y WebGL y no puedo obtener los controles del modo que quiero. Elegí intentar "hacer rodar mis propios controles" ya que los FirstPersonControls de Three.js no usan el bloqueo del puntero.Three.js First Person Controls
De todos modos, tomé la mayor parte de mi código del FirstPersonControls incorporado, lo convertí para utilizar el bloqueo del puntero (movementX
en lugar de pageX - offset
), pero estoy teniendo problemas para suavizar el movimiento de la apariencia.
Aquí es mi onMouseMove
(usando originalEvent
ya que es un evento jQuery):
onMouseMove: function(e) {
if(!document.pointerLockElement) return;
var moveX = e.originalEvent.movementX ||
e.originalEvent.mozMovementX ||
e.originalEvent.webkitMovementX ||
0,
moveY = e.originalEvent.movementY ||
e.originalEvent.mozMovementY ||
e.originalEvent.webkitMovementY ||
0;
//Update the mouse movement for coming frames
this.mouseMovementX = moveX;
this.mouseMovementY = moveY;
}
Y mi Controls.update()
(llamado en cada fotograma de la animación, con el THREE.Clock
delta):
update: function(delta) {
if(this.freeze) {
return;
}
//movement, works fine
if(this.moveForward) this.camera.translateZ(-(actualMoveSpeed + this.autoSpeedFactor));
if(this.moveBackward) this.camera.translateZ(actualMoveSpeed);
if(this.moveLeft) this.camera.translateX(-actualMoveSpeed);
if(this.moveRight) this.camera.translateX(actualMoveSpeed);
/////////
//ISSUES ARE WITH THIS CODE:
/////////
//look movement, really jumpy
this.lon += this.mouseMovementX;
this.lat -= this.mouseMovementY;
this.lat = Math.max(-85, Math.min(85, this.lat));
this.phi = (90 - this.lat) * Math.PI/180;
this.theta = this.lon * Math.PI/180;
this.target.x = this.camera.position.x + 100 * Math.sin(this.phi) * Math.cos(this.theta);
this.target.y = this.camera.position.y + 100 * Math.cos(this.phi);
this.target.z = this.camera.position.z + 100 * Math.sin(this.phi) * Math.sin(this.theta);
this.camera.lookAt(this.target);
}
Este El código funciona, pero al mover la cámara, el mouse se mueve. Realmente podría usar algo de ayuda para averiguar cómo suavizarlo.
Puedes ver lo que quiero decir con "jumpy" here. Soy nuevo en Three.js, WebGL, y solo 3D en general, así que cualquier ayuda es apreciada.
Gracias,
-Chad
EDIT Después de trabajar con @przemo_li, aquí está el código de trabajo que se le ocurrió:
onMouseMove: function(e) {
if(!document.pointerLockElement) return;
var moveX = e.originalEvent.movementX ||
e.originalEvent.mozMovementX ||
e.originalEvent.webkitMovementX ||
0,
moveY = e.originalEvent.movementY ||
e.originalEvent.mozMovementY ||
e.originalEvent.webkitMovementY ||
0;
//Update the initial coords on mouse move
this.mouseMovementX += moveX; //aggregate mouse movements as a total delta delta
this.mouseMovementY += moveY;
},
update: function(delta) {
if(this.freeze) {
return;
}
//movement
if(this.moveForward) this.camera.translateZ(-(actualMoveSpeed + this.autoSpeedFactor));
if(this.moveBackward) this.camera.translateZ(actualMoveSpeed);
if(this.moveLeft) this.camera.translateX(-actualMoveSpeed);
if(this.moveRight) this.camera.translateX(actualMoveSpeed);
//look movement
this.lon += this.mouseMovementX;
this.lat -= this.mouseMovementY;
this.mouseMovementX = 0; //reset mouse deltas to 0 each rendered frame
this.mouseMovementY = 0;
this.phi = (90 - this.lat) * Math.PI/180;
this.theta = this.lon * Math.PI/180;
if(this.constrainVertical) {
this.phi = THREE.Math.mapLinear(this.phi, 0, Math.PI, this.verticalMin, this.verticalMax);
}
this.target.x = this.camera.position.x + 100 * Math.sin(this.phi) * Math.cos(this.theta);
this.target.y = this.camera.position.y + 100 * Math.cos(this.phi);
this.target.z = this.camera.position.z + 100 * Math.sin(this.phi) * Math.sin(this.theta);
this.camera.lookAt(this.target);
}
¿Cuánto FPS qué se obtiene? –
@przemo_li Definitivamente no es un problema de FPS, estoy recibiendo 60FPS y como mencioné el movimiento funciona bien. Si WASD alrededor es perfectamente suave. Solo tengo que hacer grandes gestos con el mouse para producir un movimiento entrecortado. Obviamente no obtengo los cálculos necesarios para hacer el cálculo correctamente. – Chad
¿Qué rango llevará mouseMovementX/Y en extremos? –