24. Modules

This section has a lot of modules available and where I hope would be useful for you!

Even if you are learning LUA this is a interesting topic.

Have fun!

24.1. What is a Module?

Module is like a library that can be loaded using require and has a single global name containing a table.

All functions and variables are wrapped in to a table which acts as a namespace. Also, a well behaved module has necessary provisions to return this table on require.

Module can be an .lua , .Dll or .so extension.

A module can be an external extension for the project or not.

For example, we can consider to build a module that will use some resources from this engine like a vec3, particle system, blend operation , etc.

In another words, a modules can be an extension about what we have.

The next topics will present some modules available.

24.1.1. Creating and using Modules

The way for LUA 5.2 create module is described bellow:

First, we will create a file mymodule.lua with the following content:

local mymodule = {}

function mymodule.foo()
    print("Hello World from module!")
end

return mymodule

This is the basic concept of modules.

Now to use this new module in the interactive interpreter:

mymodule = require "mymodule"
mymodule.foo() -- Hello World from module!

For more information you can consult ModulesTutorial.

24.2. Parsing OBJ wavefront

Next we will demonstrate how to import from OBJ format using a modules written in LUA.

OBJ (or .OBJ) is a geometry definition file format first developed by Wavefront Technologies for its Advanced Visualizer animation package. The file format is open and has been adopted by other 3D graphics application vendors.

The parser implemented here might NOT be the fully implementation but at least for this example works.

To do that we will use the following module: OBJ_parser.lua

You can download OBJ_parser.lua here.

The following program will use the OBJ_parser.lua to parse an OBJ format and generate a mesh my_mesh.msh:

--import our module OBJ parser
OBJ_parser = require "OBJ_parser"

--gray color background
mbm.setColor(0.5,0.5,0.5)


function saveFrameToMeshFile(fileName,tFrame,bCentralize)

    --meshDebug is used to create dynamically mesh in the engine.
    --For mesh it has to have at least one frame to be able to generate the mesh
    local stride      = 3 --stride only can be 3 or 2. it means (x,y,z) or (x,y)
    local tMesh       = meshDebug:new() --new mesh debug to store the information about our mesh
    local indexFrame  = tMesh:addFrame(stride) -- Add one frame with stride 3 (x,y,z)

    local has_normal  = OBJ_parser:has_normal(tFrame)
    local has_texture = OBJ_parser:has_texture(tFrame)

    print('Total subset:',#tFrame)
    print('Normal      :',tostring(has_normal))
    print('Uv          :',tostring(has_texture))

    -- Add vertex buffer first
    for i=1,#tFrame do
       local tSubset = tFrame[i]

        --add each subset on frame
        local indexSubset  = tMesh:addSubSet(indexFrame) --add one subset for the first frame

        -- The table expected is : {{x,y,z,u,v,nx,ny,nz},{x,y,z,u,v,nx,ny,nz},{x,y,z,u,v,nx,ny,nz}, ...}
        if not tMesh:addVertex(indexFrame,indexSubset,tSubset.tVertex) then 
            print("Error on add vertex buffer")
            return false
        end
    end

    --Now we add index buffer and apply the texture
    for indexSubset=1,#tFrame do
        local tSubset = tFrame[indexSubset]
        if not tMesh:addIndex(indexFrame,indexSubset,tSubset.tIndex) then 
            print("Error on add index buffer")
            return false
        end

        --get texture (among the choices in the material)
        local sTexture = OBJ_parser:get_texture_from_material(tSubset.tMaterial)
        
        --apply the texture to frame / subset
        if not tMesh:setTexture(indexFrame,indexSubset,sTexture) then
            print("Error on set texture!")
            return false
        end
   end

    tMesh:setType('mesh')  -- set it to mesh type

    --Advanced options (draw mode). we do not need to set it, but it is available
    --tMesh:setModeDraw('TRIANGLES') -- TRIANGLES (default), TRIANGLE_STRIP, TRIANGLE_FAN, LINES, LINE_LOOP, LINE_STRIP, POINTS
    --tMesh:setModeCullFace('FRONT') -- FRONT     (default), BACK, FRONT_AND_BACK
    --tMesh:setModeFrontFace('CCW')  -- CCW       (default), CW, 


    if bCentralize then
        print('centralizing mesh...')
        tMesh:centralize() --centralize all subsets before save
    end

    if tMesh:save(fileName,not has_normal,not has_texture) then
        print("Mesh created successfully ")
        return true
    else
        print("Failed to create Mesh!")
        return false
    end
    
end


function onInitScene()

    tMesh = mesh:new('3D')-- our object which will load from binary file
    local bCentralize = true

    local sFileNameMesh = 'Mech.msh' --output file (msh for mesh 3D)
    local sFileNameOBJ = 'Mech.obj'  --input OBJ file
    
    local bResult , tFrame = OBJ_parser:parse_file(sFileNameOBJ)


    if bResult and saveFrameToMeshFile(sFileNameMesh,tFrame,bCentralize) then
        tMesh:load(sFileNameMesh) --all coordinate already in place
    end

    --set up camera
    camera3d = mbm.getCamera('3D')
    camera3d:setPos(0,0,-500)
    camera3d:setFocus(0,0,0)

    --needed to rotate our object
    tMouse = {x=0,y=0,clicked = false}
end

function onTouchDown(key,x,y)
    tMouse.clicked = true
    tMouse.x = x
    tMouse.y = y
end

function onTouchMove(key,x,y)
    if tMouse.clicked then
        local diff_X = tMouse.x - x
        local diff_Y = tMouse.y - y
        tMouse.x = x
        tMouse.y = y

        --simple rotation based on mouse
        tMesh.ay = tMesh.ay + math.rad(diff_X)
        tMesh.ax = tMesh.ax + math.rad(diff_Y)

    end
end

function onTouchUp(key,x,y)
    tMouse.clicked = false
end

function onTouchZoom(zoom)
    --Zoom the 3D object 
    tMesh.sx = tMesh.sx + (0.2 * zoom)
    if tMesh.sx <= 0.2 then 
        tMesh.sx = 0.2
    end
    tMesh.sy = tMesh.sx
    tMesh.sz = tMesh.sx
end

download.

_images/importing_OBJ_example_1.gif

Figure 24.1 Mesh 3D from OBJ

download OBJ. download material. download texture.