{"id":446,"date":"2011-10-05T21:09:01","date_gmt":"2011-10-05T20:09:01","guid":{"rendered":"http:\/\/www.aymericlamboley.fr\/blog\/?p=446"},"modified":"2011-10-05T21:49:48","modified_gmt":"2011-10-05T20:49:48","slug":"quick-look-into-threejs","status":"publish","type":"post","link":"http:\/\/www.aymericlamboley.fr\/blog\/quick-look-into-threejs\/","title":{"rendered":"Quick look into ThreeJS"},"content":{"rendered":"<p>This two last weeks were very exciting thanks to Adobe&#8217;s announcement : a new framework for 2D games : <a href=\"http:\/\/www.starling-framework.org\/\" target=\"_blank\">Starling<\/a>, running on top of Stage3D (Molehill). Flash Player 11 is out henceforth, new 3D frameworks are coming : <a href=\"http:\/\/www.adobe.com\/devnet\/flashplayer\/articles\/working-with-proscenium.html\" target=\"_blank\">Adobe Proscenium<\/a>, <a href=\"http:\/\/aerys.in\/\" target=\"_blank\">Aerys<\/a>. And other big things like <a href=\"http:\/\/www.bytearray.org\/?p=3597\" target=\"_blank\">Unreal Engine 3 with Unreal Tournament 3<\/a> in our browser !<\/p>\n<p>There&#8217;s a lot to digest ! Starling may be the next thing I will experiment&#8230;<\/p>\n<p>Anyway, before all this annoucement, I was keeping an eye on JavaScript and its most awesome framework : ThreeJS created by <a href=\"http:\/\/mrdoob.com\/\" target=\"_blank\">Mr Doob<\/a>. ThreeJS is a &#8220;lightweight 3D engine with a very low level of complexity \u2014 in other words, for dummies&#8221;. Dummy ? This is what I&#8217;m with 3D engine&#8230; in fact this is the first time that I try a 3D engine&#8230; so let&#8217;s start !<\/p>\n<p>The three.js repository is on <a href=\"https:\/\/github.com\/mrdoob\/three.js\/\" target=\"_blank\"><strong>github<\/strong><\/a> with code source and many examples.<br \/>\nI started to learn ThreeJS with Ilmari Heikkinen&#8217;s slides that you can find <a href=\"http:\/\/fhtr.org\/BasicsOfThreeJS\/#1\" target=\"_blank\"><strong>here<\/strong><\/a>. It is really a good way to start.<\/p>\n<p><a href=\"http:\/\/www.aymericlamboley.fr\/blog\/wp-content\/uploads\/2011\/10\/ThreeJS\/index.html\" target=\"_blank\"><strong>Click here to see my experimentation<\/strong>.<\/a><\/p>\n<p>I used three.js with WebGL render. My source code :<\/p>\n<pre lang=\"javascript\" line=\"1\"><html>\r\n    <head>\r\n        <meta http-equiv=\"content-type\" content=\"text\/html; charset=utf-8\"\/> \r\n        <title>three.js<\/title>\r\n        <style type=\"text\/css\"> \r\n            body {\r\n                color: #808080;\r\n                font-family:Monospace;\r\n                font-size:13px;\r\n                text-align:center;\r\n\r\n                background-color: #ffffff;\r\n                margin: 0px;\r\n                overflow: hidden;\r\n            }\r\n\r\n            #info {\r\n                position: absolute;\r\n                top: 0px; width: 100%;\r\n                padding: 5px;\r\n            }\r\n        <\/style>\r\n    <\/head>\r\n    <body>\r\n\r\n        <div id=\"container\"><\/div>\r\n        <div id=\"info\"><a href=\"http:\/\/github.com\/mrdoob\/three.js\" target=\"_blank\">three.js<\/a><\/div>\r\n\r\n        <script type=\"text\/javascript\" src=\"Three.js\"><\/script>\r\n        <script type=\"text\/javascript\" src=\"raf.js\"><\/script>\r\n\r\n        <script type=\"text\/javascript\">\r\n            \r\n            var renderer = new THREE.WebGLRenderer({antialias: true});\r\n            renderer.setSize(document.body.clientWidth, document.body.clientHeight);\r\n            \r\n            document.body.appendChild(renderer.domElement);\r\n            \r\n            renderer.setClearColorHex(0xEEEEEE, 1.0);\r\n            renderer.clear();\r\n            renderer.shadowCameraFov = 50;\r\n            renderer.shadowMapWidth = 1024;;\r\n            renderer.shadowMapHeight = 1024;\r\n\r\n\r\n            var fov = 45; \/\/ camera field-of-view in degrees\r\n            var width = renderer.domElement.width;\r\n            var height = renderer.domElement.height;\r\n            var aspect = width \/ height; \/\/ view aspect ratio\r\n            var near = 1; \/\/ near clip plane\r\n            var far = 10000; \/\/ far clip plane\r\n            var camera = new THREE.Camera(fov, aspect, near, far);\r\n            camera.position.z = -400;\r\n            camera.position.x = 200;\r\n            camera.position.y = 350;\r\n            \r\n            const NBR_ELEMENTS = 250;\r\n            \r\n            var scene = new THREE.Scene();  \r\n\r\n            var light = new THREE.SpotLight();\r\n            light.castShadow = true;\r\n            light.position.set( 170, 330, -160 );\r\n            scene.addLight(light);\r\n            \r\n            var tab = [];\r\n            var sprite;\r\n            \r\n            for (var i = 0; i < NBR_ELEMENTS; ++i) {\r\n                sprite = new THREE.Mesh(new THREE.CubeGeometry(25, 25, 25), new THREE.MeshLambertMaterial({color: Math.random() * 0xffffff}));\r\n                sprite.castShadow = true;\r\n                scene.addChild(sprite);\r\n                if (i == 0)\r\n                    sprite.position.x = Math.random() * 1000;\r\n                else\r\n                    sprite.position.x = (Math.random() > 0.5) ? Math.random() * 1000 : -Math.random() * 1000;\r\n                sprite.position.y = (Math.random() > 0.5) ? Math.random() * 1000 : -Math.random() * 1000;\r\n                sprite.position.z = (Math.random() > 0.5) ? Math.random() * 1000 : -Math.random() * 1000;\r\n                tab.push(sprite);\r\n            }\r\n            \r\n            var oneElement = false;\r\n            \r\n            var diffx;\r\n            var diffy;\r\n            var diffz;\r\n            \r\n            var i = 0;\r\n            \r\n            renderer.shadowMapEnabled = true;\r\n\r\n            renderer.render(scene, camera);\r\n            \r\n            var paused = false;\r\n            var last = new Date().getTime();\r\n            var down = false;\r\n            var sx = 0, sy = 0;\r\n            window.onmousedown = function (ev){\r\n                down = true; sx = ev.clientX; sy = ev.clientY;\r\n            };\r\n            window.onmouseup = function(){ down = false; };\r\n            window.onmousemove = function(ev) {\r\n                if (down) {\r\n                    var dx = ev.clientX - sx;\r\n                    var dy = ev.clientY - sy;\r\n                    camera.position.x += dx;\r\n                    camera.position.y += dy;\r\n                    sx += dx;\r\n                    sy += dy;\r\n                }\r\n            }\r\n            function animate(t) {\r\n                if (!paused) {\r\n                    \r\n                     \/*last = t;\r\n                    \r\n                    sphere.position.x = Math.cos(t\/600)*300;\r\n                    sphere.position.z = Math.sin(t\/600)*300;\r\n                    sphere.rotation.y = t\/800;*\/\r\n            \r\n                    if (oneElement) {\r\n                        \r\n                        if (tab[0].position.x < 1000) {\r\n                            \r\n                            i = 0;\r\n                            \r\n                            while (i < NBR_ELEMENTS) {\r\n                                \r\n                                diffx = 0 - tab[i].position.x;\r\n                                diffy = 0 - tab[i].position.y;\r\n                                diffz = 0 - tab[i].position.z;\r\n                                \r\n                                tab[i].position.x -= diffx * 0.05;\r\n                                tab[i].position.y -= diffy * 0.05; \r\n                                tab[i].position.z -= diffz * 0.05;\r\n                                \r\n                                ++i;\r\n                            }\r\n                            \r\n                        } else {\r\n                            oneElement = false;\r\n                        }\r\n                        \r\n                    } else {\r\n                        \r\n                        if (tab[0].position.x > 1) {\r\n                            \r\n                            i = 0; \r\n                            \r\n                            while (i < NBR_ELEMENTS) {\r\n                            \r\n                                diffx = 0 - tab[i].position.x;\r\n                                diffy = 0 - tab[i].position.y;\r\n                                diffz = 0 - tab[i].position.z;\r\n                                \r\n                                tab[i].position.x += diffx * 0.05;\r\n                                tab[i].position.y += diffy * 0.05; \r\n                                tab[i].position.z += diffz * 0.05;\r\n                                ++i;\r\n                            }\r\n                                \r\n                        } else {\r\n                            oneElement = true;\r\n                            \r\n                        }\r\n                        \r\n                    }\r\n                    \r\n                    renderer.clear();\r\n                    renderer.render(scene, camera);\r\n                }\r\n                window.requestAnimationFrame(animate, renderer.domElement);\r\n            };\r\n            animate(new Date().getTime());\r\n            onmessage = function(ev) {\r\n                paused = (ev.data == 'pause');\r\n            };\r\n        <\/script>\r\n\r\n    <\/body>\r\n<\/html>\r\n<\/pre>\n<p>I used raf.js to make an \"enter frame\" on the page, you can find the script on Ilmari Heikkinen's <a href=\"https:\/\/github.com\/kig\/BasicsOfThreeJS\" target=\"_blank\">repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This two last weeks were very exciting thanks to Adobe&#8217;s announcement : a new framework for 2D games : Starling, running on top of Stage3D (Molehill). Flash Player 11 is out henceforth, new 3D frameworks are coming : Adobe Proscenium, Aerys. And other big things like Unreal Engine 3 with Unreal Tournament 3 in our &hellip; <a href=\"http:\/\/www.aymericlamboley.fr\/blog\/quick-look-into-threejs\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Quick look into ThreeJS<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[84,85],"tags":[86,87,88,89],"_links":{"self":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/446"}],"collection":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/comments?post=446"}],"version-history":[{"count":8,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/446\/revisions"}],"predecessor-version":[{"id":454,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/446\/revisions\/454"}],"wp:attachment":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/media?parent=446"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/categories?post=446"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/tags?post=446"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}