source: other-projects/playing-in-the-street/summer-2013/trunk/Playing-in-the-Street-WPF/Content/Web/mrdoob-three.js-4862f5f/editor/js/Viewport.js@ 28897

Last change on this file since 28897 was 28897, checked in by davidb, 10 years ago

GUI front-end to server base plus web page content

File size: 10.3 KB
Line 
1var Viewport = function ( editor ) {
2
3 var signals = editor.signals;
4
5 var container = new UI.Panel();
6 container.setPosition( 'absolute' );
7
8 var info = new UI.Text();
9 info.setPosition( 'absolute' );
10 info.setRight( '5px' );
11 info.setBottom( '5px' );
12 info.setFontSize( '12px' );
13 info.setColor( '#ffffff' );
14 info.setValue( 'objects: 0, vertices: 0, faces: 0' );
15 container.add( info );
16
17 var scene = editor.scene;
18 var sceneHelpers = editor.sceneHelpers;
19
20 var objects = [];
21
22 // helpers
23
24 var grid = new THREE.GridHelper( 500, 25 );
25 sceneHelpers.add( grid );
26
27 //
28
29 var camera = new THREE.PerspectiveCamera( 50, container.dom.offsetWidth / container.dom.offsetHeight, 1, 5000 );
30 camera.position.fromArray( editor.config.getKey( 'camera' ).position );
31 camera.lookAt( new THREE.Vector3().fromArray( editor.config.getKey( 'camera' ).target ) );
32
33 //
34
35 var selectionBox = new THREE.BoxHelper();
36 selectionBox.material.depthTest = false;
37 selectionBox.material.transparent = true;
38 selectionBox.visible = false;
39 sceneHelpers.add( selectionBox );
40
41 var transformControls = new THREE.TransformControls( camera, container.dom );
42 transformControls.addEventListener( 'change', function () {
43
44 controls.enabled = true;
45
46 if ( transformControls.axis !== undefined ) {
47
48 controls.enabled = false;
49
50 }
51
52 if ( editor.selected !== null ) {
53
54 signals.objectChanged.dispatch( editor.selected );
55
56 }
57
58 } );
59 sceneHelpers.add( transformControls );
60
61 // fog
62
63 var oldFogType = "None";
64 var oldFogColor = 0xaaaaaa;
65 var oldFogNear = 1;
66 var oldFogFar = 5000;
67 var oldFogDensity = 0.00025;
68
69 // object picking
70
71 var ray = new THREE.Raycaster();
72 var projector = new THREE.Projector();
73
74 // events
75
76 var getIntersects = function ( event, object ) {
77
78 var rect = container.dom.getBoundingClientRect();
79 x = ( event.clientX - rect.left ) / rect.width;
80 y = ( event.clientY - rect.top ) / rect.height;
81 var vector = new THREE.Vector3( ( x ) * 2 - 1, - ( y ) * 2 + 1, 0.5 );
82
83 projector.unprojectVector( vector, camera );
84
85 ray.set( camera.position, vector.sub( camera.position ).normalize() );
86
87 if ( object instanceof Array ) {
88
89 return ray.intersectObjects( object );
90
91 }
92
93 return ray.intersectObject( object );
94
95 };
96
97 var onMouseDownPosition = new THREE.Vector2();
98 var onMouseUpPosition = new THREE.Vector2();
99
100 var onMouseDown = function ( event ) {
101
102 event.preventDefault();
103
104 var rect = container.dom.getBoundingClientRect();
105 x = (event.clientX - rect.left) / rect.width;
106 y = (event.clientY - rect.top) / rect.height;
107 onMouseDownPosition.set( x, y );
108
109 document.addEventListener( 'mouseup', onMouseUp, false );
110
111 };
112
113 var onMouseUp = function ( event ) {
114
115 var rect = container.dom.getBoundingClientRect();
116 x = (event.clientX - rect.left) / rect.width;
117 y = (event.clientY - rect.top) / rect.height;
118 onMouseUpPosition.set( x, y );
119
120 if ( onMouseDownPosition.distanceTo( onMouseUpPosition ) == 0 ) {
121
122 var intersects = getIntersects( event, objects );
123
124 if ( intersects.length > 0 ) {
125
126 var object = intersects[ 0 ].object;
127
128 if ( object.userData.object !== undefined ) {
129
130 // helper
131
132 editor.select( object.userData.object );
133
134 } else {
135
136 editor.select( object );
137
138 }
139
140 } else {
141
142 editor.select( null );
143
144 }
145
146 render();
147
148 }
149
150 document.removeEventListener( 'mouseup', onMouseUp );
151
152 };
153
154 var onDoubleClick = function ( event ) {
155
156 var intersects = getIntersects( event, objects );
157
158 if ( intersects.length > 0 && intersects[ 0 ].object === editor.selected ) {
159
160 controls.focus( editor.selected );
161
162 }
163
164 };
165
166 container.dom.addEventListener( 'mousedown', onMouseDown, false );
167 container.dom.addEventListener( 'dblclick', onDoubleClick, false );
168
169 // controls need to be added *after* main logic,
170 // otherwise controls.enabled doesn't work.
171
172 var controls = new THREE.EditorControls( camera, container.dom );
173 controls.center.fromArray( editor.config.getKey( 'camera' ).target )
174 controls.addEventListener( 'change', function () {
175
176 transformControls.update();
177 signals.cameraChanged.dispatch( camera );
178
179 } );
180
181 // signals
182
183 signals.themeChanged.add( function ( value ) {
184
185 switch ( value ) {
186
187 case 'css/light.css':
188 grid.setColors( 0x444444, 0x888888 );
189 clearColor = 0xaaaaaa;
190 break;
191 case 'css/dark.css':
192 grid.setColors( 0xbbbbbb, 0x888888 );
193 clearColor = 0x333333;
194 break;
195
196 }
197
198 renderer.setClearColor( clearColor );
199
200 render();
201
202 } );
203
204 signals.transformModeChanged.add( function ( mode ) {
205
206 transformControls.setMode( mode );
207
208 } );
209
210 signals.snapChanged.add( function ( dist ) {
211
212 transformControls.setSnap( dist );
213
214 } );
215
216 signals.spaceChanged.add( function ( space ) {
217
218 transformControls.setSpace( space );
219
220 } );
221
222 signals.rendererChanged.add( function ( type ) {
223
224 container.dom.removeChild( renderer.domElement );
225
226 renderer = new THREE[ type ]( { antialias: true } );
227 renderer.autoClear = false;
228 renderer.autoUpdateScene = false;
229 renderer.setClearColor( clearColor );
230 renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
231
232 container.dom.appendChild( renderer.domElement );
233
234 render();
235
236 } );
237
238 signals.sceneGraphChanged.add( function () {
239
240 render();
241 updateInfo();
242
243 } );
244
245 signals.cameraChanged.add( function () {
246
247 editor.config.setKey( 'camera', {
248 position: camera.position.toArray(),
249 target: controls.center.toArray()
250 } );
251
252 render();
253
254 } );
255
256 signals.objectSelected.add( function ( object ) {
257
258 selectionBox.visible = false;
259 transformControls.detach();
260
261 if ( object !== null ) {
262
263 if ( object.geometry !== undefined ) {
264
265 selectionBox.update( object );
266 selectionBox.visible = true;
267
268 }
269
270 if ( object instanceof THREE.PerspectiveCamera === false ) {
271
272 transformControls.attach( object );
273
274 }
275
276 }
277
278 render();
279
280 } );
281
282 signals.objectAdded.add( function ( object ) {
283
284 var materialsNeedUpdate = false;
285
286 object.traverse( function ( child ) {
287
288 if ( child instanceof THREE.Light ) materialsNeedUpdate = true;
289
290 objects.push( child );
291
292 } );
293
294 if ( materialsNeedUpdate === true ) updateMaterials();
295
296 } );
297
298 signals.objectChanged.add( function ( object ) {
299
300 transformControls.update();
301
302 if ( object !== camera ) {
303
304 if ( object.geometry !== undefined ) {
305
306 selectionBox.update( object );
307
308 }
309
310 if ( editor.helpers[ object.id ] !== undefined ) {
311
312 editor.helpers[ object.id ].update();
313
314 }
315
316 updateInfo();
317
318 }
319
320 render();
321
322 } );
323
324 signals.objectRemoved.add( function ( object ) {
325
326 var materialsNeedUpdate = false;
327
328 object.traverse( function ( child ) {
329
330 if ( child instanceof THREE.Light ) materialsNeedUpdate = true;
331
332 objects.splice( objects.indexOf( child ), 1 );
333
334 } );
335
336 if ( materialsNeedUpdate === true ) updateMaterials();
337
338 } );
339
340 signals.helperAdded.add( function ( object ) {
341
342 objects.push( object.getObjectByName( 'picker' ) );
343
344 } );
345
346 signals.helperRemoved.add( function ( object ) {
347
348 objects.splice( objects.indexOf( object.getObjectByName( 'picker' ) ), 1 );
349
350 } );
351
352 signals.materialChanged.add( function ( material ) {
353
354 render();
355
356 } );
357
358 signals.fogTypeChanged.add( function ( fogType ) {
359
360 if ( fogType !== oldFogType ) {
361
362 if ( fogType === "None" ) {
363
364 scene.fog = null;
365
366 } else if ( fogType === "Fog" ) {
367
368 scene.fog = new THREE.Fog( oldFogColor, oldFogNear, oldFogFar );
369
370 } else if ( fogType === "FogExp2" ) {
371
372 scene.fog = new THREE.FogExp2( oldFogColor, oldFogDensity );
373
374 }
375
376 updateMaterials();
377
378 oldFogType = fogType;
379
380 }
381
382 render();
383
384 } );
385
386 signals.fogColorChanged.add( function ( fogColor ) {
387
388 oldFogColor = fogColor;
389
390 updateFog( scene );
391
392 render();
393
394 } );
395
396 signals.fogParametersChanged.add( function ( near, far, density ) {
397
398 oldFogNear = near;
399 oldFogFar = far;
400 oldFogDensity = density;
401
402 updateFog( scene );
403
404 render();
405
406 } );
407
408 signals.windowResize.add( function () {
409
410 camera.aspect = container.dom.offsetWidth / container.dom.offsetHeight;
411 camera.updateProjectionMatrix();
412
413 renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
414
415 render();
416
417 } );
418
419 signals.playAnimations.add( function (animations) {
420
421 function animate() {
422
423 requestAnimationFrame( animate );
424
425 for ( var i = 0; i < animations.length ; i ++ ) {
426
427 animations[i].update(0.016);
428
429 }
430
431 render();
432 }
433
434 animate();
435
436 } );
437
438 //
439
440 var clearColor, renderer;
441
442 if ( editor.config.getKey( 'renderer' ) !== undefined ) {
443
444 renderer = new THREE[ editor.config.getKey( 'renderer' ) ]( { antialias: true } );
445
446 } else {
447
448 if ( System.support.webgl === true ) {
449
450 renderer = new THREE.WebGLRenderer( { antialias: true } );
451
452 } else {
453
454 renderer = new THREE.CanvasRenderer();
455
456 }
457
458 }
459
460 renderer.autoClear = false;
461 renderer.autoUpdateScene = false;
462 container.dom.appendChild( renderer.domElement );
463
464 animate();
465
466 //
467
468 function updateInfo() {
469
470 var objects = 0;
471 var vertices = 0;
472 var faces = 0;
473
474 scene.traverse( function ( object ) {
475
476 if ( object instanceof THREE.Mesh ) {
477
478 objects ++;
479
480 var geometry = object.geometry;
481
482 if ( geometry instanceof THREE.Geometry ) {
483
484 vertices += geometry.vertices.length;
485 faces += geometry.faces.length;
486
487 } else if ( geometry instanceof THREE.BufferGeometry ) {
488
489 vertices += geometry.attributes.position.array.length / 3;
490
491 if ( geometry.attributes.index !== undefined ) {
492
493 faces += geometry.attributes.index.array.length / 3;
494
495 } else {
496
497 faces += vertices / 3;
498
499 }
500
501 }
502
503 }
504
505 } );
506
507 info.setValue( 'objects: ' + objects + ', vertices: ' + vertices + ', faces: ' + faces );
508
509 }
510
511 function updateMaterials() {
512
513 editor.scene.traverse( function ( node ) {
514
515 if ( node.material ) {
516
517 node.material.needsUpdate = true;
518
519 if ( node.material instanceof THREE.MeshFaceMaterial ) {
520
521 for ( var i = 0; i < node.material.materials.length; i ++ ) {
522
523 node.material.materials[ i ].needsUpdate = true;
524
525 }
526
527 }
528
529 }
530
531 } );
532
533 }
534
535 function updateFog( root ) {
536
537 if ( root.fog ) {
538
539 root.fog.color.setHex( oldFogColor );
540
541 if ( root.fog.near !== undefined ) root.fog.near = oldFogNear;
542 if ( root.fog.far !== undefined ) root.fog.far = oldFogFar;
543 if ( root.fog.density !== undefined ) root.fog.density = oldFogDensity;
544
545 }
546
547 }
548
549 function animate() {
550
551 requestAnimationFrame( animate );
552
553 }
554
555 function render() {
556
557 sceneHelpers.updateMatrixWorld();
558 scene.updateMatrixWorld();
559
560 renderer.clear();
561 renderer.render( scene, camera );
562 renderer.render( sceneHelpers, camera );
563
564 //console.trace();
565
566 }
567
568 return container;
569
570}
Note: See TracBrowser for help on using the repository browser.