GetElementMatrix: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
(int CLuaFunctionDefinitions::GetElementMatrix)
(Undo revision 67564 by Daddy (talk))
Tag: Undo
 
(31 intermediate revisions by 12 users not shown)
Line 1: Line 1:
{{Client function}}
{{Shared function}}
__NOTOC__  
__NOTOC__  
// Placeholder article, please fill in details.
This function gets an [[element]]'s transform [[matrix]]. This contains 16 float values that multiplied to a point will give you the point transformed. It is most useful for matrix calculations such as calculating offsets. For further information, please refer to a tutorial of matrices in computer graphics programming.
 
{{Note|The [[matrix]] returned by this function is [http://bugs.mtasa.com/view.php?id{{=}}6984 not setup correctly for some calculations] unless the '''legacy''' argument is set to '''''false'''''.}}
{{Tip|''For [[matrix]] manipulation which goes beyond the basic examples given on this page, see the [[Lua matrix library]].'' If you are using MTA: SA 1.4 or higher, using the built-in [[matrix]] class is also recommended.}}
==Syntax==
==Syntax==
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
int getElementMatrix ( element theElement )      
table getElementMatrix ( element theElement [, bool legacy = true ] )
</syntaxhighlight>  
</syntaxhighlight>
{{OOP||[[element]]:getMatrix|matrix|setElementMatrix}}


===Required Arguments===  
===Required Arguments===  
*'''theElement:''' TODO
*'''theElement:''' The [[element]] which you wish to retrieve the [[matrix]] for.
 
===Optional Arguments===
*'''legacy:''' Set to ''false'' to return correctly setup [[matrix]] (i.e. Last column in the first 3 rows set to zero).


===Returns===
===Returns===
TODO
Returns a multi-dimensional array (which can be transformed into a proper [[matrix]] class using ''Matrix.create'' method) containing a 4x4 matrix. Returns ''false'' if the element is not streamed in, and not a [[vehicle]], [[ped]] or [[object]].


==Example==  
==Example==  
TODO
This example creates a utility function that turns an offset into a position that is relative to the specified element.
<section name="Client" class="client" show="true">
<syntaxhighlight lang="lua">
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
 
-- Get the position of a point 3 units to the right of the element:
x,y,z = getPositionFromElementOffset(element,3,0,0)
 
-- Get the position of a point 2 units in front of the element:
x,y,z = getPositionFromElementOffset(element,0,2,0)
 
-- Get the position of a point 1 unit above the element:
x,y,z = getPositionFromElementOffset(element,0,0,1)
 
</syntaxhighlight>
 
This example creates some more matrix utility functions
<syntaxhighlight lang="lua">
<syntaxhighlight lang="lua">
-- TODO
function getMatrixLeft(m)
    return m[1][1], m[1][2], m[1][3]
end
function getMatrixForward(m)
    return m[2][1], m[2][2], m[2][3]
end
function getMatrixUp(m)
    return m[3][1], m[3][2], m[3][3]
end
function getMatrixPosition(m)
    return m[4][1], m[4][2], m[4][3]
end
 
local mat = getElementMatrix(element)  -- Get the matrix
x,y,z = getMatrixLeft(mat)    -- Get the matrix left direction
x,y,z = getMatrixForward(mat)  -- Get the matrix forward direction
x,y,z = getMatrixUp(mat)      -- Get the matrix up direction
 
</syntaxhighlight>
 
This example function allows you to get the element matrix of an element that is not streamed in.
<syntaxhighlight lang="lua">
function getElementMatrix(element)
    local rx, ry, rz = getElementRotation(element, "ZXY")
    rx, ry, rz = math.rad(rx), math.rad(ry), math.rad(rz)
    local matrix = {}
    matrix[1] = {}
    matrix[1][1] = math.cos(rz)*math.cos(ry) - math.sin(rz)*math.sin(rx)*math.sin(ry)
    matrix[1][2] = math.cos(ry)*math.sin(rz) + math.cos(rz)*math.sin(rx)*math.sin(ry)
    matrix[1][3] = -math.cos(rx)*math.sin(ry)
    matrix[1][4] = 1
   
    matrix[2] = {}
    matrix[2][1] = -math.cos(rx)*math.sin(rz)
    matrix[2][2] = math.cos(rz)*math.cos(rx)
    matrix[2][3] = math.sin(rx)
    matrix[2][4] = 1
    matrix[3] = {}
    matrix[3][1] = math.cos(rz)*math.sin(ry) + math.cos(ry)*math.sin(rz)*math.sin(rx)
    matrix[3][2] = math.sin(rz)*math.sin(ry) - math.cos(rz)*math.cos(ry)*math.sin(rx)
    matrix[3][3] = math.cos(rx)*math.cos(ry)
    matrix[3][4] = 1
    matrix[4] = {}
    matrix[4][1], matrix[4][2], matrix[4][3] = getElementPosition(element)
    matrix[4][4] = 1
    return matrix
end
</syntaxhighlight>
 
 
 
 
<section name="Server side: Front to Front" class="server" show="true">
-- create a Ped (0, 0, 5, 0) and put the player to 10 m of distance, front to front
<syntaxhighlight lang="lua">
function startedThisResource (res)
if getThisResource() == res then
local thePed = createPed ( 287, 0, 0, 5, 0)
local matrix = getElementMatrix(thePed)
nx = 0 * matrix[1][1] + 10 * matrix[2][1] + 0 * matrix[3][1] + 1 * matrix[4][1]
ny = 0 * matrix[1][2] + 10 * matrix[2][2] + 0 * matrix[3][2] + 1 * matrix[4][2]
nz = 0 * matrix[1][3] + 10 * matrix[2][3] + 0 * matrix[3][3] + 1 * matrix[4][3]
for a, z in ipairs(getElementsByType("player")) do
setElementPosition (z, nx, ny, nz)
local playerX, playerY, playerZ = getElementPosition(z)
local pedX, pedY, pedZ = getElementPosition(thePed)
local rotZ = findRotation( playerX, playerY, pedX, pedY )
setElementRotation(z, 0, 0, rotZ)
end
end
end
addEventHandler("onResourceStart", getRootElement(), startedThisResource)
 
function findRotation( x1, y1, x2, y2 )
    local t = -math.deg( math.atan2( x2 - x1, y2 - y1 ) )
    return t < 0 and t + 360 or t
end
</syntaxhighlight>
</syntaxhighlight>
</section>
</section>
==Changelog==
{{ChangelogHeader}}
{{ChangelogItem|1.3.0-9.04186|Added legacy argument}}


==See Also==
==See Also==
{{Client_element_functions}}
{{Client_element_functions}}

Latest revision as of 22:08, 25 December 2020

This function gets an element's transform matrix. This contains 16 float values that multiplied to a point will give you the point transformed. It is most useful for matrix calculations such as calculating offsets. For further information, please refer to a tutorial of matrices in computer graphics programming.

[[{{{image}}}|link=|]] Note: The matrix returned by this function is not setup correctly for some calculations unless the legacy argument is set to false.
[[{{{image}}}|link=|]] Tip: For matrix manipulation which goes beyond the basic examples given on this page, see the Lua matrix library. If you are using MTA: SA 1.4 or higher, using the built-in matrix class is also recommended.

Syntax

table getElementMatrix ( element theElement [, bool legacy = true ] )

OOP Syntax Help! I don't understand this!

Method: element:getMatrix(...)
Variable: .matrix
Counterpart: setElementMatrix


Required Arguments

  • theElement: The element which you wish to retrieve the matrix for.

Optional Arguments

  • legacy: Set to false to return correctly setup matrix (i.e. Last column in the first 3 rows set to zero).

Returns

Returns a multi-dimensional array (which can be transformed into a proper matrix class using Matrix.create method) containing a 4x4 matrix. Returns false if the element is not streamed in, and not a vehicle, ped or object.

Example

This example creates a utility function that turns an offset into a position that is relative to the specified element.

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

-- Get the position of a point 3 units to the right of the element:
x,y,z = getPositionFromElementOffset(element,3,0,0)

-- Get the position of a point 2 units in front of the element:
x,y,z = getPositionFromElementOffset(element,0,2,0)

-- Get the position of a point 1 unit above the element:
x,y,z = getPositionFromElementOffset(element,0,0,1)

This example creates some more matrix utility functions

function getMatrixLeft(m)
    return m[1][1], m[1][2], m[1][3]
end
function getMatrixForward(m)
    return m[2][1], m[2][2], m[2][3]
end
function getMatrixUp(m)
    return m[3][1], m[3][2], m[3][3]
end
function getMatrixPosition(m)
    return m[4][1], m[4][2], m[4][3]
end

local mat = getElementMatrix(element)  -- Get the matrix
x,y,z = getMatrixLeft(mat)     -- Get the matrix left direction
x,y,z = getMatrixForward(mat)  -- Get the matrix forward direction
x,y,z = getMatrixUp(mat)       -- Get the matrix up direction

This example function allows you to get the element matrix of an element that is not streamed in.

function getElementMatrix(element)
    local rx, ry, rz = getElementRotation(element, "ZXY")
    rx, ry, rz = math.rad(rx), math.rad(ry), math.rad(rz)
    local matrix = {}
    matrix[1] = {}
    matrix[1][1] = math.cos(rz)*math.cos(ry) - math.sin(rz)*math.sin(rx)*math.sin(ry)
    matrix[1][2] = math.cos(ry)*math.sin(rz) + math.cos(rz)*math.sin(rx)*math.sin(ry)
    matrix[1][3] = -math.cos(rx)*math.sin(ry)
    matrix[1][4] = 1
    
    matrix[2] = {}
    matrix[2][1] = -math.cos(rx)*math.sin(rz)
    matrix[2][2] = math.cos(rz)*math.cos(rx)
    matrix[2][3] = math.sin(rx)
    matrix[2][4] = 1
	
    matrix[3] = {}
    matrix[3][1] = math.cos(rz)*math.sin(ry) + math.cos(ry)*math.sin(rz)*math.sin(rx)
    matrix[3][2] = math.sin(rz)*math.sin(ry) - math.cos(rz)*math.cos(ry)*math.sin(rx)
    matrix[3][3] = math.cos(rx)*math.cos(ry)
    matrix[3][4] = 1
	
    matrix[4] = {}
    matrix[4][1], matrix[4][2], matrix[4][3] = getElementPosition(element)
    matrix[4][4] = 1
	
    return matrix
end



Click to collapse [-]
Server side: Front to Front

-- create a Ped (0, 0, 5, 0) and put the player to 10 m of distance, front to front

function startedThisResource (res)
	if getThisResource() == res then
		local thePed = createPed ( 287, 0, 0, 5, 0)
		local matrix = getElementMatrix(thePed)
		nx = 0 * matrix[1][1] + 10 * matrix[2][1] + 0 * matrix[3][1] + 1 * matrix[4][1]
		ny = 0 * matrix[1][2] + 10 * matrix[2][2] + 0 * matrix[3][2] + 1 * matrix[4][2]
		nz = 0 * matrix[1][3] + 10 * matrix[2][3] + 0 * matrix[3][3] + 1 * matrix[4][3]
		for a, z in ipairs(getElementsByType("player")) do
			setElementPosition (z, nx, ny, nz)
			local playerX, playerY, playerZ = getElementPosition(z)
			local pedX, pedY, pedZ = getElementPosition(thePed)
			local rotZ = findRotation( playerX, playerY, pedX, pedY ) 
			setElementRotation(z, 0, 0, rotZ)
		end
	end
end
addEventHandler("onResourceStart", getRootElement(), startedThisResource)

function findRotation( x1, y1, x2, y2 ) 
    local t = -math.deg( math.atan2( x2 - x1, y2 - y1 ) )
    return t < 0 and t + 360 or t
end

Changelog

Version Description
1.3.0-9.04186 Added legacy argument

See Also