javascript - Three.js First Person Controls
3d webgl (2)
1) Restricciones? En tu código, limitas el movimiento del mouse X a - | + 85 Es poco probable que tal restricción sea necesaria.
2) Agregue todos los eventos que ocurran durante el marco En su código anula el movimiento del mouse con cada nuevo evento. Entonces, si obtienes 3 eventos durante el cuadro, solo se guardarán los más recientes.
Agrega esos movimientos. Luego de renderizar el fotograma, puedes borrar el conteo. Y comienza a reunir eventos de nuevo.
Estoy jugando con Three.js y WebGL y no puedo obtener los controles como quiero. Elegí intentar "hacer rodar mis propios controles" ya que los FirstPersonControls de Three.js no usan el bloqueo del puntero.
De todos modos, tomé la mayor parte de mi código del FirstPersonControls incorporado, lo convertí para utilizar el bloqueo del puntero ( movementX
lugar de pageX - offset
), pero estoy teniendo problemas para suavizar el movimiento de la apariencia.
Aquí está 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 cuadro de 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 código funciona, pero mover la cámara está nervioso cuando el mouse se mueve. Realmente podría usar algo de ayuda para averiguar cómo suavizarlo.
Puedes ver lo que quiero decir con "jumpy" aquí . Soy nuevo en Three.js, WebGL, y solo 3D en general, así que cualquier ayuda es apreciada.
Gracias,
-Chad
EDITAR 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);
}
Versión ''oficial'' recién agregada: https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js