forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   C++ (http://forum.boolean.name/forumdisplay.php?f=22)
-   -   передвижение с помощью матриц (http://forum.boolean.name/showthread.php?t=15333)

Mind 22.08.2011 13:22

передвижение с помощью матриц
 
Вот столкнулся с проблемой (т.к недавно перешел на С++):
Осуществляю передвижение объектом с помощью функции:

Код:

void MoveEntity(D3DXMATRIX& m,float dx,float dy,float dz)
{
 
  static float x,y,z;

  x += dx;
  y += dy;
  z += dz;

  m._11 = 1;  m._12 = 0;      m._13 = 0;  m._14 = 0;
  m._21 = 0;  m._22 = 1;      m._23 = 0;  m._24 = 0;
  m._31 = 0;  m._32 = 0;      m._33 = 1;  m._34 = 0;
  m._41 = x;  m._42 = y;        m._43 = -z;  m._44 = 1;

}

Но т.к я двигал один обьект все было норм, а как захотелось нсколько то понял что сделал ошибку - не надо инкриминировать x,y,z в функции т.к для последующего объекта будут прибавлены координать предыдущего.
Чет мозги не варят как можно сделать передвижение разных объектов с помощью одной функции?

Dream 22.08.2011 13:35

Ответ: передвижение с помощью матриц
 
Каково причина обьявления x,y,z статиками?

Mind 22.08.2011 13:57

Ответ: передвижение с помощью матриц
 
Цитата:

Сообщение от Dream (Сообщение 199661)
Каково причина обьявления x,y,z статиками?

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

Mind 22.08.2011 14:01

Ответ: передвижение с помощью матриц
 
Написал чуть модифицированную функцию но тут проблем еще больше:

Код:

void MoveEntity(D3DXMATRIX& m,float dx,float dy,float dz)
{
 
static float x,y,z;

  x = m._41 + dx;
  y = m._42 + dy;
  z = m._43 + dz;

  m._11 = 1;  m._12 = 0;          m._13 = 0;  m._14 = 0;
  m._21 = 0;  m._22 = 1;        m._23 = 0;  m._24 = 0;
  m._31 = 0;  m._32 = 0;        m._33 = 1;  m._34 = 0;
  m._41 = x;  m._42 = y;          m._43 = -z;  m._44 = 1;


}

Каковата ГНОМА тут присходит движение даже без переменных dx,dy,dz ... Без моего участия. :4to:

Mhyhr 22.08.2011 14:29

Ответ: передвижение с помощью матриц
 
зачем такие извращения с внутренностями матрицы?
чем D3DXMatrixTranslation(...) не угодил?

Mind 22.08.2011 14:43

Ответ: передвижение с помощью матриц
 
были проблемы со стандартными матрицами и с углами... да и к тому же хочется понять саму матрицу научится с ней работать ..

falcon 22.08.2011 14:55

Ответ: передвижение с помощью матриц
 
>>static
это не экономия ресурсов, компилятор умнее тебя и умеет экономить их эффективней.

бегло взглянул на вторую ф-цию, вроде всё норм (ток -z вроде не надо).
возможно порядок умножения где-то нарушен при установке матриц.
(под "без переменных" подразумиваются нулевые значения?)

Mind 22.08.2011 15:15

Ответ: передвижение с помощью матриц
 
Цитата:

Сообщение от falcon (Сообщение 199671)
>>static
бегло взглянул на вторую ф-цию, вроде всё норм (ток -z вроде не надо).
возможно порядок умножения где-то нарушен при установке матриц.
(под "без переменных" подразумиваются нулевые значения?)

1) m._41, m._42 ... имеют не нулевые значения их значения далеко за пределами 1 000 000 изначально :4to:
2) вторая функция не пашит именно из-за того что я проделываю операцию x = m._41 + dx; y ... ; z... ; Я даже не могу понять что происходит с камерой толи она отдаляеться далеко и поэтому я не вижу предмета, толи каким-то образом нарушаються матрици вида хз?

Mr_F_ 22.08.2011 15:23

Ответ: передвижение с помощью матриц
 
Цитата:

