A big part of creating the SOUR format was writing a parser to get the models into Away3D. (A parser is a part of a program which reads data in a storage format and changes it into a usable format.) In this article, I’m going to go through the basics of writing an Away3D parser.
An Away3D parser has six fundamental functions you need to use:
- the constructor and super() in it
The Parent Class: ParserBase
You’ll need to extend Away3D’s ParserBase class to get access to the functions mentioned above, and to make your parser compatible with the AssetLibrary.
Like any AS3 constructor, the constructor function will have the same name as a parser class. So for our parser, SOURParser, the constructor is SOURParser(). The only thing you need to worry about doing in the constructor (though you can do more if you so choose) is using the super() function. ParserBase, the parent class, takes a single argument, either ParserDataFormat.PLAIN_TEXT or ParserDataFormat.BINARY, depending on what kind of 3D file is being parsed.
Away3D parsers attempt to determine whether the data being fed to them is compatible in two ways: by examining the file extension and by checking the contents of the file for certain strings which are a part of the file’s formatting. supportsType() does the former and supportsData() the latter. Both return a boolean. Override them and modify them as is appropriate for your 3D file format.
The Actual Parsing
How a parser reads your data is really up to you. For SOUR, I chose to do a line-by-line approach in a while loop, much like the OBJ parser does. All the parsing gets done in proceedParsing().
One nice feature of Away3D’s ParserBase though, is that it has the hasTime() function, which allows you to do the parsing over the course of several frames rather than all at once. Why does that make a difference? If you’re attempting to read a file all at once and the file is too large to be processed in the time in between frame renders, the parsing will continue until it’s done and THEN the next frame will get rendered, causing frame loss. Using hasTime(), you can determine if you’ve exceeded the time limit between frames yet, in order to break the job of parsing down into smaller pieces, and not lose frames. If everything gets preloaded, it won’t make a difference, but if some assets are loaded on the fly, it’s rather important.
When you finish reading data from your 3D file and reconstructing it as a Mesh, Geometry, Animation, Texture, etc., you’ll want to pass that 3D-formatted data back to your application. You do that with finalizeAsset(), which takes the data itself, automatically figures out the AssetType, and delivers it back to your application via an AssetEvent. The process of turning a 3D file into Mesh data is the subject of another article.