netlib.narod.ru< Назад | Оглавление | Далее >

Самостоятельно движущиеся объекты

Контроллер полета способен привести объект в движение, однако все равно вам приходится непрерывно управлять его перемещением. Лично я не люблю подолгу сидеть за рулем, поэтому разработал несколько примеров того, как заставить объекты самостоятельно двигаться по фиксированной траектории.

Первый пример, находящийся в каталоге Cruise, приводит в движение камеру, чтобы создать иллюзию кругового полета на самолете вокруг горы. На рис. 6.6 изображен внешний вид экрана приложения.


Рис. 6.6. Полет над холмами

Рис. 6.6. Полет над холмами


Перед тем как писать это приложение, я нарисовал план местности на миллиметровке, обозначив на нем границы всех холмов. Затем я вручную закодировал все вершины и данные граней для создания ландшафта. Не стану приводить здесь фрагмент исходного текста, поскольку он состоит лишь из длинного массива вершин, за которыми следует не менее длинный список данных граней. При желании можете найти его в файле MainFrm.cpp в каталоге Cruise.

Кроме того, я вручную изобразил небольшой самолет и наложил на ландшафт текстуру, чтобы придать ему более привлекательный вид (создание и применение текстур рассмотрено в главе 8). Последним этапом в создании макета стала установка камеры в начальной позиции и увеличение ее обзорного поля для получения более широкой панорамы:

    BOOL CMainFrame::SetScene()
    {
        .
        .
        .
        // Задать траекторию полета камеры
        m_vCamera = C3dVector(5, 5, 0);
        m_dRadius = 5.0; 

        // Задать обзорное поле
        m_pScene->SetCameraField(1.5);
        .
        .
        .
    }

Траектория выбирается таким образом, чтобы камера вращалась вокруг заданной точки. На рис. 6.7 изображено движение камеры в нашем макете.


Рис. 6.7. Траектория полета камеры

Рис. 6.7. Траектория полета камеры


Все, что осталось сделать, — организовать совместное перемещение камеры и самолета при каждой итерации:

    BOOL CMainFrame::Update(double d)
    {
        // Обновить положение камеры
        C3dMatrix r;
        r.Rotate(0, 2.0, 0);
        m_vCamera = r * m_vCamera;
        m_pScene->SetCameraPosition(m_vCamera);

        // Задать верхний вектор
        C3dVector vu(0, 1, 0);

        // Построить вектор направления
        C3dVector vf = m_vCamera * vu;
        m_pScene->SetCameraDirection(vf, vu);

        // Задать положение самолета относительно камеры
        r.Rotate(0, 20, 0);
        C3dVector vp = r * m_vCamera;
        m_pPlane->SetPosition(vp);

        // Задать направление
        C3dMatrix rp;
        rp.Rotate(0, 0, 10); // Слегка покачаем крыльями!
        vu = rp * vu;
        vf = vp * vu;
        m_pPlane->SetDirection(vf, vu);

        return m_wnd3d.Update(TRUE);
    }

Текущее положение камеры хранится в объекте C3dVector. Для определения ее нового положения вектор умножается на матрицу поворота. Затем камера переносится на новое место — но это еще не все. Необходимо изменить ориентацию камеры, чтобы она по-прежнему была направлена по касательной к окружности. Чтобы вычислить новое направление камеры, мы умножаем (векторно) верхний вектор (vu) на вектор положения камеры (m_vCamera). Вектор-результат совпадает с вектором направления камеры (рис. 6.8).


Рис. 6.8. Вычисление вектора направления камеры

Рис. 6.8. Вычисление вектора направления камеры


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

Последнее, что осталось сделать, — вычислить положение и направление маленького самолета, летящего перед камерой. Самолет перемещается по той же траектории, что и камера, однако он на несколько градусов опережает камеру. Чтобы определить положение самолета, мы берем вектор положения камеры и поворачиваем его чуть дальше, пользуясь для этого другой матрицей (r). При определении ориентации самолета я сначала вычислял векторное произведение точно так же, как и для камеры. Однако мне показалось, что смотреть на самолет, который идеально ровно летит впереди камеры, довольно скучно. Я слегка повернул вектор вверх, чтобы создать иллюзию покачивания самолета. Эффект не очень впечатляющий, но зато легко реализуемый.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz