HLFX.Ru Forum
профиль •  правила •  регистрация •  календарь •  народ •  FAQ •  поиск •  новое •  сутки •  главная •  выход  
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > Лажа со стрейфами
Подскажите пожалуйста, как подправить
Страницы (11): « Первая ... « 3 4 5 6 [7] 8 9 10 11 »   Предыдущая тема   Следующая тема
Автор
Тема Новая тема    Ответить
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6749
Возраст: 33

Рейтинг



Назрел вопрос: что делает этот кусок кода?

C++ Source Code:
1
for (i = 0; i < m_pStudioHeader->numbones; i++)
2
{
3
  QuaternionMatrix( q[i], bonematrix );
4
 
5
  bonematrix[0][3] = pos[i][0];
6
  bonematrix[1][3] = pos[i][1];
7
  bonematrix[2][3] = pos[i][2];
8
 
9
  if (pbones[i].parent == -1)
10
  {
11
    if ( IEngineStudio.IsHardware() )
12
    {
13
      ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_pbonetransform)[i]);
14
 
15
      // MatrixCopy should be faster...
16
      //ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]);
17
      MatrixCopy( (*m_pbonetransform)[i], (*m_plighttransform)[i] );
18
    }
19
    else
20
    {
21
      ConcatTransforms ((*m_paliastransform), bonematrix, (*m_pbonetransform)[i]);
22
      ConcatTransforms ((*m_protationmatrix), bonematrix, (*m_plighttransform)[i]);
23
    }
24
 
25
    // Apply client-side effects to the transformation matrix
26
    StudioFxTransform( m_pCurrentEntity, (*m_pbonetransform)[i] );
27
  }
28
  else
29
  {
30
    ConcatTransforms ((*m_pbonetransform)[pbones[i].parent], bonematrix, (*m_pbonetransform)[i]);
31
    ConcatTransforms ((*m_plighttransform)[pbones[i].parent], bonematrix, (*m_plighttransform)[i]);
32
  }
33
}

Про FX-траснформацию мне всё ясно, она на сервере не нужна. m_plighttransform это для освещения? Если да, то тоже нафиг не нужно на сервере.

StudioSlerpBones что именно интерполирует? Нужно ли это на сервере?

Сообщить модератору | | IP: Записан
Сообщение: 111211

Старое сообщение 14-12-2012 06:16
- За что?
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32263
Нанёс повреждений: 392 ед.

Рейтинг



Цитата:
Ku2zoff писал:
m_plighttransform это для освещения?

да
Цитата:
Ku2zoff писал:
StudioSlerpBones что именно интерполирует?

положение между прошлым и новым кадром.
Цитата:
Ku2zoff писал:
Нужно ли это на сервере?

Народу это не нужно. Народу плезиозавры нужны. Причём позарез.

__________________
My Projects: download page

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

Цитата:

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

Сообщить модератору | | IP: Записан
Сообщение: 111226

Старое сообщение 14-12-2012 15:07
-
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6749
Возраст: 33

Рейтинг



Дядя Миша спасибо, прояснил ситуацию

Сообщить модератору | | IP: Записан
Сообщение: 111262

Старое сообщение 15-12-2012 05:22
- За что?
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6749
Возраст: 33

Рейтинг



Нифга не получается. Ни портированный код с клиентки не фурычит, не перенесённый из ксаша. Причём под ксашем игра умудряется ещё и вылетать при обращении к pEdict. В исходниках движка ДМ оставил комментарий: Warning, pEdict is unused. Под GoldSRC не вылетает, но хитбоксы всё равно на полкарты. ЧЯДНТ?

Сообщить модератору | | IP: Записан
Сообщение: 111273

Старое сообщение 15-12-2012 14:13
- За что?
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32263
Нанёс повреждений: 392 ед.

Рейтинг



Ну почему у дяди Мишы всё прекрасно получается несколько раз и туда и обратно и бамп выдернули и на место вставили, а вы, толпой в пять человек уже четвертый год не можете решить ПРОСТЕЙШУЮ ПРОБЛЕМУ, почему, я не понимаю? Вам неприятно понимать что вы делаете? Вам интереснее тыкать наугад, пока не повезет или что?

__________________
My Projects: download page

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

Цитата:

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

Сообщить модератору | | IP: Записан
Сообщение: 111280

Старое сообщение 15-12-2012 14:42
-
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6749
Возраст: 33

Рейтинг



Вроде же всё как надо делаю. Есть SV_StudioSetupBones с выкинутыми интерполяцией между анимациями и проигрыванием гейт-секвенций. Из неё вызываются ещё функции, они тоже есть. Studio Header я задаю прямо в теле SV_StudioSetupBones. bonetransform и rotationmatrix беру из движка, как и на клиенте делается. blending тоже из движка, его на сервере считать не надо. (Для стандартного халфовского блендинга).

Сообщить модератору | | IP: Записан
Сообщение: 111282

Старое сообщение 15-12-2012 14:50
- За что?
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32263
Нанёс повреждений: 392 ед.

Рейтинг



Цитата:
Ku2zoff писал:
Вроде же всё как надо делаю

engine\common\mod_studio.c - готовая рабочая реализация на классический халфовский блендинг. Для начала перенеси в игровую библиотеку её. А потом расширь до 9-way.
Я уже молчал-молчал, думал догадаются. Но куда там! В стену головой долбится куда интереснее.

__________________
My Projects: download page

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

Цитата:

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

Сообщить модератору | | IP: Записан
Сообщение: 111284

Старое сообщение 15-12-2012 14:53
-
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6749
Возраст: 33

Рейтинг



Цитата:
Дядя Миша писал:
Вам интереснее тыкать наугад

По аналогии с клиентом сделал. Ну если нет документации, как я узнаю, что нужен ещё один таинственный вызов таинственной функции откуда-нибудь из кода серверной дллки? Я StudioPlayerBlend на сервере не делал. Ну он же не повлияет на хитбоксы? Он ведь за наклоны игрока отвечает.

Добавлено 15-12-2012 в 21:57:

Цитата:
Дядя Миша писал:
engine\common\mod_studio.c - готовая рабочая реализация на классический халфовский блендинг.

Я думал, нафига этот файл вообще нужен? В sv_studio то же самое. Или я невнимательно смотрел.

Сообщить модератору | | IP: Записан
Сообщение: 111285

Старое сообщение 15-12-2012 14:57
- За что?
marikcool
Житель форума

Дата регистрации: Jul 2011
Проживает: kz
Сообщений: 1522
Возраст: 38

Рейтинг



ты параметры у себя в SV_StudioSetupBones местами поменял?

__________________
vk.com/skullcapstudios

Сообщить модератору | | IP: Записан
Сообщение: 111287

Старое сообщение 15-12-2012 14:59
- За что?
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32263
Нанёс повреждений: 392 ед.

Рейтинг



Цитата:
Ku2zoff писал:
Я думал, нафига этот файл вообще нужен? В sv_studio то же самое

не совсем. sv_studio.c уже полгода как валяется там неподключенный.
Это наследие.
Цитата:
marikcool писал:
ты параметры у себя в SV_StudioSetupBones местами поменял?

поменял, но сорцев пока нету. Как и говорил - после ревизии.

__________________
My Projects: download page

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

Цитата:

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

Сообщить модератору | | IP: Записан
Сообщение: 111289

Старое сообщение 15-12-2012 15:03
-
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6749
Возраст: 33

Рейтинг



