Context: I am trying to do real time update of a mesh. More precisely, let’s say i want to recompute the vertices of a mesh. There are two parts there: 1/ recompute a table ‘‘vertices’’, and 2/ send the vertices table via the ‘‘mesh.vertices = vertices’’ chunk. I am concerned by the step 1/ here. I have seen that my step 1 takes 2s, so i have decided to split it in 1000 steps of 2ms, each done during one frame, the next one done in the next frame, etc… This will not accelerate the update, but it will not block the ipad for 2s, and the game should still run at 50fps instaed of 60fps, which is good enough for me. But i found that my slicing of the update seems to have a strong overhead, since i cannot go faster than 15fps (without update it runs 60fps). I don’t see the source of this overhead cost. I wonder if it might come from the fact i use functions that return tables?
So this leads me to my question: when you write ‘‘return vertices’’ at the end of a function, do you get a/ the whole table being returned (the table values) or b/ simply the adress of the table (a pointer to the table)? I thought it was b/, but i cannot find this info in the lua doc that is in the reference. Can someone clarify this for me?
ps: i dont post he code cause there would be so much clean up needed…
btw, for 2/ i had the idea to split my mesh of 10000 vectors in 100 small meshes of 100 vectors, and do a step by step update as above. But i have read in an old post from Simeon that when a mesh is created, 3000 vec3 places a reserved for it in the memory. Is it still the case? If yes, what happen when i define mesh.vertices = vertices with #vertices = 100? Is the extra memory freed? If not then my solution will be not feasible, cause it would xplode the ipad memory…
All Lua types except number, boolean, and nil are always passed/returned by reference, you are correct about that. Even if the code is messy, without seeing it it’s really hard to tell where you are taking a performance hit. Is your function being called many times? Is your function creating a table and returning it each time it’s called?
Edit: documentation on reference types is here: http://www.lua.org/manual/5.1/manual.html#2.2
It doesn’t mention that strings are passed/returned by reference, but I’m pretty sure they are, as it wod be wildly inefficient to pass/return full character arrays.
Here is some parts of the code, don’t know if it can help (this code cannot run)
-- part of Main:
-- ......
-- create a mesh (my special class)
self.ms = myMesh({v=verts, c=colors, tc=tc})
-- define a 3d shape to the mesh
if self.shape=="flat" then self.warpShape = function() self:warpFlat() end end
-- warp the mesh to its 3d shape
self:warpShape()
-- ....
-- part of my mesh class:
myMesh = class()
function myMesh:init(args)
self.ms = mesh()
self.ms.vertices = args.v
self.ms.texCoords = args.tc
self.ms.colors = args.c
self.heights = args.h
self.texture = args.t
self.ready = true
local Ni = 500
self.newColors = {tbl={}, ready=nil, func=nil, i0=1, di=Ni ,imax=nil}
self.newVertices = {tbl={}, ready=nil, func=nil, i0=1, di=Ni ,imax=nil}
self.newTexCoords = {tbl={}, ready=nil, func=nil, i0=1, di=Ni ,imax=nil}
self.newTexture = {img=nil, ready=nil, func=nil, i0=1, di=Ni ,imax=nil}
end
function myMesh:update()
-- if some update is needed, do only one package of update
if self.newVertices.func then self.newVertices.func(self)
elseif self.newColors.func then self.newColors.func(self)
elseif self.newTexCoords.func then self.newTexCoords.func(self)
elseif self.newTexture.func then self.newTexture.func(self)
end
-- if some new data is ready, update the mesh, but only one at a time
if self.newVertices.ready then
self.ms.vertices = self.newVertices.tbl
self.newVertices.ready = false
elseif self.newColors.ready then
self.ms.colors = self.newColors.tbl
self.newColors.ready = false
elseif self.newTexCoords.ready then
self.ms.texCoords = self.newTexCoords.tbl
self.newTexCoords.ready = false
elseif self.newTexture.ready then
self.ms.texture = self.newTexture.img
self.newTexture.ready = false
end
end
function myMesh:getVertices() return self.ms.vertices end
function myMesh:setVertices(v) self.ms.vertices = v end
-- the warpFlat function
function Object:warpFlat()
if self.ms.newVertices.func == nil then
-- split update management
self.ms.newVertices.func = function() self:warpFlat() end
local vertices = self.ms:getVertices()
self.ms.newVertices.imax = #vertices
-- info management
globals.t0_warpFlat = os.clock()
globals.N_warpFlat = 0
else
-- split update management
local vertices = self.ms:getVertices()
local newVertices = self.ms.newVertices.tbl
local i0 = self.ms.newVertices.i0
local di = self.ms.newVertices.di
local imax = self.ms.newVertices.imax
local i1 = i0 + di
if i1>imax then i1=imax end
-- core computing
local i,v,x,y,z
local w, h = self.width, self.height
for i=i0,i1 do
v = vertices[i]
x,y,z = (v[1]-0.5)*w, (v[2]-0.5)*h, v[3]
newVertices[i] = vec3(x,y,z)
end
-- info management
globals.N_warpFlat = globals.N_warpFlat + 1
-- split update management
self.ms.newVertices.i0 = i1
if i1==imax then
self.ms.newVertices.func = nil
self.ms.newVertices.i0 = 1
self.ms.newVertices.ready = true
-- info management
globals.t0_warpFlat = os.clock()-globals.t0_warpFlat
globals.title = "warpFlat: "..globals.N_warpFlat.." steps"
globals.time = globals.t0_warpFlat
end
end
end
I solved 1/ by completely rewriting the code structure. Now i have 60 fps! Thanks for your help @toadkick, because your answer told me it should work, and this gave me the energy to hang on!
I’m glad you worked it out