For 0.4 I decided to do something different.
I hate writing test frameworks.

I was chatting with Chris the other day about his “bug”, and he mentioned how he wanted his VisualTimeline plugin to hook the actual video timeline and display its data on that.
The current iteration of his Plugin
VisualTimeline

After some research into the HTML5 video element I found out that you actually toggle the control bar with the controls tag.
This tag creates a browser-specific controller that overlays on top of the video.
It would be rather silly in my opinion to hook this – potentially changing the code for every browser.

   
    <video id="video"
      controls <---------------- This
      width="250px"
      poster="../../test/poster.png">

      <source id="mp4"
        src="../../test/trailer.mp4"
        type='video/mp4; codecs="avc1, mp4a"'>

      <source id="ogv"
        src="../../test/trailer.ogv"
        type='video/ogg; codecs="theora, vorbis"'>

      <p>Your user agent does not support the HTML5 Video element.</p>
    </video>

Chris already created what is essentially an override to the MediaController, bonus is it also conformed to the HTML5 standard.
He is accessing the Media Element (<video> tag) directly to control its flow.

So….
Some Quick

magic:
Before:

Your user agent does not support the HTML5 Video element.

 

 

<canvas id=”timelineCanvas” height=”20″></canvas> </div>

After:

Your user agent does not support the HTML5 Video element.

 

</div>

And some declaration modifications:
Before:

  .visualizedtimeline({
    vidTarget: "video",
    start: 0,
    target: "timelineCanvas",
    canvasHeight: "20",
    canvasWidth: "220"
  })

After:

  .visualizedtimeline({
    vidTarget: "video",
    start: 0,
    target: "timelineCanvas"
  })

And some code modifications:
Before:

    //Set canvas parameters
    ctx.width=options.canvasWidth;   -----> used to be fed in (see above)
    ctx.height=options.canvasHeight; -----> used to be fed in (see above)
    barX = ctx.width*0.05;

    //Get media element and save popcorn instance
    myVideo = document.getElementsByTagName(options.vidTarget)[0];
    var popcornInstance = this;

for the mouseovers:
var newdiv = document.createElement('div');
newdiv.id = 'popUp';
newdiv.style.display = 'block';
newdiv.style.position = 'absolute';
newdiv.style.background = 'yellow';
newdiv.style.top = mouseY;
newdiv.style.left = mouseX;
newdiv.style.fontSize = "10px";
newdiv.innerHTML = "Event Info </br> Start Time: " + arrayTrack[i].start + " seconds";    
document.body.appendChild(newdiv);
finished=1;

After:

    //Get media element and save popcorn instance
    myVideo = document.getElementsByTagName(options.vidTarget)[0];
    var popcornInstance = this;

    //Set canvas parameters
    ctx.width= myVideo.width;      -----> Scale to Video canvas width
    ctx.height= 20;                -----> Always 20 anyways.
    barX = ctx.width*0.05;

for the mouseovers:
var newdiv = document.createElement('div');
newdiv.id = 'popUp';
newdiv.style.display = 'block';
newdiv.style.position = 'absolute';
newdiv.style.background = 'yellow';
newdiv.style.top = mouseY - 20;    -----> To make up for the bar size and offset.
newdiv.style.left = mouseX;
newdiv.style.fontSize = "10px";
newdiv.innerHTML = "Event Info </br> Start Time: " + arrayTrack[i].start + " seconds";    
var vidDiv = document.getElementById('controls');
vidDiv.appendChild(newdiv);        -----> appends to controls <div> (shown above)
finished=1;

Voila our very own custom Media Controller!:
Prettyyyy

Get it here

Played with JavaScript the entire day:
1. Trying to make Sundae.js only run one test at a time.
2. Trying to take a screen-shot of my canvas correctly.

First Issue:
– Sundae.js runs all the tests as fast as it can multi-threaded.
– CubicVR.js can only render to one canvas.
Pretty big issue. It seems impossible without a complete refactoring of Sundae to make it work on only one test at a time.

Second Issue:
I attempted everything I could think of to try and get a screen-shot of my canvas without forcing some sort of delay (see previous posts), no dice.
I’m convinced at this point that this is an issue with Firefox or CubicVR.js.
At least its all refactored and working (more or less):