Цитата:
marikcool писал:
ты параметры у себя в SV_StudioSetupBones местами поменял?

После того как поменял, начало вылетать и под Goldsrc при обращении к pEdict.

Добавлено 16-12-2012 в 02:44:

Цитата:
Дядя Миша писал:
Для начала перенеси в игровую библиотеку её.

Переносится без проблем, только не работает. То ли дело в неправильных аргументах SV_StudioSetupBones, то ли в том, что вместо float'ов в ксашдвижке используется matrix3x4.

Сообщить модератору | | IP: Записан
Сообщение: 111300

Старое сообщение 15-12-2012 19:44
- За что?
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6749
Возраст: 33

Рейтинг



Простите, что поднимаю старую тему. Но несколько дней возни терять зря не хочется. На меня в последние дни что-то нашло, и я сделал ответную часть StudioSetupBones для 9-way blending'а на сервере. Благо, у нас теперь есть хоть какие-то исходники контр-страйка, и в них можно кое-что подглядеть
Ошибка была в том, что для 9-way нужен, как бы это сказать, более продвинутый рассчёт угла поворота игрока по YAW. На данный момент всё работает, но не очень точно. То есть хитбоксы располагаются правильно и меняют положение в зависимости от направления взгляда игрока, только серверная часть не совсем совпадает с клиентской. Скорее всего, дело в каких-то переменных на серверной стороне. Я в подробности не вдавался и не сравнивал. Как бы то ни было, есть база для дальнейшей работы.
В туторы не пишу, потому что это не тутор, а копипаста.

Шаг первый: клиентская сторона.

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

Шаг второй: серверная сторона. Рассчёт углов поворота и прочей ереси игрока.

Открываем player.cpp и копипастим туда в самый низ файла вот этот код:

C++ Source Code:
1
#include "studio.h"
2
 
3
void CBasePlayer::StudioProcessGait(void)
4
{
5
  mstudioseqdesc_t *pseqdesc;
6
  float dt = gpGlobals->frametime;
7
 
8
  if (dt < 0)
9
    dt = 0;
10
  else if (dt > 1.0)
11
    dt = 1;
12
 
13
  CalculateYawBlend();
14
  CalculatePitchBlend();
15
 
16
  void *model = GET_MODEL_PTR(ENT(pev));
17
 
18
  if (!model)
19
    return;
20
 
21
  studiohdr_t *pstudiohdr = (studiohdr_t *)model;
22
 
23
  pseqdesc = (mstudioseqdesc_t *)((byte *)pstudiohdr + pstudiohdr->seqindex) + pev->gaitsequence;
24
 
25
  if (pseqdesc->linearmovement[0] > 0)
26
    m_flGaitframe += (m_flGaitMovement / pseqdesc->linearmovement[0]) * pseqdesc->numframes;
27
  else
28
    m_flGaitframe += pseqdesc->fps * dt * pev->framerate;
29
 
30
  m_flGaitframe -= (int)(m_flGaitframe / pseqdesc->numframes) * pseqdesc->numframes;
31
 
32
  if (m_flGaitframe < 0)
33
    m_flGaitframe += pseqdesc->numframes;
34
 
35
  //	ALERT(at_notice, "Player sv_yaw: %f\n", m_flYaw);
36
  //	ALERT(at_notice, "Player sv_pitch: %f\n", m_flPitch);
37
  //	ALERT(at_notice, "Player sv_gaityaw: %f\n", m_flGaityaw);
38
}
39
 
40
void CBasePlayer::StudioEstimateGait(void)
41
{
42
  float dt;
43
  vec3_t est_velocity;
44
 
45
  dt = gpGlobals->frametime;
46
 
47
  if (dt < 0)
48
    dt = 0;
49
  else if (dt > 1)
50
    dt = 1;
51
 
52
  if (dt == 0)
53
  {
54
    m_flGaitMovement = 0;
55
    return;
56
  }
57
 
58
  est_velocity[0] = pev->origin[0] - m_prevgaitorigin[0];
59
  est_velocity[1] = pev->origin[1] - m_prevgaitorigin[1];
60
  est_velocity[2] = pev->origin[2] - m_prevgaitorigin[2];
61
  m_prevgaitorigin[0] = pev->origin[0];
62
  m_prevgaitorigin[1] = pev->origin[1];
63
  m_prevgaitorigin[2] = pev->origin[2];
64
  m_flGaitMovement = sqrt(est_velocity[0] * est_velocity[0] + est_velocity[1] * est_velocity[1] + est_velocity[2] * est_velocity[2]);
65
 
66
  if (dt <= 0 || m_flGaitMovement / dt < 5)
67
  {
68
    m_flGaitMovement = 0;
69
    est_velocity[0] = est_velocity[1] = 0;
70
  }
71
 
72
  if (est_velocity[0] == 0 && est_velocity[1] == 0)
73
  {
74
    float flYawDiff = pev->angles[1] - m_flGaityaw;
75
    float flYaw = flYawDiff;
76
    flYawDiff = flYawDiff - (int)(flYawDiff / 360) * 360;
77
 
78
    if (flYawDiff > 180)
79
      flYawDiff -= 360;
80
 
81
    if (flYawDiff < -180)
82
      flYawDiff += 360;
83
 
84
    if (flYaw < -180)
85
      flYaw += 360;
86
    else if (flYaw > 180)
87
      flYaw -= 360;
88
 
89
    if (flYaw > -5 && flYaw < 5)
90
      m_flYawModifier = 0.05;
91
 
92
    if (flYaw < -90 || flYaw > 90)
93
      m_flYawModifier = 3.5;
94
 
95
    if (dt < 0.25)
96
      flYawDiff *= dt * m_flYawModifier;
97
    else
98
      flYawDiff *= dt;
99
 
100
    if (abs(flYawDiff) < 0.1)
101
      flYawDiff = 0;
102
 
103
    m_flGaityaw += flYawDiff;
104
    m_flGaityaw -= (int)(m_flGaityaw / 360) * 360;
105
    m_flGaitMovement = 0;
106
  }
107
  else
108
  {
109
    m_flGaityaw = (atan2(est_velocity[1], est_velocity[0]) * 180 / M_PI);
110
 
111
    if (m_flGaityaw > 180)
112
      m_flGaityaw = 180;
113
 
114
    if (m_flGaityaw < -180)
115
      m_flGaityaw = -180;
116
  }
117
}
118
 
119
void CBasePlayer::CalculateYawBlend(void)
120
{
121
  float dt;
122
  float flYaw;
123
  float maxyaw;
124
  float blend_yaw;
125
 
126
  dt = gpGlobals->frametime;
127
 
128
  if (dt < 0)
129
    dt = 0;
130
  else if (dt > 1)
131
    dt = 1;
132
 
133
  StudioEstimateGait();
134
 
135
  maxyaw = 255.0;
136
  flYaw = pev->angles[1] - m_flGaityaw;
137
 
138
  if (flYaw < -180)
139
    flYaw += 360;
140
  else if (flYaw > 180)
141
    flYaw -= 360;
142
 
143
  if (m_flGaitMovement != 0)
144
  {
145
    if (flYaw > 120)
146
    {
147
      m_flGaityaw -= 180;
148
      m_flGaitMovement = -m_flGaitMovement;
149
      flYaw -= 180;
150
    }
151
    else if (flYaw < -120)
152
    {
153
      m_flGaityaw += 180;
154
      m_flGaitMovement = -m_flGaitMovement;
155
      flYaw += 180;
156
    }
157
  }
158
 
159
  flYaw = (flYaw / 90) * 128.0 + 127.0;
160
 
161
  if (flYaw > 255)
162
    flYaw = 255;
163
  else if (flYaw < 0)
164
    flYaw = 0;
165
 
166
  blend_yaw = maxyaw - flYaw;
167
  pev->blending[0] = (int)(blend_yaw);
168
  m_flYaw = blend_yaw;
169
}
170
 
