Tuesday, August 16, 2011

Less than a week

With less than a week the firm "pencils down" date, I'm feeling a little disappointed in where my project is. I'm at the point where mesh morphs are operational (albeit buggy), with what I consider is a solid and simple API.

 mesh = soy.models.Mesh()
 mesh.size = 6
 mesh[0] = face //a soy.atoms.Face object
 // repeat for mesh[1] through mesh[5]
 clone = mesh.clone()
 //clone is a Mesh object that can be rendered in its own right, if it is bound to a body
 //change the face and vertex data for clone[0] through clone[5]
 target = soy.models.Target(mesh)
 morph = mesh.morph(clone,0.5) //mesh.morph(variantMesh,delta) spins off a soy.atoms.Morph object
 //now you bind target to a soy.bodies.Body, and when its render() method is called, it will apply all its morphs at their given deltas

Rendering has not been done yet for Mesh, and this process will be complicated on the back-end once we perform optimization. Basically we have to maintain the public vertex ordering while shifting vertices around on the backend so that OpenGL can render faces that have the same material consecutively (having to switch between materials needlessly is costly). This is already done for getters and setters for Mesh, but not honored by clone(), soy.atoms.Morph, or by the Target constructor.

Odds are this process won't even be kind of complete by pencils down, but I would expect something more fully functional by PyCon.

Tuesday, August 9, 2011

One week to "pencils down"

We have a little less than a week until the soft "pencils down" deadline. In theory, we are supposed to spend the remaining time after that point doing cleanup, documentation, etc. In practice, that will hardly be the case. The firm "pencils down" deadline is two weeks away. I'm on track to have the basic morph completed by Thursday. Then I will spend the weekend figuring out a basic keyframe pattern using atomics. Then the final week will be spent working on Mesh itself -- e.g. on rendering and optimization, which still has not been done.
At first our thinking was that a morph target is a type of model. One would render the target instead of rendering the original mesh. That idea is incorrect because it makes it difficult to apply multiple morphs to the same mesh.
The direction I've been going is this: you create a morph atom, which is calculated as the difference between two meshes. Mesh has to honor a public array of vertices as it is (even though it will be performing optimizations behind the scenes), so we assume the public ordering is valid for both methods. This means for any given vertex, mesh A contains that vertex's position, normal, etc. when the morph is at 0.0, and mesh B contains that information when the morph is at 1.0.
Then you can specify a delta, between 0.0 and 1.0, and the atom computes the vertex interpolation. Then you bind the morph atom (which is basically a matrix of values to be added) to the original mesh. This means that rendering is done on the original mesh, rather than a target model, and multiple morph atoms can be added to a single mesh.p
Animation is a little more difficult problem, but expressing morph as an atomic makes it more tractable. I'm thinking the morph atom will have an optional property (some sort of soy.atoms.Keyframe), which basically expresses what the transformation matrix will look like at some point in the future. Then as we step through the thread, we compute the matrix by multiplying the delta by the ratio between the current time and the keyframe. This could get costly if we are generating new objects every time, but it should work, especially if we have an OpenGL VBO doing the actual work of applying the matrices for us.

Friday, July 29, 2011


Not much interesting in the way of updates this week. PySoy is facing a bit of a transitional period. We're wanting to move away from GTK 2.x, because gtkglext does not support nVidia cards, among other reasons. But the question has been -- moving where? We toyed with GTK 3 but we need something with better bluetooth support, etc. Clutter was an option but seems to be no good because it does not support OpenGL features like cubemapping, which will become very important to us.

So now it looks like we are going to be writing our own library to work with EGL. It's called eglib. It sounds like an interesting proposition, but I worry that it may be increasing the scope of our project beyond our ability to quickly roll out. We'll see what happens.

Monday, July 18, 2011

The best way isn't always the sexiest

This week I had to abandon my attempts to develop on Ubuntu. It seems NVidia's Ubuntu drivers lack support for some of the OpenGL calls libsoy's windowing system is making. So I am now developing solely on Mac OS X. My OS X install has X11 support, so after my initial struggle trying to compile libsoy at the beginning of the summer, I've been able to run libsoy almost without a hitch.

One thing missing, though, is cwiid support. That's fine, since cwiid is an optional dependency for the Wiimote controller. It's easy to set a dependency as optional in wscript: you just add the "Mandatory=false" flag to your conf.check_cfg(). So the configuration doesn't error out. However, the one deceptively difficult issue was in telling waf to avoid compiling the Wiimote.gs controller if cwiid is not installed. So the build breaks.

I'm the only one really affected by this issue, so I set out to learn a little about Waf (by reading the Waf Book). And I found myself trying all afternoon to make a change that on its surface seems quite simple. There are too many source files to add them to Waf's task generator one by one, and bld.add_subdirs() does not make it easy to add constraints. So I toiled around with extending Waf's TaskGenerator class for a while. Nothing doing. So, failing that, I just used ant_glob to generate a list, and wrote an if statement that removes the file Wiimote.gs from the result, if cwiid cannot be found in the configuration.

I spent hours trying to build a sexy solution, only to settle for a kludge. It's a lesson I have a hard time learning -- I should have rolled out that little bit of hackery to begin with. Sometimes the best way makes you feel a little dirty, but it's still the best way. Problem solved; onto the next one.

Monday, July 11, 2011

I have diabetes

I have been diagnosed with Type I diabetes. I am the first in my family to have it. It's been a rough ride but on the plus side I now know why I have been so tired and practically non-sentient over the past month. And suddenly having insulin in me makes me feel once again as though I can take on the world.

The past few months of gradual emaciation has affected a lot more in my life than just GSOC. My odds of failure are tremendously high at this point, for GSOC and other areas of my life. But I'm not so far gone as to believe my actions cannot effect the outcome. There's still ~6 weeks to go, and I plan to do some damage with them.

Sunday, June 12, 2011

Learning to use Genie

Doing some reading on Genie. I'm finding there is a bit of a learning curve to Vala. Once I recover from being so deathly ill this week, I intend to put some focus in learning the only way I know how: by doing.

Thursday, June 2, 2011

More Mac trouble

One of the reasons I was accepted into GSOC was because I was able to successfully build and run PySoy on Mac OS X. On a whim, I decided to jump into OS X and run tests on some of the newer iterations of libsoy (e.g. Simple.gs).

Nothing doing. Libsoy and pysoy still build, but there is a nasty memory leak. The test crashes with a bus error (EXC_BAD_ACCESS). This happens with hboxTest and vboxTest as well. I am thinking there is some quirk in Apple's OpenGL implementation that is causing this. I have to focus on development, so I'll continue working on ubuntu. But I really want to look into this.

Monday, May 23, 2011


Coding begins full throttle today. I spent my community bonding period trying to acquaint myself with libsoy conventions, lurking on IRC, reading the back entries of the PySoy wiki and the developer's blogs. I read a wonderful book on OpenGL.[1] And then I spent my weekend having the sort of adventure one recounts in blog posts.

I drove up to Salt Lake City (about 300 mi. away, which is about 4.5 hours on Interstate 15) with my sister to attend transfer orientation at the University of Utah, where I'll be attending this fall. Then we received word that my dad was booked into the ER due to a kidney infection. So we rodded homeward at about 1 AM, and almost made it too. There were a lot of ways I could have imagined the trip home ending badly -- being pulled over by one of Utah's finest, for example, or encountering some driver asleep at the wheel. What I didn't count on was my Xterra's radiator bursting at an altitude of 20,000 km, spewing antifreeze all over the engine and coating the bottom half of the windshield with a green mist.

We pushed the Sherman tank of an SUV to the nearest freeway exit (about 7 miles, but mostly downhill, thank god). Caught a ride over to Intermountain Health Care and retrieved my dad (he was fine at this point, just souped up on Lortab) and took him home around 4 AM. I slept on his sofa until the six-year-old ran through the house at about 7 AM, then got up and went home. Let the coding commence.

My GSOC project is an ambitious one. Unfortunately at this point there is not as much infrastructure as either the PySoy maintainers or I had anticipated there would be. So the first thing I will be working on before I move to mesh morphs (proposal) will be base mesh support. There's a lot to do, and nobody really has any idea how to do it.

That's not good. I can already feel myself shifting into analysis paralysis, something I struggle with regularly on any undertaking of any complexity. For my first massive (20,000+ lines) project, a ColdFusion API for my employer's enormous CRM, my solution to analysis paralysis was to launch into coding, winging it as I went. The result was one of the most buggy pieces of barely-functioning crap I have ever written. The second time I tried such complex work, I did it by pouring a lot of thought into it before I started, refactoring constantly. The result, my company's infant PHP framework, MagicPHP, was cleaner and much more useful, but took way longer than it should have.

My plan of attack for this summer to dodge the almost inevitable paralysis is thinking about the base case. Put some thought into more complex use cases, and then forget about them. Go for what utility I can get out of the minimum possible implementation. Refactor a lot. This strategy is my only hope for not failing epically this summer.

Time for some hackery :)

[1] Learning Modern 3D Graphics Programming, by Jason McKesson, available for free here. It is the most useful book on OpenGL programming I have read because it focuses on the programmability of OpenGL. Most tutorials and books on the subject merely issue a step-by-step instruction for a specific task (this is how you make a teapot), whereas this book helps you think like a graphics programmer.

Friday, May 13, 2011

Two in the morning

I don't know what to write. Considering how long I have been on the Internet, it's interesting to me that this is the first blog post I have ever composed. I don't consider myself much of a writer. For one thing, I don't often have much to say. I'm an information accumulator. I hoard information.I treasure it. Those who want me to give some of it up--to give away the knowledge that's mine, my precious--they had better be prepared for a tide of consciousness. Make sense of it later. They're lucky I even bother to form sentences, instead of just spewing out random syllables and glaring at them for not getting it.

As part of the Google Summer of Code, I'm expected to blog semi-regularly. I think that's a good thing. Now I have to write; I'm looking forward to that. I need to be better at written communication. It's like anything, in that the more often you do it, the better at it you'll be. Too much of my time has been spent writing things meant only for the compiler. I've stopped writing for humans, and my writing has fogged up. Clarity used to come easily, and now I have to labor for it. Writing hurts, like exercise. But I need to do it more.

As part of the PySoy project, I'll be working on support for mesh morphs. I'm expecting to learn a lot about 3D rendering. But I'm expecting to learn more about people. How to function independently in a wider organization. How to build consensus and get things done. That's going to be the real benefit I get out my summer.