In other news, about a month ago I started a daily Japanese practice blog (毎日日本語練習ブログ). I call it 日本語ベン強 (nihongo-benkyou). It's a pun; you won't get it unless you know some of the language. Since February of 2018, I've started taking Japanese classes. Foreign languages have always been an affinity of mine, and I was looking for a new hobby that's not related to tech. I created the blog so I could get some practice writing Japanese. Even if it's not the most correct. So far it's been fun.
Animation is one of my loves. Back when I was a second and third year university student, I had the oppourtunity to take some animation classes. They were more focused on things like The Principles of Animation instead of general film making. Back then I did upload two of my assignments that I was really proud of, but three years later, I've kind of summed up the courage to upload the majority of my work from those few classes. I'd like to share them with you; they are all below:
For RIT's "Intro. To Animation," course, there was a final assignment to show the instructor what we have learned. So I decided to make this little half a minute short called "A Ball in a Box."
I know there are quite a few sound syncing issues, I do apologize.
For week 3 (?) of RIT's "Intro. to Animation," course, we had to create an animation that would sync up to the playing music.
A pencil test for an animation assignment I did a while back at RIT's SoFA. We had to do a ball bounce, but with a very heavy bowling ball. I think I got the weight of it pretty good.
A pencil test for an animation assignment I did a while back at RIT's SoFA. We had to do a ball bounce in perspective. I decided to have a little extra fun with it and pretend there were some obstacles making it bounce a little differently,
A pencil test for an animation assignment I did a while back at RIT's SoFA. We had to have a balloon filled with water roll off of an imaginary ledge.
A pencil test for animation assignment I did a while back at RIT's SoFA. We had to made a sheet of paper fall through air; I had a little fun with it.
A pencil test for an animation assignment I did a while back at RIT's SoFA. We had to have a sack of flour do a little jump.
A pencil test for an animation assignment I did a while back at RIT's SoFA. We had to have a sack of flour wake/get up, walk a step or two, then fall over.
A pencil test for an animation assignment I did a while back at RIT's SoFA. We were given a sequence of key frames of a "Tarzan," character doing a jump n' swing with a rope, and we had to do everything in between.
A pencil test for an animation assignment I did a while back at RIT's SoFA. We had walk cycles coming up in a few weeks, so I wanted to get a little bit ahead and try doing one myself. I showed it to one of my animation professors and he said that it looked more like a march... I guess that's something at least. :P
A pencil test for an animation assignment I did a while back at RIT's SoFA. We had to do walk and run cycles (in place), along with a transition for each.
A paper cutout animation assignment I did a while back at RIT's SoFA. We had to do a lip sync, choosing any audio we liked. I went a small snippet from Charlie Chaplin's "The Great Dictator."
As of the past year Glitchet has been one of my favorite parts of the week. It's a mini newsletter that covers all sort of futurism and computer arts thing that I'm interested in. A While back (seven months actually), I contacted the curator of webzine and told him he should do an article on Random Art. I didn't hear back from him until a few days ago.
He asked me if I was willing to write a piece on how it works. Everything was fresh in my mind from my Nim port of Random Art, so I agreed. Over the weekend I came up with this. It gives you a simple overview of how the process works and where these pretty pictures come from. If you don't understand anything, I'm sure you'll be able to grasp something at least.
Edit (Jan 30th, 2017): I written an article on how Random Art works. You can read it here.
Well... actually I ported that to C++ (& Qt) first about a year ago, then I did another port over to C# four months later. The C# one was a little more interesting because it was a distributed rendering system leveraging cloud services and RabbitMQ; I ended up using it on a film I was working on. Pretty cool. Those... I don't really feel comfortable sharing the source to right now. But I'll give you a Nim implementation instead. : P
You can find the application over here on GitLab (or GitHub if you prefer it). To compile the thing, your going to need GLFW installed as well. It can run into two modes: CPU bounding rendering and GPU (via OpenGL). There is a lot more info the in the Readme, but here is the usage message:
Usage: ./random_art [input] [options..] input : a path to an equation file, or provide `stdin` to read input from standard input Options: -r, --renderer : cpu | opengl render on the CPU or with a GPU (using OpenGL) -s, --size : <width>x<height> the dimension of the render, must be a positive int -b, --bounds : <xMin>,<xMax>,<yMin>,<yMax> the bounds to use to render, must be a float -o, --output : <filename>.png the file to save the render as, must end with .png
If you run the application without providing an equation, it will think up one for you. Writing your own equations has this Scheme-like syntax. It's pretty easy to understand, but also to parse. The equation below makes the image to the right.
(mul (var y) (mod (sum (var x) (var y) ) (const 1 0.7 -0.1 0.95) ) )
I plan on working on this some more down the road. You can already see some of my changes showing up (e.g. an alpha value). I'll keep you guys posted. Once again, the code is available here (GitHub mirror).
Before I begin, you can find the source for Blit over here.
I want to talk a little bit about a project I worked on every day from July 2014 till the end of August 2015. You may have seen a few entries about it back on earlier posts; that project was something I called “Blit.” If you’re wondering what Blit was, it was my attempt at trying to make an Animation focused art program. It was pretty ambitious for someone like me at the time.
There were two main reasons why I started to work on it:
- Back when I was an undergraduate, I was part of a student group were we had to do these things called “major projects,” each year if we wanted to retain membership. They usually are of a technical nature (programming & engineering). This is where my initial drive came from
- I’ve never worked on a “large,” or “longterm,” project before. Everything else I’ve done up till that point were small things like class assignments, course projects, or tasks for my internships. I had friends who had worked on their own projects for two or three years straight and made some really cool stuff. I really wanted to be able to tell others (mainly prospective employers) “Yeah, I’ve been working on this thing for over year. Want to take a look?” Other than just “having something,” I also wanted to learn how to manage a larger and lengthier project.
The “major project,” was something that was pretty easy to fulfill. But for the second I did something kind of stupid, but worked well for me. I told myself “Alright, I’m going to work on a project that will have a 365 day long GitHub streak.” In reality, git streaks are a silly thing to track progress. I was working on Blit in a private repo, so the outside world would not see my streak at all. I feel bad for the people who have the need to maintain one. For me it was a reminder to build on Blit each day. It worked.
Whether it be programming, logging issues, source code cleanup, design & planing, writing documentation, etc., I had to minimum goal of one meaningful commit per day. Normally I would spend an hour on Blit per day (more on the weekends). I would keep at it until the kitchen timer to my side beeped. Somehow that little thing was able to keep me focused for a straight hour.
So What Is (or Was) Blit?
I’ve always been someone who’s liked art and programming. Especially combining the two. One of my favorite genres is pixel art, or sprites as they are also known. I’ve dabbled in making a few other art programs before, but nothing like this.
Originally Blit supposed to be only a sprite animation tool that had a modern look and feel, but my ideas for it grew greater (*sigh* feature creep). There are many other sprinting tools out there like GrafX2, Aseprite, (and other 2D animation programs like TVPaint). I’m not saying that it’s wrong that they make their own GUI toolkit, but it feels kind of odd. I really wanted to bring these types of programs out of the days of the Amiga. After doing some initial research, I settled on using Qt. Here are my reasons:
- It’s cross platform. I work on a Linux system, but I want my Windows and OS X friends to be able to use what I make
- It’s a C++ library; my native tongue. But there exists bindings to other languages, such as Python
- There’s a lot more to Qt than just widgets. It really is a fully featured desktop application framework
- It has a massive community around it and it’s very well documented. So if I ever ran into trouble I’d be able to find some help
Before I move any further, you might be wondering where the name “Blit.” came from. Since it had a focus on 2D graphics, the name came from the “Bit blit,” algorithm. I used to do a lot of programming with libSDL, so the function SDL_BlitSurface() has been burned into my brain. I thought it would be a cute name too.
I also wanted to keep more of a “traditional animation,” approach to Blit. Instead of drawing on images there were “Cels.” Layers were called “Planes.” Instead of a Dope Sheets I had “Exposure Sheets.” I didn’t call it “onion skinning,” but “turning on the Light Table.”
As mentioned before, I was focused on sprite animation (originally). I wanted to keep things as easy as possible. While I did consider using Qt’s native C++ libraries, I decided on making the program in Python with PyQt. Scripting languages are typically much faster to write code for. I felt as if I would be able to get more done in less time. I didn’t think that there would be too many computationally intensive procedures to worry about. In the event that I needed some performance boost, I could always write a C/C++ extension for Python.
After choosing my tools, the first thing I did was draft some design documents. These included a user interface mockup and an initial file format structure. I started to log tickets on the GitHub issue tracker. I had an miniature road map to start from. Within a month and a half, I was able to load up one of my files into Blit, do a little simple Cel & Frame editing, and then save it. You couldn’t do too much with it, but I thought it was a good starting point.
During my initial research of Qt, I discovered something called the “Graphics View Framework.” There were a lot of widgets that I had to custom make such as the Timeline or the Canvas; it made my life much easier. It really is one of the nice features of Qt. If you’re making a heavily graphical application you should take a look into it.
Despite being able to get a basic animation loaded, edited and played back, I was starting to run into some issues with the development language: Python. I had issues with things like circular imports and nested imports (python files imported from many directories deep). I don’t want to go into the details of how they were affecting me and the project, but all I can say is that they were driving me up the wall. So I devised a solution: Switch to C++.
Now, switching development languages is not always something that’s advised. But at the point where I was, it was feasible to do and would possibly have a better impact on my project. Nested imports are a non-issue in C++ and the circular imports are fixed with simple include guards. On top of that, I wouldn’t have to use PyQt’s bindings anymore and Python would not be a performance bottleneck since it would be gone. Working at my usual hour a day pace, it took somewhere between two and three weeks to port everything I had to C++. I wasn’t happy about losing that time to work on new features, but I think it was a better choice in the end.
I didn’t entirely ditch Python & PyQt. If I needed to prototype a widget, I would use those tools. It helped to realize ideas pretty quickly, then later I would integrate it into the C++ source.
Feature Creep, “Future Planning,” and Broadening Horizons
In the first couple of months that I was working on Blit, more ideas started to pour into my head of what it could or should be able to do. We all know what this is; Feature Creep. Whenever I though of a cool new thing I wanted to add, I usually weighed the cost of adding it in within my current milestone, the next, or burring it in the issue tracker. This is where I developed the “Future Planning,” tag. If something popped into my head, almost 95% of the time I would not mark it under any milestone and put it under that tag. It was a good way for me to tell myself “Alright, I think this would be a good thing, but I need to focus on other stuff right now.” This worked actually pretty well for me. At all times, the most populous tag in my issue tracker was the “Future Planning,” one.
Around 100 days into the project, I felt like I had a good direction that I was going in. I was nearing the end of my (second) internship and I would be left with nearly two months before classes would begin again. With all of this free time, I set myself the goal of “Be able to draw a bouncing ball animation and export it as a Spritesheet,” before Christmas hit. I achieved that.
By this time you could move Cels around on the Frames, move the Frames on the Timeline, and adjust their hold values. I think I focused more on the staging of objects rather than editing them. To work on this shortcoming, I decided to start work on a Tool interface. I had the idea that editing tools should be plugins and people should be able to write their own; a very common idea in art applications. Instead of only “put pixel,” and “erase pixel,” I added line/shape drawing, filling, and was working on a soft brush tool.
When I got back to school I fulfilled that first goal of passing it as a “major project,” in my student group. It was well received for what it was at the time, a very simple pixel art animation tool. Though, I started to think more beyond simple spriting. Not only do I consider myself a fan of Animation, but someone who really enjoys making it. I started to ponder “What if Blit could be used for all sorts of 2D animation, not just pixel art?”
I didn’t think it would be too hard to add a camera hookup to the program (something that I’ve done with Qt before), so Blit could be turned into an application to do pencil tests, capture paper drawn animation, or even stop motion. My rule became “If it’s Bitmap based, Blit should be able to do something with it.” I also thought that there wasn’t a good free (both as in beer and speech) software solution to 2D computer animation. TVPaint, Dragonframe, and FlipBook were used a lot in the animation department. I can understand the expensive cost of them for professionals and that it’s niche software, but it really sucks for students who want to learn how to animate, but already were paying a small fortune for their college tuition.
To make Blit more generic, it had to undergo something I called dubbed “The Grand Refactoring.” The whole animation module was like this: an Animation owns an XSheet, which owns a list of Frames, where each Frame owns a list of Cels. No reuse. This was good to get started with, but pretty bad since in the real world animation is reused all of the damn time. So I devised up this system instead:
As it would force me to fix up almost every single thing in the program that touched the Animation module (including the file format), I set this to be its own “half milestone.” It took about a month and a half to complete. It really sucked not being to add any new features for that time; only endless refactoring. At the end of that, all the logic was in the code to be able stage the same Cel across multiple Frames, or instance a Frame multiple times in the Timeline. Though, because I was focused on fixing things up, I didn’t add in an interface where the user could actually reuse Cels and Frames. If they wanted to, they would have to edit the
sequence.xml file. So it was there, it worked, but wasn’t usable by the layman.
While taking classes and juggling other (smaller) projects it sometimes became difficult to make meaningful contributions to Blit. I tried to stick to my “one hour a day rule,” but that became hard. Also, refactoring isn’t fun. You don’t get to see new features, you’re restructuring stuff that already exist. You might also break things and then have to spend time fixing them. It’s hard to stay motivated when nothing is new or exciting.
My brain was fried after writing code for my class assignments. I found that (better) documenting the source code, reviewing issue tracker tickets, and revisiting design documents wasn’t too hard. If I recall correctly there was a two week stint were that was all that I did.
Despite all these speed bumps, I got to do something really cool with Blit at the end of the year. If you’ve read some of my older blog posts, you may have seen this thing I made called MEGA_MATRIX. For those of you who don’t know what it was, it is a 24x24 LED Dot Matrix display. I actually developed it in tandem with Blit during the early days of the application. Anyways, at the end of the year my college hosts what is essentially a campus wide show and tell day. I thought it would be neat If I could let people doodle animations in Blit, then upload them onto MEGA_MATRIX. Turns out it was. I made a special fork of Blit called “The MEGA_MATRIX Edition,” where I only let users draw in two colors (red and black), preview their animations, and then upload them to an Arduino to drive the display. One of my friends said it was his favorite thing at the festival because “[I] practically made a hardware implementation of Mario Paint.”
Altered Scope, One Full Year, and the End of Development
At the beginning of 2015’s summer, I was off to my next internship. During the day I would write C# code for a rendering infrastructure. After work I would exercise, watch some TV, play a few video games, but also work on Blit, for well, at least an hour a day.
After “The Grand Refactoring,” and the MEGA_MATRIX Edition I was able to get a few more features out of the way. Changing the Canvas’ backdrop color, pixel grid, selective playback, a color picker tool and more. One of my favorite additions was onion skinning (I called it the Light Table). Thanks to the newly redesigned Animation module, it actually made it pretty easy to implement.
Then sometime in mid July I hit my second goal; hold onto a GitHub streak for one year straight.
The code for Blit was starting to get really huge at this point. I still was able to manage it myself, but it started to become a bit of a chore too. I also spent a lot more time refactoring and fixing existing code rather than working on new features. I feel like I lost a little of my drive then. As my two initial goals were achieved I could have stopped here. But for some reason, I didn’t want to. I kept on pushing.
My internship came to an end, I had a week at home, and then I was off to another internship. All of the previous places were I interned let me work on outside projects if I wanted to. As long as it wasn’t during work time, with work equipment, or a competing product I was free to do what I want. This time around, my employer asked me to stop working on outside projects all together.
While I felt that work on Blit was starting to go stale I still didn’t feel to happy about having to quit development. I could have worked on it in secret, but that didn’t feel right to me. So, right before leaving for the first day of work I made an early morning final commit to the Blit repo. It was kind of poetic that my ending streak was exactly 400 days long.
In the month that followed, I was bummed that I wasn’t able to add an interface for the reusable Cels/Frames, the Brush and Resize tools were still unfinished, no work on multiple planes was ever done (Cel layering existed though), but worst of all, I feel that it sucked when trying to make sprites; the original goal of Blit. I still had ideas popping into my head. Such as using FFmpeg to export animations as animated GIFs. All I could do is just scribble them down on some note paper and file it away for when I was done with my current internship.
So four months down the road I was done with my final practicum. Did I start back working on Blit? No. The previous month was pretty turbulent for me, as well as the next couple. It was my last semester at college and I was more focused on graduating. I still had ideas coming into my head for Blit, but they would go into the issue tracker instead of the code. I felt that I was way too out of it to startup work back on Blit. I also realized how much of a behemoth the source had become. Thus I decided to put it on hiatus indefinitely.
Final Lookback and the Future
Almost everything I’ve done is a learning project for me. Some of I learnt very little from, others a lot. Working on Blit taught me so much more about Qt than I ever wanted to know. Hell, in the process of developing Blit I spotted a minor bug in Qt and was able to submit a(n) (accepted) patch to the project. That was one of the more rewarding moments, as I’ve never contributed to a major open source project before.
But the main thing I gained from Blit was learning how to manage/handle/organize a larger project. I was never involved with issue tracking, documentation, and design so much before. As stupid of an idea it was to maintain a year long GitHub streak, it somehow worked for me. It was fun to show off the streak to my friends, it was really there for me to motive myself.
While building Blit, one the things I always wanted to do was work on it with other people. Though, I kept it in a private repo I always had the intention of releasing the source code when I was done with some of the core features. While many of my friends thought it was interesting, I couldn’t find anyone else who wanted to work on it. I always made sure to keep good documentation of the design and source code for this reason. I really wish I had others to help me with this, not only so that I could have had Blit in a much further state, but also so I could learn how to collaborate with others better too.
It’s now been a year since I last touched Blit. At the beginning of this past Summer there was a monkey on my back to figure out “the future of Blit.” I know I wanted to release the source for it, but I’m not sure where I want to go with it. In the past year Dwango released OpenToonz and Krita has added some animation tools. Both of these have much better drawing capabilities. It’s hard to compete.
I have a small desire to restart work on Blit. For example, adding a camera connection to shoot paper drawn animation or working on some FFmpeg exporting. But I have other priorities right now. If I had to do it again, I would want to write Blit in C# instead of C++. I’ve grown to love C# a lot in the past year and development in it is much easier than C++, and performance is still pretty good. I really hope that QtSharp can get off of the ground sometime soon.
If you want to check out the source for Blit, you can find it over here: gitlab.com/define-private-public/blit. If you want to see some of my fabulous source documention, it’s at: https://blit.gitlab.io/SourceDocs/. And if in the slightest chance that you’re interested in working on Blit, please contact me.
To end with, here are some stats:
- 97 source code files
- 8,175 lines of code (95% C++)
- 400 days of contributions
- 364 issues tracked
- 3,151 commits
- 91,528 additions, 65,617 deletions
- An unknown amount of users
- and 1 developer (me)
Fractals have been something that I've found really intriguing since high school, though, I've never taken too much of a stab at trying to generate them. For a few assignments back in my CS1 class we had to use Python and the Turtle package to draw some. These were done mainly to teach the concepts of recursion, state, and using geometry in computer programs; pretty basic stuff. I imagine that almost everyone has had to use Turtle at some point in their CS coursework, and incidentally, has drawn a fractal.
Last year I was taking a course in Global Illumination. We had to do two projects over the semester. Write a ray tracer (throughout the weeks) and explore a graphics related topic of your choosing. For that second one, some students chose to look into ray marching or real time raytracing. I wanted to look at fractals some more.
After talking with one of my friends, he told me to look up something called "L-Systems." The full name is "Lindenmayer System," and it's the magic behind fractal generation. In a nutshell, the idea behind it is to create a grammar (yeah, one of the CS theory ones) and give each letter (or variable) an action (e.g. "draw line forward 10 units," or "rotate 45 degrees clockwise,"). The simplest example I can think of is the Cantor Set on the L-System wiki page.
Even though I was already making a 3D graphics program for the class, I decided writing a Blender script would be the best. Here are some of my reasons why:
- All the tools, libraries, and rendering infrastructure is already there. I only need to focus on the tree logic
- My Ray Tracer has a .obj file loader, so all I need to do is export it from Blender as a Wavefront object
- On top of it too, I was also able to export it as a .stl, load it into slic3r, and materialise it on my 3D printer. Pretty cool!
- Blender is widely used and some others might find my script useful
So working in Blender there isn't a 3D Turtle object you can rely on to do the drawing. But instead, you have to work with Matrices. The basic idea of what you need to do is this:
- Chain a bunch of matrices (appending and popping to/from the end of a list works well). Most of what you'll need will come from
Matrix.Rotation(). These are equivalent of the Turtle movement commands
- Make sure you chose one axis as your "forward," direction. For my script, I always made translations in the Z+ direction.
- Compute the result of the matrix chain, by taking the leftmost (first) matrix, then multiply it by it's neighbor to the right. Rinse and repeat until you have one matrix left
- Create a new 3D mesh (e.g. via
- Blender will consider the newly created mesh as the "currently active object." So multiply that new mesh's world matrix by the computed matrix chain:
bpy.context.active_object.matrix_world *= computed_matrix_chain
- And voila! It should be in the location and orientation you want it. From here you can go to a deeper level of the fractal or move back up. Don't forgot to pop those matrices off the end of your chain!
If you're still a little bit confused, take a look at the git repo over here. All of the necessary code is in
l-system_tree.py. It's pretty simple and you should be able to follow along. My L-System grammar is quite uncomplicated:
- A → BCDE
- B → A
- C → A
- D → A
- E → A
"A," also means "draw a branch," whereas "B," "C," "D," and "E," mean rotate about an axis (each one is different). Each variable also checks the current depth to make sure that it isn't going on forever, though only "A," really needs to check for that.
There are a few other configuration options that I threw in (e.g.
TWIST) so I could make some different looking trees. Below is an example of one of the trees that I made with
VARIATION_MODE turned on; it gives the tree a much more natural looking feel.
I've been making a lot of fixes here and there and working on some new content, but this one I've been looking forward to (and dragging my feet on): A new logo!
The first logo was actually supposed to be just a temporary logo until I could flesh out my original ideas for one.
It stayed here for 3+ years, and I grew a little attached to it. So I decided to incorporate it into the new one.
I always wanted something that was a lot more colourful. Parts of it were procedurally generated (but not much). I'd say I'm happy with it.