from pyodide import create_proxy, to_js import js import asyncio from js import window from js import Math from js import THREE from js import performance from pyodide import to_js from js import Object from js import fetch from js import requestAnimationFrame import js, pyodide from js import window ''' THREE tutorials https://r105.threejsfundamentals.org/threejs/lessons/threejs-load-obj.html ''' mouse = THREE.Vector2.new(); renderer = THREE.WebGLRenderer.new({"antialias":True}) renderer.setSize(1000, 1000) renderer.shadowMap.enabled = False renderer.shadowMap.type = THREE.PCFSoftShadowMap renderer.shadowMap.needsUpdate = True document.body.appendChild( renderer.domElement ) loaderAnim = document.getElementById('js-loader') def onMouseMove(event): event.preventDefault(); mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; js.document.addEventListener('mousemove', pyodide.create_proxy(onMouseMove)) camera = THREE.PerspectiveCamera.new( 35, window.innerWidth / window.innerHeight, 1, 500 ) scene = THREE.Scene.new() cameraRange = 3 camera.aspect = window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize( window.innerWidth, window.innerHeight ) #setcolor = "#000000" #black setcolor = "0xffffff" #white scene.background = THREE.Color.new(setcolor) scene.fog = THREE.Fog.new(setcolor, 2.5, 3.5); #foggy effect based on distance from camera def mathRandom(num = 1): setNumber = - Math.random() * num + Math.random() * num return setNumber ###################################### # gltf loading using python model_location = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/1376484/stacy_lightweight.glb' texture_location = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/1376484/stacy.jpg' stacy_txt = THREE.TextureLoader.new().load(texture_location); stacy_txt.flipY = False # we flip the texture so that its the right way up perms = {"map":stacy_txt, "color":"0xffffff", "skinning":True} perms = Object.fromEntries(to_js(perms)) stacy_mtl = THREE.MeshPhongMaterial.new(perms) #mixer = None #idle = mixer.clipAction.new() clock = THREE.Clock.new() #mixer = THREE.AnimationMixer.new() #mixer = None mixer = THREE.AnimationMixer.new() idle = None animation_group = THREE.Object3D.new() loadmodel_group = THREE.Object3D.new() mixer_group = THREE.Scene.new() def child_func(c): #print("Mesh !") c.castShadow = True c.receiveShadow = True c.material = stacy_mtl def gltf_func(gltf): #goes inside this function only once global mixer,idle #print("In gltf function ") fileAnimations = gltf.animations #scale the whole model gltf.scene.scale.set(0.5, 0.5, 0.5) #translate the whole model downwards gltf.scene.position.y = -0.5 gltf.scene.traverse(create_proxy(child_func)) scene.add(gltf.scene) #loadmodel_group.add(gltf.scene) #mixer = THREE.AnimationMixer.new()(gltf.scene) #mixer = THREE.AnimationMixer.new()(gltf.scene) #global mixer #I think this below part needs to be somehow ported into the infinite while loop mixer = THREE.AnimationMixer.new()(gltf.scene) #mixer.rootObject = gltf.scene #mixer.add(gltf.scene) idleAnim = THREE.AnimationClip.findByName(fileAnimations, 'idle') idleAnim.tracks.splice(3, 3) idleAnim.tracks.splice(9, 3) idle = mixer.clipAction(idleAnim) idle = mixer.clipAction(gltf.animations[0]) idle.play() loader = THREE.GLTFLoader.new(); loader.load(model_location, create_proxy(gltf_func)) #scene.add(loadmodel_group) #scene.add(person) ###################################### camera.position.set(0, 0, cameraRange); cameraValue = False; ambientLight = THREE.AmbientLight.new(0xFFFFFF, 0.1); light = THREE.SpotLight.new(0xFFFFFF, 3); light.position.set(5, 5, 2); light.castShadow = True; light.shadow.mapSize.width = 10000; light.shadow.mapSize.height = light.shadow.mapSize.width; light.penumbra = 0.5; lightBack = THREE.PointLight.new(0x0FFFFF, 1); lightBack.position.set(0, -3, -1); #scene.add(sceneGruop); scene.add(light); scene.add(lightBack); rectSize = 2 intensity = 100 rectLight = THREE.RectAreaLight.new( 0x0FFFFF, intensity, rectSize, rectSize ) rectLight.position.set( 0, 0, 1 ) rectLight.lookAt( 0, 0, 0 ) scene.add( rectLight ) rectLightHelper = THREE.RectAreaLightHelper.new( rectLight ); raycaster = THREE.Raycaster.new(); uSpeed = 0.1 time = 0.0003; camera.lookAt(scene.position) def update()->None: #requestAnimationFrame(create_proxy(lambda _event: update())) if mixer: mixer.rootObject = scene.children[0] #print("updating !") #print(mixer.time) #the time does update mixer.update(clock.getDelta()) #renderer.render( scene, camera ) #_ = await asyncio.gather(update()) #loop=asyncio.get_event_loop() #loop.run_until_complete(update()) #mixer.rootObject = scene.children[0] #the infinite rendering loop while True: if mixer: #print("mixer is not none") mixer.update(clock.getDelta()) #update() #print("children ",loadmodel_group.children[0], animation_group.children[0]) # mixer = THREE.AnimationMixer(create_proxy(loadmodel_group)) # idleAnim = THREE.AnimationClip.findByName(animation_group.children[0], 'idle') # idleAnim.tracks.splice(3, 3) # idleAnim.tracks.splice(9, 3) # idle = mixer.clipAction(idleAnim) # idle.play() # mixer.update(clock.getDelta()) #scene.traverse(create_proxy(update_scene)) #scene.children[0].updateMatrix() #global mixer #mixer_group.children[0].update(clock.getDelta()) renderer.render( scene, camera ) await asyncio.sleep(0.02)