2013-06-07 3 views
0

Я посмотрел на кучу похожих вопросов, и я не могу найти тот, который особенно отвечает на мой вопрос. Я кодирую простую 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); 
} 

Все это здорово, но я хочу, чтобы преобразовать свою математику, так что я могу применить импульс. Вместо того, чтобы установить совершенно новую скорость для объекта, я хочу «добавить» некоторую скорость к существующей скорости. Итак, полагая, что у меня есть текущая скорость, какая математика мне нужна, чтобы «добавить» скорость? Это по сути вопрос физики игры. Спасибо!

+0

Velocity является производной от пути по времени – ka2m

+0

ли вам на самом деле нужно, своего рода, " бросать "объекты? – JBL

+0

У меня есть функция рабочего броска. Мне просто нужно добавить импульс скорости, чтобы объект вроде бы «плавал» перед глазами игрока. – arao6

ответ

0

Очень простая реализация может быть такой:

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

скорость, ускорение и сила являются векторами. t, дельта и массовые скаляры.

Это работает достаточно хорошо для небольших и одинаково расположенных дельт. То, что вы по существу пытаетесь достичь, - это моделирование тел с использованием классической механики.

0

Импульс технически FΔt для константы F. Здесь мы могли бы предпочесть aΔt, потому что масса не имеет значения. Если вы хотите оживить импульс, вам нужно решить, каково должно быть изменение скорости и сколько времени потребуется. Он становится очень быстрым.

Чтобы быть честным, импульс - это не то, что нужно делать. Вместо этого было бы предпочтительнее установить постоянную величину pick_up_velocity (люди не стремятся забирать вещи с помощью импульса) и обновлять позицию каждый раз, когда объект поднимается до скорости. Y, пока он не достигнет правильного уровня:

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

И что касается плавания перед глазами игрока, установите какой-либо EyeMovementEvent, который также отправляет правильное изменение положения любому лицу, которое удерживает игрок.

И если я что-то пропустил, и это то, что вы уже делаете, помните, что когда люди применяют импульс, это действительно очень быстрое ускорение на очень короткое время, гораздо меньше, чем у кадра. В любом случае вы не увидите его в игре.

0

основные физика ньютоновского/Даламбер диктует:

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. вождения объектов осуществляется только изменением a
    5. в случае столкновения зеркала v вектора столкновения normal

    и, возможно, умножить на некоторый k<1.0 (0.95, например) для учета потерь энергии при ударе

Вы можете добавить тяжести или любое другое силовое поле, добавляя g вектор:

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) вокруг центра масс