如何使用以前的转换组合新的Camera Rotation?

时间:2013-01-16 03:32:32

标签: three.js webgl transformation

我正在尝试在THREE.js中实现类似于FlyControls的东西,但我不能为我的生活弄清楚如何正确旋转相机的音高:

http://radiantjs.herokuapp.com/

按A或Z键“向上/向下看”。因为该演示中的初始位置已经在偏航轴上旋转,所以音高基本上看起来像是滚动。

我更新相机位置和旋转的代码如下:

/**
 * Updates this View. This is called once per frame.
 * 
 * @param {Number} delta The length of the frame (16 / milliseconds).
 */
update: function(delta) {

        if (this.velocity.length() < 0.15) {
            this.velocity.clear()
        } else {
            this.velocity.multiplyScalar(0.85 * delta)
        }

        if (this.velocity.x || this.velocity.y || this.velocity.z) {
            this.camera.position = this.camera.localToWorld(this.velocity.clone())
            this.camera.position.clamp(-16384, 16384)
        }

        if (this.rotation.length() < 0.15) {
            this.rotation.clear()
        } else {
            this.rotation.multiplyScalar(0.85 * delta)
        }

        if (this.rotation.x || this.rotation.y) {
            var rotation = this.rotation.clone().multiplyScalar(Math.PI / 180)
            this.camera.rotation.add(rotation)
        }
    }

此处还提供完整代码: https://github.com/jdolan/radiantjs/blob/master/public/scripts/main/view.js#L291

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

THREE.js IRC频道中的一位用户解释说,完成我想要做的最简单的方法是将相机包装在一个单独的对象(父/容器)中。平移和偏航应用于容器,而俯仰应用于相机本身:

this.boom = new THREE.Object3D()
this.boom.position.copy(params.position)
this.boom.up.set(0, 0, 1)
this.boom.lookAt(new THREE.Vector3(0, 1, 0).add(params.position))

this.camera = new THREE.PerspectiveCamera(this.fov, this.aspect, 0.1, 4096)

this.boom.add(this.camera)
this.scene.add(this.boom)

然后在每一帧应用我的变换:

if (this.velocity.length() < 0.15) {
    this.velocity.clear()
} else {
    this.velocity.multiplyScalar(0.85)
}

if (this.velocity.x || this.velocity.y || this.velocity.z) {
    this.boom.translate(3, this.velocity.clone())
    this.boom.position.clamp(-16384, 16384)
}

if (this.avelocity.length() < 0.15) {
    this.avelocity.clear()
} else {
    this.avelocity.multiplyScalar(0.85)
}

if (this.avelocity.x || this.avelocity.y) {
    var rotation = this.avelocity.clone().multiplyScalar(Math.PI / 180)
    this.boom.rotation.y += rotation.y
    this.camera.rotation.x += rotation.x
}

像魅力一样!请注意,同样,当this.boom应用音高时,偏航应用于this.camera。这样可以使相机相对于动臂旋转,而不是相对于场景。

答案 1 :(得分:2)

我的方法是首先设置camera.eulerOrder = "YXZ";,然后我可以使用camera.rotation.y作为偏航,camera.rotation.x作为推销。

对于移动,我使用camera.translateZ作为前进/后退,camera.translateX作为strafe。由于我希望玩家即使在直接向上/向下看时也总是跳起来(或跌倒),我使用camera.position.y += velocity.y;代替translateY(基于轮换)。

我不确定这是否比使用容器更好或更差。