Cylindrical billboarding woes
In this article, I explain how I hackishly added cylindrical billboarding support to OoT.
First, some background. If you’ve ever ported a map from Majora’s Mask to Ocarina of Time, chances are you’ve seen missing or misplaced map meshes.
“What causes this?”, you might ask yourself. Let’s inspect the display list in a hex editor and find out.
DA380001 01000040 may catch your attention. These bytes push the matrix
01000040 onto the stack. Ocarina of Time does this all the time for billboards like Navi, bombs, the sun, and the moon, but that’s with matrix
01000000. What’s so special about matrix
01000040? Let’s substitute one for the other and see what happens.
Perfect, everything works now. Case closed. Except, not really. How do these look from above?
Oh no, they are locked to face the camera from all angles! You’ll get problems with these posts anytime the camera is looking up or down. When the camera isn’t level, something is noticeably wrong with them.
It turns out that all objects using matrix
01000000 (Navi, bombs, the sun, the moon, and more) have one thing in common: they face the camera no matter what angle you view them from. We call this a spherical billboard.
After inspecting the behavior of matrix
01000040 in Majora’s Mask, we conclude that all objects that use it are always upright. The objects are still forced to face the camera, but the world’s up direction is always respected, so not on that axis. This is called a cylindrical billboard.
You can witness the difference for yourself outside the Astral Observatory in Majora’s Mask. It turns out, one of the stars uses a spherical billboard and the other uses a cylindrical billboard. Perhaps the cylindrical billboard matrix was added late in the game’s development and they forgot to update this one.
“But Ocarina of Time does that too! What about the flame actors?”, you may be thinking. This was very boggling, but it turns out actors that do this in OoT calculate their position relative to the camera and rotate the models so they align to the camera on all axes besides Y (up). In this sense, OoT does cylindrical billboards, but not via a global matrix. We cannot apply this hack on maps.
Since OoT does not create this matrix,
01000040 is junk data. This explains why the map parts that referenced it were floating around strangely.
Now, to write an assembly hack that will create a cylindrical billboard matrix that will be accessible in maps and objects by pushing matrix
01000040 onto the stack, like in MM. Do so without overwriting or breaking the matrix
To save you a long story detailing all the trouble it was and how it still isn’t perfect, I’ll just say that it’s usable for the purposes I intended for it to be usable for.
As an additional test, I modeled a lamppost and embedded it into Kokiri Forest’s geometry.
The lower right image is a screenshot from Killgore52 (aka E-Gor) showing that the assembly and mesh are hardware compatible. Thanks man!
Finally, here’s a zip containing the modified
spot04_scene. Do a file comparison between this
code and the original to find what has changed. Some notes are also embedded within. If you improve upon it (it needs it), please share your fixes so everyone can use cylindrical billboards that have been refined as much as possible.
* Because content was added to Kokiri Forest, its size increased, so keep that in mind when putting it in the rom for testing!