Genies iOS SDK v0.1.9
Updated: May 2, 2026
What's New
- Talking / Breath / Look weights.
NAFAvatarSessionisObservableObjectwith three@Publishedweights (0–1). SDK auto-loads breathing + runs gaze internally;NAFViewwires it all so consumers just setview.session.lookWeight = 1. BYO consumers registercameraPositionProvider+avatarModelTransformonce. - Blendshape GPU rendering.
NAFViewnow applies per-frame morph weights from the C++ animation graph — talking, blinks, emotions, base demeanor become visible on iOS instead of being silently discarded. New surface:NAFAvatarController.morphTargetNames+NAFAvatarSession.morphTargetWeights(forMeshAt:)for BYO consumers. NAFAvatarRendererprotocol +NAFAvatarSession.uploadAnimationState(to:). BYO consumers conform their renderer (two methods) and pump bone matrices + morph weights with one call per frame.NAFMeshData.makeMorphPositionDeltaBuffer(device:)+makeMorphWeightsBuffer(device:)(NAFKitUITools) — one-call helpers that pack morph deltas into the canonicalmorphIdx * vertexCount + vidlayout. Return a placeholder buffer for no-morph meshes so the renderer's bind path stays branch-free.NAFEventBridge— Obj-C wrapper over the unified C++GnUtils::EventBus. String-keyedsubscribe/fire/sendRequest, RAII tokens, optional dispatch queue. Sits alongsideNAFEventBus.SceneInteractionController(NAFKitUITools) — public UIKit glue aroundAvatarPicker+TransformGizmo. Owns the tap + gizmo-pan recognizers + axis overlay; consumers wire candidates / frame context / gizmo centre via closures and callattach(to:)+requireFailure(for:).NAFViewnow uses it internally.NAFAvatarSession.loadAvatarProgressive(behavior:)is optional — passnilfor test definitions.NAFView.loadAvatarProgressive(behavior:)mirrors.
What's Fixed
equip/unequipnow work incrementally on definition-loaded assets. Session reconciles its builder with the native handle's per-asset entity map after the first LOD lands.- LOD upgrade composition order is stable — batches apply in
NAFAvatarDefinition.assetsorder instead of arrival order. NAFAvatarSession.onErrornow logs alongside the UI message