<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Brian Link</title>
	<atom:link href="http://www.brianthomaslink.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.brianthomaslink.com</link>
	<description>Programming, Photography &#38; Other Stuff</description>
	<lastBuildDate>Sat, 15 Oct 2011 06:24:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Playing around with three.js</title>
		<link>http://www.brianthomaslink.com/?p=10</link>
		<comments>http://www.brianthomaslink.com/?p=10#comments</comments>
		<pubDate>Sat, 15 Oct 2011 05:18:42 +0000</pubDate>
		<dc:creator>cpsubrian</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[three.js]]></category>

		<guid isPermaLink="false">http://www.brianthomaslink.com/?p=10</guid>
		<description><![CDATA[I thought it would be fun to play around with three.js so I created a simple spinning iPhone. Rendering is handled by WebGL so it&#8217;s only viewable in browsers that have support (Chrome, Firefox 4+). View it here Three.js is &#8230; <a href="http://www.brianthomaslink.com/?p=10">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div id="attachment_12" class="wp-caption alignleft" style="width: 183px"><a href="http://iscreenshot.brianthomaslink.com"><img class="size-full wp-image-12  " title="iPhone" src="http://www.brianthomaslink.com/wp-content/uploads/2011/10/iphone.png" alt="iPhone" width="173" height="230" /></a><p class="wp-caption-text">3D iPhone utilizing three.js</p></div>
<p>I thought it would be fun to play around with three.js so I created a simple spinning iPhone. Rendering is handled by WebGL so it&#8217;s only viewable in browsers that have support (Chrome, Firefox 4+).</p>
<p><a href="http://iscreenshot.brianthomaslink.com/" target="_blank">View it here</a></p>
<p><a href="https://github.com/mrdoob/three.js/">Three.js</a> is a javascript 3d engine.  According to their README:</p>
<blockquote><p>The aim of the project is to create a lightweight 3D engine with a very low level of complexity — in other words, for dummies. The engine can render using &lt;canvas&gt;, &lt;svg&gt; and WebGL.</p></blockquote>
<p>The code is pretty simple.   First you&#8217;ll need some basic layout markup.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;iScreenShot&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;header id=&quot;page-header&quot;&gt;
      &lt;h1&gt;iScreenShot&lt;/h1&gt;
    &lt;/header&gt;

    &lt;!-- Content --&gt;
    &lt;section id=&quot;page-content&quot;&gt;
      &lt;div id=&quot;iphone&quot;&gt;&lt;/div&gt;
    &lt;/section&gt;

    &lt;script type=&quot;text/javascript&quot; src=&quot;/js/three/Three.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;/js/three/RequestAnimationFrame.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;/js/three/Detector.js&quot;&gt;&lt;/script&gt;
    &lt;script type=&quot;text/javascript&quot; src=&quot;/js/main.js&quot;&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;html&gt;
</pre>
<p>You can find the three.js library javascript files in the three.js <a href="https://github.com/mrdoob/three.js/" target="_blank">repository</a>.  The markup should require little explanation.  The only thing of real note is the empty #iphone div that will be targeted by the code in main.js.</p>
<p>Now we&#8217;ll need the javascript to set up the scene and mouse interaction.  The contents of main.js follows:</p>
<pre class="brush: jscript; title: ; notranslate">
(function($) {

  var camera, scene, renderer,
  geometry, material, mesh;

  // Set up some variables and add a mousemove handler to the page
  var mouseX = 0,
      mouseY = 0,
      windowCentreX = window.innerWidth / 2,
      windowCentreY = window.innerHeight / 2;

  document.addEventListener( 'mousemove', function( event ) {
    // Update mouseX and mouseY based on the new mouse X and Y positions
    mouseX = ( event.clientX - windowCentreX );
    mouseY = ( event.clientY - windowCentreY );
  }, false );

  init();
  animate();

  function init() {
    var width = $('#iphone').width(),
        height = 400;

    camera = new THREE.Camera( 75, width / height, 1, 10000 );
    camera.position.z = 550;

    scene = new THREE.Scene();

    var materials = [
      new THREE.MeshLambertMaterial ( { color: 0xdddde4 } ),
      new THREE.MeshLambertMaterial ( { color: 0xdddde4 } ),
      new THREE.MeshLambertMaterial ( { color: 0xdddde4 } ),
      new THREE.MeshLambertMaterial ( { color: 0xdddde4 } ),
      new THREE.MeshLambertMaterial ( { color: 0xffffff, map: THREE.ImageUtils.loadTexture( '/images/iphone-front.png' ) } ),
      new THREE.MeshLambertMaterial ( { color: 0xffffff, map: THREE.ImageUtils.loadTexture( '/images/iphone-rear.png' ) } )
    ];

    cube = new THREE.CubeGeometry( 254, 493, 30, 4, 4, 2, materials );
    mesh = new THREE.Mesh( cube, new THREE.MeshFaceMaterial() );
    scene.addObject( mesh );

    renderer = new THREE.WebGLRenderer();
    renderer.setSize( width, height );

    $('#iphone').append( renderer.domElement );
  }

  function animate() {
    mesh.rotation.y = mouseX * 0.005;
    mesh.rotation.x = mouseY * 0.005;

    requestAnimationFrame( animate );
    render();
  }

  function render() {
    renderer.render( scene, camera );
  }

})(jQuery);
</pre>
<p>Let&#8217;s break this down to see how it works.</p>
<p>First, we setup up some scoped variables and logic to handle the mouse behavior.</p>
<pre class="brush: jscript; title: ; notranslate">
(function($) {

  var camera, scene, renderer,
  geometry, material, mesh;

  // Set up some variables and add a mousemove handler to the page
  var mouseX = 0,
      mouseY = 0,
      windowCentreX = window.innerWidth / 2,
      windowCentreY = window.innerHeight / 2;

  document.addEventListener( 'mousemove', function( event ) {
    // Update mouseX and mouseY based on the new mouse X and Y positions
    mouseX = ( event.clientX - windowCentreX );
    mouseY = ( event.clientY - windowCentreY );
  }, false );

  ...
</pre>
<p>Next, we&#8217;ll execute the two main functions for rendering and animating the graphics.</p>
<pre class="brush: jscript; title: ; notranslate">
  init();
  animate();
</pre>
<p>Now for the good stuff.  First we need to set up our three.js scene and camera.</p>
<pre class="brush: jscript; title: ; notranslate">
    var width = $('#iphone').width(),
        height = 400;

    camera = new THREE.Camera( 75, width / height, 1, 10000 );
    camera.position.z = 550;

    scene = new THREE.Scene();
</pre>
<p>Here&#8217;s where we set up the materials for the cube.  See, we&#8217;re not actually rendering a fully realized iPhone 3D model.  A reasonably cool visual trick can be achieved by just rendering a stretched cube with an iPhone skin slapped on.  The materials below define how each side of the cube will look.</p>
<pre class="brush: jscript; title: ; notranslate">
var materials = [
      new THREE.MeshLambertMaterial ( { color: 0xdddde4 } ),
      new THREE.MeshLambertMaterial ( { color: 0xdddde4 } ),
      new THREE.MeshLambertMaterial ( { color: 0xdddde4 } ),
      new THREE.MeshLambertMaterial ( { color: 0xdddde4 } ),
      new THREE.MeshLambertMaterial ( {
          color: 0xffffff,
          map: THREE.ImageUtils.loadTexture( '/images/iphone-front.png' )
      } ),
      new THREE.MeshLambertMaterial ( {
          color: 0xffffff,
          map: THREE.ImageUtils.loadTexture( '/images/iphone-rear.png' )
      } )
    ];
</pre>
<p>Finally, we create the actual cube, add it to the scene, initialize the renderer and append it to our empty div.</p>
<pre class="brush: jscript; title: ; notranslate">
    cube = new THREE.CubeGeometry( 254, 493, 30, 4, 4, 2, materials );
    mesh = new THREE.Mesh( cube, new THREE.MeshFaceMaterial() );
    scene.addObject( mesh );

    renderer = new THREE.WebGLRenderer();
    renderer.setSize( width, height );

    $('#iphone').append( renderer.domElement );
</pre>
<p>For a finishing touch we allow the 3D model to be rotated by defining some animation.  It&#8217;s a simple matter of translating the cube mesh in the x and y directions.</p>
<pre class="brush: jscript; title: ; notranslate">
  function animate() {
    mesh.rotation.y = mouseX * 0.005;
    mesh.rotation.x = mouseY * 0.005;

    requestAnimationFrame( animate );
    render();
  }

  function render() {
    renderer.render( scene, camera );
  }
</pre>
<p>I&#8217;m just barely diving into the library, but working with 3D graphics is definitely a welcome change of pace from the static content I&#8217;m working with most of the time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brianthomaslink.com/?feed=rss2&#038;p=10</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

