Glb rigging issue in subclips

Hi there. For the record, this is being done in an A-frame project hosted on 8th Wall, and all the code is contained in an a-frame component. (we couldn’t rely on their animation-mixer for this)

  • We’re trying to animate a glb model exported from maya.
  • The model only has one animation clip, which we split into subclips. It’s essentially an AR video that plays out in bits and pieces.
  • If I play the whole clip through, it looks fine
  • But when I start from a subclip partway through, there are various problems with the rig. Some moving parts get disconnected some parts get reset. It looks like issues with the keyframes somehow?
    Our animator assures me that the animation is fully “baked”, having keyframes for every element at every frame.

So my questions are:

  1. Does making subclips do something with the keyframes I’m not aware of?
  2. Could I maybe start and loop from the main clip in certain frames? Or something else to preserve the fidelity of the animation
  3. Is this actually an issue with the glb?

Here is the code for the record

const deliveryAnimationComponent = {
  // USE THE INTEGER VALUE TO CHOOSE A CLIP TO PLAY
  schema: {type: 'int', default: -1},
  init() {
    this.oldClipNum = -1
    this.clips = []
    this.fps = 24
    this.clock = new THREE.Clock()
    const model = this.el.getObject3D('mesh');
    if (model) {
      this.load(model)
    } else {
      this.el.addEventListener('model-loaded', (e) => {
        this.load(e.detail.model)
      })
    }
  },
  load(model) {
    const el = this.el
    this.model = model
    this.mixer = new THREE.AnimationMixer(this.el.object3D)
    // console.log(this.model.animations[0])
    
    THIS IS AN EXAMPLE. ADD CLIPS AS NECESSARY, USING DIFFERENT START AND END FRAMES
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 1', 60, 85, 24))
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 2', 303, 394, 24))
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 3', 520, 566, 24))
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 4', 566, 580, 24))
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 5', 420, 494, 24))
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 6', 668, 712, 24))
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 7', 800, 928, 24))
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 8', 1118, 1261, 24))
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 9', 1261, 1368, 24))
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 10', 1416, 1642, 24))
    this.clips.push(THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 11', 1642, 1691, 24))

    // THIS CLIP EXISTS TO RESET TO THE FIRST FRAME
    this.stopClip = THREE.AnimationUtils.subclip(this.model.animations[0], 'Clip 0', 0, 0, 24)
    // console.log('clip loaded?')
  },

  tick() {
    // console.log('this.clipNum = ' + this.data)
    if (this.mixer) {
      if (this.data !== this.oldClipNum) {
        this.mixer.stopAllAction()
        if (this.data >= 0) {
          const newAction = this.mixer.clipAction(this.clips[this.data])
          newAction.play()
          this.oldClipNum = this.data
          // console.log('should be playing...')
        } else {
          const newAction = this.mixer.clipAction(this.stopClip)
          newAction.loop = THREE.LoopOnce
          newAction.play()
        }
      }
      this.mixer.update(this.clock.getDelta())
    }
  },
}