Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [3] 4 5   Вниз
  Печать  
Автор Тема: Создать камеру в DirectX 9  (Прочитано 123356 раз)
0 Пользователей и 1 Гость смотрят эту тему.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #60 : 04-07-2009 00:52 » 

Неужели функция D3DXMatrixLookAtLH заменяет следующие строчки?

Код:
     // Строим матрицу вида:
     float x = -D3DXVec3Dot(&_right, &_pos);
     float y = -D3DXVec3Dot(&_up, &_pos);
     float z = -D3DXVec3Dot(&_look, &_pos);

     (*V)(0, 0) = _right.x;
     (*V)(0, 1) = _up.x;
     (*V)(0, 2) = _look.x;
     (*V)(0, 3) = 0.0f;

     (*V)(1, 0) = _right.y;
     (*V)(1, 1) = _up.y;
     (*V)(1, 2) = _look.y;
     (*V)(1, 3) = 0.0f;

     (*V)(2, 0) = _right.z;
     (*V)(2, 1) = _up.z;
     (*V)(2, 2) = _look.z;
     (*V)(2, 3) = 0.0f;

     (*V)(3, 0) = x;
     (*V)(3, 1) = y;
     (*V)(3, 2) = z;
     (*V)(3, 3) = 1.0f;
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #61 : 04-07-2009 01:03 » 

видимо, она то же самое и делает

кстати, у тебя вектор right лишний ) Он откуда взялся ?
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #62 : 04-07-2009 12:00 » 

У меня вектор _right взялся из-за того что камера задаётся тремя векторами:

1. Первая стрелка, называемая направлением или вектором взгляда;
2. Вторая стрелка показывает направление взгляда в право и называется правым вектором;
3. Третья стрелка показывает направление взгляда вниз и называется верхнем вектором;
4. Начало координат, т.е. где пересекаются все вектора – это положение камеры в трёхмерном пространстве.

Вот картинка:



Я хотел спросить у меня вот эти функции не получаются перегружаемыми, я понял так как у них параметры одинаковое количество и имеют одинаковые типы, а можно в одном из этих двух функций заменить тип на double у последнего параметра, не повлияет ли это на ход работы?

Код:
// Тест куба
bool TestObject(float xcenter, float ycenter, float zcenter, float size);
// Тест сферы
bool TestObject(float xcenter, float ycenter, float zcenter, float radius);
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #63 : 04-07-2009 15:38 » 

что то ты путаешь, даже в параметрах функции написано:
Код:
D3DXMATRIX * D3DXMatrixLookAtLH(
  D3DXMATRIX *pOut,
  CONST D3DXVECTOR3 *pEye,
  CONST D3DXVECTOR3 *pAt,
  CONST D3DXVECTOR3 *pUp
);
eye - наш глаз (точка)
at - точка, куда смотрим
up - вектор для определения верха камеры.

больше ничего не требуется для задания положения камеры. То есть всего два вектора Улыбаюсь


про функции, выхода , по крайней мере, два:

1) виртуальная функция TestObject родительского класса, общего для классов куба и сферы
2)

// Тест куба
bool TestObject(DWORD dwdType,float xcenter, float ycenter, float zcenter, float size);
// Тест сферы
bool TestObject(DWORD dwdType,float xcenter, float ycenter, float zcenter, float radius);
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #64 : 04-07-2009 21:38 » 

Вот я попытался сделать viewing frustum.

Я в класс камеры добавил:

В области private: класса

Код:
D3DXPLANE mPlanes[6];  // Массив плоскастей для усечённой пирамиды

В конструкторах класса

Код:
// Инициализация массива структур
for (int i = 0; i < 6; i++)
{
        mPlanes[i].a = 0.0f;
        mPlanes[i].b = 0.0f;
        mPlanes[i].c = 0.0f;
        mPlanes[i].d = 0.0f;
}

Написал дополнительные методы (функции) в классе

