8. Table mesh

A table mesh inherit from renderizable and implement all methods as usual.. Each animation on mesh has an initial frame and final frame which represent its cycle. Also each animation has a shader table by default which can be accessed by getShader method.

8.1. mesh methods

8.1.1. mesh new

new(string * world, number * x, number * y, number * z)

Create a new instance of a mesh passing the world desired (detail) and position.

Parameters
  • stringworld can be 2ds, 2dw or 3d.

  • numberx position (optional).

  • numbery position (optional).

  • numberz position (optional).

Returns

mesh table.

Example:

tMesh = mesh:new('3d') --note that mesh inherits from renderizable

8.1.2. mesh load

load(string file_name)
Load a mesh from a binary file (expected .msh extension).
Parameters

stringfile name from binary file.

Example:

tMesh = mesh:new('3d')
if tMesh:load('crate.msh') then
   print('Successfully loaded mesh:','crate.msh')
else
   print('Failed to loaded mesh:','crate.msh')
end

Note

The load method will search in all known path.
You can add a path to search by the method addPath.

If you want to create a binary file next an example how to do that.

8.2. Creating a mesh programmatically

It is possible to save any mesh with help of meshDebug. For that it is necessary to prepare the meshDebug based on our renderizable.

  • First, we have to create coordinates of vertex buffer (indexed buffer based).

  • We also need to create index buffer (1 index based) for the vertex.

  • Then we create a meshDebug which will store all the information.

  • The UV and normal coordinates are not mandatory. For this example we will not fill it.

  • Next we create a frame informing the stride and add a new subset.

  • One frame can have one or more subsets. Each subset has its own texture.

  • Next we add the vertex buffer and index buffer.

  • The vertex buffer can have normal buffer (optional) and texture coordinates (optional).

  • Next we set the mesh type (others types are sprite, particle, font, …).

  • Finally we just need to specify the file name to save through the function save.

For the next examples we will use the following texture:

_images/crate.png

Figure 8.1 crate.png

8.2.1. Mesh to a binary file

