Войти
ПрограммированиеФорумГрафика

DirectX 9.0 статические объекты относительно камеры[РЕШЕНО]

#0
19:43, 13 янв 2013

Приветствую, вопрос такой.

Есть некая 3d сцена. и есть камера, обращенная в центр сцены, при этом у камеры несколько степеней свободы.
Я хочу взять объект, и разместить его прямо перед камерой, так чтобы он всегда находился в одном и том же прямоугольнике экранных координат.

Есть три варианта реализации.

1) самый вкусный. Взять 3D модельку, из X файла например. Потом привести матрицу мира, в координаты матрицы вида, отодвинуть на какое-то расстояние. и отрендерить.
Проблема всего одна - митрица мира не хочет приводиться в координаты матрицы вида. Думаю она берет координаты, в которые "направлена" камера, а не кординаты где она расположенна,
и двигает объект относительно этих координат, в итоге при вращении камеры вокруг точки в которую она направлена - объект вращается вокруг своей оси, не перемещаясь.

Вопрос следующий, как перенести матрицу мира в координаты матрицы вида. Если

пробовал

WorldMatrix = WievMatrix;

и

 pDevice->SetTransform(D3DTS_WORLD, &WievMatrix);

есть ли какието стандартные функции для приведения, или надо выдумывать самому?

Очень хочется узнать как это сделать, так как в таком случае можно было бы делать очень много разных классных фишек.

2) Самый непонятный, выводить спрайтами, текстуры, но я плохо понимаю как с ними работать, и как выводить. Насколько я знаю спрайты это типо примитивы обращенные всегда видимой стороной к камере, но блин, опять же надо наверное привести мировую матрицу к матрице вида, и к тому же я не понимаю можно ли сделать этот спрайт величиной например 200 на 200 пикселей, и натянуть на него полноценную текстуру (картинку). и главное как?

3) Самый тормознутый вариант. Использовать стандартые функции GDI, тобишь после рендеринга, просто взять обычную картинку и поместить в окно, прямо поверх DirectX.
Или исхитриться, и с меньшим ущербом для быстродействия - инициировать месте с Direct3D - DiretDraw7 и выводить с его помощью картинку, после рендеринга всего 3D. Если это вообще возможно.

Что по советуете?

#1
21:55, 13 янв 2013

Самый простой способ - на время рендера этого объекта установить видовую матрицу в единичную. Чтобы перемещать объект в пространстве камеры - просто юзаем матрицу мира.

#2
22:50, 13 янв 2013

>Я хочу взять объект, и разместить его прямо перед камерой, так чтобы он всегда находился в одном и том же прямоугольнике экранных координат.
1) узнай радиус шарика в каторый поместится твой3д объект
2) размести объект в центре камеры
3) узнай нормализованный вектор направления камеры)
4) далее: вектор * радиус * 1.8f ( коэффициент смещения )
5) ковсему этому прибавить положение камеры
не то?

#3
23:33, 13 янв 2013

vitalik
> размести объект в центре камеры


Вот именно это и не получается.


Che@ter
> Самый простой способ - на время рендера этого объекта установить видовую
> матрицу в единичную. Чтобы перемещать объект в пространстве камеры - просто
> юзаем матрицу мира.

Я нашел часть проблемы, матрица вида у меня создается векторами
D3DXMatrixLookAtLH(&View, &cam, &obj, &D3DXVECTOR3( 0, 1, 0 ) );

а мировая матрица - матрицей
D3DMATRIX World = {
  1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0,0,  0, 1,
  };

видимо тут они и конфликтуют....

пытался подставлять значения вектора View в матрицу, вручную... стало вроде по лучше, обьект движется вместе с матрицей, но  масштабируется, Тоесть при движении камеры на отдаление - обьект уменьшается относительно экранных координат... надо Z буфер отключить как-то. плюс начинает летать вокруг центра экрана, во время вращения камеры(вокруг Z оси, той точки в которую направлена ),
при этом улетая иногда за экран вообще.
> установить видовую матрицу в единичную
  вот это вообще не понял... туплю.

#4
0:09, 14 янв 2013

SaintShadow
> вот это вообще не понял... туплю.
Матрицы ты так устанавливаешь?