Код:
// Создание усечённой пирамиды
void Camera::CreatePyramid(D3DXMATRIX MV, D3DXMATRIX MP)
{
        D3DXMATRIX Matrix;
        D3DXMatrixMultiply(&Matrix, &MV, &MP);

        // Левая плоскость
        mPlanes[0].a = Matrix._14 + Matrix._13;
        mPlanes[0].b = Matrix._24 + Matrix._23;
        mPlanes[0].c = Matrix._34 + Matrix._33;
        mPlanes[0].d = Matrix._44 + Matrix._43;

        // Правая плоскость
        mPlanes[1].a = Matrix._14 - Matrix._13;
        mPlanes[1].b = Matrix._24 - Matrix._23;
        mPlanes[1].c = Matrix._34 - Matrix._33;
        mPlanes[1].d = Matrix._44 - Matrix._43;
                           
        // Верхняя плоскость
        mPlanes[2].a = Matrix._14 + Matrix._11;
        mPlanes[2].b = Matrix._24 + Matrix._21;
        mPlanes[2].c = Matrix._34 + Matrix._31;
        mPlanes[2].d = Matrix._44 + Matrix._41;

        // Нижняя плоскость
        mPlanes[3].a = Matrix._14 - Matrix._11;
        mPlanes[3].b = Matrix._24 - Matrix._21;
        mPlanes[3].c = Matrix._34 - Matrix._31;
        mPlanes[3].d = Matrix._44 - Matrix._41;
       
        // Ближняя плоскость
        mPlanes[4].a = Matrix._14 + Matrix._12;
        mPlanes[4].b = Matrix._24 + Matrix._22;
        mPlanes[4].c = Matrix._34 + Matrix._32;
        mPlanes[4].d = Matrix._44 + Matrix._42;
       
        // Дальняя плоскость
        mPlanes[5].a = Matrix._14 - Matrix._12;
        mPlanes[5].b = Matrix._24 - Matrix._22;
        mPlanes[5].c = Matrix._34 - Matrix._32;
        mPlanes[5].d = Matrix._44 - Matrix._42;

        // Нормализация плоскостей
        for (int i = 0; i < 6; i++)
             D3DXPlaneNormalize(&mPlanes[i], &mPlanes[i]);
}

// Тестирование точки
bool Camera::TestObject(float xpos, float ypos, float zpos)
{
        for (int i = 0; i < 6; i++)
        {
            if (D3DXPlaneDotCoord(&mPlanes[i], &D3DXVECTOR3(xpos, ypos, zpos)) < 0.0f)
   return false;
        }
        return true;
}

// Тестирование куба
bool Camera::TestObject(float xcenter, float ycenter, float zcenter, float size)
{
        for (int i = 0; i < 6; i++)
        {
            if (D3DXPlaneDotCoord(&mPlanes[i], &D3DXVECTOR3(xcenter - size, ycenter - size, zcenter - size)) >= 0.0f)
{
               if (D3DXPlaneDotCoord(&mPlanes[i], &D3DXVECTOR3(xcenter + size, ycenter - size, zcenter - size)) >= 0.0f)
   {
      if (D3DXPlaneDotCoord(&mPlanes[i], &D3DXVECTOR3(xcenter - size, ycenter + size, zcenter - size)) >= 0.0f)
      {
         if (D3DXPlaneDotCoord(&mPlanes[i], &D3DXVECTOR3(xcenter + size, ycenter + size, zcenter - size)) >= 0.0f)
         {
if (D3DXPlaneDotCoord(&mPlanes[i], &D3DXVECTOR3(xcenter - size, ycenter - size, zcenter + size)) >= 0.0f)
{
   if (D3DXPlaneDotCoord(&mPlanes[i], &D3DXVECTOR3(xcenter + size, ycenter - size, zcenter + size)) >= 0.0f)
   {
      if (D3DXPlaneDotCoord(&mPlanes[i], &D3DXVECTOR3(xcenter - size, ycenter + size, zcenter + size)) >= 0.0f)
      {
         if (D3DXPlaneDotCoord(&mPlanes[i], &D3DXVECTOR3(xcenter + size, ycenter + size, zcenter + size)) >= 0.0f)
            return false;
      }
  }
}
       }
    }
}
       }
   }
   return true;
}


// Тестирование сферы
bool Camera::TestObject(float xcenter, float ycenter, float zcenter, double radius)
{
        for (int i = 0; i < 6; i++)
        {
            if (D3DXPlaneDotCoord(&mPlanes[i], &D3DXVECTOR3(xcenter, ycenter, zcenter)) < -radius)
  return false;
        }
        return true;
}

