Все мы видели как камера плавно перелетает с места на место в различных играх. Попробуем повторить хотя бы минимум этого функционала, а именно: ограничим скорость полета камеры и дистанции текущей позиции камеры до вычисленной (чтобы камера не опаздывала за быстрым перемещением персонажа).
Итак, обозначения:
- currCameraPos — текущая позиция камеры
- nextCameraPos — будущая позиция камеры (например на n метров позади объекта наблюдения)
- speed — скорость камеры в м/с
- maxDist — максимально допустимая дистанция между currCameraPos и nextCameraPos
Алгоритм:
- вычисляем направление и длину от текущей до будущей позиций камеры
- корректируем длину в зависимости от speed и maxDist
- смещаем камеру из текущей в будущую позицию камеры с учетом длины
А вот, собственно, код этого безобразия:
void updateCameraPosition( float dt )
{
// Скорость камеры в метрах в секунду
const float speed = 0.5f;
// Максимальная дистанция от текущей позиции камеры до будущей
const float maxDist = 1.0f;
// Текущая позиция камеры
const Ogre::Vector3 currCameraPos = camera->getPosition();
// Будущая позиция камеры
const Ogre::Vector3 nextCameraPos = calculateCameraPosition();
// Направление от текущей позиции камеры до будущей
Ogre::Vector3 direction = nextCameraPos - currCameraPos;
// Длина смещения камеры
float dist = direction.length();
// Нормализуем направление
direction.normalise();
// Проверим дистанцию
if (dist > maxDist)
{
camera->setPosition(nextCameraPos - direction * maxDist);
}
// Иначе применим скорость
else
{
// Ограничим максимальное смещение,
// чтобы не улететь дальше nextCameraPos;
const float realSpeed = Ogre::Math::Clamp(dt * speed, 0.0f, dist);
camera->setPosition(currCameraPos + direction * realSpeed);
}
}
Примечание для специалистов: да, я в курсе, что в играх применяется более плавное движение камеры с учетом инерции. Об этом как-нибудь в другой раз.