# Making a subdivided mesh?

I’m working on a cloth simulation and I want to make a mesh that follows the simulation points. My idea is to make a mesh and use addRectangle to make each polygon tile, but there are up to 4 overlapping vertices on the tile corners and I wonder if there is another way to set up the mesh so polygons share vertices, or if that’s impossible?

It would make getting the indexes of the mesh.vertices a lot easier, now I need to set multiple vertices to one position and it seems a bit weird and unwieldy. I guess I can use a 2d array to group the vertices that share a position, but I’m hoping there’s a way for polys to share points?

@Kirl I tried doing a mesh on my cloth example, but I liked the way it looked without the mesh better. Here’s a link to my original cloth example. I used the triangulate function, but I didn’t save the code.

``````https://codea.io/talk/discussion/6492/cloth-example
``````

@Kirl - AFAIK, there’s no way to avoid setting individual vertex positions, even if several of them share the same position.

Because vector operations are slow in Codea, I might try

1. storing the unique vertex positions in a table V
2. creating a mesh where (say) only the x value is used for each vertex, to store the index number of each vertex in the table V
3. using a shader, and giving it an array of current vertex positions. The vertex shader can use the x value of each mesh vertex to look up the current position in the array and assign it

I don’t know if this is faster, though.

Another option may be to only recalculate vertex positions every X frames, and interpolate between them (perhaps using a shader for speed).

@Kirl Heres my cloth example where I use mesh instead of lines. When I use lines, the fps is about 10, with mesh it’s about 50. I’m using random colors for each mesh. I guess I could use a single image and break it down into all the meshes. In this one, I use 2 triangles per rectangle.

EDIT: In setup, with a CIRCLE size of 0, the cloth passes thru itself. Increasing the size of CIRCLE makes the cloth act stiffer and prevents it from passing thru itself.

EDIT: I wasn’t expecting this to run this fast since I was recalculating the mesh values each draw cycle.

``````displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT_ANY)

function setup()
x1=20
y1=30
size=30
dx,dy=0,0
tab={}
for x=1,x1 do
tab[x]={}
for y=1,y1 do
local r=physics.body(CIRCLE,0)
r.x=100+x*size
r.y=HEIGHT-50-y*size
r.gravityScale=.5
if y==1 then
r.type=STATIC
end
tab[x][y]=r
r=nil
end
end
jVert={}
for x=1,x1 do
for y=2,y1 do
local j=physics.joint(ROPE,tab[x][y-1],tab[x][y],
tab[x][y-1].position,tab[x][y].position,size)
table.insert(jVert,j)
j=nil
end
end
jHorz={}
for x=2,x1 do
for y=1,y1 do
local j=physics.joint(ROPE,tab[x-1][y],tab[x][y],
tab[x-1][y].position,tab[x][y].position,size)
table.insert(jHorz,j)
j=nil
end
end
end

function draw()
background(192, 225, 208, 255)
stroke(0, 161, 255, 255)
strokeWidth(2)
mTab={}
for x=1,x1 do
for y=1,y1 do
if x>1 and y>1 then
table.insert(mTab,vec2(tab[x][y-1].x,tab[x][y-1].y))
table.insert(mTab,vec2(tab[x-1][y-1].x,tab[x-1][y-1].y))
table.insert(mTab,vec2(tab[x-1][y].x,tab[x-1][y].y))
table.insert(mTab,vec2(tab[x][y-1].x,tab[x][y-1].y))
table.insert(mTab,vec2(tab[x-1][y].x,tab[x-1][y].y))
table.insert(mTab,vec2(tab[x][y].x,tab[x][y].y))
end
end
end
m=mesh()
m.vertices=mTab
setColors()
m.colors=cols
setColors()
m:draw()
stroke(255,0,0)
fill(255,0,0)
ellipse(tab[1][1].x,tab[1][1].y,10)
text("Cloth example",WIDTH/2,HEIGHT-10)
text("Slide your finger to move the red dot",WIDTH/2,HEIGHT-40)
text("Rate  "..1//DeltaTime,WIDTH/2,HEIGHT-70)
end

function touched(t)
if t.state==MOVING then
for z=1,x1-1 do
tab[z][1].type=DYNAMIC
end
dx=dx+t.deltaX*200
dy=dy+t.deltaY*200
tab[1][1].linearVelocity=vec2(dx,dy)
end
if t.state==ENDED then
dx,dy=0,0
tab[1][1].type=STATIC
collectgarbage()
end
end

function setColors()
if cols==nil then
cols={}
for z=1,#mTab,6 do
col=vec4(math.random(),math.random(),math.random(),1)
for q=1,6 do
table.insert(cols,col)
end
end
end
end
``````

Here’s the cloth example using an image. The image is upsidedown because of the way I originally did the cloth.

EDIT: I changed the code to correct the image.

EDIT: Changed the code to use mesh buffer.

``````displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT_ANY)