// Тестирование меши
bool Camera::TestObject(LPD3DXBASEMESH pMesh)
{
        if (pMesh)
        {
            DWORD NumVertices = pMesh->GetNumVertices();
            DWORD FVF = pMesh->GetFVF();
UINT FVFSize = D3DXGetFVFVertexSize(FVF);
LPVOID ppData = NULL;
pMesh->LockVertexBuffer(D3DLOCK_READONLY, &ppData);
if (ppData)
{
               D3DXVECTOR3 center(0.0f, 0.0f, 0.0f);
   float radius = 0.0f;

   D3DXComputeBoundingSphere((D3DXVECTOR3 *) ppData, NumVertices, FVFSize, &center, &radius);

   if (TestObject(center.x, center.y, center.z, radius))
   {
                   pMesh->UnlockVertexBuffer();
       return true;
   }
}
pMesh->UnlockVertexBuffer();
       }
       return false;
}

В основной программе в конце функции Matrix - Установка матриц преобоазования, добавил строчку кода

Код:
TheCamera.CreatePyramid(MatrixView, MatrixProjection);

В основной программе в функции RenderingDirect3D(void) - рендеринг Direct3D

В место

Код:
Matrix();
DrawMyMesh();

Сделал

Код:
if (TheCamera.TestObject(pMesh))
{
   Matrix();
   DrawMyMesh();
}

А в результате у меня даже mesh не отображается, что я сделал не так помогите разобраться?


В архиве полный код

* loadxfileCamera_viewing_frustum.rar (43.9 Кб - загружено 915 раз.)
Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #65 : 04-07-2009 21:55 » 

А на счёт камеры эту теорию я взял из книги "Графика в формате DirectX. Полное руководство по использованию 3D-пространства" автор Ален Торн.

Картинка камеры из "Ответ #62" была со сканирована из этой книги.

Неужели этот автор ошибся?

Врятли автор ошибся скорее всего мы ещё что то не понимаем, хотя всё может быть.
« Последнее редактирование: 04-07-2009 23:24 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #66 : 05-07-2009 02:57 » 

Код:
// Инициализация массива структур
for (int i = 0; i < 6; i++)
{
        mPlanes[i].a = 0.0f;
        mPlanes[i].b = 0.0f;
        mPlanes[i].c = 0.0f;
        mPlanes[i].d = 0.0f;
}

я бы оптимизировал (поскольку 0.0f в памяти имеет вид 0x00000000)
Код:
// Обнуление массива
::memset((void*)mPlanes,0,sizeof(mPlanes));

цифру 6 - законстантить
Код:
//В области private: класса
enum{e_PanezCount=6};

насчёт содержимого CreatePyramid() не вникал, там одна математика, которую надо на бумажке расписать, чтоб понять ))

Тестирование я бы начал всё с той же бумажки: чертим призму и расставляем котрольные точки  - в вершинах призмы (для устранения влияния погрешностей - чуток сдвинуть внутрь призмы)

Задаём , 8 вертексов, скажем, белого цвета, и на чёрном фоне отрисовываем как D3DPT_POINTLIST по очереди. Эти точки должны быть видны в углах сцены.

Про камеру: нашёл эту картинку, я тоже по этой книге иду) Я до этого места ещё не скоро доберусь.
Вектор "вправо" имхо не нужен , тут он используется для действия Pitch (поворот вверх-вниз). Получить вектор его всегда можно через векторное произведение Look X Up
(Cross Product) для этого есть функция D3DXVec3Cross()

В общем, дойду до этого места - уточню ))
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #67 : 05-07-2009 10:17 » 

В книге Френка Луна тоже говорится о правом векторе.

Новый ортогональный верхний вектор вычисляется по формуле up = look × right.
Затем вычисляется новый ортогональный правый вектор по формуле right = up × look.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #68 : 05-07-2009 10:44 » 

да я верю )

в моём понимании истинно следующее:

 right = look x up
 up = right x look

Как бы то ни было, right - это вспомогательный, промежуточный вектор в вычислениях. Либо таким можно считать up. , а основным будет right

