Three.js第一人称控制 [英] Three.js First Person Controls
问题描述
我玩弄Three.js和WebGL的,并不能完全得到了控制我想要的方式。我选择尝试推出自己的管制,因为Three.js的FirstPersonControls不使用指针锁定。
不管怎样,我把我的大部分code从内置FirstPersonControls,将其转换为使用指针锁定(而不是
),但我有麻烦平滑的外观运动 movementX
pageX属性 - 偏移
下面是我的的OnMouseMove
(使用 originalEvent
,因为它是一个jQuery事件):
的OnMouseMove:功能(E){
如果(document.pointerLockElement!)回报;
VAR的Movex = e.originalEvent.movementX ||
e.originalEvent.mozMovementX ||
e.originalEvent.webkitMovementX ||
0,
moveY = e.originalEvent.movementY ||
e.originalEvent.mozMovementY ||
e.originalEvent.webkitMovementY ||
0;
//更新鼠标移动的到来帧
this.mouseMovementX =的Movex;
this.mouseMovementY = moveY;
}
和我的 Controls.update()
(呼吁每个动画帧,用 THREE.Clock
增量)
更新:函数(增量){
如果(this.freeze){
返回;
}
//运动,做工精细
如果(this.moveForward)this.camera.translateZ( - (actualMoveSpeed + this.autoSpeedFactor));
如果(this.moveBackward)this.camera.translateZ(actualMoveSpeed);
如果(this.moveLeft)this.camera.translateX(-actualMoveSpeed);
如果(this.moveRight)this.camera.translateX(actualMoveSpeed);
/////////
//问题与此code:
/////////
//看动作,真是心惊肉跳
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);
}
这code做的工作,但移动相机跳动的鼠标左右移动。我真的可以使用一些帮助搞清楚如何来平滑它。
您可以看到我所说的神经质此处。我是新来Three.js,WebGL的,只是3D一般而言因此任何帮助是AP preciated。
谢谢
-Chad
修改 @przemo_li 的工作后,这里的工作$ C $ Ç他想出了:
的OnMouseMove:功能(E){
如果(document.pointerLockElement!)回报;
VAR的Movex = e.originalEvent.movementX ||
e.originalEvent.mozMovementX ||
e.originalEvent.webkitMovementX ||
0,
moveY = e.originalEvent.movementY ||
e.originalEvent.mozMovementY ||
e.originalEvent.webkitMovementY ||
0;
//更新鼠标移动的初始COORDS
this.mouseMovementX + =的Movex; //聚集鼠标移动等共达DELTA
this.mouseMovementY + = moveY;
},
更新:函数(增量){
如果(this.freeze){
返回;
}
//运动
如果(this.moveForward)this.camera.translateZ( - (actualMoveSpeed + this.autoSpeedFactor));
如果(this.moveBackward)this.camera.translateZ(actualMoveSpeed);
如果(this.moveLeft)this.camera.translateX(-actualMoveSpeed);
如果(this.moveRight)this.camera.translateX(actualMoveSpeed);
//看运动
this.lon + = this.mouseMovementX;
this.lat - = this.mouseMovementY;
this.mouseMovementX = 0; //重新设置鼠标的增量为0,每个渲染帧
this.mouseMovementY = 0;
this.phi =(90 - this.lat)* Math.PI / 180;
this.theta = this.lon * Math.PI / 180;
如果(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);
}
官方版本只是增加了:<一href="https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js">https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js
I'm playing around with Three.js and WebGL and can't quite get the controls the way I want. I chose to try to "roll my own" controls since Three.js's FirstPersonControls do not use pointer lock.
Anyway, I took most of my code from the built-in FirstPersonControls, converted it to use pointer lock (movementX
instead of pageX - offset
), but I am having trouble smoothing the look motion.
Here is my onMouseMove
(using originalEvent
since it is a jquery event):
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;
}
And my Controls.update()
(called on each animation frame, with the 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);
}
This code does work, but moving the camera is jumpy as the mouse moves around. I could really use some help figuring out how to smooth it.
You can see what I mean by "jumpy" here. I'm new to Three.js, WebGL, and just 3D in general so any help is appreciated.
Thanks,
-Chad
EDIT After working with @przemo_li, here is the working code he came up with:
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);
}
'Official' version just added: https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js
这篇关于Three.js第一人称控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!