Back around mid to late July in 2014 I set out to create Blit. One year on now (as of last Wednesday), I've made a lot of progress from practically nothing. Thinking back I ask myself “why did I want to make Blit?”
I've made many other projects before. Some of them successes whereas others were really failures (cough buzz cough). Those projects had something in common. They were short, small, and contained. When I look back on all of the stuff that I've made, I noticed that there was nothing that I could call a “grand,” or “large,” project. I wanted something that I could call a major project that I built. More importantly I wanted to know how to manage a larger project; something I've never done before.
So I set a goal for myself: “Make something large. Something that you can never really call 'complete,' but work on it for an entire year.” That's what I did. I had nothing more than a silly GitHub streak to motivate me. It now says “371 days.” There were a few days where all I did was just update a TODO file, add some extra documentation, or ones that I didn't want to work on it at all (but I did anyways).
Blit still isn't really what I originally imaged it to be. Some sort of 2D Animation solution for pixel art and larger things (and hopefully pencil testing too). And I'm still not sure 100% what I want out of it. I consider what I've done so far to be nothing more than a prototype for a future vision.
I've met my goal of “work on something for a year,” but I plan to still chug along with it until I feel that I'm done. It's been fun so far.
Here are some stats:
- 371 days of continuous development (avg. one hour per day, more on the weekends)
- 75,868 additions / 47,902 deletions
- 7,846 lines of code (core application, mostly C++ w/ Qt)
- 2,887 commits
- 352 tickets
- 247 closed
- 105 open
- 43 more issues until the next one
- 12 (active) branches
- 1 (and a 1/2) milestones completed
- 1 contributor (me)
This is what my network looks like.
Cheers.
I was planning on doing another post after Imagine RIT, but I've been pretty busy. I was able to display off MEGA_MATRIX there along with a small fork of Blit where you can create animations then upload them to the device. It's was pretty popular with the kids. I'll be posting some of the creations soon enough.
Speaking of Blit I have been still working on it daily since the first release back in February. The big thing that I had to do was refactor the underlying monolithic Animation module into a more flexible and reusable system.
Some small stats:
- 3.5 months
- +1,100 lines of code (exactly)
- 655 commits
- 51 tickets (felt like 151)
I've also done a few other things like add a shape tool, line tool, fill tool (you know, the basics), and a few icons. There are many other features that I want to add too like exporting to GIF and video files. I think I'll be able to get them done for P-2.
It's been a while since my last update. In that time, I've been working on a few projects here in there. As for MEGA_MATRIX, I've added support for the Arduino MEGA and have been able to do a few proof of concept stuff for the Raspberry Pi. The Pi version right now can get a whopping 20K FPS in the native C version! The Pi version isn't too functional right now, but expect soon enough. Link to source on GitHub.
Since the end of the summer, I've been working on my own Animation tool. It's not much right now, but you can find Linux and OS X binaries right over here. Here's the first thing I was able to make with it, a bouncing ball:
I've been a little bored while waiting for the parts and tools to come in for my January project. After playing Fez and trying out the stereoscopy mode, I decided to pass the time by trying to add the feature to my 3D cube.
Stereoscopy works by creating two cameras, one for the right eye and one for the left. These two cameras are a small distance apart. Each of them will see a slight different image/projection of the 3D objects. An image from anSGI tutorial written by Paul Bourke gives a great visualization:
There are multiple ways to view the right and left images. Probably the most common is the use of red and cyan filters. Though systems like the RealD 3D use polarized light to achieve this effect. The first method has significant color quality loss on images, where as the later has much less loss. The reason why the first method is much more prevalent is that it is much cheaper and easier to do. E.g., it doesn't require any extra equipment (sans the glasses) and is not to difficult to implement. Systems like Nintendo's 3DS use a phenomenon known as Autosteroscopy that doesn't require glasses, this is achieved by having Lenticular Lenses applied to the display. It's pretty nifty, and the quality isn't too bad, but there is there are the slight problems that it is more expensive and the viewer need to be in a “sweet spot,” to see the 3D image.
I decided to go with the red/cyan image method. In the current state of my 3D cube program, I don't have anything complicated like cameras added in, so to get this working I did this:
p = a perspective projected line
q = an oblique projection on p,
with theta = PI / 180, and a small skew value on the x component
r = an oblique projection on p,
with theta = PI, and a small skew value on the x component
color q with blue
color r with red
draw q
draw r
It's definitely an improper method, NEVER DO THIS, but it does give off the effect. I updated the repo page in case you want to view the source. Just change the variable renderStereo
to be true
.
Below is the stereo-scoped 3D cube (as JavaScript)
Finals are over and I'm back at home now. I haven't really had a nice long break in the past 2-3 years, so I'm really looking forward to these next five weeks. I'm currently waiting for from stuff from Amazon to work on my project for the break (I'll make a separate post later).
In the mean time, I decided to take a look into Google's JavaScript replacement; Dart. So far, I've really liked it. I did the Pirate Badge tutorial, but to really get into it, I went ahead and ported my 3D Canvas Cube to the language. There were also some improvements. Addition of a perspective view, better scaling, and fixing a bug where I was drawing an Impossible Cube.
When the line width of the cube was at the size of "1," it's pretty hard to see, but when you scale up the size, it's clearly visible. To fix this, I employed a simple algorithm:
sortedLines = List of "Line," objects
zLineMap = Key-Value map of floating points and a List of "Line," objects
For each line:
Look at the z coordinates of each endpoint of the line
zMin = Take the lesser of the two z's
If zMin is a key already in zLineMap:
Append it to the List at zLineMap[zMin]
Else:
Create a new list containing only the line
Add it to zLineMap at key zMin (i.e. zLineMap[zMin])
zKeys = sorted List of the keys in zLineMap (ascending)
i = 0
For each key in zKeys:
For each line in zLineMap[key]:
Put the line into sortedLines at i (i.e. sortedLines[i] = line)
increment i by 1
This algorithm might not be the most efficient (mostly likely because I haven't formally studied any computer graphics), but it avoids the issue of accidentally drawing an impossible cube. This bug was happening because I had an array of lines, would apply a rotation "matrix," to them, then sent them off to be drawn. The drawing function would process them in the order that they were indexed. Sometimes it would look right, but most of the time it would not.
The rotating cube that you see in this post had been compiled to JavaScript with the dart2js tool. If you want to see the source, it's in my toybox repo here. Don't forget the accompying HTML page.