Using pyscript and THREE js for loading GLTF

Hello, I was trying to load a GLTF file and animate it using THREE js but through pyscript that uses pyodide
So far I have been successful in loading a GLTF object with the materials, but I am stuck when trying to use the animation mixer
I probably need to define mixer as a global variable, but it becomes inaccessible when using create_proxy function.

The attached code will successfully load GLTF file but ideally it should be also animating it, can someone please help

(html file)

html.txt (2.7 KB)

(python file)
python.txt (5.7 KB)

Hey @Homagni_Saha! We are happy to help you debug your animation issue. Could you please recreate an example of your issue in a test fiddle? Three JSFiddle Skeleton - JSFiddle - Code Playground

Also, while I’m not familiar with py, you typically need access to the mixer in both your model load function and your animation loop.

Hello @notchris , thanks so much for your interest in helping, I have modified and saved the code in the test fiddle, Three JSFiddle Skeleton - JSFiddle - Code Playground can you please take a look at it?
I think Im probably just doing some simple mistake with the clip animation part
BTW, I am basically trying to reproduce this js code which works in pure js
How to Create an Interactive 3D Character with Three.js | Codrops (tympanus.net)

Hello! I am not super familiar with pyscript, but I recreated your example with js and see the model animating as expected.

	const gltf = new GLTFLoader();
	gltf.load('https://s3-us-west-2.amazonaws.com/s.cdpn.io/1376484/stacy_lightweight.glb', function (object) {
		
		const model = object.scene
    const anims = object.animations
    console.log(model, anims)
    
    scene.add(model)
    model.scale.set(4, 4, 4)
   	model.position.y -= 2
    const skinnedMesh = scene.getObjectByName('stacy')
    const texture = new THREE.TextureLoader()
    texture.load('https://s3-us-west-2.amazonaws.com/s.cdpn.io/1376484/stacy.jpg', (t) => {
      t.flipY = false
      skinnedMesh.material.map = t
      skinnedMesh.material.needsUpdate = true
        mixer = new THREE.AnimationMixer(object.scene)
        const act = mixer.clipAction(
          object.animations[2]
        )
        act.play()
    })
	})

and then in your animation loop, check that mixer exists / is ready.

function animate() {
	requestAnimationFrame(animate);
  if (mixer) {
  	mixer.update(clock.getDelta())
  }
	renderer.render(scene, camera);
}

Hello @notchris
this indeed works
but I was wondering if theres a way to take out object.animations outside the gltf.load function, so that I can call this
const act = mixer.clipAction(
object.animations[2]
)
act.play()

outside the gltf.load(…) function

Sure! Declare the act variable outside of your load function and then set the variable value inside of the load function. Then you can check: if (act) { act.play() } . For information on variable scopes in js: Scope - MDN Web Docs Glossary: Definitions of Web-related terms | MDN