Essle Posted August 3, 2017 Share Posted August 3, 2017 (edited) Function to translate angles of Euler into quaternions. Arguments: RotX, RotY, RotZ Return: RotX, RotY, RotZ, RotW function math.quaternion(x, y, z) local c = { math.cos(math.rad(-x)), math.cos(math.rad(-y)), math.cos(math.rad(z)) } local s = { math.sin(math.rad(-x)), math.sin(math.rad(-y)), math.sin(math.rad(z)) } local t = { c[2] * c[3], s[1] * s[2] * s[3] + c[1] * c[3], c[1] * c[2] } return math.drt(1.0 + t[1] - t[2] - t[3], (c[3] * s[1] - c[1] * s[2] * s[3]) - (-s[1] * c[2])), math.drt(1.0 - t[1] + t[2] - t[3], s[2] + (c[1] * s[2] * c[3] + s[1] * s[3])), math.drt(1.0 - t[1] - t[2] + t[3], (s[1] * s[2] * c[3] - c[1] * s[3]) - (c[2] * s[3])), math.drt(1.0 + t[1] + t[2] + t[3]) end function math.drt(a, b) a = math.sqrt(math.max(0.0, a)) * 0.5 return (b and ((b < 0) and -math.abs(a) or math.abs(a)) or a) end Edited August 4, 2017 by Essle Updated function syntax 1 1 Link to comment
Zorgman Posted August 3, 2017 Share Posted August 3, 2017 where to use it in a real situation? to calculate what? give a layman example... what did you used it for? thanks Link to comment
Essle Posted August 4, 2017 Author Share Posted August 4, 2017 This function is needed to convert .map to .ipl In all converters rotation is not calculated correctly. But this function works perfectly. Example local file = File.new("map-test.ipl") file:write("inst\n") for _, theSubject in ipairs(Element.getAllByType("object")) do local rX, rY, rZ = getElementRotation(theSubject, "ZXY") local rW = 0 rX, rY, rZ, rW = math.quaternion(rX, rY, rZ) file:write( theSubject.model..", "..engineGetModelNameFromID(theSubject.model)..", 0, ".. theSubject.position.x..", "..theSubject.position.y..", "..theSubject.position.z..", ".. rX..", "..rY..", "..rZ..", "..rW..", -1\n" ) end file:write("end") file:flush() file:close() 1 Link to comment
Scripting Moderators thisdp Posted August 4, 2017 Scripting Moderators Share Posted August 4, 2017 (edited) function math.quaternion(x, y, z) local rx = math.rad( -x ) local ry = math.rad( -y ) local rz = math.rad( z ) local fCosX = math.cos(rx) local fCosY = math.cos(ry) local fCosZ = math.cos(rz) local fSinX = math.sin(rx) local fSinY = math.sin(ry) local fSinZ = math.sin(rz) local temp1 = fCosY * fCosZ local temp2 = fSinX * fSinY * fSinZ + fCosX * fCosZ local temp3 = fCosX * fCosY local w = math.sqrt(math.max(0.0, 1.0 + temp1 + temp2 + temp3)) * 0.5 local x = math.sqrt(math.max(0.0, 1.0 + temp1 - temp2 - temp3)) * 0.5 local y = math.sqrt(math.max(0.0, 1.0 - temp1 + temp2 - temp3)) * 0.5 local z = math.sqrt(math.max(0.0, 1.0 - temp1 - temp2 + temp3)) * 0.5 x = math.sign(x, (fCosZ * fSinX - fCosX * fSinY * fSinZ) - (-fSinX * fCosY)) y = math.sign(y, fSinY + (fCosX * fSinY * fCosZ + fSinX * fSinZ)) z = math.sign(z, (fSinX * fSinY * fCosZ - fCosX * fSinZ) - (fCosY * fSinZ)) return x, y, z, w end function math.sign(x, a) return (a < 0) and -math.abs(x) or math.abs(x) end This will get a better performance, won't it? Edited August 4, 2017 by thisdp 1 Link to comment
Essle Posted August 4, 2017 Author Share Posted August 4, 2017 36 minutes ago, thisdp said: This will get a better performance, won't it? On tests you will not even notice difference. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now