171
void CBasePlayer::CalculatePitchBlend(void)
172
{
173
  int iBlend;
174
  float temp;
175
 
176
  temp = (int)(pev->angles[0] * 3);
177
 
178
  if (temp <= -45)
179
    iBlend = 255;
180
  else if (temp < 45)
181
    iBlend = ((45.0 - temp) / (45.0 + 45)) * 255;
182
  else
183
    iBlend = 0;
184
 
185
  pev->blending[1] = iBlend;
186
  m_flPitch = iBlend;
187
}
188
 
189
float GetPlayerYaw(const edict_t *pEdict)
190
{
191
  entvars_t *pev = VARS((edict_t *)pEdict);
192
  CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance(pev);
193
 
194
  if (!pPlayer)
195
    return 0;
196
 
197
  return pPlayer->m_flYaw;
198
}
199
 
200
float GetPlayerPitch(const edict_t *pEdict)
201
{
202
  entvars_t *pev = VARS((edict_t *)pEdict);
203
  CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance(pev);
204
 
205
  if (!pPlayer)
206
    return 0;
207
 
208
  return pPlayer->m_flPitch;
209
}
210
 
211
int GetPlayerGaitsequence(const edict_t *pEdict)
212
{
213
  entvars_t *pev = VARS((edict_t *)pEdict);
214
  CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance(pev);
215
 
216
  if (!pPlayer)
217
    return 0;
218
 
219
  return pPlayer->m_iGaitsequence;
220
}
221
 
222
float GetPlayerGaitframe(const edict_t *pEdict)
223
{
224
  entvars_t *pev = VARS((edict_t *)pEdict);
225
  CBasePlayer *pPlayer = (CBasePlayer *)CBaseEntity::Instance(pev);
226
 
227
  if (!pPlayer)
228
    return 0;
229
 
230
  return pPlayer->m_flGaitframe;
231
}
232
 
233
float GetPlayerGaitYaw(int playerIndex)
234
{
235
  CBasePlayer *pPlayer = NULL;
236
 
237
  if (playerIndex > 0 && playerIndex <= gpGlobals->maxClients)
238
  {
239
    edict_t *pPlayerEdict = INDEXENT(playerIndex);
240
 
241
    if (pPlayerEdict && !pPlayerEdict->free)
242
    {
243
      pPlayer = (CBasePlayer *)CBaseEntity::Instance(pPlayerEdict);
244
 
245
      if (pPlayer)
246
        return pPlayer->m_flGaityaw;
247
    }
248
  }
249
 
250
  return 0;
251
}
Кто разобрался с клиентской частью, тот поймёт, что здесь для чего. Далее открываем player.h и добавляем в класс игрока заголовки новых функций и новые переменные:
C++ Source Code:
1
void StudioProcessGait( void );
2
void StudioEstimateGait( void );
3
void CalculateYawBlend( void );
4
void CalculatePitchBlend( void );
5
 
6
float m_flYaw;
7
float m_flPitch;
8
float m_flGaitMovement;
9
float m_flGaitframe;
10
float m_flGaityaw;
11
float m_flYawModifier;
12
int m_iGaitsequence;
13
vec3_t m_prevgaitorigin;

Компилим, если без ошибок - всё сделали правильно. Теперь находим в player.cpp функцию void CBasePlayer::PostThink() и в самый её низ вставляем:
C++ Source Code:
m_iGaitsequence = pev->gaitsequence;
StudioProcessGait();

Надо же откуда-то вызывать все эти новые рассчёты, верно?
Далее, идём в функцию Spawn игрока, она находится ниже. В самое её начало засовываем:
C++ Source Code:
m_flGaitMovement = 0;
m_flGaitframe = 0;
m_flGaityaw = 0;
m_iGaitsequence = 0;
m_prevgaitorigin = Vector(0, 0, 0);

Чтобы новые переменные обнулялись при спавне. Компилим. Без ошибок - молодцы!

Шаг третий: серверная сторона. Собственно, ответная часть блендинга.

Сразу скажу, что на правильность работы этот код не претендует, т.к. я только-только начал более или менее разбираться в механизме работы студиомодельрендерера. Но, судя по моим нескольким тестам, он работает, хоть и не совсем точно.

Открываем animation.cpp (да, копипастить удобнее в него, потому что почти всё нужные заголовки уже подключены), в самый низ вставляем вот этот код:
C++ Source Code:
1
#include <assert.h>
2
#include "r_studioint.h"
3
#include "com_model.h"
4
 
5
#ifndef M_PI
6
#define M_PI 3.14159265358979323846
7
#endif
8
 
9
void SV_StudioSetupBones( struct model_s *pModel, float frame, int sequence, const vec3_t angles, const	vec3_t origin, const byte *pcontroller, const byte *pblending, int iBone, const edict_t *pEdict );
10
 
11
server_studio_api_t IEngineStudio;
12
studiohdr_t			*g_pStudioHeader;
13
 
14
float (*g_pRotationMatrix)[3][4];
15
float (*g_pBoneTransform)[MAXSTUDIOBONES][3][4];
16
 
17
sv_blending_interface_t sv_blending =
18
{
19
  SV_BLENDING_INTERFACE_VERSION,
20
  SV_StudioSetupBones
21
};
22
 
23
extern "C" _declspec(dllexport) int Server_GetBlendingInterface( int version, sv_blending_interface_t **pinterface, server_studio_api_t *pstudio, float ***rotationmatrix, float ****bonetransform )
24
{
25
  if (version != SV_BLENDING_INTERFACE_VERSION)
26
    return 0;
27
 
28
  *pinterface = &sv_blending;
29
 
30
  IEngineStudio.Mem_Calloc = pstudio->Mem_Calloc;
31
  IEngineStudio.Cache_Check = pstudio->Cache_Check;
32
  IEngineStudio.LoadCacheFile = pstudio->LoadCacheFile;
33
  IEngineStudio.Mod_Extradata = pstudio->Mod_Extradata;
34
 
35
  g_pRotationMatrix = (float (*)[3][4])rotationmatrix;
36
  g_pBoneTransform = (float (*)[MAXSTUDIOBONES][3][4])bonetransform;
37
 
38
  ALERT(at_console, "Server_GetBlendingInterface exported.\n");
39
 
40
  return 1;
41
}

Это недостающие заголовки и определения, а также код экспорта интерфейса. Ниже вставляем математические функции:
C++ Source Code:
1
void ConcatTransforms(const float in1[3][4], const float in2[3][4], float out[3][4])
2
{
3
  out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
4
  out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
5
  out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
6
  out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3];
7
  out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0];
8
  out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1];
9
  out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2];
10
  out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3];
11
  out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0];
12
  out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
13
  out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
14
  out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
15
}
16
 
