function quaternionToEulerAngles(quat)
local pitch = math.asin(2 * (quat.w * quat.y - quat.x * quat.z))
local roll = math.atan2(2 * (quat.w * quat.x + quat.y * quat.z), 1 - 2 * (quat.x^2 + quat.y^2))
local yaw = math.atan2(2 * (quat.w * quat.z + quat.x * quat.y), 1 - 2 * (quat.y^2 + quat.z^2))
return roll, pitch, yaw
end
function eulerAnglesToQuaternion(roll, pitch, yaw)
local cy = math.cos(yaw * 0.5)
local sy = math.sin(yaw * 0.5)
local cp = math.cos(pitch * 0.5)
local sp = math.sin(pitch * 0.5)
local cr = math.cos(roll * 0.5)
local sr = math.sin(roll * 0.5)
local qw = cy * cp * cr + sy * sp * sr
local qx = cy * cp * sr - sy * sp * cr
local qy = sy * cp * sr + cy * sp * cr
local qz = sy * cp * cr - cy * sp * sr
return {w = qw, x = qx, y = qy, z = qz}
end
function setBoneQuat(boneId, quat)
-- CBone
-- 0x0000 | BYTE m_bFlags
-- 0x0004 | CVector m_vOffset // Статичное смещение относительно родительской кости
-- 0x0010 | СHAnimIFrame *m_pIFrame // Указатель на структуру, которая содержит интерполированные данные о положении кости
-- 0x0014 | DWORD m_dwNodeId // Специальный идентификатор кости
-- СHAnimIFrame
-- 0x0000 | CQuat m_qOrientation
-- 0x0010 | CVector m_vTranslation
local cPed = memory.getuint32(0xB6F5F0)
local cBone = memory.getuint32(cPed + 0x488 + 0x4 * boneId)
memory.setfloat(cBone + 0x10 + 0x4 * 1, quat.w)
memory.setfloat(cBone + 0x10 + 0x4 * 2, quat.x)
memory.setfloat(cBone + 0x10 + 0x4 * 3, quat.y)
memory.setfloat(cBone + 0x10 + 0x4 * 4, quat.z)
end
function getBoneQuat(boneId)
local cPed = memory.getuint32(0xB6F5F0)
local cBone = memory.getuint32(cPed + 0x488 + 0x4 * boneId)
local quat = {
w = memory.getfloat(cBone + 0x10 + 0x4 * 1),
x = memory.getfloat(cBone + 0x10 + 0x4 * 2),
y = memory.getfloat(cBone + 0x10 + 0x4 * 3),
z = memory.getfloat(cBone + 0x10 + 0x4 * 4)
}
return quat
end