AvatoR Posted February 25, 2023 Share Posted February 25, 2023 I have this code: sx, sy = guiGetScreenSize() movedClip = false testAngle = 0 function math.rotVecToEular(x, y, z, rot) -- explained on mta wiki local rotx = math.deg( math.atan2 ( z, (x^2+y^2)^0.5 ) ) % 360 local rotz = math.deg( math.atan2( x, y ) ) % 360 return rotx, rot, rotz end addEventHandler("onClientRender", root, function () local relX, relY = getCursorPosition() local cursorX, cursorY = relX * sx, relY * sy local camX, camY, camZ = getCameraMatrix() local cursorWorldPosX, cursorWorldPosY, cursorWorldPosZ = getWorldFromScreenPosition(cursorX, cursorY, 20) hit, hitX, hitY, hitZ, hitElement, normalX, normalY, normalZ = processLineOfSight(camX, camY, camZ, cursorWorldPosX, cursorWorldPosY, cursorWorldPosZ, true, false, false, true, false, true, false, true) if hit then testAngle = (testAngle + 1) % 360 angleVectorX, angleVectorY, angleVectorZ = math.rotVecToEular(normalX, normalY, normalZ, testAngle) angleVectorX = angleVectorX - 90 -- cone look "up" when testAngle = 0 hitX = normalX*0.2 + hitX -- a bit up from a plane hitY = normalY*0.2 + hitY -- a bit up from a plane hitZ = normalZ*0.2 + hitZ -- a bit up from a plane if isElement(movedClip) then destroyElement(movedClip) end movedClip = createObject(1238, hitX, hitY, hitZ, angleVectorX, angleVectorY, angleVectorZ, true) end end) But i need rotation in other axis, like so: - Need rotation in "Z" axis with ZYX Euler coordinate system. Script doing that in MTA: And in blender "X" axis in XYZ Euler angles: I tried set setElementRotation with 5 argument "ZYX" but it didn't work, like it's swap X and Z angles, not a different coordinate system: local angX = 0 local angY = 0 local angZ = 0 local modelToRotate = false sx, sy = guiGetScreenSize() addEventHandler("onClientRender", root, function () if isCursorShowing() then if getKeyState("4") then angX = (angX + 1) % 360 end if getKeyState("5") then angY = (angY + 1) % 360 end if getKeyState("6") then angZ = (angZ + 1) % 360 end dxDrawText("X:" .. angX .. " Y:" .. angY .. " Z:" .. angZ, 300, 60) local relX, relY = getCursorPosition() local cursorX, cursorY = relX * sx, relY * sy local camX, camY, camZ = getCameraMatrix() local cursorWorldPosX, cursorWorldPosY, cursorWorldPosZ = getWorldFromScreenPosition(cursorX, cursorY, 20) local hit, hitX, hitY, hitZ, hitElement, normalX, normalY, normalZ = processLineOfSight(camX, camY, camZ, cursorWorldPosX, cursorWorldPosY, cursorWorldPosZ, true, false, false, true, false, true, false, true) if isElement(modelToRotate) then destroyElement(modelToRotate) end modelToRotate = createObject(1238, hitX, hitY, hitZ, 0, 0, 0, true) setElementRotation(modelToRotate, angX, angY, angZ, "ZYX") end end ) keys 4, 5, 6 for rotation in X, Y, Z axis. How to rotate a object in Z axis, but to a normal vector from processLineOfSight, like in first attached video? 1 Link to comment
relvarten Posted February 28, 2023 Share Posted February 28, 2023 (edited) I realized that the MTA rotation system is broken when I was trying to write the most common vehicle flip. I encountered exactly the same (or about the same) that you show on the video – broken Rotation Y. As I understand it, the MTA tries to avoid Rotation Y. For example, instead of RY + 90, the MTA seems to have used the chain RX - 90 > RZ - 90 > RX + 90. I believe this is a global MTA flaw, which I hope will be fixed sooner or later. P.S. I would understand if you indicated the wrong ZXY instead of the correct ZYX, but all seems correct... Edited February 28, 2023 by relvarten Link to comment
Scripting Moderators thisdp Posted February 28, 2023 Scripting Moderators Share Posted February 28, 2023 (edited) 11 hours ago, relvarten said: I realized that the MTA rotation system is broken when I was trying to write the most common vehicle flip. I encountered exactly the same (or about the same) that you show on the video – broken Rotation Y. As I understand it, the MTA tries to avoid Rotation Y. For example, instead of RY + 90, the MTA seems to have used the chain RX - 90 > RZ - 90 > RX + 90. I believe this is a global MTA flaw, which I hope will be fixed sooner or later. P.S. I would understand if you indicated the wrong ZXY instead of the correct ZYX, but all seems correct... Refer to Gimbal Lock of Euler rotation system. To resolve this, use rotation matrix to apply rotation changes, and then convert back to eular angles. Edited February 28, 2023 by thisdp 2 Link to comment
Prioq Posted March 1, 2023 Share Posted March 1, 2023 local angX = 0 local angY = 0 local angZ = 0 local modelToRotate = false sx, sy = guiGetScreenSize() addEventHandler("onClientRender", root, function () if isCursorShowing() then if getKeyState("4") then angX = (angX + 1) % 360 end if getKeyState("5") then angY = (angY + 1) % 360 end if getKeyState("6") then angZ = (angZ + 1) % 360 end dxDrawText("X:" .. angX .. " Y:" .. angY .. " Z:" .. angZ, 300, 60) local relX, relY = getCursorPosition() local cursorX, cursorY = relX * sx, relY * sy local camX, camY, camZ = getCameraMatrix() local cursorWorldPosX, cursorWorldPosY, cursorWorldPosZ = getWorldFromScreenPosition(cursorX, cursorY, 20) local hit, hitX, hitY, hitZ, hitElement, normalX, normalY, normalZ = processLineOfSight(camX, camY, camZ, cursorWorldPosX, cursorWorldPosY, cursorWorldPosZ, true, false, false, true, false, true, false, true) if isElement(modelToRotate) then destroyElement(modelToRotate) end modelToRotate = createObject(1238, hitX, hitY, hitZ, 0, 0, 0, true) -- Convert the Euler angles to radians local radX = math.rad(angX) local radY = math.rad(angY) local radZ = math.rad(angZ) -- Calculate the sin and cosine values local sinX = math.sin(radX) local cosX = math.cos(radX) local sinY = math.sin(radY) local cosY = math.cos(radY) local sinZ = math.sin(radZ) local cosZ = math.cos(radZ) -- Calculate the rotation matrix manually local rotMatrix = {{}, {}, {}, {}} rotMatrix[1][1] = cosY * cosZ rotMatrix[1][2] = cosY * sinZ rotMatrix[1][3] = -sinY rotMatrix[1][4] = 0 rotMatrix[2][1] = sinX * sinY * cosZ - cosX * sinZ rotMatrix[2][2] = sinX * sinY * sinZ + cosX * cosZ rotMatrix[2][3] = sinX * cosY rotMatrix[2][4] = 0 rotMatrix[3][1] = cosX * sinY * cosZ + sinX * sinZ rotMatrix[3][2] = cosX * sinY * sinZ - sinX * cosZ rotMatrix[3][3] = cosX * cosY rotMatrix[3][4] = 0 rotMatrix[4][1] = hitX rotMatrix[4][2] = hitY rotMatrix[4][3] = hitZ rotMatrix[4][4] = 1 -- Apply the rotation matrix to the object setElementMatrix(modelToRotate, rotMatrix) end end ) Is this what you're trying to achieve? Link to comment
AvatoR Posted March 2, 2023 Author Share Posted March 2, 2023 On 01/03/2023 at 09:33, Prioq said: local angX = 0 local angY = 0 local angZ = 0 local modelToRotate = false sx, sy = guiGetScreenSize() addEventHandler("onClientRender", root, function () if isCursorShowing() then if getKeyState("4") then angX = (angX + 1) % 360 end if getKeyState("5") then angY = (angY + 1) % 360 end if getKeyState("6") then angZ = (angZ + 1) % 360 end dxDrawText("X:" .. angX .. " Y:" .. angY .. " Z:" .. angZ, 300, 60) local relX, relY = getCursorPosition() local cursorX, cursorY = relX * sx, relY * sy local camX, camY, camZ = getCameraMatrix() local cursorWorldPosX, cursorWorldPosY, cursorWorldPosZ = getWorldFromScreenPosition(cursorX, cursorY, 20) local hit, hitX, hitY, hitZ, hitElement, normalX, normalY, normalZ = processLineOfSight(camX, camY, camZ, cursorWorldPosX, cursorWorldPosY, cursorWorldPosZ, true, false, false, true, false, true, false, true) if isElement(modelToRotate) then destroyElement(modelToRotate) end modelToRotate = createObject(1238, hitX, hitY, hitZ, 0, 0, 0, true) -- Convert the Euler angles to radians local radX = math.rad(angX) local radY = math.rad(angY) local radZ = math.rad(angZ) -- Calculate the sin and cosine values local sinX = math.sin(radX) local cosX = math.cos(radX) local sinY = math.sin(radY) local cosY = math.cos(radY) local sinZ = math.sin(radZ) local cosZ = math.cos(radZ) -- Calculate the rotation matrix manually local rotMatrix = {{}, {}, {}, {}} rotMatrix[1][1] = cosY * cosZ rotMatrix[1][2] = cosY * sinZ rotMatrix[1][3] = -sinY rotMatrix[1][4] = 0 rotMatrix[2][1] = sinX * sinY * cosZ - cosX * sinZ rotMatrix[2][2] = sinX * sinY * sinZ + cosX * cosZ rotMatrix[2][3] = sinX * cosY rotMatrix[2][4] = 0 rotMatrix[3][1] = cosX * sinY * cosZ + sinX * sinZ rotMatrix[3][2] = cosX * sinY * sinZ - sinX * cosZ rotMatrix[3][3] = cosX * cosY rotMatrix[3][4] = 0 rotMatrix[4][1] = hitX rotMatrix[4][2] = hitY rotMatrix[4][3] = hitZ rotMatrix[4][4] = 1 -- Apply the rotation matrix to the object setElementMatrix(modelToRotate, rotMatrix) end end ) Is this what you're trying to achieve? Yep, thanks, it's finally works. 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