function setup()
x1=20
y1=30
local tTab={}
local xs=1/(x1-1)
local ys=1/(y1-1)
for x=0,x1-2 do
for y=0,y1-2 do
table.insert(tTab,vec2(x*xs,y*ys))
table.insert(tTab,vec2(x*xs+xs,y*ys))
table.insert(tTab,vec2(x*xs+xs,y*ys+ys))
table.insert(tTab,vec2(x*xs,y*ys))
table.insert(tTab,vec2(x*xs,y*ys+ys))
table.insert(tTab,vec2(x*xs+xs,y*ys+ys))
end
end
local size=30
dx,dy=0,0
tab={}
for x=1,x1 do
tab[x]={}
for y=y1,1,-1 do
local r=physics.body(CIRCLE,0)
r.x=100+x*size
r.y=y*size
r.gravityScale=.5
if x==1 and y==y1 then
r.type=STATIC
end
if y==y1 then
r.type=STATIC
end
tab[x][y]=r
r=nil
end
end
jVert={}
for x=1,x1 do
for y=2,y1 do
local j=physics.joint(ROPE,tab[x][y-1],tab[x][y],
tab[x][y-1].position,tab[x][y].position,size)
table.insert(jVert,j)
j=nil
end
end
jHorz={}
for x=2,x1 do
for y=1,y1 do
local j=physics.joint(ROPE,tab[x-1][y],tab[x][y],
tab[x-1][y].position,tab[x][y].position,size)
table.insert(jHorz,j)
j=nil
end
end
m=mesh()
m.texCoords=tTab
m.texture="Cargo Bot:Startup Screen"
m.vertices=tTab
buf=m:buffer("position")
end

function draw()
background(192, 224, 225, 255)
stroke(0, 161, 255, 255)
strokeWidth(2)
local n=1
for x=1,x1-1 do
for y=1,y1-1 do
buf[n]=vec2(tab[x][y].x,tab[x][y].y)
buf[n+1]=vec2(tab[x+1][y].x,tab[x+1][y].y)
buf[n+2]=vec2(tab[x+1][y+1].x,tab[x+1][y+1].y)
buf[n+3]=vec2(tab[x][y].x,tab[x][y].y)
buf[n+4]=vec2(tab[x][y+1].x,tab[x][y+1].y)
buf[n+5]=vec2(tab[x+1][y+1].x,tab[x+1][y+1].y)
n=n+6
end
end
m:draw()
pushStyle()
stroke(255,0,0)
fill(255,0,0)
ellipse(tab[1][y1].x,tab[1][y1].y,10)
text("Cloth example",WIDTH/2,HEIGHT-10)
text("Slide your finger to move the red dot",WIDTH/2,HEIGHT-40)
text("Rate  "..1/DeltaTime//1,WIDTH/2,HEIGHT-70)
text("KB Memory used  "..collectgarbage("count")//1,WIDTH/2,HEIGHT-100)
popStyle()
end

function touched(t)
if t.state==MOVING then
for z=1,x1-1 do
tab[z][y1].type=DYNAMIC
end
dx=dx+t.deltaX*200
dy=dy+t.deltaY*200
tab[1][y1].linearVelocity=vec2(dx,dy)
end
if t.state==ENDED then
dx,dy=0,0
tab[1][y1].type=STATIC
end
end
``````

Thanks guys, looking cool dave, very well done!
I don’t want to redefine the mesh every frame but rather try to set the vertex positions using mesh:vertex(). The help mentions this is more efficient for setting a subset of vertices, I’m hoping the same is also true when setting all vertices. After seeing your example however, I had to go ahead and just try it as well.

@Ignatz
Can you elaborate on your idea? Do you mean setting the vertex positions with a shader? I’ve been experimenting with shaders a little bit but never actually passed a value or did anything other than simple color adjustments.

@Kirl I made these changes to my code. I moved the code for mesh, texCoords, and texture out of draw() and into setup(). I left vertices and draw in draw() and the code runs OK.

``````    -- moved to setup
m=mesh()
m.texCoords = tTab
m.texture = "Cargo Bot:Startup Screen"
``````
``````    -- still in draw
m.vertices=mTab
m:draw()
``````

@kirl - you can redefine vertex positions “in place” inside the mesh using the position buffer.

Have a look for buffer in the mesh reference, there is an example there.

On reflection, I’m not sure a shader will help, because whichever way you do it, you have to set a whole bunch of vertices.

Here is how the draw function in dave’s example would look, assuming you had set up a mesh m, in setup.

``````    mTab=m:buffer("position")
n=1
for x=1,x1-1 do
for y=1,y1-1 do
--if x<x1 and y<y1 then
mTab[n]=vec2(tab[x][y].x,tab[x][y].y)
mTab[n+1]=vec2(tab[x+1][y].x,tab[x+1][y].y)
mTab[n+2]=vec2(tab[x+1][y+1].x,tab[x+1][y+1].y)
mTab[n+3]=vec2(tab[x][y].x,tab[x][y].y)
mTab[n+4]=vec2(tab[x][y+1].x,tab[x][y+1].y)
mTab[n+5]=vec2(tab[x+1][y+1].x,tab[x+1][y+1].y)
n=n+6
--end
end
end
``````

@Ignatz I modified my code above to use the mesh buffer which increased the fps.

Thanks a ton guys! I still seem to have the uv’s meshed up, because the images appear upside down. Needs more fiddling, but I’m nearly there. Thanks for the help!