Blitz3D+ Command Reference

GetMatElement# ( entity,row,column )

Parameters

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

Description

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.

Example

; 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

Index