« Последнее редактирование: 05-07-2009 10:48 от Алексей1153++ » Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #69 : 05-07-2009 23:31 » 

Вот что мне посоветовали по поводу viewing frustum:

1. Функция TestObject не нужно вычислять каждый раз, а только при реальном изменении геометрии, в моём случае скорее
всего при загрузке;

2. Функция CreatePyramid нужно вызывать, только при любом изменении состояния камеры;

3. Параметр D3DXVECTOR3 center в функции TestObject хранит геометрический центр в локальных координатах объекта, а нужно его
получить в мировых координатах, для этого его нужно домножить на мировую матрицу этого объекта.

Если есть идеи как это реализовать поделись ими, а у меня сегодня весь день бошка раскалывается, да и щас не на много лучше, надеюсь завтра я буду себя чувствовать хорошо и продолжу делать дальше.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #70 : 06-07-2009 03:13 » 

1 -  Вычислить геометрию призмы нужно 1 раз , если не меняются параметры камеры, такие как Znear, Zfar, aspect и fovy. Но смысла в этом нету, так как камера поворачивается, и готовую призму всё равно придётся вращать. А вычислений там - кот наплакал.

Тест объектов нужно проводить каждый кадр, так как запоминание того, что ничего не двигалось, сожрёт больше ресурсов, чем тест в каждый рендер Улыбаюсь

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

2 - уже написал, в начале каждого кадра

3 - возьми за начало координат положение камеры, да и всё. И вычисления упростятся

---------------------

насчёт содержимого камеры, я тут поразмыслил, выходит так, что нам нужны только:
позиция x,y,z
наклоны ax,ay,az

никаких векторов, тем более зависящих друг от друга. Иначе накопится ошибка и однажды Look будет не перпендикулярен Up Улыбаюсь)

Исходным положением камеры считать
eye =0,0,0
lookat=0,0,1
up=0,1,0

на эти орты накатывать текущие параметры - повернуть вокруг осей, потом перенести в текущую позицию. И работать с временными векторами
« Последнее редактирование: 06-07-2009 03:15 от Алексей1153++ » Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #71 : 06-07-2009 23:17 » 

А как же мне быть?

У меня на промежуточном векторе _right завязаны методы (функции) LeftRight, RollRightVector, RollUpVector, RollFirstVector, getViewMatrix, getRight.

Кажись мне придётся переписывать эти методы (функции) без промежуточного вектора, это жестоко, но кажись иначе ни как(((.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #72 : 07-07-2009 00:48 » 

1) right = lookat x up = (1,0,0)
2) right+=pos
3) поворот right вокруг x + поворот right вокруг z

right готов к употреблению Улыбаюсь
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #73 : 07-07-2009 08:16 » 

А разве мне всё это делать надо для вектора _right?

В теории сказано что после нескольких поворотов из-за погрешности округления в операциях с плавающей точкой оси камеры могут стать неортогональными.


Поэтому каждый раз при вызове функции getViewMatrix заново вычисляется верхний и правый вектор на основании вектора взгляда, чтобы гарантировать, что все три вектора будут ортогональными.

Код:
// Делаем оси камеры ортогональными
D3DXVec3Normalize(&_look, &_look);

D3DXVec3Cross(&_up, &_look, &_right);
D3DXVec3Normalize(&_up, &_up);

D3DXVec3Cross(&_right, &_up, &_look);
D3DXVec3Normalize(&_right, &_right);
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #74 : 07-07-2009 08:47 » 

да не будет никакой погрешности: вектора ВСЕГДА равны

look=0,0,1
up=0,1,0
right=1,0,0

позиция x,y,z камеры задаётся именно так - координатами
наклоны ax,ay,az - тоже просто заданы радианами

когда нужно применить вектора камеры, быстренько вычисляем

Код:
D3DXVECTOR look(0+x,0+y,1+z);
D3DXVECTOR up=(0+x,1+y,0+z);
D3DXVECTOR right=(1+x,0+y,0+z);

//затем делаем поворот ax для векторов look и up вокруг оси X
//... не помню, есть ли готовые функции

//затем делаем поворот ay для векторов look и right вокруг оси Y

//затем делаем поворот az для векторов right и up вокруг оси Z

(только не тестировал)

или ещё так
Код:
D3DXVECTOR look(0+x,0+y,1+z);
D3DXVECTOR up=(0+x,1+y,0+z);
D3DXVECTOR right;

//затем делаем поворот ax для векторов look и up вокруг оси X
//...

//затем делаем поворот ay для вектора look вокруг оси Y
//...

//затем делаем поворот az для вектора up вокруг оси Z
//...

//затем вычисляем вектор right
D3DXVec3Cross(&right, &look, &up);//порядок имеено такой - look x up !!!


а нормализацию зачем делаешь ? По моему, величина модуля вектора здесь роли не играет
а может я неправильно помню, что такое нормализация ))) (я понимаю так, что это приведение модуля к 1)
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #75 : 07-07-2009 08:57 » 

А что мне тогда делать с вектором _pos?

У меня на векторе _pos завязаны методы (функции): getViewMatrix, LeftRight, UpDown, FirstBack.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #76 : 07-07-2009 09:15 » 

pos - это вектор положения камеры в пространстве

pos(x,z,y)

--------------
а вообще, я же просто свои мысли говорю, как я делаю. Никто тебя не заставляет так же делать Улыбаюсь
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #77 : 07-07-2009 09:22 » 

интер тупит, не могу пост подправить:

покажи код этих функций
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #78 : 07-07-2009 09:32 » 

Методы (Функции) зависящие от вектора _right

Код:
// влево/вправо
void Camera::LeftRight(float units)
{
     // Для наземных объектов перемещение только в плоскости xz
     if(_cameraType == LANDOBJECT)
          _pos += D3DXVECTOR3(_right.x, 0.0f, _right.z) * units;

     if(_cameraType == AIRCRAFT)
          _pos += _right * units;
}

// вращение относительно правого вектора
void Camera::RollRightVector(float angle)
{
     D3DXMATRIX T;
     D3DXMatrixRotationAxis(&T, &_right, angle);

     // Поворот векторов _up и _look относительно вектора _right
     D3DXVec3TransformCoord(&_up,&_up, &T);
     D3DXVec3TransformCoord(&_look,&_look, &T);
}

// вращение относительно верхнего вектора
void Camera::RollUpVector(float angle)
{
     D3DXMATRIX T;

     // Для наземных объектов выполняем вращение
     // вокруг мировой оси Y (0, 1, 0)
     if(_cameraType == LANDOBJECT)
          D3DXMatrixRotationY(&T, angle);

     // Для летающих объектов выполняем вращение
     // относительно верхнего вектора
     if(_cameraType == AIRCRAFT)
          D3DXMatrixRotationAxis(&T, &_up, angle);

     // Поворот векторов _right и _look относительно
     // вектора _up или оси Y
     D3DXVec3TransformCoord(&_right, &_right, &T);
     D3DXVec3TransformCoord(&_look, &_look, &T);
}

// вращение относительно вектора взгляда
void Camera::RollFirstVector(float angle)
{
     // Вращение только для летающих объектов
     if(_cameraType == AIRCRAFT)
     {
          D3DXMATRIX T;
          D3DXMatrixRotationAxis(&T, &_look, angle);

          // Поворот векторов _up и _right относительно
          // вектора _look
          D3DXVec3TransformCoord(&_right, &_right, &T);
          D3DXVec3TransformCoord(&_up, &_up, &T);
     }
}

// Получение координат правого вектора
void Camera::getRight(D3DXVECTOR3 *right)
{
*right = _right;
}

Методы (Функции) зависящие от вектора _pos

Код:
// вверх/вниз
void Camera::UpDown(float units)
{
     if(_cameraType == AIRCRAFT)
          _pos += _up * units;
}

// вперед/назад
void Camera::FirstBack(float units)
{
     // Для наземных объектов перемещение только в плоскости xz
     if(_cameraType == LANDOBJECT)
          _pos += D3DXVECTOR3(_look.x, 0.0f, _look.z) * units;

     if(_cameraType == AIRCRAFT)
          _pos += _look * units;
}

// Получение координат вектора нахождения камеры
void Camera::getPosition(D3DXVECTOR3 *pos)
{
*pos = _pos;
}

// Установка камеры в требуемом месте и на требуемой высоте
void Camera::setPosition(D3DXVECTOR3 *pos)
{
_pos = *pos;
}

Методы (Функции) зависящие от векторов _right и _pos

Код:
// Вычисление матрицы вида, на основании заданных векторов камеры
void Camera::getViewMatrix(D3DXMATRIX *V)
{
     // Делаем оси камеры ортогональными
     D3DXVec3Normalize(&_look, &_look);

     D3DXVec3Cross(&_up, &_look, &_right);
     D3DXVec3Normalize(&_up, &_up);

     D3DXVec3Cross(&_right, &_up, &_look);
     D3DXVec3Normalize(&_right, &_right);

     // Строим матрицу вида:
     float x = -D3DXVec3Dot(&_right, &_pos);
     float y = -D3DXVec3Dot(&_up, &_pos);
     float z = -D3DXVec3Dot(&_look, &_pos);

     (*V)(0, 0) = _right.x;
     (*V)(0, 1) = _up.x;
     (*V)(0, 2) = _look.x;
     (*V)(0, 3) = 0.0f;

     (*V)(1, 0) = _right.y;
     (*V)(1, 1) = _up.y;
     (*V)(1, 2) = _look.y;
     (*V)(1, 3) = 0.0f;

     (*V)(2, 0) = _right.z;
     (*V)(2, 1) = _up.z;
     (*V)(2, 2) = _look.z;
     (*V)(2, 3) = 0.0f;

     (*V)(3, 0) = x;
     (*V)(3, 1) = y;
     (*V)(3, 2) = z;
     (*V)(3, 3) = 1.0f;
}


Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #79 : 07-07-2009 09:54 » 

только быстро не напишу )
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #80 : 07-07-2009 09:58 » 

А, к стати мы  с тобой решили что матрицы вида и проекции лучше вставить в класс, а не писать в основной программе, это делаеться отдельной функцией или добавляется код в функцию getViewMatrix?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #81 : 07-07-2009 10:13 » 

значит, прототип (сделан по списку твоих методов. Ещё добавлю, я думаю, методы)
Код:
class Camera
{

D3DXVECTOR3 m_pos;//радиус-вектор положения в пространстве

//все знаги углов - по правилу правого буравчика
float m_ax;//-pi/2 ... +pi/2   //-вниз +вверх (вокруг оси X)
float m_ay;//-pi ... +pi   //-вправо +влево (вокруг оси Y)
float m_az;//-pi ... +pi   //наклон -влево +вправо (вокруг Z)

enum ee_type
{
e_LANDOBJECT,
e_AIRCRAFT
};

ee_type m_Type;

public:

Camera():
  m_pos(D3DXVECTOR3(0,0,0)),
  m_ax(0),
  m_ay(0),
  m_az(0),
  m_Type(e_AIRCRAFT)
{
}

void Camera::LeftRight(float units);

void Camera::RollRightVector(float angle);

void Camera::RollUpVector(float angle);

void Camera::RollFirstVector(float angle);

void Camera::getRight(D3DXVECTOR3 *right);

void Camera::UpDown(float units);

void Camera::FirstBack(float units);

void Camera::getPosition(D3DXVECTOR3 *pos);

void Camera::setPosition(D3DXVECTOR3 *pos);

void Camera::getViewMatrix(D3DXMATRIX *V);
};

матрицу вида и проекции никуда встраивать не будем, мы будем их считать ) Ещё дойдём до них
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #82 : 07-07-2009 10:43 » 

У меня есть ещё методы в классе которые не зависят от векторов _right и _pos

Код:
// Установка типа камеры
void Camera::setCameraType(CameraType cameraType)
{
_cameraType = cameraType;
}

// Получение координат верхнего вектора
void Camera::getUp(D3DXVECTOR3* up)
{
*up = _up;
}

// Получение координат вектора взгляда
void Camera::getLook(D3DXVECTOR3* look)
{
*look = _look;
}

Они я тоже думаю нужны в работе класса, но так как они не зависят от других методов, то их можно не трогать.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #83 : 08-07-2009 03:18 » 

ещё чуток не дописал, ребёнок не позволил )))

