Математические и механические задачи в 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 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Деление - это умножение на обратное число (1/x). То есть, вместо можно написать или, применяя степенные обозначения С матрицами всё аналогично - вместо деления применяется умножение на обратную матрицу: В 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 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: 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 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: 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. Всё работает зашибенно Спасибо большое за помощь, респект и уважуха!) Уже не раз выручаешь Добавлено (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 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: 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 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: 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 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: 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 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: 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 Добро всегда побеждает зло. Кто победил, тот и добрый!
|
|
| |