Jekyll Asset Pipeline with Stylus and Revisions

We use Jekyll for this blog and for the other pages on floored.com and host them on Github Pages. We find it simpler and faster than app-y alternatives.

One thing we did miss though was having an asset pipeline for our CSS and JS.

Jekyll has a plugin system for adding functionality like this. (Unfortunately, adding a plugin adds an extra step to publishing since Github will not use custom plugins when they generate a site.) We looked at a lot of asset management solutions but ended up with our own plugin, heavily based on jekyll-asset-pipeline.

Asset Bundle Features

  • We can develop locally with Stylus files and multiple JS files (no Coffeescript).
  • The plugin generates CSS files from the .styl files and reads a .yml file to add the <link> and <script> tags to the html
  • When publishing, the plugin concats all the files together, compresses them with Stylus or Uglifier, adds a md5 fingerprint to the filename, and inserts the <script> and <link> tags to the html.

Setup

  1. In our Gemfile:
gem 'jekyll_asset_bundle', :github => 'floored/jekyll_asset_bundle'
  1. In _plugins/assets.rb:
Jekyll::ENV = (ENV['JEKYLL_ENV'] || 'development')
require 'jekyll_asset_bundle'
  1. In Rakefile:
task :build do
      ENV['JEKYLL_ENV'] = 'production'  
      sh "jekyll build"
end

How we use it

All our CSS and JS go into an _assets folder:

_assets/
  css/
    application.styl
    nib/
      clearfix.styl
      config.styl
      index.styl
    normalize.styl          
  js/
    application.js
    app.yml
    carousel.js  

We use these liquid tags in the template:

{% css application %}
{% js app %}

When jekyll sees those tags, it generates the css and js files into _site/assets. In development, the generated html looks like:

<link rel="stylesheet" type="text/css" href="/assets/css/application.css">    
<script type="text/javascript" src="/assets/js/application.js"></script>
<script type="text/javascript" src="/assets/js/carousel.js"></script>

In production, the generated html looks like:

    
<link rel="stylesheet" type="text/css" href="/assets/css/application-5b35d372e20957954a1190612a98e906.css">    
<script type="text/javascript" src="/assets/js/app-da04f07460fbcb047c196202eb7040b3.js"></script>

Unity Skybox Weirdness

If you haven’t checked out our recent World Trade Center model, you should click on that link now! Given the crazy amount of security we had to go through to gain access to the top floor of the building, including signing our lives away to a >100-page security compliance document, we will probably have the best panorama from the top floor of the building for as long as the building is closed to the general public.

One of these days–maybe if our cool boss Dave makes a final selection for Floored’s Catered Lunch Program™ (might he be reading this?)–we will write about how these panoramas are generated. Meanwhile, we thought we’d point out one weird thing about Unity’s skybox renders.

Assume that our secret+magical sauce has given us a beautiful panorama for a model…

Since we rely on the Unity engine to render our models across devices, our panoramas have to be displayed in models via Unity Skyboxes. Here, the term “skybox” refers to the special construct that allows 3D worlds to render pretty scenes at a distant using images.

Imagine a 3D world similar to one shown below.

3D world with viewpoint marked by black dot at center
3D world with viewpoint marked by black dot at center (Image source: Wikipedia article on 'Cube Mapping')

If the objects are sufficiently far away, we could replace the objects with flat images. This helps reduce the rendering complexity of the 3D world while creating an illusion that the surroundings remain in 3D. To the observer at the viewpoint at center, the surroundings near the horizon are identical whether they are in 2D or in 3D, as shown in the image below.

3D world with viewpoint enclosed in a box
3D world with viewpoint enclosed in a box (Image source: Wikipedia article on 'Cube Mapping')

For this reason, once we have an equirectangular panorama for a model, we project the panorama into a cube by generating six images that correspond to the six sides of the skybox cube–up, down, front, back, left, and right. These images are viewed by an observer at the position indicated by the black dot in the 3D environment, so intuitively, the assignment of images to each of the six sides should the order shown below.

Intuitive assignment of image positions on an unfolded cube
Intuitive assignment of image positions on an unfolded cube (Image source: Wikipedia article on 'Cube Mapping')

Counterintuitively, Unity’s skybox convention has the left and right assignment swapped as indicated below.

Unity's assignment of image positions on an unfolded cube
Unity's counterintuitive assignment of image positions on an unfolded cube (Image source: Wikipedia article on 'Cube Mapping')

This results in an odd situation where the correct assignment of our skybox images for the World Trade Center panorama has the left and right labels swapped.

Skybox image assignment for World Trade Center panorama
Skybox image assignment for World Trade Center panorama

Isn’t this weird?

After some head-scratching, it turns out that the reason this happens is because the Unity game engine that we rely upon operates on a left-handed coordinate system. By Unity’s arbitrary convention, ‘left’ is assigned to the +X direction and ‘right’ is assigned to the -X direction, as displayed in the image below.

Unity left-handed coordinate system
Unity's left-handed coordinate system

We think that this is a pretty convincing explanation for the left-right weirdness. However, if you have an even better idea, do let us know!

Debriefing Disrupt

A behind-the-scenes blog post about our experience at Techcrunch Disrupt

I’m writing this on the plane home from a week-long vacation, the first I’ve taken in over a year–I am refreshed, rejuvenated, ready to tackle Floored’s next challenges. But two weeks ago, as I paced my living room, muttering lines from a presentation I’d be giving the following morning at TechCrunch Disrupt, I wasn’t even sure I should leave the country. The company is still very new, and my to-do list no longer fits on one page. I was going to be leaving a very capable, but new, employee in charge of a LOT of sales & account management stuff, and this presentation was all I could think about. I didn’t want to screw up our first big PR swing.

We applied to Disrupt in February, before–let’s face it–we even had a cogent sales pitch. In January, we’d done a soft launch, and completed work on our iPad app in order to put out a marketing website and start taking orders from customers. The hope was to develop a slick product in time to be accepted to Battlefield, where we’d launch our vision on the larger tech community. After the semi-finals, we were humbled and excited to be named as a finalist.

I only watched our final presentation (embedded above) for the first time last week. In hindsight, I’m pretty amazed (and relieved) by how smoothly it all went. I’m reminded of the trite description tour guides tell Ivy League college applicants: the students are ducks, “seemingly peaceful on the surface, paddling furiously below.” That’s about how I felt all of the Disrupt week. Our team cranked to get the live demo to a presentation-worthy place and our lead designer and head of biz dev built the best sales deck I’ve ever delivered.

We didn’t win the competition. We lost out to a few terrific startups that we got to know well over the final two days. But our business has never been busier, the press from the event has never been better, and I get pumped up every time I filter through my overflowing inbox to respond to potential customers and employees who are as psyched about our product as we are. Thanks to all of you who tweeted about us and supported us during the event. We’re thankful to Techcrunch Disrupt for disrupting our business, in the best possible way.

1 World Trade Center

Last Friday I had one of the cooler experiences of my life. I strapped on dusty combat boots (not mine), a hard hat, a super-sleek reflective vest and took three of my most risk-loving employees 1,700 feet above sea level. We were guests of the Port Authority, the Durst Organization and Cushman Wakefield, visiting the top floor construction site of the new One World Trade Center building.

Members of the floored team, bedecked in hard hats and high visibilty vests, inside a plywood elevator.

My heart pounded as we ascended in two separate elevators. Then it almost exploded out of my reflectively-clad chest when we hit the top floor and discovered that the walls were not yet in place! Wind whipping through my hair, knees shaking with an patrilineally-inherited fear of heights, I did my best to quickly assemble the Matterport camera. A few deep breaths later and we were scanning.

You only have to be inside the 1WTC building for a few seconds before you start to take in just how jaw-droppingly amazing the views are. But to capture them accurately, to reflect exactly what it feels like to be in the space, requires a little bit of software wizardry.

Dave wheels the Matterport camera down the skeleton of a hallway at One World Trade Center.

One of the less obvious areas of our software refinement pipeline is the difficult work that goes in to our 360 panoramic views that sit outside of the 3D models that we create. Last Friday when we went to scan to collect the interior data, we also noted that this would be a particularly challenging panorama stitching effort, as we were blessed with highly variable weather conditions. One one side of 1WTC there was beautiful clear skies, on the other end of the building it was raining pretty hard. As a result, we were lucky to see something that few ever get a chance to see in person: we were standing about 30 stories above an intense rainbow (check out the photos below).

Unfortunately when we put the photos through our pipeline, the rainbow would skew the color balance of the whole panorama, adversely affecting the coloring of the rest of the shot. Another challenge that the scene presented was that we had to take handheld photos, and so had to rely on a single shot to capture the full dynamic range (rather than multiple shot HDR, which requires a tripod).

A vertigo-inducing shot of the views from WTC as seen through mesh netting.

Marco, one of our senior software engineers, stuck a hand with the DSLR through the mesh netting that keeps small objects from falling hundreds of stories onto the street below. The dynamic range of recent DSLR cameras far surpasses the range of computer screens, so with some tone mapping (which sensibly compresses the raw sensor’s high dynamic range to the low dynamic range of the a computer screen) the resulting panorama turned out alright. Here are some examples of the images before tone mapping and then after tone mapping. The differences are stark.

An un-tonemapped shot of a rainbow from 30 stories above.
A tonemapped shot of a rainbow from 30 stories above.

Interior scenes push the extreme of the dynamic range which can be captured in a single photograph. In conventional photography, a photographer will balance the range for a single image by letting less important areas of the image go too light or too dark. One of our scans is essentially a photograph of every part of a space. When the user moves around, all parts of the scene have to be exposed properly, which is why we are working on automatic tone mapping and high dynamic range image capture. These techniques will guarantee that detail is captured in every part of our scans.

Members of the Floored team reflected in an uninstalled piece of glass.
So without further ado, [take a look](http://depot.floored.com/scans/ebony-tomato-4145/a/12 “Floored One World Trade Center”) at what it feels like to walk along the 90th floor of 1WTC. It’s a pretty incredible building and if you’re a company looking to move downtown we’re happy to introduce you to our friends at Cushman Wakefield!

About Us

Screenshot of http://www.floored.com/about.
Over the past few months the Floored team has grown steadily to the point where we’re now 10 full-time. We [recently moved](http://blog.floored.com/2013/moving-day.html “Moving Day Floored”) into a new office that can support our rapid growth. By the numbers, we’re 80% in engineering & 3D modeling and 20% on business/sales, 20% female and 100% awesome! pumped to be adding four more to our ranks this summer.

To celebrate hitting our second digit of headcount we got in touch with Michael Raphael, the CEO of Direct Dimensions, and the visionary behind Shapeshot to help digitize our team into 3D. So two weeks ago we headed over to the Makerbot store around the corner from us and got our faces digitally imaged into 3D. The results are available on our new About page, but you’ll need webGL to get the full effect. (We like to visit the page using Google Chrome.) Also, a pro tip: try clicking on our faces; it’s Easter season.

In the meantime, here’s a quick overview of our new team members and a few notes on what everyone is working on:

[Jake](http://www.floored.com/about#jake “About Us Floored”) is responsible for all things design at Floored. Jake’s talents range from designing the interactions in our iPad app, to those in our web viewer, to our website, business card and soon enough, the interior design for our office. Some say his versatility is as wild as his hair. Jake came to us via Quirky via Stamped via RISD via Carnegie Mellon.
[Nick](http://www.floored.com/about#nick-b “About Us Floored”) is a software engineer who specializes in really hard to crack problems in 3D space. His background runs the gamut from computer vision to hardware hacking to writing his own video game shaders while at RISD. Right now Nick is a primary architect on our 3D data refinement software that we call CloudLab.
[Nik](http://www.floored.com/about#nick-f “About Us Floored”) brings almost two decades worth of 3D modeling and rendering expertise to our team. He upped the quality of our custom designed 3D models 10x when he joined full time and he’s been helping manage our production line in order to please our clients over and over.
[Sonia](http://www.floored.com/about#sonia “About Us Floored”) is a software engineer who also brings tremendous talent to the company. When we saw her resume come through with the @MIT.edu suffix, we had to admit that we had never seen a GPA that high before. Couple her amazing raw talent with crazy proficiency at camera hacking, image processing and ice hockey stats recall and we’re lucky to have her as a cornerstone of the engineering team.
[Daniel](http://www.floored.com/about#daniel “About Us Floored”) is part of the business development team at Floored and our newest team member. A classic underachiever, Daniel majored in computer science at Harvard and was a nationally recognized pianist and mathematician before going to finishing school at Goldman Sachs and McKinsey. If you have product or sales ideas for Daniel, send him a note! He’s very fast on email and much less pretentious than our CEO.
If you think you might want to be the 11th member of our team, check out our [jobs page](http://www.floored.com/jobs “Jobs Floored”) and apply!