├── .gitignore ├── CODEOWNERS ├── lib ├── three.js ├── Detector.js ├── stats.min.js ├── tween.min.js ├── sprintf.js └── Coordinates.js ├── media └── img │ └── cs291 │ ├── disc.png │ └── textures │ ├── crate.gif │ ├── maple.png │ ├── water.jpg │ ├── concrete.jpg │ ├── darkam.png │ ├── feather.png │ ├── r_border.png │ ├── checker1x1.png │ ├── checker2x2.png │ ├── checker4x4.png │ ├── checker8x8.png │ ├── lettergrid.png │ ├── skybox │ ├── nx.jpg │ ├── ny.jpg │ ├── nz.jpg │ ├── px.jpg │ ├── py.jpg │ └── pz.jpg │ ├── ash_uvgrid01.jpg │ ├── checker16x16.png │ ├── checker32x32.png │ ├── checker64x64.png │ ├── grass512x512.jpg │ ├── checker128x128.png │ ├── checker256x256.png │ └── checker512x512.png ├── README.md ├── .github └── workflows │ └── manual.yml ├── unit9 ├── two-tone-shading │ └── index.html ├── procedural-texturing │ └── index.html ├── debugging-shaders │ └── index.html ├── sharp-specular │ └── index.html ├── wrap-lighting │ └── index.html ├── model-deformation │ └── index.html ├── vertex-normal-creation │ └── index.html ├── moving-flashlight │ └── index.html └── anisotropic-material │ └── index.html ├── unit3 ├── vertex-attributes.js ├── diffuse-material.js └── smooth-lambert.js ├── transforms.html ├── unit1 └── fix-javascript-errors.js ├── unit8 ├── ps-specular-mapping.js ├── particle-grid.js ├── 05-textured-square.js ├── ps-reflection-mapping.js └── ps-pick-a-letter.js ├── demo ├── unit3-lambert-demo.js ├── unit8-particles.js ├── unit1-render-mode-1.js ├── unit1-render-mode-2.js ├── unit3-diffuse-demo.js ├── unit3-color-demo.js ├── unit3-tessellation-demo.js ├── unit1-render-mode-0.js ├── unit1-fps.js ├── unit3-over_operator.js ├── unit3-blending.js ├── unit2-z-fighting.js ├── unit2-z-fighting_fixed.js ├── unit10-picking.js └── unit4-rotate_then_scale.js ├── unit2 ├── vertex-order.js ├── polygon-creation.js ├── polygon-location.js ├── polygon-radius.js └── triangle-mesh.js ├── unit4 ├── unit4-snowman_exercise.js ├── unit4-flower_exercise.js ├── unit4-rotation_exercise.js ├── unit4-flowersquish_exercise.js ├── unit4-scale_exercise.js └── unit4-clock_exercise.js └── unit5 └── unit5-axis_angle_exercise.js /.gitignore: -------------------------------------------------------------------------------- 1 | # OS X ignores 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @udacity/active-public-content -------------------------------------------------------------------------------- /lib/three.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/lib/three.js -------------------------------------------------------------------------------- /media/img/cs291/disc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/disc.png -------------------------------------------------------------------------------- /media/img/cs291/textures/crate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/crate.gif -------------------------------------------------------------------------------- /media/img/cs291/textures/maple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/maple.png -------------------------------------------------------------------------------- /media/img/cs291/textures/water.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/water.jpg -------------------------------------------------------------------------------- /media/img/cs291/textures/concrete.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/concrete.jpg -------------------------------------------------------------------------------- /media/img/cs291/textures/darkam.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/darkam.png -------------------------------------------------------------------------------- /media/img/cs291/textures/feather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/feather.png -------------------------------------------------------------------------------- /media/img/cs291/textures/r_border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/r_border.png -------------------------------------------------------------------------------- /media/img/cs291/textures/checker1x1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/checker1x1.png -------------------------------------------------------------------------------- /media/img/cs291/textures/checker2x2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/checker2x2.png -------------------------------------------------------------------------------- /media/img/cs291/textures/checker4x4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/checker4x4.png -------------------------------------------------------------------------------- /media/img/cs291/textures/checker8x8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/checker8x8.png -------------------------------------------------------------------------------- /media/img/cs291/textures/lettergrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/lettergrid.png -------------------------------------------------------------------------------- /media/img/cs291/textures/skybox/nx.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/skybox/nx.jpg -------------------------------------------------------------------------------- /media/img/cs291/textures/skybox/ny.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/skybox/ny.jpg -------------------------------------------------------------------------------- /media/img/cs291/textures/skybox/nz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/skybox/nz.jpg -------------------------------------------------------------------------------- /media/img/cs291/textures/skybox/px.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/skybox/px.jpg -------------------------------------------------------------------------------- /media/img/cs291/textures/skybox/py.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/skybox/py.jpg -------------------------------------------------------------------------------- /media/img/cs291/textures/skybox/pz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/skybox/pz.jpg -------------------------------------------------------------------------------- /media/img/cs291/textures/ash_uvgrid01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/ash_uvgrid01.jpg -------------------------------------------------------------------------------- /media/img/cs291/textures/checker16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/checker16x16.png -------------------------------------------------------------------------------- /media/img/cs291/textures/checker32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/checker32x32.png -------------------------------------------------------------------------------- /media/img/cs291/textures/checker64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/checker64x64.png -------------------------------------------------------------------------------- /media/img/cs291/textures/grass512x512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/grass512x512.jpg -------------------------------------------------------------------------------- /media/img/cs291/textures/checker128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/checker128x128.png -------------------------------------------------------------------------------- /media/img/cs291/textures/checker256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/checker256x256.png -------------------------------------------------------------------------------- /media/img/cs291/textures/checker512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/udacity/cs291/HEAD/media/img/cs291/textures/checker512x512.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | cs291 2 | ===== 3 | 4 | Interactive 3D Graphics class code 5 | 6 | Take the class at https://www.udacity.com/course/cs291 7 | 8 | IMPORTANT: to run the demo and exercise code in Units 8-10 locally on your own machine, for Chrome you need to add "--allow-file-access-from-files" to your shortcut to enable the use of textures on your machine. Make sure all Chrome processes in the Task Manager are shut down before restarting Chrome with this option. Note that even rebooting won't assure this - chrome.exe processes will often occur on startup. You have to kill these by hand and then run your shortcut. See http://www.chrome-allow-file-access-from-file.com/ for more details. 9 | 10 | If you work on exercises with textures locally and then submit your work, you'll need to change one more line at the top of the exercise, something like this: 11 | 12 | `var path = "/"; // STUDENT: set to "" to run on your computer, "/" for submitting code to Udacity` 13 | 14 | Do as the comment says. 15 | 16 | ======= 17 | Note: three.js itself is constantly evolving. What we use here is a snapshot of the r56 revision of three.js in lib/three.min.js and lib/three.js. 18 | 19 | You can see the [full migration guide](https://github.com/mrdoob/three.js/wiki/Migration) for all changes from version to version. 20 | 21 | Changes that affect this code base, between the current three.js code, r58, and this repository's, r56: 22 | * renderer.setClearColorHex should be changed to renderer.setClearColor (this is not backwards compatible). 23 | * OrbitAndPanControls.js: use OrbitAndPanControls.new.js for three.js r58 on. 24 | 25 | -------------------------------------------------------------------------------- /.github/workflows/manual.yml: -------------------------------------------------------------------------------- 1 | # Workflow to ensure whenever a Github PR is submitted, 2 | # a JIRA ticket gets created automatically. 3 | name: Manual Workflow 4 | 5 | # Controls when the action will run. 6 | on: 7 | # Triggers the workflow on pull request events but only for the master branch 8 | pull_request_target: 9 | types: [opened, reopened] 10 | 11 | # Allows you to run this workflow manually from the Actions tab 12 | workflow_dispatch: 13 | 14 | jobs: 15 | test-transition-issue: 16 | name: Convert Github Issue to Jira Issue 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@master 21 | 22 | - name: Login 23 | uses: atlassian/gajira-login@master 24 | env: 25 | JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} 26 | JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} 27 | JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} 28 | 29 | - name: Create NEW JIRA ticket 30 | id: create 31 | uses: atlassian/gajira-create@master 32 | with: 33 | project: CONUPDATE 34 | issuetype: Task 35 | summary: | 36 | Github PR [Assign the ND component] | Repo: ${{ github.repository }} | PR# ${{github.event.number}} 37 | description: | 38 | Repo link: https://github.com/${{ github.repository }} 39 | PR no. ${{ github.event.pull_request.number }} 40 | PR title: ${{ github.event.pull_request.title }} 41 | PR description: ${{ github.event.pull_request.description }} 42 | In addition, please resolve other issues, if any. 43 | fields: '{"components": [{"name":"Github PR"}], "customfield_16449":"https://classroom.udacity.com/", "customfield_16450":"Resolve the PR", "labels": ["github"], "priority":{"id": "4"}}' 44 | 45 | - name: Log created issue 46 | run: echo "Issue ${{ steps.create.outputs.issue }} was created" 47 | -------------------------------------------------------------------------------- /lib/Detector.js: -------------------------------------------------------------------------------- 1 | // TODO: This should be replaced with the checking code from http://get.webgl.org 2 | // they have better supprot messages for different browsers 3 | var Detector={ 4 | canvas:!!window.CanvasRenderingContext2D, 5 | webgl:(function(){ 6 | try{ 7 | return!!window.WebGLRenderingContext&&!!document.createElement('canvas').getContext('experimental-webgl'); 8 | } 9 | catch(e){ 10 | return false; 11 | } 12 | })(), 13 | workers:!!window.Worker, 14 | fileapi:window.File&&window.FileReader&&window.FileList&&window.Blob, 15 | getWebGLErrorMessage:function(){ 16 | var element=document.createElement('div'); 17 | element.id='webgl-error-message'; 18 | element.style.fontFamily='monospace';element.style.fontSize='13px'; 19 | element.style.fontWeight='normal'; 20 | element.style.textAlign='center'; 21 | element.style.background='#fff'; 22 | element.style.color='#000'; 23 | element.style.padding='1.5em'; 24 | element.style.width='400px'; 25 | element.style.margin='5em auto 0'; 26 | if(!this.webgl){ 27 | element.innerHTML=window.WebGLRenderingContext?['Your graphics card does not seem to support WebGL.
','Find out how to get it here.'].join('\n'):['Your browser does not seem to support WebGL.
','Find out how to get it here.'].join('\n'); 28 | } 29 | return element; 30 | }, 31 | addGetWebGLMessage:function(parameters){ 32 | var parent,id,element; 33 | parameters=parameters||{}; 34 | parent=parameters.parent!==undefined?parameters.parent:document.body; 35 | id=parameters.id!==undefined?parameters.id:'unsupported'; 36 | element=Detector.getWebGLErrorMessage(); 37 | element.id=id; 38 | document.body.insertBefore(element, document.body.childNodes[0]); 39 | } 40 | }; -------------------------------------------------------------------------------- /unit9/two-tone-shading/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 28 | 55 | 56 | -------------------------------------------------------------------------------- /lib/stats.min.js: -------------------------------------------------------------------------------- 1 | // stats.js - http://github.com/mrdoob/stats.js 2 | var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px"; 3 | i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div"); 4 | k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display= 5 | "block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:11,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height= 6 | a+"px",m=b,r=0);return b},update:function(){l=this.end()}}}; 7 | -------------------------------------------------------------------------------- /unit9/procedural-texturing/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 28 | 57 | 58 | -------------------------------------------------------------------------------- /unit3/vertex-attributes.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | /*global THREE, window, document, $*/ 4 | var camera, scene, renderer; 5 | var cameraControls; 6 | var clock = new THREE.Clock(); 7 | 8 | function fillScene() { 9 | scene = new THREE.Scene(); 10 | 11 | // Triangle Mesh 12 | var material, geometry, mesh; 13 | material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors, side: THREE.DoubleSide } ); 14 | geometry = new THREE.Geometry(); 15 | 16 | // Student: add a colored triangle here 17 | 18 | 19 | mesh = new THREE.Mesh( geometry, material ); 20 | 21 | scene.add( mesh ); 22 | 23 | } 24 | 25 | function init() { 26 | var canvasWidth = 846; 27 | var canvasHeight = 494; 28 | // For grading the window is fixed in size; here's general code: 29 | //var canvasWidth = window.innerWidth; 30 | //var canvasHeight = window.innerHeight; 31 | var canvasRatio = canvasWidth / canvasHeight; 32 | 33 | // RENDERER 34 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 35 | renderer.gammaInput = true; 36 | renderer.gammaOutput = true; 37 | renderer.setSize(canvasWidth, canvasHeight); 38 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 39 | 40 | // CAMERA 41 | camera = new THREE.PerspectiveCamera( 55, canvasRatio, 1, 4000 ); 42 | camera.position.set( 100, 150, 130 ); 43 | 44 | // CONTROLS 45 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 46 | cameraControls.target.set(0,0,0); 47 | 48 | } 49 | 50 | function addToDOM() { 51 | var container = document.getElementById('container'); 52 | var canvas = container.getElementsByTagName('canvas'); 53 | if (canvas.length>0) { 54 | container.removeChild(canvas[0]); 55 | } 56 | container.appendChild( renderer.domElement ); 57 | } 58 | 59 | function animate() { 60 | window.requestAnimationFrame(animate); 61 | render(); 62 | } 63 | 64 | function render() { 65 | var delta = clock.getDelta(); 66 | cameraControls.update(delta); 67 | 68 | renderer.render(scene, camera); 69 | } 70 | 71 | 72 | try { 73 | init(); 74 | fillScene(); 75 | addToDOM(); 76 | animate(); 77 | } catch(e) { 78 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 79 | $('#container').append(errorReport+e); 80 | } 81 | 82 | -------------------------------------------------------------------------------- /transforms.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 50 | 51 | 52 |
Explained a bit here. 53 |
54 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /unit9/debugging-shaders/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 28 | 70 | 71 | -------------------------------------------------------------------------------- /unit9/sharp-specular/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 27 | 78 | 79 | -------------------------------------------------------------------------------- /unit9/wrap-lighting/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 27 | 78 | 79 | -------------------------------------------------------------------------------- /unit1/fix-javascript-errors.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Fixing Incorrect JavaScript exercise 4 | //////////////////////////////////////////////////////////////////////////////// 5 | // Your task is to find the syntax errors in this Javacript 6 | // until it shows the the Gold Cube! 7 | // WebGL is not supported in Internet Explorer 8 | // There are 3 syntax errors in this code 9 | //////////////////////////////////////////////////////////////////////////////// 10 | /*global THREE, Coordinates, $, document, window*/ 11 | 12 | var camera, scene, renderer; 13 | var windowScale; 14 | var cameraControls; 15 | var clock = new THREE.Clock(); 16 | 17 | function drawGoldCube() { 18 | 19 | var cube; 20 | var cubeSizeLength = 100; 21 | var goldColor = "#FFDF00"; 22 | var showFrame = true; 23 | var wireMaterial = new THREE.MeshBasicMaterial( { color: goldColor, wireframe: showFrame } ) ; 24 | 25 | var cubeGeometry = new THREE.CubeGeometry(cubeSizeLength, cubeSizeLength, cubeSizeLength); 26 | 27 | cube = new THREE.Mesh( cubeGeometry, wireMaterial ); 28 | cube.position.x = 0; // centered at origin 29 | cube.position.y = 0; // centered at origin 30 | cube.position.z = 0; // centered at origin 31 | scene.add( cube ; 32 | 33 | } 34 | 35 | function init() { 36 | var canvasWidth = 846; 37 | var canvasHeight = 494; 38 | // For grading the window is fixed in size; here's general code: 39 | //var canvasWidth = window.innerWidth; 40 | //var canvasHeight = window.innerHeight; 41 | var canvasRatio = canvasWidth / canvasHeight; 42 | // SCENE 43 | scene = new THREE.Scene(); 44 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 45 | // LIGHTS 46 | scene.add( new THREE.AmbientLight( 0x222222 ) ); 47 | 48 | // RENDERER 49 | 50 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 51 | renderer.gammaInput = true; 52 | renderer.gammaOutput = true; 53 | renderer.setSize(canvasWidth, canvasHeight); 54 | renderer.setClearColor( scene.fog.color, 1 ); 55 | 56 | var container = document.getElementById('container'); 57 | container.appendChild( renderer.domElement ); 58 | 59 | 60 | // CAMERA 61 | camera = new THREE.PerspectiveCamera( 45, canvasRatio, 1, 4000 ); 62 | camera.position.set( -200, 200, -150 ); 63 | // CONTROLS 64 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 65 | cameraControls.target.set(0,0,0); 66 | 67 | / draw the coordinate grid 68 | Coordinates.drawGrid({size:1000,scale:0.01}); 69 | Coordinates.drawGrid(size:1000,scale:0.01, orientation:"y"}); 70 | Coordinates.drawGrid({size:1000,scale:0.01, orientation:"z"}); 71 | } 72 | 73 | function animate() { 74 | requestAnimationFrame(animate); 75 | render(); 76 | } 77 | 78 | function render() { 79 | var delta = clock.getDelta(); 80 | cameraControls.update(delta); 81 | renderer.render(scene, camera); 82 | } 83 | 84 | init(); 85 | drawGoldCube(); 86 | animate(); 87 | -------------------------------------------------------------------------------- /unit9/model-deformation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 31 | 78 | 79 | -------------------------------------------------------------------------------- /unit9/vertex-normal-creation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 31 | 78 | 79 | -------------------------------------------------------------------------------- /unit8/ps-specular-mapping.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Add a specular texture 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, requestAnimationFrame, $ */ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls; 9 | var clock = new THREE.Clock(); 10 | var teapotSize = 400; 11 | 12 | function createMaterial() { 13 | // MATERIALS 14 | // Student: use the texture '/media/img/cs291/textures/water.jpg' 15 | var material = new THREE.MeshPhongMaterial( { shininess: 50 } ); 16 | material.color.setHSL( 0.09, 0.46, 0.2 ); 17 | material.ambient.copy( material.color ); 18 | material.specular.setHSL( 0.09, 0.46, 1.0 ); 19 | 20 | return material; 21 | } 22 | 23 | function fillScene() { 24 | scene = new THREE.Scene(); 25 | // LIGHTS 26 | scene.add( new THREE.AmbientLight( 0x333333 ) ); 27 | var light = new THREE.DirectionalLight( 0xFFFFFF, 0.9 ); 28 | light.position.set( 200, 300, 500 ); 29 | scene.add( light ); 30 | light = new THREE.DirectionalLight( 0xFFFFFF, 0.7 ); 31 | light.position.set( -200, -100, -400 ); 32 | scene.add( light ); 33 | 34 | var material = createMaterial(); 35 | var teapot = new THREE.Mesh( 36 | new THREE.TeapotGeometry( teapotSize, 37 | 8, true, true, true, true, true ), 38 | material ); 39 | 40 | scene.add( teapot ); 41 | } 42 | 43 | function init() { 44 | var canvasWidth = 846; 45 | var canvasHeight = 494; 46 | // For grading the window is fixed in size; here's general code: 47 | //var canvasWidth = window.innerWidth; 48 | //var canvasHeight = window.innerHeight; 49 | 50 | // CAMERA 51 | 52 | camera = new THREE.PerspectiveCamera( 45, canvasWidth/ canvasHeight, 100, 20000 ); 53 | camera.position.set( -222, 494, 1746 ); 54 | 55 | // RENDERER 56 | 57 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 58 | renderer.setSize( canvasWidth, canvasHeight ); 59 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 60 | renderer.gammaInput = true; 61 | renderer.gammaOutput = true; 62 | 63 | // CONTROLS 64 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 65 | cameraControls.target.set(0, -160, 0); 66 | 67 | } 68 | 69 | function addToDOM() { 70 | var container = document.getElementById('container'); 71 | var canvas = container.getElementsByTagName('canvas'); 72 | if (canvas.length>0) { 73 | container.removeChild(canvas[0]); 74 | } 75 | container.appendChild( renderer.domElement ); 76 | } 77 | 78 | function animate() { 79 | 80 | requestAnimationFrame( animate ); 81 | render(); 82 | 83 | } 84 | 85 | function render() { 86 | var delta = clock.getDelta(); 87 | cameraControls.update( delta ); 88 | 89 | renderer.render( scene, camera ); 90 | } 91 | 92 | 93 | try { 94 | init(); 95 | fillScene(); 96 | addToDOM(); 97 | animate(); 98 | } catch(e) { 99 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 100 | $('#container').append(errorReport+e); 101 | } 102 | -------------------------------------------------------------------------------- /unit9/moving-flashlight/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 26 | 85 | 86 | -------------------------------------------------------------------------------- /unit3/diffuse-material.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Diffuse material exercise 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, window, document, $*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls; 9 | var clock = new THREE.Clock(); 10 | var ambientLight, light; 11 | 12 | function init() { 13 | var canvasWidth = 846; 14 | var canvasHeight = 494; 15 | // For grading the window is fixed in size; here's general code: 16 | //var canvasWidth = window.innerWidth; 17 | //var canvasHeight = window.innerHeight; 18 | var canvasRatio = canvasWidth / canvasHeight; 19 | 20 | // CAMERA 21 | 22 | camera = new THREE.PerspectiveCamera( 45, canvasRatio, 1, 80000 ); 23 | camera.position.set( -300, 300, -1000 ); 24 | camera.lookAt(0,0,0); 25 | // LIGHTS 26 | 27 | ambientLight = new THREE.AmbientLight( 0xFFFFFF ); 28 | 29 | light = new THREE.DirectionalLight( 0xFFFFFF, 0.7 ); 30 | light.position.set( -800, 900, 300 ); 31 | 32 | // RENDERER 33 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 34 | renderer.setSize( canvasWidth, canvasHeight ); 35 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 36 | 37 | renderer.gammaInput = true; 38 | renderer.gammaOutput = true; 39 | 40 | // CONTROLS 41 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 42 | cameraControls.target.set(0, 0, 0); 43 | 44 | } 45 | 46 | function createBall() { 47 | // Do not change the color itself, change the material and use the ambient and diffuse components. 48 | var material = new THREE.MeshBasicMaterial( { color: 0x80FC66, shading: THREE.FlatShading } ); 49 | var sphere = new THREE.Mesh( new THREE.SphereGeometry( 400, 64, 32 ), material ); 50 | return sphere; 51 | } 52 | 53 | function fillScene() { 54 | scene = new THREE.Scene(); 55 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 56 | 57 | // LIGHTS 58 | scene.add( ambientLight ); 59 | scene.add( light ); 60 | 61 | var ball = createBall(); 62 | scene.add( ball ); 63 | 64 | //Coordinates.drawGround({size:1000}); 65 | //Coordinates.drawGrid({size:1000,scale:0.01}); 66 | //Coordinates.drawAllAxes({axisLength:500,axisRadius:1,axisTess:4}); 67 | } 68 | 69 | function addToDOM() { 70 | var container = document.getElementById('container'); 71 | var canvas = container.getElementsByTagName('canvas'); 72 | if (canvas.length>0) { 73 | container.removeChild(canvas[0]); 74 | } 75 | container.appendChild( renderer.domElement ); 76 | } 77 | 78 | function animate() { 79 | window.requestAnimationFrame( animate ); 80 | render(); 81 | } 82 | 83 | function render() { 84 | var delta = clock.getDelta(); 85 | cameraControls.update(delta); 86 | 87 | renderer.render( scene, camera ); 88 | 89 | } 90 | 91 | try { 92 | init(); 93 | fillScene(); 94 | addToDOM(); 95 | animate(); 96 | } catch(e) { 97 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 98 | $('#container').append(errorReport+e); 99 | } 100 | -------------------------------------------------------------------------------- /demo/unit3-lambert-demo.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | /*global THREE, requestAnimationFrame, document, window, dat*/ 3 | var camera, scene, renderer; 4 | 5 | var cameraControls; 6 | 7 | var effectController; 8 | 9 | var clock = new THREE.Clock(); 10 | 11 | var ambientLight, light; 12 | var sphere, material; 13 | 14 | init(); 15 | animate(); 16 | 17 | function init() { 18 | 19 | // CAMERA 20 | 21 | camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 80000 ); 22 | camera.position.set( -1000, 450, -1300 ); 23 | 24 | // SCENE 25 | 26 | scene = new THREE.Scene(); 27 | 28 | scene.add( camera ); 29 | 30 | // LIGHTS 31 | 32 | ambientLight = new THREE.AmbientLight( 0xffffff ); 33 | scene.add( ambientLight ); 34 | 35 | light = new THREE.DirectionalLight( 0xffffff, 1.0 ); 36 | light.position.set( -620, 390, 100 ); 37 | 38 | scene.add( light ); 39 | 40 | // RENDERER 41 | 42 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 43 | renderer.setSize( window.innerWidth, window.innerHeight ); 44 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 45 | 46 | 47 | var container = document.getElementById('container'); 48 | container.appendChild( renderer.domElement ); 49 | 50 | renderer.gammaInput = true; 51 | renderer.gammaOutput = true; 52 | 53 | // CONTROLS 54 | 55 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 56 | cameraControls.target.set(0, 0, 0); 57 | 58 | // MATERIAL 59 | material = new THREE.MeshLambertMaterial( { color: 0x80fc66 } ); 60 | var ka = 0.4; 61 | material.ambient.setRGB( material.color.r * ka, material.color.g * ka, material.color.b * ka ); 62 | 63 | sphere = new THREE.Mesh( 64 | new THREE.SphereGeometry( 400, 64, 32 ), material ); 65 | 66 | scene.add( sphere ); 67 | 68 | // GUI 69 | 70 | setupGui(); 71 | } 72 | 73 | function setupGui() { 74 | 75 | effectController = { 76 | 77 | Ka: 0.3, 78 | Kd: 0.7, 79 | 80 | Hue: 0.09, 81 | Saturation: 0.46, 82 | Lightness: 1.0 83 | 84 | }; 85 | 86 | var gui = new dat.GUI(); 87 | 88 | // material (color) 89 | 90 | gui.add( effectController, "Hue", 0.0, 1.0 ); 91 | gui.add( effectController, "Saturation", 0.0, 1.0 ); 92 | gui.add( effectController, "Lightness", 0.0, 1.0 ); 93 | 94 | // material (attributes) 95 | 96 | gui.add( effectController, "Ka", 0.0, 1.0 ); 97 | gui.add( effectController, "Kd", 0.0, 1.0 ); 98 | 99 | } 100 | 101 | // 102 | 103 | function animate() { 104 | 105 | requestAnimationFrame( animate ); 106 | render(); 107 | 108 | } 109 | 110 | function render() { 111 | 112 | var delta = clock.getDelta(); 113 | 114 | cameraControls.update( delta ); 115 | 116 | var materialColor = new THREE.Color(); 117 | materialColor.setHSL( effectController.Hue, effectController.Saturation, effectController.Lightness * effectController.Kd ); 118 | material.color.copy( materialColor ); 119 | materialColor.setHSL( effectController.Hue, effectController.Saturation, effectController.Lightness * effectController.Ka ); 120 | material.ambient.copy( materialColor ); 121 | 122 | renderer.render( scene, camera ); 123 | 124 | } 125 | -------------------------------------------------------------------------------- /unit9/anisotropic-material/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 30 | 89 | 90 | -------------------------------------------------------------------------------- /unit3/smooth-lambert.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Smooth shading exercise: change program to make sphere look smooth 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, window, document, $*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls; 9 | var clock = new THREE.Clock(); 10 | var ambientLight, light; 11 | 12 | function init() { 13 | var canvasWidth = 846; 14 | var canvasHeight = 494; 15 | // For grading the window is fixed in size; here's general code: 16 | //var canvasWidth = window.innerWidth; 17 | //var canvasHeight = window.innerHeight; 18 | var canvasRatio = canvasWidth / canvasHeight; 19 | 20 | // CAMERA 21 | 22 | camera = new THREE.PerspectiveCamera( 45, canvasRatio, 1, 80000 ); 23 | camera.position.set( -300, 300, -1000 ); 24 | camera.lookAt(0,0,0); 25 | // LIGHTS 26 | 27 | ambientLight = new THREE.AmbientLight( 0xFFFFFF ); 28 | 29 | light = new THREE.DirectionalLight( 0xFFFFFF, 0.7 ); 30 | light.position.set( -800, 900, 300 ); 31 | 32 | // RENDERER 33 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 34 | renderer.setSize( canvasWidth, canvasHeight ); 35 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 36 | 37 | var container = document.getElementById('container'); 38 | container.appendChild( renderer.domElement ); 39 | 40 | renderer.gammaInput = true; 41 | renderer.gammaOutput = true; 42 | 43 | // CONTROLS 44 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 45 | cameraControls.target.set(0, 0, 0); 46 | 47 | } 48 | 49 | function createBall() { 50 | var material = new THREE.MeshLambertMaterial( { color: 0x80FC66, shading: THREE.FlatShading } ); 51 | var ka = 0.4; 52 | material.ambient.setRGB( material.color.r * ka, material.color.g * ka, material.color.b * ka ); 53 | var sphere = new THREE.Mesh( 54 | new THREE.SphereGeometry( 400, 64, 32 ), material ); 55 | return sphere; 56 | } 57 | 58 | function fillScene() { 59 | scene = new THREE.Scene(); 60 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 61 | 62 | // LIGHTS 63 | scene.add( ambientLight ); 64 | scene.add( light ); 65 | 66 | var ball = createBall(); 67 | scene.add( ball ); 68 | 69 | //Coordinates.drawGround({size:1000}); 70 | //Coordinates.drawGrid({size:1000,scale:0.01}); 71 | //Coordinates.drawAllAxes({axisLength:500,axisRadius:1,axisTess:4}); 72 | } 73 | 74 | function addToDOM() { 75 | var container = document.getElementById('container'); 76 | var canvas = container.getElementsByTagName('canvas'); 77 | if (canvas.length>0) { 78 | container.removeChild(canvas[0]); 79 | } 80 | container.appendChild( renderer.domElement ); 81 | } 82 | 83 | function animate() { 84 | 85 | window.requestAnimationFrame( animate ); 86 | render(); 87 | 88 | } 89 | 90 | function render() { 91 | var delta = clock.getDelta(); 92 | cameraControls.update(delta); 93 | 94 | renderer.render( scene, camera ); 95 | 96 | } 97 | 98 | try { 99 | init(); 100 | fillScene(); 101 | addToDOM(); 102 | animate(); 103 | } catch(e) { 104 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 105 | $('#container').append(errorReport+e); 106 | } 107 | -------------------------------------------------------------------------------- /demo/unit8-particles.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Particle System 4 | //////////////////////////////////////////////////////////////////////////////// 5 | 6 | /*global THREE, Stats */ 7 | 8 | //if ( ! Detector.webgl ) Detector.addGetWebGLMessage(); 9 | 10 | var path = ""; // STUDENT: set to "" to run on your computer, "/" for submitting code to Udacity 11 | 12 | var camera, scene, renderer, stats; 13 | var cameraControls; 14 | 15 | var clock = new THREE.Clock(); 16 | 17 | function init() { 18 | var canvasWidth = window.innerWidth; 19 | var canvasHeight = window.innerHeight; 20 | var canvasRatio = canvasWidth / canvasHeight; 21 | 22 | // RENDERER 23 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 24 | //renderer = new THREE.WebGLRenderer( { clearAlpha: 1 } ); 25 | renderer.gammaInput = true; 26 | renderer.gammaOutput = true; 27 | renderer.setSize(canvasWidth, canvasHeight); 28 | renderer.setClearColorHex( 0x0, 1.0 ); 29 | 30 | var container = document.getElementById('container'); 31 | container.appendChild( renderer.domElement ); 32 | 33 | renderer.gammaInput = true; 34 | renderer.gammaOutput = true; 35 | 36 | // STATS 37 | 38 | stats = new Stats(); 39 | stats.setMode( 0 ); 40 | stats.domElement.style.position = 'absolute'; 41 | stats.domElement.style.top = '0px'; 42 | stats.domElement.style.zIndex = 100; 43 | container.appendChild( stats.domElement ); 44 | 45 | stats.domElement.children[ 0 ].children[ 0 ].style.color = "#aaa"; 46 | stats.domElement.children[ 0 ].style.background = "transparent"; 47 | stats.domElement.children[ 0 ].children[ 1 ].style.display = "none"; 48 | 49 | // CAMERA 50 | camera = new THREE.PerspectiveCamera( 55, canvasRatio, 2, 8000 ); 51 | camera.position.set( 10, 5, 15 ); 52 | 53 | // CONTROLS 54 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 55 | cameraControls.target.set(0,0,0); 56 | 57 | fillScene(); 58 | } 59 | 60 | function fillScene() { 61 | scene = new THREE.Scene(); 62 | //scene.fog = new THREE.FogExp2( 0x000000, 0.0004 ); 63 | 64 | var geometry = new THREE.Geometry(); 65 | 66 | for ( var i = 0; i < 8000; i ++ ) { 67 | 68 | var vertex = new THREE.Vector3(); 69 | // accept the point only if it's in the sphere 70 | do { 71 | vertex.x = 2000 * Math.random() - 1000; 72 | vertex.y = 2000 * Math.random() - 1000; 73 | vertex.z = 2000 * Math.random() - 1000; 74 | } while ( vertex.length() > 1000 ); 75 | 76 | geometry.vertices.push( vertex ); 77 | 78 | } 79 | 80 | var disk = THREE.ImageUtils.loadTexture( path + 'media/img/cs291/disc.png' ); 81 | var material = new THREE.ParticleBasicMaterial( 82 | { size: 35, sizeAttenuation: false, map: disk, transparent: true } ); 83 | material.color.setHSL( 0.9, 0.2, 0.6 ); 84 | 85 | var particles = new THREE.ParticleSystem( geometry, material ); 86 | particles.sortParticles = true; 87 | scene.add( particles ); 88 | } 89 | 90 | function animate() { 91 | window.requestAnimationFrame(animate); 92 | render(); 93 | } 94 | 95 | function render() { 96 | var delta = clock.getDelta(); 97 | cameraControls.update(delta); 98 | 99 | renderer.render(scene, camera); 100 | stats.update(); 101 | } 102 | 103 | init(); 104 | animate(); 105 | -------------------------------------------------------------------------------- /unit2/vertex-order.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Vertex Order Exercise 4 | // Your task is to determine the problem and fix the vertex drawing order. 5 | // Check the function someObject() 6 | // and correct the code that starts at line 17. 7 | //////////////////////////////////////////////////////////////////////////////// 8 | /*global THREE, Coordinates, $, document*/ 9 | 10 | var camera, scene, renderer; 11 | var windowScale; 12 | 13 | function someObject(material) { 14 | var geometry = new THREE.Geometry(); 15 | 16 | // Student: some data below must be fixed 17 | // for both triangles to appear ! 18 | geometry.vertices.push( new THREE.Vector3( 3, 3, 0 ) ); 19 | geometry.vertices.push( new THREE.Vector3( 7, 3, 0 ) ); 20 | geometry.vertices.push( new THREE.Vector3( 7, 7, 0 ) ); 21 | geometry.vertices.push( new THREE.Vector3( 3, 7, 0 ) ); 22 | 23 | geometry.faces.push( new THREE.Face3( 0, 1, 2 ) ); 24 | geometry.faces.push( new THREE.Face3( 2, 0, 3 ) ); 25 | 26 | var mesh = new THREE.Mesh( geometry, material ); 27 | 28 | scene.add( mesh ); 29 | } 30 | 31 | function init() { 32 | // Setting up some parameters 33 | var canvasWidth = 846; 34 | var canvasHeight = 494; 35 | // For grading the window is fixed in size; here's general code: 36 | //var canvasWidth = window.innerWidth; 37 | //var canvasHeight = window.innerHeight; 38 | var canvasRatio = canvasWidth / canvasHeight; 39 | // scene 40 | scene = new THREE.Scene(); 41 | 42 | // Camera: Y up, X right, Z up 43 | windowScale = 10; 44 | var windowWidth = windowScale * canvasRatio; 45 | var windowHeight = windowScale; 46 | 47 | camera = new THREE.OrthographicCamera( windowWidth / - 2, windowWidth / 2, 48 | windowHeight / 2, windowHeight / - 2, 0, 40 ); 49 | 50 | var focus = new THREE.Vector3( 5,4,0 ); 51 | camera.position.x = focus.x; 52 | camera.position.y = focus.y; 53 | camera.position.z = 10; 54 | camera.lookAt( focus ); 55 | 56 | renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true}); 57 | renderer.gammaInput = true; 58 | renderer.gammaOutput = true; 59 | renderer.setSize( canvasWidth, canvasHeight ); 60 | renderer.setClearColorHex( 0xFFFFFF, 1.0 ); 61 | 62 | } 63 | 64 | function addToDOM() { 65 | var container = document.getElementById('container'); 66 | var canvas = container.getElementsByTagName('canvas'); 67 | if (canvas.length>0) { 68 | container.removeChild(canvas[0]); 69 | } 70 | container.appendChild( renderer.domElement ); 71 | } 72 | 73 | function showGrids() { 74 | // Background grid and axes. Grid step size is 1, axes cross at 0, 0 75 | Coordinates.drawGrid({size:100,scale:1,orientation:"z"}); 76 | Coordinates.drawAxes({axisLength:11,axisOrientation:"x",axisRadius:0.04}); 77 | Coordinates.drawAxes({axisLength:11,axisOrientation:"y",axisRadius:0.04}); 78 | } 79 | 80 | function render() { 81 | renderer.render( scene, camera ); 82 | } 83 | 84 | 85 | // Main body of the script 86 | try { 87 | init(); 88 | showGrids(); 89 | var material = new THREE.MeshBasicMaterial( { color: 0xF6831E, side: THREE.FrontSide } ); 90 | someObject(material); 91 | addToDOM(); 92 | render(); 93 | } catch(e) { 94 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 95 | $('#container').append(errorReport+e); 96 | } 97 | -------------------------------------------------------------------------------- /unit8/particle-grid.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Particle System 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, document, window, $*/ 6 | 7 | var path = ""; // STUDENT: set to "" to run on your computer, "/" for submitting code to Udacity 8 | 9 | var camera, scene, renderer; 10 | var cameraControls; 11 | 12 | var clock = new THREE.Clock(); 13 | 14 | function fillScene() { 15 | scene = new THREE.Scene(); 16 | 17 | var geometry = new THREE.Geometry(); 18 | 19 | // Student: rewrite the following vertex generation code so that 20 | // vertices are generated every 100 units: 21 | // -1000,-1000,-1000 to 1000,1000,1000, e.g. 22 | // at -1000,-1000,-1000, -900,-1000,-1000, 23 | // and so on, for the 21*21*21 = 9261 points. 24 | 25 | for ( var i = 0; i < 8000; i ++ ) { 26 | 27 | var vertex = new THREE.Vector3(); 28 | // accept the point only if it's in the sphere 29 | do { 30 | vertex.x = 2000 * Math.random() - 1000; 31 | vertex.y = 2000 * Math.random() - 1000; 32 | vertex.z = 2000 * Math.random() - 1000; 33 | } while ( vertex.length() > 1000 ); 34 | 35 | geometry.vertices.push( vertex ); 36 | 37 | } 38 | 39 | var disk = THREE.ImageUtils.loadTexture( path + 'media/img/cs291/disc.png' ); 40 | var material = new THREE.ParticleBasicMaterial( 41 | { size: 35, sizeAttenuation: false, map: disk, transparent: true } ); 42 | material.color.setHSL( 0.9, 0.2, 0.6 ); 43 | 44 | var particles = new THREE.ParticleSystem( geometry, material ); 45 | particles.sortParticles = true; 46 | scene.add( particles ); 47 | } 48 | 49 | function init() { 50 | var canvasWidth = 846; 51 | var canvasHeight = 494; 52 | // For grading the window is fixed in size; here's general code: 53 | //var canvasWidth = window.innerWidth; 54 | //var canvasHeight = window.innerHeight; 55 | var canvasRatio = canvasWidth / canvasHeight; 56 | 57 | // RENDERER 58 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 59 | renderer = new THREE.WebGLRenderer( { clearAlpha: 1 } ); 60 | renderer.gammaInput = true; 61 | renderer.gammaOutput = true; 62 | renderer.setSize(canvasWidth, canvasHeight); 63 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 64 | 65 | // CAMERA 66 | camera = new THREE.PerspectiveCamera( 55, canvasRatio, 2, 8000 ); 67 | camera.position.set( 10, 5, 15 ); 68 | // CONTROLS 69 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 70 | cameraControls.target.set(0,0,0); 71 | 72 | } 73 | 74 | function addToDOM() { 75 | var container = document.getElementById('container'); 76 | var canvas = container.getElementsByTagName('canvas'); 77 | if (canvas.length>0) { 78 | container.removeChild(canvas[0]); 79 | } 80 | container.appendChild( renderer.domElement ); 81 | } 82 | 83 | function animate() { 84 | window.requestAnimationFrame(animate); 85 | render(); 86 | } 87 | 88 | function render() { 89 | var delta = clock.getDelta(); 90 | cameraControls.update(delta); 91 | renderer.render(scene, camera); 92 | } 93 | 94 | try { 95 | init(); 96 | fillScene(); 97 | addToDOM(); 98 | animate(); 99 | } catch(e) { 100 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 101 | $('#container').append(errorReport+e); 102 | } -------------------------------------------------------------------------------- /unit2/polygon-creation.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Polygon Creation Exercise 4 | // Your task is to complete the function PolygonGeometry(sides) 5 | // which takes 1 argument: 6 | // sides - how many edges the polygon has. 7 | // Return the mesh that defines the minimum number of triangles necessary 8 | // to draw the polygon. 9 | // Radius of the polygon is 1. Center of the polygon is at 0, 0. 10 | //////////////////////////////////////////////////////////////////////////////// 11 | /*global THREE, Coordinates, $, document*/ 12 | 13 | var camera, scene, renderer; 14 | var windowScale; 15 | 16 | function PolygonGeometry(sides) { 17 | var geo = new THREE.Geometry(); 18 | 19 | // generate vertices 20 | for ( var pt = 0 ; pt < sides; pt++ ) 21 | { 22 | // Add 90 degrees so we start at +Y axis, rotate counterclockwise around 23 | var angle = (Math.PI/2) + (pt / sides) * 2 * Math.PI; 24 | 25 | var x = Math.cos( angle ); 26 | var y = Math.sin( angle ); 27 | 28 | // YOUR CODE HERE 29 | //Save the vertex location - fill in the code 30 | 31 | } 32 | // YOUR CODE HERE 33 | // Write the code to generate minimum number of faces for the polygon. 34 | 35 | // Return the geometry object 36 | return geo; 37 | } 38 | 39 | function init() { 40 | // Setting up some parameters 41 | var canvasWidth = 846; 42 | var canvasHeight = 494; 43 | // For grading the window is fixed in size; here's general code: 44 | //var canvasWidth = window.innerWidth; 45 | //var canvasHeight = window.innerHeight; 46 | var canvasRatio = canvasWidth / canvasHeight; 47 | // scene 48 | scene = new THREE.Scene(); 49 | 50 | // Camera: Y up, X right, Z up 51 | windowScale = 4; 52 | var windowWidth = windowScale * canvasRatio; 53 | var windowHeight = windowScale; 54 | 55 | camera = new THREE.OrthographicCamera( windowWidth / - 2, windowWidth / 2, windowHeight / 2, windowHeight / - 2, 0, 40 ); 56 | 57 | var focus = new THREE.Vector3( 0,1,0 ); 58 | camera.position.x = focus.x; 59 | camera.position.y = focus.y; 60 | camera.position.z = 10; 61 | camera.lookAt(focus); 62 | 63 | renderer = new THREE.WebGLRenderer({ antialias: false, preserveDrawingBuffer: true}); 64 | renderer.gammaInput = true; 65 | renderer.gammaOutput = true; 66 | renderer.setSize( canvasWidth, canvasHeight ); 67 | renderer.setClearColorHex( 0xFFFFFF, 1.0 ); 68 | 69 | } 70 | function showGrids() { 71 | // Background grid and axes. Grid step size is 1, axes cross at 0, 0 72 | Coordinates.drawGrid({size:100,scale:1,orientation:"z"}); 73 | Coordinates.drawAxes({axisLength:4,axisOrientation:"x",axisRadius:0.02}); 74 | Coordinates.drawAxes({axisLength:3,axisOrientation:"y",axisRadius:0.02}); 75 | } 76 | function addToDOM() { 77 | var container = document.getElementById('container'); 78 | var canvas = container.getElementsByTagName('canvas'); 79 | if (canvas.length>0) { 80 | container.removeChild(canvas[0]); 81 | } 82 | container.appendChild( renderer.domElement ); 83 | } 84 | function render() { 85 | renderer.render( scene, camera ); 86 | } 87 | 88 | // Main body of the script 89 | 90 | 91 | try { 92 | init(); 93 | showGrids(); 94 | var geo = PolygonGeometry(5); 95 | var material = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.FrontSide } ); 96 | var mesh = new THREE.Mesh( geo, material ); 97 | scene.add( mesh ); 98 | addToDOM(); 99 | render(); 100 | } catch(e) { 101 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 102 | $('#container').append(errorReport+e); 103 | } 104 | -------------------------------------------------------------------------------- /unit8/05-textured-square.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Make a textured square 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, Coordinates, $, document, window*/ 6 | 7 | var path = ""; // STUDENT: set to "" to run on your computer, "/" for submitting code to Udacity 8 | 9 | var camera, scene, renderer; 10 | var cameraControls; 11 | var clock = new THREE.Clock(); 12 | 13 | function fillScene() { 14 | scene = new THREE.Scene(); 15 | 16 | var myPolygon = new SquareGeometry(); 17 | var myTexture = THREE.ImageUtils.loadTexture( path + 'media/img/cs291/textures/ash_uvgrid01.jpg' ); 18 | var myPolygonMaterial = new THREE.MeshBasicMaterial( { map: myTexture } ); 19 | var polygonObject = new THREE.Mesh( myPolygon, myPolygonMaterial ); 20 | scene.add(polygonObject); 21 | } 22 | 23 | function SquareGeometry() { 24 | var geo = new THREE.Geometry(); 25 | 26 | // student should add code within this method 27 | 28 | // generate vertices 29 | geo.vertices.push( new THREE.Vector3( 0.0, 0.0, 0.0 ) ); 30 | geo.vertices.push( new THREE.Vector3( 1.0, 0.0, 0.0 ) ); 31 | geo.vertices.push( new THREE.Vector3( 1.0, 1.0, 0.0 ) ); 32 | var uvs = []; 33 | uvs.push( new THREE.Vector2( 0.0, 0.0 ) ); 34 | uvs.push( new THREE.Vector2( 1.0, 0.0 ) ); 35 | uvs.push( new THREE.Vector2( 1.0, 1.0 ) ); 36 | // generate faces 37 | geo.faces.push( new THREE.Face3( 0, 1, 2 ) ); 38 | geo.faceVertexUvs[ 0 ].push( [ uvs[0], uvs[1], uvs[2] ] ); 39 | 40 | // done: return it. 41 | return geo; 42 | } 43 | 44 | function drawHelpers() { 45 | // Background grid and axes. Grid step size is 1, axes cross at 0, 0 46 | Coordinates.drawGrid({size:100,scale:1,orientation:"z",offset:-0.01}); 47 | Coordinates.drawAxes({axisLength:2.1,axisOrientation:"x",axisRadius:0.004,offset:-0.01}); 48 | Coordinates.drawAxes({axisLength:2.1,axisOrientation:"y",axisRadius:0.004,offset:-0.01}); 49 | } 50 | 51 | function addToDOM() { 52 | var container = document.getElementById('container'); 53 | var canvas = container.getElementsByTagName('canvas'); 54 | if (canvas.length>0) { 55 | container.removeChild(canvas[0]); 56 | } 57 | container.appendChild( renderer.domElement ); 58 | } 59 | 60 | function init() { 61 | var canvasWidth = 846; 62 | var canvasHeight = 494; 63 | // For grading the window is fixed in size; here's general code: 64 | //var canvasWidth = window.innerWidth; 65 | //var canvasHeight = window.innerHeight; 66 | var canvasRatio = canvasWidth / canvasHeight; 67 | 68 | // RENDERER 69 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 70 | renderer.gammaInput = true; 71 | renderer.gammaOutput = true; 72 | renderer.setSize(canvasWidth, canvasHeight); 73 | renderer.setClearColorHex( 0xFFFFFF, 1.0 ); 74 | 75 | // Camera: Y up, X right, Z up 76 | camera = new THREE.PerspectiveCamera( 1, canvasRatio, 50, 150 ); 77 | camera.position.set( 0.5, 0.5, 100 ); 78 | 79 | // CONTROLS 80 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 81 | cameraControls.target.set(0.5,0.5,0); 82 | 83 | } 84 | 85 | function animate() { 86 | window.requestAnimationFrame(animate); 87 | render(); 88 | } 89 | function render() { 90 | var delta = clock.getDelta(); 91 | cameraControls.update(delta); 92 | renderer.render(scene, camera); 93 | } 94 | 95 | try { 96 | init(); 97 | fillScene(); 98 | drawHelpers(); 99 | addToDOM(); 100 | animate(); 101 | } catch(e) { 102 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 103 | $('#container').append(errorReport+e); 104 | } 105 | -------------------------------------------------------------------------------- /unit8/ps-reflection-mapping.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Add a reflection map 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, requestAnimationFrame, $ */ 6 | 7 | var txrpath = ""; // STUDENT: set to "" to run on your computer, "/" for submitting code to Udacity 8 | 9 | var camera, scene, renderer; 10 | var cameraControls; 11 | var clock = new THREE.Clock(); 12 | var teapotSize = 400; 13 | 14 | function fillScene() { 15 | scene = new THREE.Scene(); 16 | 17 | // LIGHTS 18 | scene.add( new THREE.AmbientLight( 0x333333 ) ); 19 | 20 | var light = new THREE.DirectionalLight( 0xFFFFFF, 0.9 ); 21 | light.position.set( -1300, 700, 1240 ); 22 | 23 | scene.add( light ); 24 | 25 | light = new THREE.DirectionalLight( 0xFFFFFF, 0.7 ); 26 | light.position.set( 1000, -500, -1200 ); 27 | 28 | scene.add( light ); 29 | 30 | // MATERIALS 31 | var path = txrpath + "media/img/cs291/textures/skybox/"; 32 | var urls = [path + "px.jpg", path + "nx.jpg", 33 | path + "py.jpg", path + "ny.jpg", 34 | path + "pz.jpg", path + "nz.jpg" ]; 35 | 36 | var textureCube = THREE.ImageUtils.loadTextureCube( urls ); 37 | textureCube.format = THREE.RGBFormat; 38 | 39 | var teapotMaterial = new THREE.MeshPhongMaterial( 40 | { color: 0x770000, specular:0xffaaaa } ); 41 | 42 | var teapot = new THREE.Mesh( 43 | new THREE.TeapotGeometry( teapotSize, 44 | 8, true, true, true, true, true ), 45 | teapotMaterial ); 46 | 47 | scene.add( teapot ); 48 | 49 | 50 | var shader = THREE.ShaderLib.cube; 51 | shader.uniforms.tCube.value = textureCube; 52 | 53 | var skyMaterial = new THREE.ShaderMaterial( { 54 | fragmentShader: shader.fragmentShader, 55 | vertexShader: shader.vertexShader, 56 | uniforms: shader.uniforms, 57 | depthWrite: false, 58 | side: THREE.BackSide 59 | } ); 60 | 61 | var sky = new THREE.Mesh( new THREE.CubeGeometry( 5000, 5000, 5000 ), skyMaterial ); 62 | scene.add( sky ); 63 | } 64 | 65 | function init() { 66 | var canvasWidth = 846; 67 | var canvasHeight = 494; 68 | // For grading the window is fixed in size; here's general code: 69 | //var canvasWidth = window.innerWidth; 70 | //var canvasHeight = window.innerHeight; 71 | 72 | // CAMERA 73 | camera = new THREE.PerspectiveCamera( 45, canvasWidth/ canvasHeight, 100, 20000 ); 74 | camera.position.set( -222, 494, 1746 ); 75 | 76 | // RENDERER 77 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 78 | renderer.setSize( canvasWidth, canvasHeight ); 79 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 80 | renderer.gammaInput = true; 81 | renderer.gammaOutput = true; 82 | 83 | // CONTROLS 84 | 85 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 86 | cameraControls.target.set(0, -160, 0); 87 | 88 | } 89 | 90 | // EVENT HANDLERS 91 | 92 | function addToDOM() { 93 | var container = document.getElementById('container'); 94 | var canvas = container.getElementsByTagName('canvas'); 95 | if (canvas.length>0) { 96 | container.removeChild(canvas[0]); 97 | } 98 | container.appendChild( renderer.domElement ); 99 | } 100 | 101 | function animate() { 102 | requestAnimationFrame( animate ); 103 | render(); 104 | } 105 | 106 | function render() { 107 | var delta = clock.getDelta(); 108 | cameraControls.update( delta ); 109 | 110 | renderer.render( scene, camera ); 111 | } 112 | 113 | try { 114 | init(); 115 | fillScene(); 116 | addToDOM(); 117 | animate(); 118 | } catch(e) { 119 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 120 | $('#container').append(errorReport+e); 121 | } 122 | -------------------------------------------------------------------------------- /unit2/polygon-location.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Polygon Location Exercise 4 | // Your task is to write a function that will take 2 arguments: 5 | // sides - how many edges the polygon has. 6 | // location - location of the center of the polygon as a THREE.Vector3. 7 | // Return the mesh that defines the minimum number of triangles necessary 8 | // to draw the polygon. 9 | //////////////////////////////////////////////////////////////////////////////// 10 | /*global THREE, Coordinates, $, document*/ 11 | 12 | var camera, scene, renderer; 13 | var windowScale; 14 | 15 | function PolygonGeometry(sides, location) { 16 | var geo = new THREE.Geometry(); 17 | 18 | // generate vertices 19 | for ( var pt = 0 ; pt < sides; pt++ ) 20 | { 21 | // Add 90 degrees so we start at +Y axis, rotate counterclockwise around 22 | var angle = (Math.PI/2) + (pt / sides) * 2 * Math.PI; 23 | 24 | var x = Math.cos( angle ); 25 | var y = Math.sin( angle ); 26 | 27 | // Save the vertex location 28 | geo.vertices.push( new THREE.Vector3( x, y, 0.0 ) ); 29 | } 30 | 31 | // generate faces 32 | for ( var face = 0 ; face < sides-2; face++ ) 33 | { 34 | // this makes a triangle fan, from the first +Y point around 35 | geo.faces.push( new THREE.Face3( 0, face+1, face+2 ) ); 36 | } 37 | // done: return it. 38 | return geo; 39 | } 40 | 41 | function init() { 42 | // Set up some parameters 43 | var canvasWidth = 846; 44 | var canvasHeight = 494; 45 | // For grading the window is fixed in size; here's general code: 46 | //var canvasWidth = window.innerWidth; 47 | //var canvasHeight = window.innerHeight; 48 | var canvasRatio = canvasWidth / canvasHeight; 49 | // scene 50 | scene = new THREE.Scene(); 51 | 52 | // Camera: Y up, X right, Z up 53 | windowScale = 8; 54 | var windowWidth = windowScale * canvasRatio; 55 | var windowHeight = windowScale; 56 | 57 | camera = new THREE.OrthographicCamera( windowWidth / - 2, windowWidth / 2, 58 | windowHeight / 2, windowHeight / - 2, 0, 40 ); 59 | 60 | var focus = new THREE.Vector3( 3,3,0 ); 61 | camera.position.x = focus.x; 62 | camera.position.y = focus.y; 63 | camera.position.z = 10; 64 | camera.lookAt(focus); 65 | 66 | renderer = new THREE.WebGLRenderer({ antialias: false, preserveDrawingBuffer: true}); 67 | renderer.gammaInput = true; 68 | renderer.gammaOutput = true; 69 | renderer.setSize(canvasWidth, canvasHeight); 70 | renderer.setClearColorHex( 0xFFFFFF, 1.0 ); 71 | 72 | } 73 | function showGrids() { 74 | // Background grid and axes. Grid step size is 1, axes cross at 0, 0 75 | Coordinates.drawGrid({size:100,scale:1,orientation:"z"}); 76 | Coordinates.drawAxes({axisLength:4,axisOrientation:"x",axisRadius:0.02}); 77 | Coordinates.drawAxes({axisLength:3,axisOrientation:"y",axisRadius:0.02}); 78 | } 79 | function addToDOM() { 80 | var container = document.getElementById('container'); 81 | var canvas = container.getElementsByTagName('canvas'); 82 | if (canvas.length>0) { 83 | container.removeChild(canvas[0]); 84 | } 85 | container.appendChild( renderer.domElement ); 86 | } 87 | 88 | function render() { 89 | renderer.render( scene, camera ); 90 | } 91 | 92 | // Main body of the script 93 | try { 94 | init(); 95 | showGrids(); 96 | var geo = PolygonGeometry(6, new THREE.Vector3( 3, 4, 0 )); 97 | var material = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.FrontSide } ); 98 | var mesh = new THREE.Mesh( geo, material ); 99 | scene.add( mesh ); 100 | addToDOM(); 101 | render(); 102 | } catch(e) { 103 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 104 | $('#container').append(errorReport+e); 105 | } 106 | -------------------------------------------------------------------------------- /unit2/polygon-radius.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Polygon Radius Exercise 4 | // Your task is to write a function that will take 3 arguments: 5 | // sides - how many edges the polygon has. 6 | // location - location of the center of the polygon as a THREE.Vector3. 7 | // radius - radius of the polygon. 8 | // Return the mesh that defines the minimum number of triangles necessary 9 | // to draw the polygon. 10 | //////////////////////////////////////////////////////////////////////////////// 11 | /*global THREE, Coordinates, $, document*/ 12 | 13 | var camera, scene, renderer; 14 | var windowScale; 15 | 16 | function PolygonGeometry(sides, location, radius) { 17 | var geo = new THREE.Geometry(); 18 | 19 | // generate vertices 20 | for ( var pt = 0 ; pt < sides; pt++ ) 21 | { 22 | // Add 90 degrees so we start at +Y axis, rotate counterclockwise around 23 | var angle = (Math.PI/2) + (pt / sides) * 2 * Math.PI; 24 | 25 | var x = Math.cos(angle) + location.x; 26 | var y = Math.sin(angle) + location.y; 27 | 28 | // Save the vertex location 29 | geo.vertices.push( new THREE.Vector3( x, y, 0.0 ) ); 30 | } 31 | 32 | // generate faces 33 | for ( var face = 0 ; face < sides-2; face++ ) 34 | { 35 | // this makes a triangle fan, from the first +Y point around 36 | geo.faces.push( new THREE.Face3( 0, face+1, face+2 ) ); 37 | } 38 | // done: return it. 39 | return geo; 40 | } 41 | 42 | function init() { 43 | // Setting up some parameters 44 | var canvasWidth = 846; 45 | var canvasHeight = 494; 46 | // For grading the window is fixed in size; here's general code: 47 | //var canvasWidth = window.innerWidth; 48 | //var canvasHeight = window.innerHeight; 49 | var canvasRatio = canvasWidth / canvasHeight; 50 | // scene 51 | scene = new THREE.Scene(); 52 | 53 | // Camera: Y up, X right, Z up 54 | windowScale = 12; 55 | var windowWidth = windowScale * canvasRatio; 56 | var windowHeight = windowScale; 57 | 58 | camera = new THREE.OrthographicCamera( windowWidth / - 2, windowWidth / 2, windowHeight / 2, windowHeight / - 2, 0, 40 ); 59 | 60 | var focus = new THREE.Vector3( 5,5,0 ); 61 | camera.position.x = focus.x; 62 | camera.position.y = focus.y; 63 | camera.position.z = 10; 64 | camera.lookAt(focus); 65 | 66 | 67 | renderer = new THREE.WebGLRenderer({ antialias: false, preserveDrawingBuffer: true}); 68 | renderer.gammaInput = true; 69 | renderer.gammaOutput = true; 70 | renderer.setSize(canvasWidth, canvasHeight); 71 | renderer.setClearColorHex( 0xFFFFFF, 1.0 ); 72 | 73 | } 74 | function showGrids() { 75 | // Background grid and axes. Grid step size is 1, axes cross at 0, 0 76 | Coordinates.drawGrid({size:100,scale:1,orientation:"z"}); 77 | Coordinates.drawAxes({axisLength:4,axisOrientation:"x",axisRadius:0.02}); 78 | Coordinates.drawAxes({axisLength:3,axisOrientation:"y",axisRadius:0.02}); 79 | } 80 | function addToDOM() { 81 | var container = document.getElementById('container'); 82 | var canvas = container.getElementsByTagName('canvas'); 83 | if (canvas.length>0) { 84 | container.removeChild(canvas[0]); 85 | } 86 | container.appendChild( renderer.domElement ); 87 | } 88 | function render() { 89 | renderer.render( scene, camera ); 90 | } 91 | 92 | // Main body of the script 93 | try { 94 | init(); 95 | showGrids(); 96 | var geo = PolygonGeometry(9, new THREE.Vector3( 5, 5, 0 ), 4); 97 | var material = new THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.FrontSide } ); 98 | var mesh = new THREE.Mesh( geo, material ); 99 | scene.add( mesh ); 100 | addToDOM(); 101 | render(); 102 | } catch(e) { 103 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 104 | $('#container').append(errorReport+e); 105 | } 106 | -------------------------------------------------------------------------------- /demo/unit1-render-mode-1.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Rendering modes demo 4 | // This is rendering mode #1 5 | // Rotate the scene and see how the objects are displayed 6 | //////////////////////////////////////////////////////////////////////////////// 7 | /*global THREE, requestAnimationFrame, window, document, Stats */ 8 | var container, camera, scene, renderer, stats; 9 | var cameraControls; 10 | var clock = new THREE.Clock(); 11 | var sphere, cube, cylinder; 12 | 13 | function addToDOM() { 14 | container = document.getElementById('container'); 15 | var canvas = container.getElementsByTagName('canvas'); 16 | if (canvas.length>0) { 17 | container.removeChild(canvas[0]); 18 | } 19 | container.appendChild( renderer.domElement ); 20 | } 21 | 22 | function init() { 23 | 24 | var canvasWidth = window.innerWidth; 25 | var canvasHeight = window.innerHeight; 26 | 27 | // CAMERA 28 | camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 4000 ); 29 | camera.position.set( 200, 550, 1300 ); 30 | 31 | // SCENE 32 | scene = new THREE.Scene(); 33 | scene.fog = new THREE.Fog( 0xFFFFFF, 1000, 4000 ); 34 | 35 | // LIGHTS 36 | scene.add( new THREE.AmbientLight( 0x222222 ) ); 37 | var light = new THREE.DirectionalLight( 0xFFFFFF, 2.25 ); 38 | light.position.set( 200, 400, 500 ); 39 | scene.add( light ); 40 | 41 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.5 ); 42 | light2.position.set( -400, -200, 200 ); 43 | scene.add( light2 ); 44 | 45 | // RENDERER 46 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 47 | renderer.setSize( canvasWidth, canvasHeight ); 48 | renderer.setClearColor( scene.fog.color, 1 ); 49 | 50 | renderer.gammaInput = true; 51 | renderer.gammaOutput = true; 52 | 53 | // Setting up rendering/sorting options 54 | renderer.sortObjects = false; 55 | renderer.context.depthFunc(renderer.context.ALWAYS); 56 | 57 | addToDOM(); 58 | // STATS 59 | stats = new Stats(); 60 | stats.domElement.style.position = 'absolute'; 61 | stats.domElement.style.top = '0px'; 62 | stats.domElement.style.zIndex = 100; 63 | container.appendChild( stats.domElement ); 64 | 65 | stats.domElement.children[ 0 ].children[ 0 ].style.color = "#aaa"; 66 | stats.domElement.children[ 0 ].style.background = "transparent"; 67 | stats.domElement.children[ 0 ].children[ 1 ].style.display = "none"; 68 | 69 | // CONTROLS 70 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 71 | cameraControls.target.set( 0, 50, 0 ); 72 | 73 | // MODELS 74 | sphere = new THREE.Mesh( 75 | new THREE.SphereGeometry( 210, 32, 16 ), 76 | new THREE.MeshPhongMaterial( { color: 0x004000, specular: 0x606060 } ) ); 77 | 78 | sphere.position.x = 0; 79 | sphere.position.y = 210; 80 | sphere.position.z = 0; 81 | 82 | scene.add( sphere ); 83 | 84 | cube = new THREE.Mesh( 85 | new THREE.CubeGeometry( 120, 380, 200 ), 86 | new THREE.MeshLambertMaterial( { color: 0x800000 } ) ); 87 | 88 | cube.position.x = 50; 89 | cube.position.y = 190; 90 | cube.position.z = 400; 91 | 92 | scene.add( cube ); 93 | 94 | cylinder = new THREE.Mesh( 95 | new THREE.CylinderGeometry( 200, 200, 500, 32, 1 ), 96 | new THREE.MeshPhongMaterial( { color: 0x000060, specular: 0x000060 } ) ); 97 | 98 | cylinder.position.x = 40; 99 | cylinder.position.y = 250; 100 | cylinder.position.z = -500; 101 | 102 | scene.add( cylinder ); 103 | 104 | } 105 | 106 | function render() { 107 | 108 | var delta = clock.getDelta(); 109 | cameraControls.update( delta ); 110 | renderer.render( scene, camera ); 111 | 112 | } 113 | 114 | function animate() { 115 | 116 | requestAnimationFrame( animate ); 117 | render(); 118 | stats.update(); 119 | 120 | } 121 | 122 | 123 | 124 | init(); 125 | 126 | animate(); -------------------------------------------------------------------------------- /demo/unit1-render-mode-2.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Rendering modes demo 4 | // This is rendering mode #2 5 | // Rotate the scene and see how the objects are displayed 6 | //////////////////////////////////////////////////////////////////////////////// 7 | /*global THREE, requestAnimationFrame, window, document, Stats */ 8 | var container, camera, scene, renderer, stats; 9 | var cameraControls; 10 | var clock = new THREE.Clock(); 11 | var sphere, cube, cylinder; 12 | 13 | function addToDOM() { 14 | container = document.getElementById('container'); 15 | var canvas = container.getElementsByTagName('canvas'); 16 | if (canvas.length>0) { 17 | container.removeChild(canvas[0]); 18 | } 19 | container.appendChild( renderer.domElement ); 20 | } 21 | 22 | function init() { 23 | 24 | var canvasWidth = window.innerWidth; 25 | var canvasHeight = window.innerHeight; 26 | 27 | // CAMERA 28 | camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 4000 ); 29 | camera.position.set( 200, 550, 1300 ); 30 | 31 | // SCENE 32 | scene = new THREE.Scene(); 33 | scene.fog = new THREE.Fog( 0xFFFFFF, 1000, 4000 ); 34 | 35 | // LIGHTS 36 | scene.add( new THREE.AmbientLight( 0x222222 ) ); 37 | var light = new THREE.DirectionalLight( 0xFFFFFF, 2.25 ); 38 | light.position.set( 200, 400, 500 ); 39 | scene.add( light ); 40 | 41 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.5 ); 42 | light2.position.set( -400, -200, 200 ); 43 | scene.add( light2 ); 44 | 45 | // RENDERER 46 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 47 | renderer.setSize( canvasWidth, canvasHeight ); 48 | renderer.setClearColor( scene.fog.color, 1 ); 49 | 50 | renderer.gammaInput = true; 51 | renderer.gammaOutput = true; 52 | 53 | // Setting up rendering/sorting options 54 | renderer.sortObjects = true; 55 | renderer.context.depthFunc(renderer.context.ALWAYS); 56 | 57 | addToDOM(); 58 | // STATS 59 | stats = new Stats(); 60 | stats.domElement.style.position = 'absolute'; 61 | stats.domElement.style.top = '0px'; 62 | stats.domElement.style.zIndex = 100; 63 | container.appendChild( stats.domElement ); 64 | 65 | stats.domElement.children[ 0 ].children[ 0 ].style.color = "#aaa"; 66 | stats.domElement.children[ 0 ].style.background = "transparent"; 67 | stats.domElement.children[ 0 ].children[ 1 ].style.display = "none"; 68 | 69 | // CONTROLS 70 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 71 | cameraControls.target.set( 0, 50, 0 ); 72 | 73 | // MODELS 74 | sphere = new THREE.Mesh( 75 | new THREE.SphereGeometry( 210, 32, 16 ), 76 | new THREE.MeshPhongMaterial( { color: 0x004000, specular: 0x606060 } ) ); 77 | 78 | sphere.position.x = 0; 79 | sphere.position.y = 210; 80 | sphere.position.z = 0; 81 | 82 | scene.add( sphere ); 83 | 84 | cube = new THREE.Mesh( 85 | new THREE.CubeGeometry( 120, 380, 200 ), 86 | new THREE.MeshLambertMaterial( { color: 0x800000 } ) ); 87 | 88 | cube.position.x = 50; 89 | cube.position.y = 190; 90 | cube.position.z = 400; 91 | 92 | scene.add( cube ); 93 | 94 | cylinder = new THREE.Mesh( 95 | new THREE.CylinderGeometry( 200, 200, 500, 32, 1 ), 96 | new THREE.MeshPhongMaterial( { color: 0x000060, specular: 0x000060 } ) ); 97 | 98 | cylinder.position.x = 40; 99 | cylinder.position.y = 250; 100 | cylinder.position.z = -500; 101 | 102 | scene.add( cylinder ); 103 | 104 | } 105 | 106 | function render() { 107 | 108 | var delta = clock.getDelta(); 109 | cameraControls.update( delta ); 110 | renderer.render( scene, camera ); 111 | 112 | } 113 | 114 | function animate() { 115 | 116 | requestAnimationFrame( animate ); 117 | render(); 118 | stats.update(); 119 | 120 | } 121 | 122 | 123 | 124 | init(); 125 | 126 | animate(); -------------------------------------------------------------------------------- /unit2/triangle-mesh.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Draw a Square Exercise 4 | // Your task is to complete the function square (at line 28). 5 | // The function takes 4 arguments - coordinates x1, y1, x2, y2 6 | // for the square and returns a geometry object (THREE.Geometry()) 7 | // that defines a square at the provided coordinates. 8 | //////////////////////////////////////////////////////////////////////////////// 9 | /*global THREE, Coordinates, document*/ 10 | 11 | var camera, scene, renderer; 12 | var windowScale; 13 | 14 | function exampleTriangle() { 15 | // This code demonstrates how to draw a triangle 16 | var triangle = new THREE.Geometry(); 17 | triangle.vertices.push( new THREE.Vector3( 1, 1, 0 ) ); 18 | triangle.vertices.push( new THREE.Vector3( 3, 1, 0 ) ); 19 | triangle.vertices.push( new THREE.Vector3( 3, 3, 0 ) ); 20 | 21 | triangle.faces.push( new THREE.Face3( 0, 1, 2 ) ); 22 | 23 | return triangle; 24 | } 25 | 26 | function drawSquare(x1, y1, x2, y2) { 27 | 28 | var square = new THREE.Geometry(); 29 | // Your code goes here 30 | 31 | // don't forget to return the geometry! The following line is required! 32 | return square; 33 | } 34 | 35 | function init() { 36 | // Set up some parameters 37 | var canvasWidth = 846; 38 | var canvasHeight = 494; 39 | // For grading the window is fixed in size; here's general code: 40 | //var canvasWidth = window.innerWidth; 41 | //var canvasHeight = window.innerHeight; 42 | var canvasRatio = canvasWidth / canvasHeight; 43 | // scene 44 | scene = new THREE.Scene(); 45 | 46 | // Camera: Y up, X right, Z up 47 | windowScale = 12; 48 | var windowWidth = windowScale * canvasRatio; 49 | var windowHeight = windowScale; 50 | 51 | camera = new THREE.OrthographicCamera(windowWidth/-2, windowWidth/2, windowHeight/2, windowHeight/-2, 0, 40); 52 | 53 | var focus = new THREE.Vector3( 5,5,0 ); 54 | camera.position.x = focus.x; 55 | camera.position.y = focus.y; 56 | camera.position.z = 20; 57 | camera.lookAt(focus); 58 | 59 | renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true}); 60 | renderer.gammaInput = true; 61 | renderer.gammaOutput = true; 62 | renderer.setSize( canvasWidth, canvasHeight ); 63 | renderer.setClearColorHex( 0xFFFFFF, 1.0 ); 64 | } 65 | 66 | function addToDOM() { 67 | var container = document.getElementById('container'); 68 | var canvas = container.getElementsByTagName('canvas'); 69 | if (canvas.length>0) { 70 | container.removeChild(canvas[0]); 71 | } 72 | container.appendChild( renderer.domElement ); 73 | } 74 | 75 | function render() { 76 | renderer.render( scene, camera ); 77 | } 78 | 79 | function showGrids() { 80 | // Background grid and axes. Grid step size is 1, axes cross at 0, 0 81 | Coordinates.drawGrid({size:100,scale:1,orientation:"z"}); 82 | Coordinates.drawAxes({axisLength:11,axisOrientation:"x",axisRadius:0.04}); 83 | Coordinates.drawAxes({axisLength:11,axisOrientation:"y",axisRadius:0.04}); 84 | } 85 | 86 | try { 87 | init(); 88 | showGrids(); 89 | // creating and adding the triangle to the scene 90 | var triangleMaterial = new THREE.MeshBasicMaterial( { color: 0x2685AA, side: THREE.DoubleSide } ); 91 | var triangleGeometry = exampleTriangle(); 92 | var triangleMesh = new THREE.Mesh( triangleGeometry, triangleMaterial ); 93 | scene.add(triangleMesh); 94 | // creating and adding your square to the scene ! 95 | var square_material = new THREE.MeshBasicMaterial( { color: 0xF6831E, side: THREE.DoubleSide } ); 96 | var square_geometry = drawSquare(3,5,7,9); 97 | var square_mesh = new THREE.Mesh(square_geometry, square_material); 98 | scene.add(square_mesh); 99 | addToDOM(); 100 | render(); 101 | } catch(e) { 102 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 103 | $('#container').append(errorReport+e); 104 | } 105 | 106 | 107 | -------------------------------------------------------------------------------- /demo/unit3-diffuse-demo.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Change angle of light to see how effect decreases with angle 4 | //////////////////////////////////////////////////////////////////////////////// 5 | 6 | /*global THREE, requestAnimationFrame, dat, window, document*/ 7 | 8 | var camera, scene, renderer; 9 | var cameraControls; 10 | var ec; 11 | var clock = new THREE.Clock(); 12 | var light1, light2, light3; 13 | var ground, lightMesh; 14 | var angle = 0; 15 | 16 | function init() { 17 | var canvasWidth = window.innerWidth; 18 | var canvasHeight = window.innerHeight; 19 | 20 | // CAMERA 21 | camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 80000 ); 22 | camera.position.set( 0, 0, 100 ); 23 | 24 | light1 = new THREE.SpotLight(); 25 | light1.color.setRGB(1, 0, 0); 26 | light1.position.set( -100*Math.sin(angle * Math.PI/180), 0, 100*Math.cos(angle * Math.PI/180) ); 27 | light1.angle = 0.1; 28 | light1.exponent = 0; 29 | light1.target.position.set( 0, 0, 0 ); 30 | 31 | var lightMaterial = new THREE.MeshBasicMaterial( { color: 0xffaa00, transparent: true}); 32 | var lightSpot = new THREE.SphereGeometry( 2, 32, 16 ); 33 | lightMesh = new THREE.Mesh( lightSpot, lightMaterial ); 34 | lightMesh.position.x = light1.position.x; 35 | lightMesh.position.z = light1.position.z; 36 | 37 | 38 | // GROUND 39 | var gg = new THREE.PlaneGeometry( 75, 75, 5, 5 ); 40 | var gm = new THREE.MeshPhongMaterial( { color: 0xFFFFFF, side: THREE.DoubleSide} ); 41 | gm.specular.setRGB(0,0,0); 42 | var wire = new THREE.MeshBasicMaterial({ color: 0x555555, wireframe: true }); 43 | 44 | ground = new THREE.SceneUtils.createMultiMaterialObject(gg, [gm, wire]); 45 | //ground = new THREE.Mesh( gg, gm ); 46 | ground.position.y = -0.1; 47 | //ground.add(new THREE.AxisHelper(100)); 48 | // RENDERER 49 | 50 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 51 | renderer.setSize( canvasWidth, canvasHeight ); 52 | renderer.setClearColorHex( 0xFFFFFF, 1.0 ); 53 | 54 | var container = document.getElementById('container'); 55 | container.appendChild( renderer.domElement ); 56 | 57 | renderer.gammaInput = true; 58 | renderer.gammaOutput = true; 59 | 60 | // EVENTS 61 | 62 | window.addEventListener( 'resize', onWindowResize, false ); 63 | 64 | // CONTROLS 65 | 66 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 67 | cameraControls.target.set(0, 0, 0); 68 | 69 | fillScene(); 70 | // GUI 71 | setupGui(); 72 | 73 | } 74 | 75 | // EVENT HANDLERS 76 | 77 | function onWindowResize() { 78 | 79 | var canvasWidth = window.innerWidth; 80 | var canvasHeight = window.innerHeight; 81 | 82 | renderer.setSize( canvasWidth, canvasHeight ); 83 | 84 | camera.aspect = canvasWidth/ canvasHeight; 85 | camera.updateProjectionMatrix(); 86 | 87 | } 88 | 89 | function setupGui() { 90 | 91 | ec = { 92 | 93 | angle: angle 94 | }; 95 | 96 | var gui = new dat.GUI(); 97 | var element = gui.add( ec, "angle", 0.0, 90.0 ).step(0.1); 98 | element.name("Light angle"); 99 | } 100 | 101 | 102 | // 103 | 104 | function animate() { 105 | 106 | requestAnimationFrame( animate ); 107 | render(); 108 | 109 | } 110 | 111 | function render() { 112 | 113 | var delta = clock.getDelta(); 114 | 115 | cameraControls.update( delta ); 116 | if ( ec.angle !== 0) 117 | { 118 | light1.position.set( -100*Math.sin(ec.angle * Math.PI/180), 0, 100*Math.cos(ec.angle * Math.PI/180) ); 119 | lightMesh.position.x = light1.position.x; 120 | lightMesh.position.z = light1.position.z; 121 | } 122 | renderer.render( scene, camera ); 123 | 124 | } 125 | 126 | function fillScene() { 127 | scene = new THREE.Scene(); 128 | 129 | // LIGHTS 130 | scene.add( light1 ); 131 | scene.add( light2 ); 132 | scene.add( light3 ); 133 | 134 | scene.add( ground ); 135 | scene.add(lightMesh); 136 | //Coordinates.drawGrid({size:75,scale:0.1, orientation:"z"}); 137 | 138 | } 139 | 140 | init(); 141 | animate(); 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /demo/unit3-color-demo.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // RGB additive color demo (unit 3) 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE*/ 6 | 7 | /*global THREE, requestAnimationFrame, dat, window, document*/ 8 | 9 | var camera, scene, renderer; 10 | var cameraControls; 11 | var ec; 12 | var clock = new THREE.Clock(); 13 | var light1, light2, light3; 14 | var ground; 15 | var intensityRed = 1; 16 | var intensityGreen = 1; 17 | var intensityBlue = 1; 18 | 19 | function init() { 20 | var canvasWidth = window.innerWidth; 21 | var canvasHeight = window.innerHeight; 22 | var canvasRatio = canvasWidth / canvasHeight; 23 | 24 | // CAMERA 25 | camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 80000 ); 26 | camera.position.set( 0, 0, 400 ); 27 | 28 | light1 = new THREE.SpotLight(); 29 | light1.color.setRGB(intensityRed, 0, 0); 30 | light1.position.set( 0, 75, 100 ); 31 | light1.angle = 0.7; 32 | light1.exponent = 0; 33 | light1.target.position.set( 0, 75, 0 ); 34 | 35 | light2 = new THREE.SpotLight(); 36 | light2.color.setRGB(0, intensityGreen, 0); 37 | light2.position.set( -61, -25, 100 ); 38 | light2.exponent = 0; 39 | light2.target.position.set( -61, -25, 0 ); 40 | light2.angle = 0.7; 41 | 42 | light3 = new THREE.SpotLight(); 43 | light3.color.setRGB(0, 0, intensityBlue); 44 | light3.position.set( 61, -25, 100 ); 45 | light3.exponent = 0; 46 | light3.target.position.set( 61, -25, 0 ); 47 | light3.angle = 0.7; 48 | 49 | // GROUND 50 | 51 | var gg = new THREE.PlaneGeometry( 10000, 10000 ); 52 | var gm = new THREE.MeshPhongMaterial( { color: 0xffffff, side: THREE.DoubleSide } ); 53 | gm.specular.setRGB(0,0,0); 54 | 55 | ground = new THREE.Mesh( gg, gm ); 56 | 57 | // RENDERER 58 | 59 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 60 | renderer.setSize( canvasWidth, canvasHeight ); 61 | renderer.setClearColorHex( 0xFFFFFF, 1.0 ); 62 | 63 | var container = document.getElementById('container'); 64 | container.appendChild( renderer.domElement ); 65 | 66 | renderer.gammaInput = true; 67 | renderer.gammaOutput = true; 68 | 69 | // EVENTS 70 | 71 | window.addEventListener( 'resize', onWindowResize, false ); 72 | 73 | // CONTROLS 74 | 75 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 76 | cameraControls.target.set(0, 0, 0); 77 | 78 | fillScene(); 79 | // GUI 80 | setupGui(); 81 | 82 | } 83 | 84 | // EVENT HANDLERS 85 | 86 | function onWindowResize() { 87 | 88 | var canvasWidth = window.innerWidth; 89 | var canvasHeight = window.innerHeight; 90 | 91 | renderer.setSize( canvasWidth, canvasHeight ); 92 | 93 | camera.aspect = canvasWidth/ canvasHeight; 94 | camera.updateProjectionMatrix(); 95 | 96 | } 97 | 98 | function setupGui() { 99 | 100 | ec = { 101 | 102 | red: intensityRed, 103 | green: intensityGreen, 104 | blue: intensityBlue 105 | }; 106 | 107 | var gui = new dat.GUI(); 108 | var element = gui.add( ec, "red", 0.0, 1.0 ).step(0.1); 109 | element.name("Red intensity"); 110 | element = gui.add( ec, "green", 0.0, 1.0 ).step(0.1); 111 | element.name("Green intensity"); 112 | element = gui.add( ec, "blue", 0.0, 1.0 ).step(0.1); 113 | element.name("Blue intensity"); 114 | } 115 | 116 | 117 | // 118 | 119 | function animate() { 120 | 121 | requestAnimationFrame( animate ); 122 | render(); 123 | 124 | } 125 | 126 | function render() { 127 | 128 | var delta = clock.getDelta(); 129 | 130 | cameraControls.update( delta ); 131 | if ( ec.red !== intensityRed || ec.green !== intensityGreen || ec.blue !== intensityBlue) 132 | { 133 | light1.intensity = ec.red; 134 | light2.intensity = ec.green; 135 | light3.intensity = ec.blue; 136 | } 137 | renderer.render( scene, camera ); 138 | 139 | } 140 | 141 | function fillScene() { 142 | scene = new THREE.Scene(); 143 | 144 | // LIGHTS 145 | 146 | scene.add( light1 ); 147 | scene.add( light2 ); 148 | scene.add( light3 ); 149 | scene.add( ground ); 150 | 151 | 152 | } 153 | 154 | init(); 155 | animate(); 156 | 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /demo/unit3-tessellation-demo.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Tessellation demo 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, dat, window, document*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls, effectController; 9 | var clock = new THREE.Clock(); 10 | var ambientLight, light; 11 | var tess = 3; // force initialization 12 | var wire; 13 | var flat; 14 | var sphere; 15 | 16 | function init() { 17 | var canvasWidth = window.innerWidth; 18 | var canvasHeight = window.innerHeight; 19 | 20 | // CAMERA 21 | 22 | camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 80000 ); 23 | camera.position.set( -300, 300, -1500 ); 24 | camera.lookAt(0,0,0); 25 | // LIGHTS 26 | 27 | ambientLight = new THREE.AmbientLight( 0xFFFFFF ); 28 | 29 | light = new THREE.DirectionalLight( 0xFFFFFF, 0.7 ); 30 | light.position.set( -800, 900, 300 ); 31 | 32 | // RENDERER 33 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 34 | renderer.setSize( canvasWidth, canvasHeight ); 35 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 36 | 37 | var container = document.getElementById('container'); 38 | container.appendChild( renderer.domElement ); 39 | 40 | renderer.gammaInput = true; 41 | renderer.gammaOutput = true; 42 | 43 | // EVENTS 44 | window.addEventListener( 'resize', onWindowResize, false ); 45 | 46 | // CONTROLS 47 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 48 | cameraControls.target.set(0, 0, 0); 49 | 50 | scene = new THREE.Scene(); 51 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 52 | 53 | // LIGHTS 54 | scene.add( ambientLight ); 55 | scene.add( light ); 56 | 57 | fillScene(); 58 | // GUI 59 | setupGui(); 60 | } 61 | 62 | function setupGui() { 63 | effectController = { 64 | newTess: 6, 65 | newFlat: false, 66 | newWire: false 67 | }; 68 | var gui = new dat.GUI(); 69 | gui.add(effectController, "newTess", [2,3,4,5,6,8,10,12,16,24,32] ).name("Tessellation Level"); 70 | gui.add( effectController, "newFlat" ).name("Flat Shading"); 71 | gui.add( effectController, "newWire" ).name("Show wireframe only"); 72 | } 73 | var material1 = new THREE.MeshLambertMaterial( { color: 0xFFFF00, shading: THREE.FlatShading } ); 74 | var ka = 0.4; 75 | material1.ambient.setRGB( material1.color.r * ka, material1.color.g * ka, material1.color.b * ka ); 76 | var material2 = new THREE.MeshLambertMaterial( { color: 0xFFFF00} ); 77 | material2.ambient.setRGB( material2.color.r * ka, material2.color.g * ka, material2.color.b * ka ); 78 | var material3 = new THREE.MeshLambertMaterial( { color: 0xFFFF00, wireframe: true } ); 79 | 80 | function fillScene() { 81 | 82 | var material = wire ? material3 : (flat ? material1 : material2 ); 83 | 84 | if ( sphere !== undefined ) { 85 | 86 | sphere.geometry.dispose(); 87 | scene.remove( sphere ); 88 | 89 | } 90 | 91 | sphere = new THREE.Mesh(new THREE.SphereGeometry( 400, tess*2, tess ), material); 92 | 93 | scene.add( sphere ); 94 | 95 | //Coordinates.drawGround({size:1000}); 96 | //Coordinates.drawGrid({size:1000,scale:0.01}); 97 | //Coordinates.drawAllAxes({axisLength:500,axisRadius:1,axisTess:4}); 98 | } 99 | 100 | // EVENT HANDLERS 101 | 102 | function onWindowResize() { 103 | 104 | var canvasWidth = window.innerWidth; 105 | var canvasHeight = window.innerHeight; 106 | 107 | renderer.setSize( canvasWidth, canvasHeight ); 108 | 109 | camera.aspect = canvasWidth / canvasHeight; 110 | camera.updateProjectionMatrix(); 111 | } 112 | 113 | // 114 | 115 | function animate() { 116 | 117 | window.requestAnimationFrame( animate ); 118 | render(); 119 | 120 | } 121 | 122 | function render() { 123 | var delta = clock.getDelta(); 124 | cameraControls.update(delta); 125 | if ( effectController.newTess !== tess || effectController.newFlat !== flat || effectController.newWire !== wire) 126 | { 127 | tess = effectController.newTess; 128 | flat = effectController.newFlat; 129 | wire = effectController.newWire; 130 | 131 | fillScene(); 132 | } 133 | renderer.render( scene, camera ); 134 | 135 | } 136 | 137 | 138 | 139 | init(); 140 | animate(); 141 | 142 | -------------------------------------------------------------------------------- /demo/unit1-render-mode-0.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Rendering modes demo 4 | // This is rendering mode #0 5 | // Rotate the scene and see how the objects are displayed 6 | //////////////////////////////////////////////////////////////////////////////// 7 | /*global THREE, requestAnimationFrame, window, document, Stats, dat */ 8 | var container, camera, scene, renderer, stats; 9 | var cameraControls, effectController; 10 | var clock = new THREE.Clock(); 11 | var sphere, cube, cylinder; 12 | 13 | function addToDOM() { 14 | container = document.getElementById('container'); 15 | var canvas = container.getElementsByTagName('canvas'); 16 | if (canvas.length>0) { 17 | container.removeChild(canvas[0]); 18 | } 19 | container.appendChild( renderer.domElement ); 20 | } 21 | 22 | function init() { 23 | 24 | var canvasWidth = window.innerWidth; 25 | var canvasHeight = window.innerHeight; 26 | 27 | // CAMERA 28 | camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 4000 ); 29 | camera.position.set( 200, 550, 1300 ); 30 | 31 | // SCENE 32 | scene = new THREE.Scene(); 33 | scene.fog = new THREE.Fog( 0xFFFFFF, 1000, 4000 ); 34 | 35 | // LIGHTS 36 | scene.add( new THREE.AmbientLight( 0x222222 ) ); 37 | var light = new THREE.DirectionalLight( 0xFFFFFF, 2.25 ); 38 | light.position.set( 200, 400, 500 ); 39 | scene.add( light ); 40 | 41 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.5 ); 42 | light2.position.set( -400, -200, 200 ); 43 | scene.add( light2 ); 44 | 45 | // RENDERER 46 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 47 | renderer.setSize( canvasWidth, canvasHeight ); 48 | renderer.setClearColor( scene.fog.color, 1 ); 49 | 50 | renderer.gammaInput = true; 51 | renderer.gammaOutput = true; 52 | 53 | // Setting up rendering/sorting options 54 | renderer.sortObjects = true; 55 | renderer.context.depthFunc(renderer.context.LEQUAL); 56 | 57 | addToDOM(); 58 | // STATS 59 | stats = new Stats(); 60 | stats.domElement.style.position = 'absolute'; 61 | stats.domElement.style.top = '0px'; 62 | stats.domElement.style.zIndex = 100; 63 | container.appendChild( stats.domElement ); 64 | 65 | stats.domElement.children[ 0 ].children[ 0 ].style.color = "#aaa"; 66 | stats.domElement.children[ 0 ].style.background = "transparent"; 67 | stats.domElement.children[ 0 ].children[ 1 ].style.display = "none"; 68 | 69 | // CONTROLS 70 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 71 | cameraControls.target.set( 0, 50, 0 ); 72 | 73 | // MODELS 74 | sphere = new THREE.Mesh( 75 | new THREE.SphereGeometry( 210, 32, 16 ), 76 | new THREE.MeshPhongMaterial( { color: 0x004000, specular: 0x606060 } ) ); 77 | 78 | sphere.position.x = 0; 79 | sphere.position.y = 210; 80 | sphere.position.z = 0; 81 | 82 | scene.add( sphere ); 83 | 84 | cube = new THREE.Mesh( 85 | new THREE.CubeGeometry( 120, 380, 200 ), 86 | new THREE.MeshLambertMaterial( { color: 0x800000 } ) ); 87 | 88 | cube.position.x = 50; 89 | cube.position.y = 190; 90 | cube.position.z = 400; 91 | 92 | scene.add( cube ); 93 | 94 | cylinder = new THREE.Mesh( 95 | new THREE.CylinderGeometry( 200, 200, 500, 32, 1 ), 96 | new THREE.MeshPhongMaterial( { color: 0x000060, specular: 0x000060 } ) ); 97 | 98 | cylinder.position.x = 40; 99 | cylinder.position.y = 250; 100 | cylinder.position.z = -500; 101 | 102 | scene.add( cylinder ); 103 | 104 | //setupGui(); 105 | } 106 | 107 | function setupGui() { 108 | 109 | effectController = { 110 | narration: function() { 111 | var song = document.getElementsByTagName('audio')[0]; 112 | if (song.paused) { 113 | song.currentTime = 0; 114 | song.play(); 115 | } 116 | else 117 | song.pause(); 118 | }, 119 | }; 120 | 121 | var gui = new dat.GUI(); 122 | 123 | var element = gui.add( effectController, "narration"); 124 | element.name("Narration"); 125 | } 126 | 127 | function render() { 128 | 129 | var delta = clock.getDelta(); 130 | cameraControls.update( delta ); 131 | renderer.render( scene, camera ); 132 | 133 | } 134 | 135 | function animate() { 136 | 137 | requestAnimationFrame( animate ); 138 | render(); 139 | stats.update(); 140 | 141 | } 142 | 143 | 144 | 145 | init(); 146 | 147 | animate(); -------------------------------------------------------------------------------- /unit8/ps-pick-a-letter.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Pick a letter, or actually - the number 1 4 | // Edit the UV values in the SquareGeometry function 5 | // to select the number "1" from the texture. 6 | // Only the array 'uvs' should be modified. 7 | //////////////////////////////////////////////////////////////////////////////// 8 | /*global THREE, Coordinates, $, document, window*/ 9 | 10 | var path = ""; // STUDENT: set to "" to run on your computer, "/" for submitting code to Udacity 11 | 12 | var camera, scene, renderer; 13 | var cameraControls, effectController; 14 | var clock = new THREE.Clock(); 15 | 16 | function SquareGeometry() { 17 | var geo = new THREE.Geometry(); 18 | 19 | // generate vertices 20 | geo.vertices.push( new THREE.Vector3( 0.0, 0.0, 0.0 ) ); 21 | geo.vertices.push( new THREE.Vector3( 1.0, 0.0, 0.0 ) ); 22 | geo.vertices.push( new THREE.Vector3( 1.0, 1.0, 0.0 ) ); 23 | geo.vertices.push( new THREE.Vector3( 0.0, 1.0, 0.0 ) ); 24 | 25 | // Change this array to select the correct part of the texture 26 | var uvs = []; 27 | uvs.push( new THREE.Vector2( 0.0, 0.0 ) ); 28 | uvs.push( new THREE.Vector2( 1.0, 0.0 ) ); 29 | uvs.push( new THREE.Vector2( 1.0, 1.0 ) ); 30 | uvs.push( new THREE.Vector2( 0.0, 1.0 ) ); 31 | 32 | // generate faces 33 | geo.faces.push( new THREE.Face3( 0, 1, 2 ) ); 34 | geo.faceVertexUvs[ 0 ].push( [ uvs[0], uvs[1], uvs[2] ] ); 35 | geo.faces.push( new THREE.Face3( 0, 2, 3 ) ); 36 | geo.faceVertexUvs[ 0 ].push( [ uvs[0], uvs[2], uvs[3] ] ); 37 | // done: return it. 38 | return geo; 39 | } 40 | 41 | function fillScene() { 42 | scene = new THREE.Scene(); 43 | 44 | var myPolygon = new SquareGeometry(); 45 | var myTexture = THREE.ImageUtils.loadTexture( path + 'media/img/cs291/textures/lettergrid.png' ); 46 | var myPolygonMaterial = new THREE.MeshBasicMaterial( { map: myTexture } ); 47 | var polygonObject = new THREE.Mesh( myPolygon, myPolygonMaterial ); 48 | scene.add(polygonObject); 49 | } 50 | 51 | function init() { 52 | var canvasWidth = 846; 53 | var canvasHeight = 494; 54 | // For grading the window is fixed in size; here's general code: 55 | //var canvasWidth = window.innerWidth; 56 | //var canvasHeight = window.innerHeight; 57 | var canvasRatio = canvasWidth / canvasHeight; 58 | 59 | // RENDERER 60 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 61 | renderer.gammaInput = true; 62 | renderer.gammaOutput = true; 63 | renderer.setSize(canvasWidth, canvasHeight); 64 | renderer.setClearColorHex( 0xFFFFFF, 1.0 ); 65 | 66 | // Camera: Y up, X right, Z up 67 | camera = new THREE.PerspectiveCamera( 1, canvasRatio, 50, 150 ); 68 | camera.position.set( 0.5, 0.5, 100 ); 69 | 70 | // CONTROLS 71 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 72 | cameraControls.target.set(0.5,0.5,0); 73 | 74 | } 75 | 76 | function addToDOM() { 77 | var container = document.getElementById('container'); 78 | var canvas = container.getElementsByTagName('canvas'); 79 | if (canvas.length>0) { 80 | container.removeChild(canvas[0]); 81 | } 82 | container.appendChild( renderer.domElement ); 83 | } 84 | 85 | function drawHelpers() { 86 | // Background grid and axes. Grid step size is 1, axes cross at 0, 0 87 | Coordinates.drawGrid({size:100,scale:1,orientation:"z",offset:-0.01}); 88 | Coordinates.drawAxes({axisLength:2.1,axisOrientation:"x",axisRadius:0.004,offset:-0.01}); 89 | Coordinates.drawAxes({axisLength:2.1,axisOrientation:"y",axisRadius:0.004,offset:-0.01}); 90 | } 91 | 92 | function animate() { 93 | window.requestAnimationFrame(animate); 94 | render(); 95 | } 96 | 97 | function render() { 98 | var delta = clock.getDelta(); 99 | cameraControls.update(delta); 100 | 101 | renderer.render(scene, camera); 102 | } 103 | 104 | function setupGui() { 105 | 106 | effectController = { 107 | 108 | alpha: 0.7, 109 | sred: 0xE5/255, 110 | sgreen: 0x33/255, 111 | sblue: 0x19/155, 112 | 113 | dred: 0xE5/255, 114 | dgreen: 0xE5/255, 115 | dblue: 0x66/255 116 | }; 117 | 118 | } 119 | 120 | try { 121 | init(); 122 | fillScene(); 123 | setupGui(); 124 | drawHelpers(); 125 | addToDOM(); 126 | animate(); 127 | } catch(e) { 128 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 129 | $('#container').append(errorReport+e); 130 | } 131 | -------------------------------------------------------------------------------- /demo/unit1-fps.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // FPS demo 4 | // Use the slider to adjust FPS an see how that changes the responsiveness 5 | // of the scene. 6 | //////////////////////////////////////////////////////////////////////////////// 7 | /*global THREE, requestAnimationFrame, Stats, dat, window, document */ 8 | 9 | var container, camera, scene, renderer, stats; 10 | var cameraControls; 11 | var effectController; 12 | var clock = new THREE.Clock(); 13 | var teapotSize = 400; 14 | var ambientLight, light, light2; 15 | var teapot; 16 | var newTime = 0, oldTime = 0; 17 | 18 | function setupGui() { 19 | 20 | effectController = { 21 | fps: 6.0 22 | }; 23 | 24 | var gui = new dat.GUI(); 25 | 26 | var element = gui.add( effectController, "fps", 1.0, 60.0 ).step(1.0); 27 | element.name("FPS"); 28 | } 29 | 30 | function addToDOM() { 31 | container = document.getElementById('container'); 32 | var canvas = container.getElementsByTagName('canvas'); 33 | if (canvas.length>0) { 34 | container.removeChild(canvas[0]); 35 | } 36 | container.appendChild( renderer.domElement ); 37 | } 38 | 39 | function init() { 40 | var canvasWidth = window.innerWidth; 41 | var canvasHeight = window.innerHeight; 42 | var canvasRatio = canvasWidth / canvasHeight; 43 | 44 | // CAMERA 45 | camera = new THREE.PerspectiveCamera( 45, canvasRatio, 1, 80000 ); 46 | camera.position.set( -800, 700, 1600 ); 47 | 48 | // SCENE 49 | scene = new THREE.Scene(); 50 | 51 | // LIGHTS 52 | ambientLight = new THREE.AmbientLight( 0x222222 ); 53 | scene.add( ambientLight ); 54 | 55 | light = new THREE.DirectionalLight( 0xFFFFFF, 0.8 ); 56 | light.position.set( 320, 390, 700 ); 57 | scene.add( light ); 58 | 59 | light2 = new THREE.DirectionalLight( 0xFFFFFF, 0.5 ); 60 | light2.position.set( -720, -190, -300 ); 61 | scene.add( light2 ); 62 | 63 | // RENDERER 64 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 65 | renderer.setSize( canvasWidth, canvasHeight); 66 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 67 | 68 | renderer.gammaInput = true; 69 | renderer.gammaOutput = true; 70 | addToDOM(); 71 | // STATS 72 | stats = new Stats(); 73 | stats.setMode( 1 ); 74 | stats.domElement.style.position = 'absolute'; 75 | stats.domElement.style.top = '0px'; 76 | stats.domElement.style.zIndex = 100; 77 | container.appendChild( stats.domElement ); 78 | 79 | stats.domElement.children[ 0 ].children[ 0 ].style.color = "#aaa"; 80 | stats.domElement.children[ 0 ].style.background = "transparent"; 81 | stats.domElement.children[ 0 ].children[ 1 ].style.display = "none"; 82 | 83 | // CONTROLS 84 | cameraControls = new THREE.OrbitAndPanControls( camera, renderer.domElement ); 85 | cameraControls.target.set(0, 0, 0); 86 | 87 | // MATERIALS 88 | // Note: setting per pixel off does not affect the specular highlight; 89 | // it affects only whether the light direction is recalculated each pixel. 90 | var lambertMaterial = new THREE.MeshLambertMaterial( { color: 0xb00505 } ); 91 | lambertMaterial.side = THREE.DoubleSide; 92 | 93 | // to test texturing, uncomment the following four lines 94 | //var path = "/"; // STUDENT: set to "" to run on your computer, "/" for submitting code to Udacity 95 | //var texture = THREE.ImageUtils.loadTexture( path + 'textures/ash_uvgrid01.jpg' ); 96 | //texture.anisotropy = renderer.getMaxAnisotropy(); 97 | //flatGouraudMaterial = new THREE.MeshLambertMaterial( { map: texture } ); 98 | 99 | teapot = new THREE.Mesh( 100 | new THREE.TeapotGeometry( teapotSize, 8, true, true, true, true ), 101 | lambertMaterial ); 102 | 103 | scene.add( teapot ); 104 | 105 | // GUI 106 | setupGui(); 107 | } 108 | 109 | function render() { 110 | 111 | var delta = clock.getDelta(); 112 | 113 | cameraControls.update( delta ); 114 | 115 | newTime += delta; 116 | 117 | // fudge factor: 0.95 correlates closer to true frame rate numbers; 118 | // basically, there's some friction as far as timing goes, and this adjusts for it. 119 | var frameTime = 0.95/effectController.fps; 120 | if ( effectController.fps > 59.9 ) 121 | { 122 | // At 60 FPS, simply go as fast as possible; 123 | // Not doing so can force a frame time that is less than 60 FPS. 124 | frameTime = 0; 125 | } 126 | 127 | if ( newTime > oldTime + frameTime ) 128 | { 129 | oldTime = newTime; 130 | renderer.render( scene, camera ); 131 | stats.update(); 132 | } 133 | } 134 | 135 | function animate() { 136 | 137 | requestAnimationFrame( animate ); 138 | render(); 139 | 140 | } 141 | 142 | init(); 143 | animate(); 144 | -------------------------------------------------------------------------------- /lib/tween.min.js: -------------------------------------------------------------------------------- 1 | // tween.js - http://github.com/sole/tween.js 2 | 'use strict';var TWEEN=TWEEN||function(){var a=[];return{REVISION:"7",getAll:function(){return a},removeAll:function(){a=[]},add:function(c){a.push(c)},remove:function(c){c=a.indexOf(c);-1!==c&&a.splice(c,1)},update:function(c){if(0===a.length)return!1;for(var b=0,d=a.length,c=void 0!==c?c:Date.now();b(a*=2)?0.5*a*a:-0.5*(--a*(a-2)-1)}},Cubic:{In:function(a){return a*a*a},Out:function(a){return--a*a*a+1},InOut:function(a){return 1>(a*=2)?0.5*a*a*a:0.5*((a-=2)*a*a+2)}},Quartic:{In:function(a){return a*a*a*a},Out:function(a){return 1- --a*a*a*a},InOut:function(a){return 1>(a*=2)?0.5*a*a*a*a:-0.5*((a-=2)*a*a*a-2)}},Quintic:{In:function(a){return a*a*a* 7 | a*a},Out:function(a){return--a*a*a*a*a+1},InOut:function(a){return 1>(a*=2)?0.5*a*a*a*a*a:0.5*((a-=2)*a*a*a*a+2)}},Sinusoidal:{In:function(a){return 1-Math.cos(a*Math.PI/2)},Out:function(a){return Math.sin(a*Math.PI/2)},InOut:function(a){return 0.5*(1-Math.cos(Math.PI*a))}},Exponential:{In:function(a){return 0===a?0:Math.pow(1024,a-1)},Out:function(a){return 1===a?1:1-Math.pow(2,-10*a)},InOut:function(a){return 0===a?0:1===a?1:1>(a*=2)?0.5*Math.pow(1024,a-1):0.5*(-Math.pow(2,-10*(a-1))+2)}},Circular:{In:function(a){return 1- 8 | Math.sqrt(1-a*a)},Out:function(a){return Math.sqrt(1- --a*a)},InOut:function(a){return 1>(a*=2)?-0.5*(Math.sqrt(1-a*a)-1):0.5*(Math.sqrt(1-(a-=2)*a)+1)}},Elastic:{In:function(a){var c,b=0.1;if(0===a)return 0;if(1===a)return 1;!b||1>b?(b=1,c=0.1):c=0.4*Math.asin(1/b)/(2*Math.PI);return-(b*Math.pow(2,10*(a-=1))*Math.sin((a-c)*2*Math.PI/0.4))},Out:function(a){var c,b=0.1;if(0===a)return 0;if(1===a)return 1;!b||1>b?(b=1,c=0.1):c=0.4*Math.asin(1/b)/(2*Math.PI);return b*Math.pow(2,-10*a)*Math.sin((a-c)* 9 | 2*Math.PI/0.4)+1},InOut:function(a){var c,b=0.1;if(0===a)return 0;if(1===a)return 1;!b||1>b?(b=1,c=0.1):c=0.4*Math.asin(1/b)/(2*Math.PI);return 1>(a*=2)?-0.5*b*Math.pow(2,10*(a-=1))*Math.sin((a-c)*2*Math.PI/0.4):0.5*b*Math.pow(2,-10*(a-=1))*Math.sin((a-c)*2*Math.PI/0.4)+1}},Back:{In:function(a){return a*a*(2.70158*a-1.70158)},Out:function(a){return--a*a*(2.70158*a+1.70158)+1},InOut:function(a){return 1>(a*=2)?0.5*a*a*(3.5949095*a-2.5949095):0.5*((a-=2)*a*(3.5949095*a+2.5949095)+2)}},Bounce:{In:function(a){return 1- 10 | TWEEN.Easing.Bounce.Out(1-a)},Out:function(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375},InOut:function(a){return 0.5>a?0.5*TWEEN.Easing.Bounce.In(2*a):0.5*TWEEN.Easing.Bounce.Out(2*a-1)+0.5}}}; 11 | TWEEN.Interpolation={Linear:function(a,c){var b=a.length-1,d=b*c,e=Math.floor(d),f=TWEEN.Interpolation.Utils.Linear;return 0>c?f(a[0],a[1],d):1b?b:e+1],d-e)},Bezier:function(a,c){var b=0,d=a.length-1,e=Math.pow,f=TWEEN.Interpolation.Utils.Bernstein,h;for(h=0;h<=d;h++)b+=e(1-c,d-h)*e(c,h)*a[h]*f(d,h);return b},CatmullRom:function(a,c){var b=a.length-1,d=b*c,e=Math.floor(d),f=TWEEN.Interpolation.Utils.CatmullRom;return a[0]===a[b]?(0>c&&(e=Math.floor(d=b*(1+c))),f(a[(e- 12 | 1+b)%b],a[e],a[(e+1)%b],a[(e+2)%b],d-e)):0>c?a[0]-(f(a[0],a[0],a[1],a[1],-d)-a[0]):1'); 147 | } 148 | 149 | init(); 150 | setupGui(); 151 | animate(); 152 | $("body").keydown(function(event) { 153 | if (event.which === 80) { 154 | takeScreenshot(); 155 | } 156 | }); -------------------------------------------------------------------------------- /lib/sprintf.js: -------------------------------------------------------------------------------- 1 | /*! sprintf.js | Copyright (c) 2007-2013 Alexandru Marasteanu | 3 clause BSD license */ 2 | 3 | (function(ctx) { 4 | var sprintf = function() { 5 | if (!sprintf.cache.hasOwnProperty(arguments[0])) { 6 | sprintf.cache[arguments[0]] = sprintf.parse(arguments[0]); 7 | } 8 | return sprintf.format.call(null, sprintf.cache[arguments[0]], arguments); 9 | }; 10 | 11 | sprintf.format = function(parse_tree, argv) { 12 | var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; 13 | for (i = 0; i < tree_length; i++) { 14 | node_type = get_type(parse_tree[i]); 15 | if (node_type === 'string') { 16 | output.push(parse_tree[i]); 17 | } 18 | else if (node_type === 'array') { 19 | match = parse_tree[i]; // convenience purposes only 20 | if (match[2]) { // keyword argument 21 | arg = argv[cursor]; 22 | for (k = 0; k < match[2].length; k++) { 23 | if (!arg.hasOwnProperty(match[2][k])) { 24 | throw(sprintf('[sprintf] property "%s" does not exist', match[2][k])); 25 | } 26 | arg = arg[match[2][k]]; 27 | } 28 | } 29 | else if (match[1]) { // positional argument (explicit) 30 | arg = argv[match[1]]; 31 | } 32 | else { // positional argument (implicit) 33 | arg = argv[cursor++]; 34 | } 35 | 36 | if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { 37 | throw(sprintf('[sprintf] expecting number but found %s', get_type(arg))); 38 | } 39 | switch (match[8]) { 40 | case 'b': arg = arg.toString(2); break; 41 | case 'c': arg = String.fromCharCode(arg); break; 42 | case 'd': arg = parseInt(arg, 10); break; 43 | case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; 44 | case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; 45 | case 'o': arg = arg.toString(8); break; 46 | case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; 47 | case 'u': arg = arg >>> 0; break; 48 | case 'x': arg = arg.toString(16); break; 49 | case 'X': arg = arg.toString(16).toUpperCase(); break; 50 | } 51 | arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); 52 | pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; 53 | pad_length = match[6] - String(arg).length; 54 | pad = match[6] ? str_repeat(pad_character, pad_length) : ''; 55 | output.push(match[5] ? arg + pad : pad + arg); 56 | } 57 | } 58 | return output.join(''); 59 | }; 60 | 61 | sprintf.cache = {}; 62 | 63 | sprintf.parse = function(fmt) { 64 | var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; 65 | while (_fmt) { 66 | if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { 67 | parse_tree.push(match[0]); 68 | } 69 | else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { 70 | parse_tree.push('%'); 71 | } 72 | else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { 73 | if (match[2]) { 74 | arg_names |= 1; 75 | var field_list = [], replacement_field = match[2], field_match = []; 76 | if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { 77 | field_list.push(field_match[1]); 78 | while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { 79 | if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { 80 | field_list.push(field_match[1]); 81 | } 82 | else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { 83 | field_list.push(field_match[1]); 84 | } 85 | else { 86 | throw('[sprintf] huh?'); 87 | } 88 | } 89 | } 90 | else { 91 | throw('[sprintf] huh?'); 92 | } 93 | match[2] = field_list; 94 | } 95 | else { 96 | arg_names |= 2; 97 | } 98 | if (arg_names === 3) { 99 | throw('[sprintf] mixing positional and named placeholders is not (yet) supported'); 100 | } 101 | parse_tree.push(match); 102 | } 103 | else { 104 | throw('[sprintf] huh?'); 105 | } 106 | _fmt = _fmt.substring(match[0].length); 107 | } 108 | return parse_tree; 109 | }; 110 | 111 | var vsprintf = function(fmt, argv, _argv) { 112 | _argv = argv.slice(0); 113 | _argv.splice(0, 0, fmt); 114 | return sprintf.apply(null, _argv); 115 | }; 116 | 117 | /** 118 | * helpers 119 | */ 120 | function get_type(variable) { 121 | return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); 122 | } 123 | 124 | function str_repeat(input, multiplier) { 125 | for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */} 126 | return output.join(''); 127 | } 128 | 129 | /** 130 | * export to either browser or node.js 131 | */ 132 | ctx.sprintf = sprintf; 133 | ctx.vsprintf = vsprintf; 134 | })(typeof exports != "undefined" ? exports : window); -------------------------------------------------------------------------------- /demo/unit3-blending.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Blending demo 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, Coordinates, $, document, window, dat*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls, effectController; 9 | var clock = new THREE.Clock(); 10 | var gridX = true; 11 | var gridY = false; 12 | var gridZ = false; 13 | var axes = false; 14 | var ground = true; 15 | var faceMaterial; 16 | 17 | function fillScene() { 18 | scene = new THREE.Scene(); 19 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 20 | 21 | // LIGHTS 22 | var ambientLight = new THREE.AmbientLight( 0x222222 ); 23 | 24 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 25 | light.position.set( 200, 400, 500 ); 26 | 27 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 28 | light2.position.set( -500, 250, -200 ); 29 | 30 | scene.add(ambientLight); 31 | scene.add(light); 32 | scene.add(light2); 33 | 34 | if (ground) { 35 | Coordinates.drawGround({size:10000, color:0xF8E7BE}); 36 | } 37 | if (gridX) { 38 | Coordinates.drawGrid({size:10000,scale:0.01}); 39 | } 40 | if (gridY) { 41 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); 42 | } 43 | if (gridZ) { 44 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); 45 | } 46 | if (axes) { 47 | Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50}); 48 | } 49 | 50 | faceMaterial = new THREE.MeshLambertMaterial( { color: 0x0087E6, opacity: 0.7, transparent: true } ); 51 | 52 | // block 53 | var cube = new THREE.Mesh( 54 | new THREE.CubeGeometry( 150, 80, 100 ), faceMaterial ); 55 | cube.position.y = 40; 56 | scene.add( cube ); 57 | 58 | var cylinder = new THREE.Mesh( 59 | new THREE.CylinderGeometry( 0, 80, 130, 32 ), faceMaterial ); 60 | cylinder.position.x = 40; 61 | cylinder.position.y = 65; 62 | cylinder.position.z = 180; 63 | scene.add( cylinder ); 64 | 65 | var sphere = new THREE.Mesh( 66 | new THREE.SphereGeometry( 70, 32, 16 ), faceMaterial ); 67 | sphere.position.x = -30; 68 | sphere.position.y = 70; 69 | sphere.position.z = -180; 70 | scene.add( sphere ); 71 | } 72 | 73 | function init() { 74 | var canvasWidth = window.innerWidth; 75 | var canvasHeight = window.innerHeight; 76 | var canvasRatio = canvasWidth / canvasHeight; 77 | 78 | // RENDERER 79 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 80 | renderer.gammaInput = true; 81 | renderer.gammaOutput = true; 82 | renderer.setSize(canvasWidth, canvasHeight); 83 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 84 | 85 | var container = document.getElementById('container'); 86 | container.appendChild( renderer.domElement ); 87 | 88 | // CAMERA 89 | camera = new THREE.PerspectiveCamera( 30, canvasRatio, 1, 10000 ); 90 | camera.position.set( -420, 400, 100 ); 91 | 92 | // CONTROLS 93 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 94 | cameraControls.target.set(0,100,0); 95 | 96 | fillScene(); 97 | 98 | } 99 | 100 | function animate() { 101 | window.requestAnimationFrame(animate); 102 | render(); 103 | } 104 | 105 | function render() { 106 | var delta = clock.getDelta(); 107 | cameraControls.update(delta); 108 | 109 | if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes) 110 | { 111 | gridX = effectController.newGridX; 112 | gridY = effectController.newGridY; 113 | gridZ = effectController.newGridZ; 114 | ground = effectController.newGround; 115 | axes = effectController.newAxes; 116 | 117 | fillScene(); 118 | } 119 | faceMaterial.opacity = effectController.alpha; 120 | renderer.render(scene, camera); 121 | } 122 | 123 | 124 | 125 | function setupGui() { 126 | 127 | effectController = { 128 | 129 | alpha: 0.7, 130 | newGridX: gridX, 131 | newGridY: gridY, 132 | newGridZ: gridZ, 133 | newGround: ground, 134 | newAxes: axes 135 | }; 136 | 137 | var gui = new dat.GUI(); 138 | gui.add( effectController, "alpha", 0.0, 1.0, 0.025).name("Alpha"); 139 | //gui.add( effectController, "newGridX").name("Show XZ grid"); 140 | //gui.add( effectController, "newGridY" ).name("Show YZ grid"); 141 | //gui.add( effectController, "newGridZ" ).name("Show XY grid"); 142 | //gui.add( effectController, "newGround" ).name("Show ground"); 143 | //gui.add( effectController, "newAxes" ).name("Show axes"); 144 | } 145 | 146 | function takeScreenshot() { 147 | effectController.newGround = true; 148 | effectController.newGridX = false; 149 | effectController.newGridY = false; 150 | effectController.newGridZ = false; 151 | effectController.newAxes = false; 152 | init(); 153 | render(); 154 | var img1 = renderer.domElement.toDataURL("image/png"); 155 | camera.position.set( 400, 500, -800 ); 156 | render(); 157 | var img2 = renderer.domElement.toDataURL("image/png"); 158 | var imgTarget = window.open('', 'For grading script'); 159 | imgTarget.document.write(''); 160 | } 161 | 162 | init(); 163 | setupGui(); 164 | animate(); 165 | $("body").keydown(function(event) { 166 | if (event.which === 80) { 167 | takeScreenshot(); 168 | } 169 | }); -------------------------------------------------------------------------------- /unit4/unit4-snowman_exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Snowman exercise: position the arms of the snowman correctly 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, Coordinates, document, window, dat, $*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls, effectController; 9 | var clock = new THREE.Clock(); 10 | var gridX = true; 11 | var gridY = false; 12 | var gridZ = false; 13 | var axes = true; 14 | var ground = true; 15 | 16 | function fillScene() { 17 | scene = new THREE.Scene(); 18 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 19 | 20 | // LIGHTS 21 | var ambientLight = new THREE.AmbientLight( 0x222222 ); 22 | 23 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 24 | light.position.set( 200, 400, 500 ); 25 | 26 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 27 | light2.position.set( -500, 250, -200 ); 28 | 29 | scene.add(ambientLight); 30 | scene.add(light); 31 | scene.add(light2); 32 | 33 | var snowMaterial = new THREE.MeshLambertMaterial( { color: 0xFFFFFF } ); 34 | var woodMaterial = new THREE.MeshLambertMaterial( { color: 0x75691B } ); 35 | 36 | var sphere = new THREE.Mesh( 37 | new THREE.SphereGeometry( 20, 32, 16 ), snowMaterial ); 38 | sphere.position.y = 20; 39 | scene.add( sphere ); 40 | 41 | sphere = new THREE.Mesh( 42 | new THREE.SphereGeometry( 15, 32, 16 ), snowMaterial ); 43 | sphere.position.y = 50; 44 | scene.add( sphere ); 45 | 46 | sphere = new THREE.Mesh( 47 | new THREE.SphereGeometry( 10, 32, 16 ), snowMaterial ); 48 | sphere.position.y = 70; 49 | scene.add( sphere ); 50 | 51 | var cylinder = new THREE.Mesh( 52 | new THREE.CylinderGeometry( 2, 2, 60, 32 ), woodMaterial ); 53 | 54 | // YOUR CHANGES HERE 55 | // These positions are given just so you can see the stick. 56 | // You will need to reposition, etc. 57 | cylinder.position.x = -20; 58 | cylinder.position.y = 30; 59 | cylinder.position.z = -55; 60 | 61 | scene.add( cylinder ); 62 | } 63 | 64 | function init() { 65 | var canvasWidth = 846; 66 | var canvasHeight = 494; 67 | // For grading the window is fixed in size; here's general code: 68 | //var canvasWidth = window.innerWidth; 69 | //var canvasHeight = window.innerHeight; 70 | var canvasRatio = canvasWidth / canvasHeight; 71 | 72 | // RENDERER 73 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 74 | renderer.gammaInput = true; 75 | renderer.gammaOutput = true; 76 | renderer.setSize(canvasWidth, canvasHeight); 77 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 78 | 79 | var container = document.getElementById('container'); 80 | container.appendChild( renderer.domElement ); 81 | 82 | // CAMERA 83 | camera = new THREE.PerspectiveCamera( 30, canvasRatio, 1, 10000 ); 84 | //camera.position.set( -170, 170, 40 ); 85 | // CONTROLS 86 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 87 | //cameraControls.target.set(0,50,0); 88 | camera.position.set(-120, 66, 23); 89 | cameraControls.target.set(0, 43, -8); 90 | 91 | } 92 | 93 | function addToDOM() { 94 | var container = document.getElementById('container'); 95 | var canvas = container.getElementsByTagName('canvas'); 96 | if (canvas.length>0) { 97 | container.removeChild(canvas[0]); 98 | } 99 | container.appendChild( renderer.domElement ); 100 | } 101 | 102 | function animate() { 103 | window.requestAnimationFrame(animate); 104 | render(); 105 | } 106 | 107 | function render() { 108 | var delta = clock.getDelta(); 109 | cameraControls.update(delta); 110 | 111 | if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes) 112 | { 113 | gridX = effectController.newGridX; 114 | gridY = effectController.newGridY; 115 | gridZ = effectController.newGridZ; 116 | ground = effectController.newGround; 117 | axes = effectController.newAxes; 118 | 119 | fillScene(); 120 | drawHelpers(); 121 | } 122 | renderer.render(scene, camera); 123 | } 124 | 125 | function drawHelpers() { 126 | if (ground) { 127 | Coordinates.drawGround({size:10000}); 128 | } 129 | if (gridX) { 130 | Coordinates.drawGrid({size:10000,scale:0.01}); 131 | } 132 | if (gridY) { 133 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); 134 | } 135 | if (gridZ) { 136 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); 137 | } 138 | if (axes) { 139 | Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50}); 140 | } 141 | } 142 | 143 | function setupGui() { 144 | 145 | effectController = { 146 | 147 | newGridX: gridX, 148 | newGridY: gridY, 149 | newGridZ: gridZ, 150 | newGround: ground, 151 | newAxes: axes 152 | }; 153 | 154 | var gui = new dat.GUI(); 155 | gui.add( effectController, "newGridX").name("Show XZ grid"); 156 | gui.add( effectController, "newGridY" ).name("Show YZ grid"); 157 | gui.add( effectController, "newGridZ" ).name("Show XY grid"); 158 | gui.add( effectController, "newGround" ).name("Show ground"); 159 | gui.add( effectController, "newAxes" ).name("Show axes"); 160 | } 161 | 162 | try { 163 | init(); 164 | fillScene(); 165 | setupGui(); 166 | drawHelpers(); 167 | addToDOM(); 168 | animate(); 169 | } catch(e) { 170 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 171 | $('#container').append(errorReport+e); 172 | } 173 | -------------------------------------------------------------------------------- /unit4/unit4-flower_exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Flower exercise: make a flower 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, Coordinates, document, window, dat, $*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls, effectController; 9 | var clock = new THREE.Clock(); 10 | var gridX = true; 11 | var gridY = false; 12 | var gridZ = false; 13 | var axes = true; 14 | var ground = true; 15 | 16 | function fillScene() { 17 | scene = new THREE.Scene(); 18 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 19 | 20 | // LIGHTS 21 | var ambientLight = new THREE.AmbientLight( 0x222222 ); 22 | 23 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 24 | light.position.set( 200, 400, 500 ); 25 | 26 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 27 | light2.position.set( -500, 250, -200 ); 28 | 29 | scene.add(ambientLight); 30 | scene.add(light); 31 | scene.add(light2); 32 | 33 | // FLOWER 34 | var petalMaterial = new THREE.MeshLambertMaterial( { color: 0xCC5920 } ); 35 | var flowerHeight = 200; 36 | var petalLength = 120; 37 | var cylGeom = new THREE.CylinderGeometry( 15, 0, petalLength, 32 ); 38 | var flower = new THREE.Object3D(); 39 | 40 | ///////// 41 | // YOUR CODE HERE 42 | // add code here to make 24 petals, radiating around the sphere 43 | // Just rotates and positions on the cylinder and petals are needed. 44 | var cylinder = new THREE.Mesh( cylGeom, petalMaterial ); 45 | var petal = new THREE.Object3D(); 46 | petal.add( cylinder ); 47 | 48 | flower.add( petal ); 49 | 50 | // Rest of the flower 51 | var stamenMaterial = new THREE.MeshLambertMaterial( { color: 0x333310 } ); 52 | var stamen = new THREE.Mesh( 53 | new THREE.SphereGeometry( 20, 32, 16 ), stamenMaterial ); 54 | stamen.position.y = flowerHeight; // move to flower center 55 | flower.add( stamen ); 56 | 57 | var stemMaterial = new THREE.MeshLambertMaterial( { color: 0x339424 } ); 58 | var stem = new THREE.Mesh( 59 | new THREE.CylinderGeometry( 10, 10, flowerHeight, 32 ), stemMaterial ); 60 | stem.position.y = flowerHeight/2; // move from ground to stamen 61 | flower.add( stem ); 62 | 63 | scene.add( flower ); 64 | 65 | } 66 | 67 | 68 | function init() { 69 | var canvasWidth = 846; 70 | var canvasHeight = 494; 71 | // For grading the window is fixed in size; here's general code: 72 | //var canvasWidth = window.innerWidth; 73 | //var canvasHeight = window.innerHeight; 74 | var canvasRatio = canvasWidth / canvasHeight; 75 | 76 | // RENDERER 77 | renderer = new THREE.WebGLRenderer( { antialias: false } ); 78 | renderer.gammaInput = true; 79 | renderer.gammaOutput = true; 80 | renderer.setSize(canvasWidth, canvasHeight); 81 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 82 | 83 | // CAMERA 84 | camera = new THREE.PerspectiveCamera( 38, canvasRatio, 1, 10000 ); 85 | // CONTROLS 86 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 87 | camera.position.set(-200, 400, 20); 88 | cameraControls.target.set(0,150,0); 89 | fillScene(); 90 | 91 | } 92 | 93 | function addToDOM() { 94 | var container = document.getElementById('container'); 95 | var canvas = container.getElementsByTagName('canvas'); 96 | if (canvas.length>0) { 97 | container.removeChild(canvas[0]); 98 | } 99 | container.appendChild( renderer.domElement ); 100 | } 101 | 102 | function drawHelpers() { 103 | if (ground) { 104 | Coordinates.drawGround({size:10000}); 105 | } 106 | if (gridX) { 107 | Coordinates.drawGrid({size:10000,scale:0.01}); 108 | } 109 | if (gridY) { 110 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); 111 | } 112 | if (gridZ) { 113 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); 114 | } 115 | if (axes) { 116 | Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50}); 117 | } 118 | } 119 | 120 | function animate() { 121 | window.requestAnimationFrame(animate); 122 | render(); 123 | } 124 | 125 | function render() { 126 | var delta = clock.getDelta(); 127 | cameraControls.update(delta); 128 | 129 | if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes) 130 | { 131 | gridX = effectController.newGridX; 132 | gridY = effectController.newGridY; 133 | gridZ = effectController.newGridZ; 134 | ground = effectController.newGround; 135 | axes = effectController.newAxes; 136 | 137 | fillScene(); 138 | drawHelpers(); 139 | } 140 | 141 | renderer.render(scene, camera); 142 | } 143 | 144 | 145 | 146 | function setupGui() { 147 | 148 | effectController = { 149 | 150 | newGridX: gridX, 151 | newGridY: gridY, 152 | newGridZ: gridZ, 153 | newGround: ground, 154 | newAxes: axes 155 | 156 | }; 157 | 158 | var gui = new dat.GUI(); 159 | var h = gui.addFolder("Grid display"); 160 | h.add( effectController, "newGridX").name("Show XZ grid"); 161 | h.add( effectController, "newGridY" ).name("Show YZ grid"); 162 | h.add( effectController, "newGridZ" ).name("Show XY grid"); 163 | h.add( effectController, "newGround" ).name("Show ground"); 164 | h.add( effectController, "newAxes" ).name("Show axes"); 165 | 166 | } 167 | 168 | 169 | // this is the main action sequence 170 | try { 171 | init(); 172 | fillScene(); 173 | drawHelpers(); 174 | addToDOM(); 175 | setupGui(); 176 | animate(); 177 | } catch(e) { 178 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 179 | $('#container').append(errorReport+e); 180 | } 181 | -------------------------------------------------------------------------------- /unit4/unit4-rotation_exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Clock hand rotation: rotate the hand into the proper orientation 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, Coordinates, document, window, dat, $*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls, effectController; 9 | var clock = new THREE.Clock(); 10 | var gridX = false; 11 | var gridY = false; 12 | var gridZ = false; 13 | var axes = true; 14 | var ground = true; 15 | 16 | function fillScene() { 17 | scene = new THREE.Scene(); 18 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 19 | 20 | // LIGHTS 21 | var ambientLight = new THREE.AmbientLight( 0x222222 ); 22 | 23 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 24 | light.position.set( 200, 400, 500 ); 25 | 26 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 27 | light2.position.set( -500, 250, -200 ); 28 | 29 | scene.add(ambientLight); 30 | scene.add(light); 31 | scene.add(light2); 32 | 33 | var faceMaterial = new THREE.MeshLambertMaterial( { color: 0xFFECA9 } ); 34 | var markMaterial = new THREE.MeshLambertMaterial( { color: 0x89581F } ); 35 | var mark12Material = new THREE.MeshLambertMaterial( { color: 0xE6880E } ); 36 | var handMaterial = new THREE.MeshLambertMaterial( { color: 0x226894 } ); 37 | 38 | // clock 39 | var clock = new THREE.Mesh( 40 | new THREE.CylinderGeometry( 75, 75, 10, 32 ), faceMaterial ); 41 | //new THREE.CubeGeometry( 150, 5, 150 ), faceMaterial ); 42 | clock.position.y = 5; 43 | scene.add( clock ); 44 | 45 | // marks 46 | var cube = new THREE.Mesh( 47 | new THREE.CubeGeometry( 20, 4, 15 ), mark12Material ); 48 | cube.position.x = 60; 49 | cube.position.y = 9; 50 | scene.add( cube ); 51 | 52 | cube = new THREE.Mesh( 53 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 54 | cube.position.x = -60; 55 | cube.position.y = 9; 56 | scene.add( cube ); 57 | 58 | cube = new THREE.Mesh( 59 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 60 | cube.position.z = 60; 61 | cube.position.y = 9; 62 | scene.add( cube ); 63 | 64 | cube = new THREE.Mesh( 65 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 66 | cube.position.z = -60; 67 | cube.position.y = 9; 68 | scene.add( cube ); 69 | 70 | // CODE FOR THE CLOCK HAND 71 | cube = new THREE.Mesh( 72 | new THREE.CubeGeometry( 110, 4, 4 ), handMaterial ); 73 | cube.position.y = 14; 74 | 75 | // YOUR CODE HERE 76 | 77 | scene.add( cube ); 78 | } 79 | 80 | function drawHelpers() { 81 | if (ground) { 82 | Coordinates.drawGround({size:10000}); 83 | } 84 | if (gridX) { 85 | Coordinates.drawGrid({size:10000,scale:0.01}); 86 | } 87 | if (gridY) { 88 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); 89 | } 90 | if (gridZ) { 91 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); 92 | } 93 | if (axes) { 94 | Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50}); 95 | } 96 | } 97 | 98 | 99 | function init() { 100 | var canvasWidth = 846; 101 | var canvasHeight = 494; 102 | // For grading the window is fixed in size; here's general code: 103 | //var canvasWidth = window.innerWidth; 104 | //var canvasHeight = window.innerHeight; 105 | var canvasRatio = canvasWidth / canvasHeight; 106 | 107 | // RENDERER 108 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 109 | renderer.gammaInput = true; 110 | renderer.gammaOutput = true; 111 | renderer.setSize(canvasWidth, canvasHeight); 112 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 113 | 114 | // CAMERA 115 | camera = new THREE.PerspectiveCamera( 30, canvasRatio, 1, 10000 ); 116 | camera.position.set( -370, 420, 190 ); 117 | // CONTROLS 118 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 119 | cameraControls.target.set(0,0,0); 120 | 121 | fillScene(); 122 | 123 | } 124 | 125 | function addToDOM() { 126 | var container = document.getElementById('container'); 127 | var canvas = container.getElementsByTagName('canvas'); 128 | if (canvas.length>0) { 129 | container.removeChild(canvas[0]); 130 | } 131 | container.appendChild( renderer.domElement ); 132 | } 133 | 134 | function animate() { 135 | window.requestAnimationFrame(animate); 136 | render(); 137 | } 138 | 139 | function render() { 140 | var delta = clock.getDelta(); 141 | cameraControls.update(delta); 142 | 143 | if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes) 144 | { 145 | gridX = effectController.newGridX; 146 | gridY = effectController.newGridY; 147 | gridZ = effectController.newGridZ; 148 | ground = effectController.newGround; 149 | axes = effectController.newAxes; 150 | 151 | fillScene(); 152 | drawHelpers(); 153 | } 154 | renderer.render(scene, camera); 155 | } 156 | 157 | function setupGui() { 158 | 159 | effectController = { 160 | 161 | newGridX: gridX, 162 | newGridY: gridY, 163 | newGridZ: gridZ, 164 | newGround: ground, 165 | newAxes: axes 166 | }; 167 | 168 | var gui = new dat.GUI(); 169 | gui.add( effectController, "newGridX").name("Show XZ grid"); 170 | gui.add( effectController, "newGridY" ).name("Show YZ grid"); 171 | gui.add( effectController, "newGridZ" ).name("Show XY grid"); 172 | gui.add( effectController, "newGround" ).name("Show ground"); 173 | gui.add( effectController, "newAxes" ).name("Show axes"); 174 | } 175 | 176 | 177 | try { 178 | init(); 179 | setupGui(); 180 | drawHelpers(); 181 | addToDOM(); 182 | animate(); 183 | } catch(e) { 184 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 185 | $('#container').append(errorReport+e); 186 | } 187 | 188 | -------------------------------------------------------------------------------- /unit4/unit4-flowersquish_exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Flower petal improvement: scale and re-orient the petals to look better 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, Coordinates, document, window, dat, $*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls, effectController; 9 | var clock = new THREE.Clock(); 10 | var gridX = true; 11 | var gridY = false; 12 | var gridZ = false; 13 | var axes = true; 14 | var ground = true; 15 | 16 | function fillScene() { 17 | scene = new THREE.Scene(); 18 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 19 | 20 | // LIGHTS 21 | var ambientLight = new THREE.AmbientLight( 0x222222 ); 22 | 23 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 24 | light.position.set( 200, 400, 500 ); 25 | 26 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 27 | light2.position.set( -500, 250, -200 ); 28 | 29 | scene.add(ambientLight); 30 | scene.add(light); 31 | scene.add(light2); 32 | 33 | // FLOWER 34 | var petalMaterial = new THREE.MeshLambertMaterial( { color: 0xCC5920 } ); 35 | var flowerHeight = 200; 36 | var petalLength = 120; 37 | var cylGeom = new THREE.CylinderGeometry( 15, 0, petalLength, 32 ); 38 | var flower = new THREE.Object3D(); 39 | 40 | ///////// 41 | // YOUR CODE HERE 42 | // add code here to make 24 petals, radiating around the sphere 43 | // Scales, rotates, and positions on the cylinder and petals are needed. 44 | // The petals should be squished and be 1/4 as thick as wide 45 | // and they should be tilted 20 degrees up from the position in the previous exercise 46 | 47 | var cylinder = new THREE.Mesh( cylGeom, petalMaterial ); 48 | var petal = new THREE.Object3D(); 49 | petal.add( cylinder ); 50 | 51 | flower.add( petal ); 52 | 53 | // Rest of the flower 54 | var stamenMaterial = new THREE.MeshLambertMaterial( { color: 0x333310 } ); 55 | var stamen = new THREE.Mesh( 56 | new THREE.SphereGeometry( 20, 32, 16 ), stamenMaterial ); 57 | stamen.position.y = flowerHeight; // move to flower center 58 | flower.add( stamen ); 59 | 60 | var stemMaterial = new THREE.MeshLambertMaterial( { color: 0x339424 } ); 61 | var stem = new THREE.Mesh( 62 | new THREE.CylinderGeometry( 10, 10, flowerHeight, 32 ), stemMaterial ); 63 | stem.position.y = flowerHeight/2; // move from ground to stamen 64 | flower.add( stem ); 65 | 66 | scene.add( flower ); 67 | 68 | } 69 | 70 | 71 | function init() { 72 | var canvasWidth = 846; 73 | var canvasHeight = 494; 74 | // For grading the window is fixed in size; here's general code: 75 | //var canvasWidth = window.innerWidth; 76 | //var canvasHeight = window.innerHeight; 77 | var canvasRatio = canvasWidth / canvasHeight; 78 | 79 | // RENDERER 80 | renderer = new THREE.WebGLRenderer( { antialias: false } ); 81 | renderer.gammaInput = true; 82 | renderer.gammaOutput = true; 83 | renderer.setSize(canvasWidth, canvasHeight); 84 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 85 | 86 | // CAMERA 87 | camera = new THREE.PerspectiveCamera( 38, canvasRatio, 1, 10000 ); 88 | // CONTROLS 89 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 90 | camera.position.set(-20, 300, 219); 91 | cameraControls.target.set(13, 152, -159); 92 | fillScene(); 93 | 94 | } 95 | 96 | function addToDOM() { 97 | var container = document.getElementById('container'); 98 | var canvas = container.getElementsByTagName('canvas'); 99 | if (canvas.length>0) { 100 | container.removeChild(canvas[0]); 101 | } 102 | container.appendChild( renderer.domElement ); 103 | } 104 | 105 | function drawHelpers() { 106 | if (ground) { 107 | Coordinates.drawGround({size:10000}); 108 | } 109 | if (gridX) { 110 | Coordinates.drawGrid({size:10000,scale:0.01}); 111 | } 112 | if (gridY) { 113 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); 114 | } 115 | if (gridZ) { 116 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); 117 | } 118 | if (axes) { 119 | Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50}); 120 | } 121 | } 122 | 123 | function animate() { 124 | window.requestAnimationFrame(animate); 125 | render(); 126 | } 127 | 128 | function render() { 129 | var delta = clock.getDelta(); 130 | cameraControls.update(delta); 131 | 132 | if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes) 133 | { 134 | gridX = effectController.newGridX; 135 | gridY = effectController.newGridY; 136 | gridZ = effectController.newGridZ; 137 | ground = effectController.newGround; 138 | axes = effectController.newAxes; 139 | 140 | fillScene(); 141 | drawHelpers(); 142 | } 143 | 144 | renderer.render(scene, camera); 145 | } 146 | 147 | 148 | 149 | function setupGui() { 150 | 151 | effectController = { 152 | 153 | newGridX: gridX, 154 | newGridY: gridY, 155 | newGridZ: gridZ, 156 | newGround: ground, 157 | newAxes: axes 158 | 159 | }; 160 | 161 | var gui = new dat.GUI(); 162 | var h = gui.addFolder("Grid display"); 163 | h.add( effectController, "newGridX").name("Show XZ grid"); 164 | h.add( effectController, "newGridY" ).name("Show YZ grid"); 165 | h.add( effectController, "newGridZ" ).name("Show XY grid"); 166 | h.add( effectController, "newGround" ).name("Show ground"); 167 | h.add( effectController, "newAxes" ).name("Show axes"); 168 | 169 | } 170 | 171 | 172 | // this is the main action sequence 173 | try { 174 | init(); 175 | fillScene(); 176 | drawHelpers(); 177 | addToDOM(); 178 | setupGui(); 179 | animate(); 180 | } catch(e) { 181 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 182 | $('#container').append(errorReport+e); 183 | } 184 | -------------------------------------------------------------------------------- /lib/Coordinates.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | /*global THREE, scene*/ 3 | var Coordinates = { 4 | drawGrid:function(params) { 5 | params = params || {}; 6 | var size = params.size !== undefined ? params.size:100; 7 | var scale = params.scale !== undefined ? params.scale:0.1; 8 | var orientation = params.orientation !== undefined ? params.orientation:"x"; 9 | var grid = new THREE.Mesh( 10 | new THREE.PlaneGeometry(size, size, size * scale, size * scale), 11 | new THREE.MeshBasicMaterial({ color: 0x555555, wireframe: true }) 12 | ); 13 | // Yes, these are poorly labeled! It would be a mess to fix. 14 | // What's really going on here: 15 | // "x" means "rotate 90 degrees around x", etc. 16 | // So "x" really means "show a grid with a normal of Y" 17 | // "y" means "show a grid with a normal of X" 18 | // "z" means (logically enough) "show a grid with a normal of Z" 19 | if (orientation === "x") { 20 | grid.rotation.x = - Math.PI / 2; 21 | } else if (orientation === "y") { 22 | grid.rotation.y = - Math.PI / 2; 23 | } else if (orientation === "z") { 24 | grid.rotation.z = - Math.PI / 2; 25 | } 26 | 27 | scene.add(grid); 28 | }, 29 | drawGround:function(params) { 30 | params = params || {}; 31 | var size = params.size !== undefined ? params.size:100; 32 | var color = params.color !== undefined ? params.color:0xFFFFFF; 33 | var ground = new THREE.Mesh( 34 | new THREE.PlaneGeometry(size, size), 35 | // When we use a ground plane we use directional lights, so illuminating 36 | // just the corners is sufficient. 37 | // Use MeshPhongMaterial if you want to capture per-pixel lighting: 38 | // new THREE.MeshPhongMaterial({ color: color, specular: 0x000000, 39 | new THREE.MeshLambertMaterial({ color: color, 40 | // polygonOffset moves the plane back from the eye a bit, so that the lines on top of 41 | // the grid do not have z-fighting with the grid: 42 | // Factor == 1 moves it back relative to the slope (more on-edge means move back farther) 43 | // Units == 4 is a fixed amount to move back, and 4 is usually a good value 44 | polygonOffset: true, polygonOffsetFactor: 1.0, polygonOffsetUnits: 4.0 45 | })); 46 | ground.rotation.x = - Math.PI / 2; 47 | scene.add(ground); 48 | }, 49 | drawAxes:function(params) { 50 | // x = red, y = green, z = blue (RGB = xyz) 51 | params = params || {}; 52 | var axisRadius = params.axisRadius !== undefined ? params.axisRadius:0.04; 53 | var axisLength = params.axisLength !== undefined ? params.axisLength:11; 54 | var axisTess = params.axisTess !== undefined ? params.axisTess:48; 55 | var axisOrientation = params.axisOrientation !== undefined ? params.axisOrientation:"x"; 56 | 57 | var axisMaterial = new THREE.MeshLambertMaterial({ color: 0x000000, side: THREE.DoubleSide }); 58 | var axis = new THREE.Mesh( 59 | new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true), 60 | axisMaterial 61 | ); 62 | if (axisOrientation === "x") { 63 | axis.rotation.z = - Math.PI / 2; 64 | axis.position.x = axisLength/2-1; 65 | } else if (axisOrientation === "y") { 66 | axis.position.y = axisLength/2-1; 67 | } 68 | 69 | scene.add( axis ); 70 | 71 | var arrow = new THREE.Mesh( 72 | new THREE.CylinderGeometry(0, 4*axisRadius, 8*axisRadius, axisTess, 1, true), 73 | axisMaterial 74 | ); 75 | if (axisOrientation === "x") { 76 | arrow.rotation.z = - Math.PI / 2; 77 | arrow.position.x = axisLength - 1 + axisRadius*4/2; 78 | } else if (axisOrientation === "y") { 79 | arrow.position.y = axisLength - 1 + axisRadius*4/2; 80 | } 81 | 82 | scene.add( arrow ); 83 | 84 | }, 85 | drawAllAxes:function(params) { 86 | params = params || {}; 87 | var axisRadius = params.axisRadius !== undefined ? params.axisRadius:0.04; 88 | var axisLength = params.axisLength !== undefined ? params.axisLength:11; 89 | var axisTess = params.axisTess !== undefined ? params.axisTess:48; 90 | 91 | var axisXMaterial = new THREE.MeshLambertMaterial({ color: 0xFF0000 }); 92 | var axisYMaterial = new THREE.MeshLambertMaterial({ color: 0x00FF00 }); 93 | var axisZMaterial = new THREE.MeshLambertMaterial({ color: 0x0000FF }); 94 | axisXMaterial.side = THREE.DoubleSide; 95 | axisYMaterial.side = THREE.DoubleSide; 96 | axisZMaterial.side = THREE.DoubleSide; 97 | var axisX = new THREE.Mesh( 98 | new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true), 99 | axisXMaterial 100 | ); 101 | var axisY = new THREE.Mesh( 102 | new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true), 103 | axisYMaterial 104 | ); 105 | var axisZ = new THREE.Mesh( 106 | new THREE.CylinderGeometry(axisRadius, axisRadius, axisLength, axisTess, 1, true), 107 | axisZMaterial 108 | ); 109 | axisX.rotation.z = - Math.PI / 2; 110 | axisX.position.x = axisLength/2-1; 111 | 112 | axisY.position.y = axisLength/2-1; 113 | 114 | axisZ.rotation.y = - Math.PI / 2; 115 | axisZ.rotation.z = - Math.PI / 2; 116 | axisZ.position.z = axisLength/2-1; 117 | 118 | scene.add( axisX ); 119 | scene.add( axisY ); 120 | scene.add( axisZ ); 121 | 122 | var arrowX = new THREE.Mesh( 123 | new THREE.CylinderGeometry(0, 4*axisRadius, 4*axisRadius, axisTess, 1, true), 124 | axisXMaterial 125 | ); 126 | var arrowY = new THREE.Mesh( 127 | new THREE.CylinderGeometry(0, 4*axisRadius, 4*axisRadius, axisTess, 1, true), 128 | axisYMaterial 129 | ); 130 | var arrowZ = new THREE.Mesh( 131 | new THREE.CylinderGeometry(0, 4*axisRadius, 4*axisRadius, axisTess, 1, true), 132 | axisZMaterial 133 | ); 134 | arrowX.rotation.z = - Math.PI / 2; 135 | arrowX.position.x = axisLength - 1 + axisRadius*4/2; 136 | 137 | arrowY.position.y = axisLength - 1 + axisRadius*4/2; 138 | 139 | arrowZ.rotation.z = - Math.PI / 2; 140 | arrowZ.rotation.y = - Math.PI / 2; 141 | arrowZ.position.z = axisLength - 1 + axisRadius*4/2; 142 | 143 | scene.add( arrowX ); 144 | scene.add( arrowY ); 145 | scene.add( arrowZ ); 146 | 147 | } 148 | 149 | }; -------------------------------------------------------------------------------- /unit5/unit5-axis_angle_exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Ornament axis/angle exercise: add three more cylinders to the ornament 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, Coordinates, document, window, dat*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls, effectController; 9 | var clock = new THREE.Clock(); 10 | var bCube = true; 11 | var gridX = false; 12 | var gridY = false; 13 | var gridZ = false; 14 | var axes = true; 15 | var ground = false; 16 | 17 | function fillScene() { 18 | scene = new THREE.Scene(); 19 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 20 | 21 | // LIGHTS 22 | var ambientLight = new THREE.AmbientLight( 0x222222 ); 23 | 24 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 25 | light.position.set( 200, 400, 500 ); 26 | 27 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 28 | light2.position.set( -500, 250, -200 ); 29 | 30 | scene.add(ambientLight); 31 | scene.add(light); 32 | scene.add(light2); 33 | 34 | var cylinderMaterial = new THREE.MeshPhongMaterial( { color: 0xD1F5FD, specular: 0xD1F5FD, shininess: 100 } ); 35 | 36 | // get two diagonally-opposite corners of the cube and compute the 37 | // cylinder axis direction and length 38 | var maxCorner = new THREE.Vector3( 1, 1, 1 ); 39 | var minCorner = new THREE.Vector3( -1,-1,-1 ); 40 | // note how you can chain one operation on to another: 41 | var cylAxis = new THREE.Vector3().subVectors( maxCorner, minCorner ); 42 | var cylLength = cylAxis.length(); 43 | 44 | // take dot product of cylAxis and up vector to get cosine of angle 45 | cylAxis.normalize(); 46 | var theta = Math.acos( cylAxis.dot( new THREE.Vector3(0,1,0) ) ); 47 | // or just simply theta = Math.acos( cylAxis.y ); 48 | 49 | // YOUR CODE HERE 50 | var cylinder = new THREE.Mesh( 51 | new THREE.CylinderGeometry( 0.2, 0.2, cylLength, 32 ), cylinderMaterial ); 52 | var rotationAxis = new THREE.Vector3(1,0,-1); 53 | // makeRotationAxis wants its axis normalized 54 | rotationAxis.normalize(); 55 | // don't use position, rotation, scale 56 | cylinder.matrixAutoUpdate = false; 57 | cylinder.matrix.makeRotationAxis( rotationAxis, theta ); 58 | scene.add( cylinder ); 59 | 60 | } 61 | 62 | function drawHelpers() { 63 | if (ground) { 64 | Coordinates.drawGround({size:100}); 65 | } 66 | if (gridX) { 67 | Coordinates.drawGrid({size:100,scale:1}); 68 | } 69 | if (gridY) { 70 | Coordinates.drawGrid({size:100,scale:1, orientation:"y"}); 71 | } 72 | if (gridZ) { 73 | Coordinates.drawGrid({size:100,scale:1, orientation:"z"}); 74 | } 75 | if (axes) { 76 | Coordinates.drawAllAxes({axisLength:5,axisRadius:0.01,axisTess:50}); 77 | } 78 | 79 | if (bCube) { 80 | var cubeMaterial = new THREE.MeshLambertMaterial( 81 | { color: 0xFFFFFF, opacity: 0.7, transparent: true } ); 82 | var cube = new THREE.Mesh( 83 | new THREE.CubeGeometry( 2, 2, 2 ), cubeMaterial ); 84 | scene.add( cube ); 85 | } 86 | } 87 | 88 | function init() { 89 | var canvasWidth = 846; 90 | var canvasHeight = 494; 91 | // For grading the window is fixed in size; here's general code: 92 | //var canvasWidth = window.innerWidth; 93 | //var canvasHeight = window.innerHeight; 94 | var canvasRatio = canvasWidth / canvasHeight; 95 | 96 | // RENDERER 97 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 98 | renderer.gammaInput = true; 99 | renderer.gammaOutput = true; 100 | renderer.setSize(canvasWidth, canvasHeight); 101 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 102 | 103 | var container = document.getElementById('container'); 104 | container.appendChild( renderer.domElement ); 105 | 106 | // CAMERA 107 | camera = new THREE.PerspectiveCamera( 30, canvasRatio, 1, 10000 ); 108 | // CONTROLS 109 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 110 | camera.position.set( -7, 7, 2 ); 111 | cameraControls.target.set(0,0,0); 112 | 113 | } 114 | 115 | function addToDOM() { 116 | var container = document.getElementById('container'); 117 | var canvas = container.getElementsByTagName('canvas'); 118 | if (canvas.length>0) { 119 | container.removeChild(canvas[0]); 120 | } 121 | container.appendChild( renderer.domElement ); 122 | } 123 | 124 | function animate() { 125 | window.requestAnimationFrame(animate); 126 | render(); 127 | } 128 | 129 | function render() { 130 | var delta = clock.getDelta(); 131 | cameraControls.update(delta); 132 | 133 | if ( effectController.newCube !== bCube || effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes) 134 | { 135 | bCube = effectController.newCube; 136 | gridX = effectController.newGridX; 137 | gridY = effectController.newGridY; 138 | gridZ = effectController.newGridZ; 139 | ground = effectController.newGround; 140 | axes = effectController.newAxes; 141 | 142 | fillScene(); 143 | drawHelpers(); 144 | } 145 | renderer.render(scene, camera); 146 | } 147 | 148 | 149 | 150 | function setupGui() { 151 | 152 | effectController = { 153 | 154 | newCube: bCube, 155 | newGridX: gridX, 156 | newGridY: gridY, 157 | newGridZ: gridZ, 158 | newGround: ground, 159 | newAxes: axes 160 | }; 161 | 162 | var gui = new dat.GUI(); 163 | gui.add( effectController, "newCube").name("Show cube"); 164 | gui.add( effectController, "newGridX").name("Show XZ grid"); 165 | gui.add( effectController, "newGridY" ).name("Show YZ grid"); 166 | gui.add( effectController, "newGridZ" ).name("Show XY grid"); 167 | gui.add( effectController, "newGround" ).name("Show ground"); 168 | gui.add( effectController, "newAxes" ).name("Show axes"); 169 | } 170 | 171 | try { 172 | init(); 173 | fillScene(); 174 | setupGui(); 175 | drawHelpers(); 176 | addToDOM(); 177 | animate(); 178 | } catch(e) { 179 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 180 | $('#container').append(errorReport+e); 181 | } 182 | 183 | -------------------------------------------------------------------------------- /unit4/unit4-scale_exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Scaling exercise: scale the sphere to make it look like a clock hand 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, Coordinates, document, window, dat, $*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls, effectController; 9 | var clock = new THREE.Clock(); 10 | var gridX = false; 11 | var gridY = false; 12 | var gridZ = false; 13 | var axes = true; 14 | var ground = true; 15 | 16 | function fillScene() { 17 | scene = new THREE.Scene(); 18 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 19 | 20 | // LIGHTS 21 | var ambientLight = new THREE.AmbientLight( 0x222222 ); 22 | 23 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 24 | light.position.set( 200, 400, 500 ); 25 | 26 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 27 | light2.position.set( -500, 250, -200 ); 28 | 29 | scene.add(ambientLight); 30 | scene.add(light); 31 | scene.add(light2); 32 | 33 | var faceMaterial = new THREE.MeshLambertMaterial( { color: 0xFFECA9 } ); 34 | var markMaterial = new THREE.MeshLambertMaterial( { color: 0x89581F } ); 35 | var mark12Material = new THREE.MeshLambertMaterial( { color: 0xE6880E } ); 36 | var minuteHandMaterial = new THREE.MeshLambertMaterial( { color: 0x226894 } ); 37 | var hourHandMaterial = new THREE.MeshLambertMaterial( { color: 0xE02BFB } ); 38 | 39 | // clock 40 | var clock = new THREE.Mesh( 41 | new THREE.CylinderGeometry( 75, 75, 10, 32 ), faceMaterial ); 42 | //new THREE.CubeGeometry( 150, 5, 150 ), faceMaterial ); 43 | clock.position.y = 5; 44 | scene.add( clock ); 45 | 46 | // marks 47 | var cube = new THREE.Mesh( 48 | new THREE.CubeGeometry( 20, 4, 15 ), mark12Material ); 49 | cube.position.x = 60; 50 | cube.position.y = 9; 51 | scene.add( cube ); 52 | 53 | cube = new THREE.Mesh( 54 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 55 | cube.position.x = -60; 56 | cube.position.y = 9; 57 | scene.add( cube ); 58 | 59 | cube = new THREE.Mesh( 60 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 61 | cube.position.z = 60; 62 | cube.position.y = 9; 63 | scene.add( cube ); 64 | 65 | cube = new THREE.Mesh( 66 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 67 | cube.position.z = -60; 68 | cube.position.y = 9; 69 | scene.add( cube ); 70 | 71 | cube = new THREE.Mesh( 72 | new THREE.CubeGeometry( 110, 4, 4 ), minuteHandMaterial ); 73 | cube.position.y = 14; 74 | cube.rotation.y = -60 * Math.PI/180; 75 | 76 | scene.add( cube ); 77 | 78 | var sphere = new THREE.Mesh( 79 | new THREE.SphereGeometry( 10, 32, 16 ), hourHandMaterial ); 80 | sphere.position.y = 18; // move the hand above the other hand 81 | 82 | // YOUR CODE HERE: 83 | 84 | scene.add( sphere ); 85 | } 86 | 87 | function drawHelpers() { 88 | if (ground) { 89 | Coordinates.drawGround({size:10000}); 90 | } 91 | if (gridX) { 92 | Coordinates.drawGrid({size:10000,scale:0.01}); 93 | } 94 | if (gridY) { 95 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); 96 | } 97 | if (gridZ) { 98 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); 99 | } 100 | if (axes) { 101 | Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50}); 102 | } 103 | } 104 | function init() { 105 | var canvasWidth = 846; 106 | var canvasHeight = 494; 107 | // For grading the window is fixed in size; here's general code: 108 | //var canvasWidth = window.innerWidth; 109 | //var canvasHeight = window.innerHeight; 110 | var canvasRatio = canvasWidth / canvasHeight; 111 | 112 | // RENDERER 113 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 114 | renderer.gammaInput = true; 115 | renderer.gammaOutput = true; 116 | renderer.setSize(canvasWidth, canvasHeight); 117 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 118 | 119 | // CAMERA 120 | camera = new THREE.PerspectiveCamera( 30, canvasRatio, 1, 10000 ); 121 | camera.position.set( -420, 400, 100 ); 122 | // CONTROLS 123 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 124 | cameraControls.target.set(0,0,0); 125 | 126 | fillScene(); 127 | 128 | } 129 | 130 | function addToDOM() { 131 | var container = document.getElementById('container'); 132 | var canvas = container.getElementsByTagName('canvas'); 133 | if (canvas.length>0) { 134 | container.removeChild(canvas[0]); 135 | } 136 | container.appendChild( renderer.domElement ); 137 | } 138 | 139 | function animate() { 140 | window.requestAnimationFrame(animate); 141 | render(); 142 | } 143 | 144 | function render() { 145 | var delta = clock.getDelta(); 146 | cameraControls.update(delta); 147 | 148 | if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes) 149 | { 150 | gridX = effectController.newGridX; 151 | gridY = effectController.newGridY; 152 | gridZ = effectController.newGridZ; 153 | ground = effectController.newGround; 154 | axes = effectController.newAxes; 155 | 156 | fillScene(); 157 | drawHelpers(); 158 | } 159 | renderer.render(scene, camera); 160 | } 161 | 162 | 163 | 164 | function setupGui() { 165 | 166 | effectController = { 167 | 168 | newGridX: gridX, 169 | newGridY: gridY, 170 | newGridZ: gridZ, 171 | newGround: ground, 172 | newAxes: axes 173 | }; 174 | 175 | var gui = new dat.GUI(); 176 | gui.add( effectController, "newGridX").name("Show XZ grid"); 177 | gui.add( effectController, "newGridY" ).name("Show YZ grid"); 178 | gui.add( effectController, "newGridZ" ).name("Show XY grid"); 179 | gui.add( effectController, "newGround" ).name("Show ground"); 180 | gui.add( effectController, "newAxes" ).name("Show axes"); 181 | } 182 | 183 | try { 184 | init(); 185 | setupGui(); 186 | drawHelpers(); 187 | addToDOM(); 188 | animate(); 189 | } catch(e) { 190 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 191 | $('#container').append(errorReport+e); 192 | } 193 | -------------------------------------------------------------------------------- /demo/unit2-z-fighting.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Z-fighting demo 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, $, Coordinates, requestAnimationFrame*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls; 9 | var clock = new THREE.Clock(); 10 | function drawDrinkingBird() { 11 | 12 | // MATERIALS 13 | var sphereMaterial = new THREE.MeshLambertMaterial( { color: 0xA00000 } ); 14 | var cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xF07020 } ); 15 | var cylinderMaterial = new THREE.MeshLambertMaterial( { color: 0x0000D0 } ); 16 | var legMaterial = new THREE.MeshLambertMaterial( { color: 0xFFFFFF } ); 17 | 18 | var sphere, cylinder, cube; 19 | 20 | // MODELS 21 | // base 22 | cube = new THREE.Mesh( 23 | new THREE.CubeGeometry( 20+64+110, 4, 2*77 ), cubeMaterial ); 24 | cube.position.x = -45; // (20+32) - half of width (20+64+110)/2 25 | cube.position.y = 4/2; // half of height 26 | cube.position.z = 0; // centered at origin 27 | scene.add( cube ); 28 | 29 | // left foot 30 | cube = new THREE.Mesh( 31 | new THREE.CubeGeometry( 20+64+110, 52, 6 ), cubeMaterial ); 32 | cube.position.x = -45; // (20+32) - half of width (20+64+110)/2 33 | cube.position.y = 52/2; // half of height 34 | cube.position.z = 77 + 6/2; // offset 77 + half of depth 6/2 35 | scene.add( cube ); 36 | 37 | // left leg 38 | cube = new THREE.Mesh( 39 | new THREE.CubeGeometry( 64, 334+52, 6 ), legMaterial ); 40 | cube.position.x = 0; // centered on origin along X 41 | cube.position.y = (334+52)/2; 42 | cube.position.z = 77 + 6/2; // negative offset 77 + half of depth 6/2 43 | scene.add( cube ); 44 | 45 | //////////////////////// 46 | // What the student adds 47 | 48 | // right foot 49 | cube = new THREE.Mesh( 50 | new THREE.CubeGeometry( 20+64+110, 52, 6 ), cubeMaterial ); 51 | cube.position.x = -45; // (20+32) - half of width (20+64+110)/2 52 | cube.position.y = 52/2; // half of height 53 | cube.position.z = -(77 + 6/2); // negative offset 77 + half of depth 6/2 54 | scene.add( cube ); 55 | 56 | // right leg 57 | cube = new THREE.Mesh( 58 | new THREE.CubeGeometry( 64, 334+52, 6 ), legMaterial ); 59 | cube.position.x = 0; // centered on origin along X 60 | cube.position.y = (334+52)/2; 61 | cube.position.z = -(77 + 6/2); // negative offset 77 + half of depth 6/2 62 | scene.add( cube ); 63 | 64 | // body 65 | sphere = new THREE.Mesh( 66 | new THREE.SphereGeometry( 116/2, 32, 16 ), sphereMaterial ); 67 | sphere.position.x = 0; 68 | sphere.position.y = 160; 69 | sphere.position.z = 0; 70 | scene.add( sphere ); 71 | 72 | // head 73 | sphere = new THREE.Mesh( 74 | new THREE.SphereGeometry( 104/2, 32, 16 ), sphereMaterial ); 75 | sphere.position.x = 0; 76 | sphere.position.y = 160 + 390; 77 | sphere.position.z = 0; 78 | scene.add( sphere ); 79 | 80 | // head/body connector 81 | cylinder = new THREE.Mesh( 82 | new THREE.CylinderGeometry( 24/2, 24/2, 390, 32 ), cylinderMaterial ); 83 | cylinder.position.x = 0; 84 | cylinder.position.y = 160 + 390/2; 85 | cylinder.position.z = 0; 86 | scene.add( cylinder ); 87 | 88 | // hat brim 89 | cylinder = new THREE.Mesh( 90 | new THREE.CylinderGeometry( 142/2, 142/2, 10, 32 ), cylinderMaterial ); 91 | cylinder.position.x = 0; 92 | cylinder.position.y = 160 + 390 + 40 + 10/2; 93 | cylinder.position.z = 0; 94 | scene.add( cylinder ); 95 | 96 | // hat top 97 | cylinder = new THREE.Mesh( 98 | new THREE.CylinderGeometry( 80/2, 80/2, 70, 32 ), cylinderMaterial ); 99 | cylinder.position.x = 0; 100 | cylinder.position.y = 160 + 390 + 40 + 10 + 70/2; 101 | cylinder.position.z = 0; 102 | scene.add( cylinder ); 103 | } 104 | 105 | function init() { 106 | var canvasWidth = window.innerWidth; 107 | var canvasHeight = window.innerHeight; 108 | var canvasRatio = canvasWidth / canvasHeight; 109 | // SCENE 110 | scene = new THREE.Scene(); 111 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 112 | // LIGHTS 113 | scene.add( new THREE.AmbientLight( 0x222222 ) ); 114 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 115 | light.position.set( 200, 400, 500 ); 116 | scene.add( light ); 117 | 118 | light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 119 | light.position.set( -400, 200, -300 ); 120 | scene.add( light ); 121 | 122 | // RENDERER 123 | 124 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 125 | renderer.gammaInput = true; 126 | renderer.gammaOutput = true; 127 | renderer.setSize(canvasWidth, canvasHeight); 128 | renderer.setClearColor( scene.fog.color, 1 ); 129 | 130 | var container = document.getElementById('container'); 131 | container.appendChild( renderer.domElement ); 132 | 133 | 134 | // CAMERA 135 | camera = new THREE.PerspectiveCamera( 45, canvasRatio, 1, 4000 ); 136 | camera.position.set( -330, 178, -400 ); 137 | // CONTROLS 138 | // For this demo, unconstrained viewing is good, to allow other angles. 139 | cameraControls = new THREE.TrackballControls(camera, renderer.domElement); 140 | // focus on the feet 141 | cameraControls.target.set(0,0,0); 142 | 143 | Coordinates.drawGround({size:10000}); 144 | Coordinates.drawGrid({size:10000,scale:0.01}); 145 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); 146 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); 147 | } 148 | 149 | // 150 | 151 | function animate() { 152 | requestAnimationFrame(animate); 153 | render(); 154 | } 155 | 156 | function render() { 157 | var delta = clock.getDelta(); 158 | cameraControls.update(delta); 159 | renderer.render(scene, camera); 160 | } 161 | 162 | function takeScreenshot() { 163 | init(); 164 | drinkingBird = drawDrinkingBird(); 165 | scene.add(drinkingBird); 166 | render(); 167 | var img1 = renderer.domElement.toDataURL("image/png"); 168 | camera.position.set( 400, 500, -800 ); 169 | render(); 170 | var img2 = renderer.domElement.toDataURL("image/png"); 171 | var imgTarget = window.open('', 'For grading script'); 172 | imgTarget.document.write(''); 173 | } 174 | 175 | init(); 176 | var drinkingBird = drawDrinkingBird(); 177 | scene.add(drinkingBird); 178 | animate(); 179 | $("body").keydown(function(event) { 180 | if (event.which === 80) { 181 | takeScreenshot(); 182 | } 183 | }); -------------------------------------------------------------------------------- /demo/unit2-z-fighting_fixed.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Z-fighting demo 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, $, Coordinates, requestAnimationFrame*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls; 9 | var clock = new THREE.Clock(); 10 | function drawDrinkingBird() { 11 | 12 | // MATERIALS 13 | var sphereMaterial = new THREE.MeshLambertMaterial( { color: 0xA00000 } ); 14 | var cubeMaterial = new THREE.MeshLambertMaterial( { color: 0xF07020 } ); 15 | var cylinderMaterial = new THREE.MeshLambertMaterial( { color: 0x0000D0 } ); 16 | var legMaterial = new THREE.MeshLambertMaterial( { color: 0xFFFFFF } ); 17 | 18 | var sphere, cylinder, cube; 19 | 20 | // MODELS 21 | // base 22 | cube = new THREE.Mesh( 23 | new THREE.CubeGeometry( 20+64+110, 4, 2*77 ), cubeMaterial ); 24 | cube.position.x = -45; // (20+32) - half of width (20+64+110)/2 25 | cube.position.y = 4/2; // half of height 26 | cube.position.z = 0; // centered at origin 27 | scene.add( cube ); 28 | 29 | // left foot 30 | cube = new THREE.Mesh( 31 | new THREE.CubeGeometry( 20+64+110, 52, 6 ), cubeMaterial ); 32 | cube.position.x = -45; // (20+32) - half of width (20+64+110)/2 33 | cube.position.y = 52/2; // half of height 34 | cube.position.z = 77 + 6/2; // offset 77 + half of depth 6/2 35 | scene.add( cube ); 36 | 37 | // left leg 38 | cube = new THREE.Mesh( 39 | new THREE.CubeGeometry( 64, 334, 6 ), legMaterial ); 40 | cube.position.x = 0; // centered on origin along X 41 | cube.position.y = 334/2 + 52; 42 | cube.position.z = 77 + 6/2; // negative offset 77 + half of depth 6/2 43 | scene.add( cube ); 44 | 45 | //////////////////////// 46 | // What the student adds 47 | 48 | // right foot 49 | cube = new THREE.Mesh( 50 | new THREE.CubeGeometry( 20+64+110, 52, 6 ), cubeMaterial ); 51 | cube.position.x = -45; // (20+32) - half of width (20+64+110)/2 52 | cube.position.y = 52/2; // half of height 53 | cube.position.z = -(77 + 6/2); // negative offset 77 + half of depth 6/2 54 | scene.add( cube ); 55 | 56 | // right leg 57 | cube = new THREE.Mesh( 58 | new THREE.CubeGeometry( 64, 334, 6 ), legMaterial ); 59 | cube.position.x = 0; // centered on origin along X 60 | cube.position.y = 334/2 + 52; 61 | cube.position.z = -(77 + 6/2); // negative offset 77 + half of depth 6/2 62 | scene.add( cube ); 63 | 64 | // body 65 | sphere = new THREE.Mesh( 66 | new THREE.SphereGeometry( 116/2, 32, 16 ), sphereMaterial ); 67 | sphere.position.x = 0; 68 | sphere.position.y = 160; 69 | sphere.position.z = 0; 70 | scene.add( sphere ); 71 | 72 | // head 73 | sphere = new THREE.Mesh( 74 | new THREE.SphereGeometry( 104/2, 32, 16 ), sphereMaterial ); 75 | sphere.position.x = 0; 76 | sphere.position.y = 160 + 390; 77 | sphere.position.z = 0; 78 | scene.add( sphere ); 79 | 80 | // head/body connector 81 | cylinder = new THREE.Mesh( 82 | new THREE.CylinderGeometry( 24/2, 24/2, 390, 32 ), cylinderMaterial ); 83 | cylinder.position.x = 0; 84 | cylinder.position.y = 160 + 390/2; 85 | cylinder.position.z = 0; 86 | scene.add( cylinder ); 87 | 88 | // hat brim 89 | cylinder = new THREE.Mesh( 90 | new THREE.CylinderGeometry( 142/2, 142/2, 10, 32 ), cylinderMaterial ); 91 | cylinder.position.x = 0; 92 | cylinder.position.y = 160 + 390 + 40 + 10/2; 93 | cylinder.position.z = 0; 94 | scene.add( cylinder ); 95 | 96 | // hat top 97 | cylinder = new THREE.Mesh( 98 | new THREE.CylinderGeometry( 80/2, 80/2, 70, 32 ), cylinderMaterial ); 99 | cylinder.position.x = 0; 100 | cylinder.position.y = 160 + 390 + 40 + 10 + 70/2; 101 | cylinder.position.z = 0; 102 | scene.add( cylinder ); 103 | } 104 | 105 | function init() { 106 | var canvasWidth = window.innerWidth; 107 | var canvasHeight = window.innerHeight; 108 | var canvasRatio = canvasWidth / canvasHeight; 109 | // SCENE 110 | scene = new THREE.Scene(); 111 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 112 | // LIGHTS 113 | scene.add( new THREE.AmbientLight( 0x222222 ) ); 114 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 115 | light.position.set( 200, 400, 500 ); 116 | scene.add( light ); 117 | 118 | light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 119 | light.position.set( -400, 200, -300 ); 120 | scene.add( light ); 121 | 122 | // RENDERER 123 | 124 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 125 | renderer.gammaInput = true; 126 | renderer.gammaOutput = true; 127 | renderer.setSize(canvasWidth, canvasHeight); 128 | renderer.setClearColor( scene.fog.color, 1 ); 129 | 130 | var container = document.getElementById('container'); 131 | container.appendChild( renderer.domElement ); 132 | 133 | 134 | // CAMERA 135 | camera = new THREE.PerspectiveCamera( 45, canvasRatio, 1, 4000 ); 136 | camera.position.set( -330, 178, -400 ); 137 | // CONTROLS 138 | // For this demo, unconstrained viewing is good, to allow other angles. 139 | cameraControls = new THREE.TrackballControls(camera, renderer.domElement); 140 | // focus on the feet 141 | cameraControls.target.set(0,0,0); 142 | 143 | Coordinates.drawGround({size:10000}); 144 | Coordinates.drawGrid({size:10000,scale:0.01}); 145 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); 146 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); 147 | } 148 | 149 | // 150 | 151 | function animate() { 152 | requestAnimationFrame(animate); 153 | render(); 154 | } 155 | 156 | function render() { 157 | var delta = clock.getDelta(); 158 | cameraControls.update(delta); 159 | renderer.render(scene, camera); 160 | } 161 | 162 | function takeScreenshot() { 163 | init(); 164 | drinkingBird = drawDrinkingBird(); 165 | scene.add(drinkingBird); 166 | render(); 167 | var img1 = renderer.domElement.toDataURL("image/png"); 168 | camera.position.set( 400, 500, -800 ); 169 | render(); 170 | var img2 = renderer.domElement.toDataURL("image/png"); 171 | var imgTarget = window.open('', 'For grading script'); 172 | imgTarget.document.write(''); 173 | } 174 | 175 | init(); 176 | var drinkingBird = drawDrinkingBird(); 177 | scene.add(drinkingBird); 178 | animate(); 179 | $("body").keydown(function(event) { 180 | if (event.which === 80) { 181 | takeScreenshot(); 182 | } 183 | }); -------------------------------------------------------------------------------- /demo/unit10-picking.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Picking: pick object and change its color and place a sphere 4 | //////////////////////////////////////////////////////////////////////////////// 5 | 6 | /*global THREE, document, window*/ 7 | 8 | // Mostly grabbed from http://mrdoob.github.com/three.js/examples/canvas_interactive_cubes.html 9 | // Author unknown. 10 | 11 | var camera, scene, projector, renderer; 12 | var sphereMaterial; 13 | 14 | var objects = []; 15 | var headlight; 16 | 17 | var sphereGeom; 18 | 19 | var canvasWidth; 20 | var canvasHeight; 21 | 22 | init(); 23 | animate(); 24 | 25 | function init() { 26 | canvasWidth = window.innerWidth; 27 | canvasHeight = window.innerHeight; 28 | var canvasRatio = canvasWidth / canvasHeight; 29 | 30 | camera = new THREE.PerspectiveCamera( 70, canvasRatio, 1, 10000 ); 31 | camera.position.set( 0, 300, 500 ); 32 | 33 | scene = new THREE.Scene(); 34 | 35 | headlight = new THREE.PointLight( 0xFFFFFF, 0.3 ); 36 | 37 | scene.add( headlight ); 38 | 39 | var light = new THREE.DirectionalLight( 0xFFFFFF, 0.6 ); 40 | light.position.set( 200, 500, 500 ); 41 | 42 | scene.add( light ); 43 | 44 | light = new THREE.DirectionalLight( 0xFFFFFF, 0.6 ); 45 | light.position.set( 0, 200, -300 ); 46 | 47 | scene.add( light ); 48 | 49 | light = new THREE.DirectionalLight( 0xFFFFFF, 0.4 ); 50 | light.position.set( -400, -300, 200 ); 51 | 52 | scene.add( light ); 53 | 54 | var geometry = new THREE.CubeGeometry( 100, 100, 100 ); 55 | 56 | for ( var i = 0; i < 10; i ++ ) { 57 | 58 | var object = new THREE.Mesh( geometry, 59 | new THREE.MeshLambertMaterial( 60 | { color: Math.random() * 0xFFFFFF } ) 61 | //, opacity: 0.5, transparent: true } ) ); 62 | ); 63 | 64 | // add a random box between -400 to +400 65 | object.position.x = Math.random() * 800 - 400; 66 | object.position.y = Math.random() * 800 - 400; 67 | object.position.z = Math.random() * 800 - 400; 68 | 69 | // make box randomly scale by 1 to 3x 70 | object.scale.x = Math.random() * 2 + 1; 71 | object.scale.y = Math.random() * 2 + 1; 72 | object.scale.z = Math.random() * 2 + 1; 73 | 74 | // probably not uniformly distributed rotations, but that's OK 75 | // See Arvo, "Graphics Gems 3", p. 117 for the right method. 76 | object.rotation.x = Math.random() * 2 * Math.PI; 77 | object.rotation.y = Math.random() * 2 * Math.PI; 78 | object.rotation.z = Math.random() * 2 * Math.PI; 79 | 80 | scene.add( object ); 81 | 82 | objects.push( object ); 83 | 84 | } 85 | 86 | sphereMaterial = new THREE.MeshBasicMaterial( { color: 0xD0D0D0 } ); 87 | 88 | projector = new THREE.Projector(); 89 | 90 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 91 | renderer.setSize(canvasWidth, canvasHeight); 92 | renderer.setClearColorHex( 0xFFFFFF, 1.0 ); 93 | 94 | var container = document.getElementById('container'); 95 | container.appendChild( renderer.domElement ); 96 | 97 | sphereGeom = new THREE.SphereGeometry( 6, 12, 6 ); 98 | 99 | document.addEventListener( 'mousedown', onDocumentMouseDown, false ); 100 | } 101 | 102 | function onDocumentMouseDown( event ) { 103 | 104 | //event.preventDefault(); 105 | 106 | // Annoying nested window code: need to subtract offsets for nested windows. 107 | // This is not needed if you have just a single window filling the browser 108 | // var node = event.target || event.srcElement; 109 | // var mouseX = event.clientX - node.offsetLeft; 110 | // var mouseY = event.clientY - node.offsetTop; 111 | 112 | 113 | // getBoundingClientRect() 114 | // gives the element's position relative to the browser's visible viewport. 115 | // clientX/Y 116 | // gives the mouse position relative to the browser's visible viewport. 117 | // 118 | // we then just have to find the difference between the two 119 | // to get the mouse position in "canvas-space" 120 | var canvasPosition = renderer.domElement.getBoundingClientRect(); 121 | var mouseX = event.clientX - canvasPosition.left; 122 | var mouseY = event.clientY - canvasPosition.top; 123 | 124 | // console.log(canvasPosition.left,canvasPosition.top); 125 | // console.log(mouseX,mouseY); 126 | 127 | /* 128 | while (node.offsetParent){ 129 | node = node.offsetParent; 130 | mouseX -= node.offsetLeft; 131 | mouseY -= node.offsetTop; 132 | }*/ 133 | 134 | /* the old way */ 135 | /* 136 | var mouseVector = new THREE.Vector3( 137 | 2 * ( mouseX / canvasWidth ) - 1, 138 | 1 - 2 * ( mouseY / canvasHeight ), 0.5 ); 139 | projector.unprojectVector( mouseVector, camera ); 140 | 141 | var raycaster = new THREE.Raycaster( camera.position, mouseVector.sub( camera.position ).normalize() ); 142 | */ 143 | 144 | /* the new way: simpler creation of raycaster */ 145 | /* from tutorial: http://soledadpenades.com/articles/three-js-tutorials/object-picking/ */ 146 | var mouseVector = new THREE.Vector3( 147 | 2 * ( mouseX / canvasWidth ) - 1, 148 | 1 - 2 * ( mouseY / canvasHeight )); 149 | 150 | // debug: console.log( "client Y " + event.clientY + ", mouse Y " + mouseY ); 151 | 152 | var raycaster = projector.pickingRay( mouseVector.clone(), camera ); 153 | 154 | var intersects = raycaster.intersectObjects( objects ); 155 | 156 | if ( intersects.length > 0 ) { 157 | 158 | intersects[ 0 ].object.material.color.setRGB( Math.random(), Math.random(), Math.random() ); 159 | 160 | var sphere = new THREE.Mesh( sphereGeom, sphereMaterial ); 161 | sphere.position = intersects[ 0 ].point; 162 | scene.add( sphere ); 163 | } 164 | 165 | /* 166 | // Parse all the faces, for when you are using face materials 167 | for ( var i in intersects ) { 168 | intersects[ i ].face.material[ 0 ].color.setHex( Math.random() * 0xFFFFFF | 0x80000000 ); 169 | } 170 | */ 171 | } 172 | 173 | // 174 | 175 | function animate() { 176 | window.requestAnimationFrame(animate); 177 | render(); 178 | } 179 | 180 | var radius = 600; 181 | var theta = 0; 182 | 183 | function render() { 184 | 185 | theta += 0.1; 186 | 187 | camera.position.x = radius * Math.sin( THREE.Math.degToRad( theta ) ); 188 | camera.position.y = radius * Math.sin( THREE.Math.degToRad( theta ) ); 189 | camera.position.z = radius * Math.cos( THREE.Math.degToRad( theta ) ); 190 | camera.lookAt( scene.position ); 191 | headlight.position.copy( camera.position ); 192 | 193 | renderer.render( scene, camera ); 194 | 195 | } 196 | -------------------------------------------------------------------------------- /unit4/unit4-clock_exercise.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Clock exercise: rotate hands correctly 4 | //////////////////////////////////////////////////////////////////////////////// 5 | /*global THREE, Coordinates, document, window, dat, $*/ 6 | 7 | var camera, scene, renderer; 8 | var cameraControls, effectController; 9 | var clock = new THREE.Clock(); 10 | var gridX = false; 11 | var gridY = false; 12 | var gridZ = false; 13 | var axes = true; 14 | var ground = true; 15 | 16 | function fillScene() { 17 | scene = new THREE.Scene(); 18 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 19 | 20 | // LIGHTS 21 | var ambientLight = new THREE.AmbientLight( 0x222222 ); 22 | 23 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 24 | light.position.set( 200, 400, 500 ); 25 | 26 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 27 | light2.position.set( -500, 250, -200 ); 28 | 29 | scene.add(ambientLight); 30 | scene.add(light); 31 | scene.add(light2); 32 | 33 | var faceMaterial = new THREE.MeshLambertMaterial( { color: 0xFFECA9 } ); 34 | var markMaterial = new THREE.MeshLambertMaterial( { color: 0x89581F } ); 35 | var mark12Material = new THREE.MeshLambertMaterial( { color: 0xE6880E } ); 36 | var minuteHandMaterial = new THREE.MeshLambertMaterial( { color: 0x226894 } ); 37 | var hourHandMaterial = new THREE.MeshLambertMaterial( { color: 0xE02BFB } ); 38 | 39 | // clock 40 | var clock = new THREE.Mesh( 41 | new THREE.CylinderGeometry( 75, 75, 10, 32 ), faceMaterial ); 42 | //new THREE.CubeGeometry( 150, 5, 150 ), faceMaterial ); 43 | clock.position.y = 5; 44 | scene.add( clock ); 45 | 46 | // marks 47 | var cube = new THREE.Mesh( 48 | new THREE.CubeGeometry( 20, 4, 15 ), mark12Material ); 49 | cube.position.x = 60; 50 | cube.position.y = 9; 51 | scene.add( cube ); 52 | 53 | cube = new THREE.Mesh( 54 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 55 | cube.position.x = -60; 56 | cube.position.y = 9; 57 | scene.add( cube ); 58 | 59 | cube = new THREE.Mesh( 60 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 61 | cube.position.z = 60; 62 | cube.position.y = 9; 63 | scene.add( cube ); 64 | 65 | cube = new THREE.Mesh( 66 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 67 | cube.position.z = -60; 68 | cube.position.y = 9; 69 | scene.add( cube ); 70 | 71 | // YOUR CODE HERE: 72 | // The dimensions and rotation angles of the hands are correct 73 | // you just have find a way to perform them in the correct order 74 | cube = new THREE.Mesh( 75 | new THREE.CubeGeometry( 70, 4, 4 ), minuteHandMaterial ); 76 | cube.position.y = 14; 77 | cube.position.x = 70/2 - 10; 78 | cube.rotation.y = -60 * Math.PI/180; 79 | scene.add( cube ); 80 | 81 | var sphere = new THREE.Mesh( 82 | new THREE.SphereGeometry( 0.5, 32, 16 ), hourHandMaterial ); 83 | sphere.position.y = 18; // move the hand above the other hand 84 | sphere.position.x = 50/2 - 10; 85 | sphere.rotation.y = 30 * Math.PI/180; 86 | sphere.scale.x = 50; 87 | sphere.scale.y = 4; 88 | sphere.scale.z = 4; 89 | 90 | scene.add( sphere ); 91 | } 92 | 93 | function init() { 94 | var canvasWidth = 846; 95 | var canvasHeight = 494; 96 | // For grading the window is fixed in size; here's general code: 97 | //var canvasWidth = window.innerWidth; 98 | //var canvasHeight = window.innerHeight; 99 | var canvasRatio = canvasWidth / canvasHeight; 100 | 101 | // RENDERER 102 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 103 | renderer.gammaInput = true; 104 | renderer.gammaOutput = true; 105 | renderer.setSize(canvasWidth, canvasHeight); 106 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 107 | 108 | // CAMERA 109 | camera = new THREE.PerspectiveCamera( 30, canvasRatio, 1, 10000 ); 110 | camera.position.set( -420, 400, 100 ); 111 | // CONTROLS 112 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 113 | cameraControls.target.set(0,0,0); 114 | 115 | fillScene(); 116 | 117 | } 118 | function drawHelpers() { 119 | if (ground) { 120 | Coordinates.drawGround({size:10000}); 121 | } 122 | if (gridX) { 123 | Coordinates.drawGrid({size:10000,scale:0.01}); 124 | } 125 | if (gridY) { 126 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); 127 | } 128 | if (gridZ) { 129 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); 130 | } 131 | if (axes) { 132 | Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50}); 133 | } 134 | } 135 | 136 | function addToDOM() { 137 | var container = document.getElementById('container'); 138 | var canvas = container.getElementsByTagName('canvas'); 139 | if (canvas.length>0) { 140 | container.removeChild(canvas[0]); 141 | } 142 | container.appendChild( renderer.domElement ); 143 | } 144 | 145 | function animate() { 146 | window.requestAnimationFrame(animate); 147 | render(); 148 | } 149 | 150 | function render() { 151 | var delta = clock.getDelta(); 152 | cameraControls.update(delta); 153 | 154 | if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes) 155 | { 156 | gridX = effectController.newGridX; 157 | gridY = effectController.newGridY; 158 | gridZ = effectController.newGridZ; 159 | ground = effectController.newGround; 160 | axes = effectController.newAxes; 161 | 162 | fillScene(); 163 | drawHelpers(); 164 | } 165 | renderer.render(scene, camera); 166 | } 167 | 168 | 169 | 170 | function setupGui() { 171 | 172 | effectController = { 173 | 174 | newGridX: gridX, 175 | newGridY: gridY, 176 | newGridZ: gridZ, 177 | newGround: ground, 178 | newAxes: axes 179 | }; 180 | 181 | var gui = new dat.GUI(); 182 | gui.add( effectController, "newGridX").name("Show XZ grid"); 183 | gui.add( effectController, "newGridY" ).name("Show YZ grid"); 184 | gui.add( effectController, "newGridZ" ).name("Show XY grid"); 185 | gui.add( effectController, "newGround" ).name("Show ground"); 186 | gui.add( effectController, "newAxes" ).name("Show axes"); 187 | } 188 | 189 | try { 190 | init(); 191 | setupGui(); 192 | drawHelpers(); 193 | addToDOM(); 194 | animate(); 195 | } catch(e) { 196 | var errorReport = "Your program encountered an unrecoverable error, can not draw on canvas. Error was:

"; 197 | $('#container').append(errorReport+e); 198 | } 199 | 200 | -------------------------------------------------------------------------------- /demo/unit4-rotate_then_scale.js: -------------------------------------------------------------------------------- 1 | "use strict"; // good practice - see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode 2 | //////////////////////////////////////////////////////////////////////////////// 3 | // Rotate, then scale 4 | // NOTE: this is not really a demo, just a way to show what goes wrong with a 5 | // bad order. 6 | //////////////////////////////////////////////////////////////////////////////// 7 | /*global THREE, Coordinates, $, document, window, dat*/ 8 | 9 | var camera, scene, renderer; 10 | var cameraControls, effectController; 11 | var clock = new THREE.Clock(); 12 | var gridX = false; 13 | var gridY = false; 14 | var gridZ = false; 15 | var axes = true; 16 | var ground = true; 17 | 18 | function fillScene() { 19 | scene = new THREE.Scene(); 20 | scene.fog = new THREE.Fog( 0x808080, 2000, 4000 ); 21 | 22 | // LIGHTS 23 | var ambientLight = new THREE.AmbientLight( 0x222222 ); 24 | 25 | var light = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 26 | light.position.set( 200, 400, 500 ); 27 | 28 | var light2 = new THREE.DirectionalLight( 0xFFFFFF, 1.0 ); 29 | light2.position.set( -500, 250, -200 ); 30 | 31 | scene.add(ambientLight); 32 | scene.add(light); 33 | scene.add(light2); 34 | 35 | if (ground) { 36 | Coordinates.drawGround({size:10000}); 37 | } 38 | if (gridX) { 39 | Coordinates.drawGrid({size:10000,scale:0.01}); 40 | } 41 | if (gridY) { 42 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"y"}); 43 | } 44 | if (gridZ) { 45 | Coordinates.drawGrid({size:10000,scale:0.01, orientation:"z"}); 46 | } 47 | if (axes) { 48 | Coordinates.drawAllAxes({axisLength:200,axisRadius:1,axisTess:50}); 49 | } 50 | 51 | var faceMaterial = new THREE.MeshLambertMaterial( { color: 0xFFECA9 } ); 52 | var markMaterial = new THREE.MeshLambertMaterial( { color: 0x89581F } ); 53 | var mark12Material = new THREE.MeshLambertMaterial( { color: 0xE6880E } ); 54 | var minuteHandMaterial = new THREE.MeshLambertMaterial( { color: 0x226894 } ); 55 | var hourHandMaterial = new THREE.MeshLambertMaterial( { color: 0xE02BFB } ); 56 | 57 | // clock 58 | var clock = new THREE.Mesh( 59 | new THREE.CylinderGeometry( 75, 75, 10, 32 ), faceMaterial ); 60 | //new THREE.CubeGeometry( 150, 5, 150 ), faceMaterial ); 61 | clock.position.y = 5; 62 | scene.add( clock ); 63 | 64 | // marks 65 | var cube = new THREE.Mesh( 66 | new THREE.CubeGeometry( 20, 4, 15 ), mark12Material ); 67 | cube.position.x = 60; 68 | cube.position.y = 9; 69 | scene.add( cube ); 70 | 71 | cube = new THREE.Mesh( 72 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 73 | cube.position.x = -60; 74 | cube.position.y = 9; 75 | scene.add( cube ); 76 | 77 | cube = new THREE.Mesh( 78 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 79 | cube.position.z = 60; 80 | cube.position.y = 9; 81 | scene.add( cube ); 82 | 83 | cube = new THREE.Mesh( 84 | new THREE.CubeGeometry( 10, 4, 10 ), markMaterial ); 85 | cube.position.z = -60; 86 | cube.position.y = 9; 87 | scene.add( cube ); 88 | 89 | cube = new THREE.Mesh( 90 | new THREE.CubeGeometry( 110, 4, 4 ), minuteHandMaterial ); 91 | cube.position.y = 14; 92 | cube.rotation.y = -60 * Math.PI/180; 93 | 94 | scene.add( cube ); 95 | 96 | var clockHourHand = new THREE.Object3D(); 97 | 98 | var sphere = new THREE.Mesh( 99 | new THREE.SphereGeometry( 10, 32, 16 ), hourHandMaterial ); 100 | 101 | sphere.rotation.y = 30 * Math.PI/180; 102 | 103 | clockHourHand.add( sphere ); 104 | clockHourHand.position.y = 18; 105 | clockHourHand.scale.x = 3.0; // 60 / (2 * radius 10 ) -> 3 106 | clockHourHand.scale.y = 0.2; // 4 / (2 * radius 10 ) -> 0.2 107 | clockHourHand.scale.z = 0.2; 108 | scene.add( clockHourHand ); 109 | } 110 | 111 | function init() { 112 | var canvasWidth = window.innerWidth; 113 | var canvasHeight = window.innerHeight; 114 | var canvasRatio = canvasWidth / canvasHeight; 115 | 116 | // RENDERER 117 | renderer = new THREE.WebGLRenderer( { antialias: true } ); 118 | renderer.gammaInput = true; 119 | renderer.gammaOutput = true; 120 | renderer.setSize(canvasWidth, canvasHeight); 121 | renderer.setClearColorHex( 0xAAAAAA, 1.0 ); 122 | 123 | var container = document.getElementById('container'); 124 | container.appendChild( renderer.domElement ); 125 | 126 | // CAMERA 127 | camera = new THREE.PerspectiveCamera( 30, canvasRatio, 1, 10000 ); 128 | camera.position.set( -420, 400, 100 ); 129 | // CONTROLS 130 | cameraControls = new THREE.OrbitAndPanControls(camera, renderer.domElement); 131 | cameraControls.target.set(0,0,0); 132 | 133 | fillScene(); 134 | 135 | } 136 | 137 | function animate() { 138 | window.requestAnimationFrame(animate); 139 | render(); 140 | } 141 | 142 | function render() { 143 | var delta = clock.getDelta(); 144 | cameraControls.update(delta); 145 | 146 | if ( effectController.newGridX !== gridX || effectController.newGridY !== gridY || effectController.newGridZ !== gridZ || effectController.newGround !== ground || effectController.newAxes !== axes) 147 | { 148 | gridX = effectController.newGridX; 149 | gridY = effectController.newGridY; 150 | gridZ = effectController.newGridZ; 151 | ground = effectController.newGround; 152 | axes = effectController.newAxes; 153 | 154 | fillScene(); 155 | } 156 | renderer.render(scene, camera); 157 | } 158 | 159 | 160 | 161 | function setupGui() { 162 | 163 | effectController = { 164 | 165 | newGridX: gridX, 166 | newGridY: gridY, 167 | newGridZ: gridZ, 168 | newGround: ground, 169 | newAxes: axes 170 | }; 171 | 172 | var gui = new dat.GUI(); 173 | gui.add( effectController, "newGridX").name("Show XZ grid"); 174 | gui.add( effectController, "newGridY" ).name("Show YZ grid"); 175 | gui.add( effectController, "newGridZ" ).name("Show XY grid"); 176 | gui.add( effectController, "newGround" ).name("Show ground"); 177 | gui.add( effectController, "newAxes" ).name("Show axes"); 178 | } 179 | 180 | function takeScreenshot() { 181 | effectController.newGround = true; 182 | effectController.newGridX = false; 183 | effectController.newGridY = false; 184 | effectController.newGridZ = false; 185 | effectController.newAxes = false; 186 | init(); 187 | render(); 188 | var img1 = renderer.domElement.toDataURL("image/png"); 189 | camera.position.set( 400, 500, -800 ); 190 | render(); 191 | var img2 = renderer.domElement.toDataURL("image/png"); 192 | var imgTarget = window.open('', 'For grading script'); 193 | imgTarget.document.write(''); 194 | } 195 | 196 | init(); 197 | setupGui(); 198 | animate(); 199 | $("body").keydown(function(event) { 200 | if (event.which === 80) { 201 | takeScreenshot(); 202 | } 203 | }); --------------------------------------------------------------------------------