1) m._41, m._42 ... имеют не нулевые значения их значения далеко за пределами 1 000 000 изначально
в с++ переменные изначально не 0. они не инициализированы, т.е. содержат в себе мусор из памяти. ты должен вручную ставить им 0.

Mind 22.08.2011 17:07

Ответ: передвижение с помощью матриц
 
Все разобрался оказалось даже проще:
Код:

void MoveEntity(D3DXMATRIX& m,float dx,float dy,float dz)
{
 
  m._11 = 1;    m._12 = 0;          m._13 = 0;      m._14 = 0;
  m._21 = 0;    m._22 = 1;      m._23 = 0;      m._24 = 0;
  m._31 = 0;    m._32 = 0;      m._33 = 1;      m._34 = 0;
  m._41 += dx;  m._42 += dy;  m._43 += -dz;  m._44 = 1;

}

Токо после инициализации D3DXMATRIX matView,matViewPos(к примеру)...
нужно обьявлять явно матрици которые инициализированы и токо тогда все будет как надо перемещаться:
НАПРИМЕР:
D3DXMATRIX matWorldPos;

matWorldPos._11 = 1; matWorldPos._12 = 0; matWorldPos._13 = 0; matWorldPos._14 = 0;
matWorldPos._21 = 0; matWorldPos._22 = 1; matWorldPos._23 = 0; matWorldPos._24 = 0;
matWorldPos._31 = 0; matWorldPos._32 = 0; matWorldPos._33 = 1; matWorldPos._34 = 0;
matWorldPos._41 = 0; matWorldPos._42 = 0; matWorldPos._43 = 10; matWorldPos._44 = 1;
dev->SetTransform(D3DTS_WORLD,&matWorldPos);

falcon 22.08.2011 18:50

Ответ: передвижение с помощью матриц
 
об этом тебе mr_f и сказал.
к тому же можно воспользоваться D3DXMatrixIdentity()

.Squid 22.08.2011 19:26

Ответ: передвижение с помощью матриц
 
Доки не читай @ сразу пиши код.

Mind 23.08.2011 22:04

Ответ: передвижение с помощью матриц
 
А как сделать передвижение объекта с помощью матриц в локальных координатах?

falcon 24.08.2011 00:23

Ответ: передвижение с помощью матриц
 
может книжки почитаешь а? учебник там, по линейной математике? ну или Луну того же (там в общем-то доступно всё написано)
или доки хотя б какие-нибудь?
как-то не гоже спрашивать такие вещи..

кури матрицы перехода, и, подскажу с твоими локальными преобразованиями, произвдение матриц перехода составляет комбинацию преобразований. (вроде ж математически коректно выразился xD )
Отсюда и пляши, чо на чо умножить, что бы перемещать тела в локальных СК.. а лучше книжки почитать)

Mr_F_ 24.08.2011 00:51

Ответ: передвижение с помощью матриц
 
Цитата:

А как сделать передвижение объекта с помощью матриц в локальных координатах?
фактически тебе достаточно вектор сдвига умножить на матрицу ротации объекта -> получишь локально смотрящий сдвиг, прибавляешь к позиции.

HolyDel 24.08.2011 14:00

Ответ: передвижение с помощью матриц
 
хранить трансформацию объекта в матрице - имхо неправильно. ИМХО, матриц нужна лишь для родительских отношений и чтобы скормить ее ГАПИ. А так - vec3 позиция, vec3 scale и кватернион на ориентацию. Если что то менялось пересчитываем локальную матрицу и матрицы всех потомков.

Mind 26.08.2011 19:21

Ответ: передвижение с помощью матриц
 
Как я понял матрицы нужны для конечного результата, а двигать объекты надо через вектора...
Объясните простой пример:
1)загружаю модель шара("shar.x")
2)создаю матрици мира,вида,проэкции.
3)теперь чтобы передвинуть шар нужно каждую вершину передвинуть на общее/определенное значение. ДА?
Так вот:

Код:


....
....

