<!DOCTYPE html>
<html lang="en">
	<head>
		<title>three.js webgl - sea3d / bvh / retarget</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<link type="text/css" rel="stylesheet" href="main.css">
	</head>
	<body>
		<div id="info">
			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - Exported by <a href="https://github.com/sunag/sea3d" target="_blank" rel="noopener">SEA3D Exporter</a>. Asset by <a href="http://www.turbosquid.com/3d-models/soccer-player-max-free/307330" target="_blank" rel="noopener">Trivision</a><br/>
			Runtime retarget of BVH Animation to SEA3D Skeleton
		</div>

		<script type="module">

			import {
				Vector3,
				Color,
				Clock,
				Group,
				Object3D,
				AnimationMixer,
				SkeletonHelper,
				PerspectiveCamera,
				Scene,
				WebGLRenderer
			} from "../build/three.module.js";

			import { OrbitControls } from './jsm/controls/OrbitControls.js';

			import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
			import { RenderPass } from './jsm/postprocessing/RenderPass.js';
			import { ShaderPass } from './jsm/postprocessing/ShaderPass.js';
			import { MaskPass } from './jsm/postprocessing/MaskPass.js';
			import { CopyShader } from './jsm/shaders/CopyShader.js';
			import { ColorCorrectionShader } from './jsm/shaders/ColorCorrectionShader.js';
			import { VignetteShader } from './jsm/shaders/VignetteShader.js';

			import { BVHLoader } from './jsm/loaders/BVHLoader.js';

			import { SEA3D } from './jsm/loaders/sea3d/SEA3DLoader.js';
			import './jsm/loaders/sea3d/SEA3DLZMA.js'; // sea3d lzma extension

			import { SkeletonUtils } from './jsm/utils/SkeletonUtils.js';

			import Stats from './jsm/libs/stats.module.js';

			console.log( "Visit https://github.com/sunag/sea3d to all codes and builds under development." );

			var container, stats;

			var camera, scene, renderer, composer, player, hat;

			var loader, options;

			var bvhSkeletonHelper, bvhMixer;

			// Initialize Three.JS

			init();

			//
			// SEA3D Loader
			//

			loader = new SEA3D( {

				autoPlay: false, // Auto play animations
				container: scene, // Container to add models
				multiplier: .6 // Light multiplier

			} );

			loader.onComplete = function ( ) {

				// Get the first camera from SEA3D Studio
				// use loader.get... to get others objects

				var cam = loader.cameras[ 0 ];
				camera.position.copy( cam.position );
				camera.rotation.copy( cam.rotation );

				new OrbitControls( camera, renderer.domElement );

				// get meshes
				player = loader.getMesh( "Player" );
				hat = loader.getMesh( "Hat" );

				hat.visible = false;

				loadBVH();

				animate();

			};

			loader.load( './models/sea3d/skin.tjs.sea' );

			//

			options = {
				hip: "hip",
				// left is SEA3D bone names and right BVH bone names
				names: {
					"Base HumanPelvis": "hip",
					"Base HumanSpine3": "abdomen",
					"Base HumanRibcage": "chest",
					"Base HumanHead": "head",

					"Base HumanRUpperarm": "rShldr",
					"Base HumanRForearm1": "rForeArm",
					"Base HumanRPalm": "rHand",

					"Base HumanLUpperarm": "lShldr",
					"Base HumanLForearm1": "lForeArm",
					"Base HumanLPalm": "lHand",

					"Base HumanRThigh": "rThigh",
					"Base HumanRCalf1": "rShin",
					"Base HumanRFoot": "rFoot",

					"Base HumanLThigh": "lThigh",
					"Base HumanLCalf1": "lShin",
					"Base HumanLFoot": "lFoot"
				}
			};

			//

			function loadBVH() {

				var loader = new BVHLoader();
				loader.load( "models/bvh/pirouette.bvh", function ( result ) {

					bvhSkeletonHelper = new SkeletonHelper( result.skeleton.bones[ 0 ] );
					bvhSkeletonHelper.skeleton = result.skeleton; // allow animation mixer to bind to SkeletonHelper directly

					var boneContainer = new Group();
					boneContainer.add( result.skeleton.bones[ 0 ] );
					boneContainer.position.z = - 100;
					boneContainer.position.y = - 100;

					scene.add( bvhSkeletonHelper );
					scene.add( boneContainer );

					// get offsets when it is in T-Pose
					options.offsets = SkeletonUtils.getSkeletonOffsets( player, bvhSkeletonHelper, options );

					// play animation
					bvhMixer = new AnimationMixer( bvhSkeletonHelper );
					bvhMixer.clipAction( result.clip ).setEffectiveWeight( 1.0 ).play();

				} );

			}

			function init() {

				scene = new Scene();
				scene.background = new Color( 0x333333 );

				container = document.createElement( 'div' );
				document.body.appendChild( container );

				camera = new PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 20000 );
				camera.position.set( 1000, - 300, 1000 );

				renderer = new WebGLRenderer();
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );
				container.appendChild( renderer.domElement );

				stats = new Stats();
				container.appendChild( stats.dom );

				// post-processing

				composer = new EffectComposer( renderer );

				var renderPass = new RenderPass( scene, camera );
				var copyPass = new ShaderPass( CopyShader );
				composer.addPass( renderPass );

				var vh = 1.4, vl = 1.2;

				var colorCorrectionPass = new ShaderPass( ColorCorrectionShader );
				colorCorrectionPass.uniforms[ "powRGB" ].value = new Vector3( vh, vh, vh );
				colorCorrectionPass.uniforms[ "mulRGB" ].value = new Vector3( vl, vl, vl );
				composer.addPass( colorCorrectionPass );

				var vignettePass = new ShaderPass( VignetteShader );
				vignettePass.uniforms[ "darkness" ].value = 1.0;
				composer.addPass( vignettePass );

				composer.addPass( copyPass );

				// events

				window.addEventListener( 'resize', onWindowResize, false );

			}

			function onWindowResize() {

				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();

				composer.setSize( window.innerWidth, window.innerHeight );
				renderer.setSize( window.innerWidth, window.innerHeight );

			}

			//

			var clock = new Clock();

			function animate() {

				var delta = clock.getDelta();

				requestAnimationFrame( animate );

				// Update SEA3D Animations
				SEA3D.AnimationHandler.update( delta );

				if ( bvhMixer ) {

					bvhMixer.update( delta );

					SkeletonUtils.retarget( player, bvhSkeletonHelper, options );

				}

				render( delta );

				stats.update();

			}

			function render( dlt ) {

				//renderer.render( scene, camera );
				composer.render( dlt );

			}

		</script>

	</body>
</html>
