从位置矢量获取速度矢量

时间:2013-06-07 18:20:44

标签: c++ math game-physics

我看了一堆类似的问题,我似乎无法找到一个特别回答我问题的问题。我正在编写一个简单的3D游戏,我正在尝试让玩家在我的地图周围拾取和移动实体。我基本上想得到一个速度矢量,它可以将物理对象“推”到玩家眼前一段距离,无论他们在哪里。这是an example这个在另一个游戏中完成的(玩家正在他眼前拿着一个椅子实体)。

为此,我找出玩家的眼角,然后从角度获得前向矢量,然后计算物体的速度。这是我的工作代码:

void Player::PickupOtherEntity( Entity& HoldingEntity )
{
    QAngle eyeAngles = this->GetPlayerEyeAngles();
    Vector3 vecPos = this->GetEyePosition();
    Vector3 vecDir = eyeAngles.Forward();

    Vector3 holdingEntPos = HoldingEntity.GetLocation();

    // update object by holding it a distance away
    vecPos.x += vecDir.x * DISTANCE_TO_HOLD;
    vecPos.y += vecDir.y * DISTANCE_TO_HOLD;
    vecPos.z += vecDir.z * DISTANCE_TO_HOLD;

    Vector3 vecVel = vecPos - holdingEntPos;
    vecVel = vecVel.Scale(OBJECT_SPEED_TO_MOVE);

    // set the entity's velocity as to "push" it to be in front of the player's eyes
    // at a distance of DISTANCE_TO_HOLD away
    HoldingEntity.SetVelocity(vecVel);
}

所有这一切都很棒,但我想转换我的数学,以便我可以施加冲动。我没有为物体设置一个全新的速度,而是想“加”一些速度到它现有的速度。所以假设我有其当前的速度,我需要什么样的数学来“加”速度?这本质上是一个游戏物理问题。谢谢!

3 个答案:

答案 0 :(得分:0)

一个非常简单的实现可能是这样的:

velocity(t+delta) = velocity(t) + delta * acceleration(t)
acceleration(t) = force(t) / mass of the object

速度,加速度和力是矢量。 t,delta和mass scalars。

这对于小而等间距的增量只能起到相当好的作用。你基本上想要实现的是使用经典力学模拟身体。

答案 1 :(得分:0)

对于常数F,脉冲在技术上是FΔt。这里我们可能想要假设Δt,因为质量是无关紧要的。如果你想要一个冲动的动画,你必须决定速度的变化应该是多少以及它需要多长时间。它变得非常复杂。

老实说,冲动不是正确的事情。相反,最好设置一个恒定的pick_up_velocity(人们不倾向于使用脉冲拾取东西),并在每次物体上升速度时刷新位置。直到达到正确的水平:

while(entPos.y < holdingEntPos.y)
{
    entPos.y += pickupVel.y;
   //some sort of short delay
}

至于漂浮在玩家眼前,设置某种类型的EyeMovementEvent,它也会向玩家持有的任何实体发送正确的位置变化。

如果我错过了某些东西并且这就是你已经在做的事情,请记住,当人类施加冲动时,它通常是非常短的时间内的高加速度,远低于一帧。无论如何你都不会在游戏中看到它。

答案 2 :(得分:0)

基本的Newtonian / D'Alembert物理学指示:

derivate(position)=velocity
derivate(velocity)=acceleration

还有倒退:

integrate(acceleration)=velocity
integrate(velocity)=position

因此,对于您的引擎,您可以使用:

矩形求和而不是积分(积分的数值解)。定义时间常量dt [seconds],它是更新之间的间隔(计时器或1 / fps)。所以更新代码(必须每隔dt定期调用:

vx+=ax*dt;
vy+=ay*dt;
vz+=az*dt;
 x+=vx*dt;
 y+=vy*dt;
 z+=vz*dt;

其中:

  • a{x,y,z} [m/s^2]是实际加速度(在您的情况下,方向向量缩放为a=Force/mass
  • v{x,y,z} [m/s]是实际速度
  • x,y,z [m]是实际位置

    1. 这些值必须初始化a,v为零,x,y,z初始化为初始位置
    2. 所有对象/玩家......都有自己的变量
    3. 完全停止由v=0; a=0;
    4. 完成
    5. 仅通过更改a
    6. 来完成对象的驱动
    7. 如果碰撞镜像v矢量碰撞normal
    8. 并且可能乘以一些k<1.0(例如0.95)来计算影响下的能量损失

您可以通过添加g vector:

来添加重力或任何其他力场
vx+=ax*dt+gx*dt;
vy+=ay*dt+gy*dt;
vz+=az*dt+gz*dt;

您也可以添加摩擦力和其他任何需要的东西

PS。同样适用角度只需使用angle/omega/epsilon/I代替x/a/v/m

通过角度I清楚表示围绕质心的旋转(pitch,yaw,roll)