17
void AngleQuaternion(const vec3_t angles, vec4_t quaternion)
18
{
19
  float angle;
20
  float sr, sp, sy, cr, cp, cy;
21
 
22
  angle = angles[2] * 0.5;
23
  sy = sin(angle);
24
  cy = cos(angle);
25
  angle = angles[1] * 0.5;
26
  sp = sin(angle);
27
  cp = cos(angle);
28
  angle = angles[0] * 0.5;
29
  sr = sin(angle);
30
  cr = cos(angle);
31
 
32
  quaternion[0] = sr * cp * cy - cr * sp * sy;
33
  quaternion[1] = cr * sp * cy + sr * cp * sy;
34
  quaternion[2] = cr * cp * sy - sr * sp * cy;
35
  quaternion[3] = cr * cp * cy + sr * sp * sy;
36
}
37
 
38
void QuaternionSlerp(const vec4_t p, vec4_t q, float t, vec4_t qt)
39
{
40
  int i;
41
  float omega, cosom, sinom, sclp, sclq;
42
  float a = 0;
43
  float b = 0;
44
 
45
  for (i = 0; i < 4; i++)
46
  {
47
    a += (p[i]-q[i]) * (p[i]-q[i]);
48
    b += (p[i]+q[i]) * (p[i]+q[i]);
49
  }
50
 
51
  if (a > b)
52
  {
53
    for (i = 0; i < 4; i++)
54
      q[i] = -q[i];
55
  }
56
 
57
  cosom = p[0] * q[0] + p[1] * q[1] + p[2] * q[2] + p[3] * q[3];
58
 
59
  if ((1.0 + cosom) > 0.00000001)
60
  {
61
    if ((1.0 - cosom) > 0.00000001)
62
    {
63
      omega = acos(cosom);
64
      sinom = sin(omega);
65
      sclp = sin((1.0 - t) * omega) / sinom;
66
      sclq = sin(t * omega) / sinom;
67
    }
68
    else
69
    {
70
      sclp = 1.0 - t;
71
      sclq = t;
72
    }
73
 
74
    for (i = 0; i < 4; i++)
75
      qt[i] = sclp * p[i] + sclq * q[i];
76
  }
77
  else
78
  {
79
    qt[0] = -p[1];
80
    qt[1] = p[0];
81
    qt[2] = -p[3];
82
    qt[3] = p[2];
83
    sclp = sin((1.0 - t) * 0.5 * M_PI);
84
    sclq = sin(t * 0.5 * M_PI);
85
 
86
    for (i = 0; i < 3; i++)
87
      qt[i] = sclp * p[i] + sclq * qt[i];
88
  }
89
}
90
 
91
void QuaternionMatrix(const vec4_t quaternion, float (*matrix)[4])
92
{
93
  matrix[0][0] = 1.0 - 2.0 * quaternion[1] * quaternion[1] - 2.0 * quaternion[2] * quaternion[2];
94
  matrix[1][0] = 2.0 * quaternion[0] * quaternion[1] + 2.0 * quaternion[3] * quaternion[2];
95
  matrix[2][0] = 2.0 * quaternion[0] * quaternion[2] - 2.0 * quaternion[3] * quaternion[1];
96
  matrix[0][1] = 2.0 * quaternion[0] * quaternion[1] - 2.0 * quaternion[3] * quaternion[2];
97
  matrix[1][1] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[2] * quaternion[2];
98
  matrix[2][1] = 2.0 * quaternion[1] * quaternion[2] + 2.0 * quaternion[3] * quaternion[0];
99
  matrix[0][2] = 2.0 * quaternion[0] * quaternion[2] + 2.0 * quaternion[3] * quaternion[1];
100
  matrix[1][2] = 2.0 * quaternion[1] * quaternion[2] - 2.0 * quaternion[3] * quaternion[0];
101
  matrix[2][2] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[1] * quaternion[1];
102
}

Их можно без изменений упереть из клиентской части.
А теперь очередь функций настройки костей. В чистом виде с клиента их не перенесёшь, нужна модификация. Но можно взять из ксашдвижка, что я и сделал. Вставляем ниже:
C++ Source Code:
1
void StudioCalcBoneAdj( float *adj, const byte *pcontroller )
2
{
3
  int			i, j;
4
  float			value;
5
  mstudiobonecontroller_t	*pbonecontroller;
6
 
7
  pbonecontroller = (mstudiobonecontroller_t *)((byte *)g_pStudioHeader + g_pStudioHeader->bonecontrollerindex);
8
 
9
  for( j = 0; j < g_pStudioHeader->numbonecontrollers; j++ )
10
  {
11
    i = pbonecontroller[j].index;
12
 
13
    //		if( i == STUDIO_MOUTH )
14
    //			continue; // ignore mouth
15
 
16
    if( i <= MAXSTUDIOCONTROLLERS )
17
    {
18
      // check for 360% wrapping
19
      if( pbonecontroller[j].type & STUDIO_RLOOP )
20
      {
21
        value = pcontroller[i] * (360.0f / 256.0f) + pbonecontroller[j].start;
22
      }
23
      else
24
      {
25
        value = pcontroller[i] / 255.0f;
26
        if (value < 0.0f) value = 0.0f;
27
        if (value > 1.0f) value = 1.0f;
28
        value = (1.0f - value) * pbonecontroller[j].start + value * pbonecontroller[j].end;
29
      }
30
    }
31
 
32
    switch( pbonecontroller[j].type & STUDIO_TYPES )
33
    {
34
    case STUDIO_XR:
35
      case STUDIO_YR:
36
        case STUDIO_ZR:
37
            adj[j] = value * (M_PI / 180.0f);
38
          break;
39
        case STUDIO_X:
40
          case STUDIO_Y:
41
            case STUDIO_Z:
42
                adj[j] = value;
43
              break;
44
            }
45
        }
46
    }
47
 
48
void StudioCalcBoneQuaterion( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *q )
49
{
50
  int		j, k;
51
  vec4_t		q1, q2;
52
  vec3_t		angle1, angle2;
53
  mstudioanimvalue_t	*panimvalue;
54
 
55
  for( j = 0; j < 3; j++ )
56
  {
57
    if( panim->offset[j+3] == 0 )
58
    {
59
      angle2[j] = angle1[j] = pbone->value[j+3]; // default;
60
    }
61
    else
62
    {
63
      panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j+3]);
64
      k = frame;
65
 
66
      // debug
67
      if( panimvalue->num.total < panimvalue->num.valid )
68
        k = 0;
69
 
70
      while( panimvalue->num.total <= k )
71
      {
72
        k -= panimvalue->num.total;
73
        panimvalue += panimvalue->num.valid + 1;
74
        // DEBUG
75
        if( panimvalue->num.total < panimvalue->num.valid )
76
          k = 0;
77
      }
78
      // Bah, missing blend!
79
      if( panimvalue->num.valid > k )
80
      {
81
        angle1[j] = panimvalue[k+1].value;
82
 
83
        if( panimvalue->num.valid > k + 1 )
84
        {
85
          angle2[j] = panimvalue[k+2].value;
86
        }
87
        else
88
        {
89
          if( panimvalue->num.total > k + 1 )
90
            angle2[j] = angle1[j];
91
          else angle2[j] = panimvalue[panimvalue->num.valid+2].value;
92
        }
93
      }
94
      else
95
      {
96
        angle1[j] = panimvalue[panimvalue->num.valid].value;
97
        if( panimvalue->num.total > k + 1 )
98
        {
99
          angle2[j] = angle1[j];
100
        }
101
        else
102
        {
103
          angle2[j] = panimvalue[panimvalue->num.valid + 2].value;
104
        }
105
      }
106
      angle1[j] = pbone->value[j+3] + angle1[j] * pbone->scale[j+3];
107
      angle2[j] = pbone->value[j+3] + angle2[j] * pbone->scale[j+3];
108
    }
