WebGL

Dec
21

At my new job I’m taking a look at WebGL for various prototype visualisations. Having tried a number of frameworks, I’ve found ThreeJS to be the easiest of them to get up and running quickly.

WebGL cube via ThreeJS

var container, stats;
var camera, scene, renderer;
var cube;

var targetRotationX = 10;
var targetRotationY = 10;
var targetRotationZ = 10;
var targetRotationOnMouseDown = 0;

var mouseX = 0;
var mouseXOnMouseDown = 10;

var mouseY = 0;
var mouseYOnMouseDown = 10;


var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;

$(function() {
    init();
    animate();
})

function init() {

    container = document.createElement( 'div' );
    document.body.appendChild( container );

    scene = new THREE.Scene();

    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
    camera.position.y = 150;
    camera.position.z = 500;
    scene.add( camera );
    
    // LIGHT IN FRONT
    var light = new THREE.PointLight( 0xffffff, 2.0 );
    light.position.set( 0, 500, 1000 );
    light.castShadow = false;
    scene.add( light );
    
    var materials = [];

    for ( var i = 0; i < 6; i ++ ) {
        materials.push( new THREE.MeshPhongMaterial( {
            color: 0x9CDB79,
            opacity: 0.5,
            transparent:true
        } ) );
    }

    cube = new THREE.Mesh( new THREE.CubeGeometry( 200, 200, 200, 1, 1, 1, materials ), new THREE.MeshFaceMaterial() );
    cube.position.x = 0;
    cube.position.y = 150;
    cube.position.z = 0;
    cube.rotation.x = 5;
    cube.rotation.y = 5;
    cube.rotation.z = 5;
    cube.doubleSided = true;
    cube.flipSided = false;
    cube.overdraw = true;
    cube.dynamic = false;
        
    cube.overdraw = true;
    scene.add( cube );

    renderer = new THREE.WebGLRenderer({ antialias: true });
    renderer.setSize( window.innerWidth, window.innerHeight );

    container.appendChild( renderer.domElement );

    stats = new Stats();
    $("#stats").append( stats.domElement )

    document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}

function onDocumentMouseDown( event ) {
    event.preventDefault();
    document.addEventListener( 'mousemove', onDocumentMouseMove, false );
    document.addEventListener( 'mouseup', onDocumentMouseUp, false );
    document.addEventListener( 'mouseout', onDocumentMouseOut, false );
    mouseXOnMouseDown = event.clientX - windowHalfX;
    mouseYOnMouseDown = event.clientY - windowHalfY;
    targetRotationOnMouseDown = 5;
}
function onDocumentMouseMove( event ) {
    mouseX = event.clientX - windowHalfX;
    targetRotationY = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
    mouseY = event.clientY - windowHalfY;
    targetRotationX = targetRotationOnMouseDown + ( mouseY - mouseYOnMouseDown ) * 0.02;
}
function onDocumentMouseUp( event ) {
    document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
    document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
    document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function onDocumentMouseOut( event ) {
    document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
    document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
    document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
}
function animate() {
    requestAnimationFrame( animate );
    render();
    stats.update();
}
function render() {
    cube.rotation.x += ( targetRotationX - cube.rotation.x ) * 0.05;
    cube.rotation.y += ( targetRotationY - cube.rotation.y ) * 0.05;
    renderer.render( scene, camera );
}

									

Click here to view the demo in action.

When creating an object we can colour it. A notes that I found useful:

cube = new THREE.Mesh( cubeGeo, new THREE.MeshLambertMaterial({ color: Math.random() * 0xffffff, opacity: 0.9, transparent: true }) );
									

Math.random() * 0xffffff generates a random colour

opacity sets the opacity level for the surfaces within our cube. For example, the you can see ‘into’ the cube through its surfaces, but other objects that are behind your cube will not be visible.

transparent:true will apply your the opacity to the entire cube. Other objects in the scene will be visible through the cube.

I’ve also seen this technique for applying a material directly to each side of a cube:

for ( var i = 0; i < 6; i ++ ) {
        materials.push( new THREE.MeshPhongMaterial( {
            color: 0x9CDB79,
            opacity: 0.5
        } ) );
    }

cube = new THREE.Mesh( new THREE.CubeGeometry( cubeSize, cubeSize, cubeSize, 1, 1, 1, materials ), new THREE.MeshFaceMaterial() );
        
									

…however it causes horrific flickering in Google Chrome. Probably best to avoid.

Are you struggling to get your Mac iCal calendars to sync with iCloud?

Unfortunately, it doesn’t appear that the MobileMe > iCloud transfer of calendars works all of the time. There’s little documentation on at Apple.com to assist if it doesn’t work, but it’s fairly simple to perform manually. Below is how I re-imported my calendars – requiring you to have gone through the iCloud setup process first. If you skipped the setup of your iCloud account, you can trigger this again through OSX’s System Preferences (there’s a new iCloud applet in there).

  1. From iCal, export each of your calendars as .ics files from the File menu. Stick the files on your desktop for easy access.
  2. You’ll notice that you have a couple of extra calendars in iCal that belong to iCloud. You’ll need to rename these to match your old calendars, and / or create some new ones. You can do this from the file menu. Make sure when creating new Calendars that you select the iCloud option for ‘location’.
  3. Back in iCal, uncheck all of your local calendars so that they are no longer displayed – this makes it a little easier to see that you have successfully recreated your calendars in the iCloud.
  4. Now, back to the File menu and choose Import, and select one of the .ICS files. Pick the destination calendar within iCloud.
  5. Across the top of iCal you will see “Updating…”. You can check the progress by logging into iCloud.com and viewing the calendar you just created.

Your calendars should now sync correctly. You’ll probably see duplicate entries on your desktop iCal as both sets of Calendars are still active. Once you are comfortable that everything has migrated successfully, you may want to remove (or disable) the ‘local’ calendars, leaving only the iCloud calendars active. You can also delete the .ics files from your desktop as you won’t need these again.

Sep
08
Posted by Shell at 2:56 pm

I thought it was time I took stock of some of the technologies I’ve been working on over the years. Thinking back over the tech I became briefly unstuck with, such as Object Orientated PHP, I thought I’d share some of the basics here. So, what follows are really, really simple code-snippits that may help someone, somewhere, if they’re looking at making the move from function-based PHP to grand world of Object Orientation.

PHP and OOP

Object Orientated Programming has been around forever (I can remember hacking away at OO within Flash years ago). However, PHP has only had OO support in a usable form since PHP 5. If you’re using an older version of PHP, upgrade! It’s not worth the hairloss.

Why Object Orientated PHP anyway?

Anyone who has spent any quality time with PHP knows how beautifully messy the code can get in a remarkably short time. Especially if there are multiple folks working on the code. OOP at the simplest level is possibly the single best way to organise your code by breaking it up into small, distinct libraries of functionality (classes). Smaller units of code can be worked simultaneously, and in theory are easier to debug.

The basics

  • A class is a ‘template’ for building an object.
  • An object is an entity that ‘does stuff’.
  • An object can contain functions (called Methods) and/or data (called Properties).

Classes are usually kept externally from your page code. This enables your classes to be included in any file you wish to access the functionality those classes offer using the PHP include directive.

<?php
  include("classes_lib.php");
?>
									

To create an object in PHP you use the new keyword. Example…

$n = new makeName;

…where makeName is the name of a class. $n is the name of our resulting object. All of the methods and properties that are part of the class makeName are available to $n.

Example

In our example here, I’ll create a simple object that takes a (hard coded) string and spits it back out onto the resulting page. Kind of pointless, but it demonstrates how all of this works in PHP.

index file (index.php):

<?php
  include("classes_lib.php");
?>
<html>
  <head>
    <title>OOP Example</title>
  </head>
  <body>
    <h1><?php displayTitle::title();?></h1>
    <?php
      $n = new makeName;
      $n -> set_name("fred");
      print($n -> get_name());
    ?>
  </body>
</html>
									

class file (classes_lib.php):

<?php
  class makeName {
    var $name;
    // setter
    function set_name($new_name) {
      $this->name = $new_name;
    }
    // getter
    function get_name() {
      return $this->name;
// gets the variable $name declared above. Note the "->" that gets property
//  value from $this object. Use $object -> property / method
    }
  }
  
  class displayTitle {
    static function title() {
      echo "<h1>This is the title</h1>n";
    }
  }
									

A setter is a method used for creating something, perhaps a bit of data, within the object. In our case, we give our setter a string (“Fred”) by calling the set_name method within our newly created $n object:

$n -> set_name("fred");

This tells PHP we want to access the  set_name method and pass a string to it. Once the object contains that string, we can do other stuff with it. In our really, really simple example, we simply get that name back again using:

print($n -> get_name());

The get_name() method is out getter.

I’ve included a second class to generate a title – displayTitle. This class contains a static method – a method that can be called without having to first create an object ($n in our first example). To access a static method, we need to tell PHP the name of the class and the name of the method within that class:

displayTitle::title();

Next step

Hopefully you’ll see that it’s not all that hard to build a reusable object. There are many things you can do with objects, but I’ll save that for another post.

Next steps, we could try and change the class to wrap the name in some pretty HTML. By doing this we then have a nice class that we can use over and over for generating nicely formatted names on the page.

I’ve never been that much of a fan of the desktop metaphor. It’s awkward. It’s cumbersome.

To me, it just doesn’t lend itself to creating that mental map of navigable ‘things’. Things on the desktop just never quite group together logically. They pile up, get lost behind each other, mimimized, in different spaces, or stacked in bizarrely stacked ways.

99% of the time I’m working in one or two applications. I want them full-screen. I want to seamlessly switch between screens with the swipe of the mouse or fingers.

So, does the desktop metaphor even work?

Generally speaking I find the Apple OS X desktop the easiest environment to use – certainly the cleanest – apart from when it comes to organising windows. The most basic of tasks always feels ‘messy’, flicking between spaces and expose and multiple physical screens.

Lessons are being learned from mobile environments where complication doesn’t work. Clean interfaces for small screens, simple naturalist interactions, these are the name of the game.

Videos of OSX Lion and the introduction of a iPad-like application view could be a step in the right direction. But I can’t help feeling that this is just another layer of complication on top of the desktop metaphor. It’s still the same old windowing-thing, with a lick of paint and a nod to full-screen apps.

Today videos of the Windows 8 desktop started floating around, and it really feels like an attempt to do something different. Not just another layer of fancy navigation.

/via Wired Magazine – article here.

I’m happy to see there being some real innovation, and a move away from the ‘traditional’ windowing environment. It’s to early to call who’s got it right, Apple or Microsoft, but I’m pretty sure these are the first steps to changing the way interact with software on our desktop computers, hopefully for something far more usable.

May
30
Posted by Shell at 4:09 pm

Little code snippit that I needed today that splits a text file line by line into sequentially numbered single-line text files: 

<?php
   $file = fopen("data.txt", "r");
   $x = 0;
   while ( !feof( $file ) ) {
      $fn = $x . ".txt";
      $newfile = fopen( $fn, "w" );
      $data = fgets($file);
      fwrite( $newfile, $data );
      fclose( $newfile );
      $x++;
   }
   fclose( $file );
?>
									

May
13
Posted by Shell at 4:08 pm

A new version of jQuery has been release, which’ll teach me not to blink. Some interesting changes, and I need to get around to moving some projects from jQuery 1.5 to the new release. jQuery remains one of the single best things that’s happen to front end development on the web! I’m still scarred by those dark, dark days of having to had code page interaction.

Latest version here.

May
12
Posted by Shell at 2:26 pm

I love WordPress, lets be frank, if you are developing your own themes there are some wonderful gotchas just waiting to trip us up. Today’s little adventure revolves around how WordPress handles “slugs”, those little browser-safe representations of posts, categories and tags you see in your address bar.

Example slug:

http://www.shellbryson.com/category/edinburgh/

The issue I found today is that slugs are actually shared across multiple types of content – so for example, if you have tagged a post as Edinburgh (with a slug of ‘edinburgh’), if you then try to create a category also called Edinburgh, WordPress will create a slug something along the lines of “edinburgh-1″. No big deal, right? But it looks nasty in the address bar:

Example bad slug:

http://www.shellbryson.com/category/edinburgh-2/

Solution

If you try rename the edinburgh-2 to edinburgh slug in the WordPress admin, it won’t let you (however it won’t warn you that it hasn’t saved your change).

Given categories are more frequently exposed in the addressbar than tags, it makes sense to instead use the Admin to change the slug for the tag instead, and indeed this does work. Happy days.

Aug
21
Posted by Shell at 12:15 am

The title of this post is a little misleading: When most people refer to ‘HTML5′ these days, what they really mean is HTML5 + JavaScript + CSS3.

Javascript Performance is being constantly improved by *competing* (this is critical) browser manufacturers. Unlike Flash, which is a locked down closed source platform. There are plenty of examples out there where well coded JS out performs Flash, and without crippling your CPU at the same time. Well-coded AS3 (Flash) will still hammer your PC, when it’s actually quite hard to have JS to gobble up 100% CPU unless you mess up your code.

Being open source, if you think you can do better, nothing to stop you contributing to one of the open source projects to improve the performance of any of the major javascript engines. There is no opportunity to do with this with Flash, short of getting a job with Adobe.

Advantages of HTML5 + JavaScript + CSS3 over Flash

It works, without any extra software, on pretty much any any modern browser, on any device, mobile or otherwise. If so inclined, you can also improve the performance of JS or video playback by contributing code to WebKit or Mozilla. There are countless open source frameworks that massively accelerate development, without the need of paid software (Adobe Creative Suite) to create your end product. Flash is NOT free to develop for.

Advantages of Flash over HTML5 + JavaScript + CSS3 over Flash

Primarily, Flash is great at video. While arguments of the best way to achieve this in HTML5 still rumble on, Flash continues to deliver fantastic HD video out of the box. Flash is generally faster, especially with graphic heavy content. It also gains, on some platforms, hardware acceleration allowing more ‘stuff’ to be shifted around screen without hammering your CPU quite so much. Critically though, this is only on some hardware.

Touch

I want to blog about this in more detail later, so this is a summary of my thoughts: On the surface (no pun!), Flash looks better places for delivering Touch interfaces, with an extensive array of pre-built widgets and tools for creating slick user interfaces quickly. However if you actually take a look at open source projects like jQueryMobile (and its UI components) it soon becomes apparent that developing this stuff in Flash is very restrictive.

Closing note…

I wish Adobe would focus their energy on developing better JS tools, supporting frameworks like jQuery and the HTML5 platform. I’m fairly confident the writing is on the wall, and it will take some kind of miracle product to save Flash in the long run. It’s not dead yet: the vast majority of video content will continue to be delivered in Flash for a long time to come.

I hope this post wasn’t too ranty…

Nov
25
Posted by Shell at 12:29 pm

While AJAX has its place, it’s good to learn when not to use it.

We discovered with our Intranet project significant speed penalties introduced by loading a lot of dynamic content in via AJAX at the same time. It’s very easy to get carried away and try load everything in with jQuery, but on an initial page draw this is clearly a Bad Thing:

Take our Intranet portal as an example. It consists of 9 widgets, each of which has fully dynamic content. After the portal is initially constructed by the server, loaded by the client, and jQuery has initialised, each Widget then goes and fetches its own content. This resulted in an average 35 seconds until the page was fully ready. Clearly this in unacceptable.

Going back and re-working the widgets so that they “pre-populate” the data server side reduced this time to 5 seconds. Subsequent updates are then performed by jQuery AJAX calls so the user experience is unaffected.

A lot of this is due to locking – only two connections can be made to a web server at once from a single client, so an application that generates many AJAX requests will end up having request queued. Also all those requests going back and forth from the server generate a lot of overhead, not to mention that once all the data has finally been received by the client poor jQuery has to do a lot of work!

So we learned the hard way: be careful how you use AJAX!