我的相机代码存在问题。在我的应用程序中,我可以旋转正在查看的模型,但也需要能够" walk"该模型。这意味着用户可以更改模型的相对方向,但仍需要相对于模型平面进行步行和旋转。
例如,想象一下看模型头,就像建筑物一样,你可以看到建筑物的侧面。如果用户按下" 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,而eyeRotation和orbitRotation是四元数。
我有这个用于改变轨道方向:
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);
};
所以问题是,如何确保眼球运动始终相对于模型平面(相对于轨道旋转平面)?
...