Follow an example how to save a mesh to a binary file:

  1 mbm.setColor(1,1,1) --set background color to white
  2 
  3 function createCubeFace()
  4 
  5    local tCube = {  {x=-50,y=-50,z=0}, 
  6                     {x=-50,y=50,z=0}, 
  7                     {x=50,y=-50,z=0}, 
  8                     {x=50,y=50,z=0}}
  9    local tIndex = {1,2,3, 3,2,4}
 10    local sTextureFileName = 'crate.png'
 11 
 12    return tCube, tIndex, sTextureFileName
 13 end
 14 
 15 function saveMeshToBinaryFile(fileName,tVertex,tIndex,sTexture)
 16 
 17     --meshDebug is used to create dynamically mesh in the engine.
 18     --For mesh it has to have at least one frame to be able to generate the mesh
 19     local stride      = 3 --stride only can be 3 or 2. it means (x,y,z) or (x,y)
 20     local tMesh       = meshDebug:new() --new mesh debug to store the information about our mesh
 21     local nFrame      = tMesh:addFrame(stride) -- Add one frame with stride 3 (x,y,z)
 22     local indexFrame  = nFrame   --(meshDebug uses 1 based index)
 23     local indexSubset = 1 --first subset (1 based index)
 24    
 25    
 26     --To add vertex, first we need to add a subset
 27     local nSubset     = tMesh:addSubSet(indexFrame) --add one subset for the first frame
 28 
 29     --we are adding vertex to frame (next)
 30     --this vertex list has to have at least 3 vertex (one triangle) to be valid
 31     -- The table expected is : {{x,y,z},{x,y,z},{x,y,z}, ...}
 32     if not tMesh:addVertex(indexFrame,indexSubset,tVertex) then 
 33         print("Error on add vertex buffer")
 34         return false
 35     end
 36     
 37     if not tMesh:addIndex(indexFrame,indexSubset,tIndex) then 
 38         print("Error on add index buffer")
 39         return false
 40     end
 41 
 42     --apply the texture to frame / subset
 43     if not tMesh:setTexture(indexFrame,indexSubset,sTexture) then
 44         print("Error on set texture!")
 45         return false
 46     end
 47 
 48     tMesh:setType('mesh')  -- set it to mesh type
 49 
 50     local calcNormal,calcUv = true,true --Instruct to calculate normal and UV
 51     if tMesh:save(fileName,calcNormal,calcUv) then
 52         print("Mesh created successfully ")
 53         return true
 54     else
 55         print("Failed to create Mesh!")
 56         return false
 57     end
 58     
 59 end
 60 
 61 
 62 function onInitScene()
 63 
 64     tMesh = mesh:new('3D')-- our object which will load from binary file
 65 
 66     local sFileNameMesh = 'crate.msh'
 67 
 68     local tCubeVertex, tCubeIndex, sCubeTextureFileName = createCubeFace()--create our cube face 
 69 
 70     if saveMeshToBinaryFile(sFileNameMesh,tCubeVertex, tCubeIndex, sCubeTextureFileName) then
 71         tMesh:load(sFileNameMesh) --all coordinate already in place
 72     else
 73         print('Failed to create ' .. sFileNameMesh)
 74         mbm.quit()
 75     end
 76 
 77 
 78     --set up camera
 79     camera3d = mbm.getCamera('3D')
 80     camera3d:setPos(0,0,-500)
 81     camera3d:setFocus(0,0,0)
 82 
 83     --need to rotate our object
 84     tMouse = {x=0,y=0,clicked = false}
 85 end
 86 
 87 function onTouchDown(key,x,y)
 88     tMouse.clicked = true
 89     tMouse.x = x
 90     tMouse.y = y
 91 end
 92 
 93 function onTouchMove(key,x,y)
 94     if tMouse.clicked then
 95         local diff_X = tMouse.x - x
 96         local diff_Y = tMouse.y - y
 97         tMouse.x = x
 98         tMouse.y = y
 99 
100         --simple rotation based on mouse
101         tMesh.ay = tMesh.ay + math.rad(diff_X)
102         tMesh.ax = tMesh.ax + math.rad(diff_Y)
103 
104     end
105 end
106 
107 function onTouchUp(key,x,y)
108     tMouse.clicked = false
109 end

download.

_images/mesh_flat.gif

Figure 8.2 Mesh flat simple (two triangles)

8.2.2. Create a cube and fill the texture coordinates

For the next example we will create a cube and fill it with our texture coordinates.

mbm.setColor(1,1,1) --set background color to white

function createCube(width,height,depth)
--[[
k-uv=1,1
    uv=0,0-f________________g-uv=1,0, i-uv=0,1
           /               /|
          /               / |
uv=0,1-b /_______________/c-uv=1,1
        |   |           |   |
        |   |           |   |
        |   |   back    |   |
    uv=0,1-e|___________|___|h-uv=1,1  j-uv=0,0
 l-uv=1,1  /            |  /
        | /             | /
        |/______________|/
 uv=0,0-a   front       d-uv=1,0

]]--

    local halfSizeCube = { x = width / 2, y = height / 2, z = depth / 2}

    local  pa = {x = -halfSizeCube.x,  y = -halfSizeCube.y,  z = -halfSizeCube.z, u = 0, v = 0};
    local  pb = {x = -halfSizeCube.x,  y =  halfSizeCube.y,  z = -halfSizeCube.z, u = 0, v = 1};
    local  pc = {x =  halfSizeCube.x,  y =  halfSizeCube.y,  z = -halfSizeCube.z, u = 1, v = 1};
    local  pd = {x =  halfSizeCube.x,  y = -halfSizeCube.y,  z = -halfSizeCube.z, u = 1, v = 0};
    local  pe = {x = -halfSizeCube.x,  y = -halfSizeCube.y,  z =  halfSizeCube.z, u = 0, v = 1};
    local  pf = {x = -halfSizeCube.x,  y =  halfSizeCube.y,  z =  halfSizeCube.z, u = 0, v = 0};
    local  pg = {x =  halfSizeCube.x,  y =  halfSizeCube.y,  z =  halfSizeCube.z, u = 1, v = 0};
    local  ph = {x =  halfSizeCube.x,  y = -halfSizeCube.y,  z =  halfSizeCube.z, u = 1, v = 1};

    --extra because of the texture coordinates
    local  pi = {x =  halfSizeCube.x,  y =  halfSizeCube.y,  z =  halfSizeCube.z, u = 0, v = 1};
    local  pj = {x =  halfSizeCube.x,  y = -halfSizeCube.y,  z =  halfSizeCube.z, u = 0, v = 0};

    local  pk = {x = -halfSizeCube.x,  y =  halfSizeCube.y,  z =  halfSizeCube.z, u = 1, v = 1};
    local  pl = {x = -halfSizeCube.x,  y = -halfSizeCube.y,  z =  halfSizeCube.z, u = 1, v = 0};

    local  tCube = {pa,pb,pc,pd,pe,pf,pg,ph,pi,pj,pk,pl};

    local a,b,c,d,e,f,g,h,i,j,k,l = 1,2,3,4,5,6,7,8,9,10,11,12

    local tIndex = { a,b,d, d,b,c, -- front
                     d,c,i, d,i,j, -- right
                     a,l,k, k,b,a, -- left
                     h,g,e, e,g,f, -- back
                     b,f,c, c,f,g, -- top
                     a,d,e, h,e,d  -- bellow
                    }
    local sTextureFileName = 'crate.png'

   return tCube, tIndex, sTextureFileName
end

function saveMeshToBinaryFile(fileName,tVertex,tIndex,sTexture)

    --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 nFrame      = tMesh:addFrame(stride) -- Add one frame with stride 3 (x,y,z)
    local indexFrame  = nFrame  --(meshDebug uses 1 based index)
    local indexSubset = 1 --first subset (1 based index)
   
   
    --To add vertex, first we need to add a subset
    local nSubset     = tMesh:addSubSet(indexFrame) --add one subset for the first frame

    --we are adding vertex to frame (next)
    --this vertex list has to have at least 3 vertex (one triangle) to be valid
    -- The table expected is : {{x,y,z},{x,y,z},{x,y,z}, ...}
    if not tMesh:addVertex(indexFrame,indexSubset,tVertex) then 
        print("Error on add vertex buffer")
        return false
    end
    
    if not tMesh:addIndex(indexFrame,indexSubset,tIndex) then 
        print("Error on add index buffer")
        return false
    end

    --apply the texture to frame / subset
    if not tMesh:setTexture(indexFrame,indexSubset,sTexture) then
        print("Error on set texture!")
        return false
    end

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

    local calcNormal,calcUv = true,false --Instruct to calculate normal
    if tMesh:save(fileName,calcNormal,calcUv) 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 sFileNameMesh = 'crate.msh'

    local width, height, depth = 100, 100, 100

    local tCubeVertex, tCubeIndex, sCubeTextureFileName = createCube(width, height, depth)--create our cube 

    if saveMeshToBinaryFile(sFileNameMesh,tCubeVertex, tCubeIndex, sCubeTextureFileName) then
        tMesh:load(sFileNameMesh) --all coordinate already in place
    else
        print('Failed to create ' .. sFileNameMesh)
        mbm.quit()
    end


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

    --need 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

download.

_images/mesh_cube.gif

Figure 8.3 Mesh cube 3D filled with texture coordinates

8.3. Importing mesh

You can find how to Import mesh and also some examples in the modules topic.

There you will find some tips and ready to use modules.