Математические и механические задачи в GTA
|
|
Den_spb | Дата: Четверг, 26.01.2012, 00:46 | Сообщение # 61 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Quote (BoPoH) Den_spb, спасибо большое На здоровье.
Quote (BoPoH) Кстати, адресок матрицы авто не подскажешь? А то вот это не совсем то: Адрес матрицы записан в структуре транспорта по смещению 20, как здесь и написано (только тип данных - dword, а не byte). А вот структура матрицы в статье описана неправильно: элементы матрицы - это координаты векторов, а не углы.
|
|
| |
BoPoH | Дата: Четверг, 26.01.2012, 01:03 | Сообщение # 62 |
Группа: Проверенные
Сообщений: 53
Статус: Offline
| Den_spb, ещё раз спасибо, попробую. Добавлено (26.01.2012, 01:03) --------------------------------------------- Да, адрес действительно содержит матрицу.
First-Person mode 85% done Добро всегда побеждает зло. Кто победил, тот и добрый!
|
|
| |
BoPoH | Дата: Четверг, 26.01.2012, 18:26 | Сообщение # 63 |
Группа: Проверенные
Сообщений: 53
Статус: Offline
| Что неверно?
First-Person mode 85% done Добро всегда побеждает зло. Кто победил, тот и добрый!
|
|
| |
Den_spb | Дата: Пятница, 27.01.2012, 00:00 | Сообщение # 64 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Не знаю, я ошибок не нашёл. Чтобы не пользоваться scm-функциями и не расходовать переменные, хранение матрицы можно организовать в буфере. Адрес матрицы в этом случае будет равен адресу метки буфера: Code 0AC6: 0@ = label @Matrix offset // получили адрес буфера (матрицы) ... 0A93:
: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
|
|
| |
BoPoH | Дата: Пятница, 27.01.2012, 09:37 | Сообщение # 65 |
Группа: Проверенные
Сообщений: 53
Статус: Offline
| Quote (Den_spb) Не знаю, я ошибок не нашёл. Однако получаю странный результат. Использую подобным образом: Code 03C0: 20@ = actor $PLAYER_ACTOR car 0A97: 21@ = car 20@ struct 21@ += 20 0A8D: 22@ = read_memory 21@ size 4 virtual_protect 0 0D08: set_matrix $11222 rotation 10@ 0.0 11@ 0AB1: call_scm_func @MUL_MATRIX 3 22@ $11222 $11223 $11222 - адрес буфера
Quote (Den_spb) Чтобы не пользоваться scm-функциями и не расходовать переменные, хранение матрицы можно организовать в буфере. Адрес матрицы в этом случае будет равен адресу метки буфера Да, об этом я знаю. Скм-функции просто удобно использовать.
First-Person mode 85% done Добро всегда побеждает зло. Кто победил, тот и добрый!
Сообщение отредактировал BoPoH - Пятница, 27.01.2012, 09:38 |
|
| |
Den_spb | Дата: Пятница, 27.01.2012, 20:14 | Сообщение # 66 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Глобальные переменные применять не стоит. Решил задачу немного иначе:Code {$CLEO} const i = 0@ TopX = 0@ j = 1@ TopY = 1@ r = 2@ ZAngle = 2@ A11_offset = 3@ YAngle = 3@ B11_offset = 4@ XAngle = 4@ C11_offset = 5@ Air_offset = 6@ RightX = 6@ Brj_offset = 7@ RightY = 7@ Cij_offset = 8@ RightZ = 8@ Air = 9@ TopZ = 9@ Brj = 10@ Cij = 11@ Offset = 12@ end
model.Load(18631) model.Load(18634) 038B: load_requested_models
// Создаём объект-родитель object.Init(14@ 18634 -2025.3341, 174.8635, 28.8359) //
// Поворачиваем объект-родитель на произвольные углы 0A98: B11_offset = object 14@ struct B11_offset += 20 0A8D: B11_offset = read_memory B11_offset size 4 virtual_protect 0 // local 0AA6: call_method 0x59B120 struct B11_offset num_params 3 pop 0 1.0 1.0 1.0 // rot Z rot Y rot X (radians) object.PutAt(14@ -2025.3341, 174.8635, 28.9359)
// Создаём объект-ребёнок и крепим его к родителю под произвольными углами object.Init(16@ 18631 0 0 0) /// 069A: attach_object 16@ to_object 14@ with_offset 0.0 0.0 0.0 rotation 28.6 28.6 28.6
// Создаём отдельный объект, который будет иметь такие же мировые углы, что и объект-ребёнок object.Init(15@ 18631 -2025.3341, 174.8635, 28.8359) marker.CreateAboveObject(17@ 15@)
// Создаём в буфере матрицу и записываем в неё углы поворота объекта-ребёнка относительно родителя 0AC6: A11_offset = label @Matrix offset 0AA6: call_method 0x59B120 struct A11_offset num_params 3 pop 0 0.5 0.5 0.5 // rot Z rot Y rot X (radians)
// Результат запишем в матрицу отдельного объекта 0A98: 15@ = object 15@ struct 15@ += 20 0A8D: C11_offset = read_memory 15@ size 4 virtual_protect 0 // local
// Перемножаем матрицы for i = 0 to 2 for j = 0 to 2 Cij = 0 for r = 0 to 2 0A90: Offset = i * 16 // int 0A8E: Air_offset = A11_offset + Offset // int 0A90: Offset = r * 4 // int 005A: Air_offset += Offset // (int) 0A8D: Air = read_memory Air_offset size 4 virtual_protect 0
0A90: Offset = r * 16 // int 0A8E: Brj_offset = B11_offset + Offset // int 0A90: Offset = j * 4 // int 005A: Brj_offset += Offset // (int) 0A8D: Brj = read_memory Brj_offset size 4 virtual_protect 0 006B: Air *= Brj // (float) 005B: Cij += Air // (float) end 0A90: Offset = i * 16 // int 0A8E: Cij_offset = C11_offset + Offset // int 0A90: Offset = j * 4 // int 005A: Cij_offset += Offset // (int) 0A8C: write_memory Cij_offset size 4 value Cij virtual_protect 0 end end
0A93:
: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 Код создаёт объект-родитель, поворачивает его на определённые углы, затем создаёт объект-ребёнок и поворачивает его на определённые углы относительно родителя. Далее создаётся третий объект, который поворачивается так, чтобы его положение совпадало с позицией объекта-ребёнка.
|
|
| |
BoPoH | Дата: Пятница, 27.01.2012, 23:28 | Сообщение # 67 |
Группа: Проверенные
Сообщений: 53
Статус: Offline
| Den_spb, Будет ли такой способ практичным, при условии, что этот код должен выполняться в цикле? И если мой код перемножения матриц был верным, то дело не в нём, а вероятно либо в матрице авто, либо в буфере? Вообще, можно ли применять углы к "мнимой" матрице, т.е. к специально выделенному участку памяти? Может стоит попробовать делать это с матрицей какого-нибудь объекта, к примеру?
Может мне стоит объяснить, для чего это нужно? Вид от первого лица. Вообще работаю над видом от первого лица в обычном режиме, т.е. не в авто, пешком, но там мне это нужно кой для чего, что может показаться сразу неясным. А раз уж на то пошло, то мне удобно объяснить на эксперименте над видом от первого лица в авто. К примеру, мне нужно применять определённые углы, относительно авто, т.е. веду мышь влево - камера вращается влево, веду мышь вверх - камера вверх, всё это относительно авто. Если получать углы тем способом, что ты как-то давал, прибавлять нужные углы, а затем применять на камере, то это не сработает, если авто, к примеру перевёрнуто. А если ты летишь на самолёте и делаешь бочку?) Потому я и решил, что мне нужен такой код, который будет "крепить" камеру с определёнными оффсетами углов, в зависимости от передвижений мыши.
First-Person mode 85% done Добро всегда побеждает зло. Кто победил, тот и добрый!
|
|
| |
Den_spb | Дата: Пятница, 27.01.2012, 23:45 | Сообщение # 68 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Quote (BoPoH) Den_spb, Будет ли такой способ практичным, при условии, что этот код должен выполняться в цикле? Код можно выполнять хоть в цикле, хоть однократно. А какие есть опасения?
Quote (BoPoH) И если мой код перемножения матриц был верным, то дело не в нём, а вероятно либо в матрице авто, либо в буфере? В перемножении матриц ошибок не было - я это проверил. Причина где-то в другом месте.
Quote (BoPoH) Вообще, можно ли применять углы к "мнимой" матрице, т.е. к специально выделенному участку памяти? Может стоит попробовать делать это с матрицей какого-нибудь объекта, к примеру? Где находится участок памяти - в структуре объекта, в клео-скрипте или ещё в каком-то месте - разницы нет. Функция перевода углов в координаты производит запись только в матрицу. В моём коде, кстати, одна из матриц находится в буфере скрипта и всё нормально работает.
Quote (BoPoH) К примеру, мне нужно применять определённые углы, относительно авто, т.е. веду мышь влево - камера вращается влево, веду мышь вверх - камера вверх, всё это относительно авто. А не проще в данной ситуации воспользоваться опкодом, крепящим камеру к авто (0679)? Там как раз можно указать углы поворота камеры относительно автомобиля.
|
|
| |
BoPoH | Дата: Суббота, 28.01.2012, 00:24 | Сообщение # 69 |
Группа: Проверенные
Сообщений: 53
Статус: Offline
| Quote (Den_spb) А не проще в данной ситуации воспользоваться опкодом, крепящим камеру к авто (0679)? Там как раз можно указать углы поворота камеры относительно автомобиля. Во-первых, как я уже сказал, мне это нужно не совсем для авто. А во-вторых - описание этого опкода не совсем верно. Там где должны указываться углы, на самом деле указываются координаты относительно авто, куда смотрит камера. Ещё один из минусов этого опкода - камера не переворачивается вместе с авто. И, кстати, в твоём скрипте ты перемножаешь матрицы? Или как? У тебя там есть такой кусок: Code // Перемножаем матрицы for i = 0 to 2 for j = 0 to 2 Cij = 0 for r = 0 to 2 0A90: Offset = i * 16 // int 0A8E: Air_offset = A11_offset + Offset // int 0A90: Offset = r * 4 // int 005A: Air_offset += Offset // (int) 0A8D: Air = read_memory Air_offset size 4 virtual_protect 0
0A90: Offset = r * 16 // int 0A8E: Brj_offset = B11_offset + Offset // int 0A90: Offset = j * 4 // int 005A: Brj_offset += Offset // (int) 0A8D: Brj = read_memory Brj_offset size 4 virtual_protect 0 006B: Air *= Brj // (float) 005B: Cij += Air // (float) end 0A90: Offset = i * 16 // int 0A8E: Cij_offset = C11_offset + Offset // int 0A90: Offset = j * 4 // int 005A: Cij_offset += Offset // (int) 0A8C: write_memory Cij_offset size 4 value Cij virtual_protect 0 end end
First-Person mode 85% done Добро всегда побеждает зло. Кто победил, тот и добрый!
Сообщение отредактировал BoPoH - Суббота, 28.01.2012, 00:27 |
|
| |
Den_spb | Дата: Суббота, 28.01.2012, 00:33 | Сообщение # 70 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Quote (BoPoH) И, кстати, в твоём скрипте ты перемножаешь матрицы? Или как? У тебя там есть такой кусок: Да, это перемножение матриц, просто я оформил его в виде цикла. В цикле значение каждого элемента матрицы вычисляется по формуле:
|
|
| |
BoPoH | Дата: Суббота, 28.01.2012, 00:37 | Сообщение # 71 |
Группа: Проверенные
Сообщений: 53
Статус: Offline
| Den_spb, Фига се формулка... то-то я понять не мог, что у тебя там за перемножение матриц... Что ж, попробую пересмотреть ещё разок свой код.
First-Person mode 85% done Добро всегда побеждает зло. Кто победил, тот и добрый!
|
|
| |
Den_spb | Дата: Суббота, 28.01.2012, 00:54 | Сообщение # 72 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Формулка на самом деле простая, только надо привыкнуть к подобным обозначениям. Самая большая буква означает суммирование. В первом слагаемом r=1, во втором r=2 ... в n-слагаемом (последнем) r=n. Например, если n = 3, то элемент i-строки j-столбца в матрице C вычисляется по формуле: Cij = Ai1*B1j + Ai2*B2j + Ai3*B3j То есть используется тот же метод перемножения матриц, о котором шла речь ранее - просто здесь он записывается иначе.
|
|
| |
BoPoH | Дата: Суббота, 28.01.2012, 01:13 | Сообщение # 73 |
Группа: Проверенные
Сообщений: 53
Статус: Offline
| Den_spb, могу ли я подставить вместо A11_offset и B11_offset адреса своих матриц (матрица авто и кусок памяти), а вместо C11_offset подставить адрес матрицы, в которую запишется результат?
First-Person mode 85% done Добро всегда побеждает зло. Кто победил, тот и добрый!
|
|
| |
Den_spb | Дата: Суббота, 28.01.2012, 01:21 | Сообщение # 74 |
Создатель сайта
Группа: Администраторы
Сообщений: 1595
Статус: Offline
| Да, конечно - это и есть адреса матриц.
|
|
| |
BoPoH | Дата: Суббота, 28.01.2012, 01:29 | Сообщение # 75 |
Группа: Проверенные
Сообщений: 53
Статус: Offline
| Den_spb, Надо же... Мой способ перемножения всё же был неверен, как ни странно. Твой способ работает. По крайней мере длина векторов равна 1 - это точно. Сейчас попробую на камере проверить.
Ага, вроде работает, но не совсем как надо. Камера крепится не очень правильно. Т.е., например, одна из матриц имела нулевые углы, то получается вот так, как на скрине:
First-Person mode 85% done Добро всегда побеждает зло. Кто победил, тот и добрый!
Сообщение отредактировал BoPoH - Суббота, 28.01.2012, 01:45 |
|
| |