Blitz3D+ Command Reference

FindBone ( entity,name$ )

Parameters

entity - handle of an animated entity
name$ - bone name, or a slash-separated path through the skeleton

Description

Finds a skeleton bone by name and returns its entity handle, or 0 if there is no such bone.

This is the practical way into a rig: FindBone(player,"Head") hands you the head joint, ready to parent a hat to, spawn blood at, or turn a few degrees towards whatever the character should be looking at. Names come from the model file - walk the skeleton with CountBones and GetBone once to see what they are.

Matching tries an exact name first and then falls back to a case-insensitive comparison, so "head" will find "Head". If more than one bone matches, you get one of them and a note in the debug log; give a slash-separated path such as "Spine/Neck/Head" to say exactly which one you mean. That happens more often than you would think, since rigs frequently have left and right chains with matching names further down.

The search only looks inside the entity you pass, so two copies of the same character each resolve to their own bones - copy a model with CopyEntity and FindBone on the copy gives the copy joints, not the original ones.

The handle you get back is an ordinary entity, so all the usual position, rotation and parenting commands work on it.

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

Example

; FindBone 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 we can look up by name in the fox skeleton
bone_name$="b_Head_05"

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

While Not KeyDown(1)

    ; Pick which named bone to track
    If KeyHit(2) Then bone_name$="b_Head_05"
    If KeyHit(3) Then bone_name$="b_Tail03_014"
    If KeyHit(4) Then bone_name$="b_RightHand_08"

    UpdateWorld

    ; FindBone looks a bone up by name and returns its entity handle
    bone=FindBone(fox,bone_name$)
    If bone Then 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,"1: head   2: tail tip   3: right hand   Arrows: camera   Esc: exit"
    Text 0,20,"FindBone(fox,"+Chr$(34)+bone_name$+Chr$(34)+") - green marker rides the bone"

    Flip

Wend

End

Index