D3DXLoadMeshFromX(L"shar.x",D3DXMESH_SYSTEMMEM,d3d_device,NULL,&pMeshBuffer,NULL,&dwNumber,&pMesh);

  D3DXMATRIX matWorld;
  D3DXMATRIX matView;
  D3DXMATRIX matProj;

  matWorld._11 = 1; matWorld._12 = 0; matWorld._13 = 0; matWorld._14 = 0;
  matWorld._21 = 0; matWorld._22 = 1; matWorld._23 = 0; matWorld._24 = 0;
  matWorld._31 = 0; matWorld._32 = 0; matWorld._33 = 1; matWorld._34 = 0;
  matWorld._41 = 0; matWorld._42 = 0; matWorld._43 = -10; matWorld._44 = 1;
  d3d-device->SetTransform(D3DTS_WORLD,&matWorld);


 matView._11 = 1; matView._12 = 0; matView._13 = 0; matView._14 = 0;
 matView._21 = 0; matView._22 = 1; matView._23 = 0; matView._24 = 0;
 matView._31 = 0; matView._32 = 0; matView._33 = 1; matView._34 = 0;
 matView._41 = 0; matView._42 = 0; matView._43 = 0;matView._44 = 1;
 d3d-device->SetTransform(D3DTS_VIEW,&matView);


  matProj._11 = 1; matProj._12 = 0; matProj._13 = 0; matProj._14 = 0;
  matProj._21 = 0; matProj._22 = 1; matProj._23 = 0; matProj._24 = 0;
  matProj._31 = 0; matProj._32 = 0; matProj._33 = 1000/999; matProj._34 = 1;
  matProj._41 = 0; matProj._42 = 0; matProj._43 = -1000/999; matProj._44 = 0;

  d3d-device->SetTransform(D3DTS_PROJECTION,&matProj);

while(1)
{

....
....

d3d-device->BeginScene();


        for(DWORD i=0;i<dwNumber;i++)
        {
        pMesh->DrawSubset(0);
        }
//Что сдесь написать чтобы передвинуть точку/точки в пространстве (Локальном)???

dev->EndScene();
dev->Present(NULL,NULL,NULL,NULL);
....
....

return 0;
}

Как можно обратьться к любой вершине загруженного объекта??

alcoSHoLiK 26.08.2011 20:05

Ответ: передвижение с помощью матриц
 
Вершины двигать не нужно. Важно понимать, что происходит во время рендера. Каждая вершина, которая поступает на графический конвеер, умножается на матрицу World, View и Projection. В итоге получаются экранные координаты вершины.

Чтобы переместить объект в мире тебе надо изменить матрицу World перед рендером этого объекта. Чтобы перемещать независимо несколько объектов, надо сохранять матрицу World до трансформации и восстанавливать после.

Для примера, продемонстрирую процесс в OpenGL коде. В OpenGL вместо отдельных матриц World и View используется одна modelview матрица. Сути это не меняет, т.к. эта матрица является произведением world на view.
Код:

// все функции трансформации работают с текущей матрицей

glPushMatrix(); // сохраним матрицу на стеке

// Переместим и отмасштабируем modelview матрицу
glTranslatef(1, -1, 10);
glScalef(2, 3, 1);

// Отрисуем объект
glDrawArrays(...);

// Восстановим modelview матрицу
glPopMatrix();

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

Аналогичным образом можно независимо двигать, вращать и масштабировать несколько объектов, надо просто каждого из них обернуть в вызовы push/pop:
Код:

for (int i = 0; i < OBJECT_COUNT; ++i) {
    glPushMatrix();

    // трансформируем что надо и рисуем объект

    glPopMatrix();
}

Все трансформации координат относительны.

Mind 26.08.2011 21:23

Ответ: передвижение с помощью матриц
 
alcoSHoLiK Спасибо большое без тебя бы долго разбирался :)

Mind 26.08.2011 22:35

Ответ: передвижение с помощью матриц
 
Появился еще вопрос:
Как мне сделать сдиг тела а потом поворот в локальных координатах?
Делаю вот так:
Код:

  RotateEntity(matWorldRY,mx);
  MoveEntity(matWorldPos,UP1,0,UP2);
  D3DXMatrixMultiply(&matWorld,&matWorldPos,&matWorldRY);
  SetTransform(WORLD,matWorld);
        pMesh->DrawSubset(0);