По ходу дела выяснил особенность функции D3DVec3Cross - она возвращает (V2 x V1) , а не (V1 x V2).

Наскоько помню, при векторном умножении действует "правило правого буравчика" , то есть если первый перемножаемый вектор поворачивать ко второму, то направление движения "буравчика" при этом укажет направление результирующего вектора. А функция возвращает с обратным знаком
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #84 : 08-07-2009 04:58 » 

вкрался вопрос - а нафига камере быть наземной или воздушной ? ) Это свойство объекта-юнита, а не камеры. Поэтому тип камеры тут не нужен
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #85 : 08-07-2009 05:50 » 

в общем, у меня вышло так
Код:
class Camera
{
D3DXVECTOR3 m_pos;//радиус-вектор положения в пространстве

//все знаги углов - по правилу правого буравчика
float m_ax;//-pi/2 ... +pi/2   //-вниз +вверх (вокруг оси X)
float m_ay;//-pi ... +pi   //-вправо +влево (вокруг оси Y)
float m_az;//-pi ... +pi   //наклон -влево +вправо (вокруг Z)

float m_zOfNearViewPlane;
float m_zOfFarViewPlane;
float m_fovy;

public:
enum ee_type
{
e_COMMON,
e_LANDOBJECT,
e_UNDERGROUND,
e_AIRCRAFT
};

private:
ee_type m_Type;

public:

Camera():
m_pos(D3DXVECTOR3(0,0,0)),
m_ax(0),
m_ay(0),
m_az(0),
m_Type(e_AIRCRAFT),
m_zOfNearViewPlane(0),
m_zOfFarViewPlane(500),
m_fovy(D3DX_PI/4)
{
}


private:
inline AddTo_m_ax(float toUp)
{
Set_m_ax(m_ax+toUp);
}

inline AddTo_m_ay(float toLeft)
{
Set_m_ay(m_ay+toLeft);
}

inline AddTo_m_az(float toRight)
{
Set_m_az(m_az+toRight);
}

public:

//надо тестировать!
inline Set_m_ax(float val)
{
//-pi/2 ... +pi/2
if(val>=0)
{
m_ax=min( D3DX_PI/2,val);
}
else
{
m_ax=max(-D3DX_PI/2,val);
}
}

//надо тестировать!
inline Set_m_ay(float val)
{
//-pi ... +pi
val-=((__int64)(((double)val)/(2*D3DX_PI)))*(2*D3DX_PI);
//detla=-2pi ... +2pi

m_ay=val;
//m_ay==-2.5pi ... +2.5pi

while(m_ay>D3DX_PI)
{
m_ay-=2*D3DX_PI;
}

while(m_ay<-D3DX_PI)
{
m_ay+=2*D3DX_PI;
}

//m_ay==-0.5pi ... +0.5pi
}

//надо тестировать!
inline Set_m_az(float val)
{
//-pi ... +pi
val-=((__int64)(((double)val)/(2*D3DX_PI)))*(2*D3DX_PI);
//detla=-2pi ... +2pi

m_az=val;
//m_az==-2.5pi ... +2.5pi

while(m_az>D3DX_PI)
{
m_az-=2*D3DX_PI;
}

while(m_az<-D3DX_PI)
{
m_az+=2*D3DX_PI;
}

//m_az==-0.5pi ... +0.5pi
}

inline D3DXMATRIX* GetXYZrotateMatrix(D3DXMATRIX* pMXYZ)const
{
D3DXMATRIX TX,TY,TZ;
D3DXVECTOR3 VX(1,0,0);
D3DXVECTOR3 VY(0,1,0);
D3DXVECTOR3 VZ(0,0,1);

::D3DXMatrixRotationAxis(&TX, &VX, m_ax);
::D3DXMatrixRotationAxis(&TY, &VY, m_ay);
::D3DXMatrixRotationAxis(&TZ, &VZ, m_az);

*pMXYZ=TX*TY*TZ;
return pMXYZ;
}

public:
//получить вектор Right
inline void GetRightVec(D3DXVECTOR3* pR)const
{
D3DXMATRIX MXYZ;
*pR=D3DXVECTOR3(1,0,0);
::D3DXVec3TransformCoord(pR, pR, GetXYZrotateMatrix(&MXYZ));
}

//получить вектор Up
inline void GetUpVec(D3DXVECTOR3* pU)const
{
D3DXMATRIX MXYZ;
*pU=D3DXVECTOR3(0,1,0);
::D3DXVec3TransformCoord(pU, pU, GetXYZrotateMatrix(&MXYZ));
}


//получить вектор Look
inline void GetLookVec(D3DXVECTOR3* pL)const
{
D3DXMATRIX MXYZ;
*pL=D3DXVECTOR3(0,0,1);
::D3DXVec3TransformCoord(pL, pL, GetXYZrotateMatrix(&MXYZ));
}

// Установка типа камеры
inline void SetCameraType(ee_type type)
{
m_Type=type;
}

void GetView(D3DXMATRIX* pvm)const
{
D3DXVECTOR3 up;
D3DXVECTOR3 look;
GetUpVec(&up);
GetLookVec(&look);

::D3DXMatrixLookAtLH(pvm, &m_pos, &look, &up);
}

void GetProjection(D3DXMATRIX* prm,FLOAT Aspect)
{
::D3DXMatrixPerspectiveFovLH(prm, m_fovy, Aspect, m_zOfNearViewPlane, m_zOfFarViewPlane);
}

// влево/вправо
void LeftRight(float units)
{
m_pos.x += units;
}

// вверх/вниз
void UpDown(float units)
{
m_pos.y += units;
}

// вперед/назад
void FirstBack(float units)
{
m_pos.z += units;
}

// вращение относительно правого вектора
void RollRightVector(float angle)
{
//сменить знак, если направление вращения не устраивает )
AddTo_m_ax(angle);
}

// вращение относительно верхнего вектора
void RollUpVector(float angle)
{
//сменить знак, если направление вращения не устраивает )
AddTo_m_ay(angle);
}

// вращение относительно вектора взгляда
void RollFirstVector(float angle)
{
//сменить знак, если направление вращения не устраивает )
AddTo_m_az(angle);
}

// Получение координат вектора нахождения камеры
void getPosition(D3DXVECTOR3 *pos)
{
*pos = m_pos;
}

// Установка камеры в требуемом месте и на требуемой высоте
void setPosition(D3DXVECTOR3 *pos)
{
m_pos = *pos;
}
};

