PMG http://forum.pmg.org.ru/ |
|
Скелетная иерархия - не выходит http://forum.pmg.org.ru/viewtopic.php?f=4&t=9446 |
Страница 1 из 1 |
Автор: | kurlyak [ 25 фев 2013 13:43 ] |
Заголовок сообщения: | Скелетная иерархия - не выходит |
Вобщим мучаю один код. В этом коде рисуеться модель человека и она анимируеться (я взял его из интернета этот код на 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 переделать в иерархию фреймов? Заранее спасибо. |
Автор: | MagicWolf [ 26 фев 2013 15:24 ] |
Заголовок сообщения: | Re: Скелетная иерархия - не выходит |
Цитата: сложить из этого что есть иерархию фреймов Не совсем понял, конечно, но может самому написать PushMatrix/PopMatrix, чтобы получить нужные координаты? |
Автор: | kurlyak [ 27 фев 2013 06:53 ] |
Заголовок сообщения: | Re: Скелетная иерархия - не выходит |
Может я немного запутанно изъяснился. Я знаю как модель рисуеться по мешам, то есть я знаю где для нее делаеться 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. Вопрос для меня очень актуальный- позарез мне надо создать эту иерархию. |
Автор: | MagicWolf [ 27 фев 2013 10:59 ] |
Заголовок сообщения: | Re: Скелетная иерархия - не выходит |
Скелетную анимация я писал, во всяком случае реализовывал ms3d-формат. Но 2008 году последний раз Тебе надо визуализировать результат, т.е. делать push/pop по нажатию клавиш. Для начала только вперед, если будет не понятно, тогда вперед/назад. Так будет нагляднее и гадать ничего не придется. |
Автор: | kurlyak [ 28 фев 2013 21:17 ] |
Заголовок сообщения: | Re: Скелетная иерархия - не выходит |
Да, я понял, спасибо- хорошая идея, визуализировать результат. Но я пишу такую прогу вобщим для геймеров типа. Что бы человек сел, открыл любой файл уровня игры (в данном случае Томб Райдер) и мог автоматически сохранить модель (то есть самостоятельно программа без участия пользователя сохраняет), то есть человек не разбираеться в программировании- сел сохранил модель. Но вот вы мне объясните MagicWolf, когда есть такой код предположим, чисто абстрактный: 1 - push - исходная матрица заталкиваеться в стек 2 - pop 3 - push 4 - pop 5 - pop вы бы не могли мне MagicWolf чисто как гуру OpenGL расписать дальше по пунктам 1,2,3,4,5 что делаеться с исходной матрицей. Особенно меня интересуют два последних pop- они выталкиваеют одну и ту же матрицу или разные? Вот если вам не сложно, напишите мне. А то по стекам матриц в интернете я нашел только примитивные примеры. Тут у меня более продвинутый пример. Что будет- можете расписать? И еще насчет стека матриц вопрос. Когда исходная матрица заталкиваеться в стек push то она остаеться на ТОП стека, и перемещаеться на его второе место типа? Или как тут. Я честно сказать путаюсь. Почитал про стек матриц на Майрософте по Директ Икс, там как- то запутанно пишут типа, что когда делаеться push матрице, то что с ней дальше не ясно. Она только на ТОП стеке или еще с ТОП стека перемещаеться на второе место в стеке? Вобщим инфа нужна деловая, продвинутая про стек матриц, с примерчиками на разные случаи жизни. |
Автор: | MagicWolf [ 01 мар 2013 10:07 ] |
Заголовок сообщения: | Re: Скелетная иерархия - не выходит |
Да, че путаться. Ты же сам понимаешь, что с точки зрения ханойской башни, пока диск не положишь, его и не вынешь. Конечно, второй 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,¢er_point,2.0); build_quads_cube (points_polygons[1],color_points_cube_tmp,¢er_point,2.0); build_quads_cube (points_polygons[2],color_points_cube_tmp,¢er_point,2.0); build_quads_cube (points_polygons[3],color_points_cube_tmp,¢er_point,2.0); build_quads_cube (points_polygons[4],color_points_cube_tmp,¢er_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(); |
Автор: | kurlyak [ 01 мар 2013 10:58 ] |
Заголовок сообщения: | Re: Скелетная иерархия - не выходит |
Спасибо, MagicWorlf, я начал копать в направлении "визуализировать результат" и обнаружил ошибки среди push/pop которые я подавал выше. Теперь все просто- каждому push у меня свой pop. Одна голова хорошо- две лучше! Огромное спасибо! |
Автор: | MagicWolf [ 01 мар 2013 16:09 ] |
Заголовок сообщения: | Re: Скелетная иерархия - не выходит |
Не за что. Главное - результат! |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа [ Летнее время ] |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |