One of the appealing aspects of Play is that it allows users to make compelling 3D interactive experiences without programming. For comparision, below is the very same scene, created first in Play, then in Javascript.

Play Version:

To create the Play scene above, this is the node diagram required.

js

Three.js version:

To create the Three.js scene above, this is the javascript required.



                  if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

            var container, stats, canvas;

            // var threeHolder = $('#three-holder');

            var camera, cameraTarget, scene, renderer;

            init();
            animate();

            function init() {

                canvas = document.getElementById( "myCanvas" );

                canvas.height = 450;
                canvas.width = 800;


                camera = new THREE.PerspectiveCamera( 35, 16 / 9, 1, 15 );
                camera.position.set( 3, 0.15, 3 );

                cameraTarget = new THREE.Vector3( 0, -0.25, 0 );

                scene = new THREE.Scene();
                scene.fog = new THREE.Fog( 0x72645b, 2, 15 );


                // Ground

                var plane = new THREE.Mesh(
                    new THREE.PlaneBufferGeometry( 40, 40 ),
                    new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
                );
                plane.rotation.x = -Math.PI/2;
                plane.position.y = -0.5;
                scene.add( plane );

        


                // ASCII file

                var loader = new THREE.STLLoader();
                loader.load( '../stl/ascii/slotted_disk.stl', function ( geometry ) {

                    var material = new THREE.MeshPhongMaterial( { color: 0xff5533, specular: 0x111111, shininess: 200 } );
                    var mesh = new THREE.Mesh( geometry, material );

                    mesh.position.set( 0, - 0.25, 0.6 );
                    mesh.rotation.set( 0, - Math.PI / 2, 0 );
                    mesh.scale.set( 0.5, 0.5, 0.5 );

    

                    scene.add( mesh );

                } );


                // Binary files

                var material = new THREE.MeshPhongMaterial( { color: 0xAAAAAA, specular: 0x111111, shininess: 200 } );

                loader.load( '../stl/binary/pr2_head_pan.stl', function ( geometry ) {

                    var mesh = new THREE.Mesh( geometry, material );

                    mesh.position.set( 0, - 0.37, - 0.6 );
                    mesh.rotation.set( - Math.PI / 2, 0, 0 );
                    mesh.scale.set( 2, 2, 2 );
// 
            

                    scene.add( mesh );

                } );

                loader.load( '../stl/binary/pr2_head_tilt.stl', function ( geometry ) {

                    var mesh = new THREE.Mesh( geometry, material );

                    mesh.position.set( 0.136, - 0.37, - 0.6 );
                    mesh.rotation.set( - Math.PI / 2, 0.3, 0 );
                    mesh.scale.set( 2, 2, 2 );


                    scene.add( mesh );

                } );

                // Colored binary STL
                loader.load( '../stl/binary/colored.stl', function ( geometry ) {

                    var meshMaterial = material;
                    if (geometry.hasColors) {
                        meshMaterial = new THREE.MeshPhongMaterial({ opacity: geometry.alpha, vertexColors: THREE.VertexColors });
                    }

                    var mesh = new THREE.Mesh( geometry, meshMaterial );

                    mesh.position.set( 0.5, 0.2, 0 );
                    mesh.rotation.set( - Math.PI / 2, Math.PI / 2, 0 );
                    mesh.scale.set( 0.3, 0.3, 0.3 );

            

                    scene.add( mesh );

                } );


                // Lights

                scene.add( new THREE.HemisphereLight( 0x443333, 0x111122 ) );

                addShadowedLight( 1, 1, 1, 0xffffff, 1.35 );
                addShadowedLight( 0.5, 1, -1, 0xffaa00, 1 );
                // renderer

                renderer = new THREE.WebGLRenderer( {canvas: canvas, antialias: true}  );
                renderer.setClearColor( scene.fog.color );
                // renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( canvas.width, canvas.height );

                renderer.gammaInput = true;
                renderer.gammaOutput = true;

                renderer.shadowMap.enabled = true;
                renderer.shadowMap.renderReverseSided = false;

                

            }

            function addShadowedLight( x, y, z, color, intensity ) {

                var directionalLight = new THREE.DirectionalLight( color, intensity );
                directionalLight.position.set( x, y, z );
                scene.add( directionalLight );

                directionalLight.castShadow = true;

                var d = 1;
                directionalLight.shadow.camera.left = -d;
                directionalLight.shadow.camera.right = d;
                directionalLight.shadow.camera.top = d;
                directionalLight.shadow.camera.bottom = -d;

                directionalLight.shadow.camera.near = 1;
                directionalLight.shadow.camera.far = 4;

                directionalLight.shadow.mapSize.width = 1024;
                directionalLight.shadow.mapSize.height = 1024;

                directionalLight.shadow.bias = -0.005;

            }


            function animate() {

                requestAnimationFrame( animate );

                render();
        

            }

            function render() {

                var timer = Date.now() * 0.0005;

                camera.position.x = Math.cos( timer ) * 3;
                camera.position.z = Math.sin( timer ) * 3;

                camera.lookAt( cameraTarget );

                renderer.render( scene, camera );

            }