Simpler Soft Bodies

Hello,
I don’t like using other people’s code, so I just decided to make my own anyways:

displayMode(FULLSCREEN)

function setup()
    numSegments = 30
    radius = 50
    springiness = math.random(3,25)
    deltaAngle = 360/numSegments
    
    softBodies = {}
    
    for i = 1,5 do
        createSoftBody(math.random()*WIDTH,math.random()*HEIGHT)
    end
    
    edges = {}
    table.insert(edges,physics.body(EDGE,vec2(0,0),vec2(WIDTH,0)))
    table.insert(edges,physics.body(EDGE,vec2(WIDTH,0),vec2(WIDTH,HEIGHT)))
    table.insert(edges,physics.body(EDGE,vec2(WIDTH,HEIGHT),vec2(0,HEIGHT)))
    table.insert(edges,physics.body(EDGE,vec2(0,HEIGHT),vec2(0,0)))
end

function draw()
    background(40, 40, 50)
    strokeWidth(1)
    physics.gravity(Gravity)
    
    for i,v in ipairs(softBodies) do
        --[[ellipse(v.centerCircle.x,v.centerCircle.y,v.centerCircle.radius*2)
        for i,v in ipairs(v.circleList) do
            ellipse(v.x,v.y,v.radius*2)
        end
        for i,v in ipairs(v.jointList) do
            line(v.bodyA.position.x,v.bodyA.position.y,v.bodyB.position.x,v.bodyB.position.y)
        end]]--
        
        updateMesh(v)
        v.mesh:draw()
    end
end

function createSoftBody(x,y)
    local center = vec2(x,y)
    local info = {
        circleList = {},
        centerObject = {},
        jointList = {}
    }
    
    for i = 1, numSegments do
        local theta = math.rad(deltaAngle * i)
        table.insert(info.circleList,getCircle(radius*math.cos(theta),radius*math.sin(theta),center))
    end
    
    info.centerCircle = getCircle(0,0,center)
    
    for i = 1,numSegments do
        local currentObj = info.circleList[i]
        local neighborObj = info.circleList[(i % numSegments)+1]
        
        local j1 = physics.joint(DISTANCE,currentObj,neighborObj,currentObj.position,neighborObj.position)
        j1.frequency = springiness
        j1.dampingRatio = .5
        
        local j2 = physics.joint(DISTANCE,currentObj,info.centerCircle,currentObj.position,info.centerCircle.position)
        j2.frequency = springiness
        j2.dampingRatio = .5
        
        table.insert(info.jointList,j1)
        table.insert(info.jointList,j2)
    end
    
    info.mesh = mesh()
    updateMesh(info)
    info.mesh:setColors(255,0,0)
    
    table.insert(softBodies,info)
end

function getCircle(x,y,cPoint)
    local c = physics.body(CIRCLE,radius/(numSegments/5))
    c.x = x+cPoint.x
    c.y = y+cPoint.y
    c.fixedRotation = true
    c.density = .5
    c.restitution = 0
    c.friction = 1
    return c
end

function updateMesh(info)
    local vertices = {}
    output.clear()
    local texCoords = {}
    for i = 1,#info.circleList do
        local currentObj = info.circleList[i]
        local neighborObj = info.circleList[(i % numSegments)+1]
        table.insert(vertices,info.centerCircle.position)
        
        local rScale = (radius+currentObj.radius)/radius
        local relativePos = currentObj.position-info.centerCircle.position
        local position = info.centerCircle.position+vec2(relativePos.x*rScale,relativePos.y*rScale)
        table.insert(vertices,position)
        
        rScale = (radius+neighborObj.radius)/radius
        relativePos = neighborObj.position-info.centerCircle.position
        position = info.centerCircle.position+vec2(relativePos.x*rScale,relativePos.y*rScale)
        table.insert(vertices,position)
    end
    
    info.mesh.vertices = vertices
    info.mesh.texCoords = vertices
end

function touched(t)
    if t.state == ENDED or t.state == CANCELLED then
        local forceAmount = 250
        for i,v in ipairs(softBodies) do
            v.centerCircle:applyForce(vec2(0,forceAmount))
            for i,v in ipairs(v.circleList) do
                v:applyForce(vec2(0,forceAmount))
            end
        end
    end
end

```


Thanks!

That’s Awesome, hope you don’t mind if i use it?

Interesting, I like the way you dress the meshes :slight_smile:

Nice, but too slow on ipad1 (that is not the case with your water shader)

@Saurabh - Ho ahed.
@juaxix - Thanks.
@Jmv38 - That’s really weird. You can try turning down the number of bodies. Here’s my BS why this is happening: The lag in the water example is caused by numerous Box2D collisions, which can’t be optimized by hardware (as easily). This code is using some heavy OpenGL stuff, and I think that the newer iPads have a better graphics processor.
Thanks!