Skip to content
On this page

glTF Timeline Markers extension and Blender add-on

Blender includes Timeline markers which are quite useful in animations. By default, when exporting a glTF file, these markers are not included in the output. This extension adds support for exporting these markers along with the scene object.

Another useful feature is to map cameras to the markers. This is useful when the camera is animated and the markers are used to switch between different camera views. The extension also saves the mapping with any camera objects in the scene to the timeline markers.

Extension Name - WEBGI_animation_markers

Data format -

typescript
type MarkerData = {
    name: string,
    frame: number,
    time: number, // frame/fps
    camera?: string
}

The data is added to scene - scene.extensions.WEBGI_animation_markers as {"markers": MarkerData[]} and exported in the glTF file.

Download from github - https://github.com/repalash/blender_gltf_timeline_markers_addon

three.js extension to import in GLTFLoader

typescript
class GLTFTimelineMarkersExtension implements GLTFLoaderPlugin {
    public name: string
    public parser: GLTFParser

    constructor(parser:GLTFParser) {
        this.parser = parser
        this.name = 'WEBGI_animation_markers'

    }
    async afterRoot(result: GLTF) {
        const markers: any[] = []
        for (const jScene of this.parser.json.scenes) {
            if (!jScene.extensions) continue
            const params = jScene.extensions[this.name]
            for (const marker of params?.markers || []) {
                const camera = marker.camera !== undefined ? await this.parser.getDependency('camera', marker.camera) : undefined
                markers.push({
                    name: marker.name,
                    frame: marker.frame,
                    camera,
                })
            }
        }
        if (markers.length < 1) return

        const scene = result.scene ?? result.scenes[0]
        if (!scene) return
        scene.userData.markers = markers

        const fps = 30
        const times = markers.map(m=>m.frame / fps)
        let i = 0
        const values = markers.map(m=>i++)
        const duration = Math.max(...times) + 0.01

        let temp = -1
        const trackName = '.currentTimelineMarker'
        Object.defineProperty(scene, 'currentTimelineMarker', {
            get: ()=>temp,
            set: (v: any)=> scene.dispatchEvent({type: 'animationTimelineMarker', marker: markers[temp = v]}),
        })
        const track = new NumberKeyframeTrack(trackName, times, values, InterpolateDiscrete)
        const anim = new AnimationClip('animationTimelineMarker', duration, [track])
        result.animations.push(anim)
    }

}

gltfLoader.register((p)=>new GLTFTimelineMarkersExtension(p))

This creates and AnimationClip(and adds to the scene), which dispatches an event of type animationTimelineMarker on the scene object when the current marker changes. This can be used to switch cameras or any other action based on the timeline markers.

See also - webgi, threepipe

Made with ❤️ using the awesome vitepress