Table of Contents
10. 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.
10.1. mesh methods¶
10.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
string – world can be
2ds,2dwor3d.number – x position (optional).
number – y position (optional).
number – z position (optional).
- Returns
mesh table.
Example:
tMesh = mesh:new('3d') --note that mesh inherits from renderizable
10.1.2. mesh load¶
- load(string file_name)
- Load a mesh from a binary file (expected
.mshextension).- Parameters
string – file 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
10.1.3. mesh loadAsync¶
- loadAsync(string file_name, function callback)
- Load a mesh from a binary file (expected
.mshextension) the same way load does, but the file reading and parsing happens on a background thread instead of blocking the caller.Thecallbackis always invoked from the main thread on a later frame, never inline, so it is safe to touch any other engine object from inside it.- Parameters
string – file name from binary file.
function – callback invoked as
callback(self, success)once the load finishes, whereselfis the mesh object itself andsuccessis aboolean.
Example:
tMesh = mesh:new('3d')
tMesh:loadAsync('crate.msh', function(self, success)
if success then
print('Successfully loaded mesh:','crate.msh')
else
print('Failed to loaded mesh:','crate.msh')
end
end)
Note
self and to the callback until the load finishes, so the
mesh object stays alive even if the script drops every other reference to it before that.If you want to create a binary file next an example how to do that.
10.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
meshtype (others types aresprite,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:
Figure 10.1 crate.png¶
10.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
Figure 10.2 Mesh flat simple (two triangles)¶
10.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
Figure 10.3 Mesh cube 3D filled with texture coordinates¶
10.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.