【发布时间】:2012-09-12 03:01:05
【问题描述】:
我正在使用 Three.js 和 WebGL,无法完全按照我想要的方式获得控件。由于 Three.js 的 FirstPersonControls 不使用指针锁定,因此我选择尝试“滚动我自己的”控件。
无论如何,我从内置的 FirstPersonControls 中获取了大部分代码,将其转换为使用指针锁定(movementX 而不是 pageX - offset),但我无法平滑外观运动。
这是我的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 的新手,因此不胜感激。
谢谢,
-乍得
编辑在使用@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);
}
【问题讨论】:
-
你能获得多少 FPS?
-
@przemo_li 这绝对不是 FPS 问题,我得到了 60FPS,就像我提到的运动工作正常。如果我在它周围 WASD,它会非常顺利。我只需要用鼠标做大的手势来产生不连贯的动作。我显然只是没有得到正确计算所需的数学知识。
-
mouseMovementX/Y 在极端情况下会采取什么范围?
-
看起来极值在
+-200范围内。尽管它们可以低至+-1甚至0(没有移动)。 -
嗯。阅读文档并检查什么是最大值。比将鼠标移动输入缩放到您的纬度和经度范围。也许这就是原因。或者它可能只是当前隐藏的另一个问题;)
标签: javascript 3d webgl three.js