PMG

Форумы по созданию игр
Текущее время: 29 мар 2024 01:38

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 8 ] 
Автор Сообщение
 Заголовок сообщения: Скелетная иерархия - не выходит
СообщениеДобавлено: 25 фев 2013 13:43 
Не в сети
Любитель

Зарегистрирован: 19 сен 2008 14:48
Сообщения: 44
Вобщим мучаю один код. В этом коде рисуеться модель человека и она анимируеться (я взял его из интернета этот код на Open GL переделую под DX). Есть 15 частей тела у модели и у них иерархия. Типа скелетной анимации но без весов вершин. Просто анимация фреймов без весов вершин.

Мне надо создать иерерхию фреймов с RootFrame на базе модели, сохраненной в файле. Модель сохранента так что можно только узнать где функция отрисовки делает PushMatrix а где PopMatrix что бы отобразить иерархию мешей модели. Мне надо по этим PushMatrix и PopMatrix вычислить саму иерархию фреймов программно и сложить из этого что есть иерархию фреймов. Я собираюсь дальше взять функцюи DX когда сложу иерархию фреймов и записать в Х файл эту иерархию D3DXSaveMeshHierarchyToFile(). Вот схематический код рисования модели после того как она загружена из файла уровня игры (игра старая за 97 год):


for(int i=0; i<NumMeshesOfModel; i++)

