Loading Up Models
The Hard Way
The hard way to do this is to manually generate an Urho VertexElement array and attach the model vertex and normal data, linking a VertexBuffer and IndexBuffer through a Geometry element.
This approach works, and there's an example of it in the sample application 34_DynamicGeometry.as, but it's fiddly and my implementation is error prone. So let's not do that.
The Easier Way
The simplest way to do this is to use the AssetImporter tool from the Urho3D distribution. This can take an OBJ format file, which we can generate easily, and produce output files that Urho3D can load directly. It adds an extra step, but simplifies the process.
So we generate the OBJ file format files as we do in the existing C++ code, and then use the fileSystem.SystemRun() call in AngelScript to shell out to the AssetImporter binary. There's code in the default Urho EditorImport.as application that we can use more or less directly for a prototype, that handles assembling the command line and also tacks on the .exe extension for windows. We'll replace this at some point, but for now let's just use it as is for the demo.
Otherwise there really isn't much clever here - we reimplement the ZFS unpacker in Angelscript to extract the resources, then we can view either individual models from GEO files, or complete vehicle assemblies from the VDF file. Extracting from the ZFS takes several minutes, and so the app should be run windowed, and the terminal will report the progress of the unpack. We could implement a background loader, but it's not worth the effort for a run-once process like this.
The only other annoyance is that the floating point output from AngelScript threw up errors with the AssetImporter by default - small values will be represented by scientific format (e.g. 3.3021e-05) and the importer doesn't like some of these, and there didn't seem to be a way to format the output more precisely. So we spot small values and treat these as exactly zero when we write them out.
- AssetLoader: assetLoad.as - Load a ZFS file, and unpack the ZFS itself, embedded PAK files and do the basic conversion for GEO to objects and VQM to texture images.
- ObjLoader: ObjLoad.as - View individual object files. Does on the fly conversion.
- CarLoad: CarLoad.as - Load VDF files - this has some issues (the tendency to mess up interior geometry fragments, and some normals are iffy), but it's functional enough to pull out some basic geometry for the composite models.
The conversion process just applies a default image file for testing at present (whichever image you copy into Textures/test.png), and requires a defaultmat.xml Material file. It's lacking basic error checking, but as a proof of concept it holds together.
Also this will not work on the Nitro ZFS, since AngelScript doesn't know how to decompress the LZO compressed files without the platform specific libraries.
Otherwise, it mostly sorta works...
AngelScript: Some ThoughtsHaving used AngelScript for a few days then the thoughts that keep cropping up are
- Fast Prototyping.
- Straightforward UI & 3D implementation.
- Feature rich primitives.
- Syntax: maps neatly to C++ versions.
- No debugger: This is a real PITA. The code has wound up with debug Print calls scattered around.
- Silent Failures: Some setup errors leave things silently non functional, rather than producing more obvious error reports.
- Slow: Although the heavy lifting is mostly done by the core engine having scripts generate things like texture images and bitmap resources can result in major slowdowns.
- Ownership: The Urho Angelscript version uses reference counting for memory management, but without a debugger it's easy to lose track of what references are valid at times and leak resources (such as open file handles).
- Not Quite Vanilla AngelScript: Enough custom types that the default AS docs don't always seem to apply directly or help understand Urho's use of the language.
- Documentation: It's there, but not always useful, and the examples take some parsing to understand: it could be better.
- No Printing Format control? I couldn't figure out how to persuade floats to output in a specific format, hence the low value rounding utility.