Monday, March 2, 2015

What I did over winter break, and why it was a massive waste of time.

I want to talk about the myriad of obstacles that I encountered over winter break (2014 - 2015). Ever since the end of my senior year of high school, after writing a pretty dinky little 2D physics simulator, I had been really wanting to give it another dimension, but held back by the complexity of it. 3D graphics and physics gets quite complex, so simplify the enormous task, there are a host of tools that one could use, ranging from closed source production-quality game engines like CryEngine or Unity to the free and open-source tools that I chose to use, Ogre3D and Open Dynamics Engine. I chose the open sourced libraries because, (a) I exclusively use Linux, and Unity isn't available for Linux and (b) I am a Linux SysAdmin, what do you expect?.

An image of what some of the starter code rendered
This Ogre is a pain in my ass!
So at the beginning of my sophomore year, I decided upon Ogre3D after learning Cinder was unfortunately Windows and OSX only. So I tried to start working through the beginner tutorials but the provided starter code wouldn't even compile. The starter code's Makefile was just broken, with about four lines of options needing to be added to the autotools makefile.am and configure.ac. After getting in touch with a developer, who kept insisting I use CodeBlocks, a graphical IDE (ew gooey), I noticed that there were some very helpful comments on one of the autotools configuration pages that included exactly what I needed to get the starter code compiling. My question is, why hadn't these changes been made to the code? Finding this and getting it to work took up most of the first half of my semester, just to get the starter code compiling!

So I went into winter break hoping that my experience would smooth out, or that I would get over some threshold and finally understand how to make Ogre do exactly what I want in an intuitive way. After all it is object based, why shouldn't it be intuitive? Well, long story short: I was wrong. Ogre's syntax is incredibly verbose and complex. It's objects are not used in an intuitive way--it's data structures are sort of hybrids between self contained objects and nested-scoped static methods. For example, I struggled to be able to simply print to the program log, and that is because printing requires the following line of code in Ogre:

    Ogre::LogManager::getSingletonPtr()->logMessage("### Error parsing config file ###");

 "Ogre::LogManager::getSingletonPtr()" is a call to a static method within the LogManager scope, which is itself within the Ogre scope. That method will return a pointer to the Ogre::LogManager object, which can only be initialized once in the program. Then you can use that pointer to call logMessage(), which will add your message to the log. Here is the initialization of the LogManager object:

    Ogre::LogManager* logMgr = new Ogre::LogManager();
    Ogre::Log* myLog = Ogre::LogManager::getSingleton().createLog("myLog.log", true, true, false);

Honestly, I don't even have a complete understanding of what this code is really doing, I mean is logMgr a deferenced LogManager pointer to a pointer to the new LogManager object? What? After that line, we can completely ignore the existence of the logMgr object, because of course we will just use getSingleton() whenever we need to log. (what was the point of even making us write that line then?) But initializing the LogManager wasn't enough, because we need to create the log file, and put it into myLog, which we will never use again. If the logManager object was only meant to be initialized once, and used through getSingleton(), then why even make us be so verbose about it. These kinds of options should not need to be written explicitly. I mean, if I wanted to rename my log's filename, or specify whether to add debugger output to it, then I should be able to via these complicated ways. However, if I just want to print some message and don't really care, I am forced to add these highly complicated lines of code to my file just to do that. 

My entire winter break went like this. There was no way I had the time to fully understand all of the highly complicated syntax of Ogre, while also trying to tie in Open Dynamics Engine.

Open Dynamics Engine (ODE) is a rigid body physics engine, written in C. Naturally, it's interface was  incredibly different than Ogre's. While it was much less complicated and slightly much more straightforward, I ran into serious difficulties when trying to get it to play nice with the big bad Ogre. For example, all the calculations ODE ran would be returned to my program in the ODE-defined 3d coordinate object const dReal* and I was tasked with the requirement to decompose that object and turn it into what Ogre wants, Ogre::Vector3 s, in order for the object to be re-rendered in the corrected location. It was a constant battle trying to make the two get along, and even today they still don't behave. 

Well that got long and complex... In summary, I dove head first into the deep end of two very complicated and very different C and C++ libraries, and I emerged with a buggy hunk of code, from which I understand <60% and have written <40% myself. I previously thought that if I forced myself to use C++ then I would be a better programmer than all those cheaters using the easy languages like Python. I even started the break off with a few OpenGL tutorials before realizing that it was far too low level for the kind of things I wanted to do. Clearly, the same was true for Ogre and ODE. I learned C++ and C are production-level languages and programs that are even mildly complicated are usually written by many people over the course of many months, not by a hobbyist experimenting with 3D programming with a low work ethic (winter break is a break after all). 

All of this is ironic, of course, because the reason this blog exists is because of my research at ASU. At ASU, I was researching the differences between Java and C++ and concluded that C++ was more geared towards businesses with more value in their software and many more programmer (wo)man-hours to devote to it, NOT lazy CS majors trying to have some fun making a realistic 3D world. I guess this whole experience was a lesson in believing the results of actual research... 

Well, thanks for reading, and if you have any questions feel free to comment and I will try to answer them if I can. 

-Jeff

1 comment:

  1. Well it looks like I tried this project about 3 months late. Recently, both Unreal Engine 4 and Valve's Source 2 have released to developers for free, AND can be built and run on Linux... They're still not open source, but I probably would've considered these options since they would have been 1000x more user friendly and productive for me.

    ReplyDelete