{

if(i =0)
{
создаем стек матриц и инициализируем вершину стека матрицей корневого меша
}
else
{

int op = GetMeshTree(); //получаем матрицу меша из файла и код операции Push или Pop

if(op = 0x01)
{
//pop
MatrixPop()
}

if(op = 0x02)
{
//push
MatrixPush()
}

//null

//делаем что- то с матрицей
//и рисуем отдельный мешь модели

}

У меня есть две модели сохраненные в таком формате Push и Pop Matrix (если честно взламал файл уровня одной игрухи, там такая байда).

Первая модель автомобиля 8 мешей, пройдемся в цикле, справа коментарии как в реальном положении должна быть схема иерархии:

i = 0 - создание матрицы фреймов (корпус)
i = 1 - push - привязан к корню (руль)
i = 2 - pop - привязан к 1 как родственник 1 (задняя ось)
i = 3 - push - привяан к 2 как ребенок 2 (заднее колесо)
i = 4 - pop - привязан к 3 как родственник (ребенок 2) (заднее колесо
i = 5 - pop - привязан к 2 как родственник 2 (передняя ось)
i = 6 - push - привязан к 5 как ребенок 5 (переднее колесо)
i = 7 - pop - привязан к 6 как родственник (ребенок 7) (переднее колесо)

Вторая модель человека 15 мешей. То же самое, но я запутался в одном месте.

i = 0 - создание матрицы фреймов (таз)
i = 1 - push - ребенок 0 (левая нога)
i = 2 - null - ребеонк 1 (левая нога)
i = 3 - null - ребеонк 2 (левая нога)
i = 4 - pop - родственник 1 (правая нога)
i = 5 - null - ребенок 4 (правая нога)
i = 6 - null - ребекно 5 (правая нога)
i = 7 - pop - родственник 4 (торс)
i = 8 - push - ребенок 7 (левая рука)
i = 9 - null - ребенок 8 (левая рука)
i = 10 - null - ребенок 9 (левая рука)
i = 11 - pop - родственник 8 (правая рука)
i = 12 - null - ребенок 11 (правая рука)
i = 13 - null - ребенок 12 (правая рука)
i = 14 - pop - родственник 11 (голова)

Я привел такак push/pop осуществляеться в цикле и реальную такую как должна быть иерархию фреймов. Я пишу программу что бы на базе этих push/pop matrix создавалась иерархия фреймов. Я создал стек фреймов на базе структуры С++ похожий на стек матриц в DirectX или Open GL. Мне тут не понятно только почему в первой модели 4 - й pop возвращаемся к фрейму 3 и привязываем 4- й как родствениик, затем 5 - й pop привязан к 2 как родственнник 2. А во второй модели 11 мешь pop привязываеться к 8 - му как родтсвенник, и 14 pop привязываеться 11 как родственник а не как в было бы в 1- модели 7 - му мешу? Я в режиме отладки следил на всеми Push и Pop matirx и привел вам схему.

То есть в первой модели:

2 pop
3 push
4 pop - привязываем 3 как родственника
5 pop - привязываем 2 как родственника

а во второй модели

7 pop
8 push -
11 pop - привязываем 8 как родственника
14 pop - привязываем 11 как родственника (а не к 7 - му как было бы логично в первой модели)


То есть тут последовательность

pop
push
pop
pop

есть и в первой и во второй модели, но по разному привязано. Почему?

Как вобще тут написать код, что бы для любой модели такого плана этой игры взломанной все эти push и pop matrix переделать в иерархию фреймов?

Заранее спасибо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Скелетная иерархия - не выходит
СообщениеДобавлено: 26 фев 2013 15:24 
Не в сети
Гуру
Аватара пользователя

Зарегистрирован: 03 авг 2004 10:37
Сообщения: 2694
Цитата:
сложить из этого что есть иерархию фреймов

Не совсем понял, конечно, но может самому написать PushMatrix/PopMatrix, чтобы получить нужные координаты?

_________________
С уважением, Сергей


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Скелетная иерархия - не выходит
СообщениеДобавлено: 27 фев 2013 06:53 
Не в сети
Любитель

Зарегистрирован: 19 сен 2008 14:48
Сообщения: 44
Может я немного запутанно изъяснился. Я знаю как модель рисуеться по мешам, то есть я знаю где для нее делаеться Pop Matrix а где Push Matrix что бы нарисовался отдельный мешь модели из иерархии. И само собой я знаю какие матрицы для анимации и как их получить- просто извлекаю после всех преобразований ТОП матрицу из стека и записую ее как матрицу анимации текущего времени анимации. Это не проблема. Я даже написал небольшой код который записует всю модель с матрицами анимации в Х файл DirectX и потом отлично анимация воспроизводиться. Но тот код что я написал работает не для всех моделей которые есть в уровне игры который я открываю и загружаю в своей программе. Вот я программой открываю файл уровня игрухи, извлекаю модели -и хочу всех их соранить как Х файл на диск с анимацией и иерархией мешей. Вот - то есть мне нужна иерархия мешей модели каждой. Универсаный такой код, который бы брал любую модель из игры, и записывал бы ее иерархию мешей в Х файл.

Я создал структуру типа:

sturct Frame
{
struct Frame *FirstSibling; //хранит указатель на следующий родственный мешь
struct Frame *FirstChild; //хранит указатель на следующий дочерний мешь
matrix TransformationMatrix; //хранит матрицу меша
}

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

Спасибо MagicWolf что откликнулся, но ты вобще в скелетной анимации разбираешься? Что такое иерархия фреймов в скелетной анимации. Тут та же скелетная анимация, но без весов вершин- просто меши друг относительно друга (без весов вершин) перемещаються в пространстве с течением времени анимации. При каждом кадре береться новая матрица из файла уровня игры- матрица этого следующего меша в иерархии, и делаеться либо Push либо Pop этой матрицы с предыдущей матрицей и рисуеться отдельный фрейм, мешь модели.

Когда делаеться Push Matrix этот мешь что щас будет рисоваться с этой матрицей просто привязываеться к предыдущему как FrameChild, а когда Pop Matrix - то как родственный FrameSibling. НО к чему родственный- вот тут у меня и заглючка. Когда делаеться Push Matrix - то привязываеться мешь (фрейм) к предыдущему очень просто - мы знаем он дочерний к предыдущему. Но следить когда делаеться Pop Matrix для текущего меша, и следить как привязать и к чему его как родственного- сложнее намного. Для этого что бы отслеживать все Push и Pop я и создал стек фреймов- тот же стек что и стек матриц, только фреймов. И мой стек фреймов следит за отрисовкой- когда в коде делаеться Push а когда Pop Matrix и соответственно создает иерархию фреймов - то есть иерархию мешей модели и мой стек фреймов привязывает меши либо как родственные либо как дочерние друг к другу в зависимости от Push/Pop Matrix.

В первом посте я привел два примера двух моделей- следил в режиме отладки в Visual Studio где делаеться при отрисовке Push а где Pop Matrix записал все на бумажку. И вот в этих двух моделях есть два одинаковых места (см. первый пост):

pop
push
pop
pop

Но при последнем Pop Matrix этот мешь по разному привязываеться- в одном случае (в одной модели) как дочерний, в другом (в другой модели) как родственный. Я это в первом посте написал. Вот меня и интересует- почему делаеться ОДИН Push Matrix и Два Pop Matrix и почему по разному относяться эти матрицы к предыдущим матрицам и соответственно иерархия складуеться по разному.

Вобще от я не пойму- когда делаеться один Push Matrix и два Pop Matrix к чему это приводит? Какая матрица будет результирующая при втором Pop?

Вобще MagicWolf я смотрю форум у Вас для новичков, вопрос больше к Вам. Раньше как то вы говорили что на Open GL писали 15 лет (давно было вы говорили) а эта программа как раз и есть на Open GL и я ее перевожу на DirectX.

Вопрос для меня очень актуальный- позарез мне надо создать эту иерархию.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Скелетная иерархия - не выходит
СообщениеДобавлено: 27 фев 2013 10:59 
Не в сети
Гуру
Аватара пользователя

Зарегистрирован: 03 авг 2004 10:37
Сообщения: 2694
Скелетную анимация я писал, во всяком случае реализовывал ms3d-формат. Но 2008 году последний раз :cry:
Тебе надо визуализировать результат, т.е. делать push/pop по нажатию клавиш. Для начала только вперед, если будет не понятно, тогда вперед/назад. Так будет нагляднее и гадать ничего не придется.

_________________
С уважением, Сергей


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Скелетная иерархия - не выходит
СообщениеДобавлено: 28 фев 2013 21:17 
Не в сети
Любитель

Зарегистрирован: 19 сен 2008 14:48
Сообщения: 44
Да, я понял, спасибо- хорошая идея, визуализировать результат. Но я пишу такую прогу вобщим для геймеров типа. Что бы человек сел, открыл любой файл уровня игры (в данном случае Томб Райдер) и мог автоматически сохранить модель (то есть самостоятельно программа без участия пользователя сохраняет), то есть человек не разбираеться в программировании- сел сохранил модель.

Но вот вы мне объясните MagicWolf, когда есть такой код предположим, чисто абстрактный:

1 - push - исходная матрица заталкиваеться в стек
2 - pop
3 - push
4 - pop
5 - pop

вы бы не могли мне MagicWolf чисто как гуру OpenGL расписать дальше по пунктам 1,2,3,4,5 что делаеться с исходной матрицей. Особенно меня интересуют два последних pop- они выталкиваеют одну и ту же матрицу или разные? Вот если вам не сложно, напишите мне. А то по стекам матриц в интернете я нашел только примитивные примеры. Тут у меня более продвинутый пример. Что будет- можете расписать?

И еще насчет стека матриц вопрос. Когда исходная матрица заталкиваеться в стек push то она остаеться на ТОП стека, и перемещаеться на его второе место типа? Или как тут. Я честно сказать путаюсь. Почитал про стек матриц на Майрософте по Директ Икс, там как- то запутанно пишут типа, что когда делаеться push матрице, то что с ней дальше не ясно. Она только на ТОП стеке или еще с ТОП стека перемещаеться на второе место в стеке? Вобщим инфа нужна деловая, продвинутая про стек матриц, с примерчиками на разные случаи жизни.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Скелетная иерархия - не выходит
СообщениеДобавлено: 01 мар 2013 10:07 
Не в сети
Гуру
Аватара пользователя

Зарегистрирован: 03 авг 2004 10:37
Сообщения: 2694
Да, че путаться. Ты же сам понимаешь, что с точки зрения ханойской башни, пока диск не положишь, его и не вынешь. Конечно, второй pop бесмысленая операция. Дисков уже нет, выталкивать из сетка нечего. Скорее всего второй pop возвратиться с ошибкой.

И я не гуру OGL. Гуру Боресков (http://steps3d.narod.ru/me.html). Я переводил уроки NeHe на русский...

Сложного примера у меня нет. Вот простой пример:
Код:
int build_quads_cube ( SPointPolygon_OGL * p/*24*/, SVector3f * colors_points/*8*/, SVector3f * center_point, float size ) // 24 points!!! 8 vertex!!!
{
  ulong_t i, j, n_vertex, k;
   static SVector3f points_cube[8]=
   {
      {-1.0f, 1.0f, 1.0f}, //left,top,front
      {1.0f,  1.0f, 1.0f}, //right,top,front
      {1.0f,  1.0f,-1.0f}, //right,top,back
      {-1.0f, 1.0f,-1.0f}, //left, top,back
      {-1.0f,-1.0f, 1.0f}, //left,bottom,front
      {1.0f, -1.0f, 1.0f}, //right,bottom,front
      {1.0f, -1.0f,-1.0f}, //right,bottom,back
      {-1.0f,-1.0f,-1.0f}  //left,bottom,back
   };
   // anti-clockwise order
   static byte_t face_cube[6][4]=
   {
      {0,1,2,3}, //top
      {0,3,7,4}, //left
      {3,2,6,7}, //back
      {2,1,5,6}, //right
      {0,4,5,1}, //front
      {4,7,6,5}, //bottom
   };

  if ( p==0 || colors_points==0 )
    return IS_ERROR;

  for ( i=0, k=0; i<6; i++ )
      for ( j=0; j<4; j++ )   {
      n_vertex = face_cube[i][j];
      p[k].x = points_cube[n_vertex].x * size + center_point->x;
      p[k].y = points_cube[n_vertex].y * size + center_point->y;
      p[k].z = points_cube[n_vertex].z * size + center_point->z;
      p[k].r = colors_points[n_vertex].r;
      p[k].g = colors_points[n_vertex].g;
      p[k].b = colors_points[n_vertex].b;
      k++;
    }

  return IS_OK;
}

  build_quads_cube (points_polygons[0],color_points_cube,&center_point,2.0);
  build_quads_cube (points_polygons[1],color_points_cube_tmp,&center_point,2.0);
  build_quads_cube (points_polygons[2],color_points_cube_tmp,&center_point,2.0);
  build_quads_cube (points_polygons[3],color_points_cube_tmp,&center_point,2.0);
  build_quads_cube (points_polygons[4],color_points_cube_tmp,&center_point,2.0);

  glRotatef(angle[1],0.0,1.0,0.0);

  polygons_draw.init(&cfg_polygons,count_points[0],points_polygons[0]);
  glPushMatrix();
    glScalef(5.0,0.1,5.0);
    polygons_draw.draw();
  glPopMatrix();

  polygons_draw.init(&cfg_polygons,count_points[1],points_polygons[1]);
  glPushMatrix();
    glTranslatef(-2.0,3.0,pos[1]);
    glRotatef(angle[1],1.0,0.0,0.0);
    glPushMatrix();
      glScalef(0.1,0.8,0.8);
      polygons_draw.draw();
    glPopMatrix();

    polygons_draw.init(&cfg_polygons,count_points[4],points_polygons[4]);
    glTranslatef(-4.0,0.0,0.0);
    glRotatef(angle[4],0.0,1.0,0.0);
    glPushMatrix();
      glScalef(0.8,0.1,0.8);
      polygons_draw.draw();
    glPopMatrix();
  glPopMatrix();

  polygons_draw.init(&cfg_polygons,count_points[2],points_polygons[2]);
  glPushMatrix();
    glTranslatef(2.0,3.0,pos[2]);
    glRotatef(angle[2],1.0,0.0,0.0);
    glPushMatrix();
      glScalef(0.1,0.8,0.8);
      polygons_draw.draw();
    glPopMatrix();

    polygons_draw.init(&cfg_polygons,count_points[3],points_polygons[3]);
    glTranslatef(4.0,0.0,0.0);
    glRotatef(angle[3],0.0,1.0,0.0);
    glPushMatrix();
      glScalef(0.8,0.1,0.8);
      polygons_draw.draw();
    glPopMatrix();
  glPopMatrix();


_________________
С уважением, Сергей


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Скелетная иерархия - не выходит
СообщениеДобавлено: 01 мар 2013 10:58 
Не в сети
Любитель

Зарегистрирован: 19 сен 2008 14:48
Сообщения: 44
Спасибо, MagicWorlf, я начал копать в направлении "визуализировать результат" и обнаружил ошибки среди push/pop которые я подавал выше. Теперь все просто- каждому push у меня свой pop. Одна голова хорошо- две лучше! Огромное спасибо!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Скелетная иерархия - не выходит
СообщениеДобавлено: 01 мар 2013 16:09 
Не в сети
Гуру
Аватара пользователя

Зарегистрирован: 03 авг 2004 10:37
Сообщения: 2694
Не за что. Главное - результат!

_________________
С уважением, Сергей


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 8 ] 

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


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

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB