Skip to content

Instantly share code, notes, and snippets.

@haehn
Created November 13, 2019 01:15
Show Gist options
  • Save haehn/be53b912d4beae85f678c963e5b4a3df to your computer and use it in GitHub Desktop.
Save haehn/be53b912d4beae85f678c963e5b4a3df to your computer and use it in GitHub Desktop.
CS460 Assignment 7 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 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>
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