Все та-же проблема с аттачами и их углами

tonline_kms65_1

Участник
Сообщения
565
Реакции
225

Всем здравствуйте.
Я уже не в первый раз касаюсь этой проблемы. Проблема в управлении углами поворота аттача.
В целом это наземный Дрон, что то типа NPC, передвигается по карте по вейпоинтам.
Тело Дрона здесь - корпус с гусеницами, на аттач тела прикреплена башня Дрона с пулеметом.
Если управлять поворотами тела Дрона, то естественно проблем не возникает - отрабатывается все просто на отлично. Но вот если управлять поворотом башни (аттача) то вот здесь возникают проблемы.
Сама схема кода у меня такая:
создаю два вектора, один вектор от тела Дрона до противника, второй вектор от башни Дрона(аттача) до противника.
Из вектора аттача получаю углы и пытаюсь по ним повернуть углы башни. Поворот естественно идет, но углы определенны не правильно, пытался ту-же процедуру проделать по вектору от тела Дрона до противника - ошибка та-же. Вариантов перепробовал массу уже.
На аттач я могу получить только абсолютные углы и координаты, на тело как относительные так и абсолютные. С относительными проблем нет, а вот с абсолютными проблема есть. Проблема именно с угловыми поворотами.
Кто с этим сталкивался - отпишитесь.
 

tonline_kms65_1

Участник
Сообщения
565
Реакции
225
покажи дебаг поворота на 360
Поворот на 360 я ограничиваю 180. Зачем 360?

Дебаг зачем? Я же объяснил принцип работы кода. Наити ошибки в коде? Ошибки я может быть и попросил бы исправить, тогда когда сам код полностью рабочий, а времени на оптимизацию нет. Это ведь не первая моя встреча с этой проблемой. Но вот проблему с углами до поры удавалось как то обходить.

Как смог так нарисовал:biggrin:. Попытался объяснить связь костей 3D модели и направлений векторов.
ABSpos.jpg ABSpos1.jpg
Так вот, при относительной системе все работает отлично.

К костям аттачей доступ только в виде абсолютных значений, и вот тогда-то и начинаются проблемы с поворотом углов. Углы поворачиваются с какой то заметной зависимостью. Я думаю зависимость от начала отсчета абсолютной системы, наверняка центр карты (но не факт).
Но, замечу, это мои личные наблюдения. Я не теоретик, я практик, поэтому возможно что то я и упустил. Вот поэтому и спрашиваю у тех, у кого подобный опыт был.
Проверка кода мне не нужна.

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

1. Независимый движек для тела (гусениц) ( движение по вейпоинтам, повороты, остановка на кемперских вейпоинтах с разворотом в направлении углов кемперского вейпоита, ожидание противника (время ожидания рендомно), для дверей и ступеней свои вейпоинты).
Ограничение "угла зрения" (это для того, что я пока не понял как делать видимость стен, или проще - не видеть вейпоинты через стены).

2. Независимый движек для башни - это постоянный сканер по оси Yaw(рыскание) (вправо-влево), поиск противников, здесь так же ограничение "угла зрения" (например, что бы можно было незамеченным подойти сзади ), анимация на модель, озвучка тревоги, выстрелов и т.д.
3. В планах был еще один независимый движек на пулемет, по координате Pitch(тангаж) (вверх-вниз).

Но пока не решу проблему с поворотом углов, естетсвенно, ничего у меня не получится. А проблема пока не решается.
 
Последнее редактирование:

Reg1oxeN

Участник
Сообщения
399
Реакции
314
я ограничиваю 180
и сиди теперь думай, как ты там ограничиваешь...
по исходникам все же как-то лучше ориентироваться.

вот смотри. если взять и запустить твоего дрона.
к углам башни вообще не касаемся. она вроде как должна смотреть всегда вперед.
при вращении самого дрона, башня вращается статично вместе с дроном?
 

tonline_kms65_1

Участник
Сообщения
565
Реакции
225
и сиди теперь думай, как ты там ограничиваешь...
по исходникам все же как-то лучше ориентироваться.
C-подобный:
//------------------------------------------------------------------------------
stock Float:NormalizeAngle( Float:flAngle ){
    while( flAngle > 180.0 ) flAngle -= 360.0;
    while( flAngle < -180.0 ) flAngle += 360.0;
    return flAngle;
}
вот смотри. если взять и запустить твоего дрона.
к углам башни вообще не касаемся. она вроде как должна смотреть всегда вперед.
при вращении самого дрона, башня вращается статично вместе с дроном?

