Beta 6: Cockpit Chaos
The code that decides what parts of the plane get drawn in what views is, to put it midly, byzantine. The code evolved, and in this process became more complex and convoluted.
The code that decides what parts of the plane get drawn in what views is, to put it midly, byzantine. The code evolved, and in this process became more complex and convoluted.
Let me just clarify one thing about yesterday’s post on materials: the new material system will let authors edit material parameters like shininess; it will not let the user change textures.
Objects will continue to require texture atlasing (that is, the use of one texture set with the individual images combined). Inside the company, we call this the “crayon rule” – Austin’s original analogy to explain atlasing to our art team was that you draw slower if you spend all your time putting a crayon back in the box and taking a new one out.
So materials will let you change some macro-parameters of how the object is drawn, but not swap out the texture.
First, we’re not going to get an OBJ materials model in 930. 930 is crammed full of stuff, and I don’t want to add anything more! I am not sure when we’ll get OBJ materials, or even if this is how it will go down. But this is what I am thinking:
To this last point, consider that OBJ currently has a number of strange cases where you can set attributes that don’t have any effect. For example, you can set the shininess while drawing the cockpit texture (which is unlit). Code like this has historically been buggy, partly because it’s not necessarily obvious to a human reader what the object should do.
X-Plane 930 beta 4 will be out real soon, and it has a somewhat significant new instrument feature: all instruments (not just generic instruments) can have additive lighting.
A number of users have commented that the X-Plane 930 betas looks “shinier” than before. There are actually two separate features going on :
Here we have the default 747, as of 922. It’s a little bit tricky to tell what’s going on because the texture has been painted to look like there are lighting effects. But the white “specular hilights” on the engine nacelles are due to the sun position. Lighting is per-vertex and specular hilights are not separate.
Next we have the same plane in 930 without shaders:
Note the increased brightness on the nacelles and fuselage. What’s happening is the hilights are no longer modulated by the texture, so they show up a bit more.
Finally, the plane in 930 with shaders. Now the hilights look smoother and much brighter. This is because the hilights are calculated on a per-pixel basis. Note how the hilights are small – smaller than the triangle size on the engines. We didn’t get the full “glare” effect before because the brightest part of the hilight did not land on a vertex at all, and was thus never seen.
Note that the change in specular hilight handling (moving to separate specular hilights) is a bit of a compatibility break. Previously authors could count on not having specular hilights on dark parts of a plane, even if they set the plane to be shiny.
I am not sure how we will ship the final version of 930. I have received very few (none, to be exact) complaints about dark surfaces appearing “too shiny”, and a lot of users like the new shiny look.
The alternative to the current scheme (specular hilights are separate by default) is to have this be a selectable feature. Older planes would look the same as they always did, but planes would have to be modified to make them look truly shiny.
ATTR_hard is the OBJ attribute that makes the geometry of an object mesh interact with X-Plane’s physics engine. ATTR_hard object has a long history of weird behavior, and its behavior in X-Plane 930 is no exception.
What Do You Do With a Buggy Feature?
Even given this limitation, you can now make a building with limited access controlled by animation; using a “deck” for the roof and a hard surface for the tops of the walls and the doors (which are animated) you can control access.
It is true that in X-Plane 922, some programmer dialed down the effective range of VORs.
I have been trying to put documentation on the X-Plane Wiki, and use this blog for announcements and “the inside story”, rather than letting the blog turn into a poor-man’s users manual. An aircraft developer asked me via email whether there was a blog entry on some of the pitfalls of the v9 panel lighting system. There is not, and the lighting system is under-documented. I will be working on improving the documents over the next few weeks, but the point of this blog entry is: “how did we get here?”
I am a huge fan of incremental software improvement. That’s the subject of another blog post (perhaps on another blog), but for now I’ll say this: all changes to the rendering engine since version 8.0 have been incremental ones, and yet if you were to look at the code, you wouldn’t see a series of band-aids taped on top of each other. Each incremental change leaves the rendering code “fully updated”, as if it had been written yesterday. I start each new scenery feature by first reshaping the existing code into the most useful form for what we want to have in the future, and then coding the new feature is relatively simple.
But this strategy has an Achilles heal; if the code being refactored has a public interface (whether it is a file format or programming API), then all of the intermediate steps in the journey become requirements for future products in order to maintain backward compatibility.
This is not a problem as long as the programmer knows where he is going. The danger comes when one of the intermediate steps is actually a step in the wrong direction, and becomes dead weight around a future design.
A Reasonable Progression: OBJ
The OBJ 800 file format has had a reasonable progression* since its birth in version 8. It has gained a number of new features, but each one has generalized and made more powerful previous ideas, such that “legacy behaviors” are not so painful. Some examples:
I can’t say that the relatively pain-free evolution of OBJ files over the last 4 years comes from good design or genius on my part – in truth it’s probably just good luck. But I think one thing has helped me keep the new OBJ extensions relatively sane: most of them are conceived several months before they make it into X-Plane.
I have a scenery system to-do list that will last me at least another four years; most of it is filled with things that Sergio has asked for. This to-do list acts as sort of a road map for future scenery system extensions; for any possible OBJ change, I can look at it relative to the other todo items and ask: “is this extension going to play nicely with things to come?”
(As a side note, this is one of the reasons why there are not light maps in any of the X-Plane modeling formats. Light maps don’t play well with a number of other scenery system extensions. I want to resolve the conflict between these future additions before they go into the sim.)
Wandering In the Desert
By comparison, the evolution of the panel system in version 9 has been more like wandering in the desert than a straight line toward a goal. Repeatedly, I put features into the panel system without a clear roadmap of where we would end up or how they would work together. The result is what you see now when looking over the panel documents: complexity and chaos.
Basically there are several major changes to the panel system that affect each other in strange ways:
The problem is the order that they were invented: first ATTR_cockpit_region, then the 3-d cockpit, then back-lit generic instruments, then 2-d spot lights, and then 3-d spot lights.
The result is two sources of confusion:
This second point is a tricky one: X-Plane has to continue to support whatever set of features was available for any given release (864, 900, 920, 930) so that older planes continue to work. But some of those combinations (e.g. the ones that exist in version 900) don’t make a lot of sense for new planes made in 930.
I am open to ideas on how to solve this. I intend to document a “correct formula” for a modern plane, perhaps with tutorials, on the Wiki. I am also considering programming Plane-Maker to flag unusual combinations of features as a warning when saving 930 planes.
Either way, I fear I’ve learned my lesson from the panel system: incremental improvement of code is only a good idea if the programmer knows where he is going! Next time I will use Google Maps. 🙂
* I suppose that whether you think the OBJ 800’s evolution has been reasonable depends on your standards for file formats. OBJ 800 absolutely does show growing pains. I would only say: consider the number of revisions and the change in the hardware platform OBJ 800 feeds when you consider its stretch marks.
I thought I had already blogged about this, but I can’t find the old posts, so here goes. The big question: why can’t we have “X” in the OBJ file format or as part of generic instruments?
I get a lot of requests for “more power” in the OBJ or generic instrument system – the ability to play sounds, to do simple math operations on datarefs, more show-hide filters, the ability for a generic instrument to change a dataref in response to another dataref instead of a mouse click.
And invariably I say “No! Go write a plugin!”, which I realize is a fairly rude thing to say to a non-programmer. First, let me explain why I say no, and then what we can do about this.
Keeping Systems Separate
These feature requests fall into two broad categories: “systems programming”, which is really anything that has a side effect (play a sound, change a dataref, apply some logic), and “visualization” (e.g. a user needs more flexibility to better visualize the sim’s state.
I definitely do not want any kind of “systems modeling” code inside OBJs or generic instruments. To give a trivial example: imagine that you could make a generic instrument that would set the generators to on when the landing gear is raised.
What then happens if this generic instrument is off the bottom of the screen when the landing gear is raised? Does the generic instrument get to perform its logic? Both OBJs and generic instruments are fundamentally “visualization” systems – both will short-circuit for performance when they are not visible. If we put systems modeling code into them, then the sim has to evaluate a potentially large number of otherwise unimportant (non-visible) objects and instruments to do system behaviors.
In computer programming, there is the notion of a “model-view-controller” design. The basic idea is to keep the code that changes the model, the model itself, and the code that lets the user see the data model, all separate. Keeping them separate keeps operation consistent – the model does not change its behavior depending on how you look at it, which is very important for consistent simulation.
So for all systems modeling, my answer is always the same: not in viewing code!
Expressions and Visualization
Some requests are simply requests for more visualization complexity – there is only so much you can do with key frames, animation, and a few filters.
I do have to admit that on some level, it is perfectly reasonable to ask for infinite power to visualize data in OBJs and generic instruments.
On the other hand, there would be a real cost to having programming-language complexity in what are otherwise relatively simple-to-use parts of X-Plane (e.g. the simplest model is just an export from ac3d…). My solution for both problems (systems and visualization) is a scripting system, but in the case of visualization, it is about not reinventing the wheel and keeping complexity limited to one place (the scripting system).
Scripting
Plugins have the power to solve all of these problems – they can change almost any aspect of the sim. But they are also very difficult to create; you need to be a programmer who knows a language like C or Pascal, and you need to know how to use the development tool for each platform you want to support. That’s a huge amount of specialized knowledge just to customize a few systems.
Basically we need to have a line in the sand. At some point, when the systems to visualize information (OBJ, generic instruments) are not powerful enough, we need to make programming easier, rather than make modeling and authoring more complex.
What we need is a scripting system. The scripting system would provide a relatively simple text-file syntax to do simple scripting of systems and instruments for airplanes.
Such a scripting system should be implemented as an open source plugin; it should not be built into X-Plane. The advantage of this would be:
Who should work on this scripting system? I don’t know. Probably not me — I am not very good at making simple systems; see also what a complex disaster the panel and instrument system has become!
When a user requests that I add a feature to the generic instrument system, there is an implicit request – that Austin or I take programming time to do the feature. So for now I can only say that if/when I take time to do some of these feature requests, it will be in the form of a scripting system, not as extensions to the generic instrument and OBJ systems. This will give us better long-term compatibility and extensibility (via an open source plugin) and will keep systems modeling code separate from the visualization system.
930 will have some new options for attached objects. One is to declare a “glass” object. When an object is declared to be glass, it is moved to the very end of the drawing order – even after the cockpit object.
The 921 draw order has the exterior cockpit object drawn first (if drawn) and the interior cockpit object drawn last (if drawn). This made sense at the time – the exterior cockpit object was being used primarily for a pilot figure, with windows in the ACF paint – so it had to be drawn before the ACF fuselage. The interior cockpit object has to be drawn last because the coordinate system is changed to a super-close-to-the-user coordinate system that has to be drawn last.