AADevLog #0 - IEEE and STL 3D file format
This is the first in a loose series of developer logs about projects I'm working on, from little experimental or example code, to more complex ideas. On my quest to create some proper Amiga software - a game! - I have encountered, and will encounter, lots of challenges.
After a steep learning curve and endless hours of failure, finally there is some usable success - yay! ;-) Over the years I've started many ambitious projects, but all of these turned out to be quite a mess. I realized I needed more basic knowledge and better testing of individual code sections, along with improving my concepts of software architecture. So basically while learning more details about how to use C and AmigaOS, my main task was to scale down my ideas and get stuff to work together properly, so I don't end up with countless individual functions each doing only half-way what's required - in other words: a mess.
Ok, long story short, with "a little bit" (cough) of prior training, I'll just share some of my experience, starting with something created recently, over a couple of days:
|First version of "stl_info" for Linux and AmigaOS|
It's called "stl_info", prints out information about an STL 3D file (binary format, as exported by e.g. Blender), and works on Linux and AmigaOS. For Linux, gcc is used for compilation, for Amiga it's vbcc (on Linux, cross-compiling). Currently the number format printed out is a bit weird (for debugging) - just think of the comma as a ".", and omit the "0." (zero integer part of float fraction).
Nothing too spectacular, but maybe a first step towards 3d printing on the Amiga? Anyway, apart from reading some header bytes from the STL file, then some 32bit numbers, etc. there were two slightly more interesting things about developing the program:
First, long numbers and the endianness thing. To make sure number storage would be identical on both my 64-bit Linux computer and the Amiga I've created a header file called "amigatypes.h" that defines e.g. ULONG as 32 bits like on the Amiga, WORD as 16 bits, etc. Still the byte order is incompatible: my Linux computer is an Intel x86, so it looks at it's bytes least-significant-first, called little-endian, or Intel-byte-order. The Amiga is a Motorola M68000, and looks at it's bytes the other way round, most-significant-first, called big-endian, or Motorola-byte-order. I tried to get around this somehow, but I ended up adding some separate code that swaps bytes around (see picture: bytereverse.c), and is activated in source code by a compiler define "AMIGA".
And then, IEEE754 numbers. In an STL binary file, Vertex coordinates are stored in IEEE754 floating point number format. (LSB first, part of the file format definition.) If you want to use this number format on AmigaOS as a float datatype, you'll probably be fine with the conversion function "SPFieee()" provided by mathtrans.library, but I wanted to be able to decode IEEE numbers to some custom format, something fixed-point, maybe for a future... game! IEEE numbers are made of three sections of bits: sign, exponent, and mantissa. I won't go into detail here, you can look it up (see links below) if you like. It looks a bit complicated on first sight, but once you work yourself through the individual steps of decoding, you realize: the exponent is just the bit-shift of the mantissa. It looks complicated when expressed as decimal-based math, but is pretty obvious in binary, and probably creates a useable fixed-point fraction. That's nice. Yes, there are more bits involved, you have to do a little bit of fiddling, but the exponent-bit-shift is really neat, feels super binary. (Well, it is.) :-)
If you're interested in IEEE754 here are some links:
So far for the first AADevLog - c u next time!