Javascript 相对于平面的运动

Javascript 相对于平面的运动,javascript,math,graphics,webgl,Javascript,Math,Graphics,Webgl,我当前的相机代码有问题。在我的应用程序中,我可以旋转正在查看的模型,但也需要能够行走模型。这意味着用户可以更改模型的相对方向,但仍需要相对于模型平面进行行走和旋转 例如,想象一下,像一座建筑物一样,正面看模型,这样您就可以看到建筑物的侧面。在这种情况下,如果用户按W键,他们将更靠近建筑物。现在,他们可以选择旋转模型的俯仰,这样他们现在可以看到模型的屋顶,或者用户可以选择向上看,然后向下看地面。在这种情况下,击打W需要保持现有高度,并向屏幕顶部移动。通常,运动需要感觉好像是相对于模型的平面行走,即

我当前的相机代码有问题。在我的应用程序中,我可以旋转正在查看的模型,但也需要能够行走模型。这意味着用户可以更改模型的相对方向,但仍需要相对于模型平面进行行走和旋转

例如,想象一下,像一座建筑物一样,正面看模型,这样您就可以看到建筑物的侧面。在这种情况下,如果用户按W键,他们将更靠近建筑物。现在,他们可以选择旋转模型的俯仰,这样他们现在可以看到模型的屋顶,或者用户可以选择向上看,然后向下看地面。在这种情况下,击打W需要保持现有高度,并向屏幕顶部移动。通常,运动需要感觉好像是相对于模型的平面行走,即使该平面已相对于您的视点旋转

左右看也存在同样的问题。假设您再次查看建筑的侧面,然后按箭头键向右或向左查看。此时的旋转与模型位于同一平面内。但是,如果用户旋转模型的俯仰以查看屋顶,那么他们会向右看,它会围绕摄影机的位置旋转,看起来就像模型在旋转,而不仅仅是旋转。想象一下站在地上向下看。摄像机的旋转看起来像是世界在旋转,但这不是我得到的。我让模型旋转离开,就像你旋转眼睛看天空一样

这是我的更新功能

    mat4.identity(this.eyeMatrix);
    mat4.identity(this.orbitMatrix);
    mat4.identity(this.mvMatrix);

    mat4.fromRotationTranslation(eyeMatrix,   this.eyeRotation,   [0, 0, 0]);
    mat4.fromRotationTranslation(orbitMatrix, this.orbitRotation, [0, 0, 0]);       

    mat4.translate(this.mvMatrix, this.mvMatrix, this.orbit);
    mat4.multiply(this.mvMatrix,  this.mvMatrix, this.orbitMatrix);
    mat4.translate(this.mvMatrix, this.mvMatrix, this.eye);
    mat4.multiply(this.mvMatrix,  this.mvMatrix, this.eyeMatrix);

    this.getModelViewMatrix();
    this.getProjectionMatrix();
    this.getNormalMatrix();
其中,轨道和眼睛是vec3,轨道和眼睛矩阵是mat4,眼睛旋转和轨道旋转是四元数

我有一个用于更改动态观察方向的工具:

    this.orbitYaw   += yawAmount;
    this.orbitPitch += pitchAmount;

    var orbitRotation = this.orbitRotation;

    var rotPitch = this.createOrbitPitchRotation();
    quat.copy(orbitRotation, rotPitch);

    var rotYaw = quat.create();
    quat.setAxisAngle(rotYaw, this.up, this.orbitYaw);
    quat.multiply(orbitRotation, rotYaw, orbitRotation);

    this.update();
    var rotYaw = quat.create();
    quat.setAxisAngle(rotYaw, this.up, yawAmount);
    quat.multiply(this.eyeRotation, rotYaw, this.eyeRotation);

    quat.rotateX(this.eyeRotation, this.eyeRotation, pitchAmount);
    quat.normalize(this.eyeRotation, this.eyeRotation);

    this.update();
我有一个改变眼睛方向的方法:

    this.orbitYaw   += yawAmount;
    this.orbitPitch += pitchAmount;

    var orbitRotation = this.orbitRotation;

    var rotPitch = this.createOrbitPitchRotation();
    quat.copy(orbitRotation, rotPitch);

    var rotYaw = quat.create();
    quat.setAxisAngle(rotYaw, this.up, this.orbitYaw);
    quat.multiply(orbitRotation, rotYaw, orbitRotation);

    this.update();
    var rotYaw = quat.create();
    quat.setAxisAngle(rotYaw, this.up, yawAmount);
    quat.multiply(this.eyeRotation, rotYaw, this.eyeRotation);

    quat.rotateX(this.eyeRotation, this.eyeRotation, pitchAmount);
    quat.normalize(this.eyeRotation, this.eyeRotation);

    this.update();
最后,我有一个改变眼睛向前位置的方法:

 function moveEye(direction, velocity) {
    vec3.scale(direction, direction, velocity);
    vec3.add(this.eye, this.eye, direction);
    this.update();
};

function moveEyeForward(velocity) {
    var dir   = vec3.fromValues(0, 0, 0);
    var right = this.getEyeRightVector();

    vec3.cross(dir, right, this.up);
    vec3.normalize(dir, dir);

    this.moveEye(dir, velocity);

    this.update();
};

function getEyeRightVector() {
    var q  = this.eyeRotation;
    var qx = q[0], qy = q[1], qz = q[2], qw = q[3];

    var x = 1 - 2 * (qy * qy + qz * qz);
    var y =     2 * (qx * qy + qw * qz);
    var z =     2 * (qx * qz - qw * qy);

    return vec3.fromValues(x, y, z);
};
所以问题是,我如何确保眼球运动始终相对于模型平面相对于轨道旋转平面


如果要独立于视图方向移动,为什么不在moveEyeForward中执行类似moveEyevec3.fromValues0、0、1、velocity的操作?它需要在模型平面内移动。只要模型平面平行于z轴,沿z方向移动将沿模型平面移动。但如果旋转模型,使模型的向上方向平行于z轴,则沿z轴移动眼睛将导致向下移动到模型,而不是沿地面。然后将方向向量与模型的世界矩阵相乘。