Математические и механические задачи в GTA - Страница 5 - Форум
Суббота, 03.12.2016, 14:34
Качественные скрипты, моды и дополнения для GTA без регистрации
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 5 из 10«1234567910»
Форум » Игры серии ГТА » Скриптинг » Математические и механические задачи в GTA (Применение знаний математики и механики в моддинге)
Математические и механические задачи в GTA
Den_spbДата: Четверг, 26.01.2012, 00:46 | Сообщение # 61
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: 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
Что неверно?
Прикрепления: mul_matrix.txt(4Kb)


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

 
Den_spbДата: Пятница, 27.01.2012, 00:00 | Сообщение # 64
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: 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
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: 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
Код создаёт объект-родитель, поворачивает его на определённые углы, затем создаёт объект-ребёнок и поворачивает его на определённые углы относительно родителя. Далее создаётся третий объект, который поворачивается так, чтобы его положение совпадало с позицией объекта-ребёнка.
Прикрепления: 3924113.jpg(121Kb)
 
BoPoHДата: Пятница, 27.01.2012, 23:28 | Сообщение # 67
Группа: Проверенные
Сообщений: 53
Статус: Offline
Den_spb, Будет ли такой способ практичным, при условии, что этот код должен выполняться в цикле?
И если мой код перемножения матриц был верным, то дело не в нём, а вероятно либо в матрице авто, либо в буфере? Вообще, можно ли применять углы к "мнимой" матрице, т.е. к специально выделенному участку памяти? Может стоит попробовать делать это с матрицей какого-нибудь объекта, к примеру?

Может мне стоит объяснить, для чего это нужно? Вид от первого лица. Вообще работаю над видом от первого лица в обычном режиме, т.е. не в авто, пешком, но там мне это нужно кой для чего, что может показаться сразу неясным. А раз уж на то пошло, то мне удобно объяснить на эксперименте над видом от первого лица в авто. К примеру, мне нужно применять определённые углы, относительно авто, т.е. веду мышь влево - камера вращается влево, веду мышь вверх - камера вверх, всё это относительно авто. Если получать углы тем способом, что ты как-то давал, прибавлять нужные углы, а затем применять на камере, то это не сработает, если авто, к примеру перевёрнуто. А если ты летишь на самолёте и делаешь бочку?) Потому я и решил, что мне нужен такой код, который будет "крепить" камеру с определёнными оффсетами углов, в зависимости от передвижений мыши.


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

 
Den_spbДата: Пятница, 27.01.2012, 23:45 | Сообщение # 68
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: 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
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: 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
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: 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
Создатель сайта
Группа: Администраторы
Сообщений: 1536
Статус: Offline
Да, конечно - это и есть адреса матриц.
 
BoPoHДата: Суббота, 28.01.2012, 01:29 | Сообщение # 75
Группа: Проверенные
Сообщений: 53
Статус: Offline
Den_spb, Надо же... Мой способ перемножения всё же был неверен, как ни странно. Твой способ работает. По крайней мере длина векторов равна 1 - это точно. Сейчас попробую на камере проверить.

Ага, вроде работает, но не совсем как надо. Камера крепится не очень правильно. Т.е., например, одна из матриц имела нулевые углы, то получается вот так, как на скрине:


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



Сообщение отредактировал BoPoH - Суббота, 28.01.2012, 01:45
 
Форум » Игры серии ГТА » Скриптинг » Математические и механические задачи в GTA (Применение знаний математики и механики в моддинге)
Страница 5 из 10«1234567910»
Поиск: