Motion Scene Widget
The motion scene widget is the path-driven character and emote runtime in ESP Emote GFX. It is designed for assets exported as a gfx_motion_asset_t bundle and rendered through gfx_motion_player_t.
When to Use It
Use the motion scene path when you need:
Character or emote playback built from vector-like paths instead of bitmap frames
Per-part styling with solid colors, palette colors, opacity, or texture binding
Small action sets such as idle, move, happy, thinking, or touch-reactive actions
Canvas-level movement where the whole character can swim, drift, or follow touch input
Core Model
The motion scene asset has four main layers:
joint_namesand joint coordinates: named control points in design spacesegments: visual primitives built from jointsposes: complete joint-coordinate snapshotsactions: sequences of pose steps with hold time, interpolation, and facing
The runtime owns a parser plus renderer:
gfx_motion_scene_tmanages pose interpolation and action stategfx_motion_player_tcreates onegfx_mesh_imgobject per segment and applies the current pose to screen space
Segment Types
The current scene format supports these segment kinds:
GFX_MOTION_SEG_CAPSULE: thick limb/body stroke between two jointsGFX_MOTION_SEG_RING: circular outline around a center jointGFX_MOTION_SEG_BEZIER_STRIP: open Bezier strokeGFX_MOTION_SEG_BEZIER_LOOP: closed Bezier strokeGFX_MOTION_SEG_BEZIER_FILL: closed filled Bezier region
Each segment can also carry:
stroke_widthoverrideresource_idxfor texture/image bindingcolor_idxfor palette-bound solid coloropacityfor per-part alpha
Playback Flow
Typical runtime usage:
Create or include a generated scene asset (for example from a designer/export pipeline).
Call
gfx_motion_player_init()with a display and the asset.Set the target canvas using
gfx_motion_player_set_canvas().Optionally set the runtime color with
gfx_motion_player_set_color().Select an initial action using
gfx_motion_player_set_action().When finished, call
gfx_motion_player_deinit().
Example
#include "gfx.h"
#include "rig_active.inc"
static gfx_motion_player_t motion_player;
void motion_scene_start(gfx_disp_t *disp)
{
gfx_motion_player_init(&motion_player, disp, &s_motion_scene_asset);
gfx_motion_player_set_canvas(&motion_player, 0, 0, 360, 360);
gfx_motion_player_set_color(&motion_player, GFX_COLOR_HEX(0xFF7A00));
gfx_motion_player_set_action(&motion_player, 0, true);
}
void motion_scene_stop(void)
{
gfx_motion_player_deinit(&motion_player);
}
Interactive Example
An end-to-end example is available in test_apps/main/test_motion.c. It demonstrates:
full-screen motion scene preview
tap-to-switch action
touch-guided movement by changing the runtime canvas
timer-driven autonomous movement between touch interactions
Current Notes
The current implementation intentionally keeps the dependency chain small:
no NanoVG dependency
no libtess2 dependency
filled polygon rendering uses the internal software path
This makes the widget easier to release and integrate into ESP-IDF projects, while keeping the scene model stable for designer/export tooling.