sheep – Mocap
I started by thinking of the bird being involved in some sort of game, but this did not work out. I was also thinking about making a flock of birds but eventually was inspired by games like Desert Bus, where the only thing that happens is the quiet of the desert. I was also going to make the shaders appear more nicely on the 3D models but eventually was pretty happy with the seemingly 2D look of it. The sketch was, in fact, made with three.js. It was my first time ever using the library, and I learned a lot. The background changes, flapping your arms makes your avatar, a bird, fly higher, and the sun rotates around day by day. I’m excited about learning more about threejs in the future. I think I would work more on adding subtle details, like tiny rotations when wings flap, or the length of the cones to be a little more even. I would also add some sounds.
<!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - arraycamera</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <style> body { margin: 0px; background-color: #000000; overflow: hidden; } </style> </head> <body> <script src="../build/three.js"></script> <script src="js/controls/OrbitControls.js"></script> <script src="js/loaders/BVHLoader.js"></script> <script> //credit to patrik huebner for describing how to bind things to the model: https://stackoverflow.com/questions/42811628/three-js-dynamic-skeleton-animation-with-bvh-and-json-model-not-baked //credit to golan levin for supplying the kinect and claire for the recording var clock = new THREE.Clock(); var camera, scene, renderer,controls; var cone; var mixer; var mixerL; var mesh; var myPos; var plane; var sun; var sphere; var feathers = []; var skeletonHelper; var random1 = 0; var numb = 0; var numbX1 = 0; var numbX2 = 0; var prevRightPosition = 0; var prevLeftPosition = 0; init(); animate(); function init() { var clock = new THREE.Clock(); var AMOUNT = 6; var list= []; var loader = new THREE.BVHLoader(); var SIZE = 1 / AMOUNT; var ASPECT_RATIO = window.innerWidth / window.innerHeight; loader.load("models/bvh/flap01_03_2018_20_08_09_body1.bvh", function( result ) { skeletonHelper = new THREE.SkeletonHelper( result.skeleton.bones[ 0 ] ); skeletonHelper.skeleton = result.skeleton; // allow animation mixer to bind to SkeletonHelper directly var boneContainer = new THREE.Group(); boneContainer.add( result.skeleton.bones[ 0 ] ); scene.add( boneContainer ); mixer = new THREE.AnimationMixer( skeletonHelper ); scene.add(skeletonHelper); // play animation mixer.clipAction( result.clip ).setEffectiveWeight( 1.0 ).play(); }); /* var subcamera = new THREE.PerspectiveCamera( 40, ASPECT_RATIO, 0.1, 10 ); subcamera.bounds = new THREE.Vector4( 1 / AMOUNT, y / AMOUNT, SIZE, SIZE ); subcamera.position.x = ( 1 / AMOUNT ) - 0.5; subcamera.position.y = 0.5 - ( y / AMOUNT ); subcamera.position.z = 1.5; subcamera.position.multiplyScalar( 2 ); subcamera.lookAt( new THREE.Vector3() ); subcamera.updateMatrixWorld(); cameras.push( subcamera ); */ camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000); camera.position.set(0,0,300); controls = new THREE.OrbitControls( camera ); controls.minDistance = 300; controls.maxDistance = 700; scene = new THREE.Scene(); var geometry = new THREE.SphereGeometry( 5, 32, 32 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); sphere = new THREE.Mesh( geometry, material ); scene.add( sphere ); var geometry = new THREE.SphereGeometry( 100, 100, 100 ); var material = new THREE.MeshBasicMaterial( {color: 0xffff00} ); sun = new THREE.Mesh( geometry, material ); scene.add( sun ); var geometry = new THREE.PlaneGeometry(10000,10000,10002); var material = new THREE.MeshBasicMaterial({color: 0xffff00, side: THREE.DoubleSide}); plane = new THREE.Mesh(geometry, material); plane.rotation.x = THREE.Math.degToRad(90); plane.lights = true; scene.add(plane); scene.add( new THREE.AmbientLight( 0x222244 ) ); var light = new THREE.DirectionalLight(); light.position.set( 0.5, 0.5, 1 ); light.castShadow = true; light.shadow.camera.zoom = 4; // tighter shadow map scene.add( light ); var geometry = new THREE.ConeGeometry( 5, 50, 32 ); var material = new THREE.MeshBasicMaterial( {color: 'rgb(255,165,0)'} ); cone = new THREE.Mesh( geometry, material ); cone.rotation.x = THREE.Math.degToRad(90); for (var b = 0; b < 42; b ++){ var geometry = new THREE.ConeGeometry( 25, 20+3*b, 32 ); var material = new THREE.MeshBasicMaterial( {color: 'rgb(29,45,92)'} ); feathers.push(new THREE.Mesh(geometry,material)); if ((b!=0 || b != 9) && b <11 ){ feathers[b].material.visible = false; } feathers[b].rotation.x = THREE.Math.degToRad(270); scene.add(feathers[b]); } scene.add( cone ); renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.shadowMap.enabled = true; document.body.appendChild( renderer.domElement ); // window.addEventListener( 'resize', onWindowResize, false ); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function animate() { var delta = clock.getDelta(); if (mixer) mixer.update(delta); if ( skeletonHelper) { skeletonHelper.material.visible = false; skeletonHelper.root.position.y +=numb; skeletonHelper.root.position.x +=numbX1 + numbX2; //console.log(skeletonHelper.root.position.x); camera.position.z = 500*Math.cos(numb/100) + skeletonHelper.root.position.z; camera.position.x = 500*Math.sin(numb/100) + skeletonHelper.root.position.x; camera.position.y = skeletonHelper.root.position.y+400; //cone.bind(skeletonHelper.bones[60]); numbX1 = 0; numbX2 = 0; controls = new THREE.OrbitControls( camera ); controls.minDistance = 300; controls.maxDistance = 700; camera.lookAt(skeletonHelper.root.position.x,skeletonHelper.root.position.y,skeletonHelper.root.position.z); for (var y = 0; y < skeletonHelper.bones.length; y++){ skeletonHelper.bones[y].castShadow = true; } for (var a = 0; a < feathers.length; a++){ myPos=skeletonHelper.bones[a].getWorldPosition(); feathers[a].position.y = myPos.y; feathers[a].position.z = myPos.z-a; feathers[a].position.x = myPos.x; } myPos = skeletonHelper.bones[60].getWorldPosition(); cone.position.y = myPos.y-1; cone.position.z = myPos.z+30; cone.position.x = myPos.x; myPos = skeletonHelper.bones[60].getWorldPosition(); sphere.position.y = myPos.y; sphere.position.z = myPos.z+30; sphere.position.x = myPos.x; myPos = skeletonHelper.bones[60].getWorldPosition(); sun.position.y = myPos.y+100; sun.position.z = 300; sun.position.x = 300; console.log(sun.position);//lefthand if (skeletonHelper.bones[14].position.y< prevLeftPosition) { numb+=5*(prevLeftPosition - skeletonHelper.bones[14].position.y); numbX1 =5; //numbX+=5*(prevLeftPosition - skeletonHelper.bones[14].position.y); } if (skeletonHelper.bones[38].position.y< prevRightPosition) { numb+=5*(prevRightPosition-skeletonHelper.bones[38].position.y); numbX2 = -5; //numbX-=5*(prevRightPosition-skeletonHelper.bones[38].position.y); } prevLeftPosition = skeletonHelper.bones[14].position.y; prevRightPosition =skeletonHelper.bones[38].position.y; if (numb>0){ numb-=.2; } } renderer.render( scene, camera ); scene.background = new THREE.Color ("rgb("+Math.round(THREE.Math.mapLinear(Math.cos(numb/500),-1,1,0,50))+"%,"+Math.round(THREE.Math.mapLinear(Math.cos(numb/500),-1,1,50,100))+"%,"+Math.round(THREE.Math.mapLinear(Math.cos(numb/500),-1,1,50,200))+"%)"); requestAnimationFrame( animate ); } </script> </body> </html> |