методы для получения векторов тут есть - если что сможешь написать, что нужно )
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #86 : 10-07-2009 23:12 » 

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

Спасибо за код Алексей1153++.
Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #87 : 11-07-2009 03:11 » 

Всё таки я нашёл немного свободного времени и переделал функцию getViewMatrix.

Мы выяснили что мне в класс "камера" нужно добавить:

1. Хранить матрицу проекций и вида в самой камере (сделать в классе);
2. Хранить угол обзора, aspect, zNear, zFar с методами получения и установки данных параметров в самой камере (сделать в классе);
3. Сделать viewing frustum или Frustum c его пересчетом, ну и методы видимости бокса, сферы точки и т.д. с перегрузкой для объектов;
if (camera.IsVisible(boundingBox)) {
//
}
4. Работа камеры с треками движения, записанными в файл или еще куда-то.

Что я сделал и мои рассуждения с вопросами:

1 пункт я сделал, смотреть функцию getViewMatrix, она теперь выглядит иначе, хотел спросить я правильно переделал эту функцию?

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

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

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

* loadxfileCamera_Edit.rar (42.97 Кб - загружено 914 раз.)
« Последнее редактирование: 11-07-2009 03:18 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #88 : 11-07-2009 05:24 » 

1 пункт я сделал, смотреть функцию getViewMatrix, она теперь выглядит иначе, хотел спросить я правильно переделал эту функцию?

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

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

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

1 - как сделать тест я уже писал - расставить вертиксы-точки в углах призмы и "увидеть" их )
2 - это же не вектора, а необходимые для построения призмы параметры
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #89 : 11-07-2009 05:44 » 

Получается нельзя проверить сбиваються ли вектора не построив View Frustum Culling и не сделав ещё вертиксы-точки в углах призмы и "увидеть" их?
Записан
Страниц: 1 2 [3] 4 5   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines