I moved office last weekend. The good news is I am no longer doubled up. The bad news is I no longer have a window. Sigh.
At companies I worked for in the past, the process for moving office was simple. I would unplug my gear, carry it over to my new desk, plug it back in, and get back to work.
Not so at Microsoft. Apparently there is some liability concern that people could injure themselves while carrying something heavy. "Hey, I sprained my toe while lifting an Xbox devkit. Bill Gates made me do it, so I'm going to sue!"
To move offices at Microsoft, you simply stick little labels on all your belongings. For bonus points you can stick your labels on any coworkers belongings that you would like to have 'accidentally' delivered to your new office, too 🙂 You go home, the movers scurry around over the weekend, and everything is sorted by the time you come in on Monday morning.
Apart from the sticky labels, that is, which I discovered are Really Hard to get off some places I probably ought not to have put them!
Also apart from the fact that because so many people were shuffling around, the weekend was not long enough. The movers needed Friday as well. And so, as we finally arrive at some kind of an actual point to this post, there I was, at home, on Friday, with no devkit, no corpnet access, and no way to do any useful framework coding.
Bored. Nothing to do.
"I know! Let's build a sample!"
I promptly set to work. And while writing this sample I had one of those "aha!" moments, where all of a sudden you remember something that you used to know, should have known all along, but had somehow forgotten about.
Once upon a time, roughly a year ago, we were busy designing the XNA Framework. The question of models came up. Should we have a standard model class? If so, what should it look like? There were many options:
- Simple or sophisticated?
- Fast or flexible?
- Indexed geometry? Non indexed? Triangle lists? Triangle strips?
- Internal hierarchy, or just triangle soup?
- What kind of animation data to include, if any?
- What kind of collision data to include, if any?
- What is a material?
- How extensible?
"My goodness", quoth we. "So many choices and so little time. One-size-fits-all does not seem to apply here. Anything we decide will be right for some people but wrong for others."
We initially thought the best approach would be not to include any model class directly, but instead to make it as easy as possible to create your own customized implementation. Instead of giving you a single fixed type of model, we would give you a model construction kit (hence things like MeshHelper and CreateVertexBuffer). People could then put together exactly whatever combination of features they needed.
Sounded good in theory. But when we gave builds of the framework to a few brave early adopters (hi Andy!) we got some pretty strong feedback that this was not so good in practice. People didn't want to bother with a construction kit: they just wanted something built in and ready to use.
Back to the drawing board. We added Model, choosing these answers for the design questions I listed above:
- Indexed triangle lists
- Stores hierarchy in the ModelBone data
- No animation data
- Bounding spheres
- Stores material data in cloned effect instances
- Very limited extensibility via the Tag property
Flexible enough to be all things for all people? No.
Good enough to get the job done for a lot of people? Sure...
So there I was, writing my sample. (see what I did there? Not only is this post ridiculously long, but it uses a nonlinear narrative, too). I needed to handle model geometry in a very specific way. My thought process went something like this:
"Boy, this is a pain. The Model class isn't really a good fit for what I'm trying to do here."
"I wonder if I should just ditch Model and use a totally custom class instead?"
"Surely not... never reinvent the wheel!"
"But abusing the Tag property like this is getting ugly. I'm going to try a custom Model replacement."
"Wow! That was ridiculously easy! I can't believe how little code I had to write!!!"
"Oh yeah. We designed everything specifically to make this easy. I remember now."
"Come to think of it, all those reasons why a single Model class cannot possibly satisfy everyone are every bit as true now as they were back then. Just because we added Model as a built in type doesn't mean it isn't sometimes smart to replace it with something more specialized."
When you were a kid, your grandma probably taught you the ancient proverb, "when all you have is a hammer, every problem starts to look like a nail."
Actually, that's a lie. My grandma never taught me that. I just find it amusing to consider a possible future where a new generation of programmers could be raised on such nuggets of engineering wisdom from their geriatric predecessors.
Sorry. I'm rambling again.
- Model is a hammer.
- It is actually rather a decent hammer: triple heat treated, with a curved claw, balanced steel head, and tag attachment for adding optional accessories such as the magnetic nail set, keyframe strimmer, or zombie head crusher.
- But sometimes you don't need a hammer!
- Don't be afraid to replace Model when you need something different.
- It is easy to do so.
- Stay tuned for the sample.