我在玩Three.js和WebGL,並且無法像我想要的那樣完全控制控件。因爲Three.js的FirstPersonControls不使用指針鎖,所以我選擇嘗試「滾動我自己的」控件。Three.js第一人稱控件
無論如何,我從內置的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
三角洲):
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);
}
你得到多少FPS? –
@przemo_li這絕對不是FPS問題,我得到60FPS,就像我提到的機芯工作正常。如果我在它附近WASD是完全平滑的。我只需用鼠標做大手勢就會產生波濤洶涌的動作。我顯然只是沒有得到正確計算所需的數學。 – Chad
mouseMovementX/Y在極端情況下的範圍是多少? –