Математические и механические задачи в GTA - Страница 9 - Форум
Суббота, 10.12.2016, 13:44
Качественные скрипты, моды и дополнения для GTA без регистрации
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 9 из 10«1278910»
Форум » Игры серии ГТА » Скриптинг » Математические и механические задачи в GTA (Применение знаний математики и механики в моддинге)
Математические и механические задачи в GTA
BoPoHДата: Воскресенье, 27.05.2012, 01:57 | Сообщение # 121
Группа: Проверенные
Сообщений: 53
Статус: Offline
Реально ли разделить одну матрицу на вторую? Т.е. определить положение одного базиса относительно второго? Т.е. к примеру: M1 * M2 = M3. Нам известны M1 и M3, надо вычислить M2. Как это сделать? (M1,M2,M3 - матрицы).

First-Person mode 85% done
Добро всегда побеждает зло. Кто победил, тот и добрый!

 
Den_spbДата: Воскресенье, 27.05.2012, 15:45 | Сообщение # 122
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: Offline
Деление - это умножение на обратное число (1/x). То есть, вместо
Code
z = y : x
можно написать
Code
z = y * 1/x
или, применяя степенные обозначения
Code
z = y * x^(-1)

С матрицами всё аналогично - вместо деления применяется умножение на обратную матрицу:
Code
M2 = M1^(-1) * M3

В gta_sa.exe есть специальная функция для нахождения обратной матрицы:
Code
0AA5: call 0x7F2070 num_params 2 pop 2 $InputMatrix $InverseMatrix
 
BoPoHДата: Понедельник, 28.05.2012, 21:44 | Сообщение # 123
Группа: Проверенные
Сообщений: 53
Статус: Offline
Den_spb, спасибо, попробую.

UPD. Вроде всё работает, спасибо большое)

Добавлено (28.05.2012, 21:44)
---------------------------------------------
А ннет... что-то ерундит. С ровными векторами (типа 1.0 0.0 0.0) всё норм, а вот если я получаю матрицу кости и хочу вычислить положение камеры относительно этой кости, то получается какая-то хрень. По какому принципу инвертируется матрица? Может там что-то не так?

PS. Матрица кости и камеры нормальные, проверял.


First-Person mode 85% done
Добро всегда побеждает зло. Кто победил, тот и добрый!



Сообщение отредактировал BoPoH - Понедельник, 28.05.2012, 21:45
 
