FindMorphTarget ( entity,name$ )

Parameters

entity - handle of the entity to search

name$ - name of the morph target to look for

Description

Returns the number of a named morph target, or -1 if the model has no such shape.

Artists name their blend shapes - "Smile", "Blink", "Charged", "Damaged" - while SetMorphWeight and MorphWeight only deal in numbers. FindMorphTarget is the bridge. Look the names up once when you set the model up, stash the numbers in variables, and the rest of your game never has to know that "Blink" happens to be shape 3 in this particular export.

The match is forgiving about case. An exact match wins if one exists, and failing that the engine tries again ignoring case, so "smile", "Smile" and "SMILE" all land on the same target. Names travel in the model file, which in practice means glTF and GLB exports that carry target names.

Like the other morph queries, it looks at the entity you give it and then descends into its children until it finds a mesh that actually has morph targets - so you can hand it the root of a freshly loaded model without picking through the hierarchy yourself.

Always test for -1 before using the result. A missing shape is usually a typo or a model exported without it, and nothing downstream will complain: SetMorphWeight with a target of -1 silently does nothing at all, so the bug shows up as a face that never blinks rather than as an error message. Printing the name you asked for makes it obvious in seconds.

See also: CountMorphTargets, SetMorphWeight, MorphWeight, FindAnimSeq, LoadAnimMesh.

Example

; FindMorphTarget Example
; -----------------------

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

camera=CreateCamera()
PositionEntity camera,0,1.5,-6

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

ground=CreatePlane()
EntityTexture ground,LoadTexture("media/MossyGround.BMP")

; A power crystal whose morph targets are named "Charged" and "Depleted"
gem=LoadAnimMesh("media/MorphGem.gltf")
If gem=0 Then RuntimeError "Could not load MorphGem.gltf: "+ModelLoadError()
PositionEntity gem,0,1,0

; Game code thinks in shape names, not shape numbers
wanted$="Charged"
asked$=""
target=-1

While Not KeyDown(1)

    ; 1 and 2 ask for real shapes, 3 asks for one this model does not have
    If KeyHit(2) Then wanted$="Charged"
    If KeyHit(3) Then wanted$="depleted"
    If KeyHit(4) Then wanted$="Sparkle"

    ; Only look the name up when the request changes - the number is stable
    If wanted$<>asked$
        asked$=wanted$
        ; FindMorphTarget returns the target number, or -1 if there is no match
        target=FindMorphTarget(gem,asked$)
        ; Flatten both shapes before driving the newly chosen one
        SetMorphWeight gem,0,0
        SetMorphWeight gem,1,0
    EndIf

    ; Drive whichever target the name resolved to
    If target>=0 Then SetMorphWeight gem,target,(Sin(MilliSecs()/6.0)+1)*0.5

    TurnEntity gem,0,0.6,0

    ; 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 Charged  2 depleted  3 Sparkle   Arrows: camera   Esc: exit"
    Text 0,20,"FindMorphTarget(gem,"+Chr$(34)+asked$+Chr$(34)+") = "+target

    If target<0
        Text 0,40,"-1 means no such shape - the gem just sits still"
    Else
        Text 0,40,"Key 2 matched despite the lower case: the search retries case-insensitively"
    EndIf

    Flip

Wend

End

Index