Blitz3D+ Command Reference

GetBone ( entity,index )

Parameters

entity - handle of an animated entity
index - bone number, from 1 to CountBones(entity)

Description

Returns a skeleton bone by number.

Bones are numbered from 1, not 0, so a loop over a whole skeleton runs For i=1 To CountBones(e). The order is stable for a given model, so an index you find once stays valid for that model - though it is safer to look bones up by name with FindBone if the art might be re-exported.

The usual reason to walk the list is to find out what a rig contains: print EntityName(GetBone(e,i)) for each bone and you have the names to use with FindBone and AttachToBone afterwards.

What comes back is a normal entity handle. Read its world position with EntityX, EntityY and EntityZ to spawn effects at a joint, parent something to it, or nudge it after UpdateWorld for procedural motion the animation does not provide.

An index outside 1 to CountBones returns 0, and raises an error in debug mode.

See also: CountBones, FindBone, AttachToBone, EntityName, LoadAnimMesh.

Example

; GetBone Example
; ---------------

Graphics3D 640,480,0,2
SetBuffer BackBuffer()

camera=CreateCamera()
PositionEntity camera,0,2,-6
RotateEntity camera,12,0,0

light=CreateLight()
RotateEntity light,45,45,0

; A grassy paddock for the fox to roam
ground=CreatePlane()
EntityTexture ground,LoadTexture("media/MossyGround.BMP")

; Load the rigged fox; its skinned mesh is driven by a bone skeleton
fox=LoadAnimMesh("../../../samples/glTF/assets/Fox/Fox.glb")
If fox=0 Then RuntimeError "Could not load Fox.glb: "+ModelLoadError()

; Shrink the fox to game scale (the file is modelled about 100 units tall)
FitMesh fox,-0.8,0,-0.8,1.6,1.6,1.6,True

; Start the fox walking
walk=FindAnimSeq(fox,"Walk")
Animate fox,1,1,walk

bones=CountBones(fox)
index=1

; A glowing marker that rides the selected bone
marker=CreateSphere(8)
ScaleEntity marker,0.06,0.06,0.06
EntityColor marker,255,80,80
EntityFX marker,1

While Not KeyDown(1)

    ; Step through the skeleton with [ and ]
    If KeyHit(26) And index>1 Then index=index-1
    If KeyHit(27) And index<bones Then index=index+1

    UpdateWorld

    ; GetBone returns a bone by its one-based index; the result is a
    ; normal entity handle we can read coordinates from
    bone=GetBone(fox,index)
    PositionEntity marker,EntityX(bone,True),EntityY(bone,True),EntityZ(bone,True)

    ; 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,"[ / ]: select bone   Arrows: camera   Esc: exit"
    Text 0,20,"GetBone(fox,"+index+") of "+bones+" = "+Chr$(34)+EntityName(bone)+Chr$(34)

    Flip

Wend

End

Index