Den_spbДата: Понедельник, 28.05.2012, 23:05 | Сообщение # 124
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: Offline
Quote (BoPoH)
и хочу вычислить положение камеры относительно этой кости
Что конкретно надо пересчитать? Координаты или углы?
Для пересчёта координат надо умножать матрицу на вектор Pos (формулы пересчёта координат тут: http://modsforgta.ucoz.ru/forum/12-62-2769-16-1324692231 ).
Пересчёт углов производится похожим образом, но в этом случае обоими множителями будут матрицы (напомню пример пересчёта углов: http://modsforgta.ucoz.ru/forum/5-24-3091-16-1327680876 ). Здесь надо только перемножить матрицы - дополнительно прибавлять или отнимать что-либо не нужно.

Quote (BoPoH)
По какому принципу инвертируется матрица? Может там что-то не так?

Если интересна теория, то она приведена тут: http://ru.wikipedia.org/wiki/Обратная_матрица (см. метод матрицы алгебраических дополнений)
Нашёл у себя в запасах примерчик обратного пересчёта координат (из глобальных в локальные):
Code
{$CLEO}         // глоб - лок
0000:
while true
             wait 0
             if
                 not player.Defined($player_char)
             then
                 continue
             end
                      
             04C4: store_coords_to 0@ 1@ 2@ from_actor $player_actor with_offset 0.0 3.0 0.0          
             04D5: create_corona_at 0@ 1@ 2@ radius 1.0 type 2 flare 2 RGB 0 255 0          

             // 0 1 2 <-- мировые координаты
             actor.StorePos($player_actor 7@ 8@ 9@) // car.storepos(29@ 7@ 8@ 9@)
             0063: 0@ -= 7@ // (float)          
             0063: 1@ -= 8@ // (float)          
             0063: 2@ -= 9@ // (float)          
                      
             0A96: 3@ = actor $PLAYER_ACTOR struct  // 0A97: 3@ = car 29@ struct
             3@ += 0x14
             0A8D: 3@ = read_memory 3@ size 4 virtual_protect 0
             0AC7: 4@ = var 0@ offset
             0AC7: 6@ = var 7@ offset
             0AC6: 5@ = label @inverse_matrix offset
                          
             0AA5: call 0x7F2070 num_params 2 pop 2 3@ 5@ // Нахождение обратной матрицы
             0AA5: call 0x59C790 num_params 3 pop 3 4@ 5@ 6@ // Пересчёт координат из одной системы в другую
             // 7 8 9 --> оффсеты
                      
             04C4: store_coords_to 10@ 11@ 12@ from_actor $player_actor with_offset 7@ 8@ 9@           
             04D5: create_corona_at 10@ 11@ 12@ radius 1.0 type 2 flare 2 RGB 0 0 255
end

:inverse_matrix
hex
             00 00 00 00     00 00 00 00     00 00 00 00     00 00 00 00
             00 00 00 00     00 00 00 00     00 00 00 00     00 00 00 00
             00 00 00 00     00 00 00 00     00 00 00 00     00 00 00 00
             00 00 00 00     00 00 00 00     00 00 00 00     00 00 00 00
end
Код создаёт одну корону на заданных оффсетах от игрока, затем пересчитывает мировые координаты этой короны обратно в оффсеты относительно игрока и создаёт в данной точке вторую корону. Позиции корон совпадают, что свидетельствует о правильности вычислений.
Как видно, для умножения матрицы на вектор применяется специальная функция - 0x59C790.
 
BoPoHДата: Понедельник, 28.05.2012, 23:57 | Сообщение # 125
Группа: Проверенные
Сообщений: 53
Статус: Offline
Den_spb, Нет. Мне нужны не координаты и не углы. Именно матрица. Попробую объяснить. Предположим, что матрица M1 - это матрица кости. Матрица M3 - это матрица камеры. Мне нужно вычислить такую матрицу M2, чтобы выполнялось следующее условие - M1 * M2 = M3. На самом деле мне нужно повернуть голову в ту же сторону, куда смотрит камера. И не стоит предлагать опкоды типа 06A9. Здесь фишка в другом. Я хочу использовать это в режиме от первого лица, а там возможен вариант, когда игрок перевёрнут (к примеру, перевёрнуто авто). Здесь стандартные опкоды не помогут. То же самое, если я хочу повернуть голову во время анимации.
Теперь о алгоритме, который я хочу использовать. У меня нет возможности изменить матрицу кости, к сожалению, если бы это было возможно, я бы не просил помощи. Есть лишь возможность использовать кватернионы костей. Также, у меня есть возможность конвертировать матрицу в кватернион. Но, как мы знаем, кватернион - это вращение кости относительно родительской кости. Т.е. чтобы получить такой кватернион нам нужно вычислить положение камеры относительно родительской кости, выражая это в матрице, которую затем можно сконвертировать в кватернион и применить к необходимой кости (в данном случае эта кость - голова). Вот теперь нужно как-то вычислить эту самую "относительную" матрицу.
Если существуют какие-то варианты с вычислениями без матриц, а, к примеру, через кватернионы - излагай. Я могу получить и матрицу и кватернион любой кости, если что, но менять можно только кватернион.


First-Person mode 85% done
Добро всегда побеждает зло. Кто победил, тот и добрый!

 
Den_spbДата: Вторник, 29.05.2012, 01:15 | Сообщение # 126
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: Offline
Quote (BoPoH)
Den_spb, Нет. Мне нужны не координаты и не углы. Именно матрица.

Под "углами" я подразумевал первые три строчки матрицы (векторы Right, Top, At).
Ну что ж, алгоритм ты придумал верный, молодец. Только надо ещё иметь в виду, что при перемножении матриц матрицы-множители нельзя менять местами - результат будет другой.
Что имеем:
М(локальный поворот головы) * М(глобальный поворот шеи) = М(глобальный поворот камеры)
Отсюда:
М(локальный поворот головы) = М(глобальный поворот камеры) * М(глобальный поворот шеи)^(-1)
Попробуй - именно в этом порядке.
 
BoPoHДата: Воскресенье, 03.06.2012, 14:03 | Сообщение # 127
Группа: Проверенные
Сообщений: 53
Статус: Offline
Den_spb, Похоже ошибка была в другом. Где-то что-то с переменными напутал.
Quote (Den_spb)
М(локальный поворот головы) * М(глобальный поворот шеи) = М(глобальный поворот камеры)

Нет, как раз-таки (глобальный поворот шеи) * (локальный поворот головы). Я уже проверял как-то на другом примере, нужно умножать глобальную матрциу на локальную. Если делать наоборот - получается белиберда.
Ещё одна проблема была в том, что кватернион кости головы развёрнут на 90 градусов против часовой стрелки по оси Y, что я смог увидеть в максе на скелете игрока. Далее дело оставалось за малым - перемножить матрицу, которую я уже получил, на матрицу, развёрнутую на 270 градусов по Y. Всё работает зашибенно smile
Спасибо большое за помощь, респект и уважуха!) Уже не раз выручаешь biggrin

Добавлено (03.06.2012, 14:03)
---------------------------------------------
Ещё вопрос. Я недавно спрашивал, как сделать плавный переход от одной матрицы к другой (тут). А можно ли это сделать с кватернионами? Т.е. плавный переход от одного кватерниона к другому? Т.е., предположим, у меня есть 2 кватерниона кости, начальный и конечный, мне нужно повернуть эту кость от начального кватерниона к конечному за какое-то время.


First-Person mode 85% done
Добро всегда побеждает зло. Кто победил, тот и добрый!



Сообщение отредактировал BoPoH - Среда, 30.05.2012, 00:03
 
Den_spbДата: Воскресенье, 03.06.2012, 16:43 | Сообщение # 128
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: Offline
С кватернионами не работал, поэтому сказать не могу. Что эти кватернионы из себя представляют?
 
BoPoHДата: Воскресенье, 03.06.2012, 19:41 | Сообщение # 129
Группа: Проверенные
Сообщений: 53
Статус: Offline
Quote (Den_spb)
Что эти кватернионы из себя представляют?

Как я понял: 4 параметра.

Вот мне DK22Pac объяснял примерно так:
Предположим, что x,y,z - координаты вектора, a - угол, тогда параметры будут такие:
x*sin(a/2)
y*sin(a/2)
z*sin(a/2)
cos(a/2)

Судя по всему, кватернион - это вращение вокруг вектора на определённый угол.


First-Person mode 85% done
Добро всегда побеждает зло. Кто победил, тот и добрый!



Сообщение отредактировал BoPoH - Воскресенье, 03.06.2012, 19:43
 
Den_spbДата: Воскресенье, 03.06.2012, 19:58 | Сообщение # 130
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: Offline
Quote
Судя по всему, кватернион - это вращение вокруг вектора на определённый угол.
Если так, то можно найти разницу между конечными и начальными координатами вектора, а также разницу между конечным и начальным значением угла. Найденные значения делятся на количество кадров, в течение которого осуществляется поворот - получатся доли, которые надо прибавлять после каждого кадра.

Quote (BoPoH)
Предположим, что x,y,z - координаты вектора, a - угол, тогда параметры будут такие:
Не понял, зачем координаты на угол умножать. По идее координаты должны быть отдельно, а угол - отдельно.


Сообщение отредактировал Den_spb - Воскресенье, 03.06.2012, 20:07
 
BoPoHДата: Воскресенье, 03.06.2012, 20:51 | Сообщение # 131
Группа: Проверенные
Сообщений: 53
Статус: Offline
Quote (Den_spb)
Не понял, зачем координаты на угол умножать. По идее координаты должны быть отдельно, а угол - отдельно.

Я имел ввиду, что эти координаты - и есть вектор. Вектор единичный. Т.е. например может быть так: X = 0, Y = 0, Z = 1.0. Тогда будет вращение вокруг оси Z.


First-Person mode 85% done
Добро всегда побеждает зло. Кто победил, тот и добрый!



Сообщение отредактировал BoPoH - Воскресенье, 03.06.2012, 21:17
 
Den_spbДата: Воскресенье, 03.06.2012, 22:19 | Сообщение # 132
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: Offline
Quote (BoPoH)
Я имел ввиду, что эти координаты - и есть вектор. Вектор единичный. Т.е. например может быть так: X = 0, Y = 0, Z = 1.0. Тогда будет вращение вокруг оси Z.

Это всё ясно. Мне не понятно, зачем координаты вектора умножаются на угол поворота вокруг этого вектора (формулы в сообщении 129). Ведь вектор и угол поворота вокруг него - это два независимых друг от друга параметра.
 
BoPoHДата: Понедельник, 04.06.2012, 01:11 | Сообщение # 133
Группа: Проверенные
Сообщений: 53
Статус: Offline
Den_spb, В том и фишка, что это мы себе представляем, что это вектор, вокруг которого производится вращение. А представление этого в кватернионе именно такое, какое я указал.
http://steps3d.narod.ru/tutorials/skeletal-animation-tutorial.html
http://wat.gamedev.ru/articles/quaternions
http://www.gamedev.ru/code/articles/?id=4215
http://www.gamedev.ru/code/articles/faq_matrix_quat
Вот тут есть кое-что о кватернионах.

Добавлено (04.06.2012, 00:52)
---------------------------------------------
О, по ходу "интерполяция" - это то, что мне нужно.
http://www.gamedev.ru/code....ionov_l

Добавлено (04.06.2012, 01:11)
---------------------------------------------
Всё, спасибо, уже не надо) DK22Pac отыскал этот метод в exe ГТА-шки. 0x769491