109
 
110
    if( pbone->bonecontroller[j+3] != -1 )
111
    {
112
      angle1[j] += adj[pbone->bonecontroller[j+3]];
113
      angle2[j] += adj[pbone->bonecontroller[j+3]];
114
    }
115
  }
116
 
117
  if( !VectorCompare( angle1, angle2 ))
118
  {
119
    AngleQuaternion( angle1, q1 );
120
    AngleQuaternion( angle2, q2 );
121
    QuaternionSlerp( q1, q2, s, q );
122
  }
123
  else
124
  {
125
    AngleQuaternion( angle1, q );
126
  }
127
}
128
 
129
void StudioCalcBonePosition( int frame, float s, mstudiobone_t *pbone, mstudioanim_t *panim, float *adj, float *pos )
130
{
131
  int		j, k;
132
  mstudioanimvalue_t	*panimvalue;
133
 
134
  for( j = 0; j < 3; j++ )
135
  {
136
    pos[j] = pbone->value[j]; // default;
137
    if( panim->offset[j] != 0.0f )
138
    {
139
      panimvalue = (mstudioanimvalue_t *)((byte *)panim + panim->offset[j]);
140
 
141
      k = frame;
142
 
143
      // debug
144
      if( panimvalue->num.total < panimvalue->num.valid )
145
        k = 0;
146
 
147
      // find span of values that includes the frame we want
148
      while( panimvalue->num.total <= k )
149
      {
150
        k -= panimvalue->num.total;
151
        panimvalue += panimvalue->num.valid + 1;
152
 
153
        // DEBUG
154
        if( panimvalue->num.total < panimvalue->num.valid )
155
          k = 0;
156
      }
157
 
158
      // if we're inside the span
159
        if( panimvalue->num.valid > k )
160
        {
161
          // and there's more data in the span
162
          if( panimvalue->num.valid > k + 1 )
163
          {
164
            pos[j] += (panimvalue[k+1].value * (1.0f - s) + s * panimvalue[k+2].value) * pbone->scale[j];
165
          }
166
        else
167
        {
168
          pos[j] += panimvalue[k+1].value * pbone->scale[j];
169
        }
170
      }
171
      else
172
      {
173
        // are we at the end of the repeating values section and there's another section with data?
174
        if( panimvalue->num.total <= k + 1 )
175
        {
176
          pos[j] += (panimvalue[panimvalue->num.valid].value * (1.0f - s) + s * panimvalue[panimvalue->num.valid + 2].value) * pbone->scale[j];
177
        }
178
        else
179
        {
180
          pos[j] += panimvalue[panimvalue->num.valid].value * pbone->scale[j];
181
        }
182
      }
183
    }
184
 
185
    if( pbone->bonecontroller[j] != -1 && adj )
186
    {
187
      pos[j] += adj[pbone->bonecontroller[j]];
188
    }
189
  }
190
}
191
 
192
mstudioanim_t *StudioGetAnim(model_t *model, mstudioseqdesc_t *pseqdesc)
193
{
194
  mstudioseqgroup_t *pseqgroup = (mstudioseqgroup_t *)((byte *)g_pStudioHeader + g_pStudioHeader->seqgroupindex) + pseqdesc->seqgroup;
195
 
196
  if (!pseqdesc->seqgroup)
197
    return (mstudioanim_t *)((byte *)g_pStudioHeader + pseqdesc->animindex);
198
 
199
  cache_user_t *paSequences = (cache_user_t *)model->submodels;
200
 
201
  if (!paSequences)
202
  {
203
    paSequences = (cache_user_t *)IEngineStudio.Mem_Calloc(16, sizeof(cache_user_t));
204
    model->submodels = (dmodel_t *)paSequences;
205
  }
206
 
207
  if (!IEngineStudio.Cache_Check(&paSequences[pseqdesc->seqgroup]))
208
    IEngineStudio.LoadCacheFile(pseqgroup->name, &paSequences[pseqdesc->seqgroup]);
209
 
210
  return (mstudioanim_t *)((byte *)paSequences[pseqdesc->seqgroup].data + pseqdesc->animindex);
211
}
212
 
213
float StudioEstimateFrame( float frame, mstudioseqdesc_t *pseqdesc )
214
{
215
  double	f;
216
 
217
  if( pseqdesc->numframes <= 1 )
218
    f = 0.0f;
219
  else f = ( frame * ( pseqdesc->numframes - 1 )) / 256.0f;
220
 
221
  if( pseqdesc->flags & STUDIO_LOOPING )
222
  {
223
    if( pseqdesc->numframes > 1 )
224
      f -= (int)(f / (pseqdesc->numframes - 1)) *  (pseqdesc->numframes - 1);
225
    if( f < 0.0f ) f += (pseqdesc->numframes - 1);
226
  }
227
  else
228
  {
229
    if( f >= pseqdesc->numframes - 1.001f )
230
      f = pseqdesc->numframes - 1.001f;
231
    if( f < 0.0f )  f = 0.0f;
232
  }
233
 
234
  return f;
235
}
236
 
237
void StudioCalcRotations( int boneused[], int numbones, const byte *pcontroller, float pos[][3], vec4_t *q, mstudioseqdesc_t *pseqdesc, mstudioanim_t *panim, float f )
238
{
239
  int		i, j, frame;
240
  mstudiobone_t	*pbone;
241
  float		adj[MAXSTUDIOCONTROLLERS];
242
  float		s;
243
 
244
  if( f > pseqdesc->numframes - 1 )
245
    f = 0.0f;
246
  else if( f < -0.01f )
247
    f = -0.01f;
248
 
249
  frame = (int)f;
250
  s = (f - frame);
251
 
252
  // add in programtic controllers
253
  pbone = (mstudiobone_t *)((byte *)g_pStudioHeader + g_pStudioHeader->boneindex);
254
 
255
  StudioCalcBoneAdj( adj, pcontroller );
256
 
257
  for( j = numbones - 1; j >= 0; j-- )
258
  {
259
    i = boneused[j];
260
    StudioCalcBoneQuaterion( frame, s, &pbone[i], &panim[i], adj, q[i] );
261
    StudioCalcBonePosition( frame, s, &pbone[i], &panim[i], adj, pos[i] );
262
  }
263
 
264
  if( pseqdesc->motiontype & STUDIO_X ) pos[pseqdesc->motionbone][0] = 0.0f;
265
  if( pseqdesc->motiontype & STUDIO_Y ) pos[pseqdesc->motionbone][1] = 0.0f;
266
  if( pseqdesc->motiontype & STUDIO_Z ) pos[pseqdesc->motionbone][2] = 0.0f;
267
}
268
 
269
void StudioSlerpBones( vec4_t q1[], float pos1[][3], vec4_t q2[], float pos2[][3], float s )
270
{
271
  int	i;
272
  vec4_t	q3;
273
  float	s1;
274
 
275
  if (s < 0.0f) s = 0.0f;
276
  else if (s > 1.0f) s = 1.0f;
277
  s1 = 1.0f - s;
278
 
279
  for( i = 0; i < g_pStudioHeader->numbones; i++ )
280
  {
281
    QuaternionSlerp( q1[i], q2[i], s, q3 );
282
    q1[i][0] = q3[0];
283
    q1[i][1] = q3[1];
284
    q1[i][2] = q3[2];
285
    q1[i][3] = q3[3];
286
    pos1[i][0] = pos1[i][0] * s1 + pos2[i][0] * s;
287
    pos1[i][1] = pos1[i][1] * s1 + pos2[i][1] * s;
288
    pos1[i][2] = pos1[i][2] * s1 + pos2[i][2] * s;
289
  }
290
}
291
 
