Skip to content

Instantly share code, notes, and snippets.

@haehn
Last active November 11, 2019 12:31
Show Gist options
  • Save haehn/69dc70aa7ce1071cb7a360daa35b0e78 to your computer and use it in GitHub Desktop.
Save haehn/69dc70aa7ce1071cb7a360daa35b0e78 to your computer and use it in GitHub Desktop.
CS460 Assignment 6 Solution
<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>
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(-30);
scene.add( floor );
r = new Robot(0, -55, 0);
r.show(scene);
controller = {
anaglyph: false
}
var gui = new dat.GUI();
var rendering = gui.addFolder( "Rendering" );
rendering.add( controller, 'anaglyph' );
rendering.open();
var moving = gui.addFolder( "Movement" );
moving.add( r.head.position, "x", -1000, 1000 ).listen();
moving.add( r.head.position, "y", -1000, 1000 ).listen();
moving.add( r.head.position, "z", -1000, 1000 ).listen();
moving.add( r, "raise_left_arm" );
moving.add( r, "lower_left_arm" );
moving.add( r, "kick" );
moving.add( r, "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.head.position.set(intersects[0].point.x,
intersects[0].point.y + 60,
intersects[0].point.z)
}
};
function animate() {
requestAnimationFrame( animate );
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>
</body>
</html>
Robot = function(x, y, z) {
this.head = new THREE.Bone();
this.head.position.set( x, y, z );
this.neck = new THREE.Bone();
this.neck.position.y = -10;
this.head.add(this.neck);
this.torso = new THREE.Bone();
this.torso.position.y = -30;
this.neck.add(this.torso);
this.left_upperarm = new THREE.Bone();
this.left_upperarm.position.y = -5;
this.left_upperarm.position.x = 5;
this.left_lowerarm = new THREE.Bone();
this.left_lowerarm.position.y = -15;
this.left_lowerarm.position.x = 5;
this.left_hand = new THREE.Bone();
this.left_hand.position.x = 5;
this.left_hand.position.y = -5;
this.neck.add(this.left_upperarm);
this.left_upperarm.add(this.left_lowerarm)
this.left_lowerarm.add(this.left_hand);
this.left_upperleg = new THREE.Bone();
this.left_upperleg.position.x = 5;
this.left_upperleg.position.y = -5;
this.left_lowerleg = new THREE.Bone();
this.left_lowerleg.position.x = 5;
this.left_lowerleg.position.y = -15;
this.left_foot = new THREE.Bone();
this.left_foot.position.x = 5;
this.left_foot.position.y = -5;
this.torso.add(this.left_upperleg);
this.left_upperleg.add(this.left_lowerleg)
this.left_lowerleg.add(this.left_foot);
this.right_upperarm = new THREE.Bone();
this.right_upperarm.position.y = -5;
this.right_upperarm.position.x = -5;
this.right_lowerarm = new THREE.Bone();
this.right_lowerarm.position.y = -15;
this.right_lowerarm.position.x = -5;
this.right_hand = new THREE.Bone();
this.right_hand.position.x = -5;
this.right_hand.position.y = -5;
this.neck.add(this.right_upperarm);
this.right_upperarm.add(this.right_lowerarm)
this.right_lowerarm.add(this.right_hand);
this.right_upperleg = new THREE.Bone();
this.right_upperleg.position.x = -5;
this.right_upperleg.position.y = -5;
this.right_lowerleg = new THREE.Bone();
this.right_lowerleg.position.x = -5;
this.right_lowerleg.position.y = -15;
this.right_foot = new THREE.Bone();
this.right_foot.position.x = -5;
this.right_foot.position.y = -5;
this.torso.add(this.right_upperleg);
this.right_upperleg.add(this.right_lowerleg)
this.right_lowerleg.add(this.right_foot);
this.movement = null;
};
Robot.prototype.show = function(scene) {
var rGroup = new THREE.Group();
rGroup.add( this.head );
var helper = new THREE.SkeletonHelper( rGroup );
helper.material.linewidth = 3;
scene.add(rGroup);
scene.add(helper);
};
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.head.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