zuze
Опытный
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;
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #61 : 04-07-2009 01:03 » |
|
видимо, она то же самое и делает
кстати, у тебя вектор right лишний ) Он откуда взялся ?
|
|
|
Записан
|
|
|
|
zuze
Опытный
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);
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Опытный
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, ¢er, &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 В местоСделалif (TheCamera.TestObject(pMesh)) { Matrix(); DrawMyMesh(); }
А в результате у меня даже mesh не отображается, что я сделал не так помогите разобраться?В архиве полный код
|
|
|
Записан
|
|
|
|
zuze
Опытный
Offline
Пол:
Россия, Москва
|
|
« Ответ #65 : 04-07-2009 21:55 » |
|
А на счёт камеры эту теорию я взял из книги "Графика в формате DirectX. Полное руководство по использованию 3D-пространства" автор Ален Торн.
Картинка камеры из "Ответ #62" была со сканирована из этой книги.
Неужели этот автор ошибся?
Врятли автор ошибся скорее всего мы ещё что то не понимаем, хотя всё может быть.
|
|
« Последнее редактирование: 04-07-2009 23:24 от zuze »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Опытный
Offline
Пол:
Россия, Москва
|
|
« Ответ #67 : 05-07-2009 10:17 » |
|
В книге Френка Луна тоже говорится о правом векторе.
Новый ортогональный верхний вектор вычисляется по формуле up = look × right. Затем вычисляется новый ортогональный правый вектор по формуле right = up × look.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Опытный
Offline
Пол:
Россия, Москва
|
|
« Ответ #69 : 05-07-2009 23:31 » |
|
Вот что мне посоветовали по поводу viewing frustum:
1. Функция TestObject не нужно вычислять каждый раз, а только при реальном изменении геометрии, в моём случае скорее всего при загрузке;
2. Функция CreatePyramid нужно вызывать, только при любом изменении состояния камеры;
3. Параметр D3DXVECTOR3 center в функции TestObject хранит геометрический центр в локальных координатах объекта, а нужно его получить в мировых координатах, для этого его нужно домножить на мировую матрицу этого объекта.
Если есть идеи как это реализовать поделись ими, а у меня сегодня весь день бошка раскалывается, да и щас не на много лучше, надеюсь завтра я буду себя чувствовать хорошо и продолжу делать дальше.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Опытный
Offline
Пол:
Россия, Москва
|
|
« Ответ #71 : 06-07-2009 23:17 » |
|
А как же мне быть?
У меня на промежуточном векторе _right завязаны методы (функции) LeftRight, RollRightVector, RollUpVector, RollFirstVector, getViewMatrix, getRight.
Кажись мне придётся переписывать эти методы (функции) без промежуточного вектора, это жестоко, но кажись иначе ни как(((.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Опытный
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);
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Опытный
Offline
Пол:
Россия, Москва
|
|
« Ответ #75 : 07-07-2009 08:57 » |
|
А что мне тогда делать с вектором _pos?
У меня на векторе _pos завязаны методы (функции): getViewMatrix, LeftRight, UpDown, FirstBack.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #76 : 07-07-2009 09:15 » |
|
pos - это вектор положения камеры в пространстве pos(x,z,y) -------------- а вообще, я же просто свои мысли говорю, как я делаю. Никто тебя не заставляет так же делать
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #77 : 07-07-2009 09:22 » |
|
интер тупит, не могу пост подправить:
покажи код этих функций
|
|
|
Записан
|
|
|
|
zuze
Опытный
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; }
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #79 : 07-07-2009 09:54 » |
|
только быстро не напишу )
|
|
|
Записан
|
|
|
|
zuze
Опытный
Offline
Пол:
Россия, Москва
|
|
« Ответ #80 : 07-07-2009 09:58 » |
|
А, к стати мы с тобой решили что матрицы вида и проекции лучше вставить в класс, а не писать в основной программе, это делаеться отдельной функцией или добавляется код в функцию getViewMatrix?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Опытный
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; }
Они я тоже думаю нужны в работе класса, но так как они не зависят от других методов, то их можно не трогать.
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #83 : 08-07-2009 03:18 » |
|
ещё чуток не дописал, ребёнок не позволил )))
По ходу дела выяснил особенность функции D3DVec3Cross - она возвращает (V2 x V1) , а не (V1 x V2).
Наскоько помню, при векторном умножении действует "правило правого буравчика" , то есть если первый перемножаемый вектор поворачивать ко второму, то направление движения "буравчика" при этом укажет направление результирующего вектора. А функция возвращает с обратным знаком
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #84 : 08-07-2009 04:58 » |
|
вкрался вопрос - а нафига камере быть наземной или воздушной ? ) Это свойство объекта-юнита, а не камеры. Поэтому тип камеры тут не нужен
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
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
Опытный
Offline
Пол:
Россия, Москва
|
|
« Ответ #86 : 10-07-2009 23:12 » |
|
Решил небольшую паузу сделать в изучении, так как маму встречаю из отпуска и надо привести квартиру в пожеский вид, а затем я сразу буду осмысливать код.
Спасибо за код Алексей1153++.
|
|
|
Записан
|
|
|
|
zuze
Опытный
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 пункт буду делать не скоро, так как у меня тормозятся другие темы, а по мере надобности я к нему вернусь.
|
|
« Последнее редактирование: 11-07-2009 03:18 от zuze »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #88 : 11-07-2009 05:24 » |
|
1 пункт я сделал, смотреть функцию getViewMatrix, она теперь выглядит иначе, хотел спросить я правильно переделал эту функцию?
2 пункт мне он вроде не нужен так как я не использую эти вектора, хотя ты говоришь может быть проблема с векторами, так что тут надо сделать пример что бы это проверить, но вопрос какой?
3 пункт начну заново думать о нём, когда точно буду уверен, что первые два пункта у меня правильно сделаны.
4 пункт буду делать не скоро, так как у меня тормозятся другие темы, а по мере надобности я к нему вернусь.
1 - как сделать тест я уже писал - расставить вертиксы-точки в углах призмы и "увидеть" их ) 2 - это же не вектора, а необходимые для построения призмы параметры
|
|
|
Записан
|
|
|
|
zuze
Опытный
Offline
Пол:
Россия, Москва
|
|
« Ответ #89 : 11-07-2009 05:44 » |
|
Получается нельзя проверить сбиваються ли вектора не построив View Frustum Culling и не сделав ещё вертиксы-точки в углах призмы и "увидеть" их?
|
|
|
Записан
|
|
|
|
|