Procedural Model 3D Files ========================= [[_TOC_]] Binding with Script Interpreters -------------------------------- Textures and meshes can be generated by scripts, but Model 3D does not specify which scripting language to use. You have to tell by providing an interpreter function by using the `M3D_TX_INTERP` and `M3D_PR_INTERP` defines before you include the m3d.h implementation. To support multiple languages, you have to pass an interpreter function that detects the script's type (either from the extension in the name, or by looking at the script itself, which can be bytecode with magic bytes) and passes it to the right interpreter functions accordingly. Most engines are happy with supporting one scripting engine, and M3D does not want to tell you which one that should be. ### Procedural Texture Generation ```c int (*m3dtxsc_t)(const char *name, const void *script, uint32_t len, m3dtx_t *output); #define M3D_TX_INTERP mytextureinterp ``` This function receives a `script` by the name `name` and should fill in width, height, format and data in `output` texture and return error code. Without a texture script interpreter configured, model importer will return `M3D_ERR_UNKIMG` error code. These scripts are referenced in the model files in material properties as if they were a normal static texture images. ### Procedural Surface Generation ```c int (*m3dprsc_t)(const char *name, void *script, uint32_t len, m3d_t *model); #define M3D_PR_INTERP mysurfaceinterp ``` This function receives a `script` by the name `name` and should adjust `model->numface`, allocate and fill in array elements in `model->face`. If needed, it can adjust `model->numvertex` and add elements to the `model->vertex` array too. Returns error code. Without a surface script interpreter configured, model importer will return `M3D_ERR_UNIMPL` error code. These scripts are referenced from "Procedural" chunks, which replace the "Mesh" chunks. Lua Binding for Model 3D ------------------------ As a Proof of Concept, the SDK contains [m3d_lua.h](https://gitlab.com/bztsrc/model3d/blob/master/m3d_lua.h), which provides [Lua language](https://www.lua.org) bindings in Model 3D files. To use it, you have to include the header in the source file which has the m3d implementation: ```c #include /* enable Lua scripts in models */ #define M3D_IMPLEMENTATION #include ``` That's all, now you can load Model 3D files with scripts inside using exactly the same [m3d_load API](https://gitlab.com/bztsrc/model3d/blob/master/docs/API.md). No need to modify your engine! You'll need to dynamically link with the lua library though. ### Texture Generator Lua Scripts These are pretty simple, can be referenced from materials in "map_" properties. They should return a table with integer values. The first item in the table is the texture's width (used as `output->w`), the second is the height (`output->h`), the third is the number of components (`output->f`, 1 = grayscale, 2 = grayscale with alpha, 3 = rgb, 4 = rgba) and the rest is the pixel data (`output->d`), width times height items. ### Surface Generator Lua Scripts These are referenced from "Procedural" chunks. They receive a library, which can be used to add triangles to the existing surface. The library's functions are very similar to Wavefront OBJ's statements, but their arguments are calculated and they're called in run-time. | Lua Function | OBJ equivalent | Description | |-------------------------------------------------------------|---------------------|----------------------------------------------------| | `vertexIndex = m3d.getVertex(color, x, y, z, w)` | v or vn | returns the vertex index for the given coordinates | | `uvIndex = m3d.getUV(u, v)` | vt | returns the UV index for the given coordinates | | `m3d.useMaterial(material name)` | usemtl | sets the material given by material name string | | `m3d.addTriangle(v1, v2, v3)` | f v v v | adds a simple triangle using 3 vertex indices | | `m3d.addTriangleUV(v1, uv1, v2, uv2, v3, uv3)` | f v/t v/t v/t | adds triangle with UV coordinates | | `m3d.addTriangleN(v1, n1, v2, n2, v3, n3)` | f v//n v//n v//n | adds triangle with normals | | `m3d.addTriangleUVN(v1, uv1, n1, v2, uv2, n2, v3, uv3, n3)` | f v/t/n v/t/n v/t/n | adds triangle with UV coordinates and normals |