HLFX.Ru Forum (https://hlfx.ru/forum/index.php)
- Half-Life SDK (https://hlfx.ru/forum/forumdisplay.php?forumid=8)
-- Вопрос по SET_VIEW() (https://hlfx.ru/forum/showthread.php?threadid=4065)
Отправлено domded 29-08-2013 в 01:06:
Вопрос по SET_VIEW()
Здравствуйте, уважаемые форумчане! Достаточно много читал ваш форум, многому научился, но не могу разобраться с одним вопросом - как привязать к камеру к аттачменту на модели? Написал свой env_model и триггер, который при активации делает SET_VIEW() на эту модель. Модель анимированая, (в качестве примера взял руки при поднимании по лестнице из cof). У неё есть аттачменты, которые при просмотре в model viewer качаются из стороны в сторону. Собственно, вопрос. Как я понял, SET_VIEW ставит камеру куда-то в середину оной, и это ещё пол беды - она (функция) относится к движковым, насколько понимаю, и влезть в её код с целью изменить что-то нет никакой возможности ( не нашёл даже сообщения, которое сервер передаёт клиенту при вызове ). В StudioModelRenderer смотрел, но и там мало что понял. Не прошу тупо кода, а просто подтолкните меня в нужном направлении, как это сделать. В какие строчки смотреть, ну или хотя бы общую теорию объясните (может быть вообще не в ту сторону копаю, так же интересен сам механизм работы SET_VIEW, потому что вменяемой информации я нигде не нашёл, кроме камеры CTriggerCamera в оригинале, но камера аттачменты никак не учитывает). Буду благодарен.
з.ы. использую sdk 2.3 без спирита
Отправлено ILZM 29-08-2013 в 04:32:
triggers.cpp там че та есть вроде. И еще в Xashe есть привязка к аттачменту.
Отправлено Дядя Миша 29-08-2013 в 15:29:
Цитата:
domded писал:
Как я понял, SET_VIEW ставит камеру куда-то в середину оной
Просто в оригин модели.
Цитата:
domded писал:
не нашёл даже сообщения, которое сервер передаёт клиенту при вызове
svc_setview
очень простая функция, сообщает клиенту от позиции какой энтити рисовать вид. В view.cpp представлен весь код камеры, который нужен.
Вот это вот в функции V_CalcNormalRefdef
C++ Source Code:
1 | // override all previous settings if the viewent isn't the client |
2 | if ( pparams->viewentity > pparams->maxclients ) |
4 | cl_entity_t *viewentity; |
5 | viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); |
8 | VectorCopy( viewentity->origin, pparams->vieworg ); |
9 | VectorCopy( viewentity->angles, pparams->viewangles ); |
11 | // Store off overridden viewangles |
12 | v_angles = pparams->viewangles; |
вот оно копирует у вью-энтити оригин и углы. Берем из аттачмента новый оригин и норм. А углы можно рассчитать, как я уже объяснял в своём легендарном туториале.
Цитата:
ILZM писал:
И еще в Xashe есть привязка к аттачменту.
Там хитрее. Привязка произвольной энтити к аттачменту через парент-систему. Поэтому в явном виде этот код скопировать не получится.__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено domded 29-08-2013 в 17:54:
Примерно понял, о чём вы. Только не получается. Код StudioCalcAttachments взял из вашего тутора "получение углов аттачмента на клиенте". Привожу изменённый код указанного вами фрагмента в view.cpp ( такое ощущение, что изменённый код вообще не видит массива аттачментов, либо во всём массиве pattachments почему-то стоит позиция нулевого - в этой модели она там в центре у самой земли).
(пробовал ставить в pattachmebt[ ] любое значение, эффекта нет). Так же я не совсем понял, куда сохранять рассчитанные углы из CalcAttachments, вижу только вариант с изменением mstudioattachment_t. Но при любом добавлении полей в эту структуру игра ( закономерно, наверняка ) валится, так как это движковый тип.
C++ Source Code:
1 | if ( pparams->viewentity > pparams->maxclients ) |
3 | cl_entity_t *viewentity; |
4 | viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); |
7 | gEngfuncs.pfnConsolePrint("entered to special viewmode\n"); |
8 | cl_entity_t *ve = gEngfuncs.GetEntityByIndex(pparams->viewentity); |
11 | gEngfuncs.pfnConsolePrint("found special entity\n"); |
12 | studiohdr_t *vm = (studiohdr_t *)IEngineStudio.Mod_Extradata (ve->model); |
14 | sprintf(sz,"attachment %i\n",vm->attachmentindex); |
15 | gEngfuncs.pfnConsolePrint(sz); |
16 | //вопрос: vm->attachmentindex это некий глобальный оффест для прибавления в следующей строке? |
17 | mstudioattachment_t *pattachment = (mstudioattachment_t *)((byte *)vm + vm->attachmentindex+2); |
20 | gEngfuncs.pfnConsolePrint("vmodel fund, culc vactas hehehehe \n"); |
21 | pparams->vieworg[0] = pattachment[0].org[0] + ve->origin[0]; |
22 | pparams->vieworg[1] = pattachment[0].org[1] + ve->origin[1]; |
23 | pparams->vieworg[2] = pattachment[0].org[2] + ve->origin[2]; |
Добавлено 29-08-2013 в 21:54:
Раз уж нельзя редактировать тему, то спрошу ещё одним постом. С координатами аттачмента я разобрался, но они не меняются. то есть каждый фрейм анимации этих самых рук я получаю координаты те, которые есть в стоячей модели (при этой самой анимации руки движутся вверх, позиция енв_модел в мире не меняется). Следовательно, как можно прибавить к координатам аттачмента текущую позицию анимации?
Апд. Попробовал по похожей схеме получить кости, чтобы узнать их координаты и прибавить к координатам аттачмента. Но в mstudiobone_t нет координат. Откуда их можно вытащить?
Отправлено Дядя Миша 29-08-2013 в 19:31:
C++ Source Code:
1 | viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); |
4 | gEngfuncs.pfnConsolePrint("entered to special viewmode\n"); |
5 | cl_entity_t *ve = gEngfuncs.GetEntityByIndex(pparams->viewentity); |
а на кой два раза одно и то же делать?
C++ Source Code:
mstudioattachment_t *pattachment = (mstudioattachment_t *)((byte *)vm + vm->attachmentindex+2); |
вот так я бы делать зарёкся. Это в чистом Си такое прокатывает, а С++ полезет совсем не туда. Я и сам себя неоднократно ловил на этом.
Пишешь по привычке, по Сишному, хренак - вылет.
attachmentindex это смещение от начала буффера, по котрому мы попадём на структуру аттачментов.
Да ты собсно, ерундой занимаешься. org аттачмента локальный и имеет какие-нибудь смешные значения, типа 0.1 5.3 -2.0
прибавляя к нему оригин ты сдвинешь камеру настолько незначительно, что даже незаметишь этого.
Более того - всё это совершенно ненужно. Вот так делай:
C++ Source Code:
1 | if ( pparams->viewentity > pparams->maxclients ) |
3 | cl_entity_t *viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); |
6 | gEngfuncs.pfnConsolePrint("entered to special viewmode\n"); |
7 | VectorCopy( viewentity->attachment[2], pparams->vieworg ); |
Добавлено 29-08-2013 в 23:31:
Цитата:
domded писал:
Так же я не совсем понял, куда сохранять рассчитанные углы из CalcAttachments, вижу только вариант с изменением mstudioattachment_t.
Гы. Ну можешь в position_history_t писать. Она вроде только игроком используется, а в остальных энтитях болтается незанятой. Там как раз оригин и углы. 64 позиции = 64 аттачмента 
Цитата:
domded писал:
куда сохранять рассчитанные углы из CalcAttachments, вижу только вариант с изменением mstudioattachment_t.
Ну ты отдаешь себе отчёт, что запишешь трансформированный аттачмент в саму модель, копий которых в мире может быть сколько угодно? Это вьюмодель одна на всю игру.__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено domded 29-08-2013 в 22:51:
Странно. Проверил всё выводом в консоль. У всех аттачментов почему-то одинаковые позиции (viewentity->attachments[i], i - с 0 до 3), и с вашим кодом рассчёта, и с оригинальным вальвовским. Из-за чего такое может быть? Прикладываю модель в архиве.
Отправлено Дядя Миша 30-08-2013 в 16:52:
Да нормальная моделька, вполне.
К слову сказать, там вот эти два аттачмента для взгляда - они как раз из-за того, что кофовцы мой тутор не читали. И тянут вектор от одного аттачмента к другому, чтобы получить углы.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено domded 30-08-2013 в 17:53:
Это понятно. Но почему тогда у разных аттачментов в массиве viewentity->attachments одинаковая позиция? Код вывода позиций привожу, во вьюэнитити моделька точно та, которая и должна быть:
C++ Source Code:
1 | cl_entity_t *viewentity = gEngfuncs.GetEntityByIndex( pparams->viewentity ); |
5 | sprintf(sz,"attachments: 1: %f %f %f\n2: %f %f %f\n3: %f %f %f\n2: %f %f %f\n4: %f %f %f\n", |
6 | viewentity->attachment[0].x,viewentity->attachment[0].y,viewentity->attachment[0].z, |
7 | viewentity->attachment[1].x,viewentity->attachment[1].y,viewentity->attachment[1].z, |
8 | viewentity->attachment[2].x,viewentity->attachment[2].y,viewentity->attachment[2].z, |
9 | viewentity->attachment[3].x,viewentity->attachment[3].y,viewentity->attachment[3].z); |
10 | gEngfuncs.pfnConsolePrint(sz); |
Отправлено Дядя Миша 30-08-2013 в 18:29:
Ну я почём знаю, где ты накосячил? Чудес не бывает.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено domded 30-08-2013 в 19:14:
Появилось предположеие при просмотре кода - аттачменты для этих моделей считаются так же как и для оружия - сначала рендер, потом рассчёт?
Отправлено Дядя Миша 30-08-2013 в 20:07:
А какая разница? Они же не обнуляются с прошлого кадра.
Для вьюмодели (оружие в руках), аттачменты считаются ПЕРЕД началом кадра. Сделано это по одной-единственной причине - чтобы маззлфлэшы не отставали от оружия при выстрелах.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено domded 30-08-2013 в 23:42:
Я не так глубоко понимаю код рендера моделей халфы, чтобы понять, как всё это устроено.
Кстати, обнаружил ещё одну весьма странную вещь: если получать оригин аттачмента через mstudioattachment_t, то аттачи получаются такими, какими они и должны быть: нормальными и встающими туда куда надо (конечно, нужно прибавить глобальный оригин самой энтити). если же получать их через viewentity->attachment[index], то во всех индексах помещён xyz центра модели на нижней её грани - мировые координаты (глюк?).
Апд, через час:
Так же порылся в коде рендера и вообще ничего в этой жизни не понимаю: в коде studiodrawmodel условие if ( flags & STUDIO_EVENTS) . Моя моделька туда попадает. В блоке этом вызывается рассчёт атттачей ( StudioCalcAttachments() ) с учётом текущей позиции костей. Это есть. А потом начинается что-то невероятное: копирование памяти в указатель на аттачменты (ent->attachment,m_pCurrentEntity). Индекс у модели соответствует индексу моей модели с руками. Но в модели с руками ( из view.cpp, причём в m_pCurrentEntity из cstudiomodelrenderer координаты аттачей двигаются как положено, я проверил это консолью) всё равно остаются какие-то непонятные числа. Как это понимать? Я действительно не могу сам разобраться, уже всю голову себе сломал. Вроде бы там идёт прямой memcpy. В чём ошибка? Остальной код CalcNormalRefDef, кроме этого куска, я вообще не трогал. Но нашёл воркэраунд, так сказать. В gHUD передаю специальное сообщение ( с указанием индекса энтити, которую камера должна сейчас отследить ), запоминаю индекс энтити и создаю массив из трёх векторов. В студиодравмодель после вызова калькуляции аттачментов запихиваю мемсру m_pCurrentEntity->attachment в мою переменную с векторами в gHUD, потом использую её (мою переменную из гхуда) в CalcNormalRefDef. Тогда камера двигается нормально, как ей и положено. Что это за глюк такой-то, а?
Отправлено Дядя Миша 02-09-2013 в 16:43:
Да ерундой маешься. Прекрасно там всё воркает. Ты по сути нагромоздил лишнего и теперь пытаешься заставить его работать. А оно не нужно по сути.
Я тебе дал код - он должен работать. Если нет - смотри где косяк на сервере.
__________________
My Projects: download page
F.A.Q по XashNT
Блог разработчика в телеграме
Цитата:
C:\DOCUME~1\C4C5~1\LOCALS~1\Temp\a33328if(72) : see declaration of 'size_t'
Отправлено domded 12-09-2013 в 01:17:
Да, всё понял. Действительно у меня какие-то глюки могут быть, поскольку у меня в длл очень много изменений. Буду проверять на чистом. Спасибо вам большое.