Created
November 13, 2019 01:15
-
-
Save haehn/be53b912d4beae85f678c963e5b4a3df to your computer and use it in GitHub Desktop.
CS460 Assignment 7 Solution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<meta charset="UTF-8" /> | |
<style> | |
html, body { | |
background-color:#000; | |
margin: 0; | |
padding: 0; | |
height: 100%; | |
overflow: hidden !important; | |
background-image: url(sky.jpg); | |
background-repeat: no-repeat; | |
background-size: 100% 100%; | |
} | |
</style> | |
<script src="https://threejs.org/build/three.min.js" type="text/javascript"></script> | |
<script src="https://threejs.org/examples/js/controls/TrackballControls.js" type="text/javascript"></script> | |
<script src="https://threejs.org/examples/js/effects/AnaglyphEffect.js" type="text/javascript"></script> | |
<script src="https://threejs.org/examples/js/libs/dat.gui.min.js" type="text/javascript"></script> | |
<script src="robot.js" type="text/javascript"></script> | |
<script src="helper.js" type="text/javascript"></script> | |
<script> | |
var scene, camera, renderer, effect, ambientLight, light, controls; | |
var floor; | |
window.onload = function() { | |
scene = new THREE.Scene(); | |
var fov = 60; | |
var ratio = window.innerWidth / window.innerHeight; | |
var zNear = 1; | |
var zFar = 10000; | |
camera = new THREE.PerspectiveCamera(fov, ratio, zNear, zFar); | |
camera.position.set( 0, 0, 500); | |
renderer = new THREE.WebGLRenderer({ alpha: true }); | |
renderer.setSize( window.innerWidth, window.innerHeight ); | |
document.body.appendChild( renderer.domElement ); | |
effect = new THREE.AnaglyphEffect( renderer ); | |
effect.setSize( window.innerWidth, window.innerHeight ); | |
ambientLight = new THREE.AmbientLight(); | |
scene.add( ambientLight ); | |
light = new THREE.DirectionalLight( 0xffffff, 5.0 ); | |
light.position.set( 10, 100, 10 ); | |
scene.add( light ); | |
var floorTexture = new THREE.TextureLoader().load( 'marble.jpg' ); | |
var floorGeometry = new THREE.PlaneBufferGeometry( 1000, 1000 ); | |
var floorMaterial = new THREE.MeshBasicMaterial( { | |
map: floorTexture, | |
side: THREE.DoubleSide | |
} ); | |
floor = new THREE.Mesh( floorGeometry, floorMaterial ); | |
floor.position.y = -100; | |
floor.rotateX(Math.PI/2); | |
scene.add( floor ); | |
all_robots = []; | |
r = new Robot(0, -30, 0); | |
r.show(scene); | |
all_robots.push(r); | |
controller = { | |
anaglyph: false, | |
dance: function() { | |
// start the music | |
var music = document.getElementById('music'); | |
music.autoplay = true; | |
music.load(); | |
var video = document.getElementById('video'); | |
var texture = new THREE.VideoTexture( video ); | |
floor.material.map = texture; | |
video.play(); | |
for (var r in all_robots) { | |
r = all_robots[r]; | |
r.dance(); | |
} | |
} | |
} | |
var gui = new dat.GUI(); | |
var rendering = gui.addFolder( "Rendering" ); | |
rendering.add( controller, 'anaglyph' ); | |
rendering.open(); | |
var moving = gui.addFolder( "Movement" ); | |
moving.add( r.root.position, "x", -1000, 1000 ).listen(); | |
moving.add( r.root.position, "y", -1000, 1000 ).listen(); | |
moving.add( r.root.position, "z", -1000, 1000 ).listen(); | |
moving.add( r, "raise_left_arm" ); | |
moving.add( r, "lower_left_arm" ); | |
moving.add( r, "kick" ); | |
moving.add( controller, "dance" ); | |
moving.open(); | |
controls = new THREE.TrackballControls( camera, renderer.domElement ); | |
animate(); | |
}; | |
window.onclick = function(e) { | |
if (!e.shiftKey) { | |
e.preventDefault(); | |
return false; | |
} | |
pixel_coords = new THREE.Vector2( e.clientX, e.clientY ); | |
vp_coords = new THREE.Vector2( ( pixel_coords.x / window.innerWidth ) * 2 - 1, | |
-( pixel_coords.y / window.innerHeight ) * 2 + 1); | |
vp_coords_near = new THREE.Vector3( vp_coords.x, vp_coords.y, 0); | |
raycaster = new THREE.Raycaster(); | |
raycaster.setFromCamera(vp_coords_near, camera); | |
intersects = raycaster.intersectObject(floor); | |
if (intersects.length > 0) { | |
// r.root.position.set(intersects[0].point.x, | |
// intersects[0].point.y + 70, | |
// intersects[0].point.z) | |
r = new Robot(intersects[0].point.x, | |
intersects[0].point.y + 70, | |
intersects[0].point.z); | |
r.show(scene); | |
all_robots.push(r); | |
} | |
}; | |
function animate() { | |
requestAnimationFrame( animate ); | |
for (r in all_robots) { | |
r = all_robots[r]; | |
r.onAnimate(); | |
} | |
controls.update(); | |
if (controller.anaglyph) { | |
renderer.setClearAlpha(1); | |
effect.render( scene, camera ); | |
} else { | |
renderer.setClearAlpha(0); | |
renderer.render( scene, camera ); | |
} | |
}; | |
</script> | |
</head> | |
<body> | |
<div style="visibility:hidden"> | |
<audio id='music'> | |
<source src="techno.mp3"> | |
</audio> | |
<video id="video" loop crossOrigin="anonymous" webkit-playsinline style="display:none"> | |
<source src="discoball.mp4" type='video/mp4'> | |
</video> | |
</div> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Robot = function(x, y, z) { | |
// create head, neck, and, torso | |
var fromhelper = HELPER.cylinderSkeletonMesh(3, 5, 'blue') | |
var geometry = fromhelper[0]; | |
var material = fromhelper[1]; | |
var bones = fromhelper[2]; | |
var mesh = new THREE.SkinnedMesh( geometry, material ); | |
var skeleton = new THREE.Skeleton( bones ); | |
mesh.add( bones[ 0 ] ); | |
mesh.bind( skeleton ); | |
this.root = bones[ 0 ]; | |
this.root.position.set(x, y, z); | |
this.head = bones[ 1 ]; | |
this.neck = bones[ 2 ]; | |
this.neck.position.y = -10; | |
this.torso = bones[ 3 ]; | |
this.torso.position.y = -30; | |
this.body_mesh = mesh; | |
// create left arm | |
var fromhelper = HELPER.cylinderSkeletonMesh(3, 5, 'blue') | |
var geometry = fromhelper[0]; | |
var material = fromhelper[1]; | |
var bones = fromhelper[2]; | |
var mesh = new THREE.SkinnedMesh( geometry, material ); | |
var skeleton = new THREE.Skeleton( bones ); | |
mesh.add( bones[ 0 ] ); | |
mesh.bind( skeleton ); | |
this.neck.add(bones[ 0 ]); | |
this.left_upperarm = bones[ 1 ]; | |
this.left_upperarm.position.y = -5; | |
this.left_upperarm.position.x = 5; | |
this.left_lowerarm = bones[ 2 ]; | |
this.left_lowerarm.position.y = -15; | |
this.left_lowerarm.position.x = 5; | |
this.left_hand = bones[ 3 ]; | |
this.left_hand.position.x = 5; | |
this.left_hand.position.y = -5; | |
this.leftarm_mesh = mesh; | |
// create right arm | |
var fromhelper = HELPER.cylinderSkeletonMesh(3, 5, 'blue') | |
var geometry = fromhelper[0]; | |
var material = fromhelper[1]; | |
var bones = fromhelper[2]; | |
var mesh = new THREE.SkinnedMesh( geometry, material ); | |
var skeleton = new THREE.Skeleton( bones ); | |
mesh.add( bones[ 0 ] ); | |
mesh.bind( skeleton ); | |
this.neck.add(bones[ 0 ]); | |
this.right_upperarm = bones[ 1 ]; | |
this.right_upperarm.position.y = -5; | |
this.right_upperarm.position.x = -5; | |
this.right_lowerarm = bones[ 2 ]; | |
this.right_lowerarm.position.y = -15; | |
this.right_lowerarm.position.x = -5; | |
this.right_hand = bones[ 3 ]; | |
this.right_hand.position.x = -5; | |
this.right_hand.position.y = -5; | |
this.rightarm_mesh = mesh; | |
// create left leg | |
var fromhelper = HELPER.cylinderSkeletonMesh(3, 5, 'blue') | |
var geometry = fromhelper[0]; | |
var material = fromhelper[1]; | |
var bones = fromhelper[2]; | |
var mesh = new THREE.SkinnedMesh( geometry, material ); | |
var skeleton = new THREE.Skeleton( bones ); | |
mesh.add( bones[ 0 ] ); | |
mesh.bind( skeleton ); | |
this.torso.add(bones[ 0 ]); | |
this.left_upperleg = bones[ 1 ]; | |
this.left_upperleg.position.y = -5; | |
this.left_upperleg.position.x = 5; | |
this.left_lowerleg = bones[ 2 ]; | |
this.left_lowerleg.position.y = -15; | |
this.left_lowerleg.position.x = 5; | |
this.left_foot = bones[ 3 ]; | |
this.left_foot.position.x = 5; | |
this.left_foot.position.y = -5; | |
this.leftleg_mesh = mesh; | |
// create right leg | |
var fromhelper = HELPER.cylinderSkeletonMesh(3, 5, 'blue') | |
var geometry = fromhelper[0]; | |
var material = fromhelper[1]; | |
var bones = fromhelper[2]; | |
var mesh = new THREE.SkinnedMesh( geometry, material ); | |
var skeleton = new THREE.Skeleton( bones ); | |
mesh.add( bones[ 0 ] ); | |
mesh.bind( skeleton ); | |
this.torso.add(bones[ 0 ]); | |
this.right_upperleg = bones[ 1 ]; | |
this.right_upperleg.position.y = -5; | |
this.right_upperleg.position.x = -5; | |
this.right_lowerleg = bones[ 2 ]; | |
this.right_lowerleg.position.y = -15; | |
this.right_lowerleg.position.x = -5; | |
this.right_foot = bones[ 3 ]; | |
this.right_foot.position.x = -5; | |
this.right_foot.position.y = -5; | |
this.rightleg_mesh = mesh; | |
this.movement = null; | |
}; | |
Robot.prototype.show = function(scene) { | |
scene.add(this.body_mesh); | |
scene.add(this.leftarm_mesh); | |
scene.add(this.rightarm_mesh); | |
scene.add(this.leftleg_mesh); | |
scene.add(this.rightleg_mesh); | |
}; | |
Robot.prototype.raise_left_arm = function() { | |
this.movement = 'raise left arm'; | |
}; | |
Robot.prototype.lower_left_arm = function() { | |
this.movement = 'lower left arm'; | |
}; | |
Robot.prototype.kick = function() { | |
this.movement = 'kick'; | |
}; | |
Robot.prototype.dance = function() { | |
this.movement = 'dance'; | |
}; | |
Robot.prototype.onAnimate = function() { | |
if (this.movement == 'raise left arm') { | |
var T = Math.PI; | |
this.left_upperarm.quaternion.slerp( new THREE.Quaternion(Math.sin(-T/2), // w | |
0, // x | |
0, // y | |
Math.cos(-T/2)), // z | |
0.1 ); | |
} else if (this.movement == 'lower left arm') { | |
this.left_upperarm.quaternion.slerp( new THREE.Quaternion(0, 0, 0, 1), | |
0.1 ); | |
} else if (this.movement == 'kick') { | |
// check if slerp reached almost the end | |
if (this.right_upperleg.quaternion.w < 0.72) { | |
// signal that the kick is done and the leg should move back | |
this.movement = 'kick done'; | |
} else { | |
var T = -Math.PI/2; | |
this.right_upperleg.quaternion.slerp( new THREE.Quaternion( Math.sin( T / 2 ), // x | |
0, // y | |
0, // z | |
Math.cos( T / 2 ) ), // w | |
0.1 ); | |
} | |
} else if (this.movement == 'kick done') { | |
// reset leg back to identity | |
this.right_upperleg.quaternion.slerp( new THREE.Quaternion(0,0,0,1), 0.1 ); | |
} else if (this.movement == 'dance') { | |
if (typeof this.dancer === 'undefined') { | |
this.dancer = setInterval(function() { | |
// | |
// some random translation | |
// | |
var shakehead = 3*Math.random(); | |
if (Math.random() < .5) { | |
shakehead *= -1; | |
} | |
var shakeneck = 3*Math.random(); | |
if (Math.random() < .5) { | |
shakeneck *= -1; | |
} | |
var shaketorso = 3*Math.random(); | |
if (Math.random() < .5) { | |
shaketorso *= -1; | |
} | |
this.root.position.x += shakehead; | |
this.neck.position.x += shakeneck; | |
this.torso.position.x += shaketorso; | |
// | |
// use actions | |
// | |
if (Math.random() < .3) { | |
this.raise_left_arm(); | |
} | |
if (Math.random() < .3) { | |
this.lower_left_arm(); | |
} | |
if (Math.random() < .3) { | |
this.kick(); | |
} | |
if (Math.random() < .3) { | |
this.movement = 'kick done'; | |
} | |
}.bind(this), 500); | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment