GetElementMatrix: Difference between revisions
No edit summary |
Zangomangu (talk | contribs) Tag: Undo |
||
(22 intermediate revisions by 8 users not shown) | |||
Line 1: | Line 1: | ||
{{ | {{Shared function}} | ||
__NOTOC__ | __NOTOC__ | ||
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. | 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'''''.}} | |||
Note | {{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"> | ||
table getElementMatrix ( element theElement ) | table getElementMatrix ( element theElement [, bool legacy = true ] ) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
{{OOP||[[element]]:getMatrix|matrix|setElementMatrix}} | |||
===Required Arguments=== | ===Required Arguments=== | ||
*'''theElement:''' The element which you wish to retrieve the matrix for | *'''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=== | ||
Returns a multi-dimensional array containing a 4x4 matrix. | 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== | ||
Line 19: | Line 23: | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
function getPositionFromElementOffset(element,offX,offY,offZ) | 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 | end | ||
-- Get the position of a point 3 units to the | -- Get the position of a point 3 units to the right of the element: | ||
x,y,z = getPositionFromElementOffset(element,3,0,0) | x,y,z = getPositionFromElementOffset(element,3,0,0) | ||
Line 40: | Line 44: | ||
<syntaxhighlight lang="lua"> | <syntaxhighlight lang="lua"> | ||
function getMatrixLeft(m) | function getMatrixLeft(m) | ||
return m[1][1], m[1][2], m[1][3] | |||
end | end | ||
function getMatrixForward(m) | function getMatrixForward(m) | ||
return m[2][1], m[2][2], m[2][3] | |||
end | end | ||
function getMatrixUp(m) | function getMatrixUp(m) | ||
return m[3][1], m[3][2], m[3][3] | |||
end | end | ||
function getMatrixPosition(m) | function getMatrixPosition(m) | ||
return m[4][1], m[4][2], m[4][3] | |||
end | end | ||
Line 58: | Line 62: | ||
</syntaxhighlight> | </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> | |||
</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.
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
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
-- 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
- getElementBoneMatrix
- getElementBonePosition
- getElementBoneRotation
- getElementBoundingBox
- getElementDistanceFromCentreOfMassToBaseOfModel
- getElementLighting
- getElementRadius
- isElementCollidableWith
- isElementLocal
- isElementOnScreen
- isElementStreamable
- isElementStreamedIn
- isElementSyncer
- isElementWaitingForGroundToLoad
- setElementBoneMatrix
- setElementBonePosition
- setElementBoneRotation
- setElementCollidableWith
- setElementStreamable
- updateElementRpHAnim
- Shared
- attachElements
- createElement
- destroyElement
- detachElements
- getAttachedElements
- getElementAlpha
- getElementAttachedOffsets
- getElementAttachedTo
- getElementByIndex
- getElementByID
- getElementChild
- getElementChildren
- getElementChildrenCount
- getElementCollisionsEnabled
- getElementColShape
- getElementData
- getAllElementData
- hasElementData
- getElementDimension
- getElementHealth
- getElementID
- getElementInterior
- getElementMatrix
- getElementModel
- getElementParent
- getElementPosition
- getElementRotation
- getElementsByType
- getElementsWithinColShape
- getElementsWithinRange
- getElementType
- getElementVelocity
- getLowLODElement
- getRootElement
- isElement
- isElementAttached
- isElementCallPropagationEnabled
- isElementDoubleSided
- isElementFrozen
- isElementInWater
- isElementLowLOD
- isElementWithinColShape
- isElementWithinMarker
- setElementAlpha
- setElementAngularVelocity
- getElementAngularVelocity
- setElementAttachedOffsets
- setElementCallPropagationEnabled
- setElementCollisionsEnabled
- setElementData
- setElementDimension
- setElementDoubleSided
- setElementFrozen
- setElementHealth
- setElementID
- setElementInterior
- setElementModel
- setElementParent
- setElementPosition
- setElementRotation
- setElementVelocity
- setLowLODElement
- getPedContactElement
- getResourceDynamicElementRoot
- getResourceRootElement