├── .gitignore
├── README.md
├── css
└── styles.css
├── img
├── ash_uvgrid01.jpg
├── noWebGL.png
└── water.jpg
├── index.html
├── js
├── LilyPad3D.js
├── Main.js
├── Params.js
├── extra.js
└── modernizr.custom.31336.js
└── vendor
├── RequestAnimationFrame.js
├── Stats.js
├── dat.gui.min.js
├── jquery-1.6.1.min.js
├── jquery-1.7.1.min.js
├── jquery.easing.1.3.js
├── jstween-1.0.min.js
├── perlin-noise-classical.js
├── perlin-noise-simplex.js
├── three
├── Three.js
├── controls
│ ├── EditorControls.js
│ ├── FirstPersonControls.js
│ ├── FlyControls.js
│ ├── OrbitControls.js
│ ├── PathControls.js
│ ├── PointerLockControls.js
│ └── TrackballControls.js
├── custom
│ ├── ThreeCanvas.js
│ ├── ThreeDOM.js
│ ├── ThreeExtras.js
│ ├── ThreeSVG.js
│ └── ThreeWebGL.js
└── three.min.js
├── toxi
├── toxi-color.js
├── toxi-core.js
├── toxi-physics2d.js
├── toxiclibs.js
└── uncompressed
│ ├── toxi-color-debug.js
│ ├── toxi-core-debug.js
│ ├── toxi-physics2d-debug.js
│ └── toxiclibs-debug.js
└── un
├── BoilerPlate.js
├── Trace.js
├── Unctrl.js
└── Utils.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .project
3 | .psd
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Lilypad
2 | ========
3 |
4 | Lily pad is an experiment that explores paper folding inspired by the form of a lily pad floating on top of water.
5 |
--------------------------------------------------------------------------------
/css/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | background-color: #050505 ;
3 | margin: 0;
4 | padding: 0;
5 | overflow: hidden;
6 | }
7 |
8 |
9 | #notification {
10 | position:absolute;
11 | bottom: 10px;
12 | left: 10px;
13 | padding: 10px 15px 10px 15px;
14 | background: #001122;
15 | font-family: arial, helvetica, sans-serif;
16 | color:#61757f;
17 | font-size:0.8em;
18 | line-height: 1.6em;
19 | text-align:left;
20 | }
21 |
22 | #notification a:hover, #notification a:link, #notification a:visited{
23 | color:#c3dbdf;
24 | text-decoration: none;
25 |
26 | }
27 |
28 |
29 | #loader {
30 | position:absolute;
31 | font-family:Arial,Helvetica, sans-serif;
32 | font-size:1.0em;
33 | text-align:center;
34 | background-color: #050505;
35 | opacity:.75;
36 | width:100%;
37 | height:100%;
38 | color:#FFF;
39 | display:none;
40 | }
41 |
42 | #noWebGL{
43 | position: absolute;
44 | bottom: 0px;
45 | left: 0px;
46 | }
47 |
48 | #container3D {
49 | position: absolute;
50 | }
51 |
52 | #guiContainer {
53 | position:absolute;
54 | background-color: #111;
55 | right:-15px;
56 | height:100%;
57 | }
58 | #about {
59 | font: 12px 'Lucida Grande', sans-serif;
60 | position:absolute;
61 | color:#999;
62 | width:230px;
63 | height:48px;
64 | padding: 10px;
65 | right:0px;
66 | }
67 | #about a {
68 | color:#E61D5F;
69 | text-decoration: none;
70 | }
71 |
72 | .close-button{
73 | display:none;
74 | }
75 | .dg.main{
76 | margin-top:70px;
77 | }
--------------------------------------------------------------------------------
/img/ash_uvgrid01.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mannytan/lilypad/4054a404a1690de91e6d0d8596dff5a5370c752c/img/ash_uvgrid01.jpg
--------------------------------------------------------------------------------
/img/noWebGL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mannytan/lilypad/4054a404a1690de91e6d0d8596dff5a5370c752c/img/noWebGL.png
--------------------------------------------------------------------------------
/img/water.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mannytan/lilypad/4054a404a1690de91e6d0d8596dff5a5370c752c/img/water.jpg
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | uncontrol :: lilyPad
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | Lilypad is an experiment that uses paper folding methods as texture.
uncontrol.com
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/js/LilyPad3D.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by unctrl.com
3 | * User: mannytan
4 | * Date: 8/22/11
5 | */
6 |
7 |
8 | LILYPAD.LilyPad3D = function(name) {
9 | var scope = this;
10 |
11 | UNCTRL.BoilerPlate.call(this);
12 |
13 | this.name = 'LilyPad3D';
14 |
15 | // 3d vars
16 | this.container = null;
17 | this.projector = null;
18 | this.camera = null;
19 | this.scene = null;
20 | this.raycaster = null;
21 | this.intersected = null;
22 | this.controls = null;
23 | this.cube = null;
24 |
25 | this.stageWidth = 0;
26 | this.stageHeight = 0;
27 | this.stageOffsetX = 0;
28 | this.stageOffsetY = 0;
29 |
30 | this.count = 0;
31 | this.centerCount = 0;
32 |
33 | this.pointLightA = null;
34 |
35 | this.customPlanes = null;
36 | this.customWirePlanes = null;
37 | this.water = null;
38 | this.ground = null;
39 |
40 | this.particles = null;
41 |
42 | this.totalPlanesH = getUrlVars()["totalWidth"] ? getUrlVars()["totalWidth"] : 28;
43 | this.totalPlanesV = getUrlVars()["totalDepth"] ? getUrlVars()["totalDepth"] : 12;
44 | this.totalVerticesH = this.totalPlanesH*2 + 1;
45 | this.totalVerticesV = this.totalPlanesV*2 + 1;
46 | this.totalVertices = this.totalVerticesH * this.totalVerticesV;
47 |
48 | this.maxHeightCache = null;
49 | this.maxHeightCacheSize = 20;
50 |
51 | this.colorOffset = .5;
52 |
53 | this.haloLine = null;
54 |
55 | this.halo = null;
56 | this.haloDot = null;
57 |
58 | // ---------------------------------------------------------
59 | // instantiation
60 | // ---------------------------------------------------------
61 |
62 | this.init = function() {
63 | this.traceFunction("init");
64 |
65 | // this.perlin = new ClassicalNoise();
66 | this.perlin = new SimplexNoise();
67 | return this;
68 | };
69 |
70 | this.createEnvironment = function() {
71 | // this.traceFunction("createEnvironment");
72 |
73 | this.projector = new THREE.Projector(); // used for mouse position in 3d space
74 | this.scene = new THREE.Scene();
75 | this.base = new THREE.Object3D();
76 | this.scene.add(this.base);
77 |
78 | this.camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 3000 );
79 | this.camera.position.x = 0;
80 | this.camera.position.y = 300;
81 | this.camera.position.z = 400;
82 |
83 | this.controls = new THREE.TrackballControls( this.camera, document.getElementById('container3D'));
84 | this.controls.rotateSpeed = 1.0;
85 | this.controls.zoomSpeed = 1.2;
86 | this.controls.panSpeed = 0.8;
87 | this.controls.noZoom = false;
88 | this.controls.noPan = false;
89 | this.controls.staticMoving = true;
90 | this.controls.dynamicDampingFactor = 0.3;
91 | this.controls.keys = [ 65, 83, 68 ];
92 |
93 | this.renderer = new THREE.WebGLRenderer({
94 | antialias: true
95 | });
96 |
97 | this.renderer.setClearColor(0xEEEEEE, 1);
98 | this.renderer.setSize(this.stageWidth, this.stageHeight);
99 |
100 | this.renderer.gammaInput = true;
101 | this.renderer.gammaOutput = true;
102 | this.renderer.physicallyBasedShading = true;
103 |
104 | this.renderer.shadowMapEnabled = true;
105 | this.renderer.shadowMapCullFace = THREE.CullFaceBack;
106 |
107 | this.container = document.getElementById('container3D');
108 | this.container.appendChild(this.renderer.domElement);
109 |
110 | return this;
111 | };
112 |
113 | this.createLights = function() {
114 |
115 | this.scene.add( new THREE.AmbientLight( 0xCCCCCC ) );
116 |
117 | var hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.6 );
118 | hemiLight.color.setHSL( 0.6, 1, 0.6 );
119 | hemiLight.groundColor.setHSL( 0.095, 1, 0.75 );
120 | hemiLight.position.set( 0, 300, 0 );
121 | this.scene.add( hemiLight );
122 |
123 | this.dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
124 | // this.dirLight.color.setHSL( 0.1, 1, 0.95 );
125 | this.dirLight.position.set( -2.5, 2.5, 2.5 );
126 | this.dirLight.position.multiplyScalar( 100 );
127 | this.scene.add( this.dirLight );
128 |
129 | this.dirLight.castShadow = true;
130 | this.dirLight.shadowMapWidth = 3500;
131 | this.dirLight.shadowMapHeight = 3500;
132 |
133 | var d = 800;
134 |
135 | this.dirLight.shadowCameraLeft = -d;
136 | this.dirLight.shadowCameraRight = d;
137 | this.dirLight.shadowCameraTop = d;
138 | this.dirLight.shadowCameraBottom = -d;
139 |
140 | this.dirLight.shadowCameraFar = 3500;
141 | this.dirLight.shadowBias = -0.0001;
142 | this.dirLight.shadowDarkness = 0.35;
143 | // this.dirLight.shadowCameraVisible = true;
144 |
145 | return this;
146 | };
147 |
148 | this.createListeners = function() {
149 | this.container.addEventListener('mousedown', function(event) {
150 | scope.onDocumentMouseDown(event);
151 | }, false);
152 |
153 | return this;
154 | };
155 |
156 | this.createPrimaryElements = function() {
157 |
158 | var i,j,k,id,
159 | particle,
160 | faceNormal,
161 | geometry,
162 | material;
163 |
164 | var percentage;
165 |
166 | // backbone dots
167 | material = new THREE.ParticleBasicMaterial( { color: 0xFFFFFF, size: 1} );
168 | geometry = new THREE.Geometry();
169 | for(i = 0; i < this.totalVertices; i++) {
170 | geometry.vertices.push(new THREE.Vector3());
171 | }
172 |
173 | this.particles = new THREE.ParticleSystem( geometry, material );
174 | this.base.add(this.particles);
175 | this.particles.visible = false;
176 |
177 | var colorSpeed = LILYPAD.Params.colorSpeed;
178 | var colorRange = LILYPAD.Params.colorRange;
179 |
180 | this.customPlanes = [];
181 | for(i = 0; i < this.totalPlanesV; i++) {
182 | geometry = this.getCustomGeometry(this.totalPlanesH, i, i*30, 30);
183 | // main plane
184 | material = new THREE.MeshLambertMaterial( {
185 | ambient: 0x000000,
186 | color: new THREE.Color().setHSL( (i/this.totalPlanesV*colorRange + colorSpeed)%1 , 1, .5),
187 | specular: 0x336699,
188 | shininess: 30,
189 | shading: THREE.SmoothShading,
190 | side:THREE.DoubleSide
191 | });
192 |
193 | customPlane = new THREE.Mesh( geometry, material );
194 | customPlane.castShadow = true;
195 | customPlane.receiveShadow = true;
196 | this.base.add(customPlane);
197 | this.customPlanes.push(customPlane);
198 | }
199 |
200 | var cache = [];
201 | for(i = 0; i < this.maxHeightCacheSize; i++) {
202 | cache.push(0);
203 | };
204 | this.maxHeightCache = [];
205 | var id = 0;
206 | for(j = 0; j < this.totalVerticesV; j++) {
207 | for(i = 0; i < this.totalVerticesH; i++) {
208 | this.maxHeightCache.push(cache.slice());
209 | id++;
210 | }
211 | }
212 |
213 | return this;
214 | };
215 |
216 | this.createSecondaryElements = function() {
217 |
218 | var width = 1000;
219 | var height = 600;
220 | var depth = 1000;
221 |
222 | var colorSpeed = LILYPAD.Params.colorSpeed;
223 | var colorRange = LILYPAD.Params.colorRange;
224 | var geometry,
225 | material;
226 |
227 | // water
228 | material = new THREE.MeshPhongMaterial( {
229 | ambient: 0x333333,
230 | color: 0xFFFFFF,
231 | side:THREE.DoubleSide,
232 | transparent: true,
233 | opacity: .9,
234 | specular: 0x050505});
235 | geometry = new THREE.PlaneGeometry( width*10, depth*10 ,100,100);
236 |
237 | this.water = new THREE.Mesh( geometry, material );
238 | this.water.rotation.x = -Math.PI/2;
239 | this.water.position.y = -100;
240 | this.water.receiveShadow = true;
241 | this.base.add( this.water );
242 |
243 | // ground
244 | material = new THREE.MeshPhongMaterial( {
245 | ambient: 0x333333,
246 | color: 0xFFFFFF,
247 | side:THREE.DoubleSide,
248 | transparent: true,
249 | opacity: .9,
250 | specular: 0x050505});
251 | geometry = new THREE.PlaneGeometry( width*10, depth*10 );
252 |
253 | this.ground = new THREE.Mesh( geometry, material );
254 | this.ground.rotation.x = -Math.PI/2;
255 | this.ground.position.y = -height*0.5;
256 | this.ground.receiveShadow = true;
257 | this.base.add( this.ground );
258 |
259 | // wireframe plane
260 | material = new THREE.MeshBasicMaterial( { color: 0xFFFFFF, wireframe:true, transparent:true, opacity:0.05 } )
261 | material.side = THREE.DoubleSide;
262 | this.customWirePlanes = [];
263 | for(i = 0; i < this.totalPlanesV; i++) {
264 | geometry = this.getCustomGeometry(this.totalPlanesH, i, i*30, 30);
265 | customPlane = new THREE.Mesh( geometry, material );
266 | this.base.add(customPlane);
267 | customPlane.visible = false;
268 | this.customWirePlanes.push(customPlane);
269 | }
270 |
271 | // draw halo
272 | material = new THREE.LineBasicMaterial({ color: 0xFFFFFF, wireframe:true, linewidth:.5 });
273 | geometry = new THREE.Geometry();
274 | geometry.vertices.push(new THREE.Vector3(), new THREE.Vector3());
275 | this.haloLine = new THREE.Line(geometry, material);
276 | this.haloLine.type = THREE.Lines;
277 | this.base.add(this.haloLine);
278 |
279 | material = new THREE.LineBasicMaterial({ color: 0xFFFFFF, wireframe:true, linewidth:.5});
280 | geometry = new THREE.Geometry();
281 | for(i = 0; i < this.totalVerticesH; i++) {
282 | geometry.vertices.push(new THREE.Vector3(Math.random()*100-50, Math.random()*100-50, Math.random()*100-50 ));
283 | }
284 | this.halo = new THREE.Line( geometry, material );
285 | this.halo.type = THREE.LineStrip;
286 | this.base.add(this.halo);
287 |
288 | // draw sphere
289 | geometry = new THREE.SphereGeometry( 1, 5, 5 );
290 | material = new THREE.MeshBasicMaterial( { color: 0xFFFFFF, wireframe:true, linewidth:.5 } )
291 |
292 | this.haloDot = new THREE.Mesh( geometry, material );
293 | this.base.add(this.haloDot);
294 |
295 | return this;
296 | };
297 |
298 |
299 | // ---------------------------------------------------------
300 | // utility
301 | // ---------------------------------------------------------
302 |
303 | // strip order is based on fold direction
304 | //
305 | // strip order 1 strip order 2 totalPlanesH distribution
306 | // 0 - 3 - 6 0 - 3 - 6 1 plane = 3 + 6
307 | // | \ | / | | / | \ | 2 plane = 3 + 6 + 6
308 | // 1 - 4 - 7 1 - 4 - 7 3 plane = 3 + 6 + 6 + 6
309 | // | / | \ | | \ | / |
310 | // 2 - 5 - 8 2 - 5 - 8
311 | this.getCustomGeometry = function(totalPlanesH, orderId, offset, height){
312 | var geometry = new THREE.Geometry();
313 | var id = 0;
314 | var percentage = 0;
315 | var i,j;
316 | var totalVertices = 3+(6)*totalPlanesH;
317 | var incV = 3;
318 | var incH = 1 + (2)*totalPlanesH;
319 |
320 | for(i = 0; i < totalVertices; i++) {
321 | geometry.vertices.push(new THREE.Vector3());
322 | }
323 |
324 | for(j = 0; j < incH; j++) {
325 | for(i = 0; i < incV; i++) {
326 | percentage = j/(incH-1.0)*TWO_PI;
327 | geometry.vertices[id].x = Math.sin(percentage)*100;
328 | geometry.vertices[id].y = i/(incV-1)*height + offset;
329 | geometry.vertices[id].z = Math.cos(percentage)*100;
330 | id++;
331 | }
332 | }
333 |
334 | if(orderId%2===0){
335 | for(j = 0; j < totalPlanesH; j++) {
336 | id = j*6;
337 |
338 | geometry.faces.push( new THREE.Face3( id+3, id+6, id+7 ) );
339 | geometry.faces.push( new THREE.Face3( id+3, id+7, id+4 ) );
340 | geometry.faces.push( new THREE.Face3( id+3, id+4, id+1 ) );
341 | geometry.faces.push( new THREE.Face3( id+3, id+1, id+0 ) );
342 | geometry.faces.push( new THREE.Face3( id+5, id+2, id+1 ) );
343 | geometry.faces.push( new THREE.Face3( id+5, id+1, id+4 ) );
344 | geometry.faces.push( new THREE.Face3( id+5, id+4, id+7 ) );
345 | geometry.faces.push( new THREE.Face3( id+5, id+7, id+8 ) );
346 | }
347 | } else {
348 | for(j = 0; j < totalPlanesH; j++) {
349 | id = j*6;
350 | geometry.faces.push( new THREE.Face3( id+4, id+1, id+0 ) );
351 | geometry.faces.push( new THREE.Face3( id+4, id+0, id+3 ) );
352 | geometry.faces.push( new THREE.Face3( id+4, id+3, id+6 ) );
353 | geometry.faces.push( new THREE.Face3( id+4, id+6, id+7 ) );
354 |
355 | geometry.faces.push( new THREE.Face3( id+4, id+7, id+8 ) );
356 | geometry.faces.push( new THREE.Face3( id+4, id+8, id+5 ) );
357 | geometry.faces.push( new THREE.Face3( id+4, id+5, id+2 ) );
358 | geometry.faces.push( new THREE.Face3( id+4, id+2, id+1 ) );
359 | }
360 | }
361 |
362 | geometry.computeFaceNormals();
363 | geometry.computeVertexNormals();
364 | return geometry;
365 | };
366 |
367 | // ---------------------------------------------------------
368 | // listeners
369 | // ---------------------------------------------------------
370 | this.onDocumentMouseDown = function(event) {
371 | this.traceFunction("onDocumentMouseDown");
372 | event.preventDefault();
373 |
374 | var mouse = new THREE.Vector2();
375 | mouse.x = ( event.clientX / (window.innerWidth-LILYPAD.Params.guiWidth) ) * 2 - 1;
376 | mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
377 | var vector = new THREE.Vector3( mouse.x, mouse.y, 0.5 );
378 | this.projector.unprojectVector( vector, this.camera );
379 | var raycaster = new THREE.Raycaster( this.camera.position, vector.sub( this.camera.position ).normalize() );
380 | var intersects = raycaster.intersectObjects( [this.water] );
381 | if ( intersects.length > 0 ) {
382 | this.dispatchEvent("MORPH_SHAPE",[]);
383 | } else {
384 |
385 | }
386 | };
387 |
388 | // ---------------------------------------------------------
389 | // public functions
390 | // ---------------------------------------------------------
391 |
392 | this.parse = function() {
393 | var i,j,k,id,
394 | particle,
395 | faceNormal,
396 | geometry,
397 | material;
398 |
399 | this.base.rotation.y += LILYPAD.Params.orbitSpeed;
400 |
401 | var centerSpeed = LILYPAD.Params.centerSpeed*.1;
402 | var noiseSpeed = LILYPAD.Params.noiseSpeed;
403 | var noiseAmount = LILYPAD.Params.noiseAmount;
404 | var noiseIntensity = LILYPAD.Params.noiseIntensity;
405 | var multiplier = LILYPAD.Params.multiplier;
406 | var centerRadius = LILYPAD.Params.centerRadius;
407 | var centerOffset = LILYPAD.Params.centerOffset;
408 |
409 | var waterHeight = LILYPAD.Params.waterHeight;
410 | var outerRadius = LILYPAD.Params.radius;
411 | var radiusRange = LILYPAD.Params.radiusRange;
412 | var wrapAmount = LILYPAD.Params.wrapAmount;
413 | var spikes = 0;
414 | var maxHeight = 0;
415 |
416 | var heightCountIncrement = (multiplier*2-multiplier)
417 | var heightOffset = LILYPAD.Params.heightOffset;
418 | var maxHeightRange = LILYPAD.Params.maxHeightRange;
419 | var heightCounter = -(this.totalVerticesV-1)*.5 * heightCountIncrement;
420 |
421 | var heightExtra = 0;
422 | var isOdd = null;
423 | var isEven = null;
424 |
425 | var centerX, centerY, centerZ;
426 |
427 | var wrappOffset = (1-wrapAmount)*TWO_PI*.5;
428 | var wrappMultiplier = (wrapAmount);
429 | var a, b;
430 |
431 | geometry = this.particles.geometry;
432 | id = 0;
433 |
434 | for(j = 0; j < this.totalVerticesV; j++) {
435 | for(i = 0; i < this.totalVerticesH; i++) {
436 |
437 | // fold specifically meant to account for tiling along a polar/clynidrical map
438 | // http://www.sjeiti.com/creating-tileable-noise-maps/
439 | percentage = ((i+this.count)/(this.totalVerticesH-1))*TWO_PI;
440 | fold = this.perlin.noise3d( Math.cos(percentage)*noiseAmount+this.count*.1, Math.sin(percentage)*noiseAmount, (j/this.totalVerticesV+this.count*.1));
441 | fold *= noiseIntensity;
442 |
443 | // spikes calculation
444 | outerRadius = LILYPAD.Params.radius - j/(this.totalVerticesV-1)*radiusRange * LILYPAD.Params.radius;
445 | spikes = outerRadius - fold*outerRadius;
446 | maxHeight = fold*multiplier*10;
447 | heightCountIncrement = (multiplier*2-multiplier)
448 |
449 | isOdd = i%2==1;
450 | isEven = i%2==0;
451 |
452 | // center radius motion
453 | percentage = (j/this.totalVerticesV+this.centerCount)*TWO_PI;
454 | centerX = Math.cos(percentage)*centerRadius*(j/this.totalVerticesV*2-1 + centerOffset);
455 | centerZ = Math.sin(percentage)*centerRadius*(j/this.totalVerticesV*2-1 + centerOffset);
456 |
457 | heightExtra = 0;
458 | if(isEven && j%4==0){
459 | heightExtra += maxHeight;
460 | } else if(isEven && j%4==2){
461 | heightExtra -= maxHeight;
462 | } else if(isOdd && j%4==2){
463 | heightExtra += maxHeight;
464 | } else if(isOdd && j%4==0){
465 | heightExtra -= maxHeight;
466 | }
467 |
468 | percentage = i/(this.totalVerticesH-1.0) * TWO_PI * wrappMultiplier + wrappOffset;
469 |
470 | if(isEven && j%4==1 || isOdd && j%4==3){
471 | geometry.vertices[id].x = Math.sin(percentage)*outerRadius + centerX;
472 | // geometry.vertices[id].y = maxHeight; //heightCounter+heightExtra;
473 | geometry.vertices[id].y = maxHeight + this.maxHeightCache[id][0]; //heightCounter+heightExtra;
474 | geometry.vertices[id].z = Math.cos(percentage)*outerRadius + centerZ;
475 |
476 | } else {
477 | geometry.vertices[id].x = Math.sin(percentage)*outerRadius + centerX;
478 | // geometry.vertices[id].y = this.maxHeightCache[id][this.maxHeightCacheSize-1]; //heightCounter+heightExtra;
479 | geometry.vertices[id].y = maxHeight*maxHeightRange + heightOffset; //heightCounter+heightExtra;
480 | geometry.vertices[id].z = Math.cos(percentage)*outerRadius + centerZ;
481 | }
482 |
483 | id++;
484 | }
485 |
486 | heightCounter += heightCountIncrement;
487 | }
488 |
489 | percentage = (this.centerCount)*TWO_PI;
490 | centerX = Math.cos(percentage)*centerRadius*(j/this.totalVerticesV*2-1 + centerOffset);
491 | centerZ = Math.sin(percentage)*centerRadius*(j/this.totalVerticesV*2-1 + centerOffset);
492 |
493 | // adjusts color
494 | this.colorOffset += LILYPAD.Params.colorSpeed;
495 | var colorRange = LILYPAD.Params.colorRange;
496 |
497 | for(i = 0; i < this.totalPlanesV; i++) {
498 | this.customPlanes[i].material.color = new THREE.Color().setHSL( (i/this.totalPlanesV*colorRange + this.colorOffset)%1 , .75, .5);
499 | }
500 | this.water.material.color = new THREE.Color().setHSL( (1*(colorRange) + this.colorOffset+.125)%1 , 1, .25);
501 | this.ground.material.color = new THREE.Color().setHSL( (1*(colorRange) + this.colorOffset+.125)%1 , .5, .05);
502 |
503 | // var clearColor = new THREE.Color().setHSL( (1*(colorRange) + this.colorOffset+.15)%1 , 1.0, .75);
504 | // this.renderer.setClearColor(clearColor);
505 |
506 |
507 | // assigns vertices from particles to planes
508 | // order is refactored to traverse from x -> y to y -> x
509 | var vertice;
510 | var particle;
511 | var kOffset, jOffset, iOffset;
512 | var verticesPerPlane = this.totalPlanesH*4+2;
513 | for(k = 0; k < this.totalPlanesV; k++) {
514 | id = 0;
515 | for(j = 0; j < this.totalVerticesH; j++) {
516 | for(i = 0; i < 3; i++) {
517 | kOffset = k * (verticesPerPlane);
518 | jOffset = i * this.totalVerticesH;
519 | iOffset = j;
520 | this.customPlanes[k].geometry.vertices[id].copy( this.particles.geometry.vertices[kOffset + jOffset + iOffset]);
521 | this.customWirePlanes[k].geometry.vertices[id].copy( this.particles.geometry.vertices[kOffset + jOffset + iOffset]);
522 | id++;
523 | }
524 | }
525 | }
526 |
527 | var scalar = 4;//centerRadius*centerOffset;
528 |
529 | outerRadius = LILYPAD.Params.radius - LILYPAD.Params.radius*radiusRange;
530 | for(j = 0; j < this.totalVerticesH; j++) {
531 | percentage = j/(this.totalVerticesH-1)*TWO_PI;
532 |
533 | fold = this.perlin.noise3d( Math.cos(percentage)*noiseAmount, Math.sin(percentage)*noiseAmount, (this.count));
534 | fold *= noiseIntensity*.5;
535 |
536 | // spikes calculation
537 | outerRadius = LILYPAD.Params.radius*1.125 - radiusRange * LILYPAD.Params.radius;
538 | spikes = outerRadius - fold*outerRadius;
539 | maxHeight = fold*multiplier;
540 |
541 | this.halo.geometry.vertices[j].x = Math.cos(percentage)*outerRadius + 0;
542 | this.halo.geometry.vertices[j].y = 200 + maxHeight;//200 + waterHeight;
543 | this.halo.geometry.vertices[j].z = Math.sin(percentage)*outerRadius + 0;
544 | }
545 |
546 | percentage = (this.centerCount)*TWO_PI;
547 |
548 | fold = this.perlin.noise3d( Math.cos(percentage)*noiseAmount, Math.sin(percentage)*noiseAmount, (this.count));
549 | fold *= noiseIntensity;
550 | outerRadius = LILYPAD.Params.radius*1.125 - radiusRange * LILYPAD.Params.radius;
551 | spikes = outerRadius - fold*outerRadius;
552 | maxHeight = fold*multiplier*.5;
553 |
554 | this.haloLine.geometry.vertices[0].x = centerX;
555 | this.haloLine.geometry.vertices[0].y = 200 + maxHeight;
556 | this.haloLine.geometry.vertices[0].z = centerZ;
557 |
558 | this.haloLine.geometry.vertices[1].x = Math.cos(percentage)*outerRadius + 0;
559 | this.haloLine.geometry.vertices[1].y = 200 + maxHeight;//200+waterHeight;
560 | this.haloLine.geometry.vertices[1].z = Math.sin(percentage)*outerRadius + 0;
561 |
562 | this.haloDot.position.x = centerX;
563 | this.haloDot.position.y = 200 + maxHeight;
564 | this.haloDot.position.z = centerZ;
565 |
566 | this.centerCount+= centerSpeed;
567 | this.count+=noiseSpeed*.1;
568 |
569 | // changes the y position of the ground relative to shape
570 | this.water.position.y = waterHeight;
571 |
572 | // changes light source
573 | var percentage = this.count*.05*TWO_PI;
574 | this.dirLight.position.x = Math.cos(percentage)*100;
575 | this.dirLight.position.z = Math.sin(percentage)*100;
576 |
577 | return this;
578 | };
579 |
580 | this.draw = function() {
581 |
582 | // update particles
583 | this.particles.geometry.verticesNeedUpdate = true;
584 |
585 | // updates halo
586 | this.halo.geometry.verticesNeedUpdate = true;
587 | this.haloLine.geometry.verticesNeedUpdate = true;
588 |
589 | // update shapes
590 | for(i = 0; i < this.customPlanes.length; i++) {
591 | this.customPlanes[i].geometry.verticesNeedUpdate = true;
592 | this.customWirePlanes[i].geometry.verticesNeedUpdate = true;
593 | }
594 |
595 | this.controls.update();
596 | this.renderer.render( this.scene , this.camera );
597 |
598 | return this;
599 | };
600 |
601 | this.toggleWireFrame = function(){
602 | var i,total = this.customPlanes.length;
603 | if (this.particles.visible===false){
604 | this.particles.visible = true;
605 | this.water.visible = false;
606 | for(i=0;i",d.insertBefore(c.lastChild,d.firstChild)}function h(){var a=k.elements;return typeof a=="string"?a.split(" "):a}function i(a){var b={},c=a.createElement,e=a.createDocumentFragment,f=e();a.createElement=function(a){var e=(b[a]||(b[a]=c(a))).cloneNode();return k.shivMethods&&e.canHaveChildren&&!d.test(a)?f.appendChild(e):e},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/\w+/g,function(a){return b[a]=c(a),f.createElement(a),'c("'+a+'")'})+");return n}")(k,f)}function j(a){var b;return a.documentShived?a:(k.shivCSS&&!e&&(b=!!g(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),f||(b=!i(a)),b&&(a.documentShived=b),a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea)$/i,e,f;(function(){var a=b.createElement("a");a.innerHTML="",e="hidden"in a,f=a.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var k={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:j};a.html5=k,j(b)}(this,b),e._version=d,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+p.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return o.call(a)=="[object Function]"}function e(a){return typeof a=="string"}function f(){}function g(a){return!a||a=="loaded"||a=="complete"||a=="uninitialized"}function h(){var a=p.shift();q=1,a?a.t?m(function(){(a.t=="c"?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){a!="img"&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l={},o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};y[c]===1&&(r=1,y[c]=[],l=b.createElement(a)),a=="object"?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),a!="img"&&(r||y[c]===2?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i(b=="c"?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),p.length==1&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&o.call(a.opera)=="[object Opera]",l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return o.call(a)=="[object Array]"},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;fFPS';m.appendChild(g);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";m.appendChild(a);
5 | p=a.getContext("2d");p.fillStyle="rgb("+b.fps.bg.r+","+b.fps.bg.g+","+b.fps.bg.b+")";p.fillRect(0,0,a.width,a.height);C=p.getImageData(0,0,a.width,a.height);h=document.createElement("div");h.style.backgroundColor="rgb("+Math.floor(b.ms.bg.r/2)+","+Math.floor(b.ms.bg.g/2)+","+Math.floor(b.ms.bg.b/2)+")";h.style.padding="2px 0px 3px 0px";h.style.display="none";e.appendChild(h);i=document.createElement("div");i.style.fontFamily="Helvetica, Arial, sans-serif";i.style.textAlign="left";i.style.fontSize=
6 | "9px";i.style.color="rgb("+b.ms.fg.r+","+b.ms.fg.g+","+b.ms.fg.b+")";i.style.margin="0px 0px 1px 3px";i.innerHTML='MS';h.appendChild(i);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";h.appendChild(a);r=a.getContext("2d");r.fillStyle="rgb("+b.ms.bg.r+","+b.ms.bg.g+","+b.ms.bg.b+")";r.fillRect(0,0,a.width,a.height);F=r.getImageData(0,0,a.width,a.height);try{if(webkitPerformance&&webkitPerformance.memory.totalJSHeapSize)x=
7 | 3}catch(L){}j=document.createElement("div");j.style.backgroundColor="rgb("+Math.floor(b.mem.bg.r/2)+","+Math.floor(b.mem.bg.g/2)+","+Math.floor(b.mem.bg.b/2)+")";j.style.padding="2px 0px 3px 0px";j.style.display="none";e.appendChild(j);k=document.createElement("div");k.style.fontFamily="Helvetica, Arial, sans-serif";k.style.textAlign="left";k.style.fontSize="9px";k.style.color="rgb("+b.mem.fg.r+","+b.mem.fg.g+","+b.mem.fg.b+")";k.style.margin="0px 0px 1px 3px";k.innerHTML='MEM';
8 | j.appendChild(k);a=document.createElement("canvas");a.width=74;a.height=30;a.style.display="block";a.style.marginLeft="3px";j.appendChild(a);t=a.getContext("2d");t.fillStyle="#301010";t.fillRect(0,0,a.width,a.height);I=t.getImageData(0,0,a.width,a.height);return{domElement:e,update:function(){y++;l=(new Date).getTime();q=l-J;D=Math.min(D,q);E=Math.max(E,q);w(F.data,Math.min(30,30-q/200*30),"ms");i.innerHTML=''+q+" MS ("+D+"-"+E+")";r.putImageData(F,0,0);J=l;if(l>
9 | z+1E3){o=Math.round(y*1E3/(l-z));A=Math.min(A,o);B=Math.max(B,o);w(C.data,Math.min(30,30-o/100*30),"fps");g.innerHTML=''+o+" FPS ("+A+"-"+B+")";p.putImageData(C,0,0);if(x==3){s=webkitPerformance.memory.usedJSHeapSize*9.54E-7;G=Math.min(G,s);H=Math.max(H,s);w(I.data,Math.min(30,30-s/2),"mem");k.innerHTML=''+Math.round(s)+" MEM ("+Math.round(G)+"-"+Math.round(H)+")";t.putImageData(I,0,0)}z=l;y=0}}}};
10 |
11 |
--------------------------------------------------------------------------------
/vendor/jquery.easing.1.3.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
3 | *
4 | * Uses the built in easing capabilities added In jQuery 1.1
5 | * to offer multiple easing options
6 | *
7 | * TERMS OF USE - jQuery Easing
8 | *
9 | * Open source under the BSD License.
10 | *
11 | * Copyright © 2008 George McGinley Smith
12 | * All rights reserved.
13 | *
14 | * Redistribution and use in source and binary forms, with or without modification,
15 | * are permitted provided that the following conditions are met:
16 | *
17 | * Redistributions of source code must retain the above copyright notice, this list of
18 | * conditions and the following disclaimer.
19 | * Redistributions in binary form must reproduce the above copyright notice, this list
20 | * of conditions and the following disclaimer in the documentation and/or other materials
21 | * provided with the distribution.
22 | *
23 | * Neither the name of the author nor the names of contributors may be used to endorse
24 | * or promote products derived from this software without specific prior written permission.
25 | *
26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
27 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
31 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34 | * OF THE POSSIBILITY OF SUCH DAMAGE.
35 | *
36 | */
37 |
38 | // t: current time, b: begInnIng value, c: change In value, d: duration
39 | jQuery.easing['jswing'] = jQuery.easing['swing'];
40 |
41 | jQuery.extend( jQuery.easing,
42 | {
43 | def: 'easeOutQuad',
44 | swing: function (x, t, b, c, d) {
45 | //alert(jQuery.easing.default);
46 | return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
47 | },
48 | easeInQuad: function (x, t, b, c, d) {
49 | return c*(t/=d)*t + b;
50 | },
51 | easeOutQuad: function (x, t, b, c, d) {
52 | return -c *(t/=d)*(t-2) + b;
53 | },
54 | easeInOutQuad: function (x, t, b, c, d) {
55 | if ((t/=d/2) < 1) return c/2*t*t + b;
56 | return -c/2 * ((--t)*(t-2) - 1) + b;
57 | },
58 | easeInCubic: function (x, t, b, c, d) {
59 | return c*(t/=d)*t*t + b;
60 | },
61 | easeOutCubic: function (x, t, b, c, d) {
62 | return c*((t=t/d-1)*t*t + 1) + b;
63 | },
64 | easeInOutCubic: function (x, t, b, c, d) {
65 | if ((t/=d/2) < 1) return c/2*t*t*t + b;
66 | return c/2*((t-=2)*t*t + 2) + b;
67 | },
68 | easeInQuart: function (x, t, b, c, d) {
69 | return c*(t/=d)*t*t*t + b;
70 | },
71 | easeOutQuart: function (x, t, b, c, d) {
72 | return -c * ((t=t/d-1)*t*t*t - 1) + b;
73 | },
74 | easeInOutQuart: function (x, t, b, c, d) {
75 | if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
76 | return -c/2 * ((t-=2)*t*t*t - 2) + b;
77 | },
78 | easeInQuint: function (x, t, b, c, d) {
79 | return c*(t/=d)*t*t*t*t + b;
80 | },
81 | easeOutQuint: function (x, t, b, c, d) {
82 | return c*((t=t/d-1)*t*t*t*t + 1) + b;
83 | },
84 | easeInOutQuint: function (x, t, b, c, d) {
85 | if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
86 | return c/2*((t-=2)*t*t*t*t + 2) + b;
87 | },
88 | easeInSine: function (x, t, b, c, d) {
89 | return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
90 | },
91 | easeOutSine: function (x, t, b, c, d) {
92 | return c * Math.sin(t/d * (Math.PI/2)) + b;
93 | },
94 | easeInOutSine: function (x, t, b, c, d) {
95 | return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
96 | },
97 | easeInExpo: function (x, t, b, c, d) {
98 | return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
99 | },
100 | easeOutExpo: function (x, t, b, c, d) {
101 | return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
102 | },
103 | easeInOutExpo: function (x, t, b, c, d) {
104 | if (t==0) return b;
105 | if (t==d) return b+c;
106 | if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
107 | return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
108 | },
109 | easeInCirc: function (x, t, b, c, d) {
110 | return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
111 | },
112 | easeOutCirc: function (x, t, b, c, d) {
113 | return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
114 | },
115 | easeInOutCirc: function (x, t, b, c, d) {
116 | if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
117 | return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
118 | },
119 | easeInElastic: function (x, t, b, c, d) {
120 | var s=1.70158;var p=0;var a=c;
121 | if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
122 | if (a < Math.abs(c)) { a=c; var s=p/4; }
123 | else var s = p/(2*Math.PI) * Math.asin (c/a);
124 | return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
125 | },
126 | easeOutElastic: function (x, t, b, c, d) {
127 | var s=1.70158;var p=0;var a=c;
128 | if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
129 | if (a < Math.abs(c)) { a=c; var s=p/4; }
130 | else var s = p/(2*Math.PI) * Math.asin (c/a);
131 | return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
132 | },
133 | easeInOutElastic: function (x, t, b, c, d) {
134 | var s=1.70158;var p=0;var a=c;
135 | if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
136 | if (a < Math.abs(c)) { a=c; var s=p/4; }
137 | else var s = p/(2*Math.PI) * Math.asin (c/a);
138 | if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
139 | return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
140 | },
141 | easeInBack: function (x, t, b, c, d, s) {
142 | if (s == undefined) s = 1.70158;
143 | return c*(t/=d)*t*((s+1)*t - s) + b;
144 | },
145 | easeOutBack: function (x, t, b, c, d, s) {
146 | if (s == undefined) s = 1.70158;
147 | return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
148 | },
149 | easeInOutBack: function (x, t, b, c, d, s) {
150 | if (s == undefined) s = 1.70158;
151 | if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
152 | return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
153 | },
154 | easeInBounce: function (x, t, b, c, d) {
155 | return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
156 | },
157 | easeOutBounce: function (x, t, b, c, d) {
158 | if ((t/=d) < (1/2.75)) {
159 | return c*(7.5625*t*t) + b;
160 | } else if (t < (2/2.75)) {
161 | return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
162 | } else if (t < (2.5/2.75)) {
163 | return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
164 | } else {
165 | return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
166 | }
167 | },
168 | easeInOutBounce: function (x, t, b, c, d) {
169 | if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
170 | return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
171 | }
172 | });
173 |
174 | /*
175 | *
176 | * TERMS OF USE - EASING EQUATIONS
177 | *
178 | * Open source under the BSD License.
179 | *
180 | * Copyright © 2001 Robert Penner
181 | * All rights reserved.
182 | *
183 | * Redistribution and use in source and binary forms, with or without modification,
184 | * are permitted provided that the following conditions are met:
185 | *
186 | * Redistributions of source code must retain the above copyright notice, this list of
187 | * conditions and the following disclaimer.
188 | * Redistributions in binary form must reproduce the above copyright notice, this list
189 | * of conditions and the following disclaimer in the documentation and/or other materials
190 | * provided with the distribution.
191 | *
192 | * Neither the name of the author nor the names of contributors may be used to endorse
193 | * or promote products derived from this software without specific prior written permission.
194 | *
195 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
196 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
197 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
198 | * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
199 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
200 | * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
201 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
202 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
203 | * OF THE POSSIBILITY OF SUCH DAMAGE.
204 | *
205 | */
--------------------------------------------------------------------------------
/vendor/jstween-1.0.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | * JSTween JavaScript Library v1.0
3 | * http://www.jstween.org/
4 | *
5 | * Copyright 2011, Marco Wolfsheimer
6 | * JSTween by Marco Wolfsheimer is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
7 | *
8 | * Date: Sun Mar 13 12:46:40 2011 -0000
9 | */
10 | var JSTween=(function(e){var d=/[\-]{0,1}[0-9\.]{1,}|#[0-9\.abcdef]{3,6}/gi,r=/[pxemtcin%]{1,2}|deg/gi,p=/[0-9\.\-]{1,}/gi,a=/[0-9a-f]{3,6}/gi,j=/^#/,f=/^[0-9\.\-]{1,}([pxemtcin%]{1,2}|deg)$/,m=/[a-z]{1,}/,q=/^rgb\(/,c=/^scroll/,g=/-([a-z])/ig,u=/^-ms/ig,o={opacity:["opacity","-moz-opacity","filter"],shadow:["box-shadow","-moz-box-shadow","-o-box-shadow","-ms-box-shadow","-webkit-box-shadow"],transform:["-moz-transform","transform","-o-transform","-ms-transform","-webkit-transform"],transformOrigin:["-moz-transform-origin","transform-origin","-o-transform-origin","-ms-transform-origin","-webkit-transform-origin"],borderRadius:["-moz-border-radius","border-radius","-webkit-border-radius"],borderRadiusTopLeft:["-moz-border-radius-topleft","border-top-left-radius","-webkit-border-top-left-radius"],borderRadiusTopRight:["-moz-border-radius-topright","border-top-right-radius","-webkit-border-top-right-radius"],borderRadiusBottomLeft:["-moz-border-radius-bottomleft","border-bottom-left-radius","-webkit-border-bottom-left-radius"],borderRadiusBottomRight:["-moz-border-radius-bottomright","border-bottom-right-radius","-webkit-border-bottom-right-radius"],backgroundSize:["background-size","-moz-background-size","-o-background-size","-webkit-background-size"]},t={},l=[],h=0,n=0,v=false,b=false,k=0,s={};e.init=function(){e.framerate(45);e.cssSupport();try{e.attach()}catch(w){return}};e.attach=function(){jQuery.JSTween=e;jQuery.fn.tween=function(w){var x,y=this.length;for(x=0;x0){if(this[0].__animate!==undefined){if(w!==undefined&&this[0].__animate.state[w]!==undefined){return this[0].__animate.state[w]}else{if(w===undefined){return this[0].__animate.state}}}}};jQuery.fn.transform=function(y){var w,x=this.length;for(w=0;wx.stop){x.stop=w[y].end}}}x.start=x.stop;for(y in w){if(w.hasOwnProperty(y)){if(w[y].timen){n=B}}}if(typeof z.onStart==="function"){e.addCallback(h+(Math.round(w.start*s.frameRate)),D,"callback",z.onStart)}if(typeof z.onFrame==="function"){for(frame=h+Math.round(w.start*s.frameRate);frame<=h+Math.round(w.stop*s.frameRate);frame++){e.addCallback(frame,D,"callback",z.onFrame)}}if(typeof z.onStop==="function"){e.addCallback(h+(Math.round(w.stop*s.frameRate)),D,"callback",z.onStop)}};e.makeFrame=function(B,w,y,A,x,C,z){if(w!==undefined){if(t[B]===undefined){t[B]={};t[B][w]={};t[B][w][y]={value:A,units:x,callback:[],skip:z}}else{if(t[B][w]===undefined){t[B][w]={};t[B][w][y]={value:A,units:x,callback:[],skip:z}}else{if(t[B][w][y]===undefined){t[B][w][y]={value:A,units:x,callback:[],skip:z}}else{if(A!==false){t[B][w][y].value=A}if(x!==false){t[B][w][y].units=x}t[B][w][y].skip=z}}}if(typeof C==="function"){t[B][w][y].callback.push(C)}}else{if(t[B]===undefined){t[B]={}}}};e.addCallback=function(y,w,x,z){e.makeFrame(y,w,x,false,false,z,true)};e.play=function(){if(v===false){b=false;v=true;k=e.timestamp();e.playHead()}};e.clear=function(w,x){var y;if(w!==undefined&&x!==undefined&&w.__animate!==undefined){for(y in t){if(t.hasOwnProperty(y)&&t[y][w.__animate.id]!==undefined&&t[y][w.__animate.id][x]!==undefined){delete t[y][w.__animate.id][x]}}}else{if(w!==undefined&&w.__animate!==undefined){for(y in t){if(t.hasOwnProperty(y)&&t[y][w.__animate.id]!==undefined){delete t[y][w.__animate.id]}}}else{for(y in t){if(t.hasOwnProperty(y)){delete t[y]}}}}};e.timestamp=function(){var w=new Date();return w.getTime()};e.playHead=function(){var z,w,y,x;if(h<=n){x=(s.frameDelay-((e.timestamp()-k)-(h*s.frameDelay)));if(x<0){x=0}else{if(x>s.frameDelay){x=s.frameDelay}}setTimeout(function(){e.playHead(x?true:false)},x);for(w in t[h]){if(t[h].hasOwnProperty(w)){z=t[h][w];for(y in z){if(z.hasOwnProperty(y)){e.action(w,y,z[y].value,z[y].units,z[y].callback,(z[y].skip===true?true:(x?true:false)))}}}}delete t[h];h++;b=e.timestamp()}else{b=v=false;h=0}};e.action=function(w,z,A,x,B,y){if(y===true&&A!==false){switch(z){case"zIndex":l[w].style.zIndex=A;break;case"alpha":e.opacity(l[w],A);break;case"transparency":e.opacity(l[w],A);break;case"opacity":e.opacity(l[w],A);break;case"scroll":e.scroll(l[w],z,A);break;case"scrollTop":e.scroll(l[w],z,A);break;case"scrollLeft":e.scroll(l[w],z,A);break;case"scrollTo":e.scroll(l[w],z,A);break;case"shadow":e.shadow(l[w],A);break;case"boxShadow":e.shadow(l[w],A);break;case"rotate":e.rotate(l[w],A);break;case"transformOrigin":e.transformOrigin(l[w],A);break;case"transform":e.transform(l[w],A);break;case"backgroundSize":e.backgroundSize(l[w],A);break;case"borderRadius":e.borderRadius(l[w],A,x);break;case"borderRadiusTopRight":e.borderRadiusCorner(l[w],"top","right",A,x);break;case"borderRadiusTopLeft":e.borderRadiusCorner(l[w],"top","left",A,x);break;case"borderRadiusBottomRight":e.borderRadiusCorner(l[w],"bottom","right",A,x);break;case"borderRadiusBottomLeft":e.borderRadiusCorner(l[w],"bottom","left",A,x);break;default:if(typeof A==="string"){l[w].style[z]=A}else{l[w].style[z]=A+x}break}}l[w].__animate.state[z]={value:A,units:x};if(B!==undefined&&B.length>0){for(i=0;iy0) {i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1)
60 | else {i1=0; j1=1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1)
61 | // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
62 | // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
63 | // c = (3-sqrt(3))/6
64 | var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
65 | var y1 = y0 - j1 + G2;
66 | var x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords
67 | var y2 = y0 - 1.0 + 2.0 * G2;
68 | // Work out the hashed gradient indices of the three simplex corners
69 | var ii = i & 255;
70 | var jj = j & 255;
71 | var gi0 = this.perm[ii+this.perm[jj]] % 12;
72 | var gi1 = this.perm[ii+i1+this.perm[jj+j1]] % 12;
73 | var gi2 = this.perm[ii+1+this.perm[jj+1]] % 12;
74 | // Calculate the contribution from the three corners
75 | var t0 = 0.5 - x0*x0-y0*y0;
76 | if(t0<0) n0 = 0.0;
77 | else {
78 | t0 *= t0;
79 | n0 = t0 * t0 * this.dot(this.grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient
80 | }
81 | var t1 = 0.5 - x1*x1-y1*y1;
82 | if(t1<0) n1 = 0.0;
83 | else {
84 | t1 *= t1;
85 | n1 = t1 * t1 * this.dot(this.grad3[gi1], x1, y1);
86 | }
87 | var t2 = 0.5 - x2*x2-y2*y2;
88 | if(t2<0) n2 = 0.0;
89 | else {
90 | t2 *= t2;
91 | n2 = t2 * t2 * this.dot(this.grad3[gi2], x2, y2);
92 | }
93 | // Add contributions from each corner to get the final noise value.
94 | // The result is scaled to return values in the interval [-1,1].
95 | return 70.0 * (n0 + n1 + n2);
96 | };
97 |
98 | // 3D simplex noise
99 | SimplexNoise.prototype.noise3d = function(xin, yin, zin) {
100 | var n0, n1, n2, n3; // Noise contributions from the four corners
101 | // Skew the input space to determine which simplex cell we're in
102 | var F3 = 1.0/3.0;
103 | var s = (xin+yin+zin)*F3; // Very nice and simple skew factor for 3D
104 | var i = Math.floor(xin+s);
105 | var j = Math.floor(yin+s);
106 | var k = Math.floor(zin+s);
107 | var G3 = 1.0/6.0; // Very nice and simple unskew factor, too
108 | var t = (i+j+k)*G3;
109 | var X0 = i-t; // Unskew the cell origin back to (x,y,z) space
110 | var Y0 = j-t;
111 | var Z0 = k-t;
112 | var x0 = xin-X0; // The x,y,z distances from the cell origin
113 | var y0 = yin-Y0;
114 | var z0 = zin-Z0;
115 | // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
116 | // Determine which simplex we are in.
117 | var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
118 | var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
119 | if(x0>=y0) {
120 | if(y0>=z0)
121 | { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order
122 | else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order
123 | else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order
124 | }
125 | else { // x0 0 ) {
147 |
148 | var container = this.getContainerDimensions();
149 | var halfWidth = container.size[ 0 ] / 2;
150 | var halfHeight = container.size[ 1 ] / 2;
151 |
152 | this.moveState.yawLeft = - ( ( event.pageX - container.offset[ 0 ] ) - halfWidth ) / halfWidth;
153 | this.moveState.pitchDown = ( ( event.pageY - container.offset[ 1 ] ) - halfHeight ) / halfHeight;
154 |
155 | this.updateRotationVector();
156 |
157 | }
158 |
159 | };
160 |
161 | this.mouseup = function( event ) {
162 |
163 | event.preventDefault();
164 | event.stopPropagation();
165 |
166 | if ( this.dragToLook ) {
167 |
168 | this.mouseStatus --;
169 |
170 | this.moveState.yawLeft = this.moveState.pitchDown = 0;
171 |
172 | } else {
173 |
174 | switch ( event.button ) {
175 |
176 | case 0: this.moveState.forward = 0; break;
177 | case 2: this.moveState.back = 0; break;
178 |
179 | }
180 |
181 | this.updateMovementVector();
182 |
183 | }
184 |
185 | this.updateRotationVector();
186 |
187 | };
188 |
189 | this.update = function( delta ) {
190 |
191 | var moveMult = delta * this.movementSpeed;
192 | var rotMult = delta * this.rollSpeed;
193 |
194 | this.object.translateX( this.moveVector.x * moveMult );
195 | this.object.translateY( this.moveVector.y * moveMult );
196 | this.object.translateZ( this.moveVector.z * moveMult );
197 |
198 | this.tmpQuaternion.set( this.rotationVector.x * rotMult, this.rotationVector.y * rotMult, this.rotationVector.z * rotMult, 1 ).normalize();
199 | this.object.quaternion.multiply( this.tmpQuaternion );
200 |
201 | // expose the rotation vector for convenience
202 | this.object.rotation.setEulerFromQuaternion( this.object.quaternion, this.object.eulerOrder );
203 |
204 |
205 | };
206 |
207 | this.updateMovementVector = function() {
208 |
209 | var forward = ( this.moveState.forward || ( this.autoForward && !this.moveState.back ) ) ? 1 : 0;
210 |
211 | this.moveVector.x = ( -this.moveState.left + this.moveState.right );
212 | this.moveVector.y = ( -this.moveState.down + this.moveState.up );
213 | this.moveVector.z = ( -forward + this.moveState.back );
214 |
215 | //console.log( 'move:', [ this.moveVector.x, this.moveVector.y, this.moveVector.z ] );
216 |
217 | };
218 |
219 | this.updateRotationVector = function() {
220 |
221 | this.rotationVector.x = ( -this.moveState.pitchDown + this.moveState.pitchUp );
222 | this.rotationVector.y = ( -this.moveState.yawRight + this.moveState.yawLeft );
223 | this.rotationVector.z = ( -this.moveState.rollRight + this.moveState.rollLeft );
224 |
225 | //console.log( 'rotate:', [ this.rotationVector.x, this.rotationVector.y, this.rotationVector.z ] );
226 |
227 | };
228 |
229 | this.getContainerDimensions = function() {
230 |
231 | if ( this.domElement != document ) {
232 |
233 | return {
234 | size : [ this.domElement.offsetWidth, this.domElement.offsetHeight ],
235 | offset : [ this.domElement.offsetLeft, this.domElement.offsetTop ]
236 | };
237 |
238 | } else {
239 |
240 | return {
241 | size : [ window.innerWidth, window.innerHeight ],
242 | offset : [ 0, 0 ]
243 | };
244 |
245 | }
246 |
247 | };
248 |
249 | function bind( scope, fn ) {
250 |
251 | return function () {
252 |
253 | fn.apply( scope, arguments );
254 |
255 | };
256 |
257 | };
258 |
259 | this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
260 |
261 | this.domElement.addEventListener( 'mousemove', bind( this, this.mousemove ), false );
262 | this.domElement.addEventListener( 'mousedown', bind( this, this.mousedown ), false );
263 | this.domElement.addEventListener( 'mouseup', bind( this, this.mouseup ), false );
264 |
265 | this.domElement.addEventListener( 'keydown', bind( this, this.keydown ), false );
266 | this.domElement.addEventListener( 'keyup', bind( this, this.keyup ), false );
267 |
268 | this.updateMovementVector();
269 | this.updateRotationVector();
270 |
271 | };
272 |
--------------------------------------------------------------------------------
/vendor/three/controls/OrbitControls.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author qiao / https://github.com/qiao
3 | * @author mrdoob / http://mrdoob.com
4 | * @author alteredq / http://alteredqualia.com/
5 | * @author WestLangley / http://github.com/WestLangley
6 | */
7 |
8 | THREE.OrbitControls = function ( object, domElement ) {
9 |
10 | this.object = object;
11 | this.domElement = ( domElement !== undefined ) ? domElement : document;
12 |
13 | // API
14 |
15 | this.enabled = true;
16 |
17 | this.center = new THREE.Vector3();
18 |
19 | this.userZoom = true;
20 | this.userZoomSpeed = 1.0;
21 |
22 | this.userRotate = true;
23 | this.userRotateSpeed = 1.0;
24 |
25 | this.userPan = true;
26 | this.userPanSpeed = 2.0;
27 |
28 | this.autoRotate = false;
29 | this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
30 |
31 | this.minPolarAngle = 0; // radians
32 | this.maxPolarAngle = Math.PI; // radians
33 |
34 | this.minDistance = 0;
35 | this.maxDistance = Infinity;
36 |
37 | this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
38 |
39 | // internals
40 |
41 | var scope = this;
42 |
43 | var EPS = 0.000001;
44 | var PIXELS_PER_ROUND = 1800;
45 |
46 | var rotateStart = new THREE.Vector2();
47 | var rotateEnd = new THREE.Vector2();
48 | var rotateDelta = new THREE.Vector2();
49 |
50 | var zoomStart = new THREE.Vector2();
51 | var zoomEnd = new THREE.Vector2();
52 | var zoomDelta = new THREE.Vector2();
53 |
54 | var phiDelta = 0;
55 | var thetaDelta = 0;
56 | var scale = 1;
57 |
58 | var lastPosition = new THREE.Vector3();
59 |
60 | var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2 };
61 | var state = STATE.NONE;
62 |
63 | // events
64 |
65 | var changeEvent = { type: 'change' };
66 |
67 |
68 | this.rotateLeft = function ( angle ) {
69 |
70 | if ( angle === undefined ) {
71 |
72 | angle = getAutoRotationAngle();
73 |
74 | }
75 |
76 | thetaDelta -= angle;
77 |
78 | };
79 |
80 | this.rotateRight = function ( angle ) {
81 |
82 | if ( angle === undefined ) {
83 |
84 | angle = getAutoRotationAngle();
85 |
86 | }
87 |
88 | thetaDelta += angle;
89 |
90 | };
91 |
92 | this.rotateUp = function ( angle ) {
93 |
94 | if ( angle === undefined ) {
95 |
96 | angle = getAutoRotationAngle();
97 |
98 | }
99 |
100 | phiDelta -= angle;
101 |
102 | };
103 |
104 | this.rotateDown = function ( angle ) {
105 |
106 | if ( angle === undefined ) {
107 |
108 | angle = getAutoRotationAngle();
109 |
110 | }
111 |
112 | phiDelta += angle;
113 |
114 | };
115 |
116 | this.zoomIn = function ( zoomScale ) {
117 |
118 | if ( zoomScale === undefined ) {
119 |
120 | zoomScale = getZoomScale();
121 |
122 | }
123 |
124 | scale /= zoomScale;
125 |
126 | };
127 |
128 | this.zoomOut = function ( zoomScale ) {
129 |
130 | if ( zoomScale === undefined ) {
131 |
132 | zoomScale = getZoomScale();
133 |
134 | }
135 |
136 | scale *= zoomScale;
137 |
138 | };
139 |
140 | this.pan = function ( distance ) {
141 |
142 | distance.transformDirection( this.object.matrix );
143 | distance.multiplyScalar( scope.userPanSpeed );
144 |
145 | this.object.position.add( distance );
146 | this.center.add( distance );
147 |
148 | };
149 |
150 | this.update = function () {
151 |
152 | var position = this.object.position;
153 | var offset = position.clone().sub( this.center );
154 |
155 | // angle from z-axis around y-axis
156 |
157 | var theta = Math.atan2( offset.x, offset.z );
158 |
159 | // angle from y-axis
160 |
161 | var phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );
162 |
163 | if ( this.autoRotate ) {
164 |
165 | this.rotateLeft( getAutoRotationAngle() );
166 |
167 | }
168 |
169 | theta += thetaDelta;
170 | phi += phiDelta;
171 |
172 | // restrict phi to be between desired limits
173 | phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );
174 |
175 | // restrict phi to be betwee EPS and PI-EPS
176 | phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );
177 |
178 | var radius = offset.length() * scale;
179 |
180 | // restrict radius to be between desired limits
181 | radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );
182 |
183 | offset.x = radius * Math.sin( phi ) * Math.sin( theta );
184 | offset.y = radius * Math.cos( phi );
185 | offset.z = radius * Math.sin( phi ) * Math.cos( theta );
186 |
187 | position.copy( this.center ).add( offset );
188 |
189 | this.object.lookAt( this.center );
190 |
191 | thetaDelta = 0;
192 | phiDelta = 0;
193 | scale = 1;
194 |
195 | if ( lastPosition.distanceTo( this.object.position ) > 0 ) {
196 |
197 | this.dispatchEvent( changeEvent );
198 |
199 | lastPosition.copy( this.object.position );
200 |
201 | }
202 |
203 | };
204 |
205 |
206 | function getAutoRotationAngle() {
207 |
208 | return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
209 |
210 | }
211 |
212 | function getZoomScale() {
213 |
214 | return Math.pow( 0.95, scope.userZoomSpeed );
215 |
216 | }
217 |
218 | function onMouseDown( event ) {
219 |
220 | if ( scope.enabled === false ) return;
221 | if ( scope.userRotate === false ) return;
222 |
223 | event.preventDefault();
224 |
225 | if ( event.button === 0 ) {
226 |
227 | state = STATE.ROTATE;
228 |
229 | rotateStart.set( event.clientX, event.clientY );
230 |
231 | } else if ( event.button === 1 ) {
232 |
233 | state = STATE.ZOOM;
234 |
235 | zoomStart.set( event.clientX, event.clientY );
236 |
237 | } else if ( event.button === 2 ) {
238 |
239 | state = STATE.PAN;
240 |
241 | }
242 |
243 | document.addEventListener( 'mousemove', onMouseMove, false );
244 | document.addEventListener( 'mouseup', onMouseUp, false );
245 |
246 | }
247 |
248 | function onMouseMove( event ) {
249 |
250 | if ( scope.enabled === false ) return;
251 |
252 | event.preventDefault();
253 |
254 | if ( state === STATE.ROTATE ) {
255 |
256 | rotateEnd.set( event.clientX, event.clientY );
257 | rotateDelta.subVectors( rotateEnd, rotateStart );
258 |
259 | scope.rotateLeft( 2 * Math.PI * rotateDelta.x / PIXELS_PER_ROUND * scope.userRotateSpeed );
260 | scope.rotateUp( 2 * Math.PI * rotateDelta.y / PIXELS_PER_ROUND * scope.userRotateSpeed );
261 |
262 | rotateStart.copy( rotateEnd );
263 |
264 | } else if ( state === STATE.ZOOM ) {
265 |
266 | zoomEnd.set( event.clientX, event.clientY );
267 | zoomDelta.subVectors( zoomEnd, zoomStart );
268 |
269 | if ( zoomDelta.y > 0 ) {
270 |
271 | scope.zoomIn();
272 |
273 | } else {
274 |
275 | scope.zoomOut();
276 |
277 | }
278 |
279 | zoomStart.copy( zoomEnd );
280 |
281 | } else if ( state === STATE.PAN ) {
282 |
283 | var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
284 | var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
285 |
286 | scope.pan( new THREE.Vector3( - movementX, movementY, 0 ) );
287 |
288 | }
289 |
290 | }
291 |
292 | function onMouseUp( event ) {
293 |
294 | if ( scope.enabled === false ) return;
295 | if ( scope.userRotate === false ) return;
296 |
297 | document.removeEventListener( 'mousemove', onMouseMove, false );
298 | document.removeEventListener( 'mouseup', onMouseUp, false );
299 |
300 | state = STATE.NONE;
301 |
302 | }
303 |
304 | function onMouseWheel( event ) {
305 |
306 | if ( scope.enabled === false ) return;
307 | if ( scope.userZoom === false ) return;
308 |
309 | var delta = 0;
310 |
311 | if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
312 |
313 | delta = event.wheelDelta;
314 |
315 | } else if ( event.detail ) { // Firefox
316 |
317 | delta = - event.detail;
318 |
319 | }
320 |
321 | if ( delta > 0 ) {
322 |
323 | scope.zoomOut();
324 |
325 | } else {
326 |
327 | scope.zoomIn();
328 |
329 | }
330 |
331 | }
332 |
333 | function onKeyDown( event ) {
334 |
335 | if ( scope.enabled === false ) return;
336 | if ( scope.userPan === false ) return;
337 |
338 | switch ( event.keyCode ) {
339 |
340 | case scope.keys.UP:
341 | scope.pan( new THREE.Vector3( 0, 1, 0 ) );
342 | break;
343 | case scope.keys.BOTTOM:
344 | scope.pan( new THREE.Vector3( 0, - 1, 0 ) );
345 | break;
346 | case scope.keys.LEFT:
347 | scope.pan( new THREE.Vector3( - 1, 0, 0 ) );
348 | break;
349 | case scope.keys.RIGHT:
350 | scope.pan( new THREE.Vector3( 1, 0, 0 ) );
351 | break;
352 | }
353 |
354 | }
355 |
356 | this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
357 | this.domElement.addEventListener( 'mousedown', onMouseDown, false );
358 | this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );
359 | this.domElement.addEventListener( 'DOMMouseScroll', onMouseWheel, false ); // firefox
360 | this.domElement.addEventListener( 'keydown', onKeyDown, false );
361 |
362 | };
363 |
364 | THREE.OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );
365 |
--------------------------------------------------------------------------------
/vendor/three/controls/PathControls.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author alteredq / http://alteredqualia.com/
3 | */
4 |
5 | THREE.PathControls = function ( object, domElement ) {
6 |
7 | this.object = object;
8 | this.domElement = ( domElement !== undefined ) ? domElement : document;
9 |
10 | this.id = "PathControls" + THREE.PathControlsIdCounter ++;
11 |
12 | // API
13 |
14 | this.duration = 10 * 1000; // milliseconds
15 | this.waypoints = [];
16 |
17 | this.useConstantSpeed = true;
18 | this.resamplingCoef = 50;
19 |
20 | this.debugPath = new THREE.Object3D();
21 | this.debugDummy = new THREE.Object3D();
22 |
23 | this.animationParent = new THREE.Object3D();
24 |
25 | this.lookSpeed = 0.005;
26 | this.lookVertical = true;
27 | this.lookHorizontal = true;
28 | this.verticalAngleMap = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0, 2 * Math.PI ] };
29 | this.horizontalAngleMap = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0, 2 * Math.PI ] };
30 |
31 | // internals
32 |
33 | this.target = new THREE.Object3D();
34 |
35 | this.mouseX = 0;
36 | this.mouseY = 0;
37 |
38 | this.lat = 0;
39 | this.lon = 0;
40 |
41 | this.phi = 0;
42 | this.theta = 0;
43 |
44 | var PI2 = Math.PI * 2;
45 |
46 | this.viewHalfX = 0;
47 | this.viewHalfY = 0;
48 |
49 | if ( this.domElement !== document ) {
50 |
51 | this.domElement.setAttribute( 'tabindex', -1 );
52 |
53 | }
54 |
55 | // methods
56 |
57 | this.handleResize = function () {
58 |
59 | if ( this.domElement === document ) {
60 |
61 | this.viewHalfX = window.innerWidth / 2;
62 | this.viewHalfY = window.innerHeight / 2;
63 |
64 | } else {
65 |
66 | this.viewHalfX = this.domElement.offsetWidth / 2;
67 | this.viewHalfY = this.domElement.offsetHeight / 2;
68 |
69 | }
70 |
71 | };
72 |
73 | this.update = function ( delta ) {
74 |
75 | var srcRange, dstRange;
76 |
77 | if( this.lookHorizontal ) this.lon += this.mouseX * this.lookSpeed * delta;
78 | if( this.lookVertical ) this.lat -= this.mouseY * this.lookSpeed * delta;
79 |
80 | this.lon = Math.max( 0, Math.min( 360, this.lon ) );
81 | this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
82 |
83 | this.phi = THREE.Math.degToRad( 90 - this.lat );
84 | this.theta = THREE.Math.degToRad( this.lon );
85 |
86 | this.phi = normalize_angle_rad( this.phi );
87 |
88 | // constrain vertical look angle
89 |
90 | srcRange = this.verticalAngleMap.srcRange;
91 | dstRange = this.verticalAngleMap.dstRange;
92 |
93 | var tmpPhi = THREE.Math.mapLinear( this.phi, srcRange[ 0 ], srcRange[ 1 ], dstRange[ 0 ], dstRange[ 1 ] );
94 | var tmpPhiFullRange = dstRange[ 1 ] - dstRange[ 0 ];
95 | var tmpPhiNormalized = ( tmpPhi - dstRange[ 0 ] ) / tmpPhiFullRange;
96 |
97 | this.phi = QuadraticEaseInOut( tmpPhiNormalized ) * tmpPhiFullRange + dstRange[ 0 ];
98 |
99 | // constrain horizontal look angle
100 |
101 | srcRange = this.horizontalAngleMap.srcRange;
102 | dstRange = this.horizontalAngleMap.dstRange;
103 |
104 | var tmpTheta = THREE.Math.mapLinear( this.theta, srcRange[ 0 ], srcRange[ 1 ], dstRange[ 0 ], dstRange[ 1 ] );
105 | var tmpThetaFullRange = dstRange[ 1 ] - dstRange[ 0 ];
106 | var tmpThetaNormalized = ( tmpTheta - dstRange[ 0 ] ) / tmpThetaFullRange;
107 |
108 | this.theta = QuadraticEaseInOut( tmpThetaNormalized ) * tmpThetaFullRange + dstRange[ 0 ];
109 |
110 | var targetPosition = this.target.position,
111 | position = this.object.position;
112 |
113 | targetPosition.x = 100 * Math.sin( this.phi ) * Math.cos( this.theta );
114 | targetPosition.y = 100 * Math.cos( this.phi );
115 | targetPosition.z = 100 * Math.sin( this.phi ) * Math.sin( this.theta );
116 |
117 | this.object.lookAt( this.target.position );
118 |
119 | };
120 |
121 | this.onMouseMove = function ( event ) {
122 |
123 | if ( this.domElement === document ) {
124 |
125 | this.mouseX = event.pageX - this.viewHalfX;
126 | this.mouseY = event.pageY - this.viewHalfY;
127 |
128 | } else {
129 |
130 | this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
131 | this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
132 |
133 | }
134 |
135 | };
136 |
137 | // utils
138 |
139 | function normalize_angle_rad( a ) {
140 |
141 | var b = a % PI2;
142 | return b >= 0 ? b : b + PI2;
143 |
144 | };
145 |
146 | function distance( a, b ) {
147 |
148 | var dx = a[ 0 ] - b[ 0 ],
149 | dy = a[ 1 ] - b[ 1 ],
150 | dz = a[ 2 ] - b[ 2 ];
151 |
152 | return Math.sqrt( dx * dx + dy * dy + dz * dz );
153 |
154 | };
155 |
156 | function QuadraticEaseInOut ( k ) {
157 |
158 | if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
159 | return - 0.5 * ( --k * ( k - 2 ) - 1 );
160 |
161 | };
162 |
163 | function bind( scope, fn ) {
164 |
165 | return function () {
166 |
167 | fn.apply( scope, arguments );
168 |
169 | };
170 |
171 | };
172 |
173 | function initAnimationPath( parent, spline, name, duration ) {
174 |
175 | var animationData = {
176 |
177 | name: name,
178 | fps: 0.6,
179 | length: duration,
180 |
181 | hierarchy: []
182 |
183 | };
184 |
185 | var i,
186 | parentAnimation, childAnimation,
187 | path = spline.getControlPointsArray(),
188 | sl = spline.getLength(),
189 | pl = path.length,
190 | t = 0,
191 | first = 0,
192 | last = pl - 1;
193 |
194 | parentAnimation = { parent: -1, keys: [] };
195 | parentAnimation.keys[ first ] = { time: 0, pos: path[ first ], rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
196 | parentAnimation.keys[ last ] = { time: duration, pos: path[ last ], rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
197 |
198 | for ( i = 1; i < pl - 1; i++ ) {
199 |
200 | // real distance (approximation via linear segments)
201 |
202 | t = duration * sl.chunks[ i ] / sl.total;
203 |
204 | // equal distance
205 |
206 | //t = duration * ( i / pl );
207 |
208 | // linear distance
209 |
210 | //t += duration * distance( path[ i ], path[ i - 1 ] ) / sl.total;
211 |
212 | parentAnimation.keys[ i ] = { time: t, pos: path[ i ] };
213 |
214 | }
215 |
216 | animationData.hierarchy[ 0 ] = parentAnimation;
217 |
218 | THREE.AnimationHandler.add( animationData );
219 |
220 | return new THREE.Animation( parent, name, THREE.AnimationHandler.CATMULLROM_FORWARD, false );
221 |
222 | };
223 |
224 |
225 | function createSplineGeometry( spline, n_sub ) {
226 |
227 | var i, index, position,
228 | geometry = new THREE.Geometry();
229 |
230 | for ( i = 0; i < spline.points.length * n_sub; i ++ ) {
231 |
232 | index = i / ( spline.points.length * n_sub );
233 | position = spline.getPoint( index );
234 |
235 | geometry.vertices[ i ] = new THREE.Vector3( position.x, position.y, position.z );
236 |
237 | }
238 |
239 | return geometry;
240 |
241 | };
242 |
243 | function createPath( parent, spline ) {
244 |
245 | var lineGeo = createSplineGeometry( spline, 10 ),
246 | particleGeo = createSplineGeometry( spline, 10 ),
247 | lineMat = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 3 } ),
248 | lineObj = new THREE.Line( lineGeo, lineMat ),
249 | particleObj = new THREE.ParticleSystem( particleGeo, new THREE.ParticleBasicMaterial( { color: 0xffaa00, size: 3 } ) );
250 |
251 | lineObj.scale.set( 1, 1, 1 );
252 | parent.add( lineObj );
253 |
254 | particleObj.scale.set( 1, 1, 1 );
255 | parent.add( particleObj );
256 |
257 | var waypoint,
258 | geo = new THREE.SphereGeometry( 1, 16, 8 ),
259 | mat = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
260 |
261 | for ( var i = 0; i < spline.points.length; i ++ ) {
262 |
263 | waypoint = new THREE.Mesh( geo, mat );
264 | waypoint.position.copy( spline.points[ i ] );
265 | parent.add( waypoint );
266 |
267 | }
268 |
269 | };
270 |
271 | this.init = function ( ) {
272 |
273 | // constructor
274 |
275 | this.spline = new THREE.Spline();
276 | this.spline.initFromArray( this.waypoints );
277 |
278 | if ( this.useConstantSpeed ) {
279 |
280 | this.spline.reparametrizeByArcLength( this.resamplingCoef );
281 |
282 | }
283 |
284 | if ( this.createDebugDummy ) {
285 |
286 | var dummyParentMaterial = new THREE.MeshLambertMaterial( { color: 0x0077ff } ),
287 | dummyChildMaterial = new THREE.MeshLambertMaterial( { color: 0x00ff00 } ),
288 | dummyParentGeo = new THREE.CubeGeometry( 10, 10, 20 ),
289 | dummyChildGeo = new THREE.CubeGeometry( 2, 2, 10 );
290 |
291 | this.animationParent = new THREE.Mesh( dummyParentGeo, dummyParentMaterial );
292 |
293 | var dummyChild = new THREE.Mesh( dummyChildGeo, dummyChildMaterial );
294 | dummyChild.position.set( 0, 10, 0 );
295 |
296 | this.animation = initAnimationPath( this.animationParent, this.spline, this.id, this.duration );
297 |
298 | this.animationParent.add( this.object );
299 | this.animationParent.add( this.target );
300 | this.animationParent.add( dummyChild );
301 |
302 | } else {
303 |
304 | this.animation = initAnimationPath( this.animationParent, this.spline, this.id, this.duration );
305 | this.animationParent.add( this.target );
306 | this.animationParent.add( this.object );
307 |
308 | }
309 |
310 | if ( this.createDebugPath ) {
311 |
312 | createPath( this.debugPath, this.spline );
313 |
314 | }
315 |
316 | this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
317 |
318 | };
319 |
320 | this.handleResize();
321 |
322 | };
323 |
324 | THREE.PathControlsIdCounter = 0;
325 |
--------------------------------------------------------------------------------
/vendor/three/controls/PointerLockControls.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author mrdoob / http://mrdoob.com/
3 | */
4 |
5 | THREE.PointerLockControls = function ( camera ) {
6 |
7 | var scope = this;
8 |
9 | var pitchObject = new THREE.Object3D();
10 | pitchObject.add( camera );
11 |
12 | var yawObject = new THREE.Object3D();
13 | yawObject.position.y = 10;
14 | yawObject.add( pitchObject );
15 |
16 | var moveForward = false;
17 | var moveBackward = false;
18 | var moveLeft = false;
19 | var moveRight = false;
20 |
21 | var isOnObject = false;
22 | var canJump = false;
23 |
24 | var velocity = new THREE.Vector3();
25 |
26 | var PI_2 = Math.PI / 2;
27 |
28 | var onMouseMove = function ( event ) {
29 |
30 | if ( scope.enabled === false ) return;
31 |
32 | var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
33 | var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
34 |
35 | yawObject.rotation.y -= movementX * 0.002;
36 | pitchObject.rotation.x -= movementY * 0.002;
37 |
38 | pitchObject.rotation.x = Math.max( - PI_2, Math.min( PI_2, pitchObject.rotation.x ) );
39 |
40 | };
41 |
42 | var onKeyDown = function ( event ) {
43 |
44 | switch ( event.keyCode ) {
45 |
46 | case 38: // up
47 | case 87: // w
48 | moveForward = true;
49 | break;
50 |
51 | case 37: // left
52 | case 65: // a
53 | moveLeft = true; break;
54 |
55 | case 40: // down
56 | case 83: // s
57 | moveBackward = true;
58 | break;
59 |
60 | case 39: // right
61 | case 68: // d
62 | moveRight = true;
63 | break;
64 |
65 | case 32: // space
66 | if ( canJump === true ) velocity.y += 10;
67 | canJump = false;
68 | break;
69 |
70 | }
71 |
72 | };
73 |
74 | var onKeyUp = function ( event ) {
75 |
76 | switch( event.keyCode ) {
77 |
78 | case 38: // up
79 | case 87: // w
80 | moveForward = false;
81 | break;
82 |
83 | case 37: // left
84 | case 65: // a
85 | moveLeft = false;
86 | break;
87 |
88 | case 40: // down
89 | case 83: // a
90 | moveBackward = false;
91 | break;
92 |
93 | case 39: // right
94 | case 68: // d
95 | moveRight = false;
96 | break;
97 |
98 | }
99 |
100 | };
101 |
102 | document.addEventListener( 'mousemove', onMouseMove, false );
103 | document.addEventListener( 'keydown', onKeyDown, false );
104 | document.addEventListener( 'keyup', onKeyUp, false );
105 |
106 | this.enabled = false;
107 |
108 | this.getObject = function () {
109 |
110 | return yawObject;
111 |
112 | };
113 |
114 | this.isOnObject = function ( boolean ) {
115 |
116 | isOnObject = boolean;
117 | canJump = boolean;
118 |
119 | };
120 |
121 | this.update = function ( delta ) {
122 |
123 | if ( scope.enabled === false ) return;
124 |
125 | delta *= 0.1;
126 |
127 | velocity.x += ( - velocity.x ) * 0.08 * delta;
128 | velocity.z += ( - velocity.z ) * 0.08 * delta;
129 |
130 | velocity.y -= 0.25 * delta;
131 |
132 | if ( moveForward ) velocity.z -= 0.12 * delta;
133 | if ( moveBackward ) velocity.z += 0.12 * delta;
134 |
135 | if ( moveLeft ) velocity.x -= 0.12 * delta;
136 | if ( moveRight ) velocity.x += 0.12 * delta;
137 |
138 | if ( isOnObject === true ) {
139 |
140 | velocity.y = Math.max( 0, velocity.y );
141 |
142 | }
143 |
144 | yawObject.translateX( velocity.x );
145 | yawObject.translateY( velocity.y );
146 | yawObject.translateZ( velocity.z );
147 |
148 | if ( yawObject.position.y < 10 ) {
149 |
150 | velocity.y = 0;
151 | yawObject.position.y = 10;
152 |
153 | canJump = true;
154 |
155 | }
156 |
157 | };
158 |
159 | };
160 |
--------------------------------------------------------------------------------
/vendor/three/controls/TrackballControls.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Eberhard Graether / http://egraether.com/
3 | */
4 |
5 | THREE.TrackballControls = function ( object, domElement ) {
6 |
7 | var _this = this;
8 | var STATE = { NONE: -1, ROTATE: 0, ZOOM: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_ZOOM: 4, TOUCH_PAN: 5 };
9 |
10 | this.object = object;
11 | this.domElement = ( domElement !== undefined ) ? domElement : document;
12 |
13 | // API
14 |
15 | this.enabled = true;
16 |
17 | this.screen = { width: 0, height: 0, offsetLeft: 0, offsetTop: 0 };
18 | this.radius = ( this.screen.width + this.screen.height ) / 4;
19 |
20 | this.rotateSpeed = 1.0;
21 | this.zoomSpeed = 1.2;
22 | this.panSpeed = 0.3;
23 |
24 | this.noRotate = false;
25 | this.noZoom = false;
26 | this.noPan = false;
27 |
28 | this.staticMoving = false;
29 | this.dynamicDampingFactor = 0.2;
30 |
31 | this.minDistance = 0;
32 | this.maxDistance = Infinity;
33 |
34 | this.keys = [ 65 /*A*/, 83 /*S*/, 68 /*D*/ ];
35 |
36 | // internals
37 |
38 | this.target = new THREE.Vector3();
39 |
40 | var lastPosition = new THREE.Vector3();
41 |
42 | var _state = STATE.NONE,
43 | _prevState = STATE.NONE,
44 |
45 | _eye = new THREE.Vector3(),
46 |
47 | _rotateStart = new THREE.Vector3(),
48 | _rotateEnd = new THREE.Vector3(),
49 |
50 | _zoomStart = new THREE.Vector2(),
51 | _zoomEnd = new THREE.Vector2(),
52 |
53 | _touchZoomDistanceStart = 0,
54 | _touchZoomDistanceEnd = 0,
55 |
56 | _panStart = new THREE.Vector2(),
57 | _panEnd = new THREE.Vector2();
58 |
59 | // for reset
60 |
61 | this.target0 = this.target.clone();
62 | this.position0 = this.object.position.clone();
63 | this.up0 = this.object.up.clone();
64 |
65 | // events
66 |
67 | var changeEvent = { type: 'change' };
68 |
69 |
70 | // methods
71 |
72 | this.handleResize = function () {
73 |
74 | this.screen.width = window.innerWidth;
75 | this.screen.height = window.innerHeight;
76 |
77 | this.screen.offsetLeft = 0;
78 | this.screen.offsetTop = 0;
79 |
80 | this.radius = ( this.screen.width + this.screen.height ) / 4;
81 |
82 | };
83 |
84 | this.handleEvent = function ( event ) {
85 |
86 | if ( typeof this[ event.type ] == 'function' ) {
87 |
88 | this[ event.type ]( event );
89 |
90 | }
91 |
92 | };
93 |
94 | this.getMouseOnScreen = function ( clientX, clientY ) {
95 |
96 | return new THREE.Vector2(
97 | ( clientX - _this.screen.offsetLeft ) / _this.radius * 0.5,
98 | ( clientY - _this.screen.offsetTop ) / _this.radius * 0.5
99 | );
100 |
101 | };
102 |
103 | this.getMouseProjectionOnBall = function ( clientX, clientY ) {
104 |
105 | var mouseOnBall = new THREE.Vector3(
106 | ( clientX - _this.screen.width * 0.5 - _this.screen.offsetLeft ) / _this.radius,
107 | ( _this.screen.height * 0.5 + _this.screen.offsetTop - clientY ) / _this.radius,
108 | 0.0
109 | );
110 |
111 | var length = mouseOnBall.length();
112 |
113 | if ( length > 1.0 ) {
114 |
115 | mouseOnBall.normalize();
116 |
117 | } else {
118 |
119 | mouseOnBall.z = Math.sqrt( 1.0 - length * length );
120 |
121 | }
122 |
123 | _eye.copy( _this.object.position ).sub( _this.target );
124 |
125 | var projection = _this.object.up.clone().setLength( mouseOnBall.y );
126 | projection.add( _this.object.up.clone().cross( _eye ).setLength( mouseOnBall.x ) );
127 | projection.add( _eye.setLength( mouseOnBall.z ) );
128 |
129 | return projection;
130 |
131 | };
132 |
133 | this.rotateCamera = function () {
134 |
135 | var angle = Math.acos( _rotateStart.dot( _rotateEnd ) / _rotateStart.length() / _rotateEnd.length() );
136 |
137 | if ( angle ) {
138 |
139 | var axis = ( new THREE.Vector3() ).crossVectors( _rotateStart, _rotateEnd ).normalize(),
140 | quaternion = new THREE.Quaternion();
141 |
142 | angle *= _this.rotateSpeed;
143 |
144 | quaternion.setFromAxisAngle( axis, -angle );
145 |
146 | _eye.applyQuaternion( quaternion );
147 | _this.object.up.applyQuaternion( quaternion );
148 |
149 | _rotateEnd.applyQuaternion( quaternion );
150 |
151 | if ( _this.staticMoving ) {
152 |
153 | _rotateStart.copy( _rotateEnd );
154 |
155 | } else {
156 |
157 | quaternion.setFromAxisAngle( axis, angle * ( _this.dynamicDampingFactor - 1.0 ) );
158 | _rotateStart.applyQuaternion( quaternion );
159 |
160 | }
161 |
162 | }
163 |
164 | };
165 |
166 | this.zoomCamera = function () {
167 |
168 | if ( _state === STATE.TOUCH_ZOOM ) {
169 |
170 | var factor = _touchZoomDistanceStart / _touchZoomDistanceEnd;
171 | _touchZoomDistanceStart = _touchZoomDistanceEnd;
172 | _eye.multiplyScalar( factor );
173 |
174 | } else {
175 |
176 | var factor = 1.0 + ( _zoomEnd.y - _zoomStart.y ) * _this.zoomSpeed;
177 |
178 | if ( factor !== 1.0 && factor > 0.0 ) {
179 |
180 | _eye.multiplyScalar( factor );
181 |
182 | if ( _this.staticMoving ) {
183 |
184 | _zoomStart.copy( _zoomEnd );
185 |
186 | } else {
187 |
188 | _zoomStart.y += ( _zoomEnd.y - _zoomStart.y ) * this.dynamicDampingFactor;
189 |
190 | }
191 |
192 | }
193 |
194 | }
195 |
196 | };
197 |
198 | this.panCamera = function () {
199 |
200 | var mouseChange = _panEnd.clone().sub( _panStart );
201 |
202 | if ( mouseChange.lengthSq() ) {
203 |
204 | mouseChange.multiplyScalar( _eye.length() * _this.panSpeed );
205 |
206 | var pan = _eye.clone().cross( _this.object.up ).setLength( mouseChange.x );
207 | pan.add( _this.object.up.clone().setLength( mouseChange.y ) );
208 |
209 | _this.object.position.add( pan );
210 | _this.target.add( pan );
211 |
212 | if ( _this.staticMoving ) {
213 |
214 | _panStart = _panEnd;
215 |
216 | } else {
217 |
218 | _panStart.add( mouseChange.subVectors( _panEnd, _panStart ).multiplyScalar( _this.dynamicDampingFactor ) );
219 |
220 | }
221 |
222 | }
223 |
224 | };
225 |
226 | this.checkDistances = function () {
227 |
228 | if ( !_this.noZoom || !_this.noPan ) {
229 |
230 | if ( _this.object.position.lengthSq() > _this.maxDistance * _this.maxDistance ) {
231 |
232 | _this.object.position.setLength( _this.maxDistance );
233 |
234 | }
235 |
236 | if ( _eye.lengthSq() < _this.minDistance * _this.minDistance ) {
237 |
238 | _this.object.position.addVectors( _this.target, _eye.setLength( _this.minDistance ) );
239 |
240 | }
241 |
242 | }
243 |
244 | };
245 |
246 | this.update = function () {
247 |
248 | _eye.subVectors( _this.object.position, _this.target );
249 |
250 | if ( !_this.noRotate ) {
251 |
252 | _this.rotateCamera();
253 |
254 | }
255 |
256 | if ( !_this.noZoom ) {
257 |
258 | _this.zoomCamera();
259 |
260 | }
261 |
262 | if ( !_this.noPan ) {
263 |
264 | _this.panCamera();
265 |
266 | }
267 |
268 | _this.object.position.addVectors( _this.target, _eye );
269 |
270 | _this.checkDistances();
271 |
272 | _this.object.lookAt( _this.target );
273 |
274 | if ( lastPosition.distanceToSquared( _this.object.position ) > 0 ) {
275 |
276 | _this.dispatchEvent( changeEvent );
277 |
278 | lastPosition.copy( _this.object.position );
279 |
280 | }
281 |
282 | };
283 |
284 | this.reset = function () {
285 |
286 | _state = STATE.NONE;
287 | _prevState = STATE.NONE;
288 |
289 | _this.target.copy( _this.target0 );
290 | _this.object.position.copy( _this.position0 );
291 | _this.object.up.copy( _this.up0 );
292 |
293 | _eye.subVectors( _this.object.position, _this.target );
294 |
295 | _this.object.lookAt( _this.target );
296 |
297 | _this.dispatchEvent( changeEvent );
298 |
299 | lastPosition.copy( _this.object.position );
300 |
301 | };
302 |
303 | // listeners
304 |
305 | function keydown( event ) {
306 |
307 | if ( _this.enabled === false ) return;
308 |
309 | window.removeEventListener( 'keydown', keydown );
310 |
311 | _prevState = _state;
312 |
313 | if ( _state !== STATE.NONE ) {
314 |
315 | return;
316 |
317 | } else if ( event.keyCode === _this.keys[ STATE.ROTATE ] && !_this.noRotate ) {
318 |
319 | _state = STATE.ROTATE;
320 |
321 | } else if ( event.keyCode === _this.keys[ STATE.ZOOM ] && !_this.noZoom ) {
322 |
323 | _state = STATE.ZOOM;
324 |
325 | } else if ( event.keyCode === _this.keys[ STATE.PAN ] && !_this.noPan ) {
326 |
327 | _state = STATE.PAN;
328 |
329 | }
330 |
331 | }
332 |
333 | function keyup( event ) {
334 |
335 | if ( _this.enabled === false ) return;
336 |
337 | _state = _prevState;
338 |
339 | window.addEventListener( 'keydown', keydown, false );
340 |
341 | }
342 |
343 | function mousedown( event ) {
344 |
345 | if ( _this.enabled === false ) return;
346 |
347 | event.preventDefault();
348 | event.stopPropagation();
349 |
350 | if ( _state === STATE.NONE ) {
351 |
352 | _state = event.button;
353 |
354 | }
355 |
356 | if ( _state === STATE.ROTATE && !_this.noRotate ) {
357 |
358 | _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
359 |
360 | } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
361 |
362 | _zoomStart = _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
363 |
364 | } else if ( _state === STATE.PAN && !_this.noPan ) {
365 |
366 | _panStart = _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
367 |
368 | }
369 |
370 | document.addEventListener( 'mousemove', mousemove, false );
371 | document.addEventListener( 'mouseup', mouseup, false );
372 |
373 | }
374 |
375 | function mousemove( event ) {
376 |
377 | if ( _this.enabled === false ) return;
378 |
379 | event.preventDefault();
380 | event.stopPropagation();
381 |
382 | if ( _state === STATE.ROTATE && !_this.noRotate ) {
383 |
384 | _rotateEnd = _this.getMouseProjectionOnBall( event.clientX, event.clientY );
385 |
386 | } else if ( _state === STATE.ZOOM && !_this.noZoom ) {
387 |
388 | _zoomEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
389 |
390 | } else if ( _state === STATE.PAN && !_this.noPan ) {
391 |
392 | _panEnd = _this.getMouseOnScreen( event.clientX, event.clientY );
393 |
394 | }
395 |
396 | }
397 |
398 | function mouseup( event ) {
399 |
400 | if ( _this.enabled === false ) return;
401 |
402 | event.preventDefault();
403 | event.stopPropagation();
404 |
405 | _state = STATE.NONE;
406 |
407 | document.removeEventListener( 'mousemove', mousemove );
408 | document.removeEventListener( 'mouseup', mouseup );
409 |
410 | }
411 |
412 | function mousewheel( event ) {
413 |
414 | if ( _this.enabled === false ) return;
415 |
416 | event.preventDefault();
417 | event.stopPropagation();
418 |
419 | var delta = 0;
420 |
421 | if ( event.wheelDelta ) { // WebKit / Opera / Explorer 9
422 |
423 | delta = event.wheelDelta / 40;
424 |
425 | } else if ( event.detail ) { // Firefox
426 |
427 | delta = - event.detail / 3;
428 |
429 | }
430 |
431 | _zoomStart.y += delta * 0.01;
432 |
433 | }
434 |
435 | function touchstart( event ) {
436 |
437 | if ( _this.enabled === false ) return;
438 |
439 | switch ( event.touches.length ) {
440 |
441 | case 1:
442 | _state = STATE.TOUCH_ROTATE;
443 | _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
444 | break;
445 |
446 | case 2:
447 | _state = STATE.TOUCH_ZOOM;
448 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
449 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
450 | _touchZoomDistanceEnd = _touchZoomDistanceStart = Math.sqrt( dx * dx + dy * dy );
451 | break;
452 |
453 | case 3:
454 | _state = STATE.TOUCH_PAN;
455 | _panStart = _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
456 | break;
457 |
458 | default:
459 | _state = STATE.NONE;
460 |
461 | }
462 |
463 | }
464 |
465 | function touchmove( event ) {
466 |
467 | if ( _this.enabled === false ) return;
468 |
469 | event.preventDefault();
470 | event.stopPropagation();
471 |
472 | switch ( event.touches.length ) {
473 |
474 | case 1:
475 | _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
476 | break;
477 |
478 | case 2:
479 | var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;
480 | var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;
481 | _touchZoomDistanceEnd = Math.sqrt( dx * dx + dy * dy )
482 | break;
483 |
484 | case 3:
485 | _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
486 | break;
487 |
488 | default:
489 | _state = STATE.NONE;
490 |
491 | }
492 |
493 | }
494 |
495 | function touchend( event ) {
496 |
497 | if ( _this.enabled === false ) return;
498 |
499 | switch ( event.touches.length ) {
500 |
501 | case 1:
502 | _rotateStart = _rotateEnd = _this.getMouseProjectionOnBall( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
503 | break;
504 |
505 | case 2:
506 | _touchZoomDistanceStart = _touchZoomDistanceEnd = 0;
507 | break;
508 |
509 | case 3:
510 | _panStart = _panEnd = _this.getMouseOnScreen( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );
511 | break;
512 |
513 | }
514 |
515 | _state = STATE.NONE;
516 |
517 | }
518 |
519 | this.domElement.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false );
520 |
521 | this.domElement.addEventListener( 'mousedown', mousedown, false );
522 |
523 | this.domElement.addEventListener( 'mousewheel', mousewheel, false );
524 | this.domElement.addEventListener( 'DOMMouseScroll', mousewheel, false ); // firefox
525 |
526 | this.domElement.addEventListener( 'touchstart', touchstart, false );
527 | this.domElement.addEventListener( 'touchend', touchend, false );
528 | this.domElement.addEventListener( 'touchmove', touchmove, false );
529 |
530 | window.addEventListener( 'keydown', keydown, false );
531 | window.addEventListener( 'keyup', keyup, false );
532 |
533 | this.handleResize();
534 |
535 | };
536 |
537 | THREE.TrackballControls.prototype = Object.create( THREE.EventDispatcher.prototype );
538 |
--------------------------------------------------------------------------------
/vendor/toxi/toxi-color.js:
--------------------------------------------------------------------------------
1 | // toxi-color r43 - http://github.com/hapticdata/toxiclibsjs
2 | toxi.color=toxi.color||{};
3 | (function(){var h=function(a){var b="0000";if(a>=0&&a<=15)b="000"+a.toString(16);else if(a>=16&&a<=255)b="00"+a.toString(16);else if(a>=256&&a<=4095)b="0"+a.toString(16);else if(a>=4096&&a<=65535)b=a.toString(16);return b};toxi.color.TColor=function(a){this.rgb=Array(3);this.hsv=Array(3);this.cmyk=Array(4);this._alpha=1;if(a!==undefined){this.cmyk=a.toCMYKAArray().splice(0,4);this.hsv=a.toHSVAArray().splice(0,3);this.rgb=a.toRGBAArray().splice(0,3);this._alpha=a._alpha}};toxi.color.TColor.prototype=
4 | {add:function(a){return this.copy().addSelf(a)},addSelf:function(a){this.rgb[0]=toxi.MathUtils.min(this.rgb[0]+a.rgb[0],1);this.rgb[1]=toxi.MathUtils.min(this.rgb[1]+a.rgb[1],1);this.rgb[2]=toxi.MathUtils.min(this.rgb[2]+a.rgb[2],1);return this.setRGB(rgb)},adjustConstrast:function(a){return this.hsv[2]<0.5?this.darken(a):this.lighten(a)},adjustHSV:function(a,b,d){return this.setHSV([this.hsv[0]+a,this.hsv[1]+b,this.hsv[2]+d])},adjustRGB:function(a,b,d){return this.setRGB([this.rgb[0]+a,this.rgb[1]+
5 | b,this.rgb[2]+d])},alpha:function(){return this._alpha},analog:function(a,b){this.rotateRYB(toxi.MathUtils.degrees(a)*toxi.MathUtils.normalizedRandom());this.hsv[1]+=b*toxi.MathUtils.normalizedRandom();this.hsv[2]+=b*toxi.MathUtils.normalizedRandom();return this.setHSV(this.hsv)},black:function(){return this.cmyk[3]},blend:function(a,b){if(b===undefined)b=0.5;var d=a.toRGBAArray();this.rgb[0]+=(d[0]-this.rgb[0])*b;this.rgb[1]+=(d[1]-this.rgb[1])*b;this.rgb[2]+=(d[2]-this.rgb[2])*b;this._alpha+=(a.alpha()-
6 | this._alpha)*b;return this.setRGB(this.rgb)},blue:function(){return this.rgb[2]},brightness:function(){return this.hsv[2]},complement:function(){return this.rotateRYB(180)},copy:function(){return new toxi.color.TColor(this)},cyan:function(){return this.cmyk[0]},darken:function(a){this.hsv[2]=toxi.MathUtils.clip(this.hsv[2]-a,0,1);return this.setHSV(this.hsv)},desaturate:function(a){this.hsv[1]=toxi.MathUtils.clip(this.hsv[1]-a,0,1);return this.setHSV(this.hsv)},differenceTo:function(a){return toxi.color.TColor.newRGB(Math.abs(this.rgb[0]-
7 | a.rgb[0]),Math.abs(this.rgb[1]-a.rgb[1]),Math.abs(this.rgb[2]-a.rgb[2]))},distanceToCMYK:function(a){var b=a.toCMYKAArray();a=this.cmyk[0]-b[0];var d=this.cmyk[1]-b[1],c=this.cmyk[2]-b[2];b=this.cmyk[3]-b[3];return Math.sqrt(a*a+d*d+c*c+b*b)},distanceToHSV:function(a){var b=this.hsv[0]*toxi.MathUtils.TWO_PI,d=a.hue()*toxi.MathUtils.TWO_PI;b=new toxi.Vec3D(Math.cos(b)*this.hsv[1],Math.sin(b)*this.hsv[1],this.hsv[2]);a=new toxi.Vec3D(Math.cos(d)*a.saturation(),Math.sin(d)*a.saturation(),a.brightness());
8 | return b.distanceTo(a)},distanceToRGB:function(a){var b=a.toRGBAArray();a=this.rgb[0]-b[0];var d=this.rgb[1]-b[1];b=this.rgb[2]-b[2];return Math.sqrt(a*a+d*d+b*b)},equals:function(a){if(a!==undefined&&a instanceof toxi.color.TColor){var b=a.rgb[0]-this.rgb[0],d=a.rgb[1]-this.rgb[1],c=a.rgb[2]-this.rgb[2];a=a.alpha()-this._alpha;return Math.sqrt(b*b+d*d+c*c+a*a)=toxi.color.TColor.WHITE_POINT&&this.rgb[0]==this.rgb[1]&&this.rgb[0]==this.rgb[2]},lighten:function(a){this.hsv[2]=toxi.MathUtils.clip(this.hsv[2]+a,0,1);return this.setHSV(this.hsv)},luminance:function(){return this.rgb[0]*0.299+this.rgb[1]*0.587+this.rgb[2]*0.114},magenta:function(){return this.cmyk[1]},red:function(){return this.rgb[0]},rotateRYB:function(a){parseInt(toxi.MathUtils.degrees(a),10);var b=this.hsv[0]*360,d=0,
12 | c,e;a%=360;var f=0;for(d=0;d>16&255)*toxi.TColor.INV8BIT,(a>>8&255)*toxi.TColor.INV8BIT,(a&255)*toxi.TColor.INV8BIT);this._alpha=(a>>>24)*toxi.TColor.INV8BIT;return this},setBlack:function(a){this.cmyk[3]=a;return this.setCMYK(cmyk)},setBlue:function(a){this.rgb[2]=a;return this.setRGB(this.rgb)},setBrightness:function(a){this.hsv[2]=
14 | toxi.MathUtils.clip(a,0,1);return this.setHSV(this.hsv)},setCMYK:function(a,b,d,c){if(a instanceof Array){b=a[1];d=a[2];c=a[3];a=a[0]}this.cmyk[0]=a;this.cmyk[1]=b;this.cmyk[2]=d;this.cmyk[3]=c;this.rgb=toxi.color.TColor.cmykToRGB(this.cmyk[0],this.cmyk[1],this.cmyk[2],this.cmyk[3]);this.hsv=toxi.color.TColor.rgbToHSV(this.rgb[0],this.rgb[1],this.rgb[2]);return this},setCyan:function(a){this.cmyk[0]=a;return this.setCMYK(this.cmyk)},setGreen:function(a){this.rgb[1]=a;return this.setRGB(this.rgb)},
15 | setHSV:function(a,b,d){if(a instanceof Array){b=a[1];d=a[2];a=a[0]}a=[a,b,d];this.hsv[0]=a[0]%1;this.hsv[0]<0&&this.hsv[0]++;this.hsv[1]=toxi.MathUtils.clip(a[1],0,1);this.hsv[2]=toxi.MathUtils.clip(a[2],0,1);this.rgb=toxi.color.TColor.hsvToRGB(this.hsv[0],this.hsv[1],this.hsv[2]);this.cmyk=toxi.color.TColor.rgbToCMYK(this.rgb[0],this.rgb[1],this.rgb[2]);return this},setHue:function(a){a%=1;a<0&&a++;this.hsv[0]=a;this.setHSV(this.hsv)},setMagenta:function(a){this.cmyk[1]=a;return this.setCMYK(this.cmyk)},
16 | setRed:function(a){this.rgb[0]=a;return this.setRGB(this.rgb)},setRGB:function(a,b,d){if(a instanceof Array){b=a[1];d=a[2];a=a[0]}this.rgb[0]=toxi.MathUtils.clip(a,0,1);this.rgb[1]=toxi.MathUtils.clip(b,0,1);this.rgb[2]=toxi.MathUtils.clip(d,0,1);this.cmyk=toxi.color.TColor.rgbToCMYK(this.rgb[0],this.rgb[1],this.rgb[2]);this.hsv=toxi.color.TColor.rgbToHSV(this.rgb[0],this.rgb[1],this.rgb[2]);return this},setSaturation:function(a){this.hsv[1]=toxi.MathUtils.clip(a,0,1);return this.setHSV(this.hsv)},
17 | setYellow:function(a){this.cmyk[2]=a;return this.setCMYK(this.cmyk)},sub:function(a){return this.copy().subSelf(a)},subSelf:function(a){this.rgb[0]=toxi.MathUtils.max(this.rgb[0]-a.rgb[0],0);this.rgb[1]=toxi.MathUtils.max(this.rgb[1]-a.rgb[1],0);this.rgb[2]=toxi.MathUtils.max(this.rgb[2]-a.rgb[2],0);return this.setRGB(this.rgb)},toARGB:function(){var a=parseInt(this.rgb[0]*255,10),b=parseInt(this.rgb[1]*255,10),d=parseInt(this.rgb[2]*255,10),c=parseInt(this._alpha*255,10);return a<<16|b<<8|d|c<<24},
18 | toCMYKAArray:function(a){if(a===undefined)a=[];a[0]=this.cmyk[0];a[1]=this.cmyk[1];a[2]=this.cmyk[2];a[3]=this._alpha;return a},toHex:function(){var a=h(this.toARGB());if(a.length>6)a=a.substring(2);return a},toHSVAArray:function(a){if(a===undefined)a=[];a[0]=this.hsv[0];a[1]=this.hsv[1];a[2]=this.hsv[2];a[3]=this._alpha;return a},toRGBAArray:function(a,b){if(a===undefined){a=[];b=0}a[b++]=this.rgb[0];a[b++]=this.rgb[1];a[b++]=this.rgb[2];a[b]=this._alpha;return a},toString:function(){return"toxi.color.TColor: rgb: "+
19 | this.rgb[0]+", "+this.rgb[1]+", "+this.rgb[2]+" hsv: "+this.hsv[0]+","+this.hsv[1]+","+this.hsv[2]+" cmyk: "+this.cmyk[0]+", "+this.cmyk[1]+","+this.cmyk[2]+","+this.cmyk[3]+" alpha: "+this._alpha},yellow:function(){return this.cmyk[2]}};toxi.color.TColor.INV60DEGREES=60/360;toxi.color.TColor.INV8BIT=1/255;toxi.color.TColor.EPS=0.0010;toxi.color.TColor.BLACK_POINT=0.08;toxi.color.TColor.WHITE_POINT=1;toxi.color.TColor.GREY_THRESHOLD=0.01;toxi.color.TColor.cmykToRGB=function(a,b,d,c,e){if(e===undefined)e=
20 | [0,0,0];e[0]=1-Math.min(1,a+c);e[1]=1-Math.min(1,b+c);e[2]=1-Math.min(1,d+c);return e};toxi.color.TColor.hexToRGB=function(a,b){if(b===undefined)b=[];a=a.charAt(0)=="#"?a.substring(1,7):a;b[0]=parseInt(a.substring(0,2),16)*toxi.color.TColor.INV8BIT;b[1]=parseInt(a.substring(2,4),16)*toxi.color.TColor.INV8BIT;b[2]=parseInt(a.substring(4,6),16)*toxi.color.TColor.INV8BIT;return b};toxi.color.TColor.hsvToRGB=function(a,b,d,c){if(c===undefined)c=[];if(b===0)c[0]=c[1]=c[2]=d;else{a/=toxi.color.TColor.INV60DEGREES;
21 | var e=parseInt(a,10),f=a-e;a=d*(1-b);var g=d*(1-b*f);b=d*(1-b*(1-f));if(e===0){c[0]=d;c[1]=b;c[2]=a}else if(e==1){c[0]=g;c[1]=d;c[2]=a}else if(e==2){c[0]=a;c[1]=d;c[2]=b}else if(e==3){c[0]=a;c[1]=g;c[2]=d}else if(e==4){c[0]=b;c[1]=a;c[2]=d}else{c[0]=d;c[1]=a;c[2]=g}}return c};toxi.color.TColor.labToRGB=function(a,b,d,c){if(c===undefined)c=[];a=(a+16)/116;b=b/500+a;var e=a-d/200;d=0;c[0]=b;c[1]=a;c[2]=e;for(d=0;d<3;d++){a=Math.pow(c[d],3);c[d]=a>0.008856?a:(c[d]-16/116)/7.787}b=c[0]*0.95047;a=c[1];
22 | e=c[2]*1.08883;c[0]=b*3.2406+a*-1.5372+e*-0.4986;c[1]=b*-0.9689+a*1.8758+e*0.0415;c[2]=b*0.0557+a*-0.204+e*1.057;a=1/2.4;for(d=0;d<3;d++)c[d]=c[d]>0.0031308?1.055*Math.pow(c[d],a)-0.055:12.92*c[d];return c};toxi.color.TColor.newARGB=function(a){return toxi.color.TColor.newRGBA((a>>16&255)*toxi.color.TColor.INV8BIT,(a>>8&255)*toxi.color.TColor.INV8BIT,(a&255)*toxi.color.TColor.INV8BIT,(a>>>24)*toxi.color.TColor.INV8BIT)};toxi.color.TColor.newCMYK=function(a,b,d,c){return toxi.color.TColor.newCMYKA(a,
23 | b,d,c,1)};toxi.color.TColor.newCMYKA=function(a,b,d,c,e){var f=new toxi.color.TColor;f.setCMYK([a,b,d,c]);f.setAlpha(toxi.MathUtils.clip(e,0,1));return f};toxi.color.TColor.newGray=function(a){return toxi.color.TColor.newGrayAlpha(a,1)};toxi.color.TColor.newGrayAlpha=function(a,b){var d=new toxi.color.TColor;d.setRGB([a,a,a]);d.setAlpha(b);return d};toxi.color.TColor.newHex=function(a){var b=new toxi.color.TColor;b.setRGB(toxi.color.TColor.hexToRGB(a));b.setAlpha(1);return b};toxi.color.TColor.newHSV=
24 | function(a,b,d){return toxi.color.TColor.newHSVA(a,b,d,1)};toxi.color.TColor.newHSVA=function(a,b,d,c){var e=new toxi.color.TColor;e.setHSV(a,b,d);e.setAlpha(toxi.MathUtils.clip(c,0,1));return e};toxi.color.TColor.newRandom=function(){return toxi.color.TColor.newRGBA(Math.random(),Math.random(),Math.random(),1)};toxi.color.TColor.newRGB=function(a,b,d){return toxi.color.TColor.newRGBA(a,b,d,1)};toxi.color.TColor.newRGBA=function(a,b,d,c){var e=new toxi.color.TColor;e.setRGB([a,b,d]);e.setAlpha(toxi.MathUtils.clip(c,
25 | 0,1));return e};toxi.color.TColor.rgbToCMYK=function(a,b,d,c){if(c===undefined)c=[];c[0]=1-a;c[1]=1-b;c[2]=1-d;c[3]=toxi.MathUtils.min(c[0],c[1],c[2]);c[0]=toxi.MathUtils.clip(c[0]-c[3],0,1);c[1]=toxi.MathUtils.clip(c[1]-c[3],0,1);c[2]=toxi.MathUtils.clip(c[2]-c[3],0,1);c[3]=toxi.MathUtils.clip(c[3],0,1);return c};toxi.color.TColor.rgbToHex=function(a,b,d){return h(toxi.MathUtils.clip(a,0,1)*255)+h(toxi.MathUtils.clip(b,0,1)*255)+h(toxi.MathUtils.clip(d,0,1)*255)};toxi.color.TColor.rgbToHSV=function(a,
26 | b,d,c){if(c===undefined)c=[];var e=0,f=0,g=toxi.MathUtils.max(a,b,d),i=g-toxi.MathUtils.min(a,b,d);if(g!==0)f=i/g;if(f!==0)e=a==g?(b-d)/i:b==g?2+(d-a)/i:4+(a-b)/i;e*=toxi.color.TColor.INV60DEGREES;if(e<0)e+=1;c[0]=e;c[1]=f;c[2]=g;return c};toxi.color.TColor.RED=toxi.color.TColor.newRGB(1,0,0);toxi.color.TColor.RYB_WHEEL=[new toxi.Vec2D(0,0),new toxi.Vec2D(15,8),new toxi.Vec2D(30,17),new toxi.Vec2D(45,26),new toxi.Vec2D(60,34),new toxi.Vec2D(75,41),new toxi.Vec2D(90,48),new toxi.Vec2D(105,54),new toxi.Vec2D(120,
27 | 60),new toxi.Vec2D(135,81),new toxi.Vec2D(150,103),new toxi.Vec2D(165,123),new toxi.Vec2D(180,138),new toxi.Vec2D(195,155),new toxi.Vec2D(210,171),new toxi.Vec2D(225,187),new toxi.Vec2D(240,204),new toxi.Vec2D(255,219),new toxi.Vec2D(270,234),new toxi.Vec2D(285,251),new toxi.Vec2D(300,267),new toxi.Vec2D(315,282),new toxi.Vec2D(330,298),new toxi.Vec2D(345,329),new toxi.Vec2D(360,0)];toxi.color.TColor.GREEN=toxi.color.TColor.newRGB(0,1,0);toxi.color.TColor.BLUE=toxi.color.TColor.newRGB(0,0,1);toxi.color.TColor.CYAN=
28 | toxi.color.TColor.newRGB(0,1,1);toxi.color.TColor.MAGENTA=toxi.color.TColor.newRGB(1,0,1);toxi.color.TColor.YELLOW=toxi.color.TColor.newRGB(1,1,0);toxi.color.TColor.BLACK=toxi.color.TColor.newRGB(0,0,0);toxi.color.TColor.WHITE=toxi.color.TColor.newRGB(1,1,1)})();
29 |
--------------------------------------------------------------------------------
/vendor/toxi/toxi-physics2d.js:
--------------------------------------------------------------------------------
1 | // toxi-physics2d r43 - http://github.com/hapticdata/toxiclibsjs
2 | toxi.physics2d=toxi.physics2d||{};toxi.physics2d.removeItemFrom=function(a,b){var c=b.indexOf(a);if(c>-1)return b.splice(c,1)};toxi.physics2d.VerletParticle2D=function(a,b,c){this.force=new toxi.Vec2D;if(a instanceof toxi.Vec2D)if(a instanceof toxi.physics2d.VerletParticle2D){b=a.y;c=a.weight;a=a.x;this.isLocked=a.isLocked}else{if(b===undefined){b=a.y;c=1}else{c=b;b=a.y}a=a.x}toxi.Vec2D.apply(this,[a,b]);this.isLocked=false;this.prev=new toxi.Vec2D(this);this.temp=new toxi.Vec2D;c=c||1;this.setWeight(c)};
3 | toxi.extend(toxi.physics2d.VerletParticle2D,toxi.Vec2D);toxi.physics2d.VerletParticle2D.prototype.addBehavior=function(a,b){if(this.behaviors===undefined)this.behaviors=[];if(a===undefined)throw{name:"TypeError",message:"behavior was undefined"};b=b===undefined?1:b;a.configure(b);this.behaviors.push(a);return this};toxi.physics2d.VerletParticle2D.prototype.addConstraint=function(a){if(this.constraints===undefined)this.constraints=[];this.constraints.push(a);return this};
4 | toxi.physics2d.VerletParticle2D.prototype.addForce=function(a){this.force.addSelf(a);return this};toxi.physics2d.VerletParticle2D.prototype.addVelocity=function(a){this.prev.subSelf(a);return this};toxi.physics2d.VerletParticle2D.prototype.applyBehaviors=function(){if(this.behaviors!==undefined){var a=0;for(a=0;a1){this.theta=b;this.rootPos=new toxi.Vec2D(a)}else{this.rootPos=new toxi.Vec2D;this.theta=a}if(parseInt(this.theta,10)!=this.theta)this.theta=toxi.MathUtils.radians(this.theta)};toxi.physics2d.AngularConstraint.prototype.applyConstraint=function(a){var b=a.sub(this.rootPos),c=toxi.MathUtils.floor(b.heading()/this.theta)*this.theta;a.set(this.rootPos.add(toxi.Vec2D.fromTheta(c).scaleSelf(b.magnitude())))};
17 | toxi.physics2d.AxisConstraint=function(a,b){this.axis=a;this.constraint=b};toxi.physics2d.AxisConstraint.prototype.applyConstraint=function(a){a.setComponent(this.axis,this.constraint)};toxi.physics2d.CircularConstraint=function(a,b){if(arguments.length==1)this.circle=a;else{console.log("a: "+a);this.circle=new toxi.Circle(a,b)}};toxi.physics2d.CircularConstraint.prototype.applyConstraint=function(a){this.circle.containsPoint(a)&&a.set(this.circle.add(a.sub(this.circle).normalizeTo(this.circle.getRadius())))};
18 | toxi.physics2d.MaxConstraint=function(a,b){this.axis=a;this.threshold=b};toxi.physics2d.MaxConstraint.prototype.applyConstraint=function(a){a.getComponent(this.axis)>this.threshold&&a.setComponent(this.axis,this.threshold)};toxi.physics2d.MinConstraint=function(a,b){this.axis=a;this.threshold=b};toxi.physics2d.MinConstraint.prototype.applyConstraint=function(a){a.getComponent(this.axis)1)this.rect=new toxi.Rect(a,b);this.intersectRay=new toxi.Ray2D(this.rect.getCentroid(),new toxi.Vec2D)};
20 | toxi.physics2d.RectConstraint.prototype={applyConstraint:function(a){this.rect.containsPoint(a)&&a.set(this.rect.intersectsRay(this.intersectRay.setDirection(this.intersectRay.sub(a)),0,Number.MAX_VALUE))},getBox:function(){return this.rect.copy()},setBox:function(a){this.rect=a.copy();this.intersectRay.set(this.rect.getCentroid())}};toxi.physics2d.ParticlePath2D=function(a){toxi.Spline2D.call(this,a);this.particles=[]};toxi.extend(toxi.physics2d.ParticlePath2D,toxi.Spline2D);
21 | (function(){toxi.physics2d.ParticlePath2D.prototype.createParticles=function(a,b,c,d){this.particles=[];this.computeVertices(b);b=0;c=this.getDecimatedVertices(c,true);for(b=0;bthis.restLengthSquared&&this.parent.update.call(this,a)};
27 | toxi.physics2d.VerletConstrainedSpring2D=function(a,b,c,d,e){toxi.physics2d.VerletSpring2D.call(this,a,b,c,d);this.limit=e===undefined?Number.MAX_VALUE:e};toxi.extend(toxi.physics2d.VerletConstrainedSpring2D,toxi.physics2d.VerletSpring2D);
28 | toxi.physics2d.VerletConstrainedSpring2D.update=function(a){var b=this.b.sub(this.a),c=b.magnitude()+toxi.physics2d.VerletSpring2D.EPS;c=(c-this.restLength)/(c*(this.a.invWeight+this.b.invWeight))*this.strength;if(!this.a.isLocked&&!this.isALocked){this.a.addSelf(b.scale(c*this.a.invWeight).limit(this.limit));a&&this.a.applyConstraints()}if(!this.b.isLocked&&!this.isBLocked){this.b.subSelf(b.scale(c*this.b.invWeight).limit(this.limit));a&&this.b.applyConstraints()}};
29 | toxi.physics2d.VerletMinDistanceSpring2D=function(a,b,c,d){toxi.physics2d.VerletSpring2D.call(this,a,b,c,d);this.setRestLength(c)};toxi.extend(toxi.physics2d.VerletMinDistanceSpring2D,toxi.physics2d.VerletSpring2D);toxi.physics2d.VerletMinDistanceSpring2D.prototype.update=function(a){this.b.distanceToSquared(this.a)0;a--)for(b=0;b -1){
7 | return array.splice(index,1);
8 | }
9 | return undefined;
10 | };
11 | toxi.physics2d.VerletParticle2D = function(x,y,w){
12 | this.force = new toxi.Vec2D();
13 | if(x instanceof toxi.Vec2D){
14 | if(x instanceof toxi.physics2d.VerletParticle2D){
15 |
16 | y = x.y;
17 | w = x.weight;
18 | x = x.x;
19 | this.isLocked = x.isLocked;
20 |
21 | } else if(y === undefined){
22 | y = x.y;
23 | w = 1;
24 | x = x.x;
25 | } else {
26 | w = y;
27 | y = x.y;
28 | x = x.x;
29 | }
30 | }
31 | toxi.Vec2D.apply(this,[x,y]);
32 | this.isLocked = false;
33 | this.prev = new toxi.Vec2D(this);
34 | this.temp = new toxi.Vec2D();
35 | w = w || 1;
36 | this.setWeight(w);
37 | };
38 |
39 | toxi.extend(toxi.physics2d.VerletParticle2D,toxi.Vec2D);
40 |
41 | toxi.physics2d.VerletParticle2D.prototype.addBehavior = function(behavior,timeStep){
42 | if(this.behaviors === undefined){
43 | this.behaviors = [];
44 | }
45 | if(behavior === undefined){
46 | throw { name: "TypeError", message: "behavior was undefined"};
47 | }
48 | timeStep = (timeStep === undefined)? 1 : timeStep;
49 | behavior.configure(timeStep);
50 | this.behaviors.push(behavior);
51 | return this;
52 | };
53 |
54 | toxi.physics2d.VerletParticle2D.prototype.addConstraint = function(c){
55 | if(this.constraints === undefined){
56 | this.constraints = [];
57 | }
58 | this.constraints.push(c);
59 | return this;
60 | };
61 |
62 | toxi.physics2d.VerletParticle2D.prototype.addForce = function(f){
63 | this.force.addSelf(f);
64 | return this;
65 | };
66 |
67 | toxi.physics2d.VerletParticle2D.prototype.addVelocity = function(v){
68 | this.prev.subSelf(v);
69 | return this;
70 | };
71 |
72 | toxi.physics2d.VerletParticle2D.prototype.applyBehaviors = function(){
73 | if(this.behaviors !== undefined){
74 | var i = 0;
75 | for(i = 0;i 1){
341 | var p = theta_p;
342 | this.theta = theta;
343 | this.rootPos = new toxi.Vec2D(p);
344 | } else {
345 | this.rootPos = new toxi.Vec2D();
346 | this.theta = theta_p;
347 | }
348 | if(parseInt(this.theta,10) != this.theta){
349 | this.theta = toxi.MathUtils.radians(this.theta);
350 | }
351 | };
352 |
353 |
354 | toxi.physics2d.AngularConstraint.prototype.applyConstraint = function(p){
355 | var delta = p.sub(this.rootPos);
356 | var heading = toxi.MathUtils.floor(delta.heading() / this.theta) * this.theta;
357 | p.set(this.rootPos.add(toxi.Vec2D.fromTheta(heading).scaleSelf(delta.magnitude())));
358 | };/**
359 | * Constrains a particle's movement by locking a given axis to a fixed value.
360 | */
361 | toxi.physics2d.AxisConstraint = function(axis,constraintAmount){
362 | this.axis = axis;
363 | this.constraint = constraintAmount;
364 | };
365 |
366 | toxi.physics2d.AxisConstraint.prototype.applyConstraint = function(p){
367 | p.setComponent(this.axis,this.constraint);
368 | };toxi.physics2d.CircularConstraint = function(a,b){
369 | if(arguments.length == 1){
370 | this.circle = a;
371 | } else {
372 | console.log("a: "+a);
373 | this.circle = new toxi.Circle(a,b);
374 | }
375 | };
376 |
377 | toxi.physics2d.CircularConstraint.prototype.applyConstraint = function(p){
378 | if(this.circle.containsPoint(p)){
379 | p.set(this.circle.add(p.sub(this.circle).normalizeTo(this.circle.getRadius())));
380 | }
381 | };toxi.physics2d.MaxConstraint = function(axis,threshold){
382 | this.axis = axis;
383 | this.threshold = threshold;
384 | };
385 |
386 | toxi.physics2d.MaxConstraint.prototype.applyConstraint = function(p){
387 | if(p.getComponent(this.axis) > this.threshold){
388 | p.setComponent(this.axis,this.threshold);
389 | }
390 | };toxi.physics2d.MinConstraint = function(axis,threshold){
391 | this.axis = axis;
392 | this.threshold = threshold;
393 | };
394 |
395 | toxi.physics2d.MinConstraint.prototype.applyConstraint = function(p){
396 | if(p.getComponent(this.axis) < this.threshold){
397 | p.setComponent(this.axis, this.threshold);
398 | }
399 | };toxi.physics2d.RectConstraint = function(a,b){
400 | if(arguments.length == 1){
401 | this.rect = a.copy();
402 | } else if(arguments.length > 1){
403 | this.rect = new toxi.Rect(a,b);
404 | }
405 | this.intersectRay = new toxi.Ray2D(this.rect.getCentroid(), new toxi.Vec2D());
406 | };
407 |
408 | toxi.physics2d.RectConstraint.prototype = {
409 | applyConstraint: function(p){
410 | if(this.rect.containsPoint(p)){
411 | p.set(this.rect.intersectsRay(this.intersectRay.setDirection(this.intersectRay.sub(p)),0,Number.MAX_VALUE));
412 | }
413 | },
414 |
415 | getBox: function(){
416 | return this.rect.copy();
417 | },
418 |
419 | setBox: function(rect){
420 | this.rect = rect.copy();
421 | this.intersectRay.set(this.rect.getCentroid());
422 | }
423 | };toxi.physics2d.ParticlePath2D = function(points){
424 | toxi.Spline2D.call(this,points);
425 | this.particles = [];
426 | };
427 | toxi.extend(toxi.physics2d.ParticlePath2D,toxi.Spline2D);
428 |
429 | (function(){
430 | //protected
431 | var createSingleParticle = function(pos,mass){
432 | return new toxi.physics2d.VerletParticle2D(pos,mass);
433 | };
434 |
435 | //public
436 | toxi.physics2d.ParticlePath2D.prototype.createParticles = function(physics,subDiv,step,mass){
437 | this.particles = [];
438 | this.computeVertices(subDiv);
439 | var i = 0;
440 | var dv = this.getDecimatedVertices(step,true);
441 | for(i = 0; i < dv; i++){
442 | var p = this.createSingleParticle(v,mass);
443 | this.particles.push(p);
444 | physics.addParticle(p);
445 | }
446 | return this.particles;
447 | };
448 |
449 |
450 | })();/**
451 | * Utility builder/grouping/management class to connect a set of particles into
452 | * a physical string/thread. Custom spring types can be used by subclassing this
453 | * class and overwriting the
454 | * {@link #createSpring(VerletParticle2D, VerletParticle2D, float, float)}
455 | method.
456 | */
457 |
458 | /**
459 | Construct a ParticleString2D,
460 | parameter options:
461 | 1 - options object
462 | 3 - VerletPhysics2D physics, Array plist, Number strength
463 | 6 - VerletPhysics2D physic, Vec2D pos, Vec2D step, Number num, Number mass, Number strength
464 | */
465 |
466 | toxi.physics2d.ParticleString2D = function(){
467 | var opts = {
468 | physics: undefined,
469 | plist: undefined,
470 | pos: undefined,
471 | step: undefined,
472 | num: undefined,
473 | mass: undefined,
474 | strength: undefined
475 | },
476 | is6ParamConstructor = false;
477 | if(arguments.length === 0){
478 | throw new Error("Incorrect Parameters");
479 | } else if(arguments.length == 1){ //options object
480 | var arg = arguments[0];
481 | for(var prop in arg){
482 | opts[prop] = arg[prop];
483 | }
484 | } else {
485 | opts.physics = arguments[0];
486 | if(arguments.length == 6){
487 | opts.pos = arguments[1];
488 | opts.step = arguments[2];
489 | opts.num = arguments[3];
490 | opts.mass = arguments[4];
491 | opts.strength = arguments[5];
492 | } else {
493 | opts.plist = arguments[1];
494 | opts.strength = arguments[2];
495 | }
496 | }
497 | if(opts.num !== undefined && opts.pos !== undefined && opts.step !== undefined && opts.mass !== undefined){
498 | is6ParamConstructor = true;
499 | }
500 | if(!is6ParamConstructor && opts.plist === undefined){
501 | throw new Error("Incorrect Parameters, please supply plist or num, pos, step & mass");
502 | }
503 |
504 |
505 | this.physics = opts.physics;
506 | this.links = [];
507 |
508 | var prev,
509 | p,
510 | s,
511 | strength,
512 | i = 0;
513 |
514 |
515 | if(is6ParamConstructor){
516 | var pos = opts.pos.copy(),
517 | step = opts.step,
518 | mass = opts.mass,
519 | len = step.magnitude();
520 | this.particles = [];
521 | strength = opts.strength;
522 |
523 | for(i = 0; i < opts.num; i++){
524 | p = new toxi.physics2d.VerletParticle2D(pos.copy(),mass);
525 | this.particles.push(p);
526 | this.physics.particles.push(p);
527 | if(prev !== undefined){
528 | s = this.createSpring(prev,p,len,strength);
529 | this.links.push(s);
530 | this.physics.addSpring(s);
531 | }
532 | prev = p;
533 | pos.addSelf(step);
534 | }
535 | } else {
536 | strength = opts.strength;
537 | this.particles = opts.plist || [];
538 |
539 |
540 | for(i = 0; i < this.particles.length; i++){
541 | p = this.particles[i];
542 | this.physics.addParticle(p);
543 | if(prev !== undefined){
544 | s = this.createSpring(prev,p,prev.distanceTo(p),strength);
545 | this.links.push(s);
546 | this.physics.addSpring(s);
547 | }
548 | prev = p;
549 | }
550 | }
551 | };
552 | toxi.physics2d.ParticleString2D.prototype = {
553 | clear: function(){
554 | for(var i = 0, len = this.links.length; i < len; i++){
555 | this.physics.removeSpringElements(s);
556 | }
557 | this.particles.clear();
558 | this.links.clear();
559 | },
560 | createSpring: function(a,b,len,strength){
561 | return new toxi.physics2d.VerletSpring2D(a,b,len,strength);
562 | },
563 |
564 | getHead: function(){
565 | return this.particles[0];
566 | },
567 |
568 | getNumParticles: function(){
569 | return this.particles.length;
570 | },
571 |
572 | getTail: function(){
573 | return this.particles[this.particles.length-1];
574 | }
575 |
576 | };/**
577 | * Creates a pullback spring (default restlength=0.5) between 2 particles and
578 | * locks the first one given at the current position. The spring is only
579 | * enforced if the current length of the spring exceeds the rest length. This
580 | * behaviour is the opposite to the {@link VerletMinDistanceSpring2D}.
581 | */
582 |
583 | toxi.physics2d.PullBackString2D = function(a,b,strength){
584 | toxi.physics2d.VerletSpring2D.apply(this,[a,b,0,strength]);
585 | a.lock();
586 | this.setRestLength(0.5);
587 | };
588 | toxi.extend(toxi.physics2d.PullBackString2D,toxi.physics2d.VerletSpring2D);
589 |
590 | toxi.physics2d.PullBackString2D.prototype.update = function(applyConstraints){
591 | if(this.b.distanceToSquared(this.a) > this.restLengthSquared){
592 | this.parent.update.call(this,applyConstraints);
593 | }
594 | };toxi.physics2d.VerletConstrainedSpring2D = function(particleA, particleB, len, str, limit){
595 | toxi.physics2d.VerletSpring2D.call(this,particleA,particleB,len,str);
596 | this.limit = (limit === undefined) ? Number.MAX_VALUE : limit;
597 | };
598 |
599 | toxi.extend(toxi.physics2d.VerletConstrainedSpring2D,toxi.physics2d.VerletSpring2D);
600 |
601 |
602 | toxi.physics2d.VerletConstrainedSpring2D.update = function(applyConstraints){
603 | var delta = this.b.sub(this.a);
604 | // add minute offset to avoid div-by-zero errors
605 | var dist = delta.magnitude() + toxi.physics2d.VerletSpring2D.EPS;
606 | var normDistStrength = (dist - this.restLength) / (dist * (this.a.invWeight + this.b.invWeight))* this.strength;
607 | if (!this.a.isLocked && !this.isALocked) {
608 | this.a.addSelf(delta.scale(normDistStrength * this.a.invWeight).limit(this.limit));
609 | if (applyConstraints) {
610 | this.a.applyConstraints();
611 | }
612 | }
613 | if (!this.b.isLocked && !this.isBLocked) {
614 | this.b.subSelf(delta.scale(normDistStrength * this.b.invWeight).limit(this.limit));
615 | if (applyConstraints) {
616 | this.b.applyConstraints();
617 | }
618 | }
619 | };toxi.physics2d.VerletMinDistanceSpring2D = function(particleA,particleB,len,str){
620 | toxi.physics2d.VerletSpring2D.call(this,particleA,particleB,len,str);
621 | this.setRestLength(len);
622 | };
623 |
624 |
625 | toxi.extend(toxi.physics2d.VerletMinDistanceSpring2D,toxi.physics2d.VerletSpring2D);
626 |
627 | toxi.physics2d.VerletMinDistanceSpring2D.prototype.update = function(applyConstraints){
628 | if(this.b.distanceToSquared(this.a) < this.restLengthSquared){
629 | this.parent.update.call(this,applyConstraints);
630 | }
631 | };toxi.physics2d.VerletPhysics2D = function(gravity, numIterations, drag, timeStep){
632 | var opts = {
633 | numIterations: 50,
634 | drag: 0,
635 | timeStep: 1
636 | },
637 | args;
638 | if(arguments.length == 1 && (arguments[0].gravity || arguments[0].numIterations || arguments[0].timeStep || arguments[0].drag)){ //options object literal
639 | args = arguments[0];
640 | if(args.gravity !== undefined){
641 | gravity = args.gravity;
642 | }
643 | if(args.numIterations !== undefined){
644 | opts.numIterations = args.gravity;
645 | }
646 | if(args.drag !== undefined){
647 | opts.drag = args.drag;
648 | }
649 | if(args.timeStep !== undefined){
650 | opts.timeStep = args.timeStep;
651 | }
652 | }
653 | this.behaviors = [];
654 | this.particles = [];
655 | this.springs = [];
656 | this.numIterations = opts.numIterations;
657 | this.timeStep = opts.timeStep;
658 | this.setDrag(opts.drag);
659 |
660 | if(gravity){
661 | if(gravity instanceof toxi.physics2d.GravityBehavior){
662 | this.addBehavior(gravity);
663 | } else if(gravity instanceof Object && gravity.hasOwnProperty('x') && gravity.hasOwnProperty('y')){
664 | this.addBehavior(
665 | new toxi.physics2d.GravityBehavior(
666 | new toxi.Vec2D(gravity)
667 | )
668 | );
669 | }
670 | }
671 | };
672 |
673 | toxi.physics2d.VerletPhysics2D.addConstraintToAll = function(c, list){
674 | for(var i=0;i 0; i--){
838 | for(j = 0;j ");
28 | }
--------------------------------------------------------------------------------
/vendor/un/Unctrl.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by unctrl.com
3 | * User: mannytan
4 | * Date: 8/22/11
5 | */
6 |
7 | var UNCTRL = UNCTRL || {};
--------------------------------------------------------------------------------
/vendor/un/Utils.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by .
3 | * User: manuelt
4 | * unsorted utils, will ned to convert to a framework eventually
5 | */
6 | function distanceTo(a, b) {
7 | var dx = a.x - b.x;
8 | var dy = a.y - b.y;
9 | return Math.sqrt((dx * dx) + (dy * dy));
10 | }
11 |
12 | function dotProduct(v0, v) {
13 | return (v0.x * v.x) + (v0.y * v.y);
14 | }
15 |
16 | function crossProduct(v0, v) {
17 | return(v0.x * v.y) - (v.x * v0.y);
18 | }
19 | function randomRange(min, max) {
20 | return ((Math.random() * (max - min)) + min);
21 | }
22 | function randomRange(min, max, expo) {
23 | return toDecimal(((Math.random() * (max - min)) + min), expo);
24 | }
25 | function toDecimal(arg, expo) {
26 | return parseFloat(arg.toFixed(expo));
27 | }
28 |
29 | function clamp(min, max, value) {
30 | return Math.max(min, Math.min(max, value));
31 | }
32 |
33 | function shuffleArray(total){
34 | var a = [];
35 | var b = [];
36 | for (var i=0; i0) {
40 | b.push(a.splice( (Math.random()*a.length) , 1)|0);
41 | }
42 | return b;
43 | }
44 |
45 | function getUrlVars() {
46 | var vars = {};
47 | var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
48 | vars[key] = value;
49 | });
50 | return vars;
51 | }
52 |
53 | var TO_DEGREES = 180 / Math.PI;
54 | var TO_RADIANS = Math.PI / 180;
55 | var TWO_PI = Math.PI * 2;
56 | var ONE_PI = Math.PI;
57 |
58 | function hsvToHex(h, s, v){
59 |
60 | var r, g, b;
61 |
62 | var i = Math.floor(h * 6);
63 | var f = h * 6 - i;
64 | var p = v * (1 - s);
65 | var q = v * (1 - f * s);
66 | var t = v * (1 - (1 - f) * s);
67 |
68 | switch(i % 6){
69 | case 0: r = v, g = t, b = p; break;
70 | case 1: r = q, g = v, b = p; break;
71 | case 2: r = p, g = v, b = t; break;
72 | case 3: r = p, g = q, b = v; break;
73 | case 4: r = t, g = p, b = v; break;
74 | case 5: r = v, g = p, b = q; break;
75 | }
76 |
77 | return "0x" + (((1 << 24) + ((r * 255) << 16) + ((g * 255) << 8) + (b * 255))|0).toString(16).slice(1);
78 |
79 | }
80 |
--------------------------------------------------------------------------------