First-Person mode 85% done
Добро всегда побеждает зло. Кто победил, тот и добрый!



Сообщение отредактировал BoPoH - Понедельник, 04.06.2012, 00:49
 
Den_spbДата: Понедельник, 04.06.2012, 02:38 | Сообщение # 134
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: Offline
Quote (BoPoH)
Вот тут есть кое-что о кватернионах.

Спасибо за информацию.
Quote (BoPoH)
Всё, спасибо, уже не надо) DK22Pac отыскал этот метод в exe ГТА-шки. 0x769491

Хорошо, что разобрались.
 
BoPoHДата: Понедельник, 04.06.2012, 16:39 | Сообщение # 135
Группа: Проверенные
Сообщений: 53
Статус: Offline
Вот теперь ещё парочка новых опкодиков в плагин DK22Pac'а)
Code
0D1D: matrix_slerp 0@ matrix_1 1@ matrix_2 2@ time 0.5
0D1E: quat_slerp 0@ quat_1 1@ quat_2 2@ time 0.5


First-Person mode 85% done
Добро всегда побеждает зло. Кто победил, тот и добрый!

 
Форум » Игры серии ГТА » Скриптинг » Математические и механические задачи в GTA (Применение знаний математики и механики в моддинге)
Страница 9 из 10«1278910»
Поиск: