кватернион и heading

Lance_Sterling

Известный
Автор темы
992
354
Версия MoonLoader
Другое
нужно получить поворот игрока по оси Z (аналог функции getCharHeading), используя кватернион который приходит в синхре
 
Решение
А чего не флоат же? Это же флоат кватернион а не целое число
За это не могу сказать, но в moonloader они считываются как uint16, в раксампе считываются как int16.

Как я понял, знаки передаются отдельно:
Lua:
local cwNeg, cxNeg, cyNeg, czNeg = bs:readBool(), bs:readBool(), bs:readBool(), bs:readBool()

И потом этот кватернион преобразуется до нормального вида с float значениями:
Lua:
local x = cx / 65535
local y = cy / 65535
local z = cz / 65535
if cxNeg then x = -x end
if cyNeg then y = -y end
if czNeg then z = -z end
local diff = 1 - x * x - y * y - z * z
if diff < 0 then diff = 0 end
local w = math.sqrt(diff)
if cwNeg then w = -w end
return {w, x, y, z}

wojciech?

Известный
Проверенный
390
288
Lua:
local matrix = require("matrix3x3")
local samp = require("samp.events")

function samp.onSendPlayerSync(data)
    local m = matrix(convertQuaternionToMatrix(data.quaternion[3], data.quaternion[0], data.quaternion[1], data.quaternion[2]))
    local heading = (math.pi * 2 - (math.atan2(m.front.y, m.up.y) + math.pi / 2)) % (math.pi * 2)
    -- math.deg(heading) == getCharHeading(PLAYER_PED)
end
 
  • Нравится
  • Вау
Реакции: Sargon и Lance_Sterling

Lance_Sterling

Известный
Автор темы
992
354
Lua:
local matrix = require("matrix3x3")
local samp = require("samp.events")

function samp.onSendPlayerSync(data)
    local m = matrix(convertQuaternionToMatrix(data.quaternion[3], data.quaternion[0], data.quaternion[1], data.quaternion[2]))
    local heading = (math.pi * 2 - (math.atan2(m.front.y, m.up.y) + math.pi / 2)) % (math.pi * 2)
    -- math.deg(heading) == getCharHeading(PLAYER_PED)
end
возвращает постоянно 180
дай норм функу convertQuaternionToMatrix, не юзаю мунлоадер
 

wojciech?

Известный
Проверенный
390
288
дай норм функу convertQuaternionToMatrix
Lua:
local function convertQuaternionToMatrix(w, x, y, z)
    return 1 - 2 * (y^2 + z^2), 2 * (x * y - z * w), 2 * (x * z + y * w),
          2 * (x * y + z * w), 1 - 2 * (x^2 + z^2), 2 * (y * z - x * w),
          2 * (x * z - y * w), 2 * (y * z + x * w), 1 - 2 * (x^2 + y^2)
end
 
  • Нравится
Реакции: Lance_Sterling

Lance_Sterling

Известный
Автор темы
992
354
Lua:
local function convertQuaternionToMatrix(w, x, y, z)
    return 1 - 2 * (y^2 + z^2), 2 * (x * y - z * w), 2 * (x * z + y * w),
          2 * (x * y + z * w), 1 - 2 * (x^2 + z^2), 2 * (y * z - x * w),
          2 * (x * z - y * w), 2 * (y * z + x * w), 1 - 2 * (x^2 + y^2)
end
херню какую то показывает, юзаю в onPlayerSync
вот так
Код:
local m = matrix(convertQuaternionToMatrix(data.quaternion[4], data.quaternion[1], data.quaternion[2], data.quaternion[3]))
 

wojciech?

Известный
Проверенный
390
288
херню какую то показывает, юзаю в onPlayerSync
вот так
Код:
local m = matrix(convertQuaternionToMatrix(data.quaternion[4], data.quaternion[1], data.quaternion[2], data.quaternion[3]))
массивы с 0 индексируются, это не луа таблица
 

wojciech?

Известный
Проверенный
390
288
это модиф самп луа для раксампа
там изменены только обработчики событий, структуры те же самые

Всё-таки там таблица, но есть нюанс. Я проверил кватернионы в onPlayerSync в муне и в раксампе и они разные при одинаковых условиях:
Lua:
function samp.onPlayerSync(id, data)
    if id == 21 then -- ид одного и того же игрока в обоих случаях, он стоит на месте
        print(("%.2f %.2f %.2f %.2f"):format(data.quaternion[1], data.quaternion[2], data.quaternion[3], data.quaternion[4]))
        -- raksamp 0.95 0.00 0.00 -0.32
        -- moon 0.73 0.00 0.00 0.68
    end
end
 
Последнее редактирование:
  • Bug
  • Грустно
Реакции: Corenale и Lance_Sterling

Lance_Sterling

Известный
Автор темы
992
354
там изменены только обработчики событий, структуры те же самые

Всё-таки там таблица, но есть нюанс. Я проверил кватернионы в onPlayerSync в муне и в раксампе и они разные при одинаковых условиях:
Lua:
function samp.onPlayerSync(id, data)
    if id == 21 then -- ид одного и того же игрока в обоих случаях, он стоит на месте
        print(("%.2f %.2f %.2f %.2f"):format(data.quaternion[1], data.quaternion[2], data.quaternion[3], data.quaternion[4]))
        -- raksamp 0.95 0.00 0.00 -0.32
        -- moon 0.73 0.00 0.00 0.68
    end
end
Это круто, я это знал, поэтому и написал сюда)
Блять ну действительно че за херня, разные кватернионы
 

wojciech?

Известный
Проверенный
390
288
Блять ну действительно че за херня, разные кватернионы
неправильные типы в либе раксампа

Lua:
-- \libs\samp\events\bitstream_io.lua, метод mod.normQuat.read

-- изменить
local cx, cy, cz = bs:readInt16(), bs:readInt16(), bs:readInt16()

-- на
local cx, cy, cz = bs:readUInt16(), bs:readUInt16(), bs:readUInt16()
 
  • Грустно
Реакции: Lance_Sterling

Lance_Sterling

Известный
Автор темы
992
354
неправильные типы в либе раксампа

Lua:
-- \libs\samp\events\bitstream_io.lua, метод mod.normQuat.read

-- изменить
local cx, cy, cz = bs:readInt16(), bs:readInt16(), bs:readInt16()

-- на
local cx, cy, cz = bs:readUInt16(), bs:readUInt16(), bs:readUInt16()
А чего не флоат же? Это же флоат кватернион а не целое число
 

wojciech?

Известный
Проверенный
390
288
А чего не флоат же? Это же флоат кватернион а не целое число
За это не могу сказать, но в moonloader они считываются как uint16, в раксампе считываются как int16.

Как я понял, знаки передаются отдельно:
Lua:
local cwNeg, cxNeg, cyNeg, czNeg = bs:readBool(), bs:readBool(), bs:readBool(), bs:readBool()

И потом этот кватернион преобразуется до нормального вида с float значениями:
Lua:
local x = cx / 65535
local y = cy / 65535
local z = cz / 65535
if cxNeg then x = -x end
if cyNeg then y = -y end
if czNeg then z = -z end
local diff = 1 - x * x - y * y - z * z
if diff < 0 then diff = 0 end
local w = math.sqrt(diff)
if cwNeg then w = -w end
return {w, x, y, z}
 
  • Влюблен
Реакции: Lance_Sterling

Ulong

Диванный критик
Проверенный
63
367
Lua:
function quat2angle(qZ, qW)
    return (2.0 * math.atan2(qZ, qW) * 180.0 / math.pi) % 360.0
end

function sampev.onPlayerSync(playerId, data)
    if playerId == 228 then
        local angle = quat2angle(-data.quaternion[4], data.quaternion[1])
        print(angle)
    end
end

замени еще либы от сюда и будет тебе счастье
 
  • Эм
Реакции: Lance_Sterling