Естественно.
При создании Дрона я аттачу к гусеницам башню, к башне станину, к станине стволы пулемета.
Всё это абсолютно отдельные, разные 3D модели. Это примерно как скелетная анимация - есть основная кость, все остальные кости подчиняются этой кости, т.е. при движении основной кости(здесь гусениц) все остальные кости так же перемещаются, то же самое и с углами - зависимость от основной кости. Основная кость абсолютно не зависит от дочерних.
После создания получается просто статичная модель Дрона.
statik.jpg
Если не пытаться управлять какими либо частями(3D моделями) этого Дрона, то он так и будет кататься по карте обычным "статиком" или "динамиком", но при желании, понятно, можно управлять каждой их этих составных моделей отдельно. Не знаю можно ли разделить их(переместить), но крутить по любой из 3 осей можно, причем совершенно независимо от остальных частей Дрона.
 

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,982
Из вектора аттача получаю углы и пытаюсь по ним повернуть углы башни. Поворот естественно идет, но углы определенны не правильно, пытался ту-же процедуру проделать по вектору от тела Дрона до противника - ошибка та-же. Вариантов перепробовал массу уже.
скинь этот кусок кода в личку, может что и подскажу
--- Добавлено позже ---
PHP:
stock Float:NormalizeAngle( Float:flAngle ){
   while( flAngle > 180.0 ) flAngle -= 360.0;
   while( flAngle < -180.0 ) flAngle += 360.0;
   return flAngle;
}
я это делал иначе:
PHP:
if(FloatAbs(flAngle) > 360) flAngle = FloatFraction(flAngle) + RoundToZero(flAngle) % 360;
а потом уже можно
PHP:
if(flAngle > 180) flAngle -= 360;
if(flAngle < -180) flAngle += 360;
 
Последнее редактирование:

Reg1oxeN

Участник
Сообщения
399
Реакции
314
при спавне и аттаче башни, как-то затрагиваются ее углы?
 

tonline_kms65_1

Участник
Сообщения
565
Реакции
225
скинь этот кусок кода в личку, может что и подскажу
я это делал иначе:
PHP:
if(FloatAbs(ang[j]) > 360) ang[j] = FloatFraction(ang[j]) + RoundToZero(ang[j]) % 360;

% - это у тебя из с++ mod?
Я, кстати, тоже пробовал переводить в абсолютные, толку и изменений никаких не увидел.
Потому что нет привязки к кости аттача (башни). Я думаю даже если скорректировать ошибку программно удастся, то на другой карте или на клиенте вполне возможна ошибка с углами. Поэтому я и хочу понять как прицепиться к костям.
--- Добавлено позже ---
при спавне и аттаче башни, как-то затрагиваются ее углы?
Нет. Я все углы сразу выставил при создании самой 3d модели (в 3dsmax) Угол аттача соответствует углу присоеденяемой кости модели.

Вообще, по хорошему, это делается кватернионами, поворачивается вокруг заданного вектора. Но реализовать здесь такую задумку....... это жесть. Просто не представляю как.
Поэтому и остается цепляться к костям, или к аттачам попробовать. Что то я об этом не думал.
Интересно а можно повернуть аттач? Если удастся повернуть атач => повернется и приаттаченная кость с моделью.
 
Последнее редактирование:

Reg1oxeN

Участник
Сообщения
399
Реакции
314
ну и получается, что просчитывать угол башни нужно исходя из углов самого дрона.
с этим как обстоят дела?
 

tonline_kms65_1

Участник
Сообщения
565
Реакции
225
при спавне и аттаче башни, как-то затрагиваются ее углы?
Нет. Я все углы выставил при создании 3dмодели
ну и получается, что просчитывать угол башни нужно исходя из углов самого дрона.
с этим как обстоят дела?
Я же об этом уже писал. Конечно я и так пробовал. Это была моя самая первая попытка. У тела(гусениц) углы относительные, у башни абсолютные т.к. башня приаттаченна к гусеницам. Я уже наверно все что можно перепробовал.
 

tonline_kms65_1

Участник
Сообщения
565
Реакции
225
PHP:
if(FloatAbs(flAngle) > 360) flAngle = FloatFraction(flAngle) + RoundToZero(flAngle) % 360;
а потом уже можно
PHP:
if(flAngle > 180) flAngle -= 360;
if(flAngle < -180) flAngle += 360;

Попробую на досуге использовать, посмотрю, мож что измениться. Отпишусь обязятельно.
--- Добавлено позже ---
нет, это из SourcePawn

Интересно, не думал что здесь работает. Век живи - век учись.
Вообще хочу заехать в политен, проконсультироваться, что получится если попробовать изменять относительные значения координат в привязке к абсолютным. Вернее как сделать такую связку. Во б... даже сам запутался.
И самое главное забыл сказать - при абсолютных значениях координаты положения (позиция) определяется правильно, без ошибок. Ошибка появляется именно при вращении углов.
 
Последнее редактирование:

Grey83

не пишу плагины с весны 2022
Сообщения
8,521
Реакции
4,982
Я, кстати, тоже пробовал переводить в абсолютные, толку и изменений никаких не увидел.
это нужно для получения модуля числа, чтобы делать одно сравнение, а не два
Вообще, по хорошему, это делается кватернионами, поворачивается вокруг заданного вектора.
если ничего не путаю, то так: bcserv/smlib
 

tonline_kms65_1

