Three.js 第一人称控制 [英] Three.js First Person Controls

查看:76
本文介绍了Three.js 第一人称控制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Three.js 和 WebGL,但不能完全按照我想要的方式获得控件.我选择尝试滚动我自己的"控件,因为 Three.js 的 FirstPersonControls 不使用指针锁定.

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.

无论如何,我从内置的 FirstPersonControls 中获取了大部分代码,将其转换为使用指针锁定(movementX 而不是 pageX - offset),但我是无法平滑外观运动.

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.

这是我的 onMouseMove(使用 originalEvent 因为它是一个 jquery 事件):

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;
}

还有我的 Controls.update()(在每个动画帧上调用,使用 THREE.Clock 增量):

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.

您可以在此处了解我所说的跳跃"的含义.我是 Three.js、WebGL 和一般 3D 的新手,因此感谢任何帮助.

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.

谢谢,

-乍得

EDIT@przemo_li 合作后,这是他来的工作代码与:

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);
}

推荐答案

'官方' 版本刚刚添加:https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js

'Official' version just added: https://github.com/mrdoob/three.js/blob/master/examples/js/controls/PointerLockControls.js

这篇关于Three.js 第一人称控制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