Sign in to follow this  
Lord Henry

Como obter a real posição de objeto anexado em um objeto rotacionado e anexado a outro objeto

Recommended Posts

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:

  1. guindasteBase (criado normalmente na posição e rotação correta, não está anexado em nenhum objeto)
  2. guindasteMiddle (anexado no guindasteBase, sem nenhum offset)
  3. guindasteTop (anexado no guindasteBase com offset de x = 0, y = -3.2, z = 19)
  4. guindasteSupport (anexado no guindasteTop com offset de x = 0, y = 50, z = 3.45)
  5. guindasteMagnet (anexado no guindasteSupport com offset de x = 0, y = 0, z = -1)
  6. 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:

I3UhqwNtQ660euU-c84D6w.jpg


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 by Lord Henry

Share this post


Link to post

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
  1. 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 )

 

Share this post


Link to post
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 by Lord Henry

Share this post


Link to post

O problema que estou tendo é assim:

Spoiler

DazrrPNNTfmBW4Lo63AQAg.jpg

NGvBUtbXRKGr_n4_0pX8Tg.jpg

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 by Lord Henry

Share this post


Link to post

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.

Share this post


Link to post
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.

Share this post


Link to post

É 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.

Share this post


Link to post

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.