我正在玩Three.js和WebGL,并且无法按照我想要的方式获得控件。我选择尝试“滚动自己的”控件,因为Three.js的FirstPersonControls不使用指针锁。
无论如何,我从内置的FirstPersonControls中获取了大部分代码,将其转换为使用指针锁(movementX
而不是pageX - offset
),但是我无法平滑外观运动。 / p>
这是我的onMouseMove
(使用originalEvent
,因为它是一个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;
}
我的Controls.update()
(调用每个动画帧,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);
}
此代码可以正常工作,但随着鼠标移动,移动相机会跳动。我真的可以帮助找出如何平滑它。
你可以通过“跳跃”here看出我的意思。我是Three.js,WebGL的新手,一般只是3D,所以任何帮助都会受到赞赏。
谢谢,
-Chad
编辑使用@przemo_li后,这是他提出的工作代码:
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);
}
答案 0 :(得分:18)
'官方'版本刚刚添加:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js
答案 1 :(得分:4)
1)约束? 在你的代码中,你将鼠标X移动限制在 - | + 85这种约束不太可能。
2)聚合在帧期间发生的所有事件 在您的代码中,您可以使用每个新事件覆盖鼠标移动。因此,如果您在帧期间获得3个事件,则仅存储最近的事件。
添加这些动作。比渲染帧后,您可以清除计数。并再次开始收集活动。