#5
9:14, 14 янв 2013

SaintShadow
> а мировая матрица - матрицей
> D3DMATRIX World = {
> 1, 0, 0, 0,
> 0, 1, 0, 0,
> 0, 0, 1, 0,
> 0,0, 0, 1,
> };

Юзай

D3DXMATRIX World;
D3DXMatrixIdentity(&World);
#6
0:31, 17 янв 2013

-Eugene-
> Юзай
>
> D3DXMATRIX World;
> D3DXMatrixIdentity(&World);

причем здесь обнуление матрицы?

Чтоб узнать положение матрицы вида в мировых координатах надо сделать D3DXMatrixInverse

А чтоб вытащить координаты например только положение по оси Х.

D3DXMATRIX View;
View._41

Еще не тестил но, у меня от отчаяния презумпция правильности работает .

#7
10:18, 17 янв 2013
Matrix matrix;
Matrix PrjMatrix2d;

matrix.Identity();
PrjMatrix2d.OrthoLH(width, -height, -100, 100);

g_pD3DDevice->SetTransform(D3DTS_VIEW, matrix.GetD3DMatrix());
matrix.Translation(-width/2 - 0.5f, -height/2 - 0.5f, 0.0f);
g_pD3DDevice->SetTransform(D3DTS_WORLD, matrix.GetD3DMatrix());
g_pD3DDevice->SetTransform(D3DTS_PROJECTION, PrjMatrix2d.GetD3DMatrix());

// дальше рисуешь квады где координаты вершин соответствуют координатам пикселей экрана.
// Matrix здесь свой класс, как сделать с использованием d3d функций разберешься самостоятельно.
#8
18:43, 19 янв 2013

Спасибо всем, сделал самый вкусный вариант.

// Делаем в точности те же преобразования что и делали с матрицей вида

void DrawGameMenu(float gradz, float grady, float dist)   // в функцию передаем градусы поворота камеры и дистанцию на которую она отодвинута от центра
{
  
  D3DXMATRIX mat1, mat2, matres;                                    // объявляем 3 матрицы

  D3DXMatrixRotationY(&mat1,  gradz*3.1415f/180 );        // ПЕРВУЮ ПОВОРАЧИВАЕМ (так же как камеру)         //gradz и grady у меня в градусах(так мне удобнее) поэтому переводим их в радианы *Pi/180
  D3DXMatrixRotationX(&mat2,  -grady*3.1415f/180 );      // ВТОРУЮ ПОВОРАЧИВАЕМ  (так же как камеру)

  D3DXMatrixMultiply(&mat1, &mat1, &mat2);                        // ПЕРЕМНОЖАЕМ, СКЛАДЫВАЕМ РЕЗУЛЬТАТ В mat1   (так же как камеру)

  D3DXMatrixIdentity(&mat2); //обнуляет матрицу  
        D3DXMatrixTranslation(&mat2,-5, 15, dist-10);                           // сдвигаем ( dist это дистанция на которую сдвигали камеру, отнимаем от нее 10 чтобы наш объект 
                                                                                                   //был перед камерой, и для прикола сдвигаем на 15 в верх, и на 5 в право )

       D3DXMatrixMultiply(&matres, &mat1, &mat2);                              // перемножаем, и закидываем в matrix result

       D3DXMatrixInverse(&matres,NULL,&matres);                                // инверсируем матрицу..... получаем матрицу мира,  центром в этой точке.

       pD3DDevice->SetTransform(D3DTS_WORLD, &matres);             //устанавливаем её


//рисуем объект
 for (DWORD i=0; i<dwNumMaterials1; i++)
  {      
    pD3DDevice->SetMaterial(&pMeshMaterials1[i]);

    if (pMeshTextures1[i])
      pD3DDevice->SetTexture(0, pMeshTextures1[i]);

    pMesh1->DrawSubset(i);
  }    
}
#9
23:57, 19 янв 2013

Матрица вида это обратная матрица по сравнению с матрицей положения объекта камеры, так как по сути она переводит мировые координаты в локальные координаты камеры.

ПрограммированиеФорумГрафика

Тема в архиве.