Other Languages Moderators Lord Henry Posted January 17, 2018 Other Languages Moderators Share Posted January 17, 2018 (edited) Eae pessoal. Bom, hoje trago um novo problema com objetos anexados. Estou criando um script que cria e movimenta um guindaste localizado nas docas de SF (lá onde faz exportação/importação de veículos). Para criar esse guindaste, eu criei 6 objetos e anexei eles da seguinte maneira: guindasteBase (criado normalmente na posição e rotação correta, não está anexado em nenhum objeto) guindasteMiddle (anexado no guindasteBase, sem nenhum offset) guindasteTop (anexado no guindasteBase com offset de x = 0, y = -3.2, z = 19) guindasteSupport (anexado no guindasteTop com offset de x = 0, y = 50, z = 3.45) guindasteMagnet (anexado no guindasteSupport com offset de x = 0, y = 0, z = -1) theCam (Uma caixa invisível, anexada no guindasteSupport com offset de x = 15, y = -60, z = 20. Será onde a câmera do jogador vai ficar.) Spoiler Esquema de construção: local guindasteBase = createObject (1380, -1594.5, 77.20019, 26.8, 0, 0, 44.995) local guindasteMiddle = createObject (1379, -1594.5, 77.20019, 26.8, 0, 0, 44.995) local guindasteTop = createObject (1394, -1592.2998, 75, 46, 0, 0, 44.995) local guindasteSupport = createObject (1389, -1627.4004, 110.09961, 49.4, 0, 0, 44.995) local guindasteMagnet = createObject (1381, -1627.4004, 110.09961, 49.5, 0, 0, 44.995) local guindaste = createVehicle (594, -1594.5, 77.20019, 32.6) -- Isso vai ser onde o jogador vai ficar quando entrar no guindaste. local enterMarker = createMarker (-1598.9, 81.6, 5.1, "cylinder", 1.5, 180, 120, 50, 200) -- Isso vai ser o marker onde o jogador vai pra subir no guindaste. local theCam = createObject (1271, -1594.5, 77.20019, 4, 0, 0, 44.995, true) setElementAlpha (theCam, 0) setVehicleDamageProof (guindaste, true) function attachCraneParts () attachElements (guindasteMiddle, guindasteBase) attachElements (guindasteTop, guindasteBase, 0, -3.2, 19, 0, 0, 0) attachElements (guindaste, guindasteTop, 0, 3.2, -16.5, 0, 0, 0) attachElements (guindasteSupport, guindasteTop, 0, 50, 3.45) attachElements (guindasteMagnet, guindasteSupport, 0, 0, -1) attachElements (theCam, guindasteSupport, 15, -60, 20, 0, 0, 0) end addEventHandler("onResourceStart", getResourceRootElement(getThisResource()), attachCraneParts) Até aí tudo certo, os objetos estão devidamente anexados e suas posições estão aparentemente corretas. O problema surge na hora de começar a movimentar o guindaste. Movimentando a base do guindaste (só se movimenta em duas direções, pra frente e pra trás), não ocorre nenhum problema. Todos os elementos anexados acompanham corretamente a movimentação, que é feita da seguinte maneira: function moveBaseUp () if isTimer (baseTimer) then killTimer (baseTimer) end if not getElementData (guindasteBase, "movingUp") then setElementData (guindasteBase, "movingUp", true) setMarkerSize (enterMarker, 0) baseTimer = setTimer (function() local x, y, z = getElementPosition (guindasteBase) if x <= -1532.5 then setElementPosition (guindasteBase, x+0.1, y+0.1, z) end end, 50, 0) else setElementData (guindasteBase, "movingUp", false) end end function moveBaseDown () if isTimer (baseTimer) then killTimer (baseTimer) end if not getElementData (guindasteBase, "movingDown") then setElementData (guindasteBase, "movingDown", true) baseTimer = setTimer (function() local x, y, z = getElementPosition (guindasteBase) if x >= -1647.5 then setElementPosition (guindasteBase, x-0.1, y-0.1, z) end end, 50, 0) else setElementData (guindasteBase, "movingDown", false) end end Quando o jogador entra no guindaste, as teclas W e S são bindadas para ativar essas funções. W para moveBaseUp e S para moveBaseDown. bindKey (thePlayer, "w", "both", moveBaseUp) bindKey (thePlayer, "s", "both", moveBaseDown) Obs: O movimento da base é na diagonal. Até então tudo certo. O problema começa quando eu rotaciono o guindasteTop, os elementos anexados nele acompanham corretamente mas não é mais possível obter a real localização deles, pois a localização deles depende da rotação do guindasteTop e não mais de sua posição. Como faço para obter a real posição dos objetos anexados no guindasteTop depois de rotacioná-lo? E dos objetos anexados nos objetos que estão anexados nele? Obs: Estou rotacionando ele assim: function rotateTopLeft () if isTimer (topTimer) then killTimer (topTimer) end if not getElementData (guindasteTop, "movingLeft") then setElementData (guindasteTop, "movingLeft", true) setMarkerSize (enterMarker, 0) topTimer = setTimer (function() local x, y, z, rx, ry, rz = getElementAttachedOffsets (guindasteTop) setElementAttachedOffsets (guindasteTop, x, y, z, rx, ry, rz+0.1) end, 50, 0) else setElementData (guindasteTop, "movingLeft", false) end end function rotateTopRight () if isTimer (topTimer) then killTimer (topTimer) end if not getElementData (guindasteTop, "movingRight") then setElementData (guindasteTop, "movingRight", true) topTimer = setTimer (function() local x, y, z, rx, ry, rz = getElementAttachedOffsets (guindasteTop) setElementAttachedOffsets (guindasteTop, x, y, z, rx, ry, rz-0.1) end, 50, 0) else setElementData (guindasteTop, "movingRight", false) end end Edited January 17, 2018 by Lord Henry Link to comment
DNL291 Posted January 18, 2018 Share Posted January 18, 2018 Consegui entender toda ideia, ótima ilustração por sinal. Sobre obter a posição dos outros objetos anexados ao guindasteTop eu não entendi o por que de não receber as coordenadas, seria por conta da rotação do elemento ao qual os outros estão anexados? De qualquer forma: Quote guindasteSupport (anexado no guindasteTop com offset de x = 0, y = 50, z = 3.45) Tente usar essa função para obter as coordenadas duma offSet: function getPositionFromElementOffset(element,offX,offY,offZ) local m = getElementMatrix ( element ) -- Get the matrix local x = offX * m[1][1] + offY * m[2][1] + offZ * m[3][1] + m[4][1] -- Apply transform local y = offX * m[1][2] + offY * m[2][2] + offZ * m[3][2] + m[4][2] local z = offX * m[1][3] + offY * m[2][3] + offZ * m[3][3] + m[4][3] return x, y, z -- Return the transformed point end -- Obtendo a posição da offSet do guindasteTop x, y, z = getPositionFromElementOffset( guindasteTop, 0, 50, 3.45 ) Link to comment
Other Languages Moderators Lord Henry Posted January 18, 2018 Author Other Languages Moderators Share Posted January 18, 2018 (edited) 11 hours ago, DNL291 said: Consegui entender toda ideia, ótima ilustração por sinal. Obrigado. 11 hours ago, DNL291 said: Sobre obter a posição dos outros objetos anexados ao guindasteTop eu não entendi o por que de não receber as coordenadas, seria por conta da rotação do elemento ao qual os outros estão anexados? Sim. O problema ocorre pois as posições dos objetos 4, 5 e 6 dependem da rotação offset do guindasteTop, em vez de sua posição. Dai não consigo obter a real posição deles ao rotacionar o guindasteTop, pois ao rotacioná-lo, os objetos anexados a ele são considerados na mesma posição porém rotacionados. No caso pra obter a posição do guindasteTop é simples, pois o objeto que ele está anexado (guindasteBase) nunca rotaciona, então consigo obter com facilidade a posição dele usando getElementAttachedOffsets (guindasteTop) somado com a posição do guindasteBase. 11 hours ago, DNL291 said: De qualquer forma: Tente usar essa função para obter as coordenadas duma offSet: function getPositionFromElementOffset(element,offX,offY,offZ) local m = getElementMatrix ( element ) -- Get the matrix local x = offX * m[1][1] + offY * m[2][1] + offZ * m[3][1] + m[4][1] -- Apply transform local y = offX * m[1][2] + offY * m[2][2] + offZ * m[3][2] + m[4][2] local z = offX * m[1][3] + offY * m[2][3] + offZ * m[3][3] + m[4][3] return x, y, z -- Return the transformed point end -- Obtendo a posição da offSet do guindasteTop x, y, z = getPositionFromElementOffset( guindasteTop, 0, 50, 3.45 ) Não funcionou quando rotaciono o guindasteTop. Edited January 18, 2018 by Lord Henry Link to comment
Other Languages Moderators Lord Henry Posted January 18, 2018 Author Other Languages Moderators Share Posted January 18, 2018 (edited) O problema que estou tendo é assim: Spoiler Como pode ver, o guindasteSupport continua tendo exatamente os mesmos Offsets. Mas sua posição real muda dependendo do offset de rotação do guindasteTop. Edited January 18, 2018 by Lord Henry Link to comment
DNL291 Posted January 19, 2018 Share Posted January 19, 2018 Tenta usar esta função: function getPointFromDistanceRotation(x, y, dist, angle) local a = math.rad(90 - angle); local dx = math.cos(a) * dist; local dy = math.sin(a) * dist; return x+dx, y+dy; end A distância deve cair no mesmo ponto que o objeto guindasteSupport está anexado, no argumento angle, você precisa passar a mesma rotação (360 graus) que a do objeto guindasteTop. Link to comment
Other Languages Moderators Lord Henry Posted January 19, 2018 Author Other Languages Moderators Share Posted January 19, 2018 45 minutes ago, DNL291 said: Tenta usar esta função: function getPointFromDistanceRotation(x, y, dist, angle) local a = math.rad(90 - angle); local dx = math.cos(a) * dist; local dy = math.sin(a) * dist; return x+dx, y+dy; end A distância deve cair no mesmo ponto que o objeto guindasteSupport está anexado, no argumento angle, você precisa passar a mesma rotação (360 graus) que a do objeto guindasteTop. Rotação do guindasteTop é 0. Ele é rotacionado por meio de offset com a base. Link to comment
DNL291 Posted January 21, 2018 Share Posted January 21, 2018 É que eu não fiz nenhum teste pra te falar como obter a rotação dele, ainda assim, tenho certeza que você pode facilmente puxar a rotação do guindasteTop pra tentar fazer o cálculo da offSet do guindasteSupport. Tentou usar getElementRotation? Talvez a correção seja atualizar a posição de acordo com a do objeto-base com a função setElementAttachedOffsets. Não sei se já testou isso também, qualquer coisa só falar aqui. Se não conseguir corrigir essa parte, considere criar um objeto duplicado e invisível pra simular o objeto original, já que a origem do problema pode estar no guindasteTop estando também anexado a outro objeto. 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