Угол поворота объекта

IlyaHL2

Активный
Автор темы
231
49
Версия MoonLoader
.026-beta
[10:13:33.708528] (error) test.lua: C:\Games\200mb treyz\moonloader\test.lua:192: attempt to index field 'heading' (a nil value)
stack traceback:
C:\Games\200mb treyz\moonloader\test.lua:192: in function 'callback'
C:\Games\200mb treyz\moonloader\lib\samp\events\core.lua:77: in function 'process_event'
C:\Games\200mb treyz\moonloader\lib\samp\events\core.lua:100: in function 'process_packet'
C:\Games\200mb treyz\moonloader\lib\samp\events\core.lua:127: in function <C:\Games\200mb treyz\moonloader\lib\samp\events\core.lua:126>
И так 876 раз эта ошибка
А я всего лишь хотел получить угол поворота объекта

Lua:
function on.onCreateObject(oId, data)
    sampCreate3dText(data.modelId.."\n"..data.heading.x, -1, data.position.x, data.position.y, data.position.z, 9999, true, -1, -1)
end
Пробовал даже без .х но выводила на 3 ошибки меньше :(
 
Решение
у этой функци 4 параметра :(
и это не оно🥹
написал перевод кватернионов в углы в градусах, если надо в радианах убери math.deg
Lua:
local rx, ry, rz, rw = getObjectQuaternion(handleObj)

t0 = 2 * (rw * rx + ry * rz)
t1 = 1 - 2 * (rx^2 + ry^2)
t2 = 2 * (rw * ry - rz * rx)
t3 = 2 * (rw * rz + rx * ry)
t4 = 1 - 2 * (rz^2 + ry^2)

rxx = math.deg(math.atan2(t0, t1))
ryy = math.deg(math.asin(t2))
rzz = math.deg(math.atan2(t3, t4))

Rice.

Известный
Модератор
1,751
1,644
[10:13:33.708528] (error) test.lua: C:\Games\200mb treyz\moonloader\test.lua:192: attempt to index field 'heading' (a nil value)
stack traceback:
C:\Games\200mb treyz\moonloader\test.lua:192: in function 'callback'
C:\Games\200mb treyz\moonloader\lib\samp\events\core.lua:77: in function 'process_event'
C:\Games\200mb treyz\moonloader\lib\samp\events\core.lua:100: in function 'process_packet'
C:\Games\200mb treyz\moonloader\lib\samp\events\core.lua:127: in function <C:\Games\200mb treyz\moonloader\lib\samp\events\core.lua:126>
И так 876 раз эта ошибка
А я всего лишь хотел получить угол поворота объекта

Lua:
function on.onCreateObject(oId, data)
    sampCreate3dText(data.modelId.."\n"..data.heading.x, -1, data.position.x, data.position.y, data.position.z, 9999, true, -1, -1)
end
Пробовал даже без .х но выводила на 3 ошибки меньше :(​
Потому что ключа "heading" нету в data.
Возможные ключи:
В файле lib/samp/events.lua:

INCOMING_RPCS[RPC.CREATEOBJECT] = {'onCreateObject', handler.rpc_create_object_reader, handler.rpc_create_object_writer}
local handler = require 'samp.events.handlers'

Мы можем увидеть расположение библиотеки handler (lib/samp/events/handlers):
Открываем библиотеку и ищем функцию rpc_create_object_reader:
Lua:
function handler.rpc_create_object_reader(bs)
    local data = {materials = {}, materialText = {}}
    local objectId = bsread.int16(bs)
    data.modelId = bsread.int32(bs)
    data.position = bsread.vector3d(bs)
    data.rotation = bsread.vector3d(bs)
    data.drawDistance = bsread.float(bs)
    data.noCameraCol = bsread.bool8(bs)
    data.attachToVehicleId = bsread.int16(bs)
    data.attachToObjectId = bsread.int16(bs)
    if data.attachToVehicleId ~= 0xFFFF or data.attachToObjectId ~= 0xFFFF then
        data.attachOffsets = bsread.vector3d(bs)
        data.attachRotation = bsread.vector3d(bs)
        data.syncRotation = bsread.bool8(bs)
    end
    data.texturesCount = bsread.int8(bs)
    while raknetBitStreamGetNumberOfUnreadBits(bs) >= 8 do
        local materialType = bsread.int8(bs)
        if materialType == MATERIAL_TYPE.TEXTURE then
            table.insert(data.materials, read_object_material(bs))
        elseif materialType == MATERIAL_TYPE.TEXT then
            table.insert(data.materialText, read_object_material_text(bs))
        end
    end
    data.materials_text = data.materialText -- obsolete
    return {objectId, data}
end
Вывод: Никакого heading тут нету. Тебе нужно использовать data.rotation (даже перевод с англ. - вращение)
 

MrDorlik

Известный
953
382
у этой функци 4 параметра :(
и это не оно🥹
написал перевод кватернионов в углы в градусах, если надо в радианах убери math.deg
Lua:
local rx, ry, rz, rw = getObjectQuaternion(handleObj)

t0 = 2 * (rw * rx + ry * rz)
t1 = 1 - 2 * (rx^2 + ry^2)
t2 = 2 * (rw * ry - rz * rx)
t3 = 2 * (rw * rz + rx * ry)
t4 = 1 - 2 * (rz^2 + ry^2)

rxx = math.deg(math.atan2(t0, t1))
ryy = math.deg(math.asin(t2))
rzz = math.deg(math.atan2(t3, t4))
 
  • Вау
  • Ха-ха
Реакции: IlyaHL2 и qdIbp

IlyaHL2

Активный
Автор темы
231
49
написал перевод кватернионов в углы в градусах, если надо в радианах убери math.deg
Lua:
local rx, ry, rz, rw = getObjectQuaternion(handleObj)

t0 = 2 * (rw * rx + ry * rz)
t1 = 1 - 2 * (rx^2 + ry^2)
t2 = 2 * (rw * ry - rz * rx)
t3 = 2 * (rw * rz + rx * ry)
t4 = 1 - 2 * (rz^2 + ry^2)

rxx = math.deg(math.atan2(t0, t1))
ryy = math.deg(math.asin(t2))
rzz = math.deg(math.atan2(t3, t4))
я тебе готов отсосать прямо на месте
 
  • Ха-ха
Реакции: qdIbp

Tema05

Известный
1,474
444
В квартернионах в сампе определённо какие-то проблемы. Я сидел день перебрав кучу формул и т.п. у меня так и не вышло однозначно преобразовывать углы поворота присылаемые сервером в конечные значения квартерниона. В 2 измерениях можно сделать так, чтобы значения идеально совпадали. Но в 3 уже нет
 
  • Нравится
Реакции: Vintik

Vintik

Через тернии к звёздам
Проверенный
1,562
1,033
В квартернионах в сампе определённо какие-то проблемы.
Да, это мне подтвердил FYP, когда я у него спрашивал:
1732810860746.png
Когда я писал статью о кватернионах — я обнаружил, что getVehicleQuaternion работает нормально, а setVehicleQuaternion — уже неправильно.
Я сидел день перебрав кучу формул и т.п. у меня так и не вышло однозначно преобразовывать углы поворота присылаемые сервером в конечные значения квартерниона.
В теории надо просто 3 раза повернуть на угол вдоль оси (вопрос в том, ось поворачивается или нет...). У меня в статье об этом рассказано:
Так вот кватернион это и обозначает. Если мы вращаем объект на угол α «в плоскости», нормаль которой имеет координаты (x, y, z), то кватернион данного вращения будет иметь вид:
q = cos(α / 2) + sin(α / 2) * (x * i + y * j + z * k)
Во-вторых, мы можем вращать последовательно. Сначала повернули в одной плоскости, потом в другой, потом в третьей. Для этого нужно просто перемножать кватернионы.
В виде кода Lua это выглядит вот так:
Lua:
function quaternion_multiply(a, b, c, d,    w, x, y, z)
    return a * w - b * x - c * y - d * z, a * x + b * w + c * z - d * y, a * y - b * z + c * w + d * x, a * z + b * y - c * x + d * w
end
Поэтому можно попробовать взять углы, которые идут с севера (назовём их α, β, γ). Взять вектора (0, 0, 1), (0, 1, 0) и (1, 0, 0) и сделать кватернионы всех 3х поворотов, а потом эти кватернионы перемножить:
Код:
q1 = cos(α / 2) + sin(α / 2) * k
q2 = cos(β / 2) + sin(β / 2) * j
q3 = cos(γ / 2) + sin(γ / 2) * z

написал перевод кватернионов в углы в градусах, если надо в радианах убери math.deg
Я бы не верил этому, выглядит слишком просто(