292
/*
293
====================
294
LookupAnimation
295
->index starts at 0 for the first set of bones
296
====================
297
*/
298
mstudioanim_t* LookupAnimation( model_t *pModel, mstudioseqdesc_t *pseqdesc, int index )
299
{
300
  mstudioanim_t *panim = NULL;
301
 
302
  panim = StudioGetAnim( pModel, pseqdesc );
303
 
304
  assert( panim );
305
 
306
  if ( index < 0 )
307
  {
308
    return panim;
309
  }
310
 
311
  if ( index > ( pseqdesc->numblends - 1 ) )
312
  {
313
    return panim;
314
  }
315
 
316
  panim += index * g_pStudioHeader->numbones;
317
 
318
  return panim;
319
}


Остальное напишу потом, ибо просто не влазит в сообщение Не пугайтесь

Напишите уже кто-нибудь что-нибудь, а то сообщение редактируется, а не добавляется новое.

Сообщить модератору | | IP: Записан
Сообщение: 131406

Старое сообщение 23-01-2014 08:11
- За что?
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6749
Возраст: 33

Рейтинг



Ниже вставляете саму настройку костей:

C++ Source Code:
1
void SV_StudioSetupBones_HL( struct model_s *pModel, float frame, int sequence, const vec3_t angles, const	vec3_t origin, const byte *pcontroller, const byte *pblending, int iBone, const edict_t *pEdict )
2
{
3
  int		i, j, numbones = 0;
4
  int		boneused[MAXSTUDIOBONES];
5
  double	f;
6
 
7
  mstudiobone_t		*pbones;
8
  mstudioseqdesc_t	*pseqdesc;
9
  mstudioanim_t		*panim;
10
 
11
  static float	pos[MAXSTUDIOBONES][3];
12
  static vec4_t	q[MAXSTUDIOBONES];
13
  float			bonematrix[3][4];
14
 
15
  static float	pos2[MAXSTUDIOBONES][3];
16
  static vec4_t	q2[MAXSTUDIOBONES];
17
  static float	pos3[MAXSTUDIOBONES][3];
18
  static vec4_t	q3[MAXSTUDIOBONES];
19
  static float	pos4[MAXSTUDIOBONES][3];
20
  static vec4_t	q4[MAXSTUDIOBONES];
21
 
22
  g_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(pModel);
23
 
24
  if( sequence < 0 || sequence >= g_pStudioHeader->numseq )
25
  {
26
    ALERT( at_notice, "SV_StudioSetupBones: sequence %i/%i out of range for model %s\n", sequence, g_pStudioHeader->numseq, g_pStudioHeader->name );
27
    sequence = 0;
28
  }
29
 
30
  pseqdesc = (mstudioseqdesc_t *)((byte *)g_pStudioHeader + g_pStudioHeader->seqindex) + sequence;
31
  pbones = (mstudiobone_t *)((byte *)g_pStudioHeader + g_pStudioHeader->boneindex);
32
  panim = StudioGetAnim( pModel, pseqdesc );
33
 
34
  if( iBone < -1 || iBone >= g_pStudioHeader->numbones )
35
    iBone = 0;
36
 
37
  if( iBone == -1 )
38
  {
39
    numbones = g_pStudioHeader->numbones;
40
    for( i = 0; i < g_pStudioHeader->numbones; i++ )
41
      boneused[(numbones - i) - 1] = i;
42
  }
43
  else
44
  {
45
    // only the parent bones
46
    for( i = iBone; i != -1; i = pbones[i].parent )
47
      boneused[numbones++] = i;
48
  }
49
 
50
  f = StudioEstimateFrame( frame, pseqdesc );
51
  StudioCalcRotations( boneused, numbones, pcontroller, pos, q, pseqdesc, panim, f );
52
 
53
  if( pseqdesc->numblends > 1 )
54
  {
55
    float	s;
56
 
57
    panim += g_pStudioHeader->numbones;
58
    StudioCalcRotations( boneused, numbones, pcontroller, pos2, q2, pseqdesc, panim, f );
59
 
60
    s = (float)pblending[0] / 255.0f;
61
 
62
    StudioSlerpBones( q, pos, q2, pos2, s );
63
 
64
    if( pseqdesc->numblends == 4 )
65
    {
66
      panim += g_pStudioHeader->numbones;
67
      StudioCalcRotations( boneused, numbones, pcontroller, pos3, q3, pseqdesc, panim, f );
68
 
69
      panim += g_pStudioHeader->numbones;
70
      StudioCalcRotations( boneused, numbones, pcontroller, pos4, q4, pseqdesc, panim, f );
71
 
72
      s = (float)pblending[0] / 255.0f;
73
      StudioSlerpBones( q3, pos3, q4, pos4, s );
74
 
75
      s = (float)pblending[1] / 255.0f;
76
      StudioSlerpBones( q, pos, q3, pos3, s );
77
    }
78
  }
79
 
80
  AngleMatrix(angles, (*g_pRotationMatrix));
81
 
82
  (*g_pRotationMatrix)[0][3] = origin[0];
83
  (*g_pRotationMatrix)[1][3] = origin[1];
84
  (*g_pRotationMatrix)[2][3] = origin[2];
85
 
86
  for( j = numbones - 1; j >= 0; j-- )
87
  {
88
    i = boneused[j];
89
 
90
    QuaternionMatrix(q[i], bonematrix);
91
 
92
    bonematrix[0][3] = pos[i][0];
93
    bonematrix[1][3] = pos[i][1];
94
    bonematrix[2][3] = pos[i][2];
95
 
96
    if( pbones[i].parent == -1 )
97
      ConcatTransforms((*g_pRotationMatrix), bonematrix, (*g_pBoneTransform)[i]);
98
    else
99
      ConcatTransforms((*g_pBoneTransform)[pbones[i].parent], bonematrix, (*g_pBoneTransform)[i]);
100
  }
101
 
102
  ALERT(at_notice, "SV_StudioSetupBones_HL processing.\n");
103
}

Это функция для 2-way блендинга, если вам нужно, чтобы правильно работали монстры.
C++ Source Code:
1
#define ANIM_SWIM_1					10
2
#define ANIM_SWIM_2					11
3
#define ANIM_FIRST_DEATH_SEQUENCE	30
4
 
5
float GetPlayerYaw(const edict_t *pEdict);
6
float GetPlayerPitch(const edict_t *pEdict);
7
int GetPlayerGaitsequence(const edict_t *pEdict);
8
float GetPlayerGaitframe(const edict_t *pEdict);
9
float GetPlayerGaitYaw(int playerIndex);
10
 
11
void SV_StudioSetupBones( struct model_s *pModel, float frame, int sequence, const vec3_t angles, const	vec3_t origin, const byte *pcontroller, const byte *pblending, int iBone, const edict_t *pEdict )
12
{
13
  int		i, j, numbones = 0;
14
  int		boneused[MAXSTUDIOBONES];
15
  double	f;
16
 
17
  mstudiobone_t		*pbones;
18
  mstudioseqdesc_t	*pseqdesc;
19
  mstudioanim_t		*panim;
20
 
21
  static float	pos[MAXSTUDIOBONES][3];
22
  static vec4_t	q[MAXSTUDIOBONES];
23
  float			bonematrix[3][4];
24
 
25
  static float	pos2[MAXSTUDIOBONES][3];
26
  static vec4_t	q2[MAXSTUDIOBONES];
27
  static float	pos3[MAXSTUDIOBONES][3];
28
  static vec4_t	q3[MAXSTUDIOBONES];
29
  static float	pos4[MAXSTUDIOBONES][3];
30
  static vec4_t	q4[MAXSTUDIOBONES];
31
 
32
  vec3_t temp_angles;
33
 
34
  if ((pEdict && !(pEdict->v.flags & FL_CLIENT)) || !pEdict)
35
  {
36
    SV_StudioSetupBones_HL( pModel, frame, sequence, angles, origin, pcontroller, pblending, iBone, pEdict );
37
    return;
38
  }
39
 
40
  g_pStudioHeader = (studiohdr_t *)IEngineStudio.Mod_Extradata(pModel);
41
 
42
  if( sequence < 0 || sequence >= g_pStudioHeader->numseq )
43
  {
44
    ALERT( at_notice, "SV_StudioSetupBones: sequence %i/%i out of range for model %s\n", sequence, g_pStudioHeader->numseq, g_pStudioHeader->name );
45
    sequence = 0;
46
  }
47
 
48
  pseqdesc = (mstudioseqdesc_t *)((byte *)g_pStudioHeader + g_pStudioHeader->seqindex) + sequence;
49
  pbones = (mstudiobone_t *)((byte *)g_pStudioHeader + g_pStudioHeader->boneindex);
50
  panim = StudioGetAnim( pModel, pseqdesc );
51
 
52
  if( iBone < -1 || iBone >= g_pStudioHeader->numbones )
53
    iBone = 0;
54
 
55
  if( iBone == -1 )
56
  {
57
    numbones = g_pStudioHeader->numbones;
58
    for( i = 0; i < g_pStudioHeader->numbones; i++ )
59
      boneused[(numbones - i) - 1] = i;
60
  }
61
  else
62
  {
63
    // only the parent bones
64
    for( i = iBone; i != -1; i = pbones[i].parent )
65
      boneused[numbones++] = i;
66
  }
67
 
68
  f = StudioEstimateFrame( frame, pseqdesc );
69
 
70
  if ( pseqdesc->numblends == 9 )
71
  {
72
    float s = GetPlayerYaw(pEdict);	// yaw (left -> right)
73
    float t = GetPlayerPitch(pEdict);	// pitch (top -> bottom)
74
 
75
    // nine-way blends are done left -> right, top -> bottom
76
 
77
    /***********************
78
 
79
    			0	-	1	-	2
80
 
81
    			|	\	|	/	|
82
 
83
    			3	-	4	-	5
84
 
85
    			|	/	|	\	|
86
 
87
    			6	-	7	-	8
88
 
89
    		 ***********************/
90
 
91
    // Blending is 0-127 == Left to Middle, 128 to 255 == Middle to Right
92
    if ( s <= 127.0 )
93
    {
94
      // Scale 0-127 blending up to 0-255
95
      s = ( s * 2.0 );
96
 
97
      if ( t <= 127.0 )
98
      {
99
        // Blending is 0-127 == Top to Middle, 128 to 255 == Middle to Bottom
100
        t = ( t * 2.0 );
101
 
102
        // need to blend 0 - 1 - 3 - 4
103
 
104
        StudioCalcRotations( boneused, numbones, pcontroller, pos, q, pseqdesc, panim, f );
105
        panim = LookupAnimation( pModel, pseqdesc, 1 );
106
        StudioCalcRotations( boneused, numbones, pcontroller, pos2, q2, pseqdesc, panim, f );
107
        panim = LookupAnimation( pModel, pseqdesc, 3 );
108
        StudioCalcRotations( boneused, numbones, pcontroller, pos3, q3, pseqdesc, panim, f );
109
        panim = LookupAnimation( pModel, pseqdesc, 4 );
110
        StudioCalcRotations( boneused, numbones, pcontroller, pos4, q4, pseqdesc, panim, f );
111
      }
112
      else
113
      {
114
        // Scale 128-255 blending up to 0-255
115
        t = 2.0 * ( t - 127.0 );
116
 
117
        // need to blend 3 - 4 - 6 - 7
118
 
119
        panim = LookupAnimation( pModel, pseqdesc, 3 );
120
        StudioCalcRotations( boneused, numbones, pcontroller, pos, q, pseqdesc, panim, f );
121
        panim = LookupAnimation( pModel, pseqdesc, 4 );
122
        StudioCalcRotations( boneused, numbones, pcontroller, pos2, q2, pseqdesc, panim, f );
123
        panim = LookupAnimation( pModel, pseqdesc, 6 );
124
        StudioCalcRotations( boneused, numbones, pcontroller, pos3, q3, pseqdesc, panim, f );
125
        panim = LookupAnimation( pModel, pseqdesc, 7 );
126
        StudioCalcRotations( boneused, numbones, pcontroller, pos4, q4, pseqdesc, panim, f );
127
      }
128
    }
129
    else
130
    {
131
      // Scale 127-255 blending up to 0-255
132
      s = 2.0 * ( s - 127.0 );
133
 
134
      if ( t <= 127.0 )
135
      {
136
        // Blending is 0-127 == Top to Middle, 128 to 255 == Middle to Bottom
137
        t = ( t * 2.0 );
138
 
139
        // need to blend 1 - 2 - 4 - 5
140
 
141
        panim = LookupAnimation( pModel, pseqdesc, 1 );
142
        StudioCalcRotations( boneused, numbones, pcontroller, pos, q, pseqdesc, panim, f );
143
        panim = LookupAnimation( pModel, pseqdesc, 2 );
144
        StudioCalcRotations( boneused, numbones, pcontroller, pos2, q2, pseqdesc, panim, f );
145
        panim = LookupAnimation( pModel, pseqdesc, 4 );
146
        StudioCalcRotations( boneused, numbones, pcontroller, pos3, q3, pseqdesc, panim, f );
147
        panim = LookupAnimation( pModel, pseqdesc, 5 );
148
        StudioCalcRotations( boneused, numbones, pcontroller, pos4, q4, pseqdesc, panim, f );
149
      }
150
      else
151
      {
152
        // Scale 128-255 blending up to 0-255
153
        t = 2.0 * ( t - 127.0 );
154
 
155
        // need to blend 4 - 5 - 7 - 8
156
 
157
        panim = LookupAnimation( pModel, pseqdesc, 4 );
158
        StudioCalcRotations( boneused, numbones, pcontroller, pos, q, pseqdesc, panim, f );
159
        panim = LookupAnimation( pModel, pseqdesc, 5 );
160
        StudioCalcRotations( boneused, numbones, pcontroller, pos2, q2, pseqdesc, panim, f );
161
        panim = LookupAnimation( pModel, pseqdesc, 7 );
162
        StudioCalcRotations( boneused, numbones, pcontroller, pos3, q3, pseqdesc, panim, f );
163
        panim = LookupAnimation( pModel, pseqdesc, 8 );
164
        StudioCalcRotations( boneused, numbones, pcontroller, pos4, q4, pseqdesc, panim, f );
165
      }
166
    }
167
 
168
    // Normalize interpolants
169
    s /= 255.0;
170
    t /= 255.0;
171
 
172
    // Spherically interpolate the bones
173
    StudioSlerpBones( q, pos, q2, pos2, s );
174
    StudioSlerpBones( q3, pos3, q4, pos4, s );
175
 
176
    StudioSlerpBones( q, pos, q3, pos3, t );
177
  }
178
  else
179
  {
180
    StudioCalcRotations( boneused, numbones, pcontroller, pos, q, pseqdesc, panim, f );
181
  }
182
 
183
  // calc gait animation
184
  // death sequences are last in the list of sequences, and we don't do gait for those
185
  // ANIM_FIRST_DEATH_SEQUENCE marks the first death sequence
186
  if ( pEdict &&
187
  sequence < ANIM_FIRST_DEATH_SEQUENCE &&
188
  sequence != ANIM_SWIM_1 &&
189
  sequence != ANIM_SWIM_2 )
190
  {
191
    int copy = 1;
192
 
193
    int gaitsequence = GetPlayerGaitsequence(pEdict);
194
 
195
    if (gaitsequence >= g_pStudioHeader->numseq)
196
      gaitsequence = 0;
197
 
198
    if (gaitsequence < 0)
199
      gaitsequence = 0;
200
 
201
    pseqdesc = (mstudioseqdesc_t *)( (byte *)g_pStudioHeader + g_pStudioHeader->seqindex ) + gaitsequence;
202
 
203
    panim = StudioGetAnim( pModel, pseqdesc );
204
    StudioCalcRotations( boneused, numbones, pcontroller, pos2, q2, pseqdesc, panim, GetPlayerGaitframe(pEdict) );
205
 
206
    for ( i = 0; i < g_pStudioHeader->numbones; i++ )
207
    {
208
      if ( !strcmp( pbones[i].name, "Bip01 Spine" ) )
209
      {
210
        copy = 0;
211
      }
212
      else if ( !strcmp( pbones[ pbones[i].parent ].name, "Bip01 Pelvis" ) )
213
      {
214
        copy = 1;
215
      }
216
 
217
      if ( copy )
218
      {
219
        memcpy( pos[i], pos2[i], sizeof( pos[i] ) );
220
        memcpy( q[i], q2[i], sizeof( q[i] ) );
221
      }
222
    }
223
  }
224
 
225
  VectorCopy(angles, temp_angles);
226
 
227
  if (pEdict)
228
  {
229
    temp_angles[1] = GetPlayerGaitYaw(g_engfuncs.pfnIndexOfEdict(pEdict));
230
 
231
    if (temp_angles[1] < 0)
232
      temp_angles[1] += 360;
233
  }
234
 
235
  AngleMatrix(temp_angles, (*g_pRotationMatrix));
236
 
237
  (*g_pRotationMatrix)[0][3] = origin[0];
238
  (*g_pRotationMatrix)[1][3] = origin[1];
239
  (*g_pRotationMatrix)[2][3] = origin[2];
240
 
241
  for( j = numbones - 1; j >= 0; j-- )
242
  {
243
    i = boneused[j];
244
 
245
    QuaternionMatrix(q[i], bonematrix);
246
 
247
    bonematrix[0][3] = pos[i][0];
248
    bonematrix[1][3] = pos[i][1];
249
    bonematrix[2][3] = pos[i][2];
250
 
251
    if( pbones[i].parent == -1 )
252
      ConcatTransforms((*g_pRotationMatrix), bonematrix, (*g_pBoneTransform)[i]);
253
    else
254
      ConcatTransforms((*g_pBoneTransform)[pbones[i].parent], bonematrix, (*g_pBoneTransform)[i]);
255
  }
256
 
257
  ALERT(at_notice, "SV_StudioSetupBones processing.\n");
258
}

