简体   繁体   English

相对于点旋转相机

[英]Rotate camera relative to a point

I need to rotate the camera around a player from a third person view. 我需要从第三人称视角围绕玩家旋转摄像机。 (Nothing fancy). (没有什么花哨)。

Here it is how I try it: 这是我尝试的方法:

// 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;
}

The problem is that if, let's say just do turn left a lot, the distance between the object and the camera increases. 问题是,如果说只是左转很多,则物体和相机之间的距离会增加。

For a very simple orbit camera, like most 3rd person adventure games, you will need 4 things: 对于非常简单的orbit摄像机,像大多数3rd person冒险游戏一样,您需要做以下四件事:

  • The position of the target 目标位置
  • The distance from the target 距目标的距离
  • The azimuthal angle 方位角
  • The polar angle 极角

(If you want your camera to be always relative to the target in orientation, you need to provide the target's orientation as well, in this case I will simply use the world orientation) (如果您希望相机始终相对于目标定向,则还需要提供目标的定向,在这种情况下,我将仅使用世界方向)

See Spherical coordinate systems for a reference. 有关参考,请参见球坐标系

You should map your azimuthal angle on your horizontal control (and make it loop around when you reach 2 * PI ) and your polar angle should be mapped on your vertical control (or inverted if the player selects that option and make it clamped between -PI and PI - watch out for calculations based on the world Up vector if you go parallel to it ( -PI or PI ) 您应该在水平控件上映射方位角(并在达到2 * PI时使其成环旋转),而极角应在垂直控件上进行映射(如果玩家选择了该选项并将其夹在-PI之间,则应该反转和PI如果与世界Up向量平行( -PIPI ), -PI注意基于世界向量的计算

The distance can be fixed or driven by a spline, for this case we will assume a fixed distance. 该距离可以是固定的,也可以由样条驱动,在这种情况下,我们将假定固定的距离。

So, to compute your position you start with WorldForward , which is a unit vector pointing in the axis that you generally consider to be your forward, for example (1,0,0) (here, if we were building a relative camera, we would use our target's forward vector) and you invert it ( * -1 ) to go "from the target" "to your camera". 因此,要计算您的位置,请从WorldForward开始,它是指向通常被认为是您的向前轴的unit vector ,例如(1,0,0) (在这里,如果我们要构建一个相对摄像机,我们将使用我们目标的前向矢量),然后将其反转( * -1 )以“从目标”“到达您的相机”。

(The following is untested pseudo code, but you should get the gist - also, keep note that it can be simplified, I just went for clarity) (以下是未经测试的伪代码,但是您应该了解要点-另外,请注意,它可以简化,我只是为了清楚起见)

Next step is to rotate this vector using our azimuth angle, which is the horizontal orientation component of your camera. 下一步是使用我们的方位角rotate此矢量,该方位角是相机的水平方向分量。 Something like: 就像是:

Vector toCamera = WorldForward * -1;
Matrix horizontalRotation = Matrix.CreateRotationZ(azimuth); // assuming Z is up
Vector horizontalRotationPosition = horizontalRotation.Transform(toCamera);

At this point, you have a camera that can rotate horizontally around your target, now to add the other axis, you simply transform again using the polar angle rotation: 此时,您有一台可以围绕目标水平旋转的摄像机,现在要添加另一个轴,只需使用极角旋转再次进行变换即可:

Matrix verticalRotation = Matrix.CreateRotationY(polar); // assuming Y is right
Vector finalRotatedVector = verticalRotation.Transform(horizontalRotationPosition);

Now, what we have is a unit vector that points to the position where the camera should be, if you multiply it by the distance you want to keep from your target and add the position of your target, you should get your final position . 现在,我们得到的是一个unit vector ,使其指向相机应该是,如果你被乘以位置distance ,你想从你的目标保持并添加你的目标的位置,你应该把你的最终position Keep in mind that this unit vector, if negated, represents the forward vector of your camera. 请记住,如果取反此单位矢量,则它代表相机的forward矢量。

Vector cameraPosition = targetPosition + finalRotatedVector * distanceFromTarget;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM