我需要从第三人称视角围绕玩家旋转摄像机。(没什么好看的)。
这是我尝试的方式:
// Forward, right, and position define the plane - they have x,y,z components.
void rotate ( float angle, Vector interestPoint )
{
Vector oldForward ( Forward );
forward = forward * cos(angle) + right * sin(angle);
forward.Normalize();
right = forward.CrossProduct ( up );
right.Normalize();
position = ( position + old_forward * position.Distance( interestPoint ) ) - (forward * position.Distance( interestPoint ) );
this->angle += angle;
}
问题是,如果,假设只是左转很多,物体和相机之间的距离就会增加。
对于非常简单的orbit
相机,就像大多数3rd person
冒险游戏一样,您将需要 4 件事:
- 目标的位置
- 与目标的距离
- 方位角
- 极角
(如果您希望相机在方向上始终相对于目标,则还需要提供目标的方向,在这种情况下,我将仅使用世界方向)
有关参考,请参见球面坐标系。
您应该在水平控件上映射方位角(并在达到2 * PI
时使其循环),并且极角应映射到垂直控件上(如果玩家选择该选项并将其夹在-PI
和PI
之间,则反转 - 请注意基于世界Up
矢量的计算,如果您平行于它(-PI
或PI
)
距离可以是固定的,也可以由样条驱动,在这种情况下,我们将假设一个固定的距离。
因此,要计算您的位置,您从WorldForward
开始,这是您通常认为是前方的轴上的unit vector
点,例如(1,0,0)
(在这里,如果我们构建一个相对相机,我们将使用目标的前向矢量)并将其反转(* -1
)以"从目标"到您的相机"。
(以下是未经测试的伪代码,但您应该了解要点 - 另外,请注意它可以简化,我只是为了清楚起见)
下一步是使用我们的方位角rotate
此矢量,方位角是相机的水平方向分量。像这样:
Vector toCamera = WorldForward * -1;
Matrix horizontalRotation = Matrix.CreateRotationZ(azimuth); // assuming Z is up
Vector horizontalRotationPosition = horizontalRotation.Transform(toCamera);
此时,您有一个可以围绕目标水平旋转的相机,现在要添加另一个轴,您只需使用极角旋转再次变换:
Matrix verticalRotation = Matrix.CreateRotationY(polar); // assuming Y is right
Vector finalRotatedVector = verticalRotation.Transform(horizontalRotationPosition);
现在,我们拥有的是一个指向相机应该在位置的unit vector
,如果您将其乘以要远离目标的distance
并添加目标的位置,您应该得到最终position
。请记住,如果取反,则此单位矢量表示相机的forward
矢量。
Vector cameraPosition = targetPosition + finalRotatedVector * distanceFromTarget;