javascript - Three.js 第一人称控制

标签 javascript 3d webgl three.js

我正在使用 Three.js 和 WebGL,但无法完全按照我想要的方式进行控制。我选择尝试“滚动我自己的”控件,因为 Three.js 的 FirstPersonControls 不使用指针锁定。

无论如何,我的大部分代码都来自内置的 FirstPersonControls,将其转换为使用指针锁定(movementX 而不是 pageX - offset),但我无法平滑注视 Action 。

这是我的 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 的新手,所以非常感谢您的帮助。

谢谢,

-乍得


编辑 使用@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);
}

最佳答案

关于javascript - Three.js 第一人称控制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12500874/

相关文章:

css - 以倒置旋转木马或 VR/球形方式查看图像

javascript - Webpack JSX 无法通过 ES6 导入解析相关模块

javascript - 从滚动条中的 div 获取 sibling 对

JavaScript:如何获取字符串形式的代码?

javascript - ViewMatrix 计算弄乱了模型

javascript - 从 WebGL 3D Canvas 读取像素信息返回所有 [0, 0, 0, 255]

javascript - Bookmarklet:将隐藏的 iframe 附加到页面并加载 url

python - 在 matplotlib python3 中向 3d 图形添加线

python - Python 中的 3D 模型(点/线)渲染器

image - Okami sumie风格渲染算法