Страницы (7): [1] 2 3 4 5 » ... Последняя » Показать все 100 сообщений этой темы на одной странице |
HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Технические вопросы (https://hlfx.ru/forum/forumdisplay.php?forumid=20)
-- Скелетная SMD анимация (https://hlfx.ru/forum/showthread.php?threadid=5532)
Скелетная SMD анимация
Всем доброго времени суток, товарищи! Может кто-нибудь помнит, как я пытался имплементировать в свой движок анимацию из smd из древней статьи на tmlibе, лет этак пять назад. Тогда мне удалось успешно забороть все глюки и выверты скелета и меша. И вот спустя столько времени, я решил портировать этот код на текущую версию движа, используя в качестве матриц не самописную либу, а рекомендуемый в среде lwjgl погромистов - JOML (Java OpenGL Math Library). После определенных манипуляций я переписал загрузчик, но по итогу вновь вернулся к раскоряченному скелету и полигонам. Собственно, что удалось выяснить - в JOML используется порядок матрицы вертикального вида
00, 10, 20, 30
01, 11, 21, 31
02, 12, 22, 32
03, 13, 23, 33
в то время, как у меня порядок был горизонтальный. Кроме того, отпала необходимость в конверсии радианов в градусы, так как JOML изначально работает в радианах. В остальном же код не слишком изменился, но модели вновь корежит (координаты вертексов тут без преобразования, то есть загружены напрямую из smd "как есть").
Загружаю рефренсный фрейм прямо
1 | int boneId = Integer.parseInt(tokens[0]); |
2 |
3 | float x = Float.parseFloat(tokens[1]); |
4 | float y = Float.parseFloat(tokens[2]); |
5 | float z = Float.parseFloat(tokens[3]); |
6 |
7 | float ax = Float.parseFloat(tokens[4]); |
8 | float ay = Float.parseFloat(tokens[5]); |
9 | float az = Float.parseFloat(tokens[6]); |
10 |
11 | referenceFrame.pos.put(boneId, new Vector3f(x, y, z)); //Сюда сторим референсную позицию |
12 | referenceFrame.angles.put(boneId, new Vector3f(ax, ay, az)); //А сюда углы в радианах |
1 | //Читаем все кости подряд |
2 | for (Bone b : bones.values()) { |
3 | Vector3f pos = startFrame.pos.get(b.id); //Получаем позицию для кости |
4 | Vector3f angles = startFrame.angles.get(b.id); //И углы |
5 |
6 | b.matRelative.identity(); //Промежуточная матрица |
7 | b.matRelative.rotateX(angles.x); |
8 | b.matRelative.rotateY(angles.y); |
9 | b.matRelative.rotateZ(angles.z); |
10 | b.matRelative.translate(pos.x, pos.y, pos.z); |
11 |
12 | if (b.parentId == -1) { |
13 | b.matAbsolute = b.matRelative; //Если парент-кости нет - то присваимаем абсолютной матрице локальную |
14 | } else { |
15 | //В ином случае - перемножаем абсолютную матрицу парента с текущей и сохраняем в текущую абсолютную |
16 | Bone p = bones.get(b.parentId); |
17 | p.matAbsolute.mul(b.matRelative, b.matAbsolute); |
18 | } |
19 |
20 | b.matAbsolute.transformPosition(b.pos); |
21 | } |
__________________
-Brain is dead-
Порядок эйлеров XYZ в этом жомле?
Таблица конверсии
Original - smd
YAW -> ROLL
PITCH -> YAW
ROLL -> PITCH
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
1 | b.matRelative.translation(pos.z, pos.x, pos.y); |
2 | b.matRelative.rotateX(angles.z); |
3 | b.matRelative.rotateY(angles.x); |
4 | b.matRelative.rotateZ(angles.y); |
__________________
-Brain is dead-
Компилятор действительно свапает вертексы и еще по дефолту вращает скелет на 90 градусов.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
__________________
-Brain is dead-
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Переделал под LH проекцию, ну это просто какая-то жесть. Такое ощусчение, что вальва просто рандомно свапала значения в smd, до кучи добавив этот непонятный и ненужный поворот root кости на 90 градусов. Теперь буду проверять анимации. Кстати, хотел спросить, по идее у модели же может быть несколько мировых костей (с parent == -1)?
Тут внезапно всплыла еще одна проблема, а именно - нормали вертексов, которые не трансформируются вместе с костями, в итоге при развороте скелета вместо симпатичного "пинхеда" мы получаем такое
__________________
-Brain is dead-
Походу они никак не могли определиться в какой системе координат им работать.
Надеюсь в ксаше и волатиле такого трешака не будет
__________________
У котёнка мокрый нос и гладенькая шерсть, у него забавный хвост и быстрых лапок шесть. Две задних, две средних и две передних лапы, такая многоножка получилася у папы.
Он ученый — папа мой — зверушек изучает, гуляет по помойкам, ловит крыс и чаек. Две крысы белокрылые и чайки две унылые покрытые пупырчатою кожей лягушат без пёрышек тоскуют и ускакать спешат.
А ещё есть муравей большой размером с гуся он пугает всех зверей, и я его боюся, когда он ковыляет на лапках на своих.
И в двери ударяет, и начинает стих: Я — муравей, воды налей! Не меньше ведра, напиться мне пора!
Эксперементально выяснил, что если в матрице проекции ось Z направлена от камеры, то модель отзеркаливается горизонтально. Ерунда какая-то
Добавлено 29-06-2020 в 17:23:
FiEctro это я для своего движка делаю, smd взял как промежуточный формат, потому-что в нем нет ничего лишнего и удобная скелеталка, плюс его легко парсить
__________________
-Brain is dead-
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
__________________
-Brain is dead-
Если ты делаешь VectorTransform для вертексов, очевидно надо сделать и VectorRotate для нормалей.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Дядя Миша именно только вращение? То есть, получается берём матрицу кости, вычленяем из неё вектор вращения и умножаем на ноомаль?
Добавлено 30-06-2020 в 01:45:
Так-то эта вся визуализация чисто утилитарная, потом я оставлю только консольный конвертер, но мне важно сейчас все правильно настроить
Добавлено 30-06-2020 в 02:04:
Вообще интересно, например, читаю Quake Specs, там пишется, что квака использует стандартную left-handed проекцию, где ось Z идёт положительно вверх. В то время, как JOML упорно строит матрицу проекции с z от камеры или в камеру. С другой стороны, это логично, Z-buffer же. Где-то меня клинит, а где, не могу понять. Как будто в 2010 откатился
__________________
-Brain is dead-
Временная зона GMT. Текущее время 13:37. | Страницы (7): [1] 2 3 4 5 » ... Последняя » Показать все 100 сообщений этой темы на одной странице |
На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024