А это 9-way. При необходимости можете убрать проверку на игрока и не использовать функцию для 2-way. Вот и всё.

Сообщить модератору | | IP: Записан
Сообщение: 131445

Старое сообщение 23-01-2014 13:08
- За что?
 Дядя Миша
racing for fish

Дата регистрации: Oct 2005
Проживает: Кубань
Сообщений: 32263
Нанёс повреждений: 392 ед.

Рейтинг



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

Добавлено 23-01-2014 в 19:43:

Поглядел код. Ну навскидку - лерпинг надо убрать к чертям, на сервере он не нужен. И самое главное - pEdict всё-таки последний аргумент или iBone? Кто кого обманывает? Valve или maricool?

__________________
My Projects: download page

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

Цитата:

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

Сообщить модератору | | IP: Записан
Сообщение: 131464

Старое сообщение 23-01-2014 15:43
-
Ku2zoff
Мастер Ёда из Деревни Дуракоф

Дата регистрации: Apr 2007
Проживает: В Деревне дураков
Сообщений: 6749
Возраст: 33

Рейтинг



Дядя Миша я же написал, что это пока не тутор. Я понял, как работает StudioSetupBones, а в остальную прочую математику не вдавался, потому что со школы её терпеть не могу. Лерпинг вырежу, когда оформлю в виде тутора. Тогда кстати, сможешь затереть эти два моих поста. Ну или оставить в назидание другим, как хочешь. Я кстати разобрался, почему хитбоксы на сервере не совпадали с клиентскими и уже это поправил.

Цитата:
Дядя Миша писал:
И самое главное - pEdict всё-таки последний аргумент или iBone? Кто кого обманывает? Valve или maricool?

Когда аргументы располагаются как у Valve, то всё работает. Стоит поменять местами - вылетает под голдсорсом. Под ксашем наоборот, но началось это после того, как ты поменял аргументы местами в движке. А вообще, эдикт приходит верный, иначе yaw/pitch игрока невозможно было бы получить. И ещё - я делал в новом СДК, что в репозитарии валяется, не думаю, что Valve оставили бы код с такой ошибкой, учитывая, что там кусок контры в виде ботов имеется.

Сообщить модератору | | IP: Записан
Сообщение: 131478

Старое сообщение 23-01-2014 16:04
- За что?
Тема: (Опционально)
Ваш ответ:



Переводчик транслита


[проверить длину сообщения]
Опции: Автоматическое формирование ссылок: автоматически добавлять [url] и [/url] вокруг интернет адресов.
Уведомление по E-Mail: отправить вам уведомление, если кто-то ответил в тему (только для зарегистрированных пользователей).
Отключить смайлики в сообщении: не преобразовывать текстовые смайлики в картинки.
Показать подпись: добавить вашу подпись в конец сообщения (только зарегистрированные пользователи могут иметь подписи).

Временная зона GMT. Текущее время 00:19. Новая тема    Ответить
Страницы (11): « Первая ... « 3 4 5 6 [7] 8 9 10 11 »   Предыдущая тема   Следующая тема
HLFX.Ru Forum HLFX.Ru Forum > Теория и практика > Half-Life SDK > Лажа со стрейфами
Подскажите пожалуйста, как подправить
Версия для печати | Отправить тему по E-Mail | Подписаться на эту тему

Быстрый переход:
Оцените эту тему:

Правила Форума:
Вы not можете создавать новые темы
Вы not можете отвечать в темы
Вы not можете прикреплять вложения
Вы not можете редактировать ваши сообщения
HTML Код ВЫКЛ
vB Код ВКЛ
Смайлики ВКЛ
[IMG] Код ВКЛ
 

< Обратная связь - HLFX.ru >

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