когда позиция = 0 то тело крутится как бы вокруг своей оси, а когда передвигаеться дальше тополучаеться что тело это child каой-то оси, т.е оно движеться не вокруг своей оси а вокруг другой как ребёнок вокруг парента? Что надо написать чтобы тело крутилось вокруг себя?

Функция поворота такая:

Код:

void RotateEntity(D3DXMATRIX& m,double angle)
{
 
  m._11 = cos(angle);  m._12 = 0;          m._13 = -sin(angle);  m._14 = 0;
  m._21 = 0;  m._22 = 1;  m._23 = 0;  m._24 = 0;
  m._31 = sin(angle);  m._32 = 0;  m._33 = cos(angle);  m._34 = 0;
  m._41 = 0;  m._42 = 0;          m._43 = 0;  m._44 = 1;

}

а передвижения:

Код:

void MoveEntity(D3DXMATRIX& m,float dx,float dy,float dz)
{
 

  m._11 = 1;  m._12 = 0;          m._13 = 0;  m._14 = 0;
  m._21 = 0;  m._22 = 1;    m._23 = 0;  m._24 = 0;
  m._31 = 0;  m._32 = 0;    m._33 = 1;  m._34 = 0;
  m._41 += dx;  m._42 += dy;          m._43 +=-dz;  m._44 = 1;

}


alcoSHoLiK 27.08.2011 00:47

Ответ: передвижение с помощью матриц
 
Попробуй поменять местами функции MoveEntity и RotateEntity. Должно получиться

Код:

  MoveEntity(matWorldPos,UP1,0,UP2);
  RotateEntity(matWorldRY,mx);
  D3DXMatrixMultiply(&matWorld,&matWorldPos,&matWorldRY);
  SetTransform(WORLD,matWorld);
        pMesh->DrawSubset(0);

Правка:
Пардон, не внимательно глянул. Вызовы MoveEntity и RotateEntity пусть остаются как есть, а вот в вызове D3DXMatrixMultiply надо поменять местами matWorldPos и matWorldRY.

---

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

Как же повернуть объект вокруг своей оси? В общем случае это делается за три шага:
1) построить вектор из начала координат в центр объекта и переместить объект вдоль этого вектора так, чтобы его центр оказался в начале координат
2) повернуть объект (или систему координат -- все относительно)
3) вернуть объект на прежнее место, переместив его вдоль построенного ранее вектора в обратную сторону

В твоем частном случае должно быть достаточно поменять местами порядок умножения матрицы смещения и матрицы поворота, чтобы достичь желаемого эффекта.

Mind 27.08.2011 11:18

Ответ: передвижение с помощью матриц
 
Хм... пулучилось. А раньше чето пробывал и не получалось(правда там все почти было по другму написано).Спасибо.
Цитата:

Как же повернуть объект вокруг своей оси? В общем случае это делается за три шага:
1) построить вектор из начала координат в центр объекта и переместить объект вдоль этого вектора так, чтобы его центр оказался в начале координат
2) повернуть объект (или систему координат -- все относительно)
3) вернуть объект на прежнее место, переместив его вдоль построенного ранее вектора в обратную сторону
А это я так понял ты написал для самостаятельно построеной матрицы чтобы повернуть объект.ДА?
т.к у меня все получилось благодаря этому:
Цитата:

В твоем частном случае должно быть достаточно поменять местами порядок умножения матрицы смещения и матрицы поворота, чтобы достичь желаемого эффекта.

alcoSHoLiK 27.08.2011 18:21

Ответ: передвижение с помощью матриц
 
Цитата:

Сообщение от Mind (Сообщение 200258)
А это я так понял ты написал для самостаятельно построеной матрицы чтобы повернуть объект.ДА?

Это я описал общий случай. Если после проделанных для объекта трансформаций ты захочешь его снова повернуть вокруг своей оси где-нибудь дальше в коде (например, при выполнении какого-то условия), тебе придется проделать три шага вместо двух, т.к. объект уже не находится в начале координат после первого перемещения.


Часовой пояс GMT +4, время: 06:45.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot