├── .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 | });
--------------------------------------------------------------------------------