Участник
Сообщения
565
Реакции
225
@Reg1oxeN,
Спасибо за совет.
В общем картина получается следущая - на аттаче углы, "вручную", меняются правильно.
Причем, что интересно, угол меняется не в зависимости от начала координат, а от положения тела танка, т.е. если я задаю 90 градусов, башня поворачивается на 90 градусов относительно угла тела Дрона, я то думал что поворачиваться будет относительно начала координат {0.0, 0.0, 0.0} оказывается нет.
Получается что привязка кости к модели в норме. Ошибка видимо набирается в процессе выравнивания по вектору.
Есть над чем серьёзно подумать. Время появится - попробую, для начала, всё в радианы перевести.

Я так понял, ты предлагаешь сравнивать положения углов вектора направления и башни? Тоже интересная мысль.
Я то сразу пытаюсь выравнивать башню по вектору.
 

Reg1oxeN

Участник
Сообщения
399
Реакции
314
от положения тела танка
ну все правильно и работает. я же уже объяснил как высчитать нужный угол для башни, если сам не затупил конечно.

A - вектор в углы
B - углы дрона
С - углы башни

С = A - B;
 

tonline_kms65_1

Участник
Сообщения
565
Реакции
225
@Reg1oxeN,

Все! Готово.
Перевел для начала в радианы, это что-бы мне стало понятно было как оно всё работает.
И вот по результатам работы в радианах сразу стало понятно где была моя ошибка.
в идеале целевой yaw минус yaw дрона равен необходимому yaw башни.
Вот где компенсация ошибки. Этакая дельта. А я бы так и не сообразил до сих пор. Что то вообще зациклился на одном.
Так что спасибо тебе огромное за дельный совет.

если ничего не путаю, то так: bcserv/smlib
Кстати, очень интересная штучка. Это конечно не кватернион, и даже не матрица вращения. Но это реально крутит в пространстве, можно задать точку вращения и крутить вокруг неё по любой координате, или по всем. Пригодится. Не знаю правда как с оптимизацией дело обстоит, что то синусы, косинусы, но имеет место для существования точно. Конкретно вот это:
PHP:
/ * *
 * Вращает вектор вокруг нулевой точки.
 * Примечание. В качестве примера вы можете повернуть mins и maxs объекта, а затем добавить его начало в mins и maxs, чтобы получить свою ограничительную рамку по отношению к миру и его вращению.
 * При использовании с игроками используйте следующий угловой вход:
 * углы [0] = 0,0;
 * углы [1] = 0,0;
 * углы [2] = playerEyeAngles [1];
 *
 * @param vec Vector для поворота.
 * @param углы Как вращать вектор.
 * @param Результат Выходной вектор.
 * @без возврата
 * /
акций Math_RotateVector ( Const Поплавок : VEC [ 3 ], Const Поплавок : углы [ 3 ],  Float : результат [ 3 ])
{
    // Сначала расчет угла / радианта
    decl Float : rad [ 3 ];
    // Я действительно не знаю, почему, но альфа, бета, гамма-порядок углов испорчены ...
    // 2 = xAxis
    // 0 = yAxis
    // 1 = zAxis
    rad [ 0 ]  =  DegToRad ( углы [ 2 ]);
    rad [ 1 ]  =  DegToRad ( углы [ 0 ]);
    rad [ 2 ]  =  DegToRad ( углы [ 1 ]);

    // Запросы вызова Pre-calc
    new Float : cosAlpha =  косинус ( rad [ 0 ]);
    new Float : sinAlpha =  Sine ( rad [ 0 ]);
    новый Float : cosBeta =  косинус ( рад [ 1 ]);
    new Float : sinBeta =  Sine ( rad [ 1 ]);
    новый Float : cosGamma =  косинус ( рад [ 2 ]);
    new Float : sinGamma =  Sine ( rad [ 2 ]);

    // 3D-матрица вращения для получения дополнительной информации: http://en.wikipedia.org/wiki/Rotation_matrix#In_three_dimensions
    new Float : x = vec [ 0 ],  Float : y = vec [ 1 ],  Float : z = vec [ 2 ];
    новый Float : newX ,  Float : newY ,  Float : newZ ;
    newY = cosAlpha * y - sinAlpha * z ;
    newZ = cosAlpha * z + sinAlpha * y ;
    y = newY ;
    z = newZ ;

    newX = cosBeta * x + sinBeta * z ;
    newZ = cosBeta * z - sinBeta * x ;
    x = newX ;
    z = newZ ;

    newX = cosGamma * x - sinGamma * y ;
    newY = cosGamma * y + sinGamma * x ;
    x = newX ;
    y = newY ;

    // Хранить все ...
    result [ 0 ]  = x ;
    результат [ 1 ]  = y ;
    результат [ 2 ]  = z ;
}
--- Добавлено позже ---
Видео с исправленной ошибкой.
Осталось по мелочам:
- при отсутствии цели возврат башни в направление вперед.
- движек на станину с пулеметом (вверх-вниз).
- нужно сделать плавный поворот башни, наведение на цель. Я думаю нужно сделать это обязательно, а то как то нерально смотрится.

P.S.
Сейчас вектор до цели идет от тела (гусениц) Дрона, можно сделать этот вектор от башни, убеличить угол зрения и дальность, тогда башню будет крутить на 360 град. Правда, тогда у нему будет не подойти вообще. Короче простор для фантазии.
 
Последнее редактирование:
Сверху Снизу