HLFX.Ru Forum
Показать все 7 сообщений этой темы на одной странице

HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Half-Life SDK (https://hlfx.ru/forum/forumdisplay.php?forumid=8)
-- Smd animation parse (https://hlfx.ru/forum/showthread.php?threadid=5618)


Отправлено -=DrTressi=- 28-01-2021 в 04:48:

Smd animation parse

Привет. Я тут задался идеей построить из smd скелет и заанимировать его, но никак не могу добиться адекватного результата. Скелет постоянно то плющит, то выворачивает. Проблема, как мне кажется, крутится где-то вокруг углов и без помощи свыше я разобраться никак не могу.

Итак, выдержка из официальная дока:

Цитата:
A bone's position relative to its parent (give absolute values in the case of root bones).
Pos is position in units relative to the parent bone.
Rot is local Tait-Bryan angles, given in radians. (90° = 1.570796 rad)

Ага, видим что углы задаются в радианах, но это не проблема, они локальные относительно родительской кости = тоже понятно. А вот что за Тайт-Браин?
Мне по сути нужно получить относительный поворот в углах Эйлера. Как перевести Тайта-Брайна к Эйлеру не понятно.

Методом чёрного ящика мне удалось добиться некоторых успехов. Код:
C++ Source Code:
1
for (int i=0; i<_smd.Skeleton.Count; i++)
2
{
3
  var bone = _bones[i];
4
  V3 temp;
5
  if (_smd.Skeleton.First(b => b.Name == bone.name).ParentBone == 0)
6
  {
7
    temp.x = _smd.Frames[_frame].Joints[i].Pos.Z;
8
    temp.y = _smd.Frames[_frame].Joints[i].Pos.X;
9
    temp.z = _smd.Frames[_frame].Joints[i].Pos.Y;
10
  }
11
  else
12
  {
13
    temp.x = _smd.Frames[_frame].Joints[i].Pos.X;
14
    temp.y = _smd.Frames[_frame].Joints[i].Pos.Z;
15
    temp.z = _smd.Frames[_frame].Joints[i].Pos.Y;
16
  }
17
 
18
  bone.locPos=temp;
19
 
20
  float newRotX = -_smd.Frames[_frame].Joints[i].Angle.X * Mathf.Rad2Deg;
21
  float newRotY = -_smd.Frames[_frame].Joints[i].Angle.Z * Mathf.Rad2Deg;
22
  float newRotZ = -_smd.Frames[_frame].Joints[i].Angle.Y * Mathf.Rad2Deg;
23
  if (_smd.Skeleton.First(b => b.Name == bone.name).ParentBone == -1)
24
    newRotZ -= 90;
25
 
26
  V3 rot=new V3(newRotX,newRotY,newRotZ);
27
  bone.localRot=rot;
28
}


Анимация прыжка стала выглядеть более-менее приемлемо(см вложение), по крайне мере её не выворачивает, но явно видно, что в работе с углами есть какая-то ошибка. Например, если загрузить анимацию смерти, то скелет упадёт на угол примерно 45 градусов от исходного, хотя должен упасть ровно на землю.

Далее, я попытался почитать код из Ксаша, но понял, что здесь замешана какая-то магия вроде матанализа или типа того. Короче не смог я понять что тут написано:
C++ Source Code:
1
cz = cos( zrotation );
2
sz = sin( zrotation );
3
 
4
while (fgets( line, sizeof( line ), input ) != NULL)
5
{
6
  linecount++;
7
  if (sscanf( line, "%d %f %f %f %f %f %f", &index, &pos[0], &pos[1], &pos[2], &rot[0], &rot[1], &rot[2] ) == 7)
8
  {
9
    if (t >= panim->startframe && t <= panim->endframe)
10
    {
11
      if (panim->node[index].parent == -1) {
12
        adjust_vertex( pos );
13
        panim->pos[index][t][0] = cz * pos[0] - sz * pos[1];
14
        panim->pos[index][t][1] = sz * pos[0] + cz * pos[1];
15
        panim->pos[index][t][2] = pos[2];
16
        // rotate model
17
        rot[2]			+= zrotation;
18
      }
19
      else
20
      {
21
        VectorCopy( pos, panim->pos[index][t] );
22
      }
23
      if (t > end)
24
        end = t;
25
      if (t < start)
26
        start = t;
27
 
28
      if (panim->node[index].mirrored)
29
        VectorScale( panim->pos[index][t], -1.0, panim->pos[index][t] );
30
 
31
      scale_vertex( panim->pos[index][t] );
32
 
33
      clip_rotations( rot );
34
 
35
      VectorCopy( rot, panim->rot[index][t] );
36
    }
37
  }


В связи с этим, если кто знает, прошу помощи. Подскажите, что там такого наворотили валвовцы с этими скелетами и как-ёптить их адекватно спарсить и отрисовать.

__________________
How interesting, just look at that!
© Scientist


Отправлено Дядя Миша 28-01-2021 в 09:07:

Z это Y
Y это X
X это Z

Цитата:
-=DrTressi=- писал:
Как перевести Тайта-Брайна к Эйлеру не понятно.

умножить на 57,295779513082320876798154814105

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено -=DrTressi=- 28-01-2021 в 09:45:

Дядя Миша

Цитата:
Z это Y
Y это X
X это Z

1. Это для углов или для смещения?
2. В каких случаях нужно добавлять минус к значению.
3. Для всех костей или для рутовой?
4. При чём здесь Zrotation и зачем синусы-косинусы?

Если вся проблема только в том, что система координат повёрнута, то оно бы решалось загрузкой без преобразований "как есть", с последующим поворотом рутовой кости на 90 градусов. Но это не канает почему-то.

Цитата:
умножить на 57,295779513082320876798154814105

Ну так это я делаю же:
code:
* Mathf.Rad2Deg

__________________
How interesting, just look at that!
© Scientist


Отправлено ncuxonaT 28-01-2021 в 11:22:

Если там заданы углы Тайта-Брайана, значит и матрицу поворота нужно брать для них, а не для Эйлера. Её можно на английской Википедии посмотреть. А одно в другое переводить - это лишний геморрой


Отправлено Дядя Миша 28-01-2021 в 12:27:

Цитата:
-=DrTressi=- писал:
Это для углов или для смещения?

Для углов.

Цитата:
-=DrTressi=- писал:
В каких случаях нужно добавлять минус к значению.

ни в каких

Цитата:
-=DrTressi=- писал:
Для всех костей или для рутовой?

для всех костей

Цитата:
-=DrTressi=- писал:
При чём здесь Zrotation и зачем синусы-косинусы?

Ну это, если моделька после компиляции смотрит боком или лежит, можно добавить Z-Rotation. А синусы-косинусы как раз и осуществляют это вращение.

Цитата:
-=DrTressi=- писал:
Если вся проблема только в том, что система координат повёрнута, то оно бы решалось загрузкой без преобразований "как есть", с последующим поворотом рутовой кости на 90 градусов. Но это не канает почему-то.

В прошлом народ упорно не хотел всё вращать честно. Экономил процессорное время. Поэтому вращение заменили свапом координат.
Что в дальнейшем добавило немало весёлых минут юным исследователям древних форматов.

Цитата:
-=DrTressi=- писал:
Ну так это я делаю же:

я понимаю. Но ты же зачем-то спросил?

Добавлено 28-01-2021 в 15:27:

Цитата:
ncuxonaT писал:
Если там заданы углы Тайта-Брайана

Углы Тайта-Брайана это подмножество углов Эйлера. Я не знаю чем они отличаются. Конкретно вот эти углы в smd - они в радианах, Эйлер обычно в градусах. Других отличий вроде бы нет. Углы как углы.

http://ru.knowledgr.com/00262803/УглыEuler

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Отправлено ncuxonaT 28-01-2021 в 12:57:

Цитата:
Дядя Миша писал:
Углы Тайта-Брайана это подмножество углов Эйлера. Я не знаю чем они отличаются.

Тем, что у обычного Эйлера первый и третий повороты идут по одной оси, а у Тайта-Брайана - по разным. Разные матрицы поворота используются. Pitch yaw roll - это как раз углы Тайта-Брайана


p.s. от таких переводов можно поехать кукухой


Отправлено Дядя Миша 28-01-2021 в 14:18:

Цитата:
ncuxonaT писал:
Разные матрицы поворота используются

Ну не знаю. Я использую те же самые матрицы, что и для обычного Эйлера.
Единственное отличие, да - я свапаю местами XYZ как написал выше.
Ну и конечно не перевожу градусы в радианы, поскольку там и так уже радианы.
Из чего следует вывод, что в кваках все углы Эйлера были в Тайт-Брайан формате, просто об этом как-то не упоминали.

__________________
My Projects: download page

F.A.Q по XashNT
Блог разработчика в телеграме

Цитата:

C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'


Временная зона GMT. Текущее время 22:14.
Показать все 7 сообщений этой темы на одной странице

На основе vBulletin версии 2.3.0
Авторское право © Jelsoft Enterprises Limited 2000 - 2002.
Дизайн и программирование: Crystice Softworks © 2005 - 2024