|
entity - handle of the entity whose world matrix you want row - which row to read: 0: the entity's right (local X) axis 1: the entity's up (local Y) axis 2: the entity's forward (local Z) axis 3: the entity's world position column - which component of that row: 0: x 1: y 2: z |
|
Returns one element of an entity's world transformation matrix. Every entity carries a matrix describing where it is and which way it is facing, and this is the command that lets you read it a number at a time. The first three rows are the entity's own axes expressed in world space - row 0 points right, row 1 points up, row 2 points forward - and row 3 is simply its world position, the same three numbers EntityX, EntityY and EntityZ give you. Rows 0 to 2 are what make this worth knowing. Want the muzzle of a tank barrel? Take row 3 and add row 2 times the barrel length, and you have the world position with no trigonometry at all. Want to strafe a ship sideways, spray sparks along its up axis, or work out whether an enemy is to your left by dotting row 0 against the direction to it? All of those are one read of the matrix instead of a page of angle maths, and they stay correct however the entity got where it is - parented, pointed, rotated by physics, whatever. The values always come from the world transform, so a wheel parented to a car reports the axes it really has on screen, not the ones it has relative to the car. Scale is baked in too: an entity scaled by 3 gives rows three units long. Normalise them yourself if you want pure directions - or use TFormVector, which does the same job with the scale already handled. The row and column numbers are not checked. Keep row in 0 to 3 and column in 0 to 2; feed it anything else and you get whichever float happens to sit next in memory rather than an error message. And remember it is a read-only view - there is no SetMatElement, so entities are still moved with PositionEntity, RotateEntity and friends. See also: TFormVector, TFormPoint, EntityX, EntityYaw, VectorYaw, AlignToVector. |
; GetMatElement Example
; ---------------------
Graphics3D 640,480,0,2
SetBuffer BackBuffer()
camera=CreateCamera()
PositionEntity camera,0,5,-11
RotateEntity camera,18,0,0
light=CreateLight()
RotateEntity light,45,45,0
ground=CreatePlane()
EntityTexture ground,LoadTexture("media/MossyGround.BMP")
; The turret whose world matrix we are going to read
turret=CreateCube()
PositionEntity turret,0,1,0
; A barrel child, so you can see which way "forward" points
barrel=CreateCylinder(12,True,turret)
ScaleEntity barrel,0.3,1.2,0.3
RotateEntity barrel,90,0,0
PositionEntity barrel,0,0,1.2
; A tracer we will park at the muzzle using nothing but matrix rows
tracer=CreateSphere(8)
ScaleEntity tracer,0.2,0.2,0.2
EntityColor tracer,255,220,60
spin=1
While Not KeyDown(1)
; Space stops the turret so the numbers hold still
If KeyHit(57) Then spin=1-spin
If spin Then TurnEntity turret,0,0.5,0
; Row 2 is the turret's forward axis, row 3 is its world position
fx#=GetMatElement(turret,2,0)
fy#=GetMatElement(turret,2,1)
fz#=GetMatElement(turret,2,2)
px#=GetMatElement(turret,3,0)
py#=GetMatElement(turret,3,1)
pz#=GetMatElement(turret,3,2)
; Muzzle = position + forward * barrel length, and not a Sin in sight
PositionEntity tracer,px+fx*2.4,py+fy*2.4,pz+fz*2.4
; Arrow keys move the camera
If KeyDown(200) Then MoveEntity camera,0,0,0.1
If KeyDown(208) Then MoveEntity camera,0,0,-0.1
If KeyDown(203) Then TurnEntity camera,0,1,0
If KeyDown(205) Then TurnEntity camera,0,-1,0
RenderWorld
Text 0,0,"Space: stop/start the turret Arrows: camera Esc: exit"
Text 0,20,"row 0 right "+GetMatElement(turret,0,0)+", "+GetMatElement(turret,0,1)+", "+GetMatElement(turret,0,2)
Text 0,40,"row 1 up "+GetMatElement(turret,1,0)+", "+GetMatElement(turret,1,1)+", "+GetMatElement(turret,1,2)
Text 0,60,"row 2 forward "+fx+", "+fy+", "+fz
Text 0,80,"row 3 position "+px+", "+py+", "+pz
Text 0,100,"The yellow tracer sits at row 3 plus row 2 times 2.4"
Flip
Wend
End