function createCanvas () {
   var canvasFrame = document.getElementById('render-frame'),
       pngFrame = document.getElementById('png-frame');

   // get rendering canvas and context
   var r = window.document.createElement('canvas');
   var rCtx = r.getContext("experimental-webgl", {preserveDrawingBuffer: true});
   r.id = "render";
   r.width = 300;
   r.height = 300;
   canvasFrame.appendChild(r);

   // get the png canvas and context
   var p = window.document.createElement('canvas');
   var pCtx = p.getContext("2d");
   p.id = "pngImage";
   p.width = 300;
   p.height = 300;
   pngFrame.appendChild(p);
}

function makeScreen () {
   var render = document.getElementById('render'),
   png = document.getElementById('pngImage'),
   pCtx = png.getContext("2d");

   pCtx.drawImage(render, 0, 0);
}

function runBuilder () {
   var render = document.getElementById('render'),
       png = document.getElementById('pngImage'),
       code = document.getElementById('code');

   // run code.
   eval(code.value);	
   test(render, function () {});

   setTimeout("makeScreen()", 500);
}

Paste your code here:
paste code
Get back a Screenshot
screenshotted

I’m super overwhelmed and about ready to give up.
I need another bug.

At least I learned how much I despise writing test runners.
Save Me Humph 😦

 
 
 
As a bonus to this release I uploaded one of my summer projects to github:
Here
Totally not a stab at extra credit >_>; nope.

It allows you to inject code into a running process.
You can replace any external symbol (eg: a call to any symbol not hardcoded into the application).
This was done during my internship at Gridcentric.

The Demo:
thetime.c
This just repeats the local time over and over using asctime() to return a string
thetime

Running it
tell me the time

We inject a call to dlopen on hammertime.so (my own shared library)
dlopen() loads a library into the address space of the process.

dlopen

inject remap [pid] [symbol_to_hook] [replacement] auto searches and replaces
The toolset allows you to manually specify the symbol you wish to find / replace.
inject remap [pid] [libname:symbol_to_hook] [libname:replacement]
hook and remap asctime

It also allows you to do a one-off call to a function of your choice:
We will be calling hammer_on() to start a thread as a child of the running process
hammertime.so

Hammer_On was called.
call hammer_on

Well… I got it working.
I was messing around just trying to make it save anything that wasn’t a 0’d array.
So I stuck alert(“stuff”); everywhere, in a mad stab at a timing based issue.

Who would have guessed…:
An Alert
what
Oh wow… It Works.
hey it worked...

 
If I call alert(); AFTER rendering to a canvas, and BEFORE saving the pixels it works fine.
setTimeout() works too:

function makePNG() {
   var image = pCtx.createImageData(p.width, p.height);
   arr = new Uint8Array(r.width * r.height * 4);
   rCtx.readPixels(0, 0, r.width, r.height, rCtx.RGBA, rCtx.UNSIGNED_BYTE, arr);
      for (var y = 0; y < p.height; y++){
        for (var x = 0; x < p.width; x++){
          var index = (y * p.width + x) * 4;
          var index2 = ((p.height-1-y) * p.width + x) * 4;
          for(var z = 0; z < 4; z++){
            image.data[index2 + z] = arr[index + z];
          }
        }
      }
   pCtx.putImageData(image, 0, 0);   
}
setTimeout("makePNG()", 500);

 
All three methods to save a 3Dcanvas to 2D work if I do this!
The other 2 being:

   // 1. get data url and write to canvas B
   //var data = r.toDataURL("image/png");
   //var img = new Image();
   //img.src = data;
   //pCtx.drawImage(img, 0, 0);
   // in case you want to try pasting the url in a new window
   //alert(data);

   // 2. draw 3Dcanvas to 2Dcanvas,
   //pCtx.drawImage(r, 0, 0);

 
 
Evidentially this is a time issue.
Speaking with ccliffe on IRC shed slightly more light on this.
He thinks its the RequestAnimationFrame call running *before* drawing the current frame.
(I have no idea what this means either, its o.k. :P)
Apparently it was done this way to workaround a timing bug in Firefox.

 
 
Applying my newfound knowledge to the sundae test suite:

   if (test.secondCanvas.src) 
      sourceLoader(test.secondCanvas, b, function () {
      alert("hax");
      whenDone('second');
      });
   }

Same Deal
Same Deal
Cool
Cool
Really Cool
Really Cool

 
 
It works, but this posed a new problem.
Sundae tries to run every test as fast as possible – all at once (multi-threaded too).
CubicVR can only render to ONE canvas at a time.
It just stays “running…” forever on the second test.
Was good while it lasted...

 
 
What has to happen next:

--> Sundae may not be the best framework for this, or needs to be heavily modified.
- The processing.js ref tester looked fantastic for this, I wonder if I can just use that?
 
--> Using setTimeout() is an extremely hacky way of making this work, It may not even work the same on every server/computer.
- Ideally this is an issue that can be fixed within CubicVR?
- Is this a bug, or just me incorrectly setting all this up?
 
--> What exactly does the "Test Creator" need to do, other then run code and give you a PNG back?
- How can I run the code that you paste in a text-box WITHOUT eval();

 
 
Is this enough for 0.2? I don’t even know.
What I do know is I’m going to keep working on this till Friday 😛

Spent the day rigging up the test builder.
You paste the code here:
Paste The Code Here
Click Run – It Renders it and gives you back a PNG:
Where’s the PNG…
It Renders

 
 
So far:

function runBuilder () {
   var canvasFrame = document.getElementById('render-frame'),
       pngFrame = document.getElementById('png-frame'),
       code = document.getElementById('code');

   // get rendering canvas and context
   var r = window.document.createElement('canvas');
   var rCtx = r.getContext("experimental-webgl", {preserveDrawingBuffer: true});
   r.id = "render";
   r.width = 300;
   r.height = 300;
   canvasFrame.appendChild(r);

   // get the png canvas and context
   var p = window.document.createElement('canvas');
   var pCtx = p.getContext("2d");
   p.id = "pngImage";
   p.width = 300;
   p.height = 300;
   pngFrame.appendChild(p);

   // run code.
   eval(code.value);
   test(r, function(){});
}

eval(code.value);
-> Will basically declare the input function (which you name test for now.)
-> I know eval() is bad practice. This is just duct-tape at the moment.
test(r, function(){});
-> Calls it on render canvas.

 
 
My problem now is no matter what I do it will not save the render as a PNG.
– Directly draw canvas to the 2d canvas:

pCtx.drawImage(r, 0, 0);

– Get image URI and draw that to canvas. (the image URI is one of a white 0’d out png)

var data = r.toDataURL("image/png");
var img = new Image();
img.src = data;
pCtx.drawImage(img, 0, 0);

– Get a readPixel Array and draw that to the 2d canvas (also 0’d out?) (copied from XB-POINTSTREAM)

var image = pCtx.createImageData(p.width, p.height);
arr = new Uint8Array(r.width * r.height * 4);
rCtx.readPixels(0, 0, r.width, r.height, rCtx.RGBA, rCtx.UNSIGNED_BYTE, arr);
for (var y = 0; y < p.height; y++){
   for (var x = 0; x < p.width; x++){

      var index = (y * p.width + x) * 4;
      var index2 = ((p.height-1-y) * p.width + x) * 4;

      for(var z = 0; z < 4; z++){
         image.data[index2 + z] = arr[index + z];
      }
   }
}
pCtx.putImageData(image, 0, 0);

 
 
I found out about this: {preserveDrawingBuffer: true}
From This Blog

Tried putting it into my context:

// get rendering canvas and context
var r = window.document.createElement('canvas');
var rCtx = r.getContext("experimental-webgl", {preserveDrawingBuffer: true});

Tried putting it into the CubicVR init context:

if (gl_in.getContext !== undef && gl_in.width !== undef && gl_in.height !== undef)
{
   try {
      if (!gl) gl = gl_in.getContext("experimental-webgl", {preserveDrawingBuffer: true});

Nothing…

 
 
More tomorrow.

Next Step for the ref-test system is to create an interface that allows a User to paste in some code and get back a PNG of the rendering.
Starting on this today I had 0 idea of how to go about this.

Step 1: I grabbed the processing.js ref-test-builder as a template -> Here
 

Step 2: Trying to figure out how to get the code in the text-box to actually execute, the way its done on processing.js is exceedingly complex (at least for this phase of the ref-test creator).
It seems like I can use eval(code.value) to execute the code, but I have to think up a way to pass parameters through.

Around here I ran into a huge issue, even the most basic CubicVR.js samples were not running. (they did last week)

Error:[18:52:12.515] uncaught exception: [Exception... "Access to restricted URI denied" code: "1012" nsresult: "0x805303f4 (NS_ERROR_DOM_BAD_URI)" location: "file:///home/tuna/apache/CubicVR.js//source/CubicVR.Utility.js Line: 69"]

After a good waste of 2 hours, I found out that I had clicked the link to the file to load it, rather than navigating to it using my localhost domain.
URL with error:

file:///home/tuna/apache/CubicVR.js/samples/basic/cube.html

URL without Error:

http://localhost/CubicVR.js/samples/basic/cube.html

 

Step 3: Just to make sure everything is working, I made a button that renders a cube into a canvas on my test runner page.
Run Button:
<input onclick="runBuilder(document.getElementById('renderCv'))" type="button" value="Run"></input>
RenderCv is a 300×300 canvas.

runBuilder:

function runBuilder (aCanvas) {
	function renderCube(canvas, callback) {
	    var gl = CubicVR.init(canvas.id);

	    if (!gl) {
		alert("Sorry, no WebGL support.");
		return;
	    };

	    // Create a camera, position at 1,1,1 and target at 0,0,0
	    var camera = new CubicVR.Camera(canvas.width,canvas.height,60);
	    camera.position = [1,1,1];
	    camera.lookat([0,0,0]);

	    // Create a material for the mesh
	    var boxMaterial = new CubicVR.Material({
		textures: {
		    color: new CubicVR.Texture("../../samples/images/6583-diffuse.jpg")
		}
	    });

	    // Add a box to mesh, size 1.0, apply material and UV parameters
	    var boxMesh = CubicVR.primitives.box({
		size: 1.0,
		material: boxMaterial,
		uvmapper: {
		    projectionMode: CubicVR.enums.uv.projection.CUBIC,
		    scale: [1, 1, 1]
		}
	    });

	    // triangulate and buffer object to GPU, remove unused data
	    boxMesh.triangulateQuads().compile().clean();

	    // Add our camera to the window resize list
	    CubicVR.addResizeable(camera);

	    CubicVR.MainLoop(function(timer, gl) {
		CubicVR.renderObject(boxMesh, camera, CubicVR.IdentityMatrix);
	    });

	    callback();
	}
renderCube(aCanvas, function(){});
}

 

Result: (I Wonder why it’s warped??? – will update CubicVR to the newest tomorrow.)
Wow, It's Warped...
 

Tomorrow:
Make it run the code pasted in the text-box, and render it to the canvas.
The Canvas should be a PNG from a data URI.
This Link
Makes it seem easy, especially as HTML5 spec says it comes with pre-stripped gamma and color correction data.

Time to jump into my first open source project.
Ditched Arch Linux and set up Ubuntu!
ubuntu yo

I have forked and cloned CubicVR, and I have cloned Sundae.js
I am now in the process of merging them.

1. Put sundae.js in tests/ref

2. Scanning through the sundae files, it looks very modular. as of right now its live-rendering canvases using XB-pointcloud.
XB-pointcloud, however is actually detached from sundae, the test runner just runs whatever you need it to.

Sundae seems relatively easy:
You stick the dependencies in the test suite layout file:

 
{
    "testSuite": [{
        "dependancyURL": [
	"../../CubicVR.js"
        ],
        "test": [{
            "name": "cubetest",
            "note": "Lets see if this works",
            "tag": "CubicVR",
            "firstCanvas" : {
                "src" : { "url" : "resources/render/cube.png", "type" : "image" }
            },
            "secondCanvas" : {
                "src" : { "url" : "resources/render/cube.js", "type" : "script" },
                "run": "renderCube"
            }
        }]
    }]
} 

This will make
firstCanvas show cube.png
and secondCanvas show a live render of script: cube.js function call: renderCube(canvas, callback).

Inside cube.js you must finish the method with a call to callback();
cjcliffe’s cube.html (now cube.js with some modifications):

function renderCube(canvas, callback) {
    var gl = CubicVR.init(canvas.id);

    if (!gl) {
	alert("Sorry, no WebGL support.");
	return;
    };

    // Create a camera, position at 1,1,1 and target at 0,0,0
    var camera = new CubicVR.Camera(canvas.width,canvas.height,60);
    camera.position = [1,1,1];
    camera.lookat([0,0,0]);

    // Create a material for the mesh
    var boxMaterial = new CubicVR.Material({
	textures: {
            color: new CubicVR.Texture("../../samples/images/6583-diffuse.jpg")
	}
    });

    // Add a box to mesh, size 1.0, apply material and UV parameters
    var boxMesh = CubicVR.primitives.box({
	size: 1.0,
	material: boxMaterial,
	uvmapper: {
            projectionMode: CubicVR.enums.uv.projection.CUBIC,
            scale: [1, 1, 1]
	}
    });

    // triangulate and buffer object to GPU, remove unused data
    boxMesh.triangulateQuads().compile().clean();

    // Add our camera to the window resize list
    CubicVR.addResizeable(camera);

    CubicVR.MainLoop(function(timer, gl) {
	CubicVR.renderObject(boxMesh, camera, CubicVR.IdentityMatrix);
    });

    callback();
}

I also changed the canvas size to 300×300 pixels as 100×100 is much to small in my opinion for 3d rendering.
Quick fix (just made them 300 from 100)->

  
var a = createCanvas(d, name + '-first', 300, 300);
var b = createCanvas(d, name + '-second', 300, 300);
var c = createCanvas(d, name + '-diff', 300, 300);

MOMENT OF TRUTH!
It failed…
After ccliffe told me about the debug console it was pretty obvious where it was failing.

Output: [16:29:22.311] util is undefined @ http://localhost/CubicVR.js/tests/ref/resources/cvr/CubicVR.js:161
odd…

I stick an alert in:

util = CubicVR.util
alert(util);

Indeed, it shows that util is undefined.

First thought: the dependencies aren’t resolved properly.
This is weird however as the way sundae.js loads dependencies is the method
(where src would be in this case “../../CubicVR.js”):

function getScript(src, callback) {
    if (!isLoaded(src)) {
        var s = _w.document.createElement('script');
        s.type = 'text/javascript';
        s.onerror = function () {
            postError(src, 'script load failed');
        };
        s.onload = function () {
            callback();
            _w.document.head.removeChild(s);
        };
        s.src = src;
        _w.document.head.appendChild(s);
    }
}

This ends up being a simple <script src="../../CubicVR.js" type="text/javascript"> </script> once it executes.

After successfully running the samples locally, the only option left was that it must be a dependency issue.
So I hacked around the sundae.js dependency loader.

tests.json:

"dependancyURL": [
"dummy.js"
],

dummy.js is an empty file.

And then inside the index.html for the test runner – a CubicVR.js include:
<script src="../../CubicVR.js" type="text/javascript"> </script>

MOMENT OF TRUTH # 2….
success!!:
success

Evidently the dependencies were not loading correctly.
After some chatting I found out:
ccliffe uses a loop with document.write() to loop through all of the modules for CubicVR, which doesn’t work when called from another script.

In the end, this way around the issue may be fine for what the tests are for.
Time to commit + push to my repo!

Next Up:
Fixing the layout.
Making a way to generate png’s.

This week was our introduction to Git.

Throughout my programming career so far, I have only used SVN and mercurial.
So far at least, it seems like Git is relatively similar to mercurial – which is fantastic.  I should be able to jump right in and do what i need to do without much more documentation.

Interestingly, when I was using mercurial my team never branched, we always just cloned the repo, and pushed to the trunk.  I’m going to have to get used to the branching way of doing things.

Next up: I plan on getting a job to do from secretrobotron, It doesnt look like the “issues” page on github has been populated yet, so I gotta talk to him.

I’m excited to start some work on paladin!

 

David’s lecture is a great accompaniment to The cathedral and the bazaar!

Something that really struck me about his lecture is the analogy to an open source project as a bustling festival.  Hans-Georg Gadamer’s ideas really resonate with the ideas of open source as a bazaar.

A festival has a mood, and standards, established methods of doing things.
As well as relatively loose rules and details.      -> so does an open source project.

An impenetrable open-source project, is no longer quite as impenetrable after viewing it this way.  A project requires you to just go, you become assimilated into it over the course of the project, the requirement to understand everything about it becomes redundant.

Its not about fully understanding it (initially.), its about going to enjoy the show.

Yes, this is late…. I know.

I really didn’t want to read the Cathedral and the Bazaar, though after reading it I can’t believe I felt that way.

This article is easily one of the most insightful (on the topic of open source) I have ever read.
And! as an added bonus, it has great tips for honing your skills and increasing the chances of success with your own projects.

It really is amazing that Linux had progressed from its beginnings as a rehash of Linus’s Minix OS into the enormous thing it is today, all as a collaborative effort between people from all over the world.
I’m tempted now to clean up my own dependency injection project and make it fully open-source!