Все мы видели как камера плавно перелетает с места на место в различных играх. Попробуем повторить хотя бы минимум этого функционала, а именно: ограничим скорость полета камеры и дистанции текущей позиции камеры до вычисленной (чтобы камера не опаздывала за быстрым перемещением персонажа).
Итак, обозначения:
- 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); } } |
Примечание для специалистов: да, я в курсе, что в играх применяется более плавное движение камеры с учетом инерции